Skip to content

Commit

Permalink
integrate frontend/dockerfile/dockerignore from buildkit
Browse files Browse the repository at this point in the history
Integrating the "frontend/dockerfile/dockerignore" package from
github.com/moby/buildkit at commit 9da03ce42beb47d0d0a34c68ea90cac793b79851

Steps taken:

    # install filter-repo (https://github.com/newren/git-filter-repo/blob/main/INSTALL.md)
    brew install git-filter-repo

    # create a temporary clone of docker
    cd ~/Projects
    git clone https://github.com/moby/buildkit.git buildkit_temp
    cd buildkit_temp

    # commit taken from
    git rev-parse --verify HEAD
    9da03ce42beb47d0d0a34c68ea90cac793b79851

    # remove all code, except for 'frontend/dockerfile/dockerignore', and rename to /ignorefile
    git filter-repo \
      --path-match 'frontend/dockerfile/dockerignore/' \
      --path-rename frontend/dockerfile/dockerignore/dockerignore.go:ignorefile/ignorefile.go \
      --path-rename frontend/dockerfile/dockerignore/dockerignore_test.go:ignorefile/ignorefile_test.go

    # go to the target github.com/moby/patternmatcher repository
    cd ~/go/src/github.com/moby/patternmatcher

    # create a branch to work with
    git checkout -b integrate_dockerignore

    # add the temporary repository as an upstream and make sure it's up-to-date
    git remote add buildkit_temp ~/Projects/buildkit_temp
    git fetch buildkit_temp

    # merge the upstream code
    git merge --allow-unrelated-histories --signoff -S buildkit_temp/master

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
  • Loading branch information
thaJeztah committed Jul 30, 2023
2 parents 8a1649d + 666020c commit 36a4227
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 0 deletions.
73 changes: 73 additions & 0 deletions ignorefile/ignorefile.go
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
}
54 changes: 54 additions & 0 deletions ignorefile/ignorefile_test.go
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])
}
}
}

0 comments on commit 36a4227

Please sign in to comment.