diff --git a/components/engine/builder/dockerignore/dockerignore.go b/components/engine/builder/dockerignore/dockerignore.go index 2db67be799..cc22381339 100644 --- a/components/engine/builder/dockerignore/dockerignore.go +++ b/components/engine/builder/dockerignore/dockerignore.go @@ -38,8 +38,23 @@ func ReadAll(reader io.Reader) ([]string, error) { if pattern == "" { continue } - pattern = filepath.Clean(pattern) - pattern = filepath.ToSlash(pattern) + // normalize absolute paths to paths relative to the context + // (taking care of '!' prefix) + invert := pattern[0] == '!' + if invert { + pattern = strings.TrimSpace(pattern[1:]) + } + if len(pattern) > 0 { + pattern = filepath.Clean(pattern) + pattern = filepath.ToSlash(pattern) + if len(pattern) > 1 && pattern[0] == '/' { + pattern = pattern[1:] + } + } + if invert { + pattern = "!" + pattern + } + excludes = append(excludes, pattern) } if err := scanner.Err(); err != nil { diff --git a/components/engine/builder/dockerignore/dockerignore_test.go b/components/engine/builder/dockerignore/dockerignore_test.go index 948f9d886b..bda38745cc 100644 --- a/components/engine/builder/dockerignore/dockerignore_test.go +++ b/components/engine/builder/dockerignore/dockerignore_test.go @@ -25,7 +25,7 @@ func TestReadAll(t *testing.T) { } diName := filepath.Join(tmpDir, ".dockerignore") - content := fmt.Sprintf("test1\n/test2\n/a/file/here\n\nlastfile") + content := fmt.Sprintf("test1\n/test2\n/a/file/here\n\nlastfile\n# this is a comment\n! /inverted/abs/path\n!\n! \n") err = ioutil.WriteFile(diName, []byte(content), 0777) if err != nil { t.Fatal(err) @@ -42,16 +42,28 @@ func TestReadAll(t *testing.T) { t.Fatal(err) } + if len(di) != 7 { + t.Fatalf("Expected 5 entries, got %v", len(di)) + } if di[0] != "test1" { t.Fatal("First element is not test1") } - if di[1] != "/test2" { - t.Fatal("Second element is not /test2") + if di[1] != "test2" { // according to https://docs.docker.com/engine/reference/builder/#dockerignore-file, /foo/bar should be treated as foo/bar + t.Fatal("Second element is not test2") } - if di[2] != "/a/file/here" { - t.Fatal("Third element is not /a/file/here") + if di[2] != "a/file/here" { // according to https://docs.docker.com/engine/reference/builder/#dockerignore-file, /foo/bar should be treated as foo/bar + t.Fatal("Third element is not a/file/here") } if di[3] != "lastfile" { t.Fatal("Fourth element is not lastfile") } + if di[4] != "!inverted/abs/path" { + t.Fatal("Fifth element is not !inverted/abs/path") + } + if di[5] != "!" { + t.Fatalf("Sixth element is not !, but %s", di[5]) + } + if di[6] != "!" { + t.Fatalf("Sixth element is not !, but %s", di[6]) + } }