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

Commit

Permalink
Add -gopath flag to init
Browse files Browse the repository at this point in the history
- Separate network mode and GOPATH mode of operations.
- In GOPATH mode, fetch projectData by searching through the current
GOPATH. Solve the dependency constraints based on the projects found on
disk and use network to solve for projects not found on disk.
- In Network mode, do not check GOPATH or any ondisk projects. Solve the
dependency constraints completely over network.
  • Loading branch information
darkowlzz committed May 13, 2017
1 parent b86ad16 commit 3b22acb
Show file tree
Hide file tree
Showing 9 changed files with 148 additions and 47 deletions.
124 changes: 80 additions & 44 deletions cmd/dep/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,19 @@ Initialize the project at filepath root by parsing its dependencies, writing
manifest and lock files, and vendoring the dependencies. If root isn't
specified, use the current directory.
The version of each dependency will reflect the current state of the GOPATH. If
a dependency doesn't exist in the GOPATH, a version will be selected from the
versions available from the upstream source per the following algorithm:
By default, the dependencies are resolved over the network. A version will be
selected from the versions available from the upstream source per the following
algorithm:
- Tags conforming to semver (sorted by semver rules)
- Default branch(es) (sorted lexicographically)
- Non-semver tags (sorted lexicographically)
An alternate mode can be activated by passing -gopath. In this mode, version of
each dependency will reflect the current state of the GOPATH. If a dependency
doesn't exist in the GOPATH, a version will be selected based on the above
network version selection algorithm.
A Gopkg.toml file will be written with inferred version constraints for all
direct dependencies. Gopkg.lock will be written with precise versions, and
vendor/ will be populated with the precise versions written to Gopkg.lock.
Expand All @@ -48,10 +53,12 @@ func (cmd *initCommand) Hidden() bool { return false }

func (cmd *initCommand) Register(fs *flag.FlagSet) {
fs.BoolVar(&cmd.noExamples, "no-examples", false, "don't include example in Gopkg.toml")
fs.BoolVar(&cmd.gopath, "gopath", false, "search in GOPATH for dependencies")
}

type initCommand struct {
noExamples bool
gopath bool
}

func trimPathPrefix(p1, p2 string) string {
Expand Down Expand Up @@ -115,44 +122,55 @@ func (cmd *initCommand) Run(ctx *dep.Ctx, args []string) error {
sm.UseDefaultSignalHandling()
defer sm.Release()

ctx.Loggers.Err.Println("Searching GOPATH for projects...")
pd, err := getProjectData(ctx, pkgT, cpr, sm)
if err != nil {
return err
}
// Create empty manifest, lock and projectData, and fill them according to
// init operation modes. If gopath flag is set, fetch projectData by searching
// through GOPATH, else operate in network mode, solve all the dependencies
// over network.
m := &dep.Manifest{
Dependencies: pd.constraints,
Dependencies: make(gps.ProjectConstraints),
}
l := &dep.Lock{}
var pd projectData

// Make an initial lock from what knowledge we've collected about the
// versions on disk
l := &dep.Lock{
P: make([]gps.LockedProject, 0, len(pd.ondisk)),
}
if cmd.gopath {
ctx.Loggers.Err.Println("Searching GOPATH for projects...")
pd, err = getProjectData(ctx, pkgT, cpr, sm)
if err != nil {
return err
}

for pr, v := range pd.ondisk {
// That we have to chop off these path prefixes is a symptom of
// a problem in gps itself
pkgs := make([]string, 0, len(pd.dependencies[pr]))
prslash := string(pr) + "/"
for _, pkg := range pd.dependencies[pr] {
if pkg == string(pr) {
pkgs = append(pkgs, ".")
} else {
pkgs = append(pkgs, trimPathPrefix(pkg, prslash))
}
m.Dependencies = pd.constraints

// Make an initial lock from what knowledge we've collected about the
// versions on disk
l = &dep.Lock{
P: make([]gps.LockedProject, 0, len(pd.ondisk)),
}

l.P = append(l.P, gps.NewLockedProject(
gps.ProjectIdentifier{ProjectRoot: pr}, v, pkgs),
)
for pr, v := range pd.ondisk {
// That we have to chop off these path prefixes is a symptom of
// a problem in gps itself
pkgs := make([]string, 0, len(pd.dependencies[pr]))
prslash := string(pr) + "/"
for _, pkg := range pd.dependencies[pr] {
if pkg == string(pr) {
pkgs = append(pkgs, ".")
} else {
pkgs = append(pkgs, trimPathPrefix(pkg, prslash))
}
}

l.P = append(l.P, gps.NewLockedProject(
gps.ProjectIdentifier{ProjectRoot: pr}, v, pkgs),
)
}
}

ctx.Loggers.Err.Println("Using network for remaining projects...")
ctx.Loggers.Err.Println("Using network for projects...")
// Copy lock before solving. Use this to separate new lock projects from soln
copyLock := *l

// Run solver with project versions found on disk
// Run solver with the available knowledge to solve the dependency constraints
if ctx.Loggers.Verbose {
ctx.Loggers.Err.Println("dep: Solving...")
}
Expand Down Expand Up @@ -180,25 +198,43 @@ func (cmd *initCommand) Run(ctx *dep.Ctx, args []string) error {
}
l = dep.LockFromInterface(soln)

// Iterate through the new projects in solved lock and add them to manifest
// if direct deps and log feedback for all the new projects.
for _, x := range l.Projects() {
pr := x.Ident().ProjectRoot
newProject := true
// Check if it's a new project, not in the old lock
for _, y := range copyLock.Projects() {
if pr == y.Ident().ProjectRoot {
newProject = false
// Populate manifest based on operation mode.
if cmd.gopath {
// Iterate through the new projects in solved lock and add them to manifest
// if direct deps and log feedback for all the new projects.
for _, x := range l.Projects() {
pr := x.Ident().ProjectRoot
newProject := true
// Check if it's a new project, not in the old lock
for _, y := range copyLock.Projects() {
if pr == y.Ident().ProjectRoot {
newProject = false
}
}
if newProject {
// Check if it's in notondisk project map. These are direct deps, should
// be added to manifest.
if _, ok := pd.notondisk[pr]; ok {
m.Dependencies[pr] = getProjectPropertiesFromVersion(x.Version())
feedback(x.Version(), pr, fb.DepTypeDirect, ctx)
} else {
// Log feedback of transitive project
feedback(x.Version(), pr, fb.DepTypeTransitive, ctx)
}
}
}
if newProject {
// Check if it's in notondisk project map. These are direct deps, should
// be added to manifest.
if _, ok := pd.notondisk[pr]; ok {
} else {
// Get direct dependencies
rm, _ := pkgT.ToReachMap(true, true, false, nil)
directDep := rm.Flatten(false)

// Pick the direct dependencies from the above solution and add to manifest
for _, x := range l.Projects() {
pr := x.Ident().ProjectRoot
if contains(directDep, string(pr)) {
m.Dependencies[pr] = getProjectPropertiesFromVersion(x.Version())
feedback(x.Version(), pr, fb.DepTypeDirect, ctx)
} else {
// Log feedback of transitive project
feedback(x.Version(), pr, fb.DepTypeTransitive, ctx)
}
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/dep/testdata/harness_tests/init/case1/testcase.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"commands": [
["init", "-no-examples"]
["init", "-no-examples", "-gopath"]
],
"gopath-initial": {
"github.com/sdboyer/deptest": "v0.8.0",
Expand Down
2 changes: 1 addition & 1 deletion cmd/dep/testdata/harness_tests/init/case2/testcase.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"commands": [
["init", "-no-examples"]
["init", "-no-examples", "-gopath"]
],
"gopath-initial": {
"github.com/sdboyer/deptest": "v0.8.0"
Expand Down
2 changes: 1 addition & 1 deletion cmd/dep/testdata/harness_tests/init/case3/testcase.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"commands": [
["init", "-no-examples"]
["init", "-no-examples", "-gopath"]
],
"gopath-initial": {
"github.com/sdboyer/deptestdos": "a0196baa11ea047dd65037287451d36b861b00ea"
Expand Down
13 changes: 13 additions & 0 deletions cmd/dep/testdata/harness_tests/init/case4/final/Gopkg.lock

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

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

[[dependencies]]
name = "github.com/sdboyer/deptest"
version = "^1.0.0"

[[dependencies]]
name = "github.com/sdboyer/deptestdos"
version = "^2.0.0"
13 changes: 13 additions & 0 deletions cmd/dep/testdata/harness_tests/init/case4/initial/foo/bar.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// 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 foo

import "github.com/sdboyer/deptest"

func Foo() deptest.Foo {
var y deptest.Foo

return y
}
19 changes: 19 additions & 0 deletions cmd/dep/testdata/harness_tests/init/case4/initial/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// 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/golang/notexist/foo"
"github.com/sdboyer/deptestdos"
)

func main() {
var x deptestdos.Bar
y := foo.FooFunc()

fmt.Println(x, y)
}
12 changes: 12 additions & 0 deletions cmd/dep/testdata/harness_tests/init/case4/testcase.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"commands": [
["init", "-no-examples"]
],
"gopath-initial": {
"github.com/sdboyer/deptestdos": "a0196baa11ea047dd65037287451d36b861b00ea"
},
"vendor-final": [
"github.com/sdboyer/deptest",
"github.com/sdboyer/deptestdos"
]
}

0 comments on commit 3b22acb

Please sign in to comment.