Browse Source

clean code

pull/103/head
Unknown 12 years ago
parent
commit
37954226bc
  1. 1
      README.md
  2. 20
      cmd/build.go
  3. 28
      cmd/check.go
  4. 78
      cmd/install.go
  5. 30
      cmd/remove.go
  6. 43
      cmd/search.go
  7. 108
      cmd/struct.go
  8. 182
      gopm.go

1
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.

20
build.go → 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("<SUCCESS>$ %s\n", promptMsg["MovedFile"]), v, wd))
utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("<SUCCESS>$ %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
}
}

28
check.go → 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, "<blank>")
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

78
install.go → 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] <packages|bundles|snapshots>",
}
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, "<blank>")
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"]))
}

30
remove.go → 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] <packages|bundles|snapshots>",
}
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
}

43
search.go → 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] <keyword>",
}
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)
}

108
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 <this-command>' 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()
}

182
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 <this-command>' 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()
}

Loading…
Cancel
Save