From 37954226bc7685ab19d1b4b2fe39ba117f373283 Mon Sep 17 00:00:00 2001 From: Unknown Date: Sat, 25 May 2013 20:30:15 -0400 Subject: [PATCH] clean code --- README.md | 1 + build.go => cmd/build.go | 20 ++-- check.go => cmd/check.go | 28 +++--- install.go => cmd/install.go | 78 +++++++-------- remove.go => cmd/remove.go | 30 +++--- search.go => cmd/search.go | 43 +++++---- cmd/struct.go | 108 +++++++++++++++++++++ gopm.go | 182 +++++++++-------------------------- 8 files changed, 256 insertions(+), 234 deletions(-) rename build.go => cmd/build.go (78%) rename check.go => cmd/check.go (83%) rename install.go => cmd/install.go (79%) rename remove.go => cmd/remove.go (84%) rename search.go => cmd/search.go (79%) create mode 100644 cmd/struct.go diff --git a/README.md b/README.md index e8f62bc81..7c05be963 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ This application still in experiment, any change could happen, but it doesn't af ### Future +- Command `search` compares version. - Command `home` and `doc`. - Command `remove` add flag `-d` for removing dependencies at the same time. - Command `remove` add feature check for dependencies, make sure other packages don't import this one, and give choose for users. diff --git a/build.go b/cmd/build.go similarity index 78% rename from build.go rename to cmd/build.go index d40bde381..6ca16867e 100644 --- a/build.go +++ b/cmd/build.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package main +package cmd import ( "fmt" @@ -11,13 +11,13 @@ import ( "github.com/GPMGo/gopm/utils" ) -var cmdBuild = &Command{ +var CmdBuild = &Command{ UsageLine: "build [build flags] [packages]", } func init() { - cmdBuild.Run = runBuild - cmdBuild.Flags = map[string]bool{ + CmdBuild.Run = runBuild + CmdBuild.Flags = map[string]bool{ "-v": false, "-r": false, } @@ -33,7 +33,7 @@ func printBuildPrompt(flag string) { func runBuild(cmd *Command, args []string) { // Check flags. - num := checkFlags(cmd.Flags, config.AutoEnable.Build, args, printBuildPrompt) + num := checkFlags(cmd.Flags, Config.AutoEnable.Build, args, printBuildPrompt) if num == -1 { return } @@ -41,7 +41,7 @@ func runBuild(cmd *Command, args []string) { var cmdArgs []string cmdArgs = append(cmdArgs, "install") - if cmdBuild.Flags["-v"] { + if CmdBuild.Flags["-v"] { cmdArgs = append(cmdArgs, "-v") } @@ -57,22 +57,22 @@ func runBuild(cmd *Command, args []string) { if utils.IsExist(wd + "/" + proName) { err := os.Remove(wd + "/" + proName) if err != nil { - utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] %s\n", promptMsg["RemoveFile"]), err)) + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] %s\n", PromptMsg["RemoveFile"]), err)) return } } err := os.Rename(v+"/bin/"+proName, wd+"/"+proName) if err == nil { - utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("$ %s\n", promptMsg["MovedFile"]), v, wd)) + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("$ %s\n", PromptMsg["MovedFile"]), v, wd)) // Check if need to run program. - if cmdBuild.Flags["-r"] { + if CmdBuild.Flags["-r"] { cmdArgs = make([]string, 0) executeCommand(proName, cmdArgs) } return } - fmt.Printf(fmt.Sprintf("%s\n", promptMsg["MoveFile"]), v, wd) + fmt.Printf(fmt.Sprintf("%s\n", PromptMsg["MoveFile"]), v, wd) break } } diff --git a/check.go b/cmd/check.go similarity index 83% rename from check.go rename to cmd/check.go index 873e4542d..29356fd0b 100644 --- a/check.go +++ b/cmd/check.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package main +package cmd import ( "fmt" @@ -13,13 +13,13 @@ import ( "github.com/GPMGo/gopm/utils" ) -var cmdCheck = &Command{ +var CmdCheck = &Command{ UsageLine: "check [check flags] [packages]", } func init() { - cmdCheck.Run = runCheck - cmdCheck.Flags = map[string]bool{ + CmdCheck.Run = runCheck + CmdCheck.Flags = map[string]bool{ "-e": false, } } @@ -29,13 +29,13 @@ func init() { func printCheckPrompt(flag string) { switch flag { case "-e": - fmt.Printf(fmt.Sprintf("%s\n", promptMsg["CheckExDeps"])) + fmt.Printf(fmt.Sprintf("%s\n", PromptMsg["CheckExDeps"])) } } func runCheck(cmd *Command, args []string) { // Check flags. - num := checkFlags(cmd.Flags, config.AutoEnable.Check, args, printCheckPrompt) + num := checkFlags(cmd.Flags, Config.AutoEnable.Check, args, printCheckPrompt) if num == -1 { return } @@ -45,14 +45,14 @@ func runCheck(cmd *Command, args []string) { // Guess import path. gopath := utils.GetBestMatchGOPATH(wd) + "/src/" if len(wd) <= len(gopath) { - fmt.Printf(fmt.Sprintf("runCheck -> %s\n", promptMsg["InvalidPath"])) + fmt.Printf(fmt.Sprintf("runCheck -> %s\n", PromptMsg["InvalidPath"])) return } importPath := wd[len(gopath):] imports, err := checkImportsByRoot(wd+"/", importPath) if err != nil { - utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("runCheck -> %s\n", promptMsg["CheckImports"]), err)) + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("runCheck -> %s\n", PromptMsg["CheckImports"]), err)) return } @@ -86,19 +86,19 @@ func runCheck(cmd *Command, args []string) { // Check if need to install packages. if len(uninstallList) > 0 { - fmt.Printf(fmt.Sprintf("%s\n", promptMsg["MissingImports"])) + fmt.Printf(fmt.Sprintf("%s\n", PromptMsg["MissingImports"])) for _, v := range uninstallList { fmt.Printf("%s\n", v) } - fmt.Printf(fmt.Sprintf("%s\n", promptMsg["ContinueDownload"])) + fmt.Printf(fmt.Sprintf("%s\n", PromptMsg["ContinueDownload"])) var option string fmt.Fscan(os.Stdin, &option) if strings.ToLower(option) != "y" { os.Exit(0) } - installGOPATH = utils.GetBestMatchGOPATH(appPath) - utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("%s\n", promptMsg["DownloadPath"]), installGOPATH)) + installGOPATH = utils.GetBestMatchGOPATH(AppPath) + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("%s\n", PromptMsg["DownloadPath"]), installGOPATH)) // Generate temporary nodes. nodes := make([]*doc.Node, len(uninstallList)) for i := range nodes { @@ -116,7 +116,7 @@ func runCheck(cmd *Command, args []string) { cmdArgs = append(cmdArgs, "") for _, k := range uninstallList { - fmt.Printf(fmt.Sprintf("%s\n", promptMsg["InstallStatus"]), k) + fmt.Printf(fmt.Sprintf("%s\n", PromptMsg["InstallStatus"]), k) cmdArgs[1] = k executeCommand("go", cmdArgs) } @@ -143,7 +143,7 @@ func checkImportsByRoot(rootPath, importPath string) (imports []string, err erro for _, d := range dirs { if d.IsDir() && - !(!cmdCheck.Flags["-e"] && strings.Contains(d.Name(), "example")) { + !(!CmdCheck.Flags["-e"] && strings.Contains(d.Name(), "example")) { importPkgs, err := checkImportsByRoot(rootPath+d.Name()+"/", importPath) if err != nil { return nil, err diff --git a/install.go b/cmd/install.go similarity index 79% rename from install.go rename to cmd/install.go index df15c2a0b..40184da59 100644 --- a/install.go +++ b/cmd/install.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package main +package cmd import ( "encoding/json" @@ -24,14 +24,14 @@ var ( installGOPATH string // The GOPATH that packages are downloaded to. ) -var cmdInstall = &Command{ +var CmdInstall = &Command{ UsageLine: "install [install flags] ", } func init() { downloadCache = make(map[string]bool) - cmdInstall.Run = runInstall - cmdInstall.Flags = map[string]bool{ + CmdInstall.Run = runInstall + CmdInstall.Flags = map[string]bool{ "-v": false, "-d": false, "-u": false, // Flag for 'go get'. @@ -45,13 +45,13 @@ func init() { func printInstallPrompt(flag string) { switch flag { case "-v": - fmt.Printf(fmt.Sprintf("%s\n", promptMsg["PureDownload"])) + fmt.Printf(fmt.Sprintf("%s\n", PromptMsg["PureDownload"])) case "-d": - fmt.Printf(fmt.Sprintf("%s\n", promptMsg["DownloadOnly"])) + fmt.Printf(fmt.Sprintf("%s\n", PromptMsg["DownloadOnly"])) case "-e": - fmt.Printf(fmt.Sprintf("%s\n", promptMsg["DownloadExDeps"])) + fmt.Printf(fmt.Sprintf("%s\n", PromptMsg["DownloadExDeps"])) case "-s": - fmt.Printf(fmt.Sprintf("%s\n", promptMsg["DownloadFromSrcs"])) + fmt.Printf(fmt.Sprintf("%s\n", PromptMsg["DownloadFromSrcs"])) } } @@ -80,7 +80,7 @@ func checkFlags(flags map[string]bool, enable []string, args []string, print fun fmt.Println("DISABLE: " + f) } } else { - fmt.Printf(fmt.Sprintf("%s\n", promptMsg["UnknownFlag"]), f) + fmt.Printf(fmt.Sprintf("%s\n", PromptMsg["UnknownFlag"]), f) return -1 } num = i + 1 @@ -104,7 +104,7 @@ func checkVCSTool() { func runInstall(cmd *Command, args []string) { // Check flags. - num := checkFlags(cmd.Flags, config.AutoEnable.Install, args, printInstallPrompt) + num := checkFlags(cmd.Flags, Config.AutoEnable.Install, args, printInstallPrompt) if num == -1 { return } @@ -112,15 +112,15 @@ func runInstall(cmd *Command, args []string) { // Check length of arguments. if len(args) < 1 { - fmt.Printf(fmt.Sprintf("%s\n", promptMsg["NoPackage"])) + fmt.Printf(fmt.Sprintf("%s\n", PromptMsg["NoPackage"])) return } // Check version control tools. checkVCSTool() - installGOPATH = utils.GetBestMatchGOPATH(appPath) - utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("%s\n", promptMsg["DownloadPath"]), installGOPATH)) + installGOPATH = utils.GetBestMatchGOPATH(AppPath) + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("%s\n", PromptMsg["DownloadPath"]), installGOPATH)) // Generate temporary nodes. nodes := make([]*doc.Node, len(args)) @@ -131,7 +131,7 @@ func runInstall(cmd *Command, args []string) { // Download packages. downloadPackages(nodes) - if !cmdInstall.Flags["-d"] && !cmdInstall.Flags["-v"] { + if !CmdInstall.Flags["-d"] && !CmdInstall.Flags["-v"] { // Remove old files. uninstallList := make([]string, 0, len(downloadCache)) for k := range downloadCache { @@ -145,21 +145,21 @@ func runInstall(cmd *Command, args []string) { cmdArgs = append(cmdArgs, "") for k := range downloadCache { - fmt.Printf(fmt.Sprintf("%s\n", promptMsg["InstallStatus"]), k) + fmt.Printf(fmt.Sprintf("%s\n", PromptMsg["InstallStatus"]), k) cmdArgs[1] = k executeCommand("go", cmdArgs) } // Save local nodes to file. - fw, err := os.Create(appPath + "data/nodes.json") + fw, err := os.Create(AppPath + "data/nodes.json") if err != nil { - utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] runInstall -> %s\n", promptMsg["OpenFile"]), err)) + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] runInstall -> %s\n", PromptMsg["OpenFile"]), err)) return } defer fw.Close() - fbytes, err := json.MarshalIndent(&localNodes, "", "\t") + fbytes, err := json.MarshalIndent(&LocalNodes, "", "\t") if err != nil { - utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] runInstall -> %s\n", promptMsg["ParseJSON"]), err)) + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] runInstall -> %s\n", PromptMsg["ParseJSON"]), err)) return } fw.Write(fbytes) @@ -181,7 +181,7 @@ func chekcDeps(nodes []*doc.Node) (depnodes []*doc.Node) { // checkLocalBundles checks if the bundle is in local file system. func checkLocalBundles(bundle string) (nodes []*doc.Node) { - for _, b := range localBundles { + for _, b := range LocalBundles { if bundle == b.Name { nodes = append(nodes, chekcDeps(b.Nodes)...) return nodes @@ -204,11 +204,11 @@ func downloadPackages(nodes []*doc.Node) { bnodes := checkLocalBundles(n.ImportPath[:l-2]) if len(bnodes) > 0 { // Check with users if continue. - utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("%s\n", promptMsg["BundleInfo"]), n.ImportPath[:l-2])) + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("%s\n", PromptMsg["BundleInfo"]), n.ImportPath[:l-2])) for _, bn := range bnodes { fmt.Printf("[%s] -> %s: %s.\n", bn.ImportPath, bn.Type, bn.Value) } - fmt.Printf(fmt.Sprintf("%s\n", promptMsg["ContinueDownload"])) + fmt.Printf(fmt.Sprintf("%s\n", PromptMsg["ContinueDownload"])) var option string fmt.Fscan(os.Stdin, &option) if strings.ToLower(option) != "y" { @@ -243,11 +243,11 @@ func downloadPackages(nodes []*doc.Node) { saveNode(node) } } else { - fmt.Printf(fmt.Sprintf("%s\n", promptMsg["SkipDownloaded"]), n.ImportPath) + fmt.Printf(fmt.Sprintf("%s\n", PromptMsg["SkipDownloaded"]), n.ImportPath) } default: // Invalid import path. - fmt.Printf(fmt.Sprintf("%s\n", promptMsg["SkipInvalidPath"]), n.ImportPath) + fmt.Printf(fmt.Sprintf("%s\n", PromptMsg["SkipInvalidPath"]), n.ImportPath) } } } @@ -258,42 +258,42 @@ func saveNode(n *doc.Node) { n.Deps = nil // Check if this node exists. - for i, v := range localNodes { + for i, v := range LocalNodes { if n.ImportPath == v.ImportPath { - localNodes[i] = n + LocalNodes[i] = n return } } // Add new node. - localNodes = append(localNodes, n) + LocalNodes = append(LocalNodes, n) } // downloadPackage downloads package either use version control tools or not. func downloadPackage(node *doc.Node) (*doc.Node, []string) { // Check if use version control tools. switch { - case cmdInstall.Flags["-v"] && + case CmdInstall.Flags["-v"] && ((node.ImportPath[0] == 'g' && isHasGit) || (node.ImportPath[0] == 'c' && isHasHg)): // github.com, code.google.com - fmt.Printf(fmt.Sprintf("%s\n", promptMsg["InstallByGoGet"]), node.ImportPath) + fmt.Printf(fmt.Sprintf("%s\n", PromptMsg["InstallByGoGet"]), node.ImportPath) args := checkGoGetFlags() args = append(args, node.ImportPath) executeCommand("go", args) return nil, nil default: // Pure download. - if cmdInstall.Flags["-v"] { - cmdInstall.Flags["-v"] = false - fmt.Printf(fmt.Sprintf("%s\n", promptMsg["NoVCSTool"])) + if CmdInstall.Flags["-v"] { + CmdInstall.Flags["-v"] = false + fmt.Printf(fmt.Sprintf("%s\n", PromptMsg["NoVCSTool"])) } - fmt.Printf(fmt.Sprintf("%s\n", promptMsg["DownloadStatus"]), node.ImportPath) + fmt.Printf(fmt.Sprintf("%s\n", PromptMsg["DownloadStatus"]), node.ImportPath) // Mark as donwloaded. downloadCache[node.ImportPath] = true imports, err := pureDownload(node) if err != nil { - utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] %s\n", promptMsg["DownloadError"]), node.ImportPath, err)) + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] %s\n", PromptMsg["DownloadError"]), node.ImportPath, err)) return nil, nil } @@ -304,10 +304,10 @@ func downloadPackage(node *doc.Node) (*doc.Node, []string) { func checkGoGetFlags() (args []string) { args = append(args, "get") switch { - case cmdInstall.Flags["-d"]: + case CmdInstall.Flags["-d"]: args = append(args, "-d") fallthrough - case cmdInstall.Flags["-u"]: + case CmdInstall.Flags["-u"]: args = append(args, "-u") } @@ -339,7 +339,7 @@ func pureDownload(node *doc.Node) ([]string, error) { if m == nil { if s.prefix != "" { return nil, - doc.NotFoundError{fmt.Sprintf("%s", promptMsg["NotFoundError"])} + doc.NotFoundError{fmt.Sprintf("%s", PromptMsg["NotFoundError"])} } continue } @@ -349,7 +349,7 @@ func pureDownload(node *doc.Node) ([]string, error) { match[n] = m[i] } } - return s.get(doc.HttpClient, match, installGOPATH, node, cmdInstall.Flags) + return s.get(doc.HttpClient, match, installGOPATH, node, CmdInstall.Flags) } - return nil, errors.New(fmt.Sprintf("%s", promptMsg["NotFoundError"])) + return nil, errors.New(fmt.Sprintf("%s", PromptMsg["NotFoundError"])) } diff --git a/remove.go b/cmd/remove.go similarity index 84% rename from remove.go rename to cmd/remove.go index f955e16d3..0721011c9 100644 --- a/remove.go +++ b/cmd/remove.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package main +package cmd import ( "encoding/json" @@ -19,19 +19,19 @@ var ( removeCache map[string]bool // Saves packages that have been removed. ) -var cmdRemove = &Command{ +var CmdRemove = &Command{ UsageLine: "remove [remove flags] ", } func init() { removeCache = make(map[string]bool) - cmdRemove.Run = runRemove + CmdRemove.Run = runRemove } func runRemove(cmd *Command, args []string) { // Check length of arguments. if len(args) < 1 { - fmt.Printf(fmt.Sprintf("%s\n", promptMsg["NoPackage"])) + fmt.Printf(fmt.Sprintf("%s\n", PromptMsg["NoPackage"])) return } @@ -46,15 +46,15 @@ func runRemove(cmd *Command, args []string) { removePackages(nodes) // Save local nodes to file. - fw, err := os.Create(appPath + "data/nodes.json") + fw, err := os.Create(AppPath + "data/nodes.json") if err != nil { - utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] runRemove -> %s\n", promptMsg["OpenFile"]), err)) + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] runRemove -> %s\n", PromptMsg["OpenFile"]), err)) return } defer fw.Close() - fbytes, err := json.MarshalIndent(&localNodes, "", "\t") + fbytes, err := json.MarshalIndent(&LocalNodes, "", "\t") if err != nil { - utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] runRemove -> %s\n", promptMsg["ParseJSON"]), err)) + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] runRemove -> %s\n", PromptMsg["ParseJSON"]), err)) return } fw.Write(fbytes) @@ -72,11 +72,11 @@ func removePackages(nodes []*doc.Node) { bnodes := checkLocalBundles(n.ImportPath[:l-2]) if len(bnodes) > 0 { // Check with users if continue. - utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("%s\n", promptMsg["BundleInfo"]), n.ImportPath[:l-2])) + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("%s\n", PromptMsg["BundleInfo"]), n.ImportPath[:l-2])) for _, bn := range bnodes { fmt.Printf("[%s] -> %s: %s.\n", bn.ImportPath, bn.Type, bn.Value) } - fmt.Printf(fmt.Sprintf("%s\n", promptMsg["ContinueRemove"])) + fmt.Printf(fmt.Sprintf("%s\n", PromptMsg["ContinueRemove"])) var option string fmt.Fscan(os.Stdin, &option) if strings.ToLower(option) != "y" { @@ -104,7 +104,7 @@ func removePackages(nodes []*doc.Node) { } default: // Invalid import path. - fmt.Printf(fmt.Sprintf("%s\n", promptMsg["SkipInvalidPath"]), n.ImportPath) + fmt.Printf(fmt.Sprintf("%s\n", PromptMsg["SkipInvalidPath"]), n.ImportPath) } } } @@ -112,9 +112,9 @@ func removePackages(nodes []*doc.Node) { // removeNode removes node from local nodes. func removeNode(n *doc.Node) { // Check if this node exists. - for i, v := range localNodes { + for i, v := range LocalNodes { if n.ImportPath == v.ImportPath { - localNodes = append(localNodes[:i], localNodes[i+1:]...) + LocalNodes = append(LocalNodes[:i], LocalNodes[i+1:]...) return } } @@ -127,7 +127,7 @@ func removePackage(node *doc.Node) (*doc.Node, []string) { for _, p := range paths { absPath := p + "/src/" + utils.GetProjectPath(node.ImportPath) + "/" if utils.IsExist(absPath) { - fmt.Printf(fmt.Sprintf("%s\n", promptMsg["RemovePackage"]), node.ImportPath) + fmt.Printf(fmt.Sprintf("%s\n", PromptMsg["RemovePackage"]), node.ImportPath) // Remove files. os.RemoveAll(absPath) // Remove file in GOPATH/bin @@ -150,7 +150,7 @@ func removePackage(node *doc.Node) (*doc.Node, []string) { } // Cannot find package. - fmt.Printf(fmt.Sprintf("%s\n", promptMsg["PackageNotFound"]), node.ImportPath) + fmt.Printf(fmt.Sprintf("%s\n", PromptMsg["PackageNotFound"]), node.ImportPath) return nil, nil } diff --git a/search.go b/cmd/search.go similarity index 79% rename from search.go rename to cmd/search.go index ed06c5ba7..98a2972e1 100644 --- a/search.go +++ b/cmd/search.go @@ -2,9 +2,10 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package main +package cmd import ( + "bytes" "fmt" "runtime" "strings" @@ -13,12 +14,12 @@ import ( "github.com/GPMGo/gopm/utils" ) -var cmdSearch = &Command{ +var CmdSearch = &Command{ UsageLine: "search [search flags] ", } func init() { - cmdSearch.Run = runSearch + CmdSearch.Run = runSearch } // printSearchPrompt prints prompt information to users to @@ -31,7 +32,7 @@ func printSearchPrompt(flag string) { func runSearch(cmd *Command, args []string) { // Check flags. - num := checkFlags(cmd.Flags, config.AutoEnable.Search, args, printSearchPrompt) + num := checkFlags(cmd.Flags, Config.AutoEnable.Search, args, printSearchPrompt) if num == -1 { return } @@ -39,7 +40,7 @@ func runSearch(cmd *Command, args []string) { // Check length of arguments. if len(args) < 1 { - fmt.Printf(fmt.Sprintf("%s\n", promptMsg["NoKeyword"])) + fmt.Printf(fmt.Sprintf("%s\n", PromptMsg["NoKeyword"])) return } @@ -50,18 +51,9 @@ func runSearch(cmd *Command, args []string) { return } - resultStr := string(results) - - isWindws := runtime.GOOS == "windows" - if !isWindws { - // Set color highlight. - resultStr = strings.Replace(resultStr, args[0], - fmt.Sprintf(utils.PureStartColor, utils.Yellow)+args[0]+utils.EndColor, -1) - } - pkgsCache := make(map[string]string) paths := utils.GetGOPATH() - pkgs := strings.Split(resultStr, "|||") + pkgs := strings.Split(string(results), "|||") for _, p := range pkgs { i := strings.Index(p, "$") if i > -1 { @@ -72,8 +64,11 @@ func runSearch(cmd *Command, args []string) { } } + isWindws := runtime.GOOS == "windows" + var buf bytes.Buffer for k, v := range pkgsCache { - fmt.Print("-> " + k) // Package import path. + // Package import path. + buf.WriteString("-> " + k) // Check if has been installed. for _, path := range paths { if checkIsExistWithVCS(path + "/src/" + k + "/") { @@ -84,14 +79,24 @@ func runSearch(cmd *Command, args []string) { installStr = strings.Replace(installStr, "]", utils.EndColor+"]", 1) } - fmt.Print(installStr) + buf.WriteString(installStr) break } } - fmt.Print("\n") + buf.WriteString("\n") if len(v) > 0 { - fmt.Println(" " + v) // Synopsis。 + buf.WriteString(" " + v + "\n") // Synopsis。 } } + + resultStr := buf.String() + + if !isWindws { + // Set color highlight. + resultStr = strings.Replace(resultStr, args[0], + fmt.Sprintf(utils.PureStartColor, utils.Yellow)+args[0]+utils.EndColor, -1) + } + + fmt.Print(resultStr) } diff --git a/cmd/struct.go b/cmd/struct.go new file mode 100644 index 000000000..cce2863c8 --- /dev/null +++ b/cmd/struct.go @@ -0,0 +1,108 @@ +// 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 cmd + +import ( + "fmt" + "io" + "os" + "os/exec" + "strings" + + "github.com/GPMGo/gopm/doc" +) + +var ( + Config tomlConfig + AppPath string // Application path. +) + +var ( + LocalNodes []*doc.Node + LocalBundles []*doc.Bundle +) + +type tomlConfig struct { + Title, Version string + Lang string `toml:"user_language"` + AutoBackup bool `toml:"auto_backup"` + Account account + AutoEnable flagEnable `toml:"auto_enable"` +} + +type flagEnable struct { + Build, Install, Search, Check []string +} + +type account struct { + Username, Password string + Github_Access_Token string `toml:"github_access_token"` +} + +// Use for i18n, key is prompt code, value is corresponding message. +var PromptMsg map[string]string + +// A Command is an implementation of a go command +// like go build or go fix. +type Command struct { + // Run runs the command. + // The args are the arguments after the command name. + Run func(cmd *Command, args []string) + + // UsageLine is the one-line usage message. + // The first word in the line is taken to be the command name. + UsageLine string + + // Short is the short description shown in the 'go help' output. + Short string + + // Long is the long message shown in the 'go help ' output. + Long string + + // Flag is a set of flags specific to this command. + Flags map[string]bool +} + +// Name returns the command's name: the first word in the usage line. +func (c *Command) Name() string { + name := c.UsageLine + i := strings.Index(name, " ") + if i >= 0 { + name = name[:i] + } + return name +} + +func (c *Command) Usage() { + fmt.Fprintf(os.Stderr, "usage: %s\n\n", c.UsageLine) + fmt.Fprintf(os.Stderr, "%s\n", strings.TrimSpace(c.Long)) + os.Exit(2) +} + +// Runnable reports whether the command can be run; otherwise +// it is a documentation pseudo-command such as importpath. +func (c *Command) Runnable() bool { + return c.Run != nil +} + +// executeCommand executes commands in command line. +func executeCommand(cmd string, args []string) { + cmdExec := exec.Command(cmd, args...) + stdout, err := cmdExec.StdoutPipe() + if err != nil { + fmt.Println(err) + } + stderr, err := cmdExec.StderrPipe() + if err != nil { + fmt.Println(err) + } + err = cmdExec.Start() + if err != nil { + fmt.Println(err) + } + go io.Copy(os.Stdout, stdout) + go io.Copy(os.Stderr, stderr) + cmdExec.Wait() +} diff --git a/gopm.go b/gopm.go index 75cf5faa4..26bf5cb3d 100644 --- a/gopm.go +++ b/gopm.go @@ -22,129 +22,57 @@ import ( "unicode/utf8" "github.com/BurntSushi/toml" + "github.com/GPMGo/gopm/cmd" "github.com/GPMGo/gopm/doc" "github.com/GPMGo/gopm/utils" ) -var ( - config tomlConfig - appPath string // Application path. -) - -var ( - localNodes []*doc.Node - localBundles []*doc.Bundle -) - -// Use for i18n, key is prompt code, value is corresponding message. -var promptMsg map[string]string - -type tomlConfig struct { - Title, Version string - Lang string `toml:"user_language"` - AutoBackup bool `toml:"auto_backup"` - Account account - AutoEnable flagEnable `toml:"auto_enable"` -} - -type flagEnable struct { - Build, Install, Search, Check []string -} - -type account struct { - Username, Password string - Github_Access_Token string `toml:"github_access_token"` -} - -// A Command is an implementation of a go command -// like go build or go fix. -type Command struct { - // Run runs the command. - // The args are the arguments after the command name. - Run func(cmd *Command, args []string) - - // UsageLine is the one-line usage message. - // The first word in the line is taken to be the command name. - UsageLine string - - // Short is the short description shown in the 'go help' output. - Short string - - // Long is the long message shown in the 'go help ' output. - Long string - - // Flag is a set of flags specific to this command. - Flags map[string]bool -} - -// Name returns the command's name: the first word in the usage line. -func (c *Command) Name() string { - name := c.UsageLine - i := strings.Index(name, " ") - if i >= 0 { - name = name[:i] - } - return name -} - -func (c *Command) Usage() { - fmt.Fprintf(os.Stderr, "usage: %s\n\n", c.UsageLine) - fmt.Fprintf(os.Stderr, "%s\n", strings.TrimSpace(c.Long)) - os.Exit(2) -} - -// Runnable reports whether the command can be run; otherwise -// it is a documentation pseudo-command such as importpath. -func (c *Command) Runnable() bool { - return c.Run != nil -} - // Commands lists the available commands and help topics. // The order here is the order in which they are printed by 'gpm help'. -var commands = []*Command{ - cmdBuild, - cmdSearch, - cmdInstall, - cmdRemove, - cmdCheck, +var commands = []*cmd.Command{ + cmd.CmdBuild, + cmd.CmdSearch, + cmd.CmdInstall, + cmd.CmdRemove, + cmd.CmdCheck, } // getAppPath returns application execute path for current process. func getAppPath() bool { // Look up executable in PATH variable. - appPath, _ = exec.LookPath(path.Base(os.Args[0])) + cmd.AppPath, _ = exec.LookPath(path.Base(os.Args[0])) // Check if run under $GOPATH/bin - if !utils.IsExist(appPath + "conf/") { + if !utils.IsExist(cmd.AppPath + "conf/") { paths := utils.GetGOPATH() for _, p := range paths { if utils.IsExist(p + "/src/github.com/GPMGo/gopm/") { - appPath = p + "/src/github.com/GPMGo/gopm/" + cmd.AppPath = p + "/src/github.com/GPMGo/gopm/" break } } } - if len(appPath) == 0 { + if len(cmd.AppPath) == 0 { utils.ColorPrint("[ERROR] getAppPath ->[ Unable to indicate current execute path. ]\n") return false } - appPath = filepath.Dir(appPath) + "/" + cmd.AppPath = filepath.Dir(cmd.AppPath) + "/" if runtime.GOOS == "windows" { // Replace all '\' to '/'. - appPath = strings.Replace(appPath, "\\", "/", -1) + cmd.AppPath = strings.Replace(cmd.AppPath, "\\", "/", -1) } - doc.SetAppConfig(appPath, config.AutoBackup) + doc.SetAppConfig(cmd.AppPath, cmd.Config.AutoBackup) return true } // loadPromptMsg loads prompt messages according to user language. func loadPromptMsg(lang string) bool { - promptMsg = make(map[string]string) + cmd.PromptMsg = make(map[string]string) // Load prompt messages. - f, err := os.Open(appPath + "i18n/" + lang + "/prompt.txt") + f, err := os.Open(cmd.AppPath + "i18n/" + lang + "/prompt.txt") if err != nil { utils.ColorPrint(fmt.Sprintf("[ERROR] loadUsage -> Fail to load prompt messages[ %s ]\n", err)) return false @@ -159,7 +87,7 @@ func loadPromptMsg(lang string) bool { for _, p := range promptStrs { i := strings.Index(p, "=") if i > -1 { - promptMsg[p[:i]] = p[i+1:] + cmd.PromptMsg[p[:i]] = p[i+1:] } } return true @@ -172,9 +100,9 @@ func loadUsage(lang string) bool { } // Load main usage. - f, err := os.Open(appPath + "i18n/" + lang + "/usage.tpl") + f, err := os.Open(cmd.AppPath + "i18n/" + lang + "/usage.tpl") if err != nil { - utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] loadUsage -> %s\n", promptMsg["LoadCommandUsage"]), "main", err)) + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] loadUsage -> %s\n", cmd.PromptMsg["LoadCommandUsage"]), "main", err)) return false } defer f.Close() @@ -186,10 +114,10 @@ func loadUsage(lang string) bool { usageTemplate = string(usageBytes) // Load command usage. - for _, cmd := range commands { - f, err := os.Open(appPath + "i18n/" + lang + "/usage_" + cmd.Name() + ".txt") + for _, command := range commands { + f, err := os.Open(cmd.AppPath + "i18n/" + lang + "/usage_" + command.Name() + ".txt") if err != nil { - utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] loadUsage -> %s\n", promptMsg["LoadCommandUsage"]), cmd.Name(), err)) + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] loadUsage -> %s\n", cmd.PromptMsg["LoadCommandUsage"]), command.Name(), err)) return false } defer f.Close() @@ -201,11 +129,11 @@ func loadUsage(lang string) bool { usages := strings.Split(string(usageBytes), "|||") if len(usages) < 2 { utils.ColorPrint(fmt.Sprintf( - fmt.Sprintf("[ERROR] loadUsage -> %s\n", promptMsg["ReadCoammndUsage"]), cmd.Name())) + fmt.Sprintf("[ERROR] loadUsage -> %s\n", cmd.PromptMsg["ReadCoammndUsage"]), command.Name())) return false } - cmd.Short = usages[0] - cmd.Long = usages[1] + command.Short = usages[0] + command.Long = usages[1] } return true @@ -213,19 +141,19 @@ func loadUsage(lang string) bool { // loadLocalNodes loads nodes information from local file system. func loadLocalNodes() bool { - if !utils.IsExist(appPath + "data/nodes.json") { - os.MkdirAll(appPath+"data/", os.ModePerm) + if !utils.IsExist(cmd.AppPath + "data/nodes.json") { + os.MkdirAll(cmd.AppPath+"data/", os.ModePerm) } else { - fr, err := os.Open(appPath + "data/nodes.json") + fr, err := os.Open(cmd.AppPath + "data/nodes.json") if err != nil { - utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] loadLocalNodes -> %s\n", promptMsg["LoadLocalData"]), err)) + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] loadLocalNodes -> %s\n", cmd.PromptMsg["LoadLocalData"]), err)) return false } defer fr.Close() - err = json.NewDecoder(fr).Decode(&localNodes) + err = json.NewDecoder(fr).Decode(&cmd.LocalNodes) if err != nil && err != io.EOF { - utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] loadLocalNodes -> %s\n", promptMsg["ParseJSON"]), err)) + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] loadLocalNodes -> %s\n", cmd.PromptMsg["ParseJSON"]), err)) return false } } @@ -235,25 +163,25 @@ func loadLocalNodes() bool { // loadLocalBundles loads bundles from local file system. func loadLocalBundles() bool { // Find all bundles. - dir, err := os.Open(appPath + "repo/bundles/") + dir, err := os.Open(cmd.AppPath + "repo/bundles/") if err != nil { - utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] loadLocalBundles -> %s\n", promptMsg["OpenFile"]), err)) + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] loadLocalBundles -> %s\n", cmd.PromptMsg["OpenFile"]), err)) return false } defer dir.Close() fis, err := dir.Readdir(0) if err != nil { - utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] loadLocalBundles -> %s\n", promptMsg["OpenFile"]), err)) + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] loadLocalBundles -> %s\n", cmd.PromptMsg["OpenFile"]), err)) return false } for _, fi := range fis { // In case this folder contains unexpected directories. if !fi.IsDir() && strings.HasSuffix(fi.Name(), ".json") { - fr, err := os.Open(appPath + "repo/bundles/" + fi.Name()) + fr, err := os.Open(cmd.AppPath + "repo/bundles/" + fi.Name()) if err != nil { - utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] loadLocalBundles -> %s\n", promptMsg["OpenFile"]), err)) + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] loadLocalBundles -> %s\n", cmd.PromptMsg["OpenFile"]), err)) return false } @@ -261,7 +189,7 @@ func loadLocalBundles() bool { err = json.NewDecoder(fr).Decode(bundle) fr.Close() if err != nil && err != io.EOF { - utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] loadLocalBundles -> %s\n", promptMsg["ParseJSON"]), err)) + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] loadLocalBundles -> %s\n", cmd.PromptMsg["ParseJSON"]), err)) return false } @@ -270,7 +198,7 @@ func loadLocalBundles() bool { bundle.Name = fi.Name()[:strings.Index(fi.Name(), ".")] } - localBundles = append(localBundles, bundle) + cmd.LocalBundles = append(cmd.LocalBundles, bundle) } } return true @@ -288,24 +216,24 @@ func initialize() bool { } // Load configuration. - if _, err := toml.DecodeFile(appPath+"conf/gopm.toml", &config); err != nil { + if _, err := toml.DecodeFile(cmd.AppPath+"conf/gopm.toml", &cmd.Config); err != nil { fmt.Printf("initialize -> Fail to load configuration[ %s ]\n", err) return false } // Set github.com access token. - doc.SetGithubCredentials(config.Account.Github_Access_Token) + doc.SetGithubCredentials(cmd.Config.Account.Github_Access_Token) // Load usages by language. - if !loadUsage(config.Lang) { + if !loadUsage(cmd.Config.Lang) { return false } // Create bundle and snapshot directories. - os.MkdirAll(appPath+"repo/bundles/", os.ModePerm) - os.MkdirAll(appPath+"repo/snapshots/", os.ModePerm) + os.MkdirAll(cmd.AppPath+"repo/bundles/", os.ModePerm) + os.MkdirAll(cmd.AppPath+"repo/snapshots/", os.ModePerm) // Create local tarball directories. - os.MkdirAll(appPath+"repo/tarballs/", os.ModePerm) + os.MkdirAll(cmd.AppPath+"repo/tarballs/", os.ModePerm) // Initialize local data. if !loadLocalNodes() || !loadLocalBundles() { @@ -344,7 +272,7 @@ func main() { } // Uknown commands. - fmt.Fprintf(os.Stderr, fmt.Sprintf("%s\n", promptMsg["UnknownCommand"]), args[0]) + fmt.Fprintf(os.Stderr, fmt.Sprintf("%s\n", cmd.PromptMsg["UnknownCommand"]), args[0]) setExitStatus(2) exit() } @@ -431,23 +359,3 @@ func exit() { } os.Exit(exitStatus) } - -// executeCommand executes commands in command line. -func executeCommand(cmd string, args []string) { - cmdExec := exec.Command(cmd, args...) - stdout, err := cmdExec.StdoutPipe() - if err != nil { - fmt.Println(err) - } - stderr, err := cmdExec.StderrPipe() - if err != nil { - fmt.Println(err) - } - err = cmdExec.Start() - if err != nil { - fmt.Println(err) - } - go io.Copy(os.Stdout, stdout) - go io.Copy(os.Stderr, stderr) - cmdExec.Wait() -}