-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from thaJeztah/integrate_dockerignore
integrate frontend/dockerfile/dockerignore from BuildKit
- Loading branch information
Showing
2 changed files
with
127 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package ignorefile | ||
|
||
import ( | ||
"bufio" | ||
"bytes" | ||
"io" | ||
"path/filepath" | ||
"strings" | ||
) | ||
|
||
// ReadAll reads an ignore file from a reader and returns the list of file | ||
// patterns to ignore, applying the following rules: | ||
// | ||
// - An UTF8 BOM header (if present) is stripped. | ||
// - Lines starting with "#" are considered comments and are skipped. | ||
// | ||
// For remaining lines: | ||
// | ||
// - Leading and trailing whitespace is removed from each ignore pattern. | ||
// - It uses [filepath.Clean] to get the shortest/cleanest path for | ||
// ignore patterns. | ||
// - Leading forward-slashes ("/") are removed from ignore patterns, | ||
// so "/some/path" and "some/path" are considered equivalent. | ||
func ReadAll(reader io.Reader) ([]string, error) { | ||
if reader == nil { | ||
return nil, nil | ||
} | ||
|
||
var excludes []string | ||
currentLine := 0 | ||
utf8bom := []byte{0xEF, 0xBB, 0xBF} | ||
|
||
scanner := bufio.NewScanner(reader) | ||
for scanner.Scan() { | ||
scannedBytes := scanner.Bytes() | ||
// We trim UTF8 BOM | ||
if currentLine == 0 { | ||
scannedBytes = bytes.TrimPrefix(scannedBytes, utf8bom) | ||
} | ||
pattern := string(scannedBytes) | ||
currentLine++ | ||
// Lines starting with # (comments) are ignored before processing | ||
if strings.HasPrefix(pattern, "#") { | ||
continue | ||
} | ||
pattern = strings.TrimSpace(pattern) | ||
if pattern == "" { | ||
continue | ||
} | ||
// 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 { | ||
return nil, err | ||
} | ||
return excludes, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package ignorefile | ||
|
||
import ( | ||
"strings" | ||
"testing" | ||
) | ||
|
||
func TestReadAll(t *testing.T) { | ||
actual, err := ReadAll(nil) | ||
if err != nil { | ||
t.Errorf("Expected no error, got %v", err) | ||
} | ||
if entries := len(actual); entries != 0 { | ||
t.Fatalf("Expected to have zero entries, got %d", entries) | ||
} | ||
|
||
const content = `test1 | ||
/test2 | ||
/a/file/here | ||
lastfile | ||
# this is a comment | ||
! /inverted/abs/path | ||
! | ||
! ` | ||
|
||
expected := []string{ | ||
"test1", | ||
"test2", // according to https://docs.docker.com/engine/reference/builder/#dockerignore-file, /foo/bar should be treated as foo/bar | ||
"a/file/here", // according to https://docs.docker.com/engine/reference/builder/#dockerignore-file, /foo/bar should be treated as foo/bar | ||
"lastfile", | ||
"!inverted/abs/path", | ||
"!", | ||
"!", | ||
} | ||
|
||
actual, err = ReadAll(strings.NewReader(content)) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
|
||
if len(actual) != len(expected) { | ||
t.Errorf("Expected %d entries, got %v", len(expected), len(actual)) | ||
} | ||
for i, expectedLine := range expected { | ||
if i >= len(actual) { | ||
t.Errorf(`missing line %d: expected: "%s", got none`, i+1, expectedLine) | ||
continue | ||
} | ||
if actual[i] != expectedLine { | ||
t.Errorf(`line %d: expected: "%s", got: "%s"`, i+1, expectedLine, actual[i]) | ||
} | ||
} | ||
} |