You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

174 lines
4.0 KiB

// Copyright (c) 2013 GPMGo Members. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package main
import (
"fmt"
"net/http"
"os/exec"
"regexp"
"strings"
"github.com/GPMGo/gpm/doc"
"github.com/GPMGo/gpm/utils"
)
var (
isHasGit, isHasHg bool
12 years ago
downloadCache map[string]bool // Saves packages that have downloaded.
)
var cmdInstall = &Command{
UsageLine: "install [install flags] <packages|hash>",
}
func init() {
12 years ago
downloadCache = make(map[string]bool)
cmdInstall.Run = runInstall
cmdInstall.Flags = map[string]bool{
"-p": false,
"-d": false,
"-u": false,
}
}
func runInstall(cmd *Command, args []string) {
// Check if has flags.
num := 0
for i, f := range args {
if strings.Index(f, "-") > -1 {
// Deal with flags.
if _, ok := cmdInstall.Flags[f]; ok {
cmdInstall.Flags[f] = true
printPrompt(f)
} else {
fmt.Printf("Unknown flag: %s.\n", f)
return
}
num = i + 1
}
}
// Cut out flag.
args = args[num:]
// Check length of arguments.
if len(args) < 1 {
fmt.Printf("Please list at least one package.\n")
return
}
// Check version control tools.
_, err := exec.LookPath("git")
if err == nil {
isHasGit = true
}
_, err = exec.LookPath("hg")
if err == nil {
isHasHg = true
}
// Install package(s).
for _, p := range args {
// Check if it is a hash string.
// TODO
// Check if it is vaild remote path.
if !utils.IsValidRemotePath(p) {
fmt.Printf("Invalid remote path: %s.\n", p)
} else {
downloadPackage(p, "")
}
}
}
func printPrompt(flag string) {
switch flag {
case "-p":
fmt.Println("You enabled pure download.")
case "-d":
fmt.Println("You enabled download without installing.")
}
}
// downloadPackage download package either use version control tools or not.
func downloadPackage(path, commit 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
args := checkGoGetFlags()
args = append(args, path)
fmt.Printf("Installing package: %s.\n", path)
executeGoCommand(args)
default: // Pure download.
if !cmdInstall.Flags["-p"] {
fmt.Printf("No version control tool available, pure download enabled!\n")
}
fmt.Printf("Downloading package: %s.\n", path)
12 years ago
pkg, err := pureDownload(path, commit)
if err != nil {
fmt.Printf("Fail to download package(%s) with error: %s.\n", path, err)
} else {
12 years ago
fmt.Println(pkg)
fmt.Printf("Checking imports(%s).\n", path)
fmt.Printf("Installing package: %s.\n", path)
}
}
}
func checkGoGetFlags() (args []string) {
args = append(args, "get")
switch {
case cmdInstall.Flags["-d"]:
args = append(args, "-d")
fallthrough
case cmdInstall.Flags["-u"]:
args = append(args, "-u")
}
return args
}
// service represents a source code control service.
type service struct {
pattern *regexp.Regexp
prefix string
12 years ago
get func(*http.Client, map[string]string, string) (*doc.Package, error)
}
// services is the list of source code control services handled by gopkgdoc.
var services = []*service{
{doc.GithubPattern, "github.com/", doc.GetGithubDoc},
//{googlePattern, "code.google.com/", getGoogleDoc},
//{bitbucketPattern, "bitbucket.org/", getBitbucketDoc},
//{launchpadPattern, "launchpad.net/", getLaunchpadDoc},
}
// pureDownload downloads package without control control.
12 years ago
func pureDownload(path, commit string) (pinfo *doc.Package, err error) {
for _, s := range services {
if s.get == nil || !strings.HasPrefix(path, s.prefix) {
continue
}
m := s.pattern.FindStringSubmatch(path)
if m == nil {
if s.prefix != "" {
return nil, doc.NotFoundError{"Import path prefix matches known service, but regexp does not."}
}
continue
}
match := map[string]string{"importPath": path}
for i, n := range s.pattern.SubexpNames() {
if n != "" {
match[n] = m[i]
}
}
return s.get(doc.HttpClient, match, commit)
}
return nil, doc.ErrNoMatch
}