-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathpackage.go
111 lines (94 loc) · 2.21 KB
/
package.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
package main
import (
"fmt"
"os"
"path/filepath"
"golang.org/x/tools/go/vcs"
)
// Package represents single Go package/repo in Gopath.
type Package struct {
Name string
Dir string
Repo *vcs.RepoRoot
Commits Commits
}
// Packages is an obvious type, but I prefer to have golint happy.
type Packages []*Package
var emojiRune = '✅'
// NewPackage returns new package.
func NewPackage(name, gopath string) (*Package, error) {
dir := filepath.Join(gopath, "src", name)
repo, err := vcs.RepoRootForImportPath(name, false)
if err != nil {
// it's ok, silently discard errors here
return nil, err
}
return &Package{
Name: name,
Dir: dir,
Repo: repo,
}, nil
}
// Refresh updates package info about new commits.
//
// It typically require internet connection to check
// remote side.
func (p *Package) Refresh() error {
var vcs VCS
switch p.Repo.VCS.Name {
case "Git":
vcs = NewGit(p.Dir)
case "Mercurial":
vcs = NewHg(p.Dir)
default:
return fmt.Errorf("unknown VCS")
}
if err := vcs.Update(); err != nil {
return err
}
p.Commits = vcs.Commits()
return nil
}
// IsOutdated returns true if package has updates on remote.
func (p *Package) IsOutdated() bool {
return len(p.Commits) > 0
}
// String implements Stringer for Package.
func (p *Package) String() string {
count := len(p.Commits)
out := fmt.Sprintf("%s [%c %d]\n", green(p.Name), emojiRune, count)
out = fmt.Sprintf("%s%s", out, p.Commits)
return out
}
// UpdateCmd returns command used to update package.
func (p Package) UpdateCmd(force bool) []string {
if force {
return []string{"go", "get", "-u", "-f", p.Name}
}
return []string{"go", "get", "-u", p.Name}
}
// Update updates package to the latest revision.
func (p *Package) Update(force bool) (err error) {
if force {
_, err = Run(p.Dir, "go", "get", "-u", "-f", p.Name)
return
}
_, err = Run(p.Dir, "go", "get", "-u", p.Name)
return
}
// Outdated filters only outdated packages.
func (pkgs Packages) Outdated() Packages {
var outdated Packages
for _, pkg := range pkgs {
if pkg.IsOutdated() {
outdated = append(outdated, pkg)
}
}
return outdated
}
func init() {
// No legacy is so rich as honesty. (:
if os.Getenv("TRUTH_MODE") != "" {
emojiRune = '🐞'
}
}