summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/cli/query.go2
-rw-r--r--pkg/rtree/index.go49
-rw-r--r--pkg/rtree/main.go11
-rw-r--r--pkg/rtree/repo.go36
4 files changed, 96 insertions, 2 deletions
diff --git a/pkg/cli/query.go b/pkg/cli/query.go
index d8602bc..0d367be 100644
--- a/pkg/cli/query.go
+++ b/pkg/cli/query.go
@@ -87,7 +87,7 @@ OUTER:
selected = len(choices) - 1
}
case "\x03": // Ctrl-C
- fmt.Fprintf(os.Stderr, "Interrupted!")
+ fmt.Fprintln(os.Stderr, "Interrupted!")
os.Exit(255)
default:
fmt.Printf("%#v\n", string(input))
diff --git a/pkg/rtree/index.go b/pkg/rtree/index.go
index aa2b2a3..2edc452 100644
--- a/pkg/rtree/index.go
+++ b/pkg/rtree/index.go
@@ -298,3 +298,52 @@ func (i *Index) InteractiveFindRepo(remoteURL string, allowClone bool) *Repo {
i.Write()
return target
}
+
+//InteractiveImportRepo moves the given repo into the rtree and adds it to the index.
+func (i *Index) InteractiveImportRepo(dirPath string) {
+ //need to make dirPath absolute first
+ dirPath, err := filepath.Abs(dirPath)
+ util.FatalIfError(err)
+ repo, err := NewRepoFromAbsolutePath(dirPath)
+ util.FatalIfError(err)
+
+ //repo must be outside $GOPATH/src
+ if !strings.HasPrefix(repo.CheckoutPath, "../") {
+ util.FatalIfError(fmt.Errorf("%s is already inside GOPATH", dirPath))
+ }
+
+ //select the remote which determines the checkout path
+ choices := make([]cli.Choice, len(repo.Remotes))
+ var checkoutPath string
+ for idx, remote := range repo.Remotes {
+ thisPath := CheckoutPathForRemoteURL(ExpandRemoteURL(remote.URL))
+ if remote.Name == "origin" {
+ //prefer "origin" over everything else
+ checkoutPath = thisPath
+ break
+ }
+ choices[idx] = cli.Choice{Text: thisPath}
+ }
+
+ //cannot decide myself -> let the user select
+ if checkoutPath == "" {
+ if len(choices) == 0 {
+ util.FatalIfError(errors.New("repo has no remotes"))
+ }
+
+ question := fmt.Sprintf("Repo has multiple remotes. Where to put below %s?", RootPath)
+ choice, _ := cli.Query(question, choices...)
+ checkoutPath = choice.Text
+ }
+
+ //double-check that there is no such repo in the rtree yet
+ for _, other := range i.Repos {
+ if other.CheckoutPath == checkoutPath {
+ util.FatalIfError(errors.New("will not overwrite existing checkout at " + other.AbsolutePath()))
+ }
+ }
+
+ //do the move
+ util.FatalIfError(repo.Move(checkoutPath, true))
+ i.Repos = append(i.Repos, &repo)
+}
diff --git a/pkg/rtree/main.go b/pkg/rtree/main.go
index 2a85ab9..4c8fb98 100644
--- a/pkg/rtree/main.go
+++ b/pkg/rtree/main.go
@@ -55,7 +55,10 @@ func Exec(args []string) {
}
commandRemotes()
case "import":
- panic("unimplemented")
+ if len(args) != 2 {
+ usageAndExit()
+ }
+ commandImport(args[1])
case "each":
if len(args) < 2 {
usageAndExit()
@@ -124,3 +127,9 @@ func commandEach(command string, args []string) {
os.Exit(1)
}
}
+
+func commandImport(dirPath string) {
+ index := ReadIndex()
+ index.InteractiveImportRepo(dirPath)
+ index.Write()
+}
diff --git a/pkg/rtree/repo.go b/pkg/rtree/repo.go
index 93ab9d2..12f087f 100644
--- a/pkg/rtree/repo.go
+++ b/pkg/rtree/repo.go
@@ -226,3 +226,39 @@ func (r Repo) InteractiveExec(command string, args ...string) (ok bool) {
}
return true
}
+
+//Move sets the CheckoutPath to the given value and moves the existing repo
+//from the old to the new checkoutPath. If makeSymlink is given, a symlink will
+//be created from the old to the new location.
+func (r *Repo) Move(checkoutPath string, makeSymlink bool) error {
+ sourcePath := filepath.Join(RootPath, r.CheckoutPath)
+ targetPath := filepath.Join(RootPath, checkoutPath)
+
+ //ensure that target does not exist
+ _, err := os.Lstat(targetPath)
+ if err == nil {
+ return fmt.Errorf("cannot move %s to %s: target exists in filesystem", sourcePath, targetPath)
+ }
+ if !os.IsNotExist(err) {
+ return err
+ }
+
+ //prepare directory to move repo into
+ err = os.MkdirAll(filepath.Dir(targetPath), 0755)
+ if err != nil {
+ return err
+ }
+
+ //move directory
+ err = os.Rename(sourcePath, targetPath)
+ if err != nil {
+ return err
+ }
+ r.CheckoutPath = checkoutPath
+
+ //if requested, make compatibility symlink
+ if makeSymlink {
+ return os.Symlink(targetPath, sourcePath)
+ }
+ return nil
+}