Skip to content
This repository was archived by the owner on Sep 9, 2020. It is now read-only.

Commit d230092

Browse files
authored
Merge pull request #1058 from carolynvs/vndr-val-subtests
cmd/dep: fix vndrImporter's rev->constraint logic
2 parents 5b31756 + 1bb5f29 commit d230092

7 files changed

+181
-141
lines changed

cmd/dep/glide_importer_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ func TestGlideConfig_Convert(t *testing.T) {
8888
wantLockCount: 1,
8989
wantConstraint: "^1.0.0",
9090
wantVersion: "v1.0.0",
91+
wantRevision: "ff2948a2ac8f538c4ecd55962e919d1e13e74baf",
9192
},
9293
},
9394
"revision only": {
@@ -110,6 +111,7 @@ func TestGlideConfig_Convert(t *testing.T) {
110111
projectRoot: "github.com/sdboyer/deptest",
111112
wantLockCount: 1,
112113
wantRevision: gps.Revision("ff2948a2ac8f538c4ecd55962e919d1e13e74baf"),
114+
wantVersion: "v1.0.0",
113115
},
114116
},
115117
"with ignored package": {

cmd/dep/godep_importer_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ func TestGodepConfig_Convert(t *testing.T) {
5656
wantConstraint: "^1.12.0-12-g2fd980e",
5757
wantLockCount: 1,
5858
wantVersion: "v1.0.0",
59+
wantRevision: "ff2948a2ac8f538c4ecd55962e919d1e13e74baf",
5960
},
6061
},
6162
"empty comment": {
@@ -116,6 +117,7 @@ func TestGodepConfig_Convert(t *testing.T) {
116117
wantLockCount: 1,
117118
wantConstraint: "^1.0.0",
118119
wantVersion: "v1.0.0",
120+
wantRevision: "ff2948a2ac8f538c4ecd55962e919d1e13e74baf",
119121
},
120122
},
121123
}

cmd/dep/root_analyzer.go

+20
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,26 @@ func (a *rootAnalyzer) Info() gps.ProjectAnalyzerInfo {
173173
}
174174
}
175175

176+
// isVersion determines if the specified value is a version/tag in the project.
177+
func isVersion(pi gps.ProjectIdentifier, value string, sm gps.SourceManager) (bool, gps.Version, error) {
178+
versions, err := sm.ListVersions(pi)
179+
if err != nil {
180+
return false, nil, errors.Wrapf(err, "list versions for %s(%s)", pi.ProjectRoot, pi.Source) // means repo does not exist
181+
}
182+
183+
for _, version := range versions {
184+
if version.Type() != gps.IsVersion && version.Type() != gps.IsSemver {
185+
continue
186+
}
187+
188+
if value == version.String() {
189+
return true, version, nil
190+
}
191+
}
192+
193+
return false, nil, nil
194+
}
195+
176196
// lookupVersionForLockedProject figures out the appropriate version for a locked
177197
// project based on the locked revision and the constraint from the manifest.
178198
// First try matching the revision to a version, then try the constraint from the

cmd/dep/root_analyzer_test.go

+54-18
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,41 @@ func TestProjectExistsInLock(t *testing.T) {
154154
}
155155
}
156156

157+
func TestIsVersion(t *testing.T) {
158+
testcases := map[string]struct {
159+
wantIsVersion bool
160+
wantVersion gps.Version
161+
}{
162+
"v1.0.0": {wantIsVersion: true, wantVersion: gps.NewVersion("v1.0.0").Pair("ff2948a2ac8f538c4ecd55962e919d1e13e74baf")},
163+
"3f4c3bea144e112a69bbe5d8d01c1b09a544253f": {wantIsVersion: false},
164+
"master": {wantIsVersion: false},
165+
}
166+
167+
pi := gps.ProjectIdentifier{ProjectRoot: gps.ProjectRoot("github.com/sdboyer/deptest")}
168+
h := test.NewHelper(t)
169+
defer h.Cleanup()
170+
171+
ctx := newTestContext(h)
172+
sm, err := ctx.SourceManager()
173+
h.Must(err)
174+
defer sm.Release()
175+
176+
for value, testcase := range testcases {
177+
t.Run(value, func(t *testing.T) {
178+
gotIsVersion, gotVersion, err := isVersion(pi, value, sm)
179+
h.Must(err)
180+
181+
if testcase.wantIsVersion != gotIsVersion {
182+
t.Fatalf("unexpected isVersion result for %s: \n\t(GOT) %v \n\t(WNT) %v", value, gotIsVersion, testcase.wantIsVersion)
183+
}
184+
185+
if testcase.wantVersion != gotVersion {
186+
t.Fatalf("unexpected version for %s: \n\t(GOT) %v \n\t(WNT) %v", value, testcase.wantVersion, gotVersion)
187+
}
188+
})
189+
}
190+
}
191+
157192
// convertTestCase is a common set of validations applied to the result
158193
// of an importer converting from an external config format to dep's.
159194
type convertTestCase struct {
@@ -229,26 +264,27 @@ func validateConvertTestCase(testCase *convertTestCase, manifest *dep.Manifest,
229264
return errors.Errorf("Expected locked source to be %s, got '%s'", testCase.wantSourceRepo, p.Ident().Source)
230265
}
231266

232-
if testCase.wantVersion != "" {
233-
ver := p.Version().String()
234-
if ver != testCase.wantVersion {
235-
return errors.Errorf("Expected locked version to be '%s', got %s", testCase.wantVersion, ver)
236-
}
267+
// Break down the locked "version" into a version (optional) and revision
268+
var gotVersion string
269+
var gotRevision gps.Revision
270+
if lpv, ok := p.Version().(gps.PairedVersion); ok {
271+
gotVersion = lpv.String()
272+
gotRevision = lpv.Revision()
273+
} else if lr, ok := p.Version().(gps.Revision); ok {
274+
gotRevision = lr
275+
} else {
276+
return errors.New("could not determine the type of the locked version")
237277
}
238278

239-
if testCase.wantRevision != "" {
240-
lv := p.Version()
241-
lpv, ok := lv.(gps.PairedVersion)
242-
if !ok {
243-
return errors.Errorf("Expected locked version to be PairedVersion but got %T", lv)
244-
}
245-
246-
rev := lpv.Revision()
247-
if rev != testCase.wantRevision {
248-
return errors.Errorf("Expected locked revision to be '%s', got %s",
249-
testCase.wantRevision,
250-
rev)
251-
}
279+
if gotRevision != testCase.wantRevision {
280+
return errors.Errorf("unexpected locked revision : \n\t(GOT) %v \n\t(WNT) %v",
281+
testCase.wantRevision,
282+
gotRevision)
283+
}
284+
if gotVersion != testCase.wantVersion {
285+
return errors.Errorf("unexpected locked version: \n\t(GOT) %v \n\t(WNT) %v",
286+
testCase.wantVersion,
287+
gotVersion)
252288
}
253289
}
254290
return nil

cmd/dep/testdata/vndr/golden.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Detected vndr configuration file...
22
Converting from vendor.conf...
3-
Using 3f4c3bea144e112a69bbe5d8d01c1b09a544253f as initial hint for imported dep github.com/sdboyer/deptest
3+
Using ^0.8.1 as initial constraint for imported dep github.com/sdboyer/deptest
44
Trying v0.8.1 (3f4c3be) as initial lock for imported dep github.com/sdboyer/deptest
55
Using ^2.0.0 as initial constraint for imported dep github.com/sdboyer/deptestdos
6-
Trying * (v2.0.0) as initial lock for imported dep github.com/sdboyer/deptestdos
6+
Trying v2.0.0 (5c60720) as initial lock for imported dep github.com/sdboyer/deptestdos

cmd/dep/vndr_importer.go

+40-14
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,28 @@ func (v *vndrImporter) convert(pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, er
8888
var (
8989
manifest = dep.NewManifest()
9090
lock = &dep.Lock{}
91-
err error
9291
)
9392

9493
for _, pkg := range v.packages {
95-
// ImportPath must not be empty
9694
if pkg.importPath == "" {
97-
err := errors.New("Invalid vndr configuration, missing import path")
95+
err := errors.New("Invalid vndr configuration, import path is required")
96+
return nil, nil, err
97+
}
98+
99+
// Obtain ProjectRoot. Required for avoiding sub-package imports.
100+
ip, err := v.sm.DeduceProjectRoot(pkg.importPath)
101+
if err != nil {
102+
return nil, nil, err
103+
}
104+
pkg.importPath = string(ip)
105+
106+
// Check if it already existing in locked projects
107+
if projectExistsInLock(lock, ip) {
108+
continue
109+
}
110+
111+
if pkg.reference == "" {
112+
err := errors.New("Invalid vndr configuration, revision is required")
98113
return nil, nil, err
99114
}
100115

@@ -103,10 +118,28 @@ func (v *vndrImporter) convert(pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, er
103118
ProjectRoot: gps.ProjectRoot(pkg.importPath),
104119
Source: pkg.repository,
105120
},
121+
Constraint: gps.Any(),
106122
}
107-
pc.Constraint, err = v.sm.InferConstraint(pkg.revision, pc.Ident)
123+
124+
// A vndr entry could contain either a version or a revision
125+
isVersion, version, err := isVersion(pc.Ident, pkg.reference, v.sm)
108126
if err != nil {
109-
return nil, nil, errors.Wrapf(err, "Unable to interpret revision specifier '%s' for package %s", pkg.importPath, pkg.revision)
127+
return nil, nil, err
128+
}
129+
130+
// If the reference is a revision, check if it is tagged with a version
131+
if !isVersion {
132+
revision := gps.Revision(pkg.reference)
133+
version, err = lookupVersionForLockedProject(pc.Ident, nil, revision, v.sm)
134+
if err != nil {
135+
v.logger.Println(err.Error())
136+
}
137+
}
138+
139+
// Try to build a constraint from the version
140+
pp := getProjectPropertiesFromVersion(version)
141+
if pp.Constraint != nil {
142+
pc.Constraint = pp.Constraint
110143
}
111144

112145
manifest.Constraints[pc.Ident.ProjectRoot] = gps.ProjectProperties{
@@ -115,14 +148,7 @@ func (v *vndrImporter) convert(pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, er
115148
}
116149
fb.NewConstraintFeedback(pc, fb.DepTypeImported).LogFeedback(v.logger)
117150

118-
revision := gps.Revision(pkg.revision)
119-
version, err := lookupVersionForLockedProject(pc.Ident, pc.Constraint, revision, v.sm)
120-
if err != nil {
121-
v.logger.Println(err.Error())
122-
}
123-
124151
lp := gps.NewLockedProject(pc.Ident, version, nil)
125-
126152
lock.P = append(lock.P, lp)
127153
fb.NewLockedProjectFeedback(lp, fb.DepTypeImported).LogFeedback(v.logger)
128154
}
@@ -132,7 +158,7 @@ func (v *vndrImporter) convert(pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, er
132158

133159
type vndrPackage struct {
134160
importPath string
135-
revision string
161+
reference string
136162
repository string
137163
}
138164

@@ -155,7 +181,7 @@ func parseVndrLine(line string) (*vndrPackage, error) {
155181

156182
pkg := &vndrPackage{
157183
importPath: parts[0],
158-
revision: parts[1],
184+
reference: parts[1],
159185
}
160186
if len(parts) == 3 {
161187
pkg.repository = parts[2]

0 commit comments

Comments
 (0)