Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use a local Walk function #421

Merged
merged 17 commits into from
Oct 29, 2019
55 changes: 54 additions & 1 deletion arduino/builder/sketch.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,16 @@ import (

"github.com/arduino/arduino-cli/arduino/globals"
"github.com/arduino/arduino-cli/arduino/sketch"
"github.com/arduino/arduino-cli/cli/errorcodes"
"github.com/arduino/arduino-cli/cli/feedback"

"github.com/pkg/errors"
)

// As currently implemented on Linux,
// the maximum number of symbolic links that will be followed while resolving a pathname is 40
const maxFileSystemDepth = 40

var includesArduinoH = regexp.MustCompile(`(?m)^\s*#\s*include\s*[<\"]Arduino\.h[>\"]`)

// QuoteCppString returns the given string as a quoted string for use with the C
Expand Down Expand Up @@ -58,6 +64,39 @@ func SketchSaveItemCpp(item *sketch.Item, destPath string) error {
return nil
}

// simpleLocalWalk locally replaces filepath.Walk and/but goes through symlinks
func simpleLocalWalk(root string, maxDepth int, walkFn func(path string, info os.FileInfo, err error) error) error {

info, err := os.Stat(root)

if err != nil {
return walkFn(root, nil, err)
}

err = walkFn(root, info, err)
if err == filepath.SkipDir {
return nil
}

if info.IsDir() {
if maxDepth <= 0 {
return walkFn(root, info, errors.New("Filesystem bottom is too deep (directory recursion or filesystem really deep): "+root))
}
maxDepth--
files, err := ioutil.ReadDir(root)
if err == nil {
for _, file := range files {
err = simpleLocalWalk(root+string(os.PathSeparator)+file.Name(), maxDepth, walkFn)
if err == filepath.SkipDir {
return nil
}
}
}
}

return nil
}

// SketchLoad collects all the files composing a sketch.
// The parameter `sketchPath` holds a path pointing to a single sketch file or a sketch folder,
// the path must be absolute.
Expand All @@ -79,14 +118,28 @@ func SketchLoad(sketchPath, buildPath string) (*sketch.Sketch, error) {
return nil, errors.Wrap(err, "unable to find the main sketch file")
}
f.Close()
// ensure it is not a directory
info, err := os.Stat(mainSketchFile)
if err != nil {
return nil, errors.Wrap(err, "unable to check the main sketch file")
}
if info.IsDir() {
return nil, errors.Wrap(errors.New(mainSketchFile), "sketch must not be a directory")
}
} else {
sketchFolder = filepath.Dir(sketchPath)
mainSketchFile = sketchPath
}

// collect all the sketch files
var files []string
err = filepath.Walk(sketchFolder, func(path string, info os.FileInfo, err error) error {
err = simpleLocalWalk(sketchFolder, maxFileSystemDepth, func(path string, info os.FileInfo, err error) error {

if err != nil {
feedback.Errorf("Error during sketch processing: %v", err)
os.Exit(errorcodes.ErrGeneric)
}

// ignore hidden files and skip hidden directories
if strings.HasPrefix(info.Name(), ".") {
if info.IsDir() {
Expand Down