Walk is the main recursive implementation of fast walk. Sends the file/dir and any contents to the channel so long as it passes the include/exclude filter. Increments waitg.Add(1) for each new goroutine launched internally workDir - Relative path inside the repository
(isRoot bool, workDir string, itemFi os.FileInfo, excludePaths []filepathfilter.Pattern)
| 329 | // |
| 330 | // workDir - Relative path inside the repository |
| 331 | func (w *fastWalker) Walk(isRoot bool, workDir string, itemFi os.FileInfo, |
| 332 | excludePaths []filepathfilter.Pattern) { |
| 333 | |
| 334 | var fullPath string // Absolute path to the current file or dir |
| 335 | var parentWorkDir string // Absolute path to the workDir inside the repository |
| 336 | if isRoot { |
| 337 | fullPath = w.rootDir |
| 338 | } else { |
| 339 | parentWorkDir = join(w.rootDir, workDir) |
| 340 | fullPath = join(parentWorkDir, itemFi.Name()) |
| 341 | } |
| 342 | |
| 343 | if !isRoot && itemFi.IsDir() { |
| 344 | // If this directory has a .git directory or file in it, then |
| 345 | // this is a submodule, and we should not recurse into it. |
| 346 | _, err := os.Stat(filepath.Join(fullPath, ".git")) |
| 347 | if err == nil { |
| 348 | return |
| 349 | } |
| 350 | } |
| 351 | |
| 352 | workPath := join(workDir, itemFi.Name()) |
| 353 | if !filepathfilter.NewFromPatterns(nil, excludePaths).Allows(workPath) { |
| 354 | return |
| 355 | } |
| 356 | |
| 357 | w.ch <- fastWalkInfo{ParentDir: parentWorkDir, Info: itemFi} |
| 358 | |
| 359 | if !itemFi.IsDir() { |
| 360 | // Nothing more to do if this is not a dir |
| 361 | return |
| 362 | } |
| 363 | |
| 364 | var childWorkDir string |
| 365 | if !isRoot { |
| 366 | childWorkDir = join(workDir, itemFi.Name()) |
| 367 | } |
| 368 | |
| 369 | // The absolute optimal way to scan would be File.Readdirnames but we |
| 370 | // still need the Stat() to know whether something is a dir, so use |
| 371 | // File.Readdir instead. Means we can provide os.FileInfo to callers like |
| 372 | // filepath.Walk as a bonus. |
| 373 | df, err := os.Open(fullPath) |
| 374 | if err != nil { |
| 375 | w.ch <- fastWalkInfo{Err: err} |
| 376 | return |
| 377 | } |
| 378 | |
| 379 | // The number of items in a dir we process in each goroutine |
| 380 | jobSize := 100 |
| 381 | for children, err := df.Readdir(jobSize); err == nil; children, err = df.Readdir(jobSize) { |
| 382 | // Parallelise all dirs, and chop large dirs into batches |
| 383 | w.walk(children, func(subitems []os.FileInfo) { |
| 384 | for _, childFi := range subitems { |
| 385 | w.Walk(false, childWorkDir, childFi, excludePaths) |
| 386 | } |
| 387 | }) |
| 388 | } |