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

Add importer for github.com/robfig/glock #1422

Merged
merged 1 commit into from
Dec 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# v0.3.3 (Unreleased)

NEW FEATURES:
* Add support for importing from [glock](https://github.com/robfig/glock) based projects (#1422).
* Add support for importing from [govendor](https://github.com/kardianos/govendor)
based projects (#815).

Expand Down
2 changes: 1 addition & 1 deletion cmd/dep/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
// 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, gb, gvt.
// glide, godep, vndr, govend, gb, gvt, glock.
//
// Any dependencies that are not constrained by external configuration use the
// GOPATH analysis below.
Expand Down
2 changes: 1 addition & 1 deletion cmd/dep/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,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, gb, gvt, govendor.
glide, godep, vndr, govend, gb, gvt, govendor, glock.
Any dependencies that are not constrained by external configuration use the
GOPATH analysis below.
Expand Down

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"
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
cmd github.com/golang/lint
github.com/sdboyer/deptest 3f4c3bea144e112a69bbe5d8d01c1b09a544253f
github.com/sdboyer/deptestdos 5c607206be5decd28e6263ffffdcee067266015e
16 changes: 16 additions & 0 deletions cmd/dep/testdata/harness_tests/init/glock/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)
}
13 changes: 13 additions & 0 deletions cmd/dep/testdata/harness_tests/init/glock/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 @@ -217,7 +217,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`, `govend`, `gb`, `gvt` and `govendor`.
The following tools are supported: `glide`, `godep`, `vndr`, `govend`, `gb`, `gvt`, `govendor` and `glock`.

See [#186](https://github.com/golang/dep/issues/186#issuecomment-306363441) for
how to add support for another tool.
Expand Down
139 changes: 139 additions & 0 deletions internal/importers/glock/importer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
// Copyright 2016 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 glock

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

"github.com/golang/dep"
"github.com/golang/dep/gps"
"github.com/golang/dep/internal/importers/base"
"github.com/pkg/errors"
)

const glockfile = "GLOCKFILE"

// Importer imports glock configuration into the dep configuration format.
type Importer struct {
*base.Importer

packages []glockPackage
}

// NewImporter for glock.
func NewImporter(logger *log.Logger, verbose bool, sm gps.SourceManager) *Importer {
return &Importer{Importer: base.NewImporter(logger, verbose, sm)}
}

// Name of the importer.
func (g *Importer) Name() string {
return "glock"
}

// HasDepMetadata checks if a directory contains config that the importer can handle.
func (g *Importer) HasDepMetadata(dir string) bool {
path := filepath.Join(dir, glockfile)
if _, err := os.Stat(path); 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)
}

type glockPackage struct {
importPath string
revision string
}

func (g *Importer) load(projectDir string) error {
g.Logger.Println("Detected glock configuration files...")
path := filepath.Join(projectDir, glockfile)
if g.Verbose {
g.Logger.Printf(" Loading %s", path)
}

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

scanner := bufio.NewScanner(f)
for scanner.Scan() {
pkg, err := parseGlockLine(scanner.Text())
if err != nil {
return err
}
if pkg == nil {
continue
}
g.packages = append(g.packages, *pkg)
}

return nil
}

func parseGlockLine(line string) (*glockPackage, error) {
fields := strings.Fields(line)
switch len(fields) {
case 2: // Valid.
case 0: // Skip empty lines.
return nil, nil
default:
return nil, fmt.Errorf("invalid glock configuration: %s", line)
}

// Skip commands.
if fields[0] == "cmd" {
return nil, nil
}
return &glockPackage{
importPath: fields[0],
revision: fields[1],
}, nil
}

func (g *Importer) convert(pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, error) {
g.Logger.Println("Converting from GLOCKFILE ...")

packages := make([]base.ImportedPackage, 0, len(g.packages))
for _, pkg := range g.packages {
// Validate
if pkg.importPath == "" {
return nil, nil, errors.New("invalid glock configuration, import path is required")
}

if pkg.revision == "" {
return nil, nil, errors.New("invalid glock configuration, revision is required")
}

packages = append(packages, base.ImportedPackage{
Name: pkg.importPath,
LockHint: pkg.revision,
})
}

err := g.ImportPackages(packages, true)
if err != nil {
return nil, nil, err
}

return g.Manifest, g.Lock, nil
}
133 changes: 133 additions & 0 deletions internal/importers/glock/importer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
// Copyright 2016 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 glock

import (
"bytes"
"fmt"
"log"
"path/filepath"
"testing"

"github.com/golang/dep"
"github.com/golang/dep/gps"
"github.com/golang/dep/internal/importers/importertest"
"github.com/golang/dep/internal/test"
"github.com/pkg/errors"
)

func TestGlockConfig_Convert(t *testing.T) {
testCases := map[string]struct {
importertest.TestCase
packages []glockPackage
}{
"package": {
importertest.TestCase{
WantConstraint: importertest.V1Constraint,
WantRevision: importertest.V1Rev,
WantVersion: importertest.V1Tag,
},
[]glockPackage{
{
importPath: importertest.Project,
revision: importertest.V1Rev,
},
},
},
"missing package name": {
importertest.TestCase{
WantConvertErr: true,
},
[]glockPackage{{importPath: ""}},
},
"missing revision": {
importertest.TestCase{
WantConvertErr: true,
},
[]glockPackage{{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.packages = testCase.packages
return g.convert(importertest.RootProject)
})
if err != nil {
t.Fatalf("%#v", err)
}
})
}
}

func TestGlockConfig_LoadInvalid(t *testing.T) {
const testLine = "github.com/sdboyer/deptest 3f4c3bea144e112a69bbe5d8d01c1b09a544253f invalid"
_, err := parseGlockLine(testLine)
expected := fmt.Errorf("invalid glock configuration: %s", testLine)
if err.Error() != expected.Error() {
t.Errorf("want error %s, got %s", err, expected)
}
}

func TestGlockConfig_LoadEmptyLine(t *testing.T) {
pkg, err := parseGlockLine("")
if err != nil {
t.Fatalf("%#v", err)
}
if pkg != nil {
t.Errorf("want package nil, got %+v", pkg)
}
}

func TestGlockConfig_Import(t *testing.T) {
h := test.NewHelper(t)
defer h.Cleanup()

ctx := importertest.NewTestContext(h)
sm, err := ctx.SourceManager()
h.Must(err)
defer sm.Release()

h.TempDir(filepath.Join("src", importertest.RootProject))
h.TempCopy(filepath.Join(importertest.RootProject, glockfile), glockfile)
projectRoot := h.Path(importertest.RootProject)

// Capture stderr so we can verify output
verboseOutput := &bytes.Buffer{}
ctx.Err = log.New(verboseOutput, "", 0)

g := NewImporter(ctx.Err, 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 the glock configuration files")
}

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)
}
}
}
3 changes: 3 additions & 0 deletions internal/importers/glock/testdata/GLOCKFILE
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
cmd github.com/golang/lint
github.com/sdboyer/deptest 3f4c3bea144e112a69bbe5d8d01c1b09a544253f
github.com/sdboyer/deptestdos 5c607206be5decd28e6263ffffdcee067266015e
6 changes: 6 additions & 0 deletions internal/importers/glock/testdata/golden.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Detected glock configuration files...
Converting from GLOCKFILE ...
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
2 changes: 2 additions & 0 deletions internal/importers/importers.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/golang/dep"
"github.com/golang/dep/gps"
"github.com/golang/dep/internal/importers/glide"
"github.com/golang/dep/internal/importers/glock"
"github.com/golang/dep/internal/importers/godep"
"github.com/golang/dep/internal/importers/govend"
"github.com/golang/dep/internal/importers/govendor"
Expand Down Expand Up @@ -39,5 +40,6 @@ func BuildAll(logger *log.Logger, verbose bool, sm gps.SourceManager) []Importer
govend.NewImporter(logger, verbose, sm),
gvt.NewImporter(logger, verbose, sm),
govendor.NewImporter(logger, verbose, sm),
glock.NewImporter(logger, verbose, sm),
}
}