diff --git a/initrd/directory.go b/initrd/directory.go index 54c3a187c7..6af78f7caf 100644 --- a/initrd/directory.go +++ b/initrd/directory.go @@ -75,11 +75,35 @@ func (initrd *directory) Build(ctx context.Context) (string, error) { writer := cpio.NewWriter(f) defer writer.Close() + ignoringItems, err := getKraftignoreItems(initrd) + if err != nil { + return "", err + } + + // **If the function returns the special value SkipDir, Walk skips the current directory (path if info.IsDir() is true, + // otherwise path's parent directory). If the function returns the special value SkipAll, Walk skips all remaining files and directories. + // Otherwise, if the function returns a non-nil error, Walk stops entirely and returns that error. + // Returning `nil` from the funtion make WalkDir() to work as `continue`.** if err := filepath.WalkDir(initrd.path, func(path string, d fs.DirEntry, err error) error { if err != nil { return fmt.Errorf("received error before parsing path: %w", err) } + if len(ignoringItems) > 0 { + str, err := isExistInKraftignoreFile(path, ignoringItems) + if err != nil { + return err + } + switch str { + case "SkipDir": + return filepath.SkipDir + case "SkipAll": + return filepath.SkipAll + case "Exist": + return nil + } + } + internal := strings.TrimPrefix(path, filepath.Clean(initrd.path)) internal = filepath.ToSlash(internal) if internal == "" { diff --git a/initrd/kraftignore.go b/initrd/kraftignore.go new file mode 100644 index 0000000000..84e80a3334 --- /dev/null +++ b/initrd/kraftignore.go @@ -0,0 +1,63 @@ +package initrd + +import ( + "bufio" + "errors" + "os" + "path/filepath" + "strings" +) + +// kraftignore filename +const KraftignoreFileName = ".kraftignore" + +func getKraftignoreItems(initrd *directory) ([]string, error) { + if initrd.opts.kraftignorePath == "" { + cwd, err := os.Getwd() + if err != nil { + return []string{}, err + } + initrd.opts.kraftignorePath = filepath.Join(cwd, KraftignoreFileName) + } + + if _, err := os.Stat(initrd.opts.kraftignorePath); errors.Is(err, os.ErrNotExist) { + return []string{}, nil + } else if err != nil { + return []string{}, err + } + + kraftignoreFile, err := os.Open(initrd.opts.kraftignorePath) + defer kraftignoreFile.Close() + + if err != nil { + return []string{}, err + } + kraftignoreScanner := bufio.NewScanner(kraftignoreFile) + kraftignoreScanner.Split(bufio.ScanLines) + var kraftignoreFileLines, ignoringItems []string + + for kraftignoreScanner.Scan() { + kraftignoreFileLines = append(kraftignoreFileLines, kraftignoreScanner.Text()) + } + + for _, line := range kraftignoreFileLines { + line = strings.TrimSpace(line) + if line == "" || strings.HasPrefix(line, "#") { + continue + } + items := strings.Split(line, " ") + for _, item := range items { + item = strings.TrimSpace(item) + if item == "" { + continue + } + ignoringItems = append(ignoringItems, item) + } + } + return ignoringItems, nil +} + +func isExistInKraftignoreFile(path string, kraftignoreItems []string) (string, error) { + // Write code here + return "", nil +} diff --git a/initrd/options.go b/initrd/options.go index b4967bdc53..c8fcda9069 100644 --- a/initrd/options.go +++ b/initrd/options.go @@ -4,9 +4,14 @@ // You may not use this file except in compliance with the License. package initrd +import ( + "path/filepath" +) + type InitrdOptions struct { - output string - cacheDir string + output string + cacheDir string + kraftignorePath string } type InitrdOption func(*InitrdOptions) error @@ -29,3 +34,11 @@ func WithCacheDir(dir string) InitrdOption { return nil } } + +// WithKraftignorePath sets the path for .kraftignore. +func WithKraftignorePath(dir string) InitrdOption { + return func(opts *InitrdOptions) error { + opts.kraftignorePath = filepath.Join(dir, KraftignoreFileName) + return nil + } +}