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

WIP - Import godep #589

Closed
wants to merge 20 commits into from
Closed
Show file tree
Hide file tree
Changes from 18 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
8 changes: 7 additions & 1 deletion Gopkg.lock

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

4 changes: 4 additions & 0 deletions Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ required = ["github.com/Masterminds/semver"]
name = "github.com/Masterminds/vcs"
version = "^1.11.0"

[[dependencies]]
branch = "v2"
name = "github.com/go-yaml/yaml"

[[dependencies]]
branch = "master"
name = "github.com/pelletier/go-toml"
Expand Down
15 changes: 9 additions & 6 deletions analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,18 @@ import (

type Analyzer struct{}

func (a Analyzer) DeriveManifestAndLock(path string, n gps.ProjectRoot) (gps.Manifest, gps.Lock, error) {
// TODO: If we decide to support other tools manifest, this is where we would need
// to add that support.
func (a Analyzer) HasConfig(path string) bool {
mf := filepath.Join(path, ManifestName)
if fileOK, err := IsRegular(mf); err != nil || !fileOK {
// Do not return an error, when does not exist.
fileOK, err := IsRegular(mf)
return err == nil && fileOK
}

func (a Analyzer) DeriveManifestAndLock(path string, n gps.ProjectRoot) (gps.Manifest, gps.Lock, error) {
if !a.HasConfig(path) {
return nil, nil, nil
}
f, err := os.Open(mf)

f, err := os.Open(filepath.Join(path, ManifestName))
if err != nil {
return nil, nil, err
}
Expand Down
72 changes: 72 additions & 0 deletions cmd/dep/composite_analyzer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// 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 main

import (
"github.com/golang/dep"
"github.com/golang/dep/internal/gps"
"github.com/pkg/errors"
)

// compositeAnalyzer overlays configuration from multiple analyzers
type compositeAnalyzer struct {
// Analyzers is the set of analyzers to apply, last one wins any conflicts
Analyzers []rootProjectAnalyzer
}

func (a compositeAnalyzer) DeriveRootManifestAndLock(path string, n gps.ProjectRoot) (*dep.Manifest, *dep.Lock, error) {
var rootM *dep.Manifest
var rootL *dep.Lock

for _, a := range a.Analyzers {
m, l, err := a.DeriveRootManifestAndLock(path, n)
if err != nil {
return nil, nil, errors.Wrapf(err, "%T.DeriveRootManifestAndLock", a)
}

if rootM == nil && rootL == nil {
rootM = m
rootL = l
} else {
// Overlay the changes from the analyzer on-top of the previous analyzer's work
if m != nil {
for pkg, prj := range m.Dependencies {
rootM.Dependencies[pkg] = prj
}
for pkg, prj := range m.Ovr {
rootM.Ovr[pkg] = prj
}
for _, pkg := range m.Required {
if !contains(rootM.Required, pkg) {
rootM.Required = append(rootM.Required, pkg)
}
}
for _, pkg := range m.Ignored {
if !contains(rootM.Ignored, pkg) {
rootM.Ignored = append(rootM.Ignored, pkg)
}
}
}

if l != nil {
for _, lp := range l.P {
for i, existingLP := range rootL.P {
if lp.Ident().ProjectRoot == existingLP.Ident().ProjectRoot {
rootL.P[i] = lp
}
}
}
Copy link
Collaborator Author

@darkowlzz darkowlzz May 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@carolynvs a little problem here. Overlaying of lock isn't happening in some cases.

Let's take the example of integration test init/godep/case1/.
In godep/case1/testcase.json, although gopath-initial contains deptest, since deptest is a transitive dependency, the default (first analyzer) doesn't adds it to the manifest or lock it generates. And since there's no deptestdos in gopath-initial, the first analyzer generates empty (not nil) manifest and lock structs.
Now in the above code, when overlay is attempted for lock with godep analyzer generated manifest and lock,

for i, existingLP := range rootL.P {

is skipped because rootL is empty from the first analyzer run. And no lock overlay happens.

Makes sense?

The final lock in init/godep/case1/ is incorrect at the moment. Commit hash in final lock is different from the one in Godep.json.

UPDATE: I see you have changed the overlay code in #500 and now it's handling this case :)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah found that I broke overlay at some point. I have a bunch of fixes/pr feedback I'll push tonight. 😊

}
}
}

return rootM, rootL, nil
}

func (a compositeAnalyzer) FinalizeManifestAndLock(m *dep.Manifest, l *dep.Lock) {
for _, a := range a.Analyzers {
a.FinalizeManifestAndLock(m, l)
}
}
181 changes: 181 additions & 0 deletions cmd/dep/composite_analyzer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
// 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 main

import (
"testing"

"github.com/golang/dep"
"github.com/golang/dep/internal/gps"
)

type testRootProjectAnalyzer struct {
*dep.Manifest
*dep.Lock
}

func (a testRootProjectAnalyzer) DeriveRootManifestAndLock(path string, n gps.ProjectRoot) (*dep.Manifest, *dep.Lock, error) {
return a.Manifest, a.Lock, nil
}

func (a testRootProjectAnalyzer) FinalizeManifestAndLock(*dep.Manifest, *dep.Lock) {
// do nothing
}

func TestCompositeAnalyzer_ManifestDependencies(t *testing.T) {
pkg := gps.ProjectRoot("github.com/sdboyer/deptest")
m1 := &dep.Manifest{
Dependencies: gps.ProjectConstraints{
pkg: gps.ProjectProperties{Constraint: gps.NewVersion("^1.0.0")},
},
}
m2 := &dep.Manifest{
Dependencies: gps.ProjectConstraints{
pkg: gps.ProjectProperties{Constraint: gps.NewVersion("^2.0.0")},
},
}
c := compositeAnalyzer{
Analyzers: []rootProjectAnalyzer{
testRootProjectAnalyzer{Manifest: m1},
testRootProjectAnalyzer{Manifest: m2},
},
}

rm, _, err := c.DeriveRootManifestAndLock("", "")
if err != nil {
t.Fatal(err)
}

if rm == nil {
t.Fatal("Expected the root manifest to not be nil")
}

dep, has := rm.Dependencies[pkg]
if !has {
t.Fatal("Expected the root manifest to contain the test project")
}

wantC := "^2.0.0"
gotC := dep.Constraint.String()
if wantC != gotC {
t.Fatalf("Expected the test project to be constrained to '%s', got '%s'", wantC, gotC)
}
}

func TestCompositeAnalyzer_ManifestOverrides(t *testing.T) {
pkg := gps.ProjectRoot("github.com/sdboyer/deptest")
m1 := &dep.Manifest{
Ovr: gps.ProjectConstraints{
pkg: gps.ProjectProperties{Constraint: gps.NewVersion("^1.0.0")},
},
}
m2 := &dep.Manifest{
Ovr: gps.ProjectConstraints{
pkg: gps.ProjectProperties{Constraint: gps.NewVersion("^2.0.0")},
},
}
c := compositeAnalyzer{
Analyzers: []rootProjectAnalyzer{
testRootProjectAnalyzer{Manifest: m1},
testRootProjectAnalyzer{Manifest: m2},
},
}

rm, _, err := c.DeriveRootManifestAndLock("", "")
if err != nil {
t.Fatal(err)
}

if rm == nil {
t.Fatal("Expected the root manifest to not be nil")
}

dep, has := rm.Ovr[pkg]
if !has {
t.Fatal("Expected the root manifest to contain the test project override")
}

wantC := "^2.0.0"
gotC := dep.Constraint.String()
if wantC != gotC {
t.Fatalf("Expected the test project to be overridden to '%s', got '%s'", wantC, gotC)
}
}

func TestCompositeAnalyzer_ManifestRequired(t *testing.T) {
pkg1 := "github.com/sdboyer/deptest"
pkg2 := "github.com/sdboyer/deptestdos"
m1 := &dep.Manifest{
Required: []string{pkg1},
}
m2 := &dep.Manifest{
Required: []string{pkg2},
}
c := compositeAnalyzer{
Analyzers: []rootProjectAnalyzer{
testRootProjectAnalyzer{Manifest: m1},
testRootProjectAnalyzer{Manifest: m2},
},
}

rm, _, err := c.DeriveRootManifestAndLock("", "")
if err != nil {
t.Fatal(err)
}

if rm == nil {
t.Fatal("Expected the root manifest to not be nil")
}

if len(rm.Required) != 2 {
t.Fatalf("Expected the root manifest to contain 2 required packages, got %d", len(rm.Required))
}

if rm.Required[0] != pkg1 {
t.Fatalf("Expected the first required package to be '%s', got '%s'", pkg1, rm.Required[0])
}

if rm.Required[1] != pkg2 {
t.Fatalf("Expected the second required package to be '%s', got '%s'", pkg2, rm.Required[1])
}
}

func TestCompositeAnalyzer_ManifestIgnored(t *testing.T) {
pkg1 := "github.com/sdboyer/deptest"
pkg2 := "github.com/sdboyer/deptestdos"
m1 := &dep.Manifest{
Ignored: []string{pkg1},
}
m2 := &dep.Manifest{
Ignored: []string{pkg2},
}
c := compositeAnalyzer{
Analyzers: []rootProjectAnalyzer{
testRootProjectAnalyzer{Manifest: m1},
testRootProjectAnalyzer{Manifest: m2},
},
}

rm, _, err := c.DeriveRootManifestAndLock("", "")
if err != nil {
t.Fatal(err)
}

if rm == nil {
t.Fatal("Expected the root manifest to not be nil")
}

if len(rm.Ignored) != 2 {
t.Fatalf("Expected the root manifest to contain 2 ignored packages, got %d", len(rm.Ignored))
}

if rm.Ignored[0] != pkg1 {
t.Fatalf("Expected the first ignored package to be '%s', got '%s'", pkg1, rm.Ignored[0])
}

if rm.Ignored[1] != pkg2 {
t.Fatalf("Expected the second ignored package to be '%s', got '%s'", pkg2, rm.Ignored[1])
}
}
Loading