Skip to content

Commit

Permalink
dockerignore: tweak the directory-skipping optimization
Browse files Browse the repository at this point in the history
fixes #6129

Signed-off-by: Nick Santos <[email protected]>
  • Loading branch information
nicks committed Jun 9, 2023
1 parent 541352d commit 5b03556
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 1 deletion.
25 changes: 25 additions & 0 deletions internal/build/tar_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,31 @@ func TestArchiveException(t *testing.T) {
f.assertFileInTar(actual, expectedFile{Path: "target/foo.txt", Contents: "bar"})
}

func TestArchiveAllGoFiles(t *testing.T) {
f := newFixture(t)

filter, err := dockerignore.NewDockerPatternMatcher(f.Path(),
[]string{"*", "!pkg/**/*.go"})
require.NoError(t, err)

buf := new(bytes.Buffer)
ab := NewArchiveBuilder(buf, filter)
defer ab.Close()

f.WriteFile("pkg/internal/somemodule/foo.go", "bar")

paths := []PathMapping{{LocalPath: f.Path(), ContainerPath: "/"}}

err = ab.ArchivePathsIfExist(f.ctx, paths)
if err != nil {
f.t.Fatal(err)
}

actual := tar.NewReader(buf)
f.assertFileInTar(actual,
expectedFile{Path: "pkg/internal/somemodule/foo.go", Contents: "bar"})
}

// Write a file continuously, and make sure we don't get tar errors.
func TestRapidWrite(t *testing.T) {
f := newFixture(t)
Expand Down
44 changes: 43 additions & 1 deletion internal/dockerignore/ignore.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,58 @@ func (i dockerPathMatcher) MatchesEntireDir(f string) (bool, error) {
if !pattern.Exclusion() {
continue
}
if ospath.IsChild(f, pattern.String()) {

// An exclusion pattern handles the case where the user
// does something like:
//
// *
// !path/to/include
// !pkg/**/*.go
//
// where they ignore all files and select the files
// they want to exclude.
//
// Because MatchesEntireDir is an optimization, we err
// on the side of crawling too much.
patternString := pattern.String()

// Handle the case where the pattern matches a subfile of the
// current directory.
if ospath.IsChild(f, patternString) {
// Found an exclusion match -- we don't match this whole dir
return false, nil
}

// Handle the case where the pattern has a glob that matches
// arbitrary files, and the glob could match a subfile of
// the current directory.
prefix := definitePatternPrefix(patternString)
if prefix != patternString && ospath.IsChild(prefix, f) {
return false, nil
}
}
return true, nil
}
return true, nil
}

// Truncate the pattern to just the prefxi that's a concrete directory.
func definitePatternPrefix(p string) string {
if !strings.Contains(p, "*") {
return p
}
parts := strings.Split(p, string(filepath.Separator))
for i, part := range parts {
if strings.Contains(part, "*") {
if i == 0 {
return "."
}
return strings.Join(parts[0:i], string(filepath.Separator))
}
}
return p
}

func NewDockerIgnoreTester(repoRoot string) (*dockerPathMatcher, error) {
absRoot, err := filepath.Abs(repoRoot)
if err != nil {
Expand Down
13 changes: 13 additions & 0 deletions internal/dockerignore/ignore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,19 @@ func TestOrthogonalException(t *testing.T) {
tf.AssertResultEntireDir(tf.JoinPath("b"), false)
}

func TestOnlyGoFiles(t *testing.T) {
tf := newTestFixture(t, "*", "!pkg/**/*.go", "!go.mod", "!go.sum")
tf.AssertResult(tf.JoinPath("pkg", "hello.txt"), true)
tf.AssertResult(tf.JoinPath("pkg", "internal", "hello.txt"), true)
tf.AssertResult(tf.JoinPath("pkg", "internal", "module", "hello.txt"), true)
tf.AssertResult(tf.JoinPath("pkg", "hello.go"), false)
tf.AssertResult(tf.JoinPath("pkg", "internal", "hello.go"), false)
tf.AssertResult(tf.JoinPath("pkg", "internal", "module", "hello.go"), false)
tf.AssertResultEntireDir(tf.JoinPath("pkg"), false)
tf.AssertResultEntireDir(tf.JoinPath("pkg", "internal"), false)
tf.AssertResultEntireDir(tf.JoinPath("pkg", "internal", "module"), false)
}

func TestNoDockerignoreFile(t *testing.T) {
tf := newTestFixture(t)
tf.AssertResult(tf.JoinPath("hi"), false)
Expand Down

0 comments on commit 5b03556

Please sign in to comment.