From 3f280798c94cb712f6f4a2cc4eafe5be224158ad Mon Sep 17 00:00:00 2001 From: Jukie <10012479+Jukie@users.noreply.github.com> Date: Mon, 27 Mar 2023 23:24:07 -0600 Subject: [PATCH 1/2] Fix autoplan modules for per-repo configs --- go.mod | 1 + go.sum | 2 ++ server/events/modules.go | 2 +- server/events/project_command_builder.go | 15 ++++++++------- server/events/project_finder.go | 22 ++++++++++++++++++++-- server/events/project_finder_test.go | 2 +- 6 files changed, 33 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index 4426816b40..c756fcfd3c 100644 --- a/go.mod +++ b/go.mod @@ -42,6 +42,7 @@ require ( github.com/xanzy/go-gitlab v0.81.0 go.etcd.io/bbolt v1.3.7 go.uber.org/zap v1.24.0 + golang.org/x/exp v0.0.0-20230321023759-10a507213a29 golang.org/x/term v0.6.0 golang.org/x/text v0.8.0 gopkg.in/yaml.v2 v2.4.0 diff --git a/go.sum b/go.sum index 7670d0dc68..409caf89ce 100644 --- a/go.sum +++ b/go.sum @@ -506,6 +506,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= diff --git a/server/events/modules.go b/server/events/modules.go index a545d380cf..396cd59d8a 100644 --- a/server/events/modules.go +++ b/server/events/modules.go @@ -130,7 +130,7 @@ func findModuleDependants(files fs.FS, autoplanModuleDependants string) (ModuleP filter, _ := patternmatcher.New(strings.Split(autoplanModuleDependants, ",")) var projects []string err := fs.WalkDir(files, ".", func(rel string, info fs.DirEntry, err error) error { - if match, _ := filter.Matches(rel); match { + if match, _ := filter.MatchesOrParentMatches(rel); match { if projectDir := getProjectDirFromFs(files, rel); projectDir != "" { projects = append(projects, projectDir) } diff --git a/server/events/project_command_builder.go b/server/events/project_command_builder.go index 1069a80480..37fe51301a 100644 --- a/server/events/project_command_builder.go +++ b/server/events/project_command_builder.go @@ -297,7 +297,7 @@ func (p *DefaultProjectCommandBuilder) buildAllCommandsByCfg(ctx *command.Contex } ctx.Log.Info("successfully parsed remote %s file", repoCfgFile) if len(repoCfg.Projects) > 0 { - matchingProjects, err := p.ProjectFinder.DetermineProjectsViaConfig(ctx.Log, modifiedFiles, repoCfg, "") + matchingProjects, err := p.ProjectFinder.DetermineProjectsViaConfig(ctx.Log, modifiedFiles, repoCfg, "", nil) if err != nil { return nil, err } @@ -351,8 +351,14 @@ func (p *DefaultProjectCommandBuilder) buildAllCommandsByCfg(ctx *command.Contex ctx.Log.Info("successfully parsed %s file", repoCfgFile) } + moduleInfo, err := FindModuleProjects(repoDir, p.AutoDetectModuleFiles) + if err != nil { + ctx.Log.Warn("error(s) loading project module dependencies: %s", err) + } + ctx.Log.Debug("moduleInfo for %s (matching %q) = %v", repoDir, p.AutoDetectModuleFiles, moduleInfo) + if len(repoCfg.Projects) > 0 { - matchingProjects, err := p.ProjectFinder.DetermineProjectsViaConfig(ctx.Log, modifiedFiles, repoCfg, repoDir) + matchingProjects, err := p.ProjectFinder.DetermineProjectsViaConfig(ctx.Log, modifiedFiles, repoCfg, repoDir, moduleInfo) if err != nil { return nil, err } @@ -386,11 +392,6 @@ func (p *DefaultProjectCommandBuilder) buildAllCommandsByCfg(ctx *command.Contex ctx.Log.Info("found no %s file", repoCfgFile) } // build a module index for projects that are explicitly included - moduleInfo, err := FindModuleProjects(repoDir, p.AutoDetectModuleFiles) - if err != nil { - ctx.Log.Warn("error(s) loading project module dependencies: %s", err) - } - ctx.Log.Debug("moduleInfo for %s (matching %q) = %v", repoDir, p.AutoDetectModuleFiles, moduleInfo) modifiedProjects := p.ProjectFinder.DetermineProjects(ctx.Log, modifiedFiles, ctx.Pull.BaseRepo.FullName, repoDir, p.AutoplanFileList, moduleInfo) ctx.Log.Info("automatically determined that there were %d projects modified in this pull request: %s", len(modifiedProjects), modifiedProjects) for _, mp := range modifiedProjects { diff --git a/server/events/project_finder.go b/server/events/project_finder.go index 80049cc4f0..31c71eb460 100644 --- a/server/events/project_finder.go +++ b/server/events/project_finder.go @@ -22,6 +22,7 @@ import ( "strings" "github.com/runatlantis/atlantis/server/core/config/valid" + "golang.org/x/exp/slices" "github.com/moby/patternmatcher" "github.com/pkg/errors" @@ -44,7 +45,7 @@ type ProjectFinder interface { // DetermineProjectsViaConfig returns the list of projects that were modified // based on modifiedFiles and the repo's config. // absRepoDir is the path to the cloned repo on disk. - DetermineProjectsViaConfig(log logging.SimpleLogging, modifiedFiles []string, config valid.RepoCfg, absRepoDir string) ([]valid.Project, error) + DetermineProjectsViaConfig(log logging.SimpleLogging, modifiedFiles []string, config valid.RepoCfg, absRepoDir string, moduleInfo ModuleProjects) ([]valid.Project, error) DetermineWorkspaceFromHCL(log logging.SimpleLogging, absRepoDir string) (string, error) } @@ -174,10 +175,27 @@ func (p *DefaultProjectFinder) DetermineProjects(log logging.SimpleLogging, modi } // See ProjectFinder.DetermineProjectsViaConfig. -func (p *DefaultProjectFinder) DetermineProjectsViaConfig(log logging.SimpleLogging, modifiedFiles []string, config valid.RepoCfg, absRepoDir string) ([]valid.Project, error) { +func (p *DefaultProjectFinder) DetermineProjectsViaConfig(log logging.SimpleLogging, modifiedFiles []string, config valid.RepoCfg, absRepoDir string, moduleInfo ModuleProjects) ([]valid.Project, error) { + + // Check moduleInfo for downstream project dependencies + var dependentProjects []string + for _, file := range modifiedFiles { + if moduleInfo != nil { + downstreamProjects := moduleInfo.DependentProjects(path.Dir(file)) + log.Debug("found downstream projects for %q: %v", file, downstreamProjects) + dependentProjects = append(dependentProjects, downstreamProjects...) + } + } + var projects []valid.Project for _, project := range config.Projects { log.Debug("checking if project at dir %q workspace %q was modified", project.Dir, project.Workspace) + + if slices.Contains(dependentProjects, project.Dir) { + projects = append(projects, project) + continue + } + var whenModifiedRelToRepoRoot []string for _, wm := range project.Autoplan.WhenModified { wm = strings.TrimSpace(wm) diff --git a/server/events/project_finder_test.go b/server/events/project_finder_test.go index c88b0f123a..f3405494dd 100644 --- a/server/events/project_finder_test.go +++ b/server/events/project_finder_test.go @@ -538,7 +538,7 @@ func TestDefaultProjectFinder_DetermineProjectsViaConfig(t *testing.T) { for _, c := range cases { t.Run(c.description, func(t *testing.T) { pf := events.DefaultProjectFinder{} - projects, err := pf.DetermineProjectsViaConfig(logging.NewNoopLogger(t), c.modified, c.config, tmpDir) + projects, err := pf.DetermineProjectsViaConfig(logging.NewNoopLogger(t), c.modified, c.config, tmpDir, nil) Ok(t, err) Equals(t, len(c.expProjPaths), len(projects)) for i, proj := range projects { From bc26fb3ca2409f7f2d9913a67108434cda9b1c88 Mon Sep 17 00:00:00 2001 From: Jukie <10012479+Jukie@users.noreply.github.com> Date: Sat, 1 Apr 2023 09:53:07 -0600 Subject: [PATCH 2/2] Use utils package for slices.Contains --- go.mod | 1 - go.sum | 2 -- server/events/project_finder.go | 4 ++-- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index c756fcfd3c..4426816b40 100644 --- a/go.mod +++ b/go.mod @@ -42,7 +42,6 @@ require ( github.com/xanzy/go-gitlab v0.81.0 go.etcd.io/bbolt v1.3.7 go.uber.org/zap v1.24.0 - golang.org/x/exp v0.0.0-20230321023759-10a507213a29 golang.org/x/term v0.6.0 golang.org/x/text v0.8.0 gopkg.in/yaml.v2 v2.4.0 diff --git a/go.sum b/go.sum index 409caf89ce..7670d0dc68 100644 --- a/go.sum +++ b/go.sum @@ -506,8 +506,6 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= -golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= diff --git a/server/events/project_finder.go b/server/events/project_finder.go index 31c71eb460..8d5ecafe52 100644 --- a/server/events/project_finder.go +++ b/server/events/project_finder.go @@ -22,7 +22,7 @@ import ( "strings" "github.com/runatlantis/atlantis/server/core/config/valid" - "golang.org/x/exp/slices" + "github.com/runatlantis/atlantis/server/utils" "github.com/moby/patternmatcher" "github.com/pkg/errors" @@ -191,7 +191,7 @@ func (p *DefaultProjectFinder) DetermineProjectsViaConfig(log logging.SimpleLogg for _, project := range config.Projects { log.Debug("checking if project at dir %q workspace %q was modified", project.Dir, project.Workspace) - if slices.Contains(dependentProjects, project.Dir) { + if utils.SlicesContains(dependentProjects, project.Dir) { projects = append(projects, project) continue }