github.com/git-ogawa/go-dbyml@v1.2.1/dbyml/dockerignore.go (about) 1 package dbyml 2 3 import ( 4 "bufio" 5 "bytes" 6 "fmt" 7 "io" 8 "io/fs" 9 "os" 10 "path" 11 "path/filepath" 12 "strings" 13 ) 14 15 // ReadDockerignore reads exclude files from .dockerignore. 16 // If not exists, return empty list. 17 func ReadDockerignore(dir string) ([]string, error) { 18 excludes := []string{} 19 reader, err := SearchDockerignore(dir) 20 if err != nil { 21 return nil, err 22 } 23 24 if reader != nil { 25 exclude, err := ReadAll(reader) 26 if err != nil { 27 return excludes, err 28 } 29 excludes = append(excludes, exclude...) 30 } 31 return excludes, nil 32 } 33 34 // SearchDockerignore searches .dockerignore exists in a given directory. 35 // If exists, return the io.Reader of the .dockerignore, otherwise return nil. 36 func SearchDockerignore(dir string) (io.Reader, error) { 37 var ignore string 38 if err := filepath.Walk(dir, func(file string, info fs.FileInfo, err error) error { 39 if path.Base(file) == ".dockerignore" { 40 ignore = file 41 } 42 return nil 43 }); err != nil { 44 return nil, err 45 } 46 47 if ignore == "" { 48 return nil, nil 49 } 50 51 f, err := os.Open(ignore) 52 return f, err 53 } 54 55 // ReadAll reads a .dockerignore file and returns the list of file patterns 56 // to ignore. Note this will trim whitespace from each line as well 57 // as use GO's "clean" func to get the shortest/cleanest path for each. 58 func ReadAll(reader io.Reader) ([]string, error) { 59 if reader == nil { 60 return nil, nil 61 } 62 63 scanner := bufio.NewScanner(reader) 64 var excludes []string 65 currentLine := 0 66 67 utf8bom := []byte{0xEF, 0xBB, 0xBF} 68 for scanner.Scan() { 69 scannedBytes := scanner.Bytes() 70 // We trim UTF8 BuildkitdTomlTemplate 71 if currentLine == 0 { 72 scannedBytes = bytes.TrimPrefix(scannedBytes, utf8bom) 73 } 74 pattern := string(scannedBytes) 75 currentLine++ 76 // Lines starting with # (comments) are ignored before processing 77 if strings.HasPrefix(pattern, "#") { 78 continue 79 } 80 pattern = strings.TrimSpace(pattern) 81 if pattern == "" { 82 continue 83 } 84 // normalize absolute paths to paths relative to the context 85 // (taking care of '!' prefix) 86 invert := pattern[0] == '!' 87 if invert { 88 pattern = strings.TrimSpace(pattern[1:]) 89 } 90 if len(pattern) > 0 { 91 pattern = filepath.Clean(pattern) 92 pattern = filepath.ToSlash(pattern) 93 if len(pattern) > 1 && pattern[0] == '/' { 94 pattern = pattern[1:] 95 } 96 } 97 if invert { 98 pattern = "!" + pattern 99 } 100 101 excludes = append(excludes, pattern) 102 } 103 if err := scanner.Err(); err != nil { 104 return nil, fmt.Errorf("Error reading .dockerignore: %v", err) 105 } 106 return excludes, nil 107 }