diff --git a/internal/git/fixtures/README.md b/internal/git/fixtures/README.md new file mode 100644 index 00000000..9ede0edb --- /dev/null +++ b/internal/git/fixtures/README.md @@ -0,0 +1 @@ +This folder is the base of git repositories created in tests. diff --git a/internal/git/fixtures/nested/names.txt b/internal/git/fixtures/nested/names.txt new file mode 100644 index 00000000..86e041da --- /dev/null +++ b/internal/git/fixtures/nested/names.txt @@ -0,0 +1,3 @@ +foo +bar +baz diff --git a/internal/git/fixtures/sample.txt b/internal/git/fixtures/sample.txt new file mode 100644 index 00000000..6f2c2d8b --- /dev/null +++ b/internal/git/fixtures/sample.txt @@ -0,0 +1 @@ +another boring file diff --git a/internal/git/git.go b/internal/git/git.go index 787291d0..b241162e 100644 --- a/internal/git/git.go +++ b/internal/git/git.go @@ -13,6 +13,7 @@ import ( "path/filepath" "regexp" "runtime" + "slices" "strings" "time" @@ -115,10 +116,11 @@ func (g *Git) CheckDirDirty(dir string, ignoreChangePatterns map[string]string) filesToIgnore := []string{"gen.yaml", "gen.lock", "workflow.yaml", "workflow.lock"} for f, s := range status { - for _, fileToIgnore := range filesToIgnore { - if strings.Contains(f, fileToIgnore) { - continue - } + shouldSkip := slices.ContainsFunc(filesToIgnore, func(fileToIgnore string) bool { + return strings.Contains(f, fileToIgnore) + }) + if shouldSkip { + continue } if strings.HasPrefix(f, cleanedDir) { diff --git a/internal/git/git_test.go b/internal/git/git_test.go new file mode 100644 index 00000000..0954ea59 --- /dev/null +++ b/internal/git/git_test.go @@ -0,0 +1,107 @@ +package git + +import ( + "fmt" + "io" + "io/fs" + "os" + "path/filepath" + "testing" + "time" + + "github.com/go-git/go-billy/v5" + "github.com/go-git/go-billy/v5/memfs" + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing/object" + "github.com/go-git/go-git/v5/storage/memory" + "github.com/stretchr/testify/require" +) + +func newTestRepo(t *testing.T) (*git.Repository, billy.Filesystem) { + t.Helper() + + mfs := memfs.New() + + err := filepath.WalkDir("./fixtures", func(path string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + + if d.IsDir() { + return nil + } + + fixture, err := os.Open(path) + if err != nil { + return err + } + defer fixture.Close() + + f, err := mfs.Create(path) + if err != nil { + return err + } + defer f.Close() + + _, err = io.Copy(f, fixture) + if err != nil { + return err + } + + return nil + }) + require.NoError(t, err, "expected to walk the fixture directory") + + storage := memory.NewStorage() + repo, err := git.Init(storage, mfs) + require.NoError(t, err, "expected empty repo to be initialized") + + wt, err := repo.Worktree() + require.NoError(t, err, "expected to get worktree") + + _, err = wt.Add(".") + require.NoError(t, err, "expected to add all files") + + _, err = wt.Commit("initial commit", &git.CommitOptions{ + Author: &object.Signature{ + Name: "Test User", + Email: "test@example.com", + When: time.Unix(0, 0), + }, + }) + require.NoError(t, err, "expected to commit all files") + + return repo, mfs +} + +func TestGit_CheckDirDirty(t *testing.T) { + repo, mfs := newTestRepo(t) + + f, err := mfs.Create("dirty-file") + require.NoError(t, err, "expected to create a dirty file") + defer f.Close() + fmt.Fprintln(f, "sample content") + + g := Git{repo: repo} + dirty, str, err := g.CheckDirDirty(".", map[string]string{}) + require.NoError(t, err, "expected to check the directory") + + require.Equal(t, `new file found: []string{"dirty-file"}`, str) + require.True(t, dirty, "expected the directory to be dirty") +} + +func TestGit_CheckDirDirty_IgnoredFiles(t *testing.T) { + repo, mfs := newTestRepo(t) + + f, err := mfs.Create("workflow.lock") + require.NoError(t, err, "expected to create a dirty file") + defer f.Close() + fmt.Fprintln(f, "sample content") + + g := Git{repo: repo} + dirty, str, err := g.CheckDirDirty(".", map[string]string{}) + require.NoError(t, err, "expected to check the directory") + + require.Equal(t, "", str, "expected no dirty files reported") + require.False(t, dirty, "expected the directory to be clean") +}