From 27da0393ecd30b674697121e5b75848bf6c1c173 Mon Sep 17 00:00:00 2001 From: Mark Ryan Date: Fri, 17 Jun 2016 15:48:42 +0100 Subject: [PATCH 1/7] ciao-vendor: Move dependency db into a separate file. This is necessary to implement some new commands such as revendor and unvendor. Information about the dependencies that ciao uses are now stored in ciao-vendor. Signed-off-by: Mark Ryan --- ciao-vendor/ciao-vendor.go | 80 ++++++++++++++++----------- ciao-vendor/packages.json | 107 +++++++++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+), 32 deletions(-) create mode 100755 ciao-vendor/packages.json diff --git a/ciao-vendor/ciao-vendor.go b/ciao-vendor/ciao-vendor.go index b1861f03f..059b5f0c7 100644 --- a/ciao-vendor/ciao-vendor.go +++ b/ciao-vendor/ciao-vendor.go @@ -22,6 +22,7 @@ import ( "encoding/json" "flag" "fmt" + "io/ioutil" "os" "os/exec" "path" @@ -32,9 +33,9 @@ import ( ) type repoInfo struct { - URL string - version string - license string + URL string `json:"url"` + Version string `json:"version"` + License string `json:"license"` } type packageDeps struct { @@ -76,29 +77,7 @@ func (p piList) Less(i, j int) bool { return p[i].name < p[j].name } -var repos = map[string]repoInfo{ - "github.com/docker/distribution": {"https://github.com/docker/distribution.git", "v2.4.0", "Apache v2.0"}, - "gopkg.in/yaml.v2": {"https://gopkg.in/yaml.v2", "a83829b", "LGPL v3.0 + MIT"}, - "github.com/Sirupsen/logrus": {"https://github.com/Sirupsen/logrus.git", "v0.9.0", "MIT"}, - "github.com/boltdb/bolt": {"https://github.com/boltdb/bolt.git", "144418e", "MIT"}, - "github.com/coreos/go-iptables": {"https://github.com/coreos/go-iptables.git", "fbb7337", "Apache v2.0"}, - "github.com/docker/docker": {"https://github.com/docker/docker.git", "v1.10.3", "Apache v2.0"}, - "github.com/docker/engine-api": {"https://github.com/docker/engine-api.git", "v0.3.3", "Apache v2.0"}, - "github.com/docker/go-connections": {"https://github.com/docker/go-connections.git", "5b7154b", "Apache v2.0"}, - "github.com/docker/go-units": {"https://github.com/docker/go-units.git", "651fc22", "Apache v2.0"}, - "github.com/docker/libnetwork": {"https://github.com/docker/libnetwork.git", "dbb0722", "Apache v2.0"}, - "github.com/golang/glog": {"https://github.com/golang/glog.git", "23def4e", "Apache v2.0"}, - "github.com/gorilla/context": {"https://github.com/gorilla/context.git", "1ea2538", "BSD (3 clause)"}, - "github.com/gorilla/mux": {"https://github.com/gorilla/mux.git", "0eeaf83", "BSD (3 clause)"}, - "github.com/mattn/go-sqlite3": {"https://github.com/mattn/go-sqlite3.git", "467f50b", "MIT + Public domain"}, - "github.com/mitchellh/mapstructure": {"https://github.com/mitchellh/mapstructure.git", "d2dd026", "MIT"}, - "github.com/opencontainers/runc": {"https://github.com/opencontainers/runc.git", "v0.1.0", "Apache v2.0"}, - "github.com/rackspace/gophercloud": {"https://github.com/rackspace/gophercloud.git", "67139b9", "Apache v2.0"}, - "github.com/tylerb/graceful": {"https://github.com/tylerb/graceful.git", "9a3d423", "MIT"}, - "github.com/vishvananda/netlink": {"https://github.com/vishvananda/netlink.git", "293adec", "Apache v2.0"}, - "github.com/vishvananda/netns": {"https://github.com/vishvananda/netns.git", "8ba1072", "Apache v2.0"}, - "golang.org/x/net": {"https://go.googlesource.com/net", "origin/release-branch.go1.6", "BSD (3 clause)"}, -} +var repos = map[string]repoInfo{} var listTemplate = ` {{- range .Deps -}} @@ -217,7 +196,7 @@ func copyRepos(cwd, sourceRoot string, subPackages map[string][]*subPackage) err return } - cmd1 := exec.Command("git", "archive", repos[k].version) + cmd1 := exec.Command("git", "archive", repos[k].Version) cmd1.Dir = path.Join(sourceRoot, k) os.MkdirAll(path.Join(cwd, "vendor", k), 0755) args := []string{"-xC", path.Join(cwd, "vendor", k), "--wildcards", @@ -337,7 +316,7 @@ func getCurrentBranch(repo string) (string, error) { func checkoutVersion(sourceRoot string) { for k, v := range repos { - cmd := exec.Command("git", "checkout", v.version) + cmd := exec.Command("git", "checkout", v.Version) cmd.Dir = path.Join(sourceRoot, k) _ = cmd.Run() } @@ -734,11 +713,11 @@ func packages(cwd, projectRoot string) error { if repos[r].URL != "" { fmt.Fprintf(w, "%s\t", r) if d.vendored { - fmt.Fprintf(w, "%s\t", repos[r].version) + fmt.Fprintf(w, "%s\t", repos[r].Version) } else { fmt.Fprintf(w, "master\t") } - fmt.Fprintf(w, "%s", repos[r].license) + fmt.Fprintf(w, "%s", repos[r].License) } else { fmt.Fprintf(w, "Unknown\tUnknown\tUnknown") } @@ -777,7 +756,7 @@ func deps(projectRoot string) error { for _, k := range keys { r := repos[k] - fmt.Fprintf(w, "%s\t%s\t%s\t%s\n", k, r.URL, r.version, r.license) + fmt.Fprintf(w, "%s\t%s\t%s\t%s\n", k, r.URL, r.Version, r.License) } w.Flush() @@ -883,7 +862,7 @@ func updates(sourceRoot, projectRoot string) error { for _, k := range keys { v := repos[k] var output bytes.Buffer - cmd := exec.Command("git", "log", "--oneline", fmt.Sprintf("%s..HEAD", v.version)) + cmd := exec.Command("git", "log", "--oneline", fmt.Sprintf("%s..HEAD", v.Version)) cmd.Stdout = &output cmd.Dir = path.Join(sourceRoot, k) err = cmd.Run() @@ -997,6 +976,37 @@ func runCommand(cwd, sourceRoot string, args []string) error { return err } +func readRepos(projectRoot string) error { + packageFile := path.Join(projectRoot, "ciao-vendor", "packages.json") + d, err := ioutil.ReadFile(packageFile) + if err != nil { + return fmt.Errorf("Unable to read %s : %v", packageFile, err) + } + + err = json.Unmarshal(d, &repos) + if err != nil { + return fmt.Errorf("Unable to unmarshall %s : %v", packageFile, err) + } + + return nil +} + +func writeRepos(projectRoot string) error { + packageFile := path.Join(projectRoot, "ciao-vendor", "packages.json") + + d, err := json.MarshalIndent(&repos, "", "\t") + if err != nil { + return fmt.Errorf("Unable to marhsall %s : %v", packageFile, err) + } + + err = ioutil.WriteFile(packageFile, d, 0755) + if err != nil { + return fmt.Errorf("Unable to write %s : %v", packageFile, err) + } + + return nil +} + func main() { if !((len(os.Args) == 2 && (os.Args[1] == "vendor" || os.Args[1] == "check" || os.Args[1] == "deps" || @@ -1015,6 +1025,12 @@ func main() { os.Exit(1) } + err = readRepos(cwd) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + sourceRoot := path.Join(goPath, "src") if len(cwd) < len(sourceRoot)+1 { fmt.Fprintln(os.Stderr, "Could not determine project root") diff --git a/ciao-vendor/packages.json b/ciao-vendor/packages.json new file mode 100755 index 000000000..e72fca30f --- /dev/null +++ b/ciao-vendor/packages.json @@ -0,0 +1,107 @@ +{ + "github.com/Sirupsen/logrus": { + "url": "https://github.com/Sirupsen/logrus.git", + "version": "v0.9.0", + "license": "MIT" + }, + "github.com/boltdb/bolt": { + "url": "https://github.com/boltdb/bolt.git", + "version": "144418e", + "license": "MIT" + }, + "github.com/coreos/go-iptables": { + "url": "https://github.com/coreos/go-iptables.git", + "version": "fbb7337", + "license": "Apache v2.0" + }, + "github.com/docker/distribution": { + "url": "https://github.com/docker/distribution.git", + "version": "v2.4.0", + "license": "Apache v2.0" + }, + "github.com/docker/docker": { + "url": "https://github.com/docker/docker.git", + "version": "v1.10.3", + "license": "Apache v2.0" + }, + "github.com/docker/engine-api": { + "url": "https://github.com/docker/engine-api.git", + "version": "v0.3.3", + "license": "Apache v2.0" + }, + "github.com/docker/go-connections": { + "url": "https://github.com/docker/go-connections.git", + "version": "5b7154b", + "license": "Apache v2.0" + }, + "github.com/docker/go-units": { + "url": "https://github.com/docker/go-units.git", + "version": "651fc22", + "license": "Apache v2.0" + }, + "github.com/docker/libnetwork": { + "url": "https://github.com/docker/libnetwork.git", + "version": "dbb0722", + "license": "Apache v2.0" + }, + "github.com/golang/glog": { + "url": "https://github.com/golang/glog.git", + "version": "23def4e", + "license": "Apache v2.0" + }, + "github.com/gorilla/context": { + "url": "https://github.com/gorilla/context.git", + "version": "1ea2538", + "license": "BSD (3 clause)" + }, + "github.com/gorilla/mux": { + "url": "https://github.com/gorilla/mux.git", + "version": "0eeaf83", + "license": "BSD (3 clause)" + }, + "github.com/mattn/go-sqlite3": { + "url": "https://github.com/mattn/go-sqlite3.git", + "version": "467f50b", + "license": "MIT + Public domain" + }, + "github.com/mitchellh/mapstructure": { + "url": "https://github.com/mitchellh/mapstructure.git", + "version": "d2dd026", + "license": "MIT" + }, + "github.com/opencontainers/runc": { + "url": "https://github.com/opencontainers/runc.git", + "version": "v0.1.0", + "license": "Apache v2.0" + }, + "github.com/rackspace/gophercloud": { + "url": "https://github.com/rackspace/gophercloud.git", + "version": "67139b9", + "license": "Apache v2.0" + }, + "github.com/tylerb/graceful": { + "url": "https://github.com/tylerb/graceful.git", + "version": "9a3d423", + "license": "MIT" + }, + "github.com/vishvananda/netlink": { + "url": "https://github.com/vishvananda/netlink.git", + "version": "293adec", + "license": "Apache v2.0" + }, + "github.com/vishvananda/netns": { + "url": "https://github.com/vishvananda/netns.git", + "version": "8ba1072", + "license": "Apache v2.0" + }, + "golang.org/x/net": { + "url": "https://go.googlesource.com/net", + "version": "origin/release-branch.go1.6", + "license": "BSD (3 clause)" + }, + "gopkg.in/yaml.v2": { + "url": "https://gopkg.in/yaml.v2", + "version": "a83829b", + "license": "LGPL v3.0 + MIT" + } +} \ No newline at end of file From 8475e5e5d9afd495947e56c0e3f7aa4bb85d521a Mon Sep 17 00:00:00 2001 From: Mark Ryan Date: Fri, 17 Jun 2016 17:11:56 +0100 Subject: [PATCH 2/7] ciao-vendor: Add revendor command ciao-vendor now supports a revendor command that allows one to update a given repository to a new version. When revendoring, all the packages in the repository that are used by ciao are necessarily updated. An example of its use is: go run ciao-vendor/ciao-vendor.go revendor github.com/tylerb/graceful 510b0c6 Fixes #70 Signed-off-by: Mark Ryan --- ciao-vendor/ciao-vendor.go | 39 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/ciao-vendor/ciao-vendor.go b/ciao-vendor/ciao-vendor.go index 059b5f0c7..77ccc5f52 100644 --- a/ciao-vendor/ciao-vendor.go +++ b/ciao-vendor/ciao-vendor.go @@ -935,6 +935,38 @@ func test(sudo bool, sourceRoot, projectRoot, pkg, version string, goTestFlags [ return err } +func revendor(cwd, sourceRoot, projectRoot, repo, version string) error { + ri, ok := repos[repo] + if !ok { + return fmt.Errorf("%s is not a vendored repository", repo) + } + fmt.Printf("Go getting %s\n", repo) + cmd := exec.Command("go", "get", "-v", "-u", "-d", repo+"/...") + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + err := cmd.Run() + if err != nil { + return fmt.Errorf("Unable to go get %s", repo) + } + + ri.Version = version + repos[repo] = ri + err = writeRepos(cwd) + if err != nil { + return err + } + + vendoredDir := path.Join(cwd, "vendor", repo) + err = os.RemoveAll(vendoredDir) + if err != nil { + return fmt.Errorf("Unable to remove vendored directory %s : %v", + vendoredDir, err) + } + + return vendor(cwd, projectRoot, sourceRoot) +} + func runCommand(cwd, sourceRoot string, args []string) error { var err error @@ -971,6 +1003,8 @@ func runCommand(cwd, sourceRoot string, args []string) error { args = fs.Args() err = test(sudo, sourceRoot, projectRoot, args[0], args[1], args[2:]) + case "revendor": + err = revendor(cwd, sourceRoot, projectRoot, args[2], args[3]) } return err @@ -1011,11 +1045,12 @@ func main() { if !((len(os.Args) == 2 && (os.Args[1] == "vendor" || os.Args[1] == "check" || os.Args[1] == "deps" || os.Args[1] == "packages" || os.Args[1] == "updates")) || - (len(os.Args) >= 3 && (os.Args[1] == "uses")) || + (len(os.Args) >= 3 && (os.Args[1] == "uses" || os.Args[1] == "revendor")) || (len(os.Args) >= 4 && (os.Args[1] == "test"))) { fmt.Fprintln(os.Stderr, "Usage: ciao-vendor vendor|check|deps|packages|updates") fmt.Fprintln(os.Stderr, "Usage: ciao-vendor uses [-d] package") - fmt.Fprintln(os.Stderr, "Usage: ciao-vendor test package version [go-test flags]") + fmt.Fprintln(os.Stderr, "Usage: ciao-vendor test package version [go-test flags]") + fmt.Fprintln(os.Stderr, "Usage: ciao-vendor revendor package version") os.Exit(1) } From a501554e5d7ee426f9b869bb84307dfb3c94a2d1 Mon Sep 17 00:00:00 2001 From: Mark Ryan Date: Mon, 20 Jun 2016 11:36:50 +0100 Subject: [PATCH 3/7] ciao-vendor: Don't break when packages.json does not exist Ciao-vendor should work normally if the packages.json does not exist. This could happen if we unvendored all our dependencies or used ciao-vendor as the vendoring tool on a new project. Signed-off-by: Mark Ryan --- ciao-vendor/ciao-vendor.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ciao-vendor/ciao-vendor.go b/ciao-vendor/ciao-vendor.go index 77ccc5f52..15a05c336 100644 --- a/ciao-vendor/ciao-vendor.go +++ b/ciao-vendor/ciao-vendor.go @@ -1014,7 +1014,10 @@ func readRepos(projectRoot string) error { packageFile := path.Join(projectRoot, "ciao-vendor", "packages.json") d, err := ioutil.ReadFile(packageFile) if err != nil { - return fmt.Errorf("Unable to read %s : %v", packageFile, err) + if !os.IsNotExist(err) { + return fmt.Errorf("Unable to read %s : %v", packageFile, err) + } + return nil } err = json.Unmarshal(d, &repos) From 5204e6f1ddca4006e0dfe43ffa96d863c306c1dd Mon Sep 17 00:00:00 2001 From: Mark Ryan Date: Mon, 20 Jun 2016 13:36:21 +0100 Subject: [PATCH 4/7] ciao-vendor: Add vendornew command vendornew allows users to vendor a new package. You simply need to supply the package name, the branch you wish to vendor, the license and the git URL of the upstream package. Ciao-vendor will do the rest. Fixed #69 Signed-off-by: Mark Ryan --- ciao-vendor/ciao-vendor.go | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/ciao-vendor/ciao-vendor.go b/ciao-vendor/ciao-vendor.go index 15a05c336..c15431237 100644 --- a/ciao-vendor/ciao-vendor.go +++ b/ciao-vendor/ciao-vendor.go @@ -967,6 +967,20 @@ func revendor(cwd, sourceRoot, projectRoot, repo, version string) error { return vendor(cwd, projectRoot, sourceRoot) } +func vendorNew(cwd, sourceRoot, projectRoot, repo string, ri repoInfo) error { + _, ok := repos[repo] + if ok { + return fmt.Errorf("%s is already vendored", repo) + } + + repos[repo] = ri + if err := writeRepos(cwd); err != nil { + return err + } + + return vendor(cwd, projectRoot, sourceRoot) +} + func runCommand(cwd, sourceRoot string, args []string) error { var err error @@ -1005,6 +1019,9 @@ func runCommand(cwd, sourceRoot string, args []string) error { err = test(sudo, sourceRoot, projectRoot, args[0], args[1], args[2:]) case "revendor": err = revendor(cwd, sourceRoot, projectRoot, args[2], args[3]) + case "vendornew": + ri := repoInfo{URL: args[5], Version: args[3], License: args[4]} + err = vendorNew(cwd, sourceRoot, projectRoot, args[2], ri) } return err @@ -1048,12 +1065,15 @@ func main() { if !((len(os.Args) == 2 && (os.Args[1] == "vendor" || os.Args[1] == "check" || os.Args[1] == "deps" || os.Args[1] == "packages" || os.Args[1] == "updates")) || - (len(os.Args) >= 3 && (os.Args[1] == "uses" || os.Args[1] == "revendor")) || + (len(os.Args) >= 3 && (os.Args[1] == "uses")) || + (len(os.Args) == 4 && (os.Args[1] == "revendor")) || + (len(os.Args) == 6 && (os.Args[1] == "vendornew")) || (len(os.Args) >= 4 && (os.Args[1] == "test"))) { fmt.Fprintln(os.Stderr, "Usage: ciao-vendor vendor|check|deps|packages|updates") fmt.Fprintln(os.Stderr, "Usage: ciao-vendor uses [-d] package") fmt.Fprintln(os.Stderr, "Usage: ciao-vendor test package version [go-test flags]") fmt.Fprintln(os.Stderr, "Usage: ciao-vendor revendor package version") + fmt.Fprintln(os.Stderr, "Usage: ciao-vendor vendornew package version license URL") os.Exit(1) } From 4cd6b41e0e5ff621f8a57a49200fb8f77c12357c Mon Sep 17 00:00:00 2001 From: Mark Ryan Date: Mon, 20 Jun 2016 14:00:50 +0100 Subject: [PATCH 5/7] ciao-vendor: Add unvendor command Add a command to unvendor a dependency. Fixes #89 Signed-off-by: Mark Ryan --- ciao-vendor/ciao-vendor.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/ciao-vendor/ciao-vendor.go b/ciao-vendor/ciao-vendor.go index c15431237..2c8b276f4 100644 --- a/ciao-vendor/ciao-vendor.go +++ b/ciao-vendor/ciao-vendor.go @@ -981,6 +981,29 @@ func vendorNew(cwd, sourceRoot, projectRoot, repo string, ri repoInfo) error { return vendor(cwd, projectRoot, sourceRoot) } +func unvendor(cwd, sourceRoot, projectRoot, repo string) error { + _, ok := repos[repo] + if !ok { + return fmt.Errorf("%s is not vendored", repo) + } + + delete(repos, repo) + if err := writeRepos(cwd); err != nil { + return err + } + + vendoredDir := path.Join(cwd, "vendor", repo) + err := os.RemoveAll(vendoredDir) + if err != nil { + return fmt.Errorf("Unable to remove vendored directory %s : %v", + vendoredDir, err) + } + + fmt.Printf("%s unvendored. Run go run ciao-vendor/ciao-vendor.go check to verify all is well\n", repo) + + return nil +} + func runCommand(cwd, sourceRoot string, args []string) error { var err error @@ -1022,6 +1045,8 @@ func runCommand(cwd, sourceRoot string, args []string) error { case "vendornew": ri := repoInfo{URL: args[5], Version: args[3], License: args[4]} err = vendorNew(cwd, sourceRoot, projectRoot, args[2], ri) + case "unvendor": + err = unvendor(cwd, sourceRoot, projectRoot, args[2]) } return err @@ -1065,6 +1090,7 @@ func main() { if !((len(os.Args) == 2 && (os.Args[1] == "vendor" || os.Args[1] == "check" || os.Args[1] == "deps" || os.Args[1] == "packages" || os.Args[1] == "updates")) || + (len(os.Args) == 3 && (os.Args[1] == "unvendor")) || (len(os.Args) >= 3 && (os.Args[1] == "uses")) || (len(os.Args) == 4 && (os.Args[1] == "revendor")) || (len(os.Args) == 6 && (os.Args[1] == "vendornew")) || @@ -1072,6 +1098,7 @@ func main() { fmt.Fprintln(os.Stderr, "Usage: ciao-vendor vendor|check|deps|packages|updates") fmt.Fprintln(os.Stderr, "Usage: ciao-vendor uses [-d] package") fmt.Fprintln(os.Stderr, "Usage: ciao-vendor test package version [go-test flags]") + fmt.Fprintln(os.Stderr, "Usage: ciao-vendor unvendor package") fmt.Fprintln(os.Stderr, "Usage: ciao-vendor revendor package version") fmt.Fprintln(os.Stderr, "Usage: ciao-vendor vendornew package version license URL") os.Exit(1) From 1a893e936794867535828a28b6c60eb8ad2e9622 Mon Sep 17 00:00:00 2001 From: Mark Ryan Date: Mon, 20 Jun 2016 14:23:13 +0100 Subject: [PATCH 6/7] ciao-vendor: Fix gocyclo errors The code that checks whether we have the right number of arguments per command has been split into several functions to keep gocyclo happy. Signed-off-by: Mark Ryan --- ciao-vendor/ciao-vendor.go | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/ciao-vendor/ciao-vendor.go b/ciao-vendor/ciao-vendor.go index 2c8b276f4..388470148 100644 --- a/ciao-vendor/ciao-vendor.go +++ b/ciao-vendor/ciao-vendor.go @@ -1086,15 +1086,23 @@ func writeRepos(projectRoot string) error { return nil } +func checkTwoArgs(args []string) bool { + return (len(args) == 2 && + (args[1] == "vendor" || args[1] == "check" || args[1] == "deps" || + args[1] == "packages" || args[1] == "updates")) +} + +func checkArgs(args []string) bool { + return checkTwoArgs(args) || + (len(args) == 3 && (args[1] == "unvendor")) || + (len(args) >= 3 && (args[1] == "uses")) || + (len(args) == 4 && (args[1] == "revendor")) || + (len(args) == 6 && (args[1] == "vendornew")) || + (len(args) >= 4 && (args[1] == "test")) +} + func main() { - if !((len(os.Args) == 2 && - (os.Args[1] == "vendor" || os.Args[1] == "check" || os.Args[1] == "deps" || - os.Args[1] == "packages" || os.Args[1] == "updates")) || - (len(os.Args) == 3 && (os.Args[1] == "unvendor")) || - (len(os.Args) >= 3 && (os.Args[1] == "uses")) || - (len(os.Args) == 4 && (os.Args[1] == "revendor")) || - (len(os.Args) == 6 && (os.Args[1] == "vendornew")) || - (len(os.Args) >= 4 && (os.Args[1] == "test"))) { + if !checkArgs(os.Args) { fmt.Fprintln(os.Stderr, "Usage: ciao-vendor vendor|check|deps|packages|updates") fmt.Fprintln(os.Stderr, "Usage: ciao-vendor uses [-d] package") fmt.Fprintln(os.Stderr, "Usage: ciao-vendor test package version [go-test flags]") From 0b92a3a491898d604b7a71e00c9dfbbf7f04e279 Mon Sep 17 00:00:00 2001 From: Mark Ryan Date: Mon, 20 Jun 2016 14:28:57 +0100 Subject: [PATCH 7/7] ciao-vendor: Fix a panic when no argument is supplied to uses We were accessing the first element of a nil array which was panicking. Fixes #289 Signed-off-by: Mark Ryan --- ciao-vendor/ciao-vendor.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ciao-vendor/ciao-vendor.go b/ciao-vendor/ciao-vendor.go index 388470148..72181c0ff 100644 --- a/ciao-vendor/ciao-vendor.go +++ b/ciao-vendor/ciao-vendor.go @@ -1026,6 +1026,10 @@ func runCommand(cwd, sourceRoot string, args []string) error { return err } + if len(fs.Args()) == 0 { + return fmt.Errorf("Missing package for uses command") + } + err = uses(fs.Args()[0], projectRoot, direct) case "updates": err = updates(sourceRoot, projectRoot)