Skip to content

Commit

Permalink
Path subcommand to update import paths.
Browse files Browse the repository at this point in the history
Closes #2.
  • Loading branch information
emil2k committed Mar 8, 2015
1 parent 025dced commit 71d8bce
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 21 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,26 @@ Example :
vend mv ./lib/pq ./lib/postgresql
```

### `vend path`

Updates all the usages of the import path [from] to the import path [to] for
the package in the current working directory. When updating it includes import
paths located in subdirectories of the [from] import path, updating them to
their corresponding location in the [to] import path.

```
vend path [from] [to]
-r=false: recurse into subdirectories to update their import paths
-v=false: detailed output
```

Example :

```
vend path github.com/example/lib/pq github.com/lib/pq
```

### `vend list`

Lists all the dependencies of the package specified by the `[path]`, if ommitted
Expand Down
4 changes: 2 additions & 2 deletions cp.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,12 @@ func cp(ctx *build.Context, cwd, src, dst string, recurse, hidden bool) (err err
// Update import paths in the copied package itself, as it may contain
// an external _test package that imports itself or may contain packages
// in its subdirectories that import it, must recurse.
if err := update(ctx, dst, srcImp, dstImp, true); err != nil {
if err := path(ctx, dst, srcImp, dstImp, true); err != nil {
return err
}
// Update the import paths, if the recurse flag is set recurse through
// the subdirectories and update import paths.
return update(ctx, cwd, srcImp, dstImp, recurse)
return path(ctx, cwd, srcImp, dstImp, recurse)
}

// copyFileJob holds a pending copyFile call.
Expand Down
7 changes: 7 additions & 0 deletions flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,11 @@ func init() {
mv.BoolVar(&opt.hidden, "i", false,
"include hidden files, files starting with a dot")
flagMap["mv"] = mv
// Path flagset
path := flag.NewFlagSet("path", flag.ExitOnError)
path.Usage = usage(path, pathUsage)
path.BoolVar(&opt.verbose, "v", false, "detailed output")
path.BoolVar(&opt.recurse, "r", false,
"recurse into subdirectories to update their import paths")
flagMap["path"] = path
}
2 changes: 1 addition & 1 deletion init.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func initc(ctx *build.Context, cwd, dst string, recurse, hidden bool) error {
}
// Run update commands on other packages that need updating.
for _, uj := range updates {
if err := update(ctx, uj.src, uj.from, uj.to, uj.recurse); err != nil {
if err := path(ctx, uj.src, uj.from, uj.to, uj.recurse); err != nil {
return err
}
}
Expand Down
10 changes: 10 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,16 @@ func main() {
f.Usage()
os.Exit(1)
}
case "path":
f := flagMap["path"]
f.Parse(os.Args[2:])
if len(f.Args()) > 1 {
err = path(ctx, cwd, f.Arg(0), f.Arg(1), opt.recurse)
} else {
printErr("Missing arguments")
f.Usage()
os.Exit(1)
}
case "-h":
flagMap["main"].Usage()
default:
Expand Down
24 changes: 12 additions & 12 deletions update.go → path.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,25 @@ import (
"github.com/emil2k/vend/lib/astutil"
)

// update subcommand updates the import paths in the `src` directory that
// path subcommand updates the import paths in the `cwd` directory that
// contain the `from` import or an import located in its subdirectory to the
// equivalent import in the `to` path.
// Recurses into subdirectories to update import paths based on the `recurse`
// parameter.
func update(ctx *build.Context, src, from, to string, recurse bool) error {
process := func(srcPkg *build.Package, _ error) error {
// Get a list of all imports for the package in the src
func path(ctx *build.Context, cwd, from, to string, recurse bool) error {
process := func(cwdPkg *build.Package, _ error) error {
// Get a list of all imports for the package in the cwd
// directory, to determine which child package also need to be
// updated.
srcImp, srcDir := srcPkg.ImportPath, srcPkg.Dir
if len(srcImp) == 0 || len(srcDir) == 0 {
return fmt.Errorf("no import path or directory for src package")
cwdImp, cwdDir := cwdPkg.ImportPath, cwdPkg.Dir
if len(cwdImp) == 0 || len(cwdDir) == 0 {
return fmt.Errorf("no import path or directory for cwd package")
}
// Compile map of import paths to change.
rw := make(map[string]string)
// Get the children of the src package their import paths will
// Get the children of the cwd package their import paths will
// be updated as well.
for _, a := range getImports(srcPkg, true) {
for _, a := range getImports(cwdPkg, true) {
switch {
case from == a:
rw[from] = to
Expand All @@ -44,16 +44,16 @@ func update(ctx *build.Context, src, from, to string, recurse bool) error {
}
}
if len(rw) > 0 {
return rwDir(srcDir, rw)
return rwDir(cwdDir, rw)
}
return nil
}
if recurse {
// Recurse into subdirectory packages.
if err := recursePackages(ctx, src, process); err != nil {
if err := recursePackages(ctx, cwd, process); err != nil {
return err
}
} else if err := process(getPackage(ctx, src, src)); err != nil {
} else if err := process(getPackage(ctx, cwd, cwd)); err != nil {
return err
}
return nil
Expand Down
12 changes: 6 additions & 6 deletions update_test.go → path_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ import (
"testing"
)

// TestUpdate test the update subcommand to make sure that it properly changes
// TestPath test the path subcommand to make sure that it properly changes
// imports, including imports of child packages.
// Also this command tests the call without recursion into subdirectories,
// checks to make sure they are not affected.
func TestUpdate(t *testing.T) {
ctx := getTestContextCopy(t, filepath.Join("testdata", "update"))
defer os.RemoveAll(ctx.GOPATH)
pkgDir := filepath.Join(ctx.GOPATH, "src", "example.com", "x")
err := update(ctx, pkgDir, "go", "mygo", false)
err := path(ctx, pkgDir, "go", "mygo", false)
if err != nil {
t.Errorf("update error : %s", err.Error())
}
Expand All @@ -27,13 +27,13 @@ func TestUpdate(t *testing.T) {
[]string{"fmt", "os", "go/ast", "go/parser"}, false)
}

// TestUpdateRecurse test the update subcommand with the recurse option. Makes
// sure subdirectory package is also updated.
func TestUpdateRecurse(t *testing.T) {
// TestPathRecurse test the path subcommand with the recurse option. Makes sure
// subdirectory package is also updated.
func TestPathRecurse(t *testing.T) {
ctx := getTestContextCopy(t, filepath.Join("testdata", "update"))
defer os.RemoveAll(ctx.GOPATH)
pkgDir := filepath.Join(ctx.GOPATH, "src", "example.com", "x")
err := update(ctx, pkgDir, "go", "mygo", true)
err := path(ctx, pkgDir, "go", "mygo", true)
if err != nil {
t.Errorf("update error : %s", err.Error())
}
Expand Down
11 changes: 11 additions & 0 deletions usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Valid subcommands :
vend init
vend cp
vend mv
vend path
vend list
vend info
Expand Down Expand Up @@ -73,3 +74,13 @@ cp instead.
vend mv [from] [to]
`

// pathUsage describes usage of the path subcommand.
const pathUsage string = `
Updates all the usages of the import path [from] to the import path [to] for
the package in the current working directory. When updating it includes import
paths located in subdirectories of the [from] import path, updating them to
their corresponding location in the [to] import path.
vend path [from] [to]
`

0 comments on commit 71d8bce

Please sign in to comment.