diff --git a/.gopmfile b/.gopmfile index 103a06e97..a19877d1b 100644 --- a/.gopmfile +++ b/.gopmfile @@ -5,5 +5,5 @@ path=github.com/gpmgo/gopm github.com/codegangsta/cli= github.com/Unknwon/com= github.com/Unknwon/goconfig= -github.com/aybabtme/color= +github.com/aybabtme/color= diff --git a/cmd/bin.go b/cmd/bin.go index 04994ae48..2a21c189c 100644 --- a/cmd/bin.go +++ b/cmd/bin.go @@ -49,12 +49,10 @@ contains main package`, func runBin(ctx *cli.Context) { if len(ctx.Args()) == 0 { - log.Error("Bin", "Fail to start command") - log.Fatal("", "No package specified") + log.Error("bin", "Cannot start command:") + log.Fatal("", "\tNo package specified") } - doc.LoadPkgNameList(doc.HomeDir + "/data/pkgname.list") - installRepoPath = doc.HomeDir + "/repos" // Check arguments. @@ -63,14 +61,14 @@ func runBin(ctx *cli.Context) { num = 2 } if len(ctx.Args()) != num { - log.Error("Bin", "Fail to start command") - log.Fatal("", "Invalid argument number") + log.Error("bin", "Cannot start command:") + log.Fatal("", "\tMissing indicated path to build binary") } // Check if given directory exists. if ctx.Bool("dir") && !com.IsDir(ctx.Args()[1]) { - log.Error("Bin", "Fail to start command") - log.Fatal("", "Given directory does not exist") + log.Error("bin", "Cannot start command:") + log.Fatal("", "\tIndicated path does not exist or is not a directory") } // Parse package version. @@ -82,49 +80,43 @@ func runBin(ctx *cli.Context) { pkgPath = info[:i] _, ver, err = validPath(info[i+1:]) if err != nil { - log.Error("Bin", "Fail to parse version") - log.Fatal("", err.Error()) + log.Error("bin", "Cannot parse package version") + log.Error("", err.Error()+":") + log.Error("", "\t"+info[i+1:]) + log.Help("Try 'gopm help get' to get more information") } } // Check package name. if !strings.Contains(pkgPath, "/") { - name, ok := doc.PackageNameList[pkgPath] - if !ok { - log.Error("Bin", "Invalid package name: "+pkgPath) - log.Fatal("", "No match in the package name list") - } - pkgPath = name + pkgPath = doc.GetPkgFullPath(pkgPath) } // Get code. - stdout, _, _ := com.ExecCmd("gopm", "get", ctx.Args()[0]) + stdout, _, _ := com.ExecCmd("gopm", "get", "-r", ctx.Args()[0]) if len(stdout) > 0 { fmt.Print(stdout) } // Check if previous steps were successful. - repoPath := installRepoPath + "/" + pkgPath - if len(ver) > 0 { - repoPath += "." + ver - } + repoPath := installRepoPath + "/" + pkgPath + versionSuffix(ver) if !com.IsDir(repoPath) { - log.Error("Bin", "Fail to continue command") - log.Fatal("", "Previous steps weren't successful") + log.Error("bin", "Cannot continue command:") + log.Fatal("", "\tPrevious steps weren't successful") } wd, err := os.Getwd() if err != nil { - log.Error("Bin", "Fail to get work directory") - log.Fatal("", err.Error()) + log.Error("bin", "Cannot get work directory:") + log.Fatal("", "\t"+err.Error()) } // Change to repository path. log.Log("Changing work directory to %s", repoPath) err = os.Chdir(repoPath) if err != nil { - log.Error("Bin", "Fail to change work directory") - log.Fatal("", err.Error()) + log.Error("bin", "Fail to change work directory:") + log.Fatal("", "\t"+err.Error()) } // Build application. @@ -134,11 +126,11 @@ func runBin(ctx *cli.Context) { } defer func() { // Clean files. - os.RemoveAll(path.Join(repoPath, doc.VENDOR)) + //os.RemoveAll(path.Join(repoPath, doc.VENDOR)) }() // Check if previous steps were successful. - if com.IsFile(doc.GopmFileName) { + if com.IsFile(doc.GOPM_FILE_NAME) { log.Trace("Loading gopmfile...") gf := doc.NewGopmfile(".") @@ -157,10 +149,9 @@ func runBin(ctx *cli.Context) { if runtime.GOOS == "windows" { binName += ".exe" } - binPath := path.Join(doc.VENDOR, "src", pkgPath, binName) - if !com.IsFile(binPath) { - log.Error("Bin", "Fail to continue command") - log.Fatal("", "Previous steps weren't successful or the project does not contain main package") + if !com.IsFile(binName) { + log.Error("bin", "Cannot continue command:") + log.Fatal("", "\tPrevious steps weren't successful or the project does not contain main package") } // Move binary to given directory. @@ -168,15 +159,15 @@ func runBin(ctx *cli.Context) { if ctx.Bool("dir") { movePath = ctx.Args()[1] } - err = os.Rename(binPath, movePath+"/"+binName) + err = os.Rename(binName, movePath+"/"+binName) if err != nil { - log.Error("Bin", "Fail to move binary") - log.Fatal("", err.Error()) + log.Error("bin", "Fail to move binary:") + log.Fatal("", "\t"+err.Error()) } os.Chmod(movePath+"/"+binName, os.ModePerm) log.Log("Changing work directory back to %s", wd) os.Chdir(wd) - log.Success("SUCC", "Bin", "Command execute successfully!") + log.Success("SUCC", "bin", "Command execute successfully!") } diff --git a/cmd/gen.go b/cmd/gen.go index fccd070df..0b01cccc7 100644 --- a/cmd/gen.go +++ b/cmd/gen.go @@ -47,14 +47,14 @@ func runGen(ctx *cli.Context) { gf, err := goconfig.LoadConfigFile(".gopmfile") if err != nil { - log.Error("Gen", "Fail to load gopmfile") - log.Fatal("", err.Error()) + log.Error("gen", "Cannot load gopmfile:") + log.Fatal("", "\t"+err.Error()) } curPath, err := os.Getwd() if err != nil { - log.Error("Gen", "Fail to get work directory") - log.Fatal("", err.Error()) + log.Error("gen", "Cannot get work directory:") + log.Fatal("", "\t"+err.Error()) } // Get dependencies. @@ -73,9 +73,9 @@ func runGen(ctx *cli.Context) { err = goconfig.SaveConfigFile(gf, ".gopmfile") if err != nil { - log.Error("Gen", "Fail to save gopmfile") - log.Fatal("", err.Error()) + log.Error("gen", "Fail to save gopmfile:") + log.Fatal("", "\t"+err.Error()) } - log.Success("SUCC", "Gen", "Generate gopmfile successfully!") + log.Success("SUCC", "gen", "Generate gopmfile successfully!") } diff --git a/cmd/get.go b/cmd/get.go index 455eed0d0..7a636c7c9 100644 --- a/cmd/get.go +++ b/cmd/get.go @@ -31,8 +31,8 @@ import ( ) var ( - installRepoPath string - installGopath string + installRepoPath string // The path of gopm local repository. + installGopath string // The first path in the GOPATH. downloadCache map[string]bool // Saves packages that have been downloaded. downloadCount int failConut int @@ -41,7 +41,7 @@ var ( var CmdGet = cli.Command{ Name: "get", Usage: "fetch remote package(s) and dependencies to local repository", - Description: `Command get fetches a package, and any pakcages that it depents on. + Description: `Command get fetches a package, and any pakcage that it depents on. If the package has a gopmfile, the fetch process will be driven by that. gopm get @@ -50,12 +50,16 @@ gopm get @[:] Can specify one or more: gopm get beego@tag:v0.9.0 github.com/beego/bee -If no argument is supplied, then gopmfile must be present`, +If no argument is supplied, then gopmfile must be present. +If no version specified and package exists in GOPATH, +it will be skipped unless user enabled '--remote, -r' option +then all the packages go into gopm local repository.`, Action: runGet, Flags: []cli.Flag{ - cli.BoolFlag{"gopath, g", "download package(s) to GOPATH"}, + cli.BoolFlag{"gopath, g", "download all pakcages to GOPATH"}, cli.BoolFlag{"force, f", "force to update pakcage(s) and dependencies"}, - cli.BoolFlag{"example, e", "download dependencies for example(s)"}, + cli.BoolFlag{"example, e", "download dependencies for example folder"}, + cli.BoolFlag{"remote, r", "download all pakcages to gopm local repository"}, }, } @@ -64,19 +68,26 @@ func init() { } func runGet(ctx *cli.Context) { - doc.LoadPkgNameList(doc.HomeDir + "/data/pkgname.list") - - if ctx.Bool("gopath") { - installGopath = com.GetGOPATHs()[0] - if !com.IsDir(installGopath) { - log.Error("Get", "Fail to start command") - log.Fatal("", "GOPATH does not exist: "+installGopath) - } - log.Log("Indicate GOPATH: %s", installGopath) + // Check conflicts. + if ctx.Bool("gopath") && ctx.Bool("remote") { + log.Error("get", "Command options have conflicts") + log.Error("", "Following options are not supposed to use at same time:") + log.Error("", "\t'--gopath, -g' '--remote, -r'") + log.Help("Try 'gopm help get' to get more information") + } - installGopath += "/src" + // Get GOPATH. + installGopath = com.GetGOPATHs()[0] + if !com.IsDir(installGopath) { + log.Error("get", "Invalid GOPATH path") + log.Error("", "GOPATH does not exist or is not a directory:") + log.Error("", "\t"+installGopath) + log.Help("Try 'go help gopath' to get more information") } + log.Log("Indicated GOPATH: %s", installGopath) + installGopath += "/src" + // The gopm local repository. installRepoPath = doc.HomeDir + "/repos" log.Log("Local repository path: %s", installRepoPath) @@ -92,15 +103,20 @@ func runGet(ctx *cli.Context) { func getByGopmfile(ctx *cli.Context) { if !com.IsFile(".gopmfile") { - log.Fatal("Get", "No argument is supplied and no gopmfile exist") + log.Error("get", "Gopmfile not found") + log.Error("", "No argument is supplied and no gopmfile exists") + log.Help("\n%s\n%s\n%s", + "Work directory is supposed to have gopmfile when there is no argument supplied", + "Try 'gopm gen' to auto-generate gopmfile", + "Try 'gopm help gen' to get more information") } gf := doc.NewGopmfile(".") absPath, err := filepath.Abs(".") if err != nil { - log.Error("Get", "Fail to get absolute path of work directory") - log.Fatal("", err.Error()) + log.Error("get", "Fail to get absolute path of work directory") + log.Fatal("", "\t"+err.Error()) } log.Log("Work directory: %s", absPath) @@ -117,8 +133,10 @@ func getByGopmfile(ctx *cli.Context) { if v, err := gf.GetValue("deps", p); err == nil && len(v) > 0 { tp, ver, err := validPath(v) if err != nil { - log.Error("", "Fail to parse version") - log.Fatal("", err.Error()) + log.Error("get", "Cannot parse dependency version") + log.Error("", err.Error()+":") + log.Error("", "\t"+v) + log.Help("Try 'gopm help get' to get more information") } node.Type = tp node.Value = ver @@ -131,7 +149,8 @@ func getByGopmfile(ctx *cli.Context) { if doc.LocalNodes != nil { if err := goconfig.SaveConfigFile(doc.LocalNodes, doc.HomeDir+doc.LocalNodesFile); err != nil { - log.Error("Get", "Fail to save localnodes.list") + log.Error("get", "Fail to save localnodes.list:") + log.Error("", "\t"+err.Error()) } } @@ -142,27 +161,24 @@ func getByGopmfile(ctx *cli.Context) { func getByPath(ctx *cli.Context) { nodes := make([]*doc.Node, 0, len(ctx.Args())) for _, info := range ctx.Args() { - pkgName := info - node := doc.NewNode(pkgName, pkgName, doc.BRANCH, "", true) + pkgPath := info + node := doc.NewNode(pkgPath, pkgPath, doc.BRANCH, "", true) if i := strings.Index(info, "@"); i > -1 { - pkgName = info[:i] + pkgPath = info[:i] tp, ver, err := validPath(info[i+1:]) if err != nil { - log.Error("Get", "Fail to parse version") - log.Fatal("", err.Error()) + log.Error("get", "Cannot parse dependency version") + log.Error("", err.Error()+":") + log.Error("", "\t"+info[i+1:]) + log.Help("Try 'gopm help get' to get more information") } - node = doc.NewNode(pkgName, pkgName, tp, ver, true) + node = doc.NewNode(pkgPath, pkgPath, tp, ver, true) } // Check package name. - if !strings.Contains(pkgName, "/") { - name, ok := doc.PackageNameList[pkgName] - if !ok { - log.Error("Get", "Invalid package name: "+pkgName) - log.Fatal("", "No match in the package name list") - } - pkgName = name + if !strings.Contains(pkgPath, "/") { + pkgPath = doc.GetPkgFullPath(pkgPath) } nodes = append(nodes, node) @@ -173,7 +189,8 @@ func getByPath(ctx *cli.Context) { if doc.LocalNodes != nil { if err := goconfig.SaveConfigFile(doc.LocalNodes, doc.HomeDir+doc.LocalNodesFile); err != nil { - log.Error("Get", "Fail to save localnodes.list") + log.Error("get", "Fail to save localnodes.list:") + log.Error("", "\t"+err.Error()) } } @@ -182,12 +199,11 @@ func getByPath(ctx *cli.Context) { } func copyToGopath(srcPath, destPath string) { - fmt.Println(destPath) os.RemoveAll(destPath) err := com.CopyDir(srcPath, destPath) if err != nil { - log.Error("Download", "Fail to copy to GOPATH") - log.Fatal("", err.Error()) + log.Error("download", "Fail to copy to GOPATH:") + log.Fatal("", "\t"+err.Error()) } } @@ -200,14 +216,14 @@ func downloadPackages(ctx *cli.Context, nodes []*doc.Node) { // Check if it is a valid remote path. if doc.IsValidRemotePath(n.ImportPath) { gopathDir := path.Join(installGopath, n.ImportPath) - installPath := path.Join(installRepoPath, doc.GetProjectPath(n.ImportPath)) - if len(n.Value) > 0 { - installPath += "." + n.Value - } + n.RootPath = doc.GetProjectPath(n.ImportPath) + installPath := path.Join(installRepoPath, n.RootPath) + + versionSuffix(n.Value) if !ctx.Bool("force") { // Check if package has been downloaded. - if com.IsExist(installPath) { + if (len(n.Value) == 0 && !ctx.Bool("remote") && com.IsExist(gopathDir)) || + com.IsExist(installPath) { log.Trace("Skipped installed package: %s@%s:%s", n.ImportPath, n.Type, doc.CheckNodeValue(n.Value)) @@ -216,22 +232,22 @@ func downloadPackages(ctx *cli.Context, nodes []*doc.Node) { } continue } else { - doc.LocalNodes.SetValue(doc.GetProjectPath(n.ImportPath), "value", "") + doc.LocalNodes.SetValue(n.RootPath, "value", "") } } - if !downloadCache[n.ImportPath] { + if !downloadCache[n.RootPath] { // Download package. nod, imports := downloadPackage(ctx, n) if len(imports) > 0 { var gf *goconfig.ConfigFile // Check if has gopmfile - if com.IsFile(installPath + "/" + doc.GopmFileName) { + if com.IsFile(installPath + "/" + doc.GOPM_FILE_NAME) { log.Log("Found gopmgile: %s@%s:%s", n.ImportPath, n.Type, doc.CheckNodeValue(n.Value)) - gf = doc.NewGopmfile(installPath /* + "/.gopmfile"*/) + gf = doc.NewGopmfile(installPath) } // Need to download dependencies. @@ -249,8 +265,10 @@ func downloadPackages(ctx *cli.Context, nodes []*doc.Node) { len(v) > 0 { tp, ver, err := validPath(v) if err != nil { - log.Error("Download", "Fail to parse version") - log.Fatal("", err.Error()) + log.Error("download", "Cannot parse dependency version") + log.Error("", err.Error()+":") + log.Error("", "\t"+v) + log.Help("Try 'gopm help get' to get more information") } nodes[i].Type = tp nodes[i].Value = ver @@ -268,7 +286,7 @@ func downloadPackages(ctx *cli.Context, nodes []*doc.Node) { // Only save non-commit node. if len(nod.Value) == 0 && len(nod.Revision) > 0 { - doc.LocalNodes.SetValue(doc.GetProjectPath(nod.ImportPath), "value", nod.Revision) + doc.LocalNodes.SetValue(nod.RootPath, "value", nod.Revision) } if ctx.Bool("gopath") { @@ -283,7 +301,7 @@ func downloadPackages(ctx *cli.Context, nodes []*doc.Node) { continue } else { // Invalid import path. - log.Error("", "Skipped invalid package: "+fmt.Sprintf("%s@%s:%s", + log.Error("download", "Skipped invalid package: "+fmt.Sprintf("%s@%s:%s", n.ImportPath, n.Type, doc.CheckNodeValue(n.Value))) failConut++ } @@ -297,14 +315,14 @@ func downloadPackage(ctx *cli.Context, nod *doc.Node) (*doc.Node, []string) { // Mark as donwloaded. downloadCache[nod.ImportPath] = true - nod.Revision = doc.LocalNodes.MustValue(doc.GetProjectPath(nod.ImportPath), "value") + nod.Revision = doc.LocalNodes.MustValue(nod.RootPath, "value") imports, err := doc.PureDownload(nod, installRepoPath, ctx) //CmdGet.Flags) if err != nil { - log.Error("Get", "Fail to download pakage: "+nod.ImportPath) - log.Error("", err.Error()) + log.Error("get", "Fail to download pakage: "+nod.ImportPath) + log.Error("", "\t"+err.Error()) failConut++ - os.RemoveAll(installRepoPath + "/" + doc.GetProjectPath(nod.ImportPath) + "/") + os.RemoveAll(installRepoPath + "/" + nod.RootPath) return nil, nil } return nod, imports @@ -312,7 +330,7 @@ func downloadPackage(ctx *cli.Context, nod *doc.Node) (*doc.Node, []string) { // validPath checks if the information of the package is valid. func validPath(info string) (string, string, error) { - infos := strings.SplitN(info, ":", 2) + infos := strings.Split(info, ":") l := len(infos) switch { @@ -328,3 +346,10 @@ func validPath(info string) (string, string, error) { return "", "", errors.New("Invalid version information") } } + +func versionSuffix(value string) string { + if len(value) > 0 { + return "." + value + } + return "" +} diff --git a/cmd/gopath.go b/cmd/gopath.go index 4a903ab08..f6599b27d 100644 --- a/cmd/gopath.go +++ b/cmd/gopath.go @@ -26,7 +26,7 @@ func getGopmPkgs(dirPath string, isTest bool) (pkgs map[string]*doc.Pkg, err err var builds map[string]string - if com.IsFile(absPath + "/" + doc.GopmFileName) { + if com.IsFile(absPath + "/" + doc.GOPM_FILE_NAME) { gf := doc.NewGopmfile(absPath) if builds, err = gf.GetSection("deps"); err != nil { @@ -190,7 +190,7 @@ func genNewGoPath(ctx *cli.Context, isTest bool) { installRepoPath = doc.HomeDir + "/repos" - if com.IsFile(curPath + "/" + doc.GopmFileName) { + if com.IsFile(curPath + "/" + doc.GOPM_FILE_NAME) { log.Trace("Loading gopmfile...") gf := doc.NewGopmfile(curPath) diff --git a/cmd/run.go b/cmd/run.go index faa070e4a..5705782fe 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -16,6 +16,7 @@ package cmd import ( "github.com/codegangsta/cli" + "github.com/gpmgo/gopm/log" ) diff --git a/cmd/test.go b/cmd/test.go index 71308d884..74e837aec 100644 --- a/cmd/test.go +++ b/cmd/test.go @@ -16,6 +16,7 @@ package cmd import ( "github.com/codegangsta/cli" + "github.com/gpmgo/gopm/log" ) diff --git a/cmd/update.go b/cmd/update.go index d72a1ddb1..db592e65a 100644 --- a/cmd/update.go +++ b/cmd/update.go @@ -127,7 +127,7 @@ func runUpdate(ctx *cli.Context) { }() // Check if previous steps were successful. - if com.IsFile(doc.GopmFileName) { + if com.IsFile(doc.GOPM_FILE_NAME) { log.Trace("Loading gopmfile...") gf := doc.NewGopmfile(".") diff --git a/doc/conf.go b/doc/conf.go index 82f8374e8..64def7765 100644 --- a/doc/conf.go +++ b/doc/conf.go @@ -17,6 +17,7 @@ package doc import ( "os" "path" + "path/filepath" "strings" "github.com/Unknwon/com" @@ -26,8 +27,8 @@ import ( ) const ( - GopmFileName = ".gopmfile" - RawHomeDir = "~/.gopm" + GOPM_FILE_NAME = ".gopmfile" + RawHomeDir = "~/.gopm" ) var ( @@ -46,13 +47,16 @@ func init() { HomeDir = strings.Replace(RawHomeDir, "~", hd, -1) LoadLocalNodes() + LoadPkgNameList(HomeDir + "/data/pkgname.list") } +// NewGopmfile loads gopmgile in given directory. func NewGopmfile(dirPath string) *goconfig.ConfigFile { - gf, err := goconfig.LoadConfigFile(path.Join(dirPath, GopmFileName)) + dirPath, _ = filepath.Abs(dirPath) + gf, err := goconfig.LoadConfigFile(path.Join(dirPath, GOPM_FILE_NAME)) if err != nil { - log.Error("", "Fail to load gopmfile") - log.Fatal("", err.Error()) + log.Error("", "Fail to load gopmfile:") + log.Fatal("", "\t"+err.Error()) } return gf } @@ -85,6 +89,16 @@ func LoadPkgNameList(filePath string) { } } +func GetPkgFullPath(short string) string { + name, ok := PackageNameList[short] + if !ok { + log.Error("", "Invalid package name") + log.Error("", "No match in the package name list:") + log.Fatal("", "\t"+short) + } + return name +} + func LoadLocalNodes() { if !com.IsDir(HomeDir + "/data") { os.MkdirAll(HomeDir+"/data", os.ModePerm) diff --git a/doc/struct.go b/doc/struct.go index f1ad2d4b4..f92151618 100644 --- a/doc/struct.go +++ b/doc/struct.go @@ -36,6 +36,7 @@ const ( type Pkg struct { ImportPath string + RootPath string Type string Value string // Branch, tag or commit. } @@ -48,7 +49,7 @@ func (pkg *Pkg) VerString() string { } func NewPkg(importPath, tp, value string) *Pkg { - return &Pkg{importPath, tp, value} + return &Pkg{importPath, "", tp, value} } func NewDefaultPkg(importPath string) *Pkg { @@ -65,9 +66,10 @@ type Node struct { func NewNode(importPath, downloadUrl, tp, value string, isGetDeps bool) *Node { return &Node{ - Pkg: Pkg{ImportPath: importPath, - Type: tp, - Value: value, + Pkg: Pkg{ + ImportPath: importPath, + Type: tp, + Value: value, }, DownloadURL: downloadUrl, IsGetDeps: isGetDeps, diff --git a/log/log.go b/log/log.go index 9c445ae61..07d2be159 100644 --- a/log/log.go +++ b/log/log.go @@ -14,6 +14,7 @@ // +build !windows +// Package log provides npm-like style log output. package log import ( @@ -58,3 +59,9 @@ func Message(hl, msg string) { } fmt.Printf("gopm %s%s %s\n", brush.Yellow("MSG!"), hl, msg) } + +func Help(format string, args ...interface{}) { + fmt.Printf("gopm %s %s\n", brush.Cyan("HELP"), + fmt.Sprintf(format, args...)) + os.Exit(2) +} diff --git a/log/log_windows.go b/log/log_windows.go index 0c180263b..fcfa4174a 100644 --- a/log/log_windows.go +++ b/log/log_windows.go @@ -12,6 +12,7 @@ // License for the specific language governing permissions and limitations // under the License. +// Package log provides npm-like style log output. package log import (