Files
8334da36f2 Bump major version to 3 (#21410)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: crenshaw-dev <[email protected]>
2025-01-10 16:14:00 -05:00

86 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 := 0; i < minLen; i++ {
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.Split(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
}