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

Commit a7103ca

Browse files
committed
import gvt manifest on init
1 parent d62440d commit a7103ca

File tree

5 files changed

+360
-0
lines changed

5 files changed

+360
-0
lines changed

internal/importers/gvt/importer.go

+124
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
// Copyright 2017 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package gvt
6+
7+
import (
8+
"encoding/json"
9+
"io/ioutil"
10+
"log"
11+
"os"
12+
"path/filepath"
13+
14+
"github.com/golang/dep"
15+
"github.com/golang/dep/internal/gps"
16+
"github.com/golang/dep/internal/importers/base"
17+
"github.com/pkg/errors"
18+
)
19+
20+
const gvtPath = "vendor" + string(os.PathSeparator) + "manifest"
21+
22+
// Importer imports gvt configuration into the dep configuration format.
23+
type Importer struct {
24+
*base.Importer
25+
gvtConfig gvtManifest
26+
}
27+
28+
// NewImporter for gvt.
29+
func NewImporter(logger *log.Logger, verbose bool, sm gps.SourceManager) *Importer {
30+
return &Importer{Importer: base.NewImporter(logger, verbose, sm)}
31+
}
32+
33+
type gvtManifest struct {
34+
Deps []gvtPkg `json:"dependencies"`
35+
}
36+
37+
type gvtPkg struct {
38+
ImportPath string
39+
Repository string
40+
Revision string
41+
Branch string
42+
}
43+
44+
// Name of the importer.
45+
func (g *Importer) Name() string {
46+
return "gvt"
47+
}
48+
49+
// HasDepMetadata checks if a directory contains config that the importer can handle.
50+
func (g *Importer) HasDepMetadata(dir string) bool {
51+
y := filepath.Join(dir, gvtPath)
52+
if _, err := os.Stat(y); err != nil {
53+
return false
54+
}
55+
56+
return true
57+
}
58+
59+
// Import the config found in the directory.
60+
func (g *Importer) Import(dir string, pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, error) {
61+
err := g.load(dir)
62+
if err != nil {
63+
return nil, nil, err
64+
}
65+
66+
return g.convert(pr)
67+
}
68+
69+
func (g *Importer) load(projectDir string) error {
70+
g.Logger.Println("Detected gvt configuration files...")
71+
j := filepath.Join(projectDir, gvtPath)
72+
if g.Verbose {
73+
g.Logger.Printf(" Loading %s", j)
74+
}
75+
jb, err := ioutil.ReadFile(j)
76+
if err != nil {
77+
return errors.Wrapf(err, "unable to read %s", j)
78+
}
79+
err = json.Unmarshal(jb, &g.gvtConfig)
80+
if err != nil {
81+
return errors.Wrapf(err, "unable to parse %s", j)
82+
}
83+
84+
return nil
85+
}
86+
87+
func (g *Importer) convert(pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, error) {
88+
g.Logger.Println("Converting from vendor/manifest ...")
89+
90+
packages := make([]base.ImportedPackage, 0, len(g.gvtConfig.Deps))
91+
for _, pkg := range g.gvtConfig.Deps {
92+
// Validate
93+
if pkg.ImportPath == "" {
94+
err := errors.New("invalid gvt configuration, ImportPath is required")
95+
return nil, nil, err
96+
}
97+
98+
if pkg.Revision == "" {
99+
err := errors.New("invalid gvt configuration, Revision is required")
100+
return nil, nil, err
101+
}
102+
103+
var contstraintHint = ""
104+
if pkg.Branch != "master" {
105+
contstraintHint = pkg.Branch
106+
}
107+
108+
ip := base.ImportedPackage{
109+
Name: pkg.ImportPath,
110+
//TODO: temporarly ignore .Repository. see https://github.com/golang/dep/pull/1166
111+
// Source: pkg.Repository,
112+
LockHint: pkg.Revision,
113+
ConstraintHint: contstraintHint,
114+
}
115+
packages = append(packages, ip)
116+
}
117+
118+
err := g.ImportPackages(packages, true)
119+
if err != nil {
120+
return nil, nil, err
121+
}
122+
123+
return g.Manifest, g.Lock, nil
124+
}
+209
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
// Copyright 2017 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package gvt
6+
7+
import (
8+
"bytes"
9+
"log"
10+
"path/filepath"
11+
"testing"
12+
13+
"github.com/golang/dep"
14+
"github.com/golang/dep/internal/gps"
15+
"github.com/golang/dep/internal/importers/importertest"
16+
"github.com/golang/dep/internal/test"
17+
"github.com/pkg/errors"
18+
)
19+
20+
func TestGvtConfig_Convert(t *testing.T) {
21+
testCases := map[string]struct {
22+
importertest.TestCase
23+
gvtConfig gvtManifest
24+
}{
25+
"package with master branch": {
26+
importertest.TestCase{
27+
WantConstraint: importertest.V1Constraint,
28+
WantRevision: importertest.V1Rev,
29+
WantVersion: importertest.V1Tag,
30+
},
31+
gvtManifest{
32+
Deps: []gvtPkg{
33+
{
34+
ImportPath: importertest.Project,
35+
Revision: importertest.V1Rev,
36+
Branch: "master",
37+
},
38+
},
39+
},
40+
},
41+
"package with non-master branch": {
42+
importertest.TestCase{
43+
WantConstraint: importertest.V2Branch,
44+
WantRevision: importertest.V2PatchRev,
45+
WantVersion: importertest.V2PatchTag,
46+
},
47+
gvtManifest{
48+
Deps: []gvtPkg{
49+
{
50+
ImportPath: importertest.Project,
51+
Revision: importertest.V2PatchRev,
52+
Branch: importertest.V2Branch,
53+
},
54+
},
55+
},
56+
},
57+
"missing package name": {
58+
importertest.TestCase{
59+
WantConvertErr: true,
60+
},
61+
gvtManifest{
62+
Deps: []gvtPkg{{ImportPath: ""}},
63+
},
64+
},
65+
"missing revision": {
66+
importertest.TestCase{
67+
WantConvertErr: true,
68+
},
69+
gvtManifest{
70+
Deps: []gvtPkg{
71+
{
72+
ImportPath: importertest.Project,
73+
},
74+
},
75+
},
76+
},
77+
}
78+
79+
for name, testCase := range testCases {
80+
name := name
81+
testCase := testCase
82+
t.Run(name, func(t *testing.T) {
83+
err := testCase.Execute(t, func(logger *log.Logger, sm gps.SourceManager) (*dep.Manifest, *dep.Lock, error) {
84+
g := NewImporter(logger, true, sm)
85+
g.gvtConfig = testCase.gvtConfig
86+
return g.convert(importertest.RootProject)
87+
})
88+
if err != nil {
89+
t.Fatalf("%#v", err)
90+
}
91+
})
92+
}
93+
}
94+
95+
func TestGvtConfig_Import(t *testing.T) {
96+
h := test.NewHelper(t)
97+
defer h.Cleanup()
98+
99+
cacheDir := "gps-repocache"
100+
h.TempDir(cacheDir)
101+
h.TempDir("src")
102+
h.TempDir(filepath.Join("src", importertest.RootProject))
103+
h.TempCopy(filepath.Join(importertest.RootProject, gvtPath), "manifest")
104+
105+
projectRoot := h.Path(importertest.RootProject)
106+
sm, err := gps.NewSourceManager(gps.SourceManagerConfig{
107+
Cachedir: h.Path(cacheDir),
108+
Logger: log.New(test.Writer{TB: t}, "", 0),
109+
})
110+
h.Must(err)
111+
defer sm.Release()
112+
113+
// Capture stderr so we can verify output
114+
verboseOutput := &bytes.Buffer{}
115+
logger := log.New(verboseOutput, "", 0)
116+
117+
g := NewImporter(logger, false, sm) // Disable verbose so that we don't print values that change each test run
118+
if !g.HasDepMetadata(projectRoot) {
119+
t.Fatal("Expected the importer to detect gvt configuration file")
120+
}
121+
122+
m, l, err := g.Import(projectRoot, importertest.RootProject)
123+
h.Must(err)
124+
125+
if m == nil {
126+
t.Fatal("Expected the manifest to be generated")
127+
}
128+
129+
if l == nil {
130+
t.Fatal("Expected the lock to be generated")
131+
}
132+
133+
goldenFile := "golden.txt"
134+
got := verboseOutput.String()
135+
want := h.GetTestFileString(goldenFile)
136+
if want != got {
137+
if *test.UpdateGolden {
138+
if err := h.WriteTestFile(goldenFile, got); err != nil {
139+
t.Fatalf("%+v", errors.Wrapf(err, "Unable to write updated golden file %s", goldenFile))
140+
}
141+
} else {
142+
t.Fatalf("want %s, got %s", want, got)
143+
}
144+
}
145+
}
146+
147+
func TestGvtConfig_JsonLoad(t *testing.T) {
148+
// This is same as testdata/manifest
149+
wantConfig := gvtManifest{
150+
Deps: []gvtPkg{
151+
{
152+
ImportPath: "github.com/sdboyer/deptest",
153+
Revision: "3f4c3bea144e112a69bbe5d8d01c1b09a544253f",
154+
},
155+
{
156+
ImportPath: "github.com/sdboyer/deptestdos",
157+
Revision: "5c607206be5decd28e6263ffffdcee067266015e",
158+
},
159+
{
160+
ImportPath: "github.com/carolynvs/deptest-importers",
161+
Revision: "b79bc9482da8bb7402cdc3e3fd984db250718dd7",
162+
Branch: "v2",
163+
},
164+
},
165+
}
166+
167+
h := test.NewHelper(t)
168+
defer h.Cleanup()
169+
170+
ctx := importertest.NewTestContext(h)
171+
172+
h.TempCopy(filepath.Join(importertest.RootProject, gvtPath), "manifest")
173+
174+
projectRoot := h.Path(importertest.RootProject)
175+
176+
g := NewImporter(ctx.Err, true, nil)
177+
err := g.load(projectRoot)
178+
if err != nil {
179+
t.Fatalf("Error while loading... %v", err)
180+
}
181+
182+
if !equalImports(g.gvtConfig.Deps, wantConfig.Deps) {
183+
t.Fatalf("Expected imports to be equal. \n\t(GOT): %v\n\t(WNT): %v", g.gvtConfig.Deps, wantConfig.Deps)
184+
}
185+
}
186+
187+
// equalImports compares two slices of gvtPkg and checks if they are
188+
// equal.
189+
func equalImports(a, b []gvtPkg) bool {
190+
if a == nil && b == nil {
191+
return true
192+
}
193+
194+
if a == nil || b == nil {
195+
return false
196+
}
197+
198+
if len(a) != len(b) {
199+
return false
200+
}
201+
202+
for i := range a {
203+
if a[i] != b[i] {
204+
return false
205+
}
206+
}
207+
208+
return true
209+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Detected gvt configuration files...
2+
Converting from vendor/manifest ...
3+
Using ^0.8.1 as initial constraint for imported dep github.com/sdboyer/deptest
4+
Trying v0.8.1 (3f4c3be) as initial lock for imported dep github.com/sdboyer/deptest
5+
Using ^2.0.0 as initial constraint for imported dep github.com/sdboyer/deptestdos
6+
Trying v2.0.0 (5c60720) as initial lock for imported dep github.com/sdboyer/deptestdos
7+
Using v2 as initial constraint for imported dep github.com/carolynvs/deptest-importers
8+
Trying v2 (b79bc94) as initial lock for imported dep github.com/carolynvs/deptest-importers
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"dependencies": [
3+
{
4+
"importpath": "github.com/sdboyer/deptest",
5+
"revision": "3f4c3bea144e112a69bbe5d8d01c1b09a544253f"
6+
},
7+
{
8+
"importpath": "github.com/sdboyer/deptestdos",
9+
"revision": "5c607206be5decd28e6263ffffdcee067266015e"
10+
},
11+
{
12+
"importpath": "github.com/carolynvs/deptest-importers",
13+
"revision": "b79bc9482da8bb7402cdc3e3fd984db250718dd7",
14+
"branch": "v2"
15+
}
16+
]
17+
}

internal/importers/importers.go

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/golang/dep/internal/importers/glide"
1313
"github.com/golang/dep/internal/importers/godep"
1414
"github.com/golang/dep/internal/importers/govend"
15+
"github.com/golang/dep/internal/importers/gvt"
1516
"github.com/golang/dep/internal/importers/vndr"
1617
)
1718

@@ -35,5 +36,6 @@ func BuildAll(logger *log.Logger, verbose bool, sm gps.SourceManager) []Importer
3536
godep.NewImporter(logger, verbose, sm),
3637
vndr.NewImporter(logger, verbose, sm),
3738
govend.NewImporter(logger, verbose, sm),
39+
gvt.NewImporter(logger, verbose, sm),
3840
}
3941
}

0 commit comments

Comments
 (0)