func parseIgnoreFile(fd io.Reader, base string) []*regexp.Regexp { var exps []*regexp.Regexp scanner := bufio.NewScanner(fd) for scanner.Scan() { line := strings.TrimSpace(scanner.Text()) if line == "" { continue } if strings.HasPrefix(line, "/") { // Pattern is rooted in the current dir only exp, err := fnmatch.Convert(path.Join(base, line[1:]), fnmatch.FNM_PATHNAME) if err != nil { l.Warnf("Invalid pattern %q in ignore file", line) continue } exps = append(exps, exp) } else if strings.HasPrefix(line, "**/") { // Add the pattern as is, and without **/ so it matches in current dir exp, err := fnmatch.Convert(line, fnmatch.FNM_PATHNAME) if err != nil { l.Warnf("Invalid pattern %q in ignore file", line) continue } exps = append(exps, exp) exp, err = fnmatch.Convert(path.Join(base, line[3:]), fnmatch.FNM_PATHNAME) if err != nil { l.Warnf("Invalid pattern %q in ignore file", line) continue } exps = append(exps, exp) } else { // Path name or pattern, add it so it matches files both in // current directory and subdirs. exp, err := fnmatch.Convert(path.Join(base, line), fnmatch.FNM_PATHNAME) if err != nil { l.Warnf("Invalid pattern %q in ignore file", line) continue } exps = append(exps, exp) exp, err = fnmatch.Convert(path.Join(base, "**", line), fnmatch.FNM_PATHNAME) if err != nil { l.Warnf("Invalid pattern %q in ignore file", line) continue } exps = append(exps, exp) } } return exps }
func parseIgnoreFile(fd io.Reader, currentFile string, seen map[string]bool) (Patterns, error) { var exps Patterns addPattern := func(line string) error { include := true if strings.HasPrefix(line, "!") { line = line[1:] include = false } if strings.HasPrefix(line, "/") { // Pattern is rooted in the current dir only exp, err := fnmatch.Convert(line[1:], fnmatch.FNM_PATHNAME) if err != nil { return fmt.Errorf("Invalid pattern %q in ignore file", line) } exps = append(exps, Pattern{exp, include}) } else if strings.HasPrefix(line, "**/") { // Add the pattern as is, and without **/ so it matches in current dir exp, err := fnmatch.Convert(line, fnmatch.FNM_PATHNAME) if err != nil { return fmt.Errorf("Invalid pattern %q in ignore file", line) } exps = append(exps, Pattern{exp, include}) exp, err = fnmatch.Convert(line[3:], fnmatch.FNM_PATHNAME) if err != nil { return fmt.Errorf("Invalid pattern %q in ignore file", line) } exps = append(exps, Pattern{exp, include}) } else if strings.HasPrefix(line, "#include ") { includeFile := filepath.Join(filepath.Dir(currentFile), line[len("#include "):]) includes, err := loadIgnoreFile(includeFile, seen) if err != nil { return err } else { exps = append(exps, includes...) } } else { // Path name or pattern, add it so it matches files both in // current directory and subdirs. exp, err := fnmatch.Convert(line, fnmatch.FNM_PATHNAME) if err != nil { return fmt.Errorf("Invalid pattern %q in ignore file", line) } exps = append(exps, Pattern{exp, include}) exp, err = fnmatch.Convert("**/"+line, fnmatch.FNM_PATHNAME) if err != nil { return fmt.Errorf("Invalid pattern %q in ignore file", line) } exps = append(exps, Pattern{exp, include}) } return nil } scanner := bufio.NewScanner(fd) var err error for scanner.Scan() { line := strings.TrimSpace(scanner.Text()) switch { case line == "": continue case strings.HasPrefix(line, "#"): err = addPattern(line) case strings.HasSuffix(line, "/**"): err = addPattern(line) case strings.HasSuffix(line, "/"): err = addPattern(line) if err == nil { err = addPattern(line + "**") } default: err = addPattern(line) if err == nil { err = addPattern(line + "/**") } } if err != nil { return nil, err } } return exps, nil }
func parseIgnoreFile(fd io.Reader, base, currentFile string, filesSeen map[string]map[string]bool) []*regexp.Regexp { var exps []*regexp.Regexp scanner := bufio.NewScanner(fd) for scanner.Scan() { line := strings.TrimSpace(scanner.Text()) if line == "" { continue } if strings.HasPrefix(line, "/") { // Pattern is rooted in the current dir only exp, err := fnmatch.Convert(path.Join(base, line[1:]), fnmatch.FNM_PATHNAME) if err != nil { l.Warnf("Invalid pattern %q in ignore file", line) continue } exps = append(exps, exp) } else if strings.HasPrefix(line, "**/") { // Add the pattern as is, and without **/ so it matches in current dir exp, err := fnmatch.Convert(line, fnmatch.FNM_PATHNAME) if err != nil { l.Warnf("Invalid pattern %q in ignore file", line) continue } exps = append(exps, exp) exp, err = fnmatch.Convert(path.Join(base, line[3:]), fnmatch.FNM_PATHNAME) if err != nil { l.Warnf("Invalid pattern %q in ignore file", line) continue } exps = append(exps, exp) } else if strings.HasPrefix(line, "#include ") { includeFile := filepath.Join(filepath.Dir(currentFile), strings.Replace(line, "#include ", "", 1)) if _, err := os.Stat(includeFile); os.IsNotExist(err) { l.Infoln("Could not open ignore include file", includeFile) } else { seen := false if seenByCurrent, ok := filesSeen[currentFile]; ok { _, seen = seenByCurrent[includeFile] } if seen { l.Warnf("Recursion detected while including %s from %s", includeFile, currentFile) } else { if filesSeen[currentFile] == nil { filesSeen[currentFile] = make(map[string]bool) } filesSeen[currentFile][includeFile] = true includes := loadIgnoreFile(includeFile, base, filesSeen) exps = append(exps, includes...) } } } else { // Path name or pattern, add it so it matches files both in // current directory and subdirs. exp, err := fnmatch.Convert(path.Join(base, line), fnmatch.FNM_PATHNAME) if err != nil { l.Warnf("Invalid pattern %q in ignore file", line) continue } exps = append(exps, exp) exp, err = fnmatch.Convert(path.Join(base, "**", line), fnmatch.FNM_PATHNAME) if err != nil { l.Warnf("Invalid pattern %q in ignore file", line) continue } exps = append(exps, exp) } } return exps }