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/robfig/glock
Browse files Browse the repository at this point in the history
  • Loading branch information
s111 committed Dec 1, 2017
1 parent ef6a28f commit 43b1b5b
Show file tree
Hide file tree
Showing 14 changed files with 344 additions and 3 deletions.
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
21 changes: 21 additions & 0 deletions cmd/dep/testdata/harness_tests/init/glock/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"
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),
}
}

0 comments on commit 43b1b5b

Please sign in to comment.