Merge pull request #1577 from orisano/1576-improve-validate-context-directory
feat: improves ValidateContextDirectory performance
This commit is contained in:
commit
f28d078426
@ -41,6 +41,12 @@ func ValidateContextDirectory(srcPath string, excludes []string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pm, err := fileutils.NewPatternMatcher(excludes)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return filepath.Walk(contextRoot, func(filePath string, f os.FileInfo, err error) error {
|
return filepath.Walk(contextRoot, func(filePath string, f os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsPermission(err) {
|
if os.IsPermission(err) {
|
||||||
@ -55,7 +61,7 @@ func ValidateContextDirectory(srcPath string, excludes []string) error {
|
|||||||
// skip this directory/file if it's not in the path, it won't get added to the context
|
// skip this directory/file if it's not in the path, it won't get added to the context
|
||||||
if relFilePath, err := filepath.Rel(contextRoot, filePath); err != nil {
|
if relFilePath, err := filepath.Rel(contextRoot, filePath); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if skip, err := fileutils.Matches(relFilePath, excludes); err != nil {
|
} else if skip, err := filepathMatches(pm, relFilePath); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if skip {
|
} else if skip {
|
||||||
if f.IsDir() {
|
if f.IsDir() {
|
||||||
@ -81,6 +87,15 @@ func ValidateContextDirectory(srcPath string, excludes []string) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func filepathMatches(matcher *fileutils.PatternMatcher, file string) (bool, error) {
|
||||||
|
file = filepath.Clean(file)
|
||||||
|
if file == "." {
|
||||||
|
// Don't let them exclude everything, kind of silly.
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return matcher.Matches(file)
|
||||||
|
}
|
||||||
|
|
||||||
// DetectArchiveReader detects whether the input stream is an archive or a
|
// DetectArchiveReader detects whether the input stream is an archive or a
|
||||||
// Dockerfile and returns a buffered version of input, safe to consume in lieu
|
// Dockerfile and returns a buffered version of input, safe to consume in lieu
|
||||||
// of input. If an archive is detected, isArchive is set to true, and to false
|
// of input. If an archive is detected, isArchive is set to true, and to false
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/archive"
|
"github.com/docker/docker/pkg/archive"
|
||||||
|
"github.com/docker/docker/pkg/fileutils"
|
||||||
"gotest.tools/assert"
|
"gotest.tools/assert"
|
||||||
is "gotest.tools/assert/cmp"
|
is "gotest.tools/assert/cmp"
|
||||||
)
|
)
|
||||||
@ -330,3 +331,86 @@ func TestDetectArchiveReader(t *testing.T) {
|
|||||||
assert.Check(t, is.Equal(testcase.expected, isArchive), testcase.file)
|
assert.Check(t, is.Equal(testcase.expected, isArchive), testcase.file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func mustPatternMatcher(t *testing.T, patterns []string) *fileutils.PatternMatcher {
|
||||||
|
t.Helper()
|
||||||
|
pm, err := fileutils.NewPatternMatcher(patterns)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("failed to construct pattern matcher: ", err)
|
||||||
|
}
|
||||||
|
return pm
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWildcardMatches(t *testing.T) {
|
||||||
|
match, _ := filepathMatches(mustPatternMatcher(t, []string{"*"}), "fileutils.go")
|
||||||
|
if !match {
|
||||||
|
t.Errorf("failed to get a wildcard match, got %v", match)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A simple pattern match should return true.
|
||||||
|
func TestPatternMatches(t *testing.T) {
|
||||||
|
match, _ := filepathMatches(mustPatternMatcher(t, []string{"*.go"}), "fileutils.go")
|
||||||
|
if !match {
|
||||||
|
t.Errorf("failed to get a match, got %v", match)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// An exclusion followed by an inclusion should return true.
|
||||||
|
func TestExclusionPatternMatchesPatternBefore(t *testing.T) {
|
||||||
|
match, _ := filepathMatches(mustPatternMatcher(t, []string{"!fileutils.go", "*.go"}), "fileutils.go")
|
||||||
|
if !match {
|
||||||
|
t.Errorf("failed to get true match on exclusion pattern, got %v", match)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A folder pattern followed by an exception should return false.
|
||||||
|
func TestPatternMatchesFolderExclusions(t *testing.T) {
|
||||||
|
match, _ := filepathMatches(mustPatternMatcher(t, []string{"docs", "!docs/README.md"}), "docs/README.md")
|
||||||
|
if match {
|
||||||
|
t.Errorf("failed to get a false match on exclusion pattern, got %v", match)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A folder pattern followed by an exception should return false.
|
||||||
|
func TestPatternMatchesFolderWithSlashExclusions(t *testing.T) {
|
||||||
|
match, _ := filepathMatches(mustPatternMatcher(t, []string{"docs/", "!docs/README.md"}), "docs/README.md")
|
||||||
|
if match {
|
||||||
|
t.Errorf("failed to get a false match on exclusion pattern, got %v", match)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A folder pattern followed by an exception should return false.
|
||||||
|
func TestPatternMatchesFolderWildcardExclusions(t *testing.T) {
|
||||||
|
match, _ := filepathMatches(mustPatternMatcher(t, []string{"docs/*", "!docs/README.md"}), "docs/README.md")
|
||||||
|
if match {
|
||||||
|
t.Errorf("failed to get a false match on exclusion pattern, got %v", match)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A pattern followed by an exclusion should return false.
|
||||||
|
func TestExclusionPatternMatchesPatternAfter(t *testing.T) {
|
||||||
|
match, _ := filepathMatches(mustPatternMatcher(t, []string{"*.go", "!fileutils.go"}), "fileutils.go")
|
||||||
|
if match {
|
||||||
|
t.Errorf("failed to get false match on exclusion pattern, got %v", match)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A filename evaluating to . should return false.
|
||||||
|
func TestExclusionPatternMatchesWholeDirectory(t *testing.T) {
|
||||||
|
match, _ := filepathMatches(mustPatternMatcher(t, []string{"*.go"}), ".")
|
||||||
|
if match {
|
||||||
|
t.Errorf("failed to get false match on ., got %v", match)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Matches with no patterns
|
||||||
|
func TestMatchesWithNoPatterns(t *testing.T) {
|
||||||
|
matches, err := filepathMatches(mustPatternMatcher(t, []string{}), "/any/path/there")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if matches {
|
||||||
|
t.Fatalf("Should not have match anything")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user