Skip to content

Commit

Permalink
govendor/context: add tree support to context
Browse files Browse the repository at this point in the history
  • Loading branch information
kardianos committed Jan 16, 2016
1 parent f5ffcf4 commit b504a85
Show file tree
Hide file tree
Showing 8 changed files with 184 additions and 53 deletions.
121 changes: 93 additions & 28 deletions context/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,40 @@ func (ctx *Context) VendorFilePackagePath(canonical string) *vendorfile.Package
return nil
}

// findPackageChild finds any package under the current package.
// Used for finding tree overlaps.
func (ctx *Context) findPackageChild(ck *Package) []string {
canonical := ck.Canonical
out := make([]string, 0, 3)
for _, pkg := range ctx.Package {
if pkg == ck {
continue
}
if strings.HasPrefix(pkg.Canonical, canonical) {
out = append(out, pkg.Canonical)
}
}
return out
}

// findPackageParentTree finds any parent tree package that would
// include the given canonical path.
func (ctx *Context) findPackageParentTree(ck *Package) []string {
canonical := ck.Canonical
out := make([]string, 0, 1)
for _, pkg := range ctx.Package {
if pkg.Tree == false || pkg == ck {
continue
}
// pkg.Canonical = github.com/usera/pkg, tree = true
// canonical = github.com/usera/pkg/dance
if strings.HasPrefix(canonical, pkg.Canonical) {
out = append(out, pkg.Canonical)
}
}
return out
}

// updatePackageReferences populates the referenced field in each Package.
func (ctx *Context) updatePackageReferences() {
canonicalUnderDirLookup := make(map[string]map[string]*Package)
Expand Down Expand Up @@ -416,6 +450,26 @@ func (ctx *Context) ModifyImport(sourcePath string, mod Modify) error {
}
}

// Do not support setting "tree" on Remove.
if tree && mod != Remove {
pkg.Tree = true
}

// A restriction where packages cannot live inside a tree package.
if mod != Remove {
if pkg.Tree {
children := ctx.findPackageChild(pkg)
if len(children) > 0 {
return fmt.Errorf("Cannot have a sub-tree %q contain sub-packages %q", pkg.Canonical, children)
}
}
treeParents := ctx.findPackageParentTree(pkg)
if len(treeParents) > 0 {
return fmt.Errorf("Cannot add this package which is already found in sub-tree %q", treeParents)
}
}

// TODO (DT): figure out how to upgrade a non-tree package to a tree package with correct checks.
localExists, err := hasGoFileInFolder(filepath.Join(ctx.RootDir, ctx.VendorFolder, pathos.SlashToFilepath(canonicalImportPath)))
if err != nil {
return err
Expand All @@ -440,6 +494,40 @@ func (ctx *Context) ModifyImport(sourcePath string, mod Modify) error {
}
}

func (ctx *Context) getIngoreFiles(src string) ([]string, error) {
var ignoreFile []string
srcDir, err := os.Open(src)
if err != nil {
return nil, err
}
fl, err := srcDir.Readdir(-1)
srcDir.Close()
if err != nil {
return nil, err
}
for _, fi := range fl {
if fi.IsDir() {
continue
}
if fi.Name()[0] == '.' {
continue
}
tags, err := ctx.getFileTags(filepath.Join(src, fi.Name()), nil)
if err != nil {
return nil, err
}

for _, tag := range tags {
for _, ignore := range ctx.ignoreTag {
if tag == ignore {
ignoreFile = append(ignoreFile, fi.Name())
}
}
}
}
return ignoreFile, nil
}

func (ctx *Context) modifyAdd(pkg *Package) error {
var err error
src := pkg.OriginDir
Expand All @@ -452,35 +540,11 @@ func (ctx *Context) modifyAdd(pkg *Package) error {
if cpkg, found := ctx.Package[pkg.Canonical]; found {
ignoreFile = cpkg.ignoreFile
} else {
srcDir, err := os.Open(src)
var err error
ignoreFile, err = ctx.getIngoreFiles(src)
if err != nil {
return err
}
fl, err := srcDir.Readdir(-1)
srcDir.Close()
if err != nil {
return err
}
for _, fi := range fl {
if fi.IsDir() {
continue
}
if fi.Name()[0] == '.' {
continue
}
tags, err := ctx.getFileTags(filepath.Join(src, fi.Name()), nil)
if err != nil {
return err
}

for _, tag := range tags {
for _, ignore := range ctx.ignoreTag {
if tag == ignore {
ignoreFile = append(ignoreFile, fi.Name())
}
}
}
}
}
dest := filepath.Join(ctx.RootDir, ctx.VendorFolder, pathos.SlashToFilepath(pkg.Canonical))
// TODO: This might cause other issues or might be hiding the underlying issues. Examine in depth later.
Expand Down Expand Up @@ -508,6 +572,7 @@ func (ctx *Context) modifyAdd(pkg *Package) error {
vp.Origin = pkg.Local
}
}
vp.Tree = pkg.Tree

// Find the VCS information.
system, err := vcs.FindVcs(pkg.Gopath, src)
Expand Down Expand Up @@ -757,9 +822,9 @@ func (ctx *Context) copy() error {
dprintf("MV: %s (%q -> %q)\n", pkg.Local, op.Src, op.Dest)
// Copy the package or remove.
if len(op.Dest) == 0 {
err = RemovePackage(op.Src, filepath.Join(ctx.RootDir, ctx.VendorFolder))
err = RemovePackage(op.Src, filepath.Join(ctx.RootDir, ctx.VendorFolder), pkg.Tree)
} else {
err = CopyPackage(op.Dest, op.Src, op.IgnoreFile)
err = ctx.CopyPackage(op.Dest, op.Src, op.IgnoreFile, pkg.Tree)
}
if err != nil {
return fmt.Errorf("Failed to copy package %q -> %q: %v", op.Src, op.Dest, err)
Expand Down
27 changes: 24 additions & 3 deletions context/copy.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (

// CopyPackage copies the files from the srcPath to the destPath, destPath
// folder and parents are are created if they don't already exist.
func CopyPackage(destPath, srcPath string, ignoreFiles []string) error {
func (ctx *Context) CopyPackage(destPath, srcPath string, ignoreFiles []string, tree bool) error {
if pathos.FileStringEquals(destPath, srcPath) {
return fmt.Errorf("Attempting to copy package to same location %q.", destPath)
}
Expand All @@ -29,6 +29,7 @@ func CopyPackage(destPath, srcPath string, ignoreFiles []string) error {
if err != nil {
return err
}
// TODO: If tree == true then add sub-directories too.

fl, err := destDir.Readdir(-1)
destDir.Close()
Expand All @@ -37,6 +38,12 @@ func CopyPackage(destPath, srcPath string, ignoreFiles []string) error {
}
for _, fi := range fl {
if fi.IsDir() {
if tree {
err = os.RemoveAll(filepath.Join(destPath, fi.Name()))
if err != nil {
return err
}
}
continue
}
err = os.Remove(filepath.Join(destPath, fi.Name()))
Expand All @@ -58,10 +65,24 @@ func CopyPackage(destPath, srcPath string, ignoreFiles []string) error {
}
fileLoop:
for _, fi := range fl {
if fi.IsDir() {
if fi.Name()[0] == '.' {
continue
}
if fi.Name()[0] == '.' {
if fi.IsDir() {
if !tree {
continue
}
nextDestPath := filepath.Join(destPath, fi.Name())
nextSrcPath := filepath.Join(srcPath, fi.Name())
nextIgnoreFiles, err := ctx.getIngoreFiles(nextSrcPath)
if err != nil {
return err
}

err = ctx.CopyPackage(nextDestPath, nextSrcPath, nextIgnoreFiles, true)
if err != nil {
return err
}
continue
}
for _, ignore := range ignoreFiles {
Expand Down
11 changes: 10 additions & 1 deletion context/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,20 +180,28 @@ func hasGoFileInFolder(folder string) (bool, error) {

// RemovePackage removes the specified folder files. If folder is empty when
// done (no nested folders, remove the folder and any empty parent folders.
func RemovePackage(path, root string) error {
func RemovePackage(path, root string, tree bool) error {
// Ensure the path is empty of files.
dir, err := os.Open(path)
if err != nil {
return err
}

// Remove package files.
fl, err := dir.Readdir(-1)
dir.Close()
if err != nil {
return err
}
for _, fi := range fl {
if fi.IsDir() {
if tree {
// If tree == true then remove sub-directories too.
err = os.RemoveAll(filepath.Join(path, fi.Name()))
if err != nil {
return err
}
}
continue
}
err = os.Remove(filepath.Join(path, fi.Name()))
Expand All @@ -202,6 +210,7 @@ func RemovePackage(path, root string) error {
}
}

// Remove empty parent folders.
// Ignore errors here.
for i := 0; i <= looplimit; i++ {
if pathos.FileStringEquals(path, root) {
Expand Down
4 changes: 4 additions & 0 deletions internal/vos/stub.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ func Remove(name string) error {
l("remove", name)
return os.Remove(name)
}
func RemoveAll(name string) error {
l("removeall", name)
return os.RemoveAll(name)
}
func Create(name string) (*os.File, error) {
l("create", name)
return os.Create(name)
Expand Down
6 changes: 2 additions & 4 deletions migrate/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,6 @@ func (sysGb) Migrate(root string) error {
// Move files from "src" to first GOPATH.
// Move vendor files from "vendor/src" to "vendor".
// Translate "vendor/manifest" to vendor.json file.

_ = context.CopyPackage
return errors.New("Migrate gb not implemented")
}

Expand Down Expand Up @@ -205,7 +203,7 @@ func (sysGodep) Migrate(root string) error {

// Remove existing.
for _, r := range remove {
err = context.RemovePackage(r, "")
err = context.RemovePackage(r, "", false)
if err != nil {
return err
}
Expand Down Expand Up @@ -265,7 +263,7 @@ func (sysInternal) Migrate(root string) error {

// Remove existing.
for _, r := range remove {
err = context.RemovePackage(r, "")
err = context.RemovePackage(r, "", false)
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions run.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ package main

// imports for this file should not contain "os".
import (
"path"
"errors"
"flag"
"fmt"
"io"
"os"
"path"
"path/filepath"
"strings"

Expand Down Expand Up @@ -366,7 +366,7 @@ func run(w io.Writer, appArgs []string) (bool, error) {
}
importPath := strings.TrimSuffix(imp.Import, "...")
importPath = strings.TrimSuffix(importPath, "/")
if *tree

err = ctx.ModifyImport(addTree(importPath), mod)
if err != nil {
return false, err
Expand Down
Loading

0 comments on commit b504a85

Please sign in to comment.