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

Commit

Permalink
gvt (and gb-vendor) importer (#1149)
Browse files Browse the repository at this point in the history
  • Loading branch information
michael-go authored and carolynvs committed Sep 28, 2017
1 parent 0979f44 commit 6fb987b
Show file tree
Hide file tree
Showing 14 changed files with 556 additions and 3 deletions.
2 changes: 1 addition & 1 deletion cmd/dep/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ specified, use the current directory.
When configuration for another dependency management tool is detected, it is
imported into the initial manifest and lock. Use the -skip-tools flag to
disable this behavior. The following external tools are supported:
glide, godep, vndr, govend.
glide, godep, vndr, govend, gb, gvt.
Any dependencies that are not constrained by external configuration use the
GOPATH analysis below.
Expand Down
28 changes: 28 additions & 0 deletions cmd/dep/testdata/harness_tests/init/gvt/case1/final/Gopkg.lock

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

11 changes: 11 additions & 0 deletions cmd/dep/testdata/harness_tests/init/gvt/case1/final/Gopkg.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

[[constraint]]
name = "github.com/sdboyer/deptest"
source = "https://github.com/carolynvs/deptest"

[[constraint]]
name = "github.com/sdboyer/deptestdos"

[[constraint]]
branch = "v2"
name = "gopkg.in/yaml.v2"
20 changes: 20 additions & 0 deletions cmd/dep/testdata/harness_tests/init/gvt/case1/initial/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// 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/deptest"
"github.com/sdboyer/deptestdos"
"gopkg.in/yaml.v2"
)

func main() {
var a deptestdos.Bar
var b yaml.MapItem
var c deptest.Foo
fmt.Println(a, b, c)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"version": "0",
"dependencies": [
{
"importpath": "github.com/sdboyer/deptest",
"repository": "https://github.com/carolynvs/deptest",
"revision": "3f4c3bea144e112a69bbe5d8d01c1b09a544253f",
"branch": "HEAD"
},
{
"importpath": "github.com/sdboyer/deptestdos",
"repository": "https://github.com/sdboyer/deptestdos",
"revision": "5c607206be5decd28e6263ffffdcee067266015eXXX",
"branch": "master"
},
{
"importpath": "gopkg.in/yaml.v2",
"repository": "https://gopkg.in/yaml.v2",
"revision": "f7716cbe52baa25d2e9b0d0da546fcf909fc16b4",
"branch": "v2"
}
]
}
13 changes: 13 additions & 0 deletions cmd/dep/testdata/harness_tests/init/gvt/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"
]
}
2 changes: 1 addition & 1 deletion docs/FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ about what's going on.
During `dep init` configuration from other dependency managers is detected
and imported, unless `-skip-tools` is specified.

The following tools are supported: `glide`, `godep`, `vndr` and `govend`.
The following tools are supported: `glide`, `godep`, `vndr`, `govend`, `gb` and `gvt`.

See [#186](https://github.com/golang/dep/issues/186#issuecomment-306363441) for
how to add support for another tool.
Expand Down
33 changes: 32 additions & 1 deletion internal/importers/base/importer.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,10 +180,21 @@ func (i *Importer) ImportPackages(packages []ImportedPackage, defaultConstraintF
}

for _, prj := range projects {
source := prj.Source
if len(source) > 0 {
isDefault, err := i.isDefaultSource(prj.Root, source)
if err != nil {
i.Logger.Printf(" Ignoring imported source %s for %s: %s", source, prj.Root, err.Error())
source = ""
} else if isDefault {
source = ""
}
}

pc := gps.ProjectConstraint{
Ident: gps.ProjectIdentifier{
ProjectRoot: prj.Root,
Source: prj.Source,
Source: source,
},
}

Expand Down Expand Up @@ -291,3 +302,23 @@ func (i *Importer) convertToConstraint(v gps.Version) gps.Constraint {
}
return v
}

func (i *Importer) isDefaultSource(projectRoot gps.ProjectRoot, sourceURL string) (bool, error) {
// this condition is mainly for gopkg.in imports,
// as some importers specify the repository url as https://gopkg.in/...,
// but sm.SourceURLsForPath() returns https://github.com/... urls for gopkg.in
if sourceURL == "https://"+string(projectRoot) {
return true, nil
}

sourceURLs, err := i.sm.SourceURLsForPath(string(projectRoot))
if err != nil {
return false, err
}
// The first url in the slice will be the default one (usually https://...)
if len(sourceURLs) > 0 && sourceURL == sourceURLs[0].String() {
return true, nil
}

return false, nil
}
24 changes: 24 additions & 0 deletions internal/importers/base/importer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,30 @@ func TestBaseImporter_ImportProjects(t *testing.T) {
},
},
},
"alternate source": {
importertest.TestCase{
WantConstraint: "*",
WantSourceRepo: importertest.ProjectSrc,
},
[]ImportedPackage{
{
Name: importertest.Project,
Source: importertest.ProjectSrc,
},
},
},
"ignoring default source": {
importertest.TestCase{
WantConstraint: "*",
WantSourceRepo: "",
},
[]ImportedPackage{
{
Name: importertest.Project,
Source: "https://" + importertest.Project,
},
},
},
}

for name, tc := range testcases {
Expand Down
129 changes: 129 additions & 0 deletions internal/importers/gvt/importer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// 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. It handles gb (gb-vendor) too as they share a common manifest file & format
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 gb/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 == "HEAD" {
// gb-vendor sets "branch" to "HEAD", if the package was feteched via -tag or -revision,
// we pass the revision as the constraint hint
contstraintHint = pkg.Revision
} else if pkg.Branch != "master" {
// both gvt & gb-vendor set "branch" to "master" unless a different branch was requested.
// so it's not realy a constraint unless it's a different branch
contstraintHint = pkg.Branch
}

ip := base.ImportedPackage{
Name: pkg.ImportPath,
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
}
Loading

0 comments on commit 6fb987b

Please sign in to comment.