-
Notifications
You must be signed in to change notification settings - Fork 10
/
main.go
128 lines (113 loc) · 3.49 KB
/
main.go
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// gostatus is a command line tool that shows the status of Go repositories.
package main
import (
"bufio"
"flag"
"fmt"
"log"
"os"
"github.com/kisielk/gotool"
)
// parallelism for workers.
const parallelism = 8
var (
debugFlag = flag.Bool("debug", false, "Cause the repository data to be printed in verbose debug format.")
fFlag = flag.Bool("f", false, "Force not to verify that each package has been checked out from the source control repository implied by its import path. This can be useful if the source is a local fork of the original.")
stdinFlag = flag.Bool("stdin", false, "Read the list of newline separated Go packages from stdin.")
vFlag = flag.Bool("v", false, "Verbose mode. Show all Go packages, not just ones with notable status.")
compactFlag = flag.Bool("c", false, "Compact output with inline notation.")
)
func usage() {
fmt.Fprint(os.Stderr, "Usage: gostatus [flags] [packages]\n")
fmt.Fprint(os.Stderr, " [newline separated packages] | gostatus -stdin [flags]\n")
flag.PrintDefaults()
fmt.Fprint(os.Stderr, `
Examples:
# Show status of all packages.
gostatus all
# Show status of package in current directory.
gostatus
# Show status of all dependencies (recursive) of package in current dir.
go list -deps | gostatus -stdin -v
Legend:
? - Not under version control or unreachable remote
b - Non-default branch checked out
* - Uncommited changes in working dir
+ - Update available
- - Local revision is ahead of remote revision
± - Update available; local revision is ahead of remote revision
! - No remote
/ - Remote repository not found (was it deleted? made private?)
# - Remote path doesn't match import path
$ - Stash exists
`)
}
func main() {
flag.Usage = usage
flag.Parse()
var shouldShow RepoFilter
switch {
default:
shouldShow = func(r *Repo) bool {
// Check for notable status.
return CompactPresenter(r)[:4] != " "
}
case *vFlag:
shouldShow = func(*Repo) bool { return true }
}
var presenter RepoPresenter
switch {
case *debugFlag:
presenter = DebugPresenter
case *compactFlag:
presenter = CompactPresenter
default:
presenter = PorcelainPresenter
}
workspace := NewWorkspace(shouldShow, presenter)
// Feed input into workspace processing pipeline.
switch *stdinFlag {
case false:
go func() { // This needs to happen in the background because sending input will be blocked on processing and receiving output.
importPaths := gotool.ImportPaths(flag.Args())
for _, importPath := range importPaths {
workspace.ImportPaths <- importPath
}
close(workspace.ImportPaths)
}()
case true:
go func() { // This needs to happen in the background because sending input will be blocked on processing and receiving output.
br := bufio.NewReader(os.Stdin)
for line, err := br.ReadString('\n'); err == nil; line, err = br.ReadString('\n') {
importPath := line[:len(line)-1] // Trim last newline.
workspace.ImportPaths <- importPath
}
close(workspace.ImportPaths)
}()
}
// Output results.
for workspace.Statuses != nil || workspace.Errors != nil {
select {
case status, ok := <-workspace.Statuses:
if !ok {
workspace.Statuses = nil
continue
}
fmt.Println(status)
case error, ok := <-workspace.Errors:
if !ok {
workspace.Errors = nil
continue
}
fmt.Fprintln(os.Stderr, error)
}
}
}
var wd = func() string {
// Get current directory.
wd, err := os.Getwd()
if err != nil {
log.Fatalln("failed to get current directory:", err)
}
return wd
}()