This repository has been archived by the owner on Sep 9, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d62440d
commit a7103ca
Showing
5 changed files
with
360 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
// Copyright 2017 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package gvt | ||
|
||
import ( | ||
"encoding/json" | ||
"io/ioutil" | ||
"log" | ||
"os" | ||
"path/filepath" | ||
|
||
"github.com/golang/dep" | ||
"github.com/golang/dep/internal/gps" | ||
"github.com/golang/dep/internal/importers/base" | ||
"github.com/pkg/errors" | ||
) | ||
|
||
const gvtPath = "vendor" + string(os.PathSeparator) + "manifest" | ||
|
||
// Importer imports gvt configuration into the dep configuration format. | ||
type Importer struct { | ||
*base.Importer | ||
gvtConfig gvtManifest | ||
} | ||
|
||
// NewImporter for gvt. | ||
func NewImporter(logger *log.Logger, verbose bool, sm gps.SourceManager) *Importer { | ||
return &Importer{Importer: base.NewImporter(logger, verbose, sm)} | ||
} | ||
|
||
type gvtManifest struct { | ||
Deps []gvtPkg `json:"dependencies"` | ||
} | ||
|
||
type gvtPkg struct { | ||
ImportPath string | ||
Repository string | ||
Revision string | ||
Branch string | ||
} | ||
|
||
// Name of the importer. | ||
func (g *Importer) Name() string { | ||
return "gvt" | ||
} | ||
|
||
// HasDepMetadata checks if a directory contains config that the importer can handle. | ||
func (g *Importer) HasDepMetadata(dir string) bool { | ||
y := filepath.Join(dir, gvtPath) | ||
if _, err := os.Stat(y); err != nil { | ||
return false | ||
} | ||
|
||
return true | ||
} | ||
|
||
// Import the config found in the directory. | ||
func (g *Importer) Import(dir string, pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, error) { | ||
err := g.load(dir) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
return g.convert(pr) | ||
} | ||
|
||
func (g *Importer) load(projectDir string) error { | ||
g.Logger.Println("Detected gvt configuration files...") | ||
j := filepath.Join(projectDir, gvtPath) | ||
if g.Verbose { | ||
g.Logger.Printf(" Loading %s", j) | ||
} | ||
jb, err := ioutil.ReadFile(j) | ||
if err != nil { | ||
return errors.Wrapf(err, "unable to read %s", j) | ||
} | ||
err = json.Unmarshal(jb, &g.gvtConfig) | ||
if err != nil { | ||
return errors.Wrapf(err, "unable to parse %s", j) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (g *Importer) convert(pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, error) { | ||
g.Logger.Println("Converting from vendor/manifest ...") | ||
|
||
packages := make([]base.ImportedPackage, 0, len(g.gvtConfig.Deps)) | ||
for _, pkg := range g.gvtConfig.Deps { | ||
// Validate | ||
if pkg.ImportPath == "" { | ||
err := errors.New("invalid gvt configuration, ImportPath is required") | ||
return nil, nil, err | ||
} | ||
|
||
if pkg.Revision == "" { | ||
err := errors.New("invalid gvt configuration, Revision is required") | ||
return nil, nil, err | ||
} | ||
|
||
var contstraintHint = "" | ||
if pkg.Branch != "master" { | ||
contstraintHint = pkg.Branch | ||
} | ||
|
||
ip := base.ImportedPackage{ | ||
Name: pkg.ImportPath, | ||
//TODO: temporarly ignore .Repository. see https://github.com/golang/dep/pull/1166 | ||
// Source: pkg.Repository, | ||
LockHint: pkg.Revision, | ||
ConstraintHint: contstraintHint, | ||
} | ||
packages = append(packages, ip) | ||
} | ||
|
||
err := g.ImportPackages(packages, true) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
return g.Manifest, g.Lock, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,209 @@ | ||
// Copyright 2017 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package gvt | ||
|
||
import ( | ||
"bytes" | ||
"log" | ||
"path/filepath" | ||
"testing" | ||
|
||
"github.com/golang/dep" | ||
"github.com/golang/dep/internal/gps" | ||
"github.com/golang/dep/internal/importers/importertest" | ||
"github.com/golang/dep/internal/test" | ||
"github.com/pkg/errors" | ||
) | ||
|
||
func TestGvtConfig_Convert(t *testing.T) { | ||
testCases := map[string]struct { | ||
importertest.TestCase | ||
gvtConfig gvtManifest | ||
}{ | ||
"package with master branch": { | ||
importertest.TestCase{ | ||
WantConstraint: importertest.V1Constraint, | ||
WantRevision: importertest.V1Rev, | ||
WantVersion: importertest.V1Tag, | ||
}, | ||
gvtManifest{ | ||
Deps: []gvtPkg{ | ||
{ | ||
ImportPath: importertest.Project, | ||
Revision: importertest.V1Rev, | ||
Branch: "master", | ||
}, | ||
}, | ||
}, | ||
}, | ||
"package with non-master branch": { | ||
importertest.TestCase{ | ||
WantConstraint: importertest.V2Branch, | ||
WantRevision: importertest.V2PatchRev, | ||
WantVersion: importertest.V2PatchTag, | ||
}, | ||
gvtManifest{ | ||
Deps: []gvtPkg{ | ||
{ | ||
ImportPath: importertest.Project, | ||
Revision: importertest.V2PatchRev, | ||
Branch: importertest.V2Branch, | ||
}, | ||
}, | ||
}, | ||
}, | ||
"missing package name": { | ||
importertest.TestCase{ | ||
WantConvertErr: true, | ||
}, | ||
gvtManifest{ | ||
Deps: []gvtPkg{{ImportPath: ""}}, | ||
}, | ||
}, | ||
"missing revision": { | ||
importertest.TestCase{ | ||
WantConvertErr: true, | ||
}, | ||
gvtManifest{ | ||
Deps: []gvtPkg{ | ||
{ | ||
ImportPath: importertest.Project, | ||
}, | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
for name, testCase := range testCases { | ||
name := name | ||
testCase := testCase | ||
t.Run(name, func(t *testing.T) { | ||
err := testCase.Execute(t, func(logger *log.Logger, sm gps.SourceManager) (*dep.Manifest, *dep.Lock, error) { | ||
g := NewImporter(logger, true, sm) | ||
g.gvtConfig = testCase.gvtConfig | ||
return g.convert(importertest.RootProject) | ||
}) | ||
if err != nil { | ||
t.Fatalf("%#v", err) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestGvtConfig_Import(t *testing.T) { | ||
h := test.NewHelper(t) | ||
defer h.Cleanup() | ||
|
||
cacheDir := "gps-repocache" | ||
h.TempDir(cacheDir) | ||
h.TempDir("src") | ||
h.TempDir(filepath.Join("src", importertest.RootProject)) | ||
h.TempCopy(filepath.Join(importertest.RootProject, gvtPath), "manifest") | ||
|
||
projectRoot := h.Path(importertest.RootProject) | ||
sm, err := gps.NewSourceManager(gps.SourceManagerConfig{ | ||
Cachedir: h.Path(cacheDir), | ||
Logger: log.New(test.Writer{TB: t}, "", 0), | ||
}) | ||
h.Must(err) | ||
defer sm.Release() | ||
|
||
// Capture stderr so we can verify output | ||
verboseOutput := &bytes.Buffer{} | ||
logger := log.New(verboseOutput, "", 0) | ||
|
||
g := NewImporter(logger, false, sm) // Disable verbose so that we don't print values that change each test run | ||
if !g.HasDepMetadata(projectRoot) { | ||
t.Fatal("Expected the importer to detect gvt configuration file") | ||
} | ||
|
||
m, l, err := g.Import(projectRoot, importertest.RootProject) | ||
h.Must(err) | ||
|
||
if m == nil { | ||
t.Fatal("Expected the manifest to be generated") | ||
} | ||
|
||
if l == nil { | ||
t.Fatal("Expected the lock to be generated") | ||
} | ||
|
||
goldenFile := "golden.txt" | ||
got := verboseOutput.String() | ||
want := h.GetTestFileString(goldenFile) | ||
if want != got { | ||
if *test.UpdateGolden { | ||
if err := h.WriteTestFile(goldenFile, got); err != nil { | ||
t.Fatalf("%+v", errors.Wrapf(err, "Unable to write updated golden file %s", goldenFile)) | ||
} | ||
} else { | ||
t.Fatalf("want %s, got %s", want, got) | ||
} | ||
} | ||
} | ||
|
||
func TestGvtConfig_JsonLoad(t *testing.T) { | ||
// This is same as testdata/manifest | ||
wantConfig := gvtManifest{ | ||
Deps: []gvtPkg{ | ||
{ | ||
ImportPath: "github.com/sdboyer/deptest", | ||
Revision: "3f4c3bea144e112a69bbe5d8d01c1b09a544253f", | ||
}, | ||
{ | ||
ImportPath: "github.com/sdboyer/deptestdos", | ||
Revision: "5c607206be5decd28e6263ffffdcee067266015e", | ||
}, | ||
{ | ||
ImportPath: "github.com/carolynvs/deptest-importers", | ||
Revision: "b79bc9482da8bb7402cdc3e3fd984db250718dd7", | ||
Branch: "v2", | ||
}, | ||
}, | ||
} | ||
|
||
h := test.NewHelper(t) | ||
defer h.Cleanup() | ||
|
||
ctx := importertest.NewTestContext(h) | ||
|
||
h.TempCopy(filepath.Join(importertest.RootProject, gvtPath), "manifest") | ||
|
||
projectRoot := h.Path(importertest.RootProject) | ||
|
||
g := NewImporter(ctx.Err, true, nil) | ||
err := g.load(projectRoot) | ||
if err != nil { | ||
t.Fatalf("Error while loading... %v", err) | ||
} | ||
|
||
if !equalImports(g.gvtConfig.Deps, wantConfig.Deps) { | ||
t.Fatalf("Expected imports to be equal. \n\t(GOT): %v\n\t(WNT): %v", g.gvtConfig.Deps, wantConfig.Deps) | ||
} | ||
} | ||
|
||
// equalImports compares two slices of gvtPkg and checks if they are | ||
// equal. | ||
func equalImports(a, b []gvtPkg) bool { | ||
if a == nil && b == nil { | ||
return true | ||
} | ||
|
||
if a == nil || b == nil { | ||
return false | ||
} | ||
|
||
if len(a) != len(b) { | ||
return false | ||
} | ||
|
||
for i := range a { | ||
if a[i] != b[i] { | ||
return false | ||
} | ||
} | ||
|
||
return true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
Detected gvt configuration files... | ||
Converting from vendor/manifest ... | ||
Using ^0.8.1 as initial constraint for imported dep github.com/sdboyer/deptest | ||
Trying v0.8.1 (3f4c3be) as initial lock for imported dep github.com/sdboyer/deptest | ||
Using ^2.0.0 as initial constraint for imported dep github.com/sdboyer/deptestdos | ||
Trying v2.0.0 (5c60720) as initial lock for imported dep github.com/sdboyer/deptestdos | ||
Using v2 as initial constraint for imported dep github.com/carolynvs/deptest-importers | ||
Trying v2 (b79bc94) as initial lock for imported dep github.com/carolynvs/deptest-importers |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"dependencies": [ | ||
{ | ||
"importpath": "github.com/sdboyer/deptest", | ||
"revision": "3f4c3bea144e112a69bbe5d8d01c1b09a544253f" | ||
}, | ||
{ | ||
"importpath": "github.com/sdboyer/deptestdos", | ||
"revision": "5c607206be5decd28e6263ffffdcee067266015e" | ||
}, | ||
{ | ||
"importpath": "github.com/carolynvs/deptest-importers", | ||
"revision": "b79bc9482da8bb7402cdc3e3fd984db250718dd7", | ||
"branch": "v2" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters