diff --git a/kyaml/copyutil/copyutil.go b/kyaml/copyutil/copyutil.go index fa1891110..3b7d01784 100644 --- a/kyaml/copyutil/copyutil.go +++ b/kyaml/copyutil/copyutil.go @@ -25,7 +25,7 @@ func CopyDir(src string, dst string) error { // don't copy the .git dir if path != src { rel := strings.TrimPrefix(path, src) - if strings.HasPrefix(rel, string(filepath.Separator)+".git") { + if IsDotGitFolder(rel) { return nil } } @@ -67,7 +67,7 @@ func Diff(sourceDir, destDir string) (sets.String, error) { } // skip git repo if it exists - if strings.Contains(path, ".git") { + if IsDotGitFolder(path) { return nil } @@ -86,7 +86,7 @@ func Diff(sourceDir, destDir string) (sets.String, error) { } // skip git repo if it exists - if strings.Contains(path, ".git") { + if IsDotGitFolder(path) { return nil } @@ -129,6 +129,18 @@ func Diff(sourceDir, destDir string) (sets.String, error) { return diff, nil } +// IsDotGitFolder checks if the provided path is either the .git folder or +// a file underneath the .git folder. +func IsDotGitFolder(path string) bool { + cleanPath := filepath.ToSlash(filepath.Clean(path)) + for _, c := range strings.Split(cleanPath, "/") { + if c == ".git" { + return true + } + } + return false +} + // PrettyFileDiff takes the content of two files and returns the pretty diff func PrettyFileDiff(s1, s2 string) string { dmp := diffmatchpatch.New() diff --git a/kyaml/copyutil/copyutil_test.go b/kyaml/copyutil/copyutil_test.go index 70e73cd1e..8fbb2c23f 100644 --- a/kyaml/copyutil/copyutil_test.go +++ b/kyaml/copyutil/copyutil_test.go @@ -154,6 +154,11 @@ func TestDiff_skipGitSrc(t *testing.T) { filepath.Join(s, "a1", "f.yaml"), []byte(`a`), 0600) assert.NoError(t, err) + // files that just happen to start with .git should not be ignored. + err = ioutil.WriteFile( + filepath.Join(s, ".gitlab-ci.yml"), []byte(`a`), 0600) + assert.NoError(t, err) + // git should be ignored err = os.Mkdir(filepath.Join(s, ".git"), 0700) assert.NoError(t, err) @@ -167,6 +172,10 @@ func TestDiff_skipGitSrc(t *testing.T) { filepath.Join(d, "a1", "f.yaml"), []byte(`a`), 0600) assert.NoError(t, err) + err = ioutil.WriteFile( + filepath.Join(d, ".gitlab-ci.yml"), []byte(`a`), 0600) + assert.NoError(t, err) + diff, err := Diff(s, d) assert.NoError(t, err) assert.Empty(t, diff.List()) @@ -283,3 +292,99 @@ metadata: assert.Contains(t, PrettyFileDiff(s1, s2), expectedLine1) assert.Contains(t, PrettyFileDiff(s1, s2), expectedLine2) } + +func TestCopyDir(t *testing.T) { + s, err := ioutil.TempDir("", "copyutilsrc") + assert.NoError(t, err) + v, err := ioutil.TempDir("", "copyutilvalidate") + assert.NoError(t, err) + + err = os.Mkdir(filepath.Join(s, "a1"), 0700) + assert.NoError(t, err) + err = ioutil.WriteFile( + filepath.Join(s, "a1", "f.yaml"), []byte(`a`), 0600) + assert.NoError(t, err) + + // files that just happen to start with .git should not be ignored. + err = ioutil.WriteFile( + filepath.Join(s, ".gitlab-ci.yml"), []byte(`a`), 0600) + assert.NoError(t, err) + + // git should be ignored + err = os.Mkdir(filepath.Join(s, ".git"), 0700) + assert.NoError(t, err) + err = ioutil.WriteFile( + filepath.Join(s, ".git", "f.yaml"), []byte(`a`), 0600) + assert.NoError(t, err) + + err = os.Mkdir(filepath.Join(v, "a1"), 0700) + assert.NoError(t, err) + err = ioutil.WriteFile( + filepath.Join(v, "a1", "f.yaml"), []byte(`a`), 0600) + assert.NoError(t, err) + + err = ioutil.WriteFile( + filepath.Join(v, ".gitlab-ci.yml"), []byte(`a`), 0600) + assert.NoError(t, err) + + d, err := ioutil.TempDir("", "copyutildestination") + assert.NoError(t, err) + + err = CopyDir(s, d) + assert.NoError(t, err) + + diff, err := Diff(d, v) + assert.NoError(t, err) + assert.Empty(t, diff.List()) +} + +func TestIsDotGitFolder(t *testing.T) { + testCases := []struct { + name string + path string + isDotGitFolder bool + }{ + { + name: ".git folder", + path: "/foo/bar/.git", + isDotGitFolder: true, + }, + { + name: "subfolder of .git folder", + path: "/foo/.git/bar/zoo", + isDotGitFolder: true, + }, + { + name: "subfolder of .gitignore folder", + path: "/foo/.gitignore/bar", + isDotGitFolder: false, + }, + { + name: ".gitignore file", + path: "foo/bar/.gitignore", + isDotGitFolder: false, + }, + { + name: ".gitlab-ci.yml under .git folder", + path: "/foo/.git/bar/.gitignore", + isDotGitFolder: true, + }, + { + name: "windows path with .git folder", + path: "c:/foo/.git/bar", + isDotGitFolder: true, + }, + { + name: "windows path with .gitignore file", + path: "d:/foo/bar/.gitignore", + isDotGitFolder: false, + }, + } + + for i := range testCases { + test := testCases[i] + t.Run(test.name, func(t *testing.T) { + assert.Equal(t, test.isDotGitFolder, IsDotGitFolder(test.path)) + }) + } +}