Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(smart-mode): configuration option for smart-mode base revision #95

Merged
merged 1 commit into from
Sep 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ func init() {
asyncHelp := "sets the number of applications to be processed in parallel\nthe default (0) is no limit"
rootCmd.PersistentFlags().IntVarP(&asyncLevel, "async", "a", 0, asyncHelp)

smartModeBaseRevisionHelp := "base revision to compare against in Smart Mode\n" +
"if not provided, only local changes will be considered"
rootCmd.PersistentFlags().String("smart-mode.base-revision", "", smartModeBaseRevisionHelp)

if err := viper.BindPFlags(rootCmd.PersistentFlags()); err != nil {
log.Fatal().Err(err).Msg("Unable to bind flags")
}
Expand Down Expand Up @@ -82,7 +86,7 @@ func detectTargetEnvsAndApps(cmd *cobra.Command, args []string) (err error) {
// smart mode requires instantiation of globe object to get the list of environments
// the globe object will not be used later in the process. It is only used to get the list of all environments and their apps.
globeAllEnvsAndApps := myks.New(".")
targetEnvironments, targetApplications, err = globeAllEnvsAndApps.DetectChangedEnvsAndApps()
targetEnvironments, targetApplications, err = globeAllEnvsAndApps.DetectChangedEnvsAndApps(viper.GetString("smart-mode.base-revision"))
if err != nil {
log.Warn().Err(err).Msg("Unable to run Smart Mode. Rendering everything.")
}
Expand Down
93 changes: 0 additions & 93 deletions internal/myks/git.go

This file was deleted.

4 changes: 2 additions & 2 deletions internal/myks/globe.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ type Globe struct {

// Base directory for environments
EnvironmentBaseDir string `default:"envs"`
// Main branch name
MainBranchName string `default:"main"`
// Prefix for kubernetes namespaces
NamespacePrefix string `default:""`
// Application prototypes directory
Expand Down Expand Up @@ -68,8 +70,6 @@ type Globe struct {
YttPkgStepDirName string `default:"ytt-pkg"`
// Ytt step directory name
YttStepDirName string `default:"ytt"`
// Main branch name
MainBranchName string `default:"main"`

/// User input

Expand Down
9 changes: 2 additions & 7 deletions internal/myks/smart_mode.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func (g *Globe) getAppsExpr() string {
return "^" + g.GitPathPrefix + "(" + g.EnvironmentBaseDir + "/.*?)/_apps/(.*?)/.*$"
}

func (g *Globe) DetectChangedEnvsAndApps() ([]string, []string, error) {
func (g *Globe) DetectChangedEnvsAndApps(baseRevision string) ([]string, []string, error) {
g.collectEnvironments(nil)

err := process(0, g.environments, func(item interface{}) error {
Expand All @@ -55,12 +55,7 @@ func (g *Globe) DetectChangedEnvsAndApps() ([]string, []string, error) {
return nil, nil, err
}

curRev, err := getDiffRevision(g.MainBranchName)
if err != nil {
log.Err(err).Msg(g.Msg("Failed to get current revision"))
return nil, nil, err
}
changedFiles, err := getChangedFiles(curRev)
changedFiles, err := getChangedFiles(baseRevision)
if err != nil {
log.Err(err).Msg(g.Msg("Failed to get diff"))
return nil, nil, err
Expand Down
52 changes: 52 additions & 0 deletions internal/myks/smart_mode_git.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package myks

import (
"regexp"
"strings"

"github.com/rs/zerolog/log"
)

type ChangedFiles map[string]string

// getChangedFiles returns list of files changed since the baseRevision, if specified, and since the last commit
func getChangedFiles(baseRevision string) (ChangedFiles, error) {
logFn := func(name string, args []string) {
log.Debug().Msg(msgRunCmd("collect changed files for smart-mode", name, args))
}

files := ChangedFiles{}
if baseRevision != "" {
result, err := runCmd("git", nil, []string{"diff", "--name-status", baseRevision}, logFn)
if err != nil {
return nil, err
}
for path, status := range convertToChangedFiles(result.Stdout) {
files[path] = status
}
}

result, err := runCmd("git", nil, []string{"status", "--porcelain"}, logFn)
if err != nil {
return nil, err
}
for path, status := range convertToChangedFiles(result.Stdout) {
files[path] = status
}

return files, nil
}

func convertToChangedFiles(changes string) ChangedFiles {
cfs := ChangedFiles{}
expr := regexp.MustCompile(`^([A-Z]\t|[A-Z? ]{2} )(.*)$`)
for _, str := range strings.Split(changes, "\n") {
matches := expr.FindStringSubmatch(str)
if len(matches) == 3 {
// 1: the first character of the status, after trimming spaces and tabs
// 2: the file path
cfs[matches[2]] = strings.Trim(matches[1], " \t")[:1]
}
}
return cfs
}
47 changes: 0 additions & 47 deletions internal/myks/git_test.go → internal/myks/smart_mode_git_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,53 +28,6 @@ func Test_getChangedFiles(t *testing.T) {
}
}

func Test_getMainBranchHeadRevision(t *testing.T) {
type args struct {
mainBranch string
}
tests := []struct {
name string
args args
wantErr bool
}{
{"happy path", args{"main"}, false},
{"sad path", args{"unknown-branch"}, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := getMainBranchHeadRevision(tt.args.mainBranch)
if (err != nil) != tt.wantErr {
t.Errorf("getMainBranchHeadRevision() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !tt.wantErr && got == "" {
t.Errorf("getMainBranchHeadRevision() must not be empty")
}
})
}
}

func Test_getCurrentBranchHeadRevision(t *testing.T) {
tests := []struct {
name string
wantErr bool
}{
{"happy path", false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := getCurrentBranchHeadRevision()
if (err != nil) != tt.wantErr {
t.Errorf("getCurrentBranchHeadRevision() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !tt.wantErr && got == "" {
t.Errorf("getCurrentBranchHeadRevision() must not be empty")
}
})
}
}

func Test_convertToChangedFiles(t *testing.T) {
type args struct {
changes string
Expand Down