'filepath.Walk() - can i provides rules on which directories not to walk on?

I'm writing a GoLang app using Go 1.7rc1.

now I want to find all go files in a specific path. besides that I want not to walk on some directories.. for example.. hidden directories like .git.

is there a way to provide Walk() with some rules ? or.. is there a diferent libraries that provide these capabilities ?

for now this is my code:

func visit(path string, f os.FileInfo, err error) error {
    fmt.Printf("Visited: %s\n", path)
    return nil
}

func main() {
    filepath.Walk(path,visit)
}

any information regarding the issue would be greatly appreciated. thanks!



Solution 1:[1]

You can skip directories by returning the error filepath.SkipDir from your visit function.

Here's how to skip .git directories:

func visit(path string, f os.FileInfo, err error) error {
    if f.IsDir() && f.Name() == ".git" {
        return filepath.SkipDir
    }
    fmt.Printf("Visited: %s\n", path)
    return nil
}

The test f.IsDir() is required to avoid skipping the remainder of a directory that contains a normal file named ".git".

Solution 2:[2]

This is an example provided by go

https://github.com/golang/go/blob/f229e70/src/path/filepath/example_unix_walk_test.go#L40-L54


If you need more complex filtering, you can use regexp to help you.

Assume the directory is like below

- index.html
- main.go
- ?.git   ------------------------> unwanted all
- ?static   
    - ?css -----------------------> unwanted {*.md}
        - test.bat  ----------------> unwanted
        - styles.css
        - README.md  
    - ?js
        - a.js
        - ?sub
            - b.js
  - ?sass ------------------------> unwanted all
      - main.sass
      - ?src
         - foo.sass
         - bar.sass
package main

import (
    "fmt"
    "log"
    "os"
    "path/filepath"
    "regexp"
    "strings"
)

func main() {
    collectFiles := func(dir string, excludeList []string) (fileList []string, err error) {
        err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
            if regexp.MustCompile(strings.Join(excludeList, "|")).Match([]byte(path)) {
                // fmt.Printf("%s\n", path)
                return nil
            }

            if info.IsDir() {
                return nil
            }

            fileList = append(fileList, path)
            return nil
        })
        if err != nil {
            log.Fatalf("walk error [%v]\n", err)
            return nil, err
        }
        return fileList, nil
    }
    targetFiles, _ := collectFiles(".", []string{
        `.git\.*`,
        `static\\css\\.*\.md`,
        `static\\css\\test.bat`,
        `static\\sass\\.*`,
    })
    fmt.Printf("%v", targetFiles)
}

output

index.html 
main.go 
static\css\styles.css 
static\js\a.js 
static\js\sub\b.js

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2