According to documentation (https://docs.docker.com/engine/reference/builder/#dockerignore-file), absolute paths like `/foo/bar` should have the same effect as `foo/bar`. This is not the case today.
This fix normalize paths when reading the .dockerignore file by removing
leading slashes.
Signed-off-by: Simon Ferquel <simon.ferquel@docker.com>
| ... | ... |
@@ -38,8 +38,23 @@ func ReadAll(reader io.Reader) ([]string, error) {
|
| 38 | 38 |
if pattern == "" {
|
| 39 | 39 |
continue |
| 40 | 40 |
} |
| 41 |
- pattern = filepath.Clean(pattern) |
|
| 42 |
- pattern = filepath.ToSlash(pattern) |
|
| 41 |
+ // normalize absolute paths to paths relative to the context |
|
| 42 |
+ // (taking care of '!' prefix) |
|
| 43 |
+ invert := pattern[0] == '!' |
|
| 44 |
+ if invert {
|
|
| 45 |
+ pattern = strings.TrimSpace(pattern[1:]) |
|
| 46 |
+ } |
|
| 47 |
+ if len(pattern) > 0 {
|
|
| 48 |
+ pattern = filepath.Clean(pattern) |
|
| 49 |
+ pattern = filepath.ToSlash(pattern) |
|
| 50 |
+ if len(pattern) > 1 && pattern[0] == '/' {
|
|
| 51 |
+ pattern = pattern[1:] |
|
| 52 |
+ } |
|
| 53 |
+ } |
|
| 54 |
+ if invert {
|
|
| 55 |
+ pattern = "!" + pattern |
|
| 56 |
+ } |
|
| 57 |
+ |
|
| 43 | 58 |
excludes = append(excludes, pattern) |
| 44 | 59 |
} |
| 45 | 60 |
if err := scanner.Err(); err != nil {
|
| ... | ... |
@@ -25,7 +25,7 @@ func TestReadAll(t *testing.T) {
|
| 25 | 25 |
} |
| 26 | 26 |
|
| 27 | 27 |
diName := filepath.Join(tmpDir, ".dockerignore") |
| 28 |
- content := fmt.Sprintf("test1\n/test2\n/a/file/here\n\nlastfile")
|
|
| 28 |
+ content := fmt.Sprintf("test1\n/test2\n/a/file/here\n\nlastfile\n# this is a comment\n! /inverted/abs/path\n!\n! \n")
|
|
| 29 | 29 |
err = ioutil.WriteFile(diName, []byte(content), 0777) |
| 30 | 30 |
if err != nil {
|
| 31 | 31 |
t.Fatal(err) |
| ... | ... |
@@ -42,16 +42,28 @@ func TestReadAll(t *testing.T) {
|
| 42 | 42 |
t.Fatal(err) |
| 43 | 43 |
} |
| 44 | 44 |
|
| 45 |
+ if len(di) != 7 {
|
|
| 46 |
+ t.Fatalf("Expected 5 entries, got %v", len(di))
|
|
| 47 |
+ } |
|
| 45 | 48 |
if di[0] != "test1" {
|
| 46 | 49 |
t.Fatal("First element is not test1")
|
| 47 | 50 |
} |
| 48 |
- if di[1] != "/test2" {
|
|
| 49 |
- t.Fatal("Second element is not /test2")
|
|
| 51 |
+ if di[1] != "test2" { // according to https://docs.docker.com/engine/reference/builder/#dockerignore-file, /foo/bar should be treated as foo/bar
|
|
| 52 |
+ t.Fatal("Second element is not test2")
|
|
| 50 | 53 |
} |
| 51 |
- if di[2] != "/a/file/here" {
|
|
| 52 |
- t.Fatal("Third element is not /a/file/here")
|
|
| 54 |
+ 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
|
|
| 55 |
+ t.Fatal("Third element is not a/file/here")
|
|
| 53 | 56 |
} |
| 54 | 57 |
if di[3] != "lastfile" {
|
| 55 | 58 |
t.Fatal("Fourth element is not lastfile")
|
| 56 | 59 |
} |
| 60 |
+ if di[4] != "!inverted/abs/path" {
|
|
| 61 |
+ t.Fatal("Fifth element is not !inverted/abs/path")
|
|
| 62 |
+ } |
|
| 63 |
+ if di[5] != "!" {
|
|
| 64 |
+ t.Fatalf("Sixth element is not !, but %s", di[5])
|
|
| 65 |
+ } |
|
| 66 |
+ if di[6] != "!" {
|
|
| 67 |
+ t.Fatalf("Sixth element is not !, but %s", di[6])
|
|
| 68 |
+ } |
|
| 57 | 69 |
} |