argo-cd/reposerver/repository/utils.go
Matthieu MOREL 342aea457f
chore(reposerver): Fix modernize linter (#26315)
Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>
Co-authored-by: Blake Pettersson <blake.pettersson@gmail.com>
2026-02-07 18:34:35 +01:00

85 lines
2.4 KiB
Go

package repository
import (
"path/filepath"
"strings"
securejoin "github.com/cyphar/filepath-securejoin"
log "github.com/sirupsen/logrus"
"github.com/argoproj/argo-cd/v3/reposerver/apiclient"
"github.com/argoproj/argo-cd/v3/util/io/files"
)
// getApplicationRootPath returns the common root path (shortest shared structure between all paths) among a
// set of application-related paths for manifest generation. AppPath is the lower possible value
func getApplicationRootPath(q *apiclient.ManifestRequest, appPath, repoPath string) string {
paths := getPaths(q, appPath, repoPath)
if len(paths) == 0 {
// backward compatibility, by default the root path is the repoPath
return repoPath
}
// the app path must be the lower possible value
commonParts := strings.Split(appPath, string(filepath.Separator))
var disjoint bool
for _, path := range paths {
parts := strings.Split(path, string(filepath.Separator))
// find the minimum length between the current common parts and the current path
minLen := func(a, b int) int {
if a < b {
return a
}
return b
}(len(commonParts), len(parts))
// check if diverge /disjoint in some point
for i := range minLen {
if commonParts[i] != parts[i] {
commonParts = commonParts[:i]
disjoint = true
break
}
}
// for non-disjoint paths
if !disjoint && minLen < len(commonParts) {
commonParts = commonParts[:minLen]
}
}
return string(filepath.Separator) + filepath.Join(commonParts...)
}
// getPaths retrieves all absolute paths associated with the generation of application manifests.
func getPaths(q *apiclient.ManifestRequest, appPath, repoPath string) []string {
var paths []string
for annotationPath := range strings.SplitSeq(q.AnnotationManifestGeneratePaths, ";") {
if annotationPath == "" {
continue
}
var err error
var path, unsafePath string
if filepath.IsAbs(annotationPath) {
unsafePath = filepath.Clean(annotationPath)
} else {
appRelPath, err := files.RelativePath(appPath, repoPath)
if err != nil {
log.Errorf("error building app relative path: %v", err)
continue
}
unsafePath = filepath.Clean(filepath.Join(appRelPath, annotationPath))
}
path, err = securejoin.SecureJoin(repoPath, unsafePath)
if err != nil {
log.Errorf("error joining repoPath %q and absolute unsafePath %q: %v", repoPath, unsafePath, err)
continue
}
paths = append(paths, path)
}
return paths
}