From c52c92417a285f15db8375b9ea32fe1a38bfde6d Mon Sep 17 00:00:00 2001 From: Mateusz Tracz Date: Wed, 24 May 2023 13:09:32 +0100 Subject: [PATCH] Handle nested changes --- patrol/repo.go | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/patrol/repo.go b/patrol/repo.go index ed1865e..b312676 100644 --- a/patrol/repo.go +++ b/patrol/repo.go @@ -245,7 +245,8 @@ func (r *Repo) detectInternalChangesFrom(revision string, allFiles bool) error { } for _, change := range diff { - if !allFiles && !strings.HasSuffix(change.From.Name, ".go") { + goFile := strings.HasSuffix(change.From.Name, ".go") + if !allFiles && !goFile { // we're only interested in Go files continue } @@ -259,11 +260,17 @@ func (r *Repo) detectInternalChangesFrom(revision string, allFiles bool) error { // package is part of our module if pkgName == "" { - if allFiles { - pkgName = r.ModuleName() - } else { + if goFile { + // go files are always in packages pkgName = r.ModuleName() + "/" + filepath.Dir(change.From.Name) } + if allFiles && !goFile { + // Non go files belong to the closest package + pkgName, err = r.closestPackageForFileInModule(change.From.Name) + if err != nil { + return err + } + } } r.flagPackageAsChanged(pkgName) @@ -272,6 +279,27 @@ func (r *Repo) detectInternalChangesFrom(revision string, allFiles bool) error { return nil } +// closestPackageForFileInModule returns the closest go package path for the given file +// it will return the module name if no package is found +func (r *Repo) closestPackageForFileInModule(fileName string) (string, error) { + currentDir := filepath.Dir(fileName) + for currentDir != "." { + files, err := os.ReadDir(r.path + "/" + currentDir) + if err != nil { + return "", err + } + + for _, f := range files { + if strings.HasSuffix(f.Name(), ".go") { + return r.ModuleName() + "/" + currentDir, nil + } + } + + currentDir = filepath.Dir(currentDir) + } + return r.ModuleName(), nil +} + // detectGoModulesChanges finds differences in dependencies required by // HEAD:go.mod and {revision}:go.mod and flags as changed any packages // depending on any of the changed dependencies.