-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
86 lines (72 loc) · 2.02 KB
/
main.go
File metadata and controls
86 lines (72 loc) · 2.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package main
import (
"flag"
"fmt"
"io"
"os"
"path/filepath"
"time"
)
func main() {
os.Exit(realMain(time.Now(), os.Args[1:], os.UserConfigDir, os.Stdout, os.Stderr))
}
// realMain does all the work and can more easily be the target of testing
func realMain(start time.Time, args []string, confFunc userConfigDirFunc, stdout, stderr io.Writer) int {
fs := flag.NewFlagSet(Name, flag.ContinueOnError)
fs.SetOutput(stderr)
fs.Usage = func() { fmt.Fprintln(stderr, "Consider -h for option details") }
cfg := newConfig(fs, confFunc)
err := cfg.loadDefaults() // Load early so setFlags see revised defaults
if err != nil { // Config load errors only generate warnings
fmt.Fprintln(stderr, "Warning:", err)
}
cfg.setFlags()
err = fs.Parse(args)
if err != nil {
return EX_USAGE
}
// Documentation requests usurp all scanning options
if cfg.help {
printUsage(stdout, stderr, false, fs, cfg)
return EX_OK
}
if cfg.version {
printVersion(stdout)
return EX_OK
}
if cfg.manpage {
fmt.Fprint(stdout, Manpage)
return EX_OK
}
// We're actually going to run a scan
err = cfg.compile()
if err != nil {
fmt.Fprintln(stderr, err)
return EX_USAGE
}
scanList := fs.Args()
if len(scanList) == 0 { // If none supplied, scan current working directory.
scanList = append(scanList, ".")
}
allCandidates := newCandidates(int(cfg.maxCount.v), cfg.maxAge)
cc := newConcurrencyController(int(cfg.maxScanners.v))
scn := newScanner(cfg, cc, allCandidates, start, stderr)
for _, dirName := range scanList {
dirName = filepath.Clean(dirName) // Clean here so we can avoid .Join/Clean later
scn.descend(0, dirName) // Runs a goroutine
}
scn.wait() // Wait for all goroutines started by scn.descend()
// Sort and print
scn.allCandidates.sortAscending()
end := time.Now()
secs := end.Sub(start)
scn.printCandidates(stdout)
if scn.cfg.printStats.v {
scn.printStats(stdout, secs)
}
// If any access errors occurred, exit non-zero
if scn.stats.errorCount > 0 {
return EX_OSFILE
}
return EX_OK
}