-
Notifications
You must be signed in to change notification settings - Fork 541
/
Copy pathlegacy.go
338 lines (296 loc) · 9.15 KB
/
legacy.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
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
package cfg
import (
"fmt"
"path"
"reflect"
"strings"
"time"
"github.com/Masterminds/glide/util"
)
// lConfig1 is a legacy Config file.
type lConfig1 struct {
Name string `yaml:"package"`
Description string `json:"description,omitempty"`
Home string `yaml:"homepage,omitempty"`
License string `yaml:"license,omitempty"`
Owners Owners `yaml:"owners,omitempty"`
Ignore []string `yaml:"ignore,omitempty"`
Exclude []string `yaml:"excludeDirs,omitempty"`
Imports lDependencies1 `yaml:"import"`
DevImports lDependencies1 `yaml:"testImport,omitempty"`
}
func (c *lConfig1) UnmarshalYAML(unmarshal func(interface{}) error) error {
newConfig := &lcf1{}
if err := unmarshal(&newConfig); err != nil {
return err
}
c.Name = newConfig.Name
c.Description = newConfig.Description
c.Home = newConfig.Home
c.License = newConfig.License
c.Owners = newConfig.Owners
c.Ignore = newConfig.Ignore
c.Exclude = newConfig.Exclude
c.Imports = newConfig.Imports
c.DevImports = newConfig.DevImports
// Cleanup the Config object now that we have it.
err := c.DeDupe()
return err
}
func (c *lConfig1) Convert() (*Config, error) {
// This is probably already done, but do it just in case
err := c.DeDupe()
if err != nil {
return nil, err
}
// Pull over the easy values
c2 := &Config{
Name: c.Name,
Description: c.Description,
Home: c.Home,
License: c.License,
Owners: c.Owners,
Ignore: c.Ignore,
}
// _if_ the name is set, path-prepend it to exclude, and add that to ignore.
// Otherwise, we just skip excludes. Not that big a deal, since they're a
// root-only property anyway; the user can reasonably recreate.
if c.Name != "" {
for _, excl := range c.Exclude {
c.Ignore = append(c.Ignore, path.Join(c.Name, excl))
// The trailing * is interpreted by gps as an ignore on that and all
// child paths (or, soon - https://github.com/sdboyer/gps/issues/88)
c.Ignore = append(c.Ignore, path.Join(c.Name, excl, "*"))
}
}
// Quitting early on this might seem risky, but a) all possible errs
// _should_ have already been surfaced in the earlier DeDupe(), and b) there
// are no new errs introduced by the conversion itself, so this doesn't
// actually increase the surface area for failures vis-a-vis pre-gps glide.
c2.Imports, err = c.Imports.Convert()
if err != nil {
return nil, err
}
c2.DevImports, err = c.DevImports.Convert()
if err != nil {
return nil, err
}
return c2, nil
}
// DeDupe consolidates duplicate dependencies on a Config instance
func (c *lConfig1) DeDupe() error {
// Remove duplicates in the imports
var err error
c.Imports, err = c.Imports.DeDupe()
if err != nil {
return err
}
c.DevImports, err = c.DevImports.DeDupe()
if err != nil {
return err
}
// If the name on the config object is part of the imports remove it.
found := -1
for i, dep := range c.Imports {
if dep.Name == c.Name {
found = i
}
}
if found >= 0 {
c.Imports = append(c.Imports[:found], c.Imports[found+1:]...)
}
found = -1
for i, dep := range c.DevImports {
if dep.Name == c.Name {
found = i
}
}
if found >= 0 {
c.DevImports = append(c.DevImports[:found], c.DevImports[found+1:]...)
}
// If something is on the ignore list remove it from the imports.
for _, v := range c.Ignore {
found = -1
for k, d := range c.Imports {
if v == d.Name {
found = k
}
}
if found >= 0 {
c.Imports = append(c.Imports[:found], c.Imports[found+1:]...)
}
found = -1
for k, d := range c.DevImports {
if v == d.Name {
found = k
}
}
if found >= 0 {
c.DevImports = append(c.DevImports[:found], c.DevImports[found+1:]...)
}
}
return nil
}
// Legacy representation of a glide.yaml file.
type lcf1 struct {
Name string `yaml:"package"`
Description string `yaml:"description,omitempty"`
Home string `yaml:"homepage,omitempty"`
License string `yaml:"license,omitempty"`
Owners Owners `yaml:"owners,omitempty"`
Ignore []string `yaml:"ignore,omitempty"`
Exclude []string `yaml:"excludeDirs,omitempty"`
Imports lDependencies1 `yaml:"import"`
DevImports lDependencies1 `yaml:"testImport,omitempty"`
// these fields guarantee that this struct fails to unmarshal the new yamls
Compat int `yaml:"dependencies,omitempty"`
Compat2 int `yaml:"testDependencies,omitempty"`
}
type lDependencies1 []*lDependency1
func (ds lDependencies1) Convert() (Dependencies, error) {
dds, err := ds.DeDupe()
if err != nil {
return nil, err
}
var ds2 Dependencies
for _, d := range dds {
// If we have neither a repo nor a reference, then it's pointless to
// include this dep in the list (it will add no information to gps)
if d.Repository == "" && d.Reference == "" {
continue
}
d2 := &Dependency{
Name: d.Name,
Repository: d.Repository,
Version: d.Reference,
}
// TODO(sdboyer) d.Reference doesn't disambiguate between branches and
// tags. Check the version list (via source manager) to convert most
// sanely?
ds2 = append(ds2, d2)
}
return ds2, nil
}
// DeDupe cleans up duplicates on a list of dependencies.
func (d lDependencies1) DeDupe() (lDependencies1, error) {
checked := map[string]int{}
imports := make(lDependencies1, 0, 1)
i := 0
for _, dep := range d {
// The first time we encounter a dependency add it to the list
if val, ok := checked[dep.Name]; !ok {
checked[dep.Name] = i
imports = append(imports, dep)
i++
} else {
// In here we've encountered a dependency for the second time.
// Make sure the details are the same or return an error.
v := imports[val]
if dep.Reference != v.Reference {
return d, fmt.Errorf("Import %s repeated with different versions '%s' and '%s'", dep.Name, dep.Reference, v.Reference)
}
if dep.Repository != v.Repository || dep.VcsType != v.VcsType {
return d, fmt.Errorf("Import %s repeated with different Repository details", dep.Name)
}
if !reflect.DeepEqual(dep.Os, v.Os) || !reflect.DeepEqual(dep.Arch, v.Arch) {
return d, fmt.Errorf("Import %s repeated with different OS or Architecture filtering", dep.Name)
}
imports[checked[dep.Name]].Subpackages = stringArrayDeDupe(v.Subpackages, dep.Subpackages...)
}
}
return imports, nil
}
type lDependency1 struct {
Name string `yaml:"package"`
Reference string `yaml:"version,omitempty"`
Pin string `yaml:"-"`
Repository string `yaml:"repo,omitempty"`
VcsType string `yaml:"vcs,omitempty"`
Subpackages []string `yaml:"subpackages,omitempty"`
Arch []string `yaml:"arch,omitempty"`
Os []string `yaml:"os,omitempty"`
}
// Legacy unmarshaler for dependency component of yaml files
func (d *lDependency1) UnmarshalYAML(unmarshal func(interface{}) error) error {
newDep := &ldep1{}
err := unmarshal(newDep)
if err != nil {
return err
}
d.Name = newDep.Name
d.Reference = newDep.Reference
d.Repository = newDep.Repository
d.VcsType = newDep.VcsType
d.Subpackages = newDep.Subpackages
d.Arch = newDep.Arch
d.Os = newDep.Os
if d.Reference == "" && newDep.Ref != "" {
d.Reference = newDep.Ref
}
// Make sure only legitimate VCS are listed.
d.VcsType = filterVcsType(d.VcsType)
// Get the root name for the package
tn, subpkg := util.NormalizeName(d.Name)
d.Name = tn
if subpkg != "" {
d.Subpackages = append(d.Subpackages, subpkg)
}
// Older versions of Glide had a / prefix on subpackages in some cases.
// Here that's cleaned up. Someday we should be able to remove this.
for k, v := range d.Subpackages {
d.Subpackages[k] = strings.TrimPrefix(v, "/")
}
return nil
}
// Legacy representation of a dep constraint
type ldep1 struct {
Name string `yaml:"package"`
Reference string `yaml:"version,omitempty"`
Ref string `yaml:"ref,omitempty"`
Repository string `yaml:"repo,omitempty"`
VcsType string `yaml:"vcs,omitempty"`
Subpackages []string `yaml:"subpackages,omitempty"`
Arch []string `yaml:"arch,omitempty"`
Os []string `yaml:"os,omitempty"`
}
type lLockfile1 struct {
Hash string `yaml:"hash"`
Updated time.Time `yaml:"updated"`
Imports lLocks1 `yaml:"imports"`
DevImports lLocks1 `yaml:"testImports"` // TODO remove and fold in as prop
Compat int `yaml:"import,omitempty"`
Compat2 int `yaml:"testImport,omitempty"`
}
func (l *lLockfile1) Convert() *Lockfile {
return &Lockfile{
Hash: l.Hash,
Updated: l.Updated,
Imports: l.Imports.Convert(),
DevImports: l.DevImports.Convert(),
}
}
type lLocks1 []*lLock1
func (ll lLocks1) Convert() Locks {
var ll2 Locks
for _, l := range ll {
// If they have no rev, just drop them
if l.Version == "" {
continue
}
ll2 = append(ll2, &Lock{
Name: l.Name,
Repository: l.Repository,
Revision: l.Version,
})
}
return ll2
}
type lLock1 struct {
Name string `yaml:"name"`
Version string `yaml:"version"`
Repository string `yaml:"repo,omitempty"`
VcsType string `yaml:"vcs,omitempty"`
Subpackages []string `yaml:"subpackages,omitempty"`
Arch []string `yaml:"arch,omitempty"`
Os []string `yaml:"os,omitempty"`
}