diff --git a/README.md b/README.md index 220b22b7a..c7e0e4866 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ gpm - Go Package Manager === -![GPMGo_Logo](https://raw.github.com/GPMGo/gpm-site/master/static/img/gpmgo.png?raw=true) +![GPMGo_Logo](https://raw.github.com/GPMGo/gpm-site/master/static/img/gpmgo2.png?raw=true) gpm(Go Package Manager) is a Go package manage tool for search, install, update and share packages in Go. @@ -22,11 +22,13 @@ gpm(Go Package Manager) is a Go package manage tool for search, install, update - Add bundle and snapshot parser code for downloading by bundle or snapshot id. - Add user system to create, edit, upload, and download bundles or snapshots through gpm client program. - Download package from code.google.com only support hg as version control system, probably support git and svn. -- Add support for downloading by tag for packages in github.com, bitbucket.org, git.oschina.net, gitcafe.com. +- Add support for downloading by tag and branch for packages in bitbucket.org, git.oschina.net, gitcafe.com. - Get author commit time and save in node. - Collect download and installation results and report to users in the end. - Command `install` add support for downloading code from git.oschina.net, gitcafe.com, *.codeplex.com; - Command `check` is for checking and downloading all missing dependencies. - Command `daemon` is for auto-compile web applications when debug it locally. - Command `update` is for checking updates. -- Command `remove` is for removing packages. \ No newline at end of file +- Command `remove` is for removing packages. +- Command `search` is for searching packages. +- Add feature "struct generator". \ No newline at end of file diff --git a/doc/bitbucket.go b/doc/bitbucket.go index a206844a0..df3d97787 100644 --- a/doc/bitbucket.go +++ b/doc/bitbucket.go @@ -22,7 +22,8 @@ var ( ) // GetBitbucketDoc downloads tarball from bitbucket.org. -func GetBitbucketDoc(client *http.Client, match map[string]string, installGOPATH, commit string, cmdFlags map[string]bool) (*Node, []string, error) { +func GetBitbucketDoc(client *http.Client, match map[string]string, installGOPATH string, node *Node, cmdFlags map[string]bool) ([]string, error) { + commit := node.Value // Check version control. if m := bitbucketEtagRe.FindStringSubmatch(commit); m != nil { match["vcs"] = m[1] @@ -31,7 +32,7 @@ func GetBitbucketDoc(client *http.Client, match map[string]string, installGOPATH Scm string } if err := httpGetJSON(client, expand("https://api.bitbucket.org/1.0/repositories/{owner}/{repo}", match), &repo); err != nil { - return nil, nil, err + return nil, err } match["vcs"] = repo.Scm } @@ -48,7 +49,7 @@ func GetBitbucketDoc(client *http.Client, match map[string]string, installGOPATH Node string } if err := httpGetJSON(client, expand("https://api.bitbucket.org/1.0/repositories/{owner}/{repo}/{0}", match, nodeType), &nodes); err != nil { - return nil, nil, err + return nil, err } for t, n := range nodes { tags[t] = n.Node @@ -59,7 +60,7 @@ func GetBitbucketDoc(client *http.Client, match map[string]string, installGOPATH var err error match["tag"], match["commit"], err = bestTag(tags, defaultTags[match["vcs"]]) if err != nil { - return nil, nil, err + return nil, err } } else { match["commit"] = commit @@ -72,7 +73,7 @@ func GetBitbucketDoc(client *http.Client, match map[string]string, installGOPATH // Downlaod archive. p, err := httpGetBytes(client, expand("https://bitbucket.org/{owner}/{repo}/get/{commit}.tar.gz", match), nil) if err != nil { - return nil, nil, err + return nil, err } projectPath := expand("bitbucket.org/{owner}/{repo}", match) @@ -85,7 +86,7 @@ func GetBitbucketDoc(client *http.Client, match map[string]string, installGOPATH gzr, err := gzip.NewReader(bytes.NewReader(p)) if err != nil { - return nil, nil, err + return nil, err } defer gzr.Close() @@ -99,7 +100,7 @@ func GetBitbucketDoc(client *http.Client, match map[string]string, installGOPATH if err == io.EOF { break } else if err != nil { - return nil, nil, err + return nil, err } fn := h.FileInfo().Name() @@ -125,26 +126,27 @@ func GetBitbucketDoc(client *http.Client, match map[string]string, installGOPATH // Get data from archive. fbytes := make([]byte, h.Size) if _, err := io.ReadFull(tr, fbytes); err != nil { - return nil, nil, err + return nil, err } // Write data to file fw, err := os.Create(absPath) if err != nil { - return nil, nil, err + return nil, err } _, err = fw.Write(fbytes) fw.Close() if err != nil { - return nil, nil, err + return nil, err } } - node := &Node{ + node.Value = commit + /* node := &Node{ ImportPath: projectPath, Commit: commit, - } + }*/ var imports []string @@ -153,13 +155,13 @@ func GetBitbucketDoc(client *http.Client, match map[string]string, installGOPATH for _, d := range dirs { importPkgs, err := checkImports(d+"/", match["importPath"]) if err != nil { - return nil, nil, err + return nil, err } imports = append(imports, importPkgs...) } } - return node, imports, err + return imports, err } // checkDir checks if current directory has been saved. diff --git a/doc/github.go b/doc/github.go index 04ba6e489..bb8fe5c51 100644 --- a/doc/github.go +++ b/doc/github.go @@ -7,6 +7,7 @@ package doc import ( "archive/zip" "bytes" + "errors" "io" "net/http" "os" @@ -26,7 +27,7 @@ func SetGithubCredentials(id, secret string) { } // GetGithubDoc downloads tarball from github.com. -func GetGithubDoc(client *http.Client, match map[string]string, installGOPATH, commit string, cmdFlags map[string]bool) (*Node, []string, error) { +func GetGithubDoc(client *http.Client, match map[string]string, installGOPATH string, node *Node, cmdFlags map[string]bool) ([]string, error) { SetGithubCredentials("1862bcb265171f37f36c", "308d71ab53ccd858416cfceaed52d5d5b7d53c5f") match["cred"] = githubCred @@ -43,14 +44,14 @@ func GetGithubDoc(client *http.Client, match map[string]string, installGOPATH, c // bundle and snapshot will have commit 'B' and 'S', // but does not need to download dependencies. - isCheckImport := len(commit) == 0 + isCheckImport := len(node.Value) == 0 - // Check if download with specific revision. - if isCheckImport || len(commit) == 1 { + switch { + case isCheckImport || len(node.Value) == 1: // Get up-to-date version. err := httpGetJSON(client, expand("https://api.github.com/repos/{owner}/{repo}/git/refs?{cred}", match), &refs) if err != nil { - return nil, nil, err + return nil, err } tags := make(map[string]string) @@ -64,9 +65,19 @@ func GetGithubDoc(client *http.Client, match map[string]string, installGOPATH, c } // Check revision tag. - match["tag"], commit, err = bestTag(tags, "master") + match["tag"], match["sha"], err = bestTag(tags, "master") if err != nil { - return nil, nil, err + return nil, err + } + + node.Type = "commit" + case !isCheckImport: // Bundle or snapshot. + // Check downlaod type. + switch node.Type { + case "tag", "commit", "branch": + match["sha"] = node.Value + default: + return nil, errors.New("Unknown node type: " + node.Type) } } @@ -74,19 +85,22 @@ func GetGithubDoc(client *http.Client, match map[string]string, installGOPATH, c // zip : https://github.com/{owner}/{repo}/archive/{sha}.zip // tarball : https://github.com/{owner}/{repo}/tarball/{sha} - match["sha"] = commit // Downlaod archive. p, err := httpGetBytes(client, expand("https://github.com/{owner}/{repo}/archive/{sha}.zip", match), nil) if err != nil { - return nil, nil, err + return nil, err } r, err := zip.NewReader(bytes.NewReader(p), int64(len(p))) if err != nil { - return nil, nil, err + return nil, err } shaName := expand("{repo}-{sha}", match) + if node.Type == "tag" { + shaName = strings.Replace(shaName, "-v", "-", 1) + } + projectPath := expand("github.com/{owner}/{repo}", match) installPath := installGOPATH + "/src/" + projectPath @@ -114,7 +128,7 @@ func GetGithubDoc(client *http.Client, match map[string]string, installGOPATH, c // Get file from archive. rc, err := f.Open() if err != nil { - return nil, nil, err + return nil, err } // Create diretory before create file. @@ -123,20 +137,19 @@ func GetGithubDoc(client *http.Client, match map[string]string, installGOPATH, c // Write data to file fw, _ := os.Create(absPath) if err != nil { - return nil, nil, err + return nil, err } _, err = io.Copy(fw, rc) rc.Close() fw.Close() if err != nil { - return nil, nil, err + return nil, err } } - node := &Node{ - ImportPath: projectPath, - Commit: commit, + if node.Type == "commit" { + node.Value = match["sha"] } var imports []string @@ -146,11 +159,11 @@ func GetGithubDoc(client *http.Client, match map[string]string, installGOPATH, c for _, d := range dirs { importPkgs, err := checkImports(d, match["importPath"]) if err != nil { - return nil, nil, err + return nil, err } imports = append(imports, importPkgs...) } } - return node, imports, err + return imports, err } diff --git a/doc/google.go b/doc/google.go index 3cc0c1b3b..947c4c073 100644 --- a/doc/google.go +++ b/doc/google.go @@ -48,13 +48,14 @@ func getGoogleVCS(client *http.Client, match map[string]string) error { } // GetGoogleDoc downloads raw files from code.google.com. -func GetGoogleDoc(client *http.Client, match map[string]string, installGOPATH, commit string, cmdFlags map[string]bool) (*Node, []string, error) { +func GetGoogleDoc(client *http.Client, match map[string]string, installGOPATH string, node *Node, cmdFlags map[string]bool) ([]string, error) { setupGoogleMatch(match) + commit := node.Value // Check version control. if m := googleEtagRe.FindStringSubmatch(commit); m != nil { match["vcs"] = m[1] } else if err := getGoogleVCS(client, match); err != nil { - return nil, nil, err + return nil, err } // bundle and snapshot will have commit 'B' and 'S', @@ -66,12 +67,12 @@ func GetGoogleDoc(client *http.Client, match map[string]string, installGOPATH, c // Scrape the repo browser to find the project revision and individual Go files. p, err := httpGetBytes(client, rootPath+"?r="+commit, nil) if err != nil { - return nil, nil, err + return nil, err } // Check revision tag. if m := googleRevisionRe.FindSubmatch(p); m == nil { - return nil, nil, + return nil, errors.New("doc.GetGoogleDoc(): Could not find revision for " + match["importPath"]) } @@ -86,7 +87,7 @@ func GetGoogleDoc(client *http.Client, match map[string]string, installGOPATH, c // Get source files in root path. files := make([]*source, 0, 5) for _, m := range googleFileRe.FindAllSubmatch(p, -1) { - fname := string(m[1]) + fname := strings.Split(string(m[1]), "?")[0] files = append(files, &source{ name: fname, rawURL: expand("http://{subrepo}{dot}{repo}.googlecode.com/{vcs}{dir}/{0}", match, fname) + "?r=" + commit, @@ -95,7 +96,7 @@ func GetGoogleDoc(client *http.Client, match map[string]string, installGOPATH, c // Fetch files from VCS. if err := fetchFiles(client, files, nil); err != nil { - return nil, nil, err + return nil, err } // Save files. @@ -108,13 +109,13 @@ func GetGoogleDoc(client *http.Client, match map[string]string, installGOPATH, c // Write data to file fw, err := os.Create(absPath + f.name) if err != nil { - return nil, nil, err + return nil, err } _, err = fw.Write(f.data) fw.Close() if err != nil { - return nil, nil, err + return nil, err } } @@ -129,26 +130,28 @@ func GetGoogleDoc(client *http.Client, match map[string]string, installGOPATH, c err = downloadFiles(client, match, rootPath, installPath+"/", commit, dirs) if err != nil { - return nil, nil, err + return nil, err } - node := &Node{ + node.Value = commit + /* node := &Node{ ImportPath: projectPath, Commit: commit, - } + }*/ + var imports []string // Check if need to check imports. if isCheckImport { rootdir, err := os.Open(installPath + "/") if err != nil { - return nil, nil, err + return nil, err } defer rootdir.Close() dirs, err := rootdir.Readdir(0) if err != nil { - return nil, nil, err + return nil, err } for _, d := range dirs { @@ -156,14 +159,14 @@ func GetGoogleDoc(client *http.Client, match map[string]string, installGOPATH, c absPath := installPath + "/" + d.Name() + "/" importPkgs, err := checkImports(absPath, match["importPath"]) if err != nil { - return nil, nil, err + return nil, err } imports = append(imports, importPkgs...) } } } - return node, imports, err + return imports, err } func downloadFiles(client *http.Client, match map[string]string, rootPath, installPath, commit string, dirs []string) error { diff --git a/doc/launchpad.go b/doc/launchpad.go index 207d36c88..677a837f5 100644 --- a/doc/launchpad.go +++ b/doc/launchpad.go @@ -19,7 +19,7 @@ import ( var LaunchpadPattern = regexp.MustCompile(`^launchpad\.net/(?P(?P[a-z0-9A-Z_.\-]+)(?P/[a-z0-9A-Z_.\-]+)?|~[a-z0-9A-Z_.\-]+/(\+junk|[a-z0-9A-Z_.\-]+)/[a-z0-9A-Z_.\-]+)(?P/[a-z0-9A-Z_.\-/]+)*$`) // GetLaunchpadDoc downloads tarball from launchpad.net. -func GetLaunchpadDoc(client *http.Client, match map[string]string, installGOPATH, commit string, cmdFlags map[string]bool) (*Node, []string, error) { +func GetLaunchpadDoc(client *http.Client, match map[string]string, installGOPATH string, node *Node, cmdFlags map[string]bool) ([]string, error) { if match["project"] != "" && match["series"] != "" { rc, err := httpGet(client, expand("https://code.launchpad.net/{project}{series}/.bzr/branch-format", match), nil) @@ -32,10 +32,10 @@ func GetLaunchpadDoc(client *http.Client, match map[string]string, installGOPATH match["repo"] = match["project"] match["dir"] = expand("{series}{dir}", match) default: - return nil, nil, err + return nil, err } } - + commit := node.Value // bundle and snapshot will have commit 'B' and 'S', // but does not need to download dependencies. isCheckImport := len(commit) == 0 @@ -51,7 +51,7 @@ func GetLaunchpadDoc(client *http.Client, match map[string]string, installGOPATH // Scrape the repo browser to find the project revision and individual Go files. p, err := httpGetBytes(client, downloadPath, nil) if err != nil { - return nil, nil, err + return nil, err } projectPath := expand("launchpad.net/{repo}", match) @@ -64,7 +64,7 @@ func GetLaunchpadDoc(client *http.Client, match map[string]string, installGOPATH gzr, err := gzip.NewReader(bytes.NewReader(p)) if err != nil { - return nil, nil, err + return nil, err } defer gzr.Close() @@ -78,7 +78,7 @@ func GetLaunchpadDoc(client *http.Client, match map[string]string, installGOPATH if err == io.EOF { break } else if err != nil { - return nil, nil, err + return nil, err } fn := h.FileInfo().Name() @@ -104,26 +104,27 @@ func GetLaunchpadDoc(client *http.Client, match map[string]string, installGOPATH // Get data from archive. fbytes := make([]byte, h.Size) if _, err := io.ReadFull(tr, fbytes); err != nil { - return nil, nil, err + return nil, err } // Write data to file fw, err := os.Create(absPath) if err != nil { - return nil, nil, err + return nil, err } _, err = fw.Write(fbytes) fw.Close() if err != nil { - return nil, nil, err + return nil, err } } - node := &Node{ + node.Value = commit + /* node := &Node{ ImportPath: projectPath, Commit: commit, - } + }*/ var imports []string @@ -132,11 +133,11 @@ func GetLaunchpadDoc(client *http.Client, match map[string]string, installGOPATH for _, d := range dirs { importPkgs, err := checkImports(d+"/", match["importPath"]) if err != nil { - return nil, nil, err + return nil, err } imports = append(imports, importPkgs...) } } - return node, imports, err + return imports, err } diff --git a/doc/struct.go b/doc/struct.go index e7dbe1f5f..cc348e1b6 100644 --- a/doc/struct.go +++ b/doc/struct.go @@ -12,9 +12,9 @@ import ( // Node represents a node. type Node struct { - ImportPath string `json:"import_path"` - Commit string - Date string + ImportPath string `json:"import_path"` + Type, Value string + Deps []*Node `json:"-"` // Dependencies. } // Bundle represents a bundle. diff --git a/gpm.go b/gpm.go index 45135258e..530f3a574 100644 --- a/gpm.go +++ b/gpm.go @@ -183,7 +183,7 @@ func loadLocalBundles() bool { for _, fi := range fis { // In case this folder contains unexpected directories. - if !fi.IsDir() { + if !fi.IsDir() && strings.HasSuffix(fi.Name(), ".json") { fr, err := os.Open(appPath + "repo/bundles/" + fi.Name()) if err != nil { fmt.Println(err) @@ -202,6 +202,7 @@ func loadLocalBundles() bool { if len(bundle.Name) == 0 { bundle.Name = fi.Name()[:strings.Index(fi.Name(), ".")] } + localBundles = append(localBundles, bundle) } } diff --git a/install.go b/install.go index 89207ae2a..548feafa1 100644 --- a/install.go +++ b/install.go @@ -113,9 +113,14 @@ func runInstall(cmd *Command, args []string) { installGOPATH = utils.GetBestMatchGOPATH(appPath) fmt.Printf("Packages will be downloaded to GOPATH(%s).\n", installGOPATH) + // Generate temporary nodes. + nodes := make([]*doc.Node, len(args)) + for i := range nodes { + nodes[i] = new(doc.Node) + nodes[i].ImportPath = args[i] + } // Download packages. - commits := make([]string, len(args)) - downloadPackages(args, commits) + downloadPackages(nodes) if !cmdInstall.Flags["-d"] && cmdInstall.Flags["-p"] { // Install packages all together. @@ -144,40 +149,48 @@ func runInstall(cmd *Command, args []string) { } // checkLocalBundles checks if the bundle is in local file system. -func checkLocalBundles(bundle string) (pkgs, commits []string) { +func checkLocalBundles(bundle string) (nodes []*doc.Node) { for _, b := range localBundles { if bundle == b.Name { for _, n := range b.Nodes { - pkgs = append(pkgs, n.ImportPath) // Make sure it will not download all dependencies automatically. - if len(n.Commit) == 0 { - commits = append(commits, "B") - } else { - commits = append(commits, n.Commit) + if len(n.Value) == 0 { + n.Value = "B" + } + nodes = append(nodes, n) + + // Check dependencies. + for _, d := range n.Deps { + // Make sure it will not download all dependencies automatically. + if len(d.Value) == 0 { + d.Value = "B" + } + nodes = append(nodes, d) } } - return pkgs, commits + return nodes } } - return nil, nil + return nil } // downloadPackages downloads packages with certain commit, // if the commit is empty string, then it downloads all dependencies, // otherwise, it only downloada package with specific commit only. -func downloadPackages(pkgs, commits []string) { +func downloadPackages(nodes []*doc.Node) { // Check all packages, they may be bundles, snapshots or raw packages path. - for i, p := range pkgs { + for _, n := range nodes { // Check if it is a bundle or snapshot. switch { - case p[0] == 'B': + case n.ImportPath[0] == 'B': // Check local bundles. - bpkgs, bcommits := checkLocalBundles(p[1:]) - if len(bpkgs) > 0 { + bnodes := checkLocalBundles(n.ImportPath[1:]) + if len(nodes) > 0 { // Check with users if continue. - fmt.Printf("Bundle(%s) contains following nodes:\n", p[1:]) - for i := range bpkgs { - fmt.Printf("import path: %s, commit: %s.\n", bpkgs[i], bcommits[i]) + fmt.Printf("Bundle(%s) contains following nodes:\n", + n.ImportPath[1:]) + for _, bn := range bnodes { + fmt.Printf("[%s] -> %s: %s.\n", bn.ImportPath, bn.Type, bn.Value) } fmt.Print("Continue to download?(Y/n).") var option string @@ -185,36 +198,40 @@ func downloadPackages(pkgs, commits []string) { if strings.ToLower(option) != "y" { os.Exit(0) } - downloadPackages(bpkgs, bcommits) + downloadPackages(bnodes) } else { // Check from server. // TODO: api.GetBundleInfo() fmt.Println("Unable to check with server right now.") } - case p[0] == 'S': + case n.ImportPath[0] == 'S': // TODO: api.GetSnapshotInfo() - case utils.IsValidRemotePath(p): - if !downloadCache[p] { + case utils.IsValidRemotePath(n.ImportPath): + if !downloadCache[n.ImportPath] { // Download package. - node, imports := downloadPackage(p, commits[i]) + node, imports := downloadPackage(n) if len(imports) > 0 { // Need to download dependencies. - tags := make([]string, len(imports)) - downloadPackages(imports, tags) + // Generate temporary nodes. + nodes := make([]*doc.Node, len(imports)) + for i := range nodes { + nodes[i] = new(doc.Node) + nodes[i].ImportPath = imports[i] + } + downloadPackages(nodes) } // Only save package information with specific commit. if node != nil { // Save record in local nodes. saveNode(node) - //fmt.Printf("Saved information: %s:%s.\n", pkg.ImportPath, pkg.Commit) } } else { - fmt.Printf("Skipped downloaded package: %s.\n", p) + fmt.Printf("Skipped downloaded package: %s.\n", n.ImportPath) } default: // Invalid import path. - fmt.Printf("Skipped invalid import path: %s.\n", p) + fmt.Printf("Skipped invalid import path: %s.\n", n.ImportPath) } } } @@ -222,9 +239,9 @@ func downloadPackages(pkgs, commits []string) { // saveNode saves node into local nodes. func saveNode(n *doc.Node) { // Check if this node exists. - for _, v := range localNodes { + for i, v := range localNodes { if n.ImportPath == v.ImportPath { - v = n + localNodes[i] = n return } } @@ -234,14 +251,14 @@ func saveNode(n *doc.Node) { } // downloadPackage download package either use version control tools or not. -func downloadPackage(path, commit string) (node *doc.Node, imports []string) { +func downloadPackage(node *doc.Node) (*doc.Node, []string) { // Check if use version control tools. switch { case !cmdInstall.Flags["-p"] && - ((path[0] == 'g' && isHasGit) || (path[0] == 'c' && isHasHg)): // github.com, code.google.com - fmt.Printf("Installing package(%s) through 'go get'.\n", path) + ((node.ImportPath[0] == 'g' && isHasGit) || (node.ImportPath[0] == 'c' && isHasHg)): // github.com, code.google.com + fmt.Printf("Installing package(%s) through 'go get'.\n", node.ImportPath) args := checkGoGetFlags() - args = append(args, path) + args = append(args, node.ImportPath) executeGoCommand(args) return nil, nil default: // Pure download. @@ -250,14 +267,13 @@ func downloadPackage(path, commit string) (node *doc.Node, imports []string) { fmt.Printf("No version control tool is available, pure download enabled!\n") } - fmt.Printf("Downloading package: %s.\n", path) + fmt.Printf("Downloading package: %s.\n", node.ImportPath) // Mark as donwloaded. - downloadCache[path] = true + downloadCache[node.ImportPath] = true - var err error - node, imports, err = pureDownload(path, commit) + imports, err := pureDownload(node) if err != nil { - fmt.Printf("Fail to download package(%s) with error: %s.\n", path, err) + fmt.Printf("Fail to download package(%s) with error: %s.\n", node.ImportPath, err) return nil, nil } @@ -282,7 +298,7 @@ func checkGoGetFlags() (args []string) { type service struct { pattern *regexp.Regexp prefix string - get func(*http.Client, map[string]string, string, string, map[string]bool) (*doc.Node, []string, error) + get func(*http.Client, map[string]string, string, *doc.Node, map[string]bool) ([]string, error) } // services is the list of source code control services handled by gopkgdoc. @@ -294,26 +310,26 @@ var services = []*service{ } // pureDownload downloads package without version control. -func pureDownload(path, commit string) (*doc.Node, []string, error) { +func pureDownload(node *doc.Node) ([]string, error) { for _, s := range services { - if s.get == nil || !strings.HasPrefix(path, s.prefix) { + if s.get == nil || !strings.HasPrefix(node.ImportPath, s.prefix) { continue } - m := s.pattern.FindStringSubmatch(path) + m := s.pattern.FindStringSubmatch(node.ImportPath) if m == nil { if s.prefix != "" { - return nil, nil, + return nil, doc.NotFoundError{"Import path prefix matches known service, but regexp does not."} } continue } - match := map[string]string{"importPath": path} + match := map[string]string{"importPath": node.ImportPath} for i, n := range s.pattern.SubexpNames() { if n != "" { match[n] = m[i] } } - return s.get(doc.HttpClient, match, installGOPATH, commit, cmdInstall.Flags) + return s.get(doc.HttpClient, match, installGOPATH, node, cmdInstall.Flags) } - return nil, nil, doc.ErrNoMatch + return nil, doc.ErrNoMatch }