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.
Add godepFile load, convert and godep importer
- Loading branch information
Showing
5 changed files
with
354 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,102 @@ | ||
package main | ||
|
||
import ( | ||
"encoding/json" | ||
"io/ioutil" | ||
"path/filepath" | ||
|
||
"github.com/golang/dep" | ||
"github.com/golang/dep/internal/gps" | ||
"github.com/pkg/errors" | ||
) | ||
|
||
type godepFile struct { | ||
json godepJson | ||
loggers *dep.Loggers | ||
} | ||
|
||
func newGodepFile(loggers *dep.Loggers) *godepFile { | ||
return &godepFile{loggers: loggers} | ||
} | ||
|
||
type godepJson struct { | ||
Name string `json:"ImportPath"` | ||
Imports []godepPackage `json:"Deps"` | ||
} | ||
|
||
type godepPackage struct { | ||
ImportPath string `json:"ImportPath"` | ||
Rev string `json:"Rev"` | ||
Comment string `json:"Comment"` | ||
} | ||
|
||
// load parses Godeps.json in projectDir and unmarshals the json to godepFile.json | ||
func (g *godepFile) load(projectDir string) error { | ||
j := filepath.Join(projectDir, "Godeps", godepJsonName) | ||
if g.loggers.Verbose { | ||
g.loggers.Err.Printf("godep: Loading %s", j) | ||
} | ||
|
||
raw, err := ioutil.ReadFile(j) | ||
if err != nil { | ||
return errors.Wrapf(err, "Unable to read %s", j) | ||
} | ||
err = json.Unmarshal(raw, &g.json) | ||
|
||
return nil | ||
} | ||
|
||
func (g *godepFile) convert(projectName string, sm gps.SourceManager) (*dep.Manifest, *dep.Lock, error) { | ||
// Create empty manifest and lock | ||
manifest := &dep.Manifest{ | ||
Dependencies: make(gps.ProjectConstraints), | ||
} | ||
lock := &dep.Lock{} | ||
|
||
// Parse through each import and add them to manifest and lock | ||
for _, pkg := range g.json.Imports { | ||
// ImportPath must not be empty | ||
if pkg.ImportPath == "" { | ||
err := errors.New("godep: Invalid godep configuration, ImportPath is required") | ||
return nil, nil, err | ||
} | ||
|
||
if pkg.Comment != "" { | ||
// If there's a comment, use it to create project constraint | ||
pc, err := g.buildProjectConstraint(pkg, sm) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
manifest.Dependencies[pc.Ident.ProjectRoot] = gps.ProjectProperties{Source: pc.Ident.Source, Constraint: pc.Constraint} | ||
} | ||
|
||
if pkg.Rev != "" { | ||
// Use the revision to create lock project | ||
lp := g.buildLockedProject(pkg, manifest) | ||
lock.P = append(lock.P, lp) | ||
} | ||
} | ||
|
||
return manifest, lock, nil | ||
} | ||
|
||
func (g *godepFile) buildProjectConstraint(pkg godepPackage, sm gps.SourceManager) (pc gps.ProjectConstraint, err error) { | ||
pc.Ident = gps.ProjectIdentifier{ProjectRoot: gps.ProjectRoot(pkg.ImportPath), Source: pkg.ImportPath} | ||
pc.Constraint, err = deduceConstraint(pkg.Comment, pc.Ident, sm) | ||
return | ||
} | ||
|
||
func (g *godepFile) buildLockedProject(pkg godepPackage, manifest *dep.Manifest) gps.LockedProject { | ||
var ver gps.Version | ||
id := gps.ProjectIdentifier{ProjectRoot: gps.ProjectRoot(pkg.ImportPath), Source: pkg.ImportPath} | ||
c, has := manifest.Dependencies[id.ProjectRoot] | ||
if has { | ||
// Create PairedVersion if constraint details are available | ||
version := gps.NewVersion(c.Constraint.String()) | ||
ver = version.Is(gps.Revision(pkg.Rev)) | ||
} else { | ||
ver = gps.Revision(pkg.Rev) | ||
} | ||
|
||
return gps.NewLockedProject(id, ver, 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,149 @@ | ||
package main | ||
|
||
import ( | ||
"log" | ||
"os" | ||
"path/filepath" | ||
"testing" | ||
|
||
"github.com/golang/dep" | ||
"github.com/golang/dep/internal/test" | ||
) | ||
|
||
const testGodepProjectRoot = "github.com/golang/notexist" | ||
|
||
func TestGodepJsonLoad(t *testing.T) { | ||
// This is same as cmd/dep/testdata/Godeps.json | ||
wantJSON := godepJson{ | ||
Name: "github.com/golang/notexist", | ||
Imports: []godepPackage{ | ||
{ | ||
ImportPath: "github.com/sdboyer/deptest", | ||
Rev: "3f4c3bea144e112a69bbe5d8d01c1b09a544253f", | ||
}, | ||
{ | ||
ImportPath: "github.com/sdboyer/deptestdos", | ||
Rev: "5c607206be5decd28e6263ffffdcee067266015e", | ||
Comment: "v2.0.0", | ||
}, | ||
}, | ||
} | ||
|
||
h := test.NewHelper(t) | ||
defer h.Cleanup() | ||
|
||
h.TempCopy(filepath.Join(testGodepProjectRoot, "Godeps", godepJsonName), "Godeps.json") | ||
|
||
projectRoot := h.Path(testGodepProjectRoot) | ||
|
||
g := &godepFile{ | ||
loggers: &dep.Loggers{ | ||
Out: log.New(os.Stderr, "", 0), | ||
Err: log.New(os.Stderr, "", 0), | ||
Verbose: true, | ||
}, | ||
} | ||
err := g.load(projectRoot) | ||
if err != nil { | ||
t.Fatalf("Error while loading... %v", err) | ||
} | ||
|
||
if g.json.Name != wantJSON.Name { | ||
t.Fatalf("Expected project name to be %v, but got %v", wantJSON.Name, g.json.Name) | ||
} | ||
|
||
if !equalImports(g.json.Imports, wantJSON.Imports) { | ||
t.Fatalf("Expected imports to be equal. \n\t(GOT): %v\n\t(WNT): %v", g.json.Imports, wantJSON.Imports) | ||
} | ||
} | ||
|
||
func TestGodepConvertProject(t *testing.T) { | ||
loggers := &dep.Loggers{ | ||
Out: log.New(os.Stdout, "", 0), | ||
Err: log.New(os.Stderr, "", 0), | ||
Verbose: true, | ||
} | ||
|
||
f := godepFile{ | ||
loggers: loggers, | ||
json: godepJson{ | ||
Name: "github.com/foo/bar", | ||
Imports: []godepPackage{ | ||
{ | ||
ImportPath: "github.com/sdboyer/deptest", | ||
Rev: "6a741be0cc55ecbe4f45690ebfd606a956d5f14a", | ||
Comment: "v1.0.0", | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
manifest, lock, err := f.convert("", nil) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
d, ok := manifest.Dependencies["github.com/sdboyer/deptest"] | ||
if !ok { | ||
t.Fatal("Expected the manifest to have a dependency for 'github.com/sdboyer/deptest' but got none") | ||
} | ||
|
||
v := d.Constraint.String() | ||
if v != "v1.0.0" { | ||
t.Fatalf("Expected manifest constraint to be master, got %s", v) | ||
} | ||
|
||
p := lock.P[0] | ||
if p.Ident().ProjectRoot != "github.com/sdboyer/deptest" { | ||
t.Fatalf("Expected the lock to have a project for 'github.com/sdboyer/deptest' but got '%s'", p.Ident().ProjectRoot) | ||
} | ||
|
||
lv := p.Version().String() | ||
if lv != "v1.0.0" { | ||
t.Fatalf("Expected locked revision to be 'v1.0.0', got %s", lv) | ||
} | ||
} | ||
|
||
func TestGodepConvertBadInput_EmptyPackageName(t *testing.T) { | ||
loggers := &dep.Loggers{ | ||
Out: log.New(os.Stdout, "", 0), | ||
Err: log.New(os.Stderr, "", 0), | ||
Verbose: true, | ||
} | ||
|
||
f := godepFile{ | ||
loggers: loggers, | ||
json: godepJson{ | ||
Imports: []godepPackage{{ImportPath: ""}}, | ||
}, | ||
} | ||
|
||
_, _, err := f.convert("", nil) | ||
if err == nil { | ||
t.Fatal("Expected conversion to fail because the ImportPath is empty") | ||
} | ||
} | ||
|
||
// Compares two slices of godepPackage and checks if they are equal. | ||
func equalImports(a, b []godepPackage) 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,39 @@ | ||
package main | ||
|
||
import ( | ||
"os" | ||
"path/filepath" | ||
|
||
"github.com/golang/dep" | ||
"github.com/golang/dep/internal/gps" | ||
) | ||
|
||
const godepJsonName = "Godeps.json" | ||
|
||
type godepImporter struct { | ||
loggers *dep.Loggers | ||
sm gps.SourceManager | ||
} | ||
|
||
func newGodepImporter(loggers *dep.Loggers, sm gps.SourceManager) *godepImporter { | ||
return &godepImporter{loggers: loggers, sm: sm} | ||
} | ||
|
||
func (i godepImporter) HasConfig(dir string) bool { | ||
y := filepath.Join(dir, "Godeps", godepJsonName) | ||
if _, err := os.Stat(y); err != nil { | ||
return false | ||
} | ||
|
||
return true | ||
} | ||
|
||
func (i godepImporter) Import(dir string, pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, error) { | ||
file := newGodepFile(i.loggers) | ||
err := file.load(dir) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
return file.convert(string(pr), i.sm) | ||
} |
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,48 @@ | ||
package main | ||
|
||
import ( | ||
"log" | ||
"os" | ||
"path/filepath" | ||
"testing" | ||
|
||
"github.com/golang/dep" | ||
"github.com/golang/dep/internal/gps" | ||
"github.com/golang/dep/internal/test" | ||
) | ||
|
||
func TestGodepImport(t *testing.T) { | ||
h := test.NewHelper(t) | ||
defer h.Cleanup() | ||
|
||
cacheDir := "gps-repocache" | ||
h.TempDir(cacheDir) | ||
h.TempDir("src") | ||
h.TempDir(filepath.Join("src", testGlideProjectRoot)) | ||
h.TempCopy(filepath.Join(testGodepProjectRoot, "Godeps", godepJsonName), "Godeps.json") | ||
|
||
loggers := &dep.Loggers{ | ||
Out: log.New(os.Stdout, "", 0), | ||
Err: log.New(os.Stderr, "", 0), | ||
Verbose: true, | ||
} | ||
projectRoot := h.Path(testGodepProjectRoot) | ||
sm, err := gps.NewSourceManager(h.Path(cacheDir)) | ||
h.Must(err) | ||
|
||
i := newGodepImporter(loggers, sm) | ||
if !i.HasConfig(projectRoot) { | ||
t.Fatal("Expected the importer to detect the godep configuration file") | ||
} | ||
|
||
m, l, err := i.Import(projectRoot, gps.ProjectRoot(testGodepProjectRoot)) | ||
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") | ||
} | ||
} |
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,16 @@ | ||
{ | ||
"ImportPath": "github.com/golang/notexist", | ||
"GoVersion": "go1.8", | ||
"GodepVersion": "vXYZ", | ||
"Deps": [ | ||
{ | ||
"ImportPath": "github.com/sdboyer/deptest", | ||
"Rev": "3f4c3bea144e112a69bbe5d8d01c1b09a544253f" | ||
}, | ||
{ | ||
"ImportPath": "github.com/sdboyer/deptestdos", | ||
"Comment": "v2.0.0", | ||
"Rev": "5c607206be5decd28e6263ffffdcee067266015e" | ||
} | ||
] | ||
} |