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

Commit

Permalink
Add importer for github.com/LK4D4/vndr (#978)
Browse files Browse the repository at this point in the history
  • Loading branch information
spenczar authored and carolynvs committed Aug 11, 2017
1 parent c20daf3 commit 4f22124
Show file tree
Hide file tree
Showing 12 changed files with 545 additions and 22 deletions.
28 changes: 13 additions & 15 deletions cmd/dep/glide_importer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ import (
"github.com/pkg/errors"
)

const testGlideProjectRoot = "github.com/golang/notexist"

var (
discardLogger = log.New(ioutil.Discard, "", 0)
)
Expand Down Expand Up @@ -110,7 +108,7 @@ func TestGlideConfig_Convert(t *testing.T) {
yaml: glideYaml{
ExcludeDirs: []string{"samples"},
},
projectRoot: testGlideProjectRoot,
projectRoot: testProjectRoot,
wantIgnoreCount: 1,
wantIgnoredPackages: []string{"github.com/golang/notexist/samples"},
},
Expand All @@ -119,15 +117,15 @@ func TestGlideConfig_Convert(t *testing.T) {
Name: "github.com/golang/mismatched-package-name",
ExcludeDirs: []string{"samples"},
},
projectRoot: testGlideProjectRoot,
projectRoot: testProjectRoot,
wantIgnoreCount: 1,
wantIgnoredPackages: []string{"github.com/golang/notexist/samples"},
},
"bad input, empty package name": {
yaml: glideYaml{
Imports: []glidePackage{{Name: ""}},
},
projectRoot: testGlideProjectRoot,
projectRoot: testProjectRoot,
wantConvertErr: true,
},
}
Expand Down Expand Up @@ -243,10 +241,10 @@ func TestGlideConfig_Import(t *testing.T) {
h.Must(err)
defer sm.Release()

h.TempDir(filepath.Join("src", testGlideProjectRoot))
h.TempCopy(filepath.Join(testGlideProjectRoot, glideYamlName), "glide/glide.yaml")
h.TempCopy(filepath.Join(testGlideProjectRoot, glideLockName), "glide/glide.lock")
projectRoot := h.Path(testGlideProjectRoot)
h.TempDir(filepath.Join("src", testProjectRoot))
h.TempCopy(filepath.Join(testProjectRoot, glideYamlName), "glide/glide.yaml")
h.TempCopy(filepath.Join(testProjectRoot, glideLockName), "glide/glide.lock")
projectRoot := h.Path(testProjectRoot)

// Capture stderr so we can verify output
verboseOutput := &bytes.Buffer{}
Expand All @@ -257,7 +255,7 @@ func TestGlideConfig_Import(t *testing.T) {
t.Fatal("Expected the importer to detect the glide configuration files")
}

m, l, err := g.Import(projectRoot, testGlideProjectRoot)
m, l, err := g.Import(projectRoot, testProjectRoot)
h.Must(err)

if m == nil {
Expand Down Expand Up @@ -291,16 +289,16 @@ func TestGlideConfig_Import_MissingLockFile(t *testing.T) {
h.Must(err)
defer sm.Release()

h.TempDir(filepath.Join("src", testGlideProjectRoot))
h.TempCopy(filepath.Join(testGlideProjectRoot, glideYamlName), "glide/glide.yaml")
projectRoot := h.Path(testGlideProjectRoot)
h.TempDir(filepath.Join("src", testProjectRoot))
h.TempCopy(filepath.Join(testProjectRoot, glideYamlName), "glide/glide.yaml")
projectRoot := h.Path(testProjectRoot)

g := newGlideImporter(ctx.Err, true, sm)
if !g.HasDepMetadata(projectRoot) {
t.Fatal("The glide importer should gracefully handle when only glide.yaml is present")
}

m, l, err := g.Import(projectRoot, testGlideProjectRoot)
m, l, err := g.Import(projectRoot, testProjectRoot)
h.Must(err)

if m == nil {
Expand Down Expand Up @@ -340,7 +338,7 @@ func TestGlideConfig_Convert_WarnsForUnusedFields(t *testing.T) {
Imports: []glidePackage{pkg},
}

_, _, err = g.convert(testGlideProjectRoot)
_, _, err = g.convert(testProjectRoot)
if err != nil {
t.Fatal(err)
}
Expand Down
14 changes: 7 additions & 7 deletions cmd/dep/godep_importer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
"github.com/pkg/errors"
)

const testGodepProjectRoot = "github.com/golang/notexist"
const testProjectRoot = "github.com/golang/notexist"

func TestGodepConfig_Convert(t *testing.T) {
testCases := map[string]struct {
Expand Down Expand Up @@ -198,10 +198,10 @@ func TestGodepConfig_Import(t *testing.T) {
cacheDir := "gps-repocache"
h.TempDir(cacheDir)
h.TempDir("src")
h.TempDir(filepath.Join("src", testGodepProjectRoot))
h.TempCopy(filepath.Join(testGodepProjectRoot, godepPath), "godep/Godeps.json")
h.TempDir(filepath.Join("src", testProjectRoot))
h.TempCopy(filepath.Join(testProjectRoot, godepPath), "godep/Godeps.json")

projectRoot := h.Path(testGodepProjectRoot)
projectRoot := h.Path(testProjectRoot)
sm, err := gps.NewSourceManager(h.Path(cacheDir))
h.Must(err)
defer sm.Release()
Expand All @@ -215,7 +215,7 @@ func TestGodepConfig_Import(t *testing.T) {
t.Fatal("Expected the importer to detect godep configuration file")
}

m, l, err := g.Import(projectRoot, testGodepProjectRoot)
m, l, err := g.Import(projectRoot, testProjectRoot)
h.Must(err)

if m == nil {
Expand Down Expand Up @@ -261,9 +261,9 @@ func TestGodepConfig_JsonLoad(t *testing.T) {

ctx := newTestContext(h)

h.TempCopy(filepath.Join(testGodepProjectRoot, godepPath), "godep/Godeps.json")
h.TempCopy(filepath.Join(testProjectRoot, godepPath), "godep/Godeps.json")

projectRoot := h.Path(testGodepProjectRoot)
projectRoot := h.Path(testProjectRoot)

g := newGodepImporter(ctx.Err, true, nil)
err := g.load(projectRoot)
Expand Down
1 change: 1 addition & 0 deletions cmd/dep/root_analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ func (a *rootAnalyzer) importManifestAndLock(dir string, pr gps.ProjectRoot, sup
importers := []importer{
newGlideImporter(logger, a.ctx.Verbose, a.sm),
newGodepImporter(logger, a.ctx.Verbose, a.sm),
newVndrImporter(logger, a.ctx.Verbose, a.sm),
}

for _, i := range importers {
Expand Down
21 changes: 21 additions & 0 deletions cmd/dep/testdata/harness_tests/init/vndr/case1/final/Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

[[constraint]]
name = "github.com/sdboyer/deptestdos"
version = "2.0.0"
16 changes: 16 additions & 0 deletions cmd/dep/testdata/harness_tests/init/vndr/case1/initial/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// 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 main

import (
"fmt"

"github.com/sdboyer/deptestdos"
)

func main() {
var x deptestdos.Bar
fmt.Println(x)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Comment on its own line
github.com/sdboyer/deptest 3f4c3bea144e112a69bbe5d8d01c1b09a544253f https://github.com/sdboyer/deptest.git
github.com/sdboyer/deptestdos v2.0.0
13 changes: 13 additions & 0 deletions cmd/dep/testdata/harness_tests/init/vndr/case1/testcase.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"commands": [
["init", "-no-examples"]
],
"error-expected": "",
"gopath-initial": {
"github.com/sdboyer/deptest": "3f4c3bea144e112a69bbe5d8d01c1b09a544253f"
},
"vendor-final": [
"github.com/sdboyer/deptest",
"github.com/sdboyer/deptestdos"
]
}
6 changes: 6 additions & 0 deletions cmd/dep/testdata/vndr/golden.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Detected vndr configuration file...
Converting from vendor.conf...
Using 3f4c3bea144e112a69bbe5d8d01c1b09a544253f as initial hint 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) as initial lock for imported dep github.com/sdboyer/deptestdos
4 changes: 4 additions & 0 deletions cmd/dep/testdata/vndr/vendor.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
github.com/sdboyer/deptest 3f4c3bea144e112a69bbe5d8d01c1b09a544253f https://github.com/sdboyer/deptest.git # trailing comment
# line comment

github.com/sdboyer/deptestdos v2.0.0 # trailing comment
161 changes: 161 additions & 0 deletions cmd/dep/vndr_importer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
// 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 main

import (
"bufio"
"log"
"os"
"path/filepath"
"strings"

"github.com/golang/dep"
fb "github.com/golang/dep/internal/feedback"
"github.com/golang/dep/internal/gps"
"github.com/pkg/errors"
)

func vndrFile(dir string) string {
return filepath.Join(dir, "vendor.conf")
}

type vndrImporter struct {
packages []vndrPackage

logger *log.Logger
verbose bool
sm gps.SourceManager
}

func newVndrImporter(log *log.Logger, verbose bool, sm gps.SourceManager) *vndrImporter {
return &vndrImporter{
logger: log,
verbose: verbose,
sm: sm,
}
}

func (v *vndrImporter) Name() string { return "vndr" }

func (v *vndrImporter) HasDepMetadata(dir string) bool {
_, err := os.Stat(vndrFile(dir))
return err == nil
}

func (v *vndrImporter) Import(dir string, pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, error) {
v.logger.Println("Detected vndr configuration file...")

err := v.loadVndrFile(dir)
if err != nil {
return nil, nil, errors.Wrapf(err, "unable to load vndr file")
}

return v.convert(pr)
}

func (v *vndrImporter) loadVndrFile(dir string) error {
v.logger.Printf("Converting from vendor.conf...")

f, err := os.Open(vndrFile(dir))
if err != nil {
return errors.Wrapf(err, "Unable to open %s", vndrFile(dir))
}
defer f.Close()

scanner := bufio.NewScanner(f)
for scanner.Scan() {
pkg, err := parseVndrLine(scanner.Text())
if err != nil {
return errors.Wrapf(err, "unable to parse line")
}
if pkg == nil {
// Could be an empty line or one which is just a comment
continue
}
v.packages = append(v.packages, *pkg)
}

if scanner.Err() != nil {
return errors.Wrapf(err, "unable to read %s", vndrFile(dir))
}

return nil
}

func (v *vndrImporter) convert(pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, error) {
var (
manifest = &dep.Manifest{
Constraints: make(gps.ProjectConstraints),
}
lock = &dep.Lock{}
err error
)

for _, pkg := range v.packages {
pc := gps.ProjectConstraint{
Ident: gps.ProjectIdentifier{
ProjectRoot: gps.ProjectRoot(pkg.importPath),
Source: pkg.repository,
},
}
pc.Constraint, err = v.sm.InferConstraint(pkg.revision, pc.Ident)
if err != nil {
return nil, nil, errors.Wrapf(err, "Unable to interpret revision specifier '%s' for package %s", pkg.importPath, pkg.revision)
}

manifest.Constraints[pc.Ident.ProjectRoot] = gps.ProjectProperties{
Source: pc.Ident.Source,
Constraint: pc.Constraint,
}
fb.NewConstraintFeedback(pc, fb.DepTypeImported).LogFeedback(v.logger)

revision := gps.Revision(pkg.revision)
version, err := lookupVersionForLockedProject(pc.Ident, pc.Constraint, revision, v.sm)
if err != nil {
v.logger.Println(err.Error())
}

lp := gps.NewLockedProject(pc.Ident, version, nil)

lock.P = append(lock.P, lp)
fb.NewLockedProjectFeedback(lp, fb.DepTypeImported).LogFeedback(v.logger)
}

return manifest, lock, nil
}

type vndrPackage struct {
importPath string
revision string
repository string
}

func parseVndrLine(line string) (*vndrPackage, error) {
commentIdx := strings.Index(line, "#")
if commentIdx >= 0 {
line = line[:commentIdx]
}
line = strings.TrimSpace(line)

if line == "" {
return nil, nil
}

parts := strings.Fields(line)

if !(len(parts) == 2 || len(parts) == 3) {
return nil, errors.Errorf("invalid config format: %q", line)
}

pkg := &vndrPackage{
importPath: parts[0],
revision: parts[1],
}
if len(parts) == 3 {
pkg.repository = parts[2]
}

return pkg, nil
}
Loading

0 comments on commit 4f22124

Please sign in to comment.