forked from Masterminds/glide
/
recursive_glide.go
210 lines (182 loc) · 5.44 KB
/
recursive_glide.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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
package cmd
import (
"github.com/Masterminds/cookoo"
"github.com/kylelemons/go-gypsy/yaml"
"io/ioutil"
"os"
"path"
"strings"
)
// Recurse does glide installs on dependent packages.
// Recurse looks in all known packages for a glide.yaml files and installs for
// each one it finds.
func Recurse(c cookoo.Context, p *cookoo.Params) (interface{}, cookoo.Interrupt) {
if !p.Get("enable", true).(bool) {
return nil, nil
}
force := p.Get("force", true).(bool)
godeps, gpm, deleteFlatten := false, false, false
if g, ok := p.Has("importGodeps"); ok {
godeps = g.(bool)
}
if g, ok := p.Has("importGPM"); ok {
gpm = g.(bool)
}
if g, ok := p.Has("deleteFlatten"); ok {
deleteFlatten = g.(bool)
}
Info("Checking dependencies for updates. Godeps: %v, GPM: %v\n", godeps, gpm)
if deleteFlatten == true {
Info("Deleting flattened dependencies enabled\n")
}
conf := p.Get("conf", &Config{}).(*Config)
vend, _ := VendorPath(c)
return recDepResolve(conf, vend, godeps, gpm, force, deleteFlatten)
}
func recDepResolve(conf *Config, vend string, godeps, gpm, force, deleteFlatten bool) (interface{}, error) {
Info("Inspecting %s.\n", vend)
if len(conf.Imports) == 0 {
Info("No imports.\n")
}
// Look in each package to see whether it has a glide.yaml, and no vendor/
for _, imp := range conf.Imports {
if imp.Flattened == true {
continue
}
base := path.Join(vend, imp.Name)
Info("Looking in %s for a glide.yaml file.\n", base)
if !needsGlideUp(base) {
if godeps {
importGodep(base, imp.Name)
}
if gpm {
importGPM(base, imp.Name)
}
if !needsGlideUp(base) {
Info("Package %s manages its own dependencies.\n", imp.Name)
continue
}
}
if err := dependencyGlideUp(conf, base, godeps, gpm, force, deleteFlatten); err != nil {
Warn("Failed to update dependency %s: %s", imp.Name, err)
}
}
// Run `glide up`
return nil, nil
}
func dependencyGlideUp(parentConf *Config, base string, godep, gpm, force, deleteFlatten bool) error {
Info("Doing a glide in %s\n", base)
//conf := new(Config)
fname := path.Join(base, "glide.yaml")
f, err := yaml.ReadFile(fname)
if err != nil {
return err
}
conf, err := FromYaml(f.Root)
conf.Parent = parentConf
if err != nil {
return err
}
for _, imp := range conf.Imports {
vdir := path.Join(base, "vendor")
wd := path.Join(vdir, imp.Name)
// if our root glide.yaml says to flatten this, we skip it
if dep := conf.GetRoot().Imports.Get(imp.Name); dep != nil {
flatten := conf.GetRoot().Flatten
if flatten == true && dep.Flatten == false ||
flatten == false && dep.Flatten == true {
flatten = dep.Flatten
}
if flatten == true {
Info("Skipping importing %s due to flatten being set in root import glide.yaml\n", imp.Name)
imp.Flattened = true
}
if flatten == true && imp.Reference != dep.Reference {
Warn("Flattened package %s ref (%s) is diferent from sub vendored package ref (%s)\n", imp.Name, imp.Reference, dep.Reference)
}
if imp.Flattened == true && deleteFlatten == true {
if exists, _ := fileExist(wd); exists == true || true {
remove := wd + string(os.PathSeparator)
Warn("Removing flattened sub vendored package: %s\n", strings.TrimPrefix(remove, base))
rerr := os.RemoveAll(remove)
if rerr != nil {
return rerr
}
}
}
if imp.Flattened == true {
continue
}
}
// We don't use the global var to find vendor dir name because the
// user may mis-use that var to modify the local vendor dir, and
// we don't want that to break the embedded vendor dirs.
if err := ensureDir(wd); err != nil {
Warn("Skipped getting %s (vendor/ error): %s\n", imp.Name, err)
continue
}
if VcsExists(imp, wd) {
Info("Updating project %s (%s)\n", imp.Name, wd)
if err := VcsUpdate(imp, vdir, force); err != nil {
// We can still go on just fine even if this fails.
Warn("Skipped update %s: %s\n", imp.Name, err)
continue
}
} else {
Info("Importing %s to project %s\n", imp.Name, base)
if err := VcsGet(imp, wd); err != nil {
Warn("Skipped getting %s: %v\n", imp.Name, err)
continue
}
}
// If a revision has been set use it.
err = VcsVersion(imp, vdir)
if err != nil {
Warn("Problem setting version on %s: %s\n", imp.Name, err)
}
//recDepResolve(conf, path.Join(wd, "vendor"))
}
recDepResolve(conf, path.Join(base, "vendor"), godep, gpm, force, deleteFlatten)
return nil
}
func ensureDir(dirpath string) error {
if fi, err := os.Stat(dirpath); err == nil && fi.IsDir() {
return nil
}
return os.MkdirAll(dirpath, 0755)
}
func needsGlideUp(dir string) bool {
stat, err := os.Stat(path.Join(dir, "glide.yaml"))
if err != nil || stat.IsDir() {
return false
}
// Should probably see if vendor is there and non-empty.
return true
}
func importGodep(dir, pkg string) error {
Info("Looking in %s/Godeps/ for a Godeps.json file.\n", dir)
d, err := parseGodepGodeps(dir)
if err != nil {
Warn("Looking for Godeps: %s\n", err)
return err
}
return quickDirtyYAMLWrite(dir, d, pkg)
}
func importGPM(dir, pkg string) error {
d, err := parseGPMGodeps(dir)
if err != nil {
return err
}
return quickDirtyYAMLWrite(dir, d, pkg)
}
func quickDirtyYAMLWrite(dir string, d []*Dependency, pkg string) error {
if len(d) == 0 {
return nil
}
c := &Config{Name: pkg, Imports: d}
node := c.ToYaml()
data := yaml.Render(node)
f := path.Join(dir, "glide.yaml")
Info("Writing new glide.yaml file in %s\n", dir)
return ioutil.WriteFile(f, []byte(data), 0755)
}