Merge pull request #483 from darkowlzz/481-drop-remove-subcommand

Drop remove subcommand
This commit is contained in:
sam boyer 2017-05-30 08:59:31 -04:00 коммит произвёл GitHub
Родитель 37fe793f0d abcd78e733
Коммит cb2c56a602
23 изменённых файлов: 0 добавлений и 535 удалений

Просмотреть файл

@ -60,7 +60,6 @@ func (c *Config) Run() (exitCode int) {
&initCommand{},
&statusCommand{},
&ensureCommand{},
&removeCommand{},
&hashinCommand{},
&pruneCommand{},
}

Просмотреть файл

@ -1,190 +0,0 @@
// 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 (
"flag"
"strings"
"github.com/golang/dep"
"github.com/golang/dep/internal/gps"
"github.com/golang/dep/internal/gps/paths"
"github.com/golang/dep/internal/gps/pkgtree"
"github.com/pkg/errors"
)
const removeShortHelp = `Remove a dependency from the project`
const removeLongHelp = `
Remove a dependency from the project's lock file, and vendor
folder. If the project includes that dependency in its import graph, remove will
fail unless -force is specified.
`
func (cmd *removeCommand) Name() string { return "remove" }
func (cmd *removeCommand) Args() string { return "[spec...]" }
func (cmd *removeCommand) ShortHelp() string { return removeShortHelp }
func (cmd *removeCommand) LongHelp() string { return removeLongHelp }
func (cmd *removeCommand) Hidden() bool { return false }
func (cmd *removeCommand) Register(fs *flag.FlagSet) {
fs.BoolVar(&cmd.dryRun, "n", false, "dry run, don't actually remove anything")
fs.BoolVar(&cmd.unused, "unused", false, "remove all dependencies that aren't imported by the project")
fs.BoolVar(&cmd.force, "force", false, "remove the given dependencies even if they are imported by the project")
fs.BoolVar(&cmd.keepSource, "keep-source", false, "don't remove source code")
}
type removeCommand struct {
dryRun bool
unused bool
force bool
keepSource bool
}
func (cmd *removeCommand) Run(ctx *dep.Ctx, args []string) error {
p, err := ctx.LoadProject("")
if err != nil {
return err
}
sm, err := ctx.SourceManager()
if err != nil {
return err
}
sm.UseDefaultSignalHandling()
defer sm.Release()
cpr, err := ctx.SplitAbsoluteProjectRoot(p.AbsRoot)
if err != nil {
return errors.Wrap(err, "determineProjectRoot")
}
pkgT, err := pkgtree.ListPackages(p.AbsRoot, cpr)
if err != nil {
return errors.Wrap(err, "gps.ListPackages")
}
reachmap, _ := pkgT.ToReachMap(true, true, false, nil)
if cmd.unused {
if len(args) > 0 {
return errors.Errorf("remove takes no arguments when running with -unused")
}
reachlist := reachmap.FlattenFn(paths.IsStandardImportPath)
// warm the cache in parallel, in case any paths require go get metadata
// discovery
for _, im := range reachlist {
go sm.DeduceProjectRoot(im)
}
otherroots := make(map[gps.ProjectRoot]bool)
for _, im := range reachlist {
if paths.IsStandardImportPath(im) {
continue
}
pr, err := sm.DeduceProjectRoot(im)
if err != nil {
// not being able to detect the root for an import path that's
// actually in the import list is a deeper problem. However,
// it's not our direct concern here, so we just warn.
ctx.Loggers.Err.Printf("dep: could not infer root for %q\n", pr)
continue
}
otherroots[pr] = true
}
var rm []gps.ProjectRoot
for pr := range p.Manifest.Constraints {
if _, has := otherroots[pr]; !has {
delete(p.Manifest.Constraints, pr)
rm = append(rm, pr)
}
}
if len(rm) == 0 {
ctx.Loggers.Err.Println("dep: nothing to do")
return nil
}
} else {
// warm the cache in parallel, in case any paths require go get metadata
// discovery
for _, arg := range args {
go sm.DeduceProjectRoot(arg)
}
for _, arg := range args {
pr, err := sm.DeduceProjectRoot(arg)
if err != nil {
// couldn't detect the project root for this string -
// a non-valid project root was provided
return errors.Wrap(err, "gps.DeduceProjectRoot")
}
if string(pr) != arg {
// don't be magical with subpaths, otherwise we muddy the waters
// between project roots and import paths
return errors.Errorf("%q is not a project root, but %q is - is that what you want to remove?", arg, pr)
}
/*
* - Remove package from manifest
* - if the package IS NOT being used, solving should do what we want
* - if the package IS being used:
* - Desired behavior: stop and tell the user, unless --force
* - Actual solver behavior: ?
*/
var pkgimport []string
for pkg, ie := range reachmap {
for _, im := range ie.External {
if hasImportPathPrefix(im, arg) {
pkgimport = append(pkgimport, pkg)
break
}
}
}
if _, indeps := p.Manifest.Constraints[gps.ProjectRoot(arg)]; !indeps {
return errors.Errorf("%q is not present in the manifest, cannot remove it", arg)
}
if len(pkgimport) > 0 && !cmd.force {
if len(pkgimport) == 1 {
return errors.Errorf("not removing %q because it is imported by %q (pass -force to override)", arg, pkgimport[0])
}
return errors.Errorf("not removing %q because it is imported by:\n\t%s (pass -force to override)", arg, strings.Join(pkgimport, "\n\t"))
}
delete(p.Manifest.Constraints, gps.ProjectRoot(arg))
}
}
params := p.MakeParams()
params.RootPackageTree = pkgT
if ctx.Loggers.Verbose {
params.TraceLogger = ctx.Loggers.Err
}
s, err := gps.Prepare(params, sm)
if err != nil {
return errors.Wrap(err, "prepare solver")
}
soln, err := s.Solve()
if err != nil {
handleAllTheFailuresOfTheWorld(err)
return err
}
newLock := dep.LockFromSolution(soln)
sw, err := dep.NewSafeWriter(nil, p.Lock, newLock, dep.VendorOnChanged)
if err != nil {
return err
}
if err := sw.Write(p.AbsRoot, sm, true); err != nil {
return errors.Wrap(err, "grouped write of manifest, lock and vendor")
}
return nil
}

Просмотреть файл

@ -1,67 +0,0 @@
// 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 (
"os"
"path/filepath"
"testing"
"github.com/golang/dep/internal/test"
)
func TestRemoveErrors(t *testing.T) {
t.Parallel()
test.NeedsExternalNetwork(t)
test.NeedsGit(t)
testName := "remove/unused/case1"
wd, err := os.Getwd()
if err != nil {
panic(err)
}
t.Run(testName+"/external", removeErrors(testName, wd, true, execCmd))
t.Run(testName+"/internal", removeErrors(testName, wd, false, runMain))
}
func removeErrors(name, wd string, externalProc bool, run test.RunFunc) func(*testing.T) {
return func(t *testing.T) {
t.Parallel()
testCase := test.NewTestCase(t, filepath.Join(wd, "testdata", "harness_tests"), name)
testProj := test.NewTestProject(t, testCase.InitialPath(), wd, externalProc, run)
defer testProj.Cleanup()
// Create and checkout the vendor revisions
for ip, rev := range testCase.VendorInitial {
testProj.GetVendorGit(ip)
testProj.RunGit(testProj.VendorPath(ip), "checkout", rev)
}
// Create and checkout the import revisions
for ip, rev := range testCase.GopathInitial {
testProj.RunGo("get", ip)
testProj.RunGit(testProj.Path("src", ip), "checkout", rev)
}
if err := testProj.DoRun([]string{"remove", "-unused", "github.com/not/used"}); err == nil {
t.Fatal("rm with both -unused and arg should have failed")
}
if err := testProj.DoRun([]string{"remove", "github.com/not/present"}); err == nil {
t.Fatal("rm with arg not in manifest should have failed")
}
if err := testProj.DoRun([]string{"remove", "github.com/not/used", "github.com/not/present"}); err == nil {
t.Fatal("rm with one arg not in manifest should have failed")
}
if err := testProj.DoRun([]string{"remove", "github.com/sdboyer/deptest"}); err == nil {
t.Fatal("rm of arg in manifest and imports should have failed without -force")
}
}
}

21
cmd/dep/testdata/harness_tests/remove/force/case1/final/Gopkg.lock сгенерированный поставляемый
Просмотреть файл

@ -1,21 +0,0 @@
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]]
name = "github.com/sdboyer/deptest"
packages = ["."]
revision = "ff2948a2ac8f538c4ecd55962e919d1e13e74baf"
version = "v1.0.0"
[[projects]]
name = "github.com/sdboyer/deptestdos"
packages = ["."]
revision = "5c607206be5decd28e6263ffffdcee067266015e"
version = "v2.0.0"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "1b381263a360eafafe3ef7f9be626672668d17250a3c9a8debd169d1b5e2eebb"
solver-name = "gps-cdcl"
solver-version = 1

Просмотреть файл

@ -1,11 +0,0 @@
[[constraint]]
name = "github.com/not/used"
version = "2.0.0"
[[constraint]]
name = "github.com/sdboyer/deptest"
version = "^0.8.0"
[[constraint]]
name = "github.com/sdboyer/deptestdos"
revision = "a0196baa11ea047dd65037287451d36b861b00ea"

Просмотреть файл

@ -1,11 +0,0 @@
[[constraint]]
name = "github.com/not/used"
version = "2.0.0"
[[constraint]]
name = "github.com/sdboyer/deptest"
version = "^0.8.0"
[[constraint]]
name = "github.com/sdboyer/deptestdos"
revision = "a0196baa11ea047dd65037287451d36b861b00ea"

Просмотреть файл

@ -1,18 +0,0 @@
// 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/sdboyer/deptest"
"github.com/sdboyer/deptestdos"
)
func main() {
err := nil
if err != nil {
deptest.Map["yo yo!"]
}
deptestdos.diMeLo("whatev")
}

Просмотреть файл

@ -1,10 +0,0 @@
{
"commands": [
["remove", "-force", "github.com/sdboyer/deptestdos", "github.com/not/used"]
],
"error-expected": "",
"vendor-final": [
"github.com/sdboyer/deptest",
"github.com/sdboyer/deptestdos"
]
}

20
cmd/dep/testdata/harness_tests/remove/specific/case1/final/Gopkg.lock сгенерированный поставляемый
Просмотреть файл

@ -1,20 +0,0 @@
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]]
name = "github.com/sdboyer/deptest"
packages = ["."]
revision = "ff2948a2ac8f538c4ecd55962e919d1e13e74baf"
version = "v1.0.0"
[[projects]]
name = "github.com/sdboyer/deptestdos"
packages = ["."]
revision = "a0196baa11ea047dd65037287451d36b861b00ea"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "722f8e1427ab6d4dd1bc92376e4ce41ba6034a74e283a3fe4d65c7c838c7e0d2"
solver-name = "gps-cdcl"
solver-version = 1

Просмотреть файл

@ -1,11 +0,0 @@
[[constraint]]
name = "github.com/not/used"
version = "2.0.0"
[[constraint]]
name = "github.com/sdboyer/deptest"
version = "^0.8.0"
[[constraint]]
name = "github.com/sdboyer/deptestdos"
revision = "a0196baa11ea047dd65037287451d36b861b00ea"

Просмотреть файл

@ -1,11 +0,0 @@
[[constraint]]
name = "github.com/not/used"
version = "2.0.0"
[[constraint]]
name = "github.com/sdboyer/deptest"
version = "^0.8.0"
[[constraint]]
name = "github.com/sdboyer/deptestdos"
revision = "a0196baa11ea047dd65037287451d36b861b00ea"

Просмотреть файл

@ -1,18 +0,0 @@
// 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/sdboyer/deptest"
"github.com/sdboyer/deptestdos"
)
func main() {
err := nil
if err != nil {
deptest.Map["yo yo!"]
}
deptestdos.diMeLo("whatev")
}

Просмотреть файл

@ -1,10 +0,0 @@
{
"commands": [
["remove", "github.com/not/used"]
],
"error-expected": "",
"vendor-final": [
"github.com/sdboyer/deptest",
"github.com/sdboyer/deptestdos"
]
}

15
cmd/dep/testdata/harness_tests/remove/specific/case2/final/Gopkg.lock сгенерированный поставляемый
Просмотреть файл

@ -1,15 +0,0 @@
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]]
name = "github.com/sdboyer/deptest"
packages = ["."]
revision = "ff2948a2ac8f538c4ecd55962e919d1e13e74baf"
version = "v1.0.0"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "e7725ea56516a42a641aaaf5d48754258d9f3c59949cb8a0e8a21b1ab6e07179"
solver-name = "gps-cdcl"
solver-version = 1

Просмотреть файл

@ -1,11 +0,0 @@
[[constraint]]
name = "github.com/not/used"
version = "2.0.0"
[[constraint]]
name = "github.com/sdboyer/deptest"
version = "^0.8.0"
[[constraint]]
name = "github.com/sdboyer/deptestdos"
revision = "a0196baa11ea047dd65037287451d36b861b00ea"

Просмотреть файл

@ -1,11 +0,0 @@
[[constraint]]
name = "github.com/not/used"
version = "2.0.0"
[[constraint]]
name = "github.com/sdboyer/deptest"
version = "^0.8.0"
[[constraint]]
name = "github.com/sdboyer/deptestdos"
revision = "a0196baa11ea047dd65037287451d36b861b00ea"

Просмотреть файл

@ -1,16 +0,0 @@
// 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/sdboyer/deptest"
)
func main() {
err := nil
if err != nil {
deptest.Map["yo yo!"]
}
}

Просмотреть файл

@ -1,13 +0,0 @@
{
"commands": [
["remove", "github.com/not/used"]
],
"error-expected": "",
"vendor-initial": {
"github.com/sdboyer/deptest": "v0.8.0",
"github.com/sdboyer/deptestdos": "a0196baa11ea047dd65037287451d36b861b00ea"
},
"vendor-final": [
"github.com/sdboyer/deptest"
]
}

20
cmd/dep/testdata/harness_tests/remove/unused/case1/final/Gopkg.lock сгенерированный поставляемый
Просмотреть файл

@ -1,20 +0,0 @@
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]]
name = "github.com/sdboyer/deptest"
packages = ["."]
revision = "ff2948a2ac8f538c4ecd55962e919d1e13e74baf"
version = "v1.0.0"
[[projects]]
name = "github.com/sdboyer/deptestdos"
packages = ["."]
revision = "a0196baa11ea047dd65037287451d36b861b00ea"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "722f8e1427ab6d4dd1bc92376e4ce41ba6034a74e283a3fe4d65c7c838c7e0d2"
solver-name = "gps-cdcl"
solver-version = 1

Просмотреть файл

@ -1,11 +0,0 @@
[[constraint]]
name = "github.com/not/used"
version = "2.0.0"
[[constraint]]
name = "github.com/sdboyer/deptest"
version = "^0.8.0"
[[constraint]]
name = "github.com/sdboyer/deptestdos"
revision = "a0196baa11ea047dd65037287451d36b861b00ea"

Просмотреть файл

@ -1,11 +0,0 @@
[[constraint]]
name = "github.com/not/used"
version = "2.0.0"
[[constraint]]
name = "github.com/sdboyer/deptest"
version = "^0.8.0"
[[constraint]]
name = "github.com/sdboyer/deptestdos"
revision = "a0196baa11ea047dd65037287451d36b861b00ea"

Просмотреть файл

@ -1,18 +0,0 @@
// 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/sdboyer/deptest"
"github.com/sdboyer/deptestdos"
)
func main() {
err := nil
if err != nil {
deptest.Map["yo yo!"]
}
deptestdos.diMeLo("whatev")
}

Просмотреть файл

@ -1,10 +0,0 @@
{
"commands": [
["remove", "-unused"]
],
"error-expected": "",
"vendor-final": [
"github.com/sdboyer/deptest",
"github.com/sdboyer/deptestdos"
]
}