From dbd5fd116efd87f7d5695504367148f255b562ef Mon Sep 17 00:00:00 2001 From: Unknown Date: Mon, 27 May 2013 03:11:51 -0700 Subject: [PATCH] add feature auto-generate package config file for command check --- README.md | 8 +++--- cmd/check.go | 67 +++++++++++++++++++------------------------ cmd/install.go | 20 +++++++++++-- cmd/remove.go | 8 ++++++ cmd/search.go | 2 +- cmd/struct.go | 5 ++++ conf/gopm.toml | 2 +- gopm.json | 16 +++++++++++ i18n/en-US/prompt.txt | 4 ++- i18n/zh-CN/prompt.txt | 4 ++- utils/utils.go | 41 ++++++++++++++++++++++++++ 11 files changed, 129 insertions(+), 48 deletions(-) create mode 100644 gopm.json diff --git a/README.md b/README.md index f348d06c0..9ec503acb 100644 --- a/README.md +++ b/README.md @@ -35,18 +35,18 @@ This application still in experiment, any change could happen, but it doesn't af ### v0.3.* -- Command `install` add flag `-u` for force update pakcages, and need to check if has downloaded same package with same version already. -- Command `install` and `remove` give number to let user choose operate one package. -- Command `check` add feature to update or generate gopack.json. +- Command `check` add feature to update gopm.json. - Command `install` generates dependencies configuration file. - Command `install` save tarball add support for packages in code.google.com, bitbucket.org, launchpad.net, git.oschina.net, gitcafe.com, *.codeplex.com. -- Command `build` use dependencies configuration file to build with specific versions of dependencies, if VCS tools are available, simply use `checkout`. +- Command `build` use dependencies configuration file to build with specific versions of dependencies. - Command `clean` is for cleaning empty directories and backup. - Add gpm working principle design. - Complete documentation. ### Future +- Command `install` and `remove` give number to let user choose operate one package when using snapshot. +- Figure out how to use tool chian directly in order to compile only with `.a` files. - Command `search` compares version. - Command `home` and `doc`. - Command `remove` add flag `-d` for removing dependencies at the same time. diff --git a/cmd/check.go b/cmd/check.go index c82ef0818..cd6405e52 100644 --- a/cmd/check.go +++ b/cmd/check.go @@ -5,6 +5,7 @@ package cmd import ( + "encoding/json" "fmt" "os" "strings" @@ -61,25 +62,28 @@ func runCheck(cmd *Command, args []string) { return } + pkgConf := new(gopmConfig) importsCache := make(map[string]bool) uninstallList := make([]string, 0) isInstalled := false // Check if dependencies have been installed. - paths := utils.GetGOPATH() for _, v := range imports { // Make sure it doesn't belong to same project. if utils.GetProjectPath(v) != utils.GetProjectPath(importPath) { - for _, p := range paths { - if checkIsExistWithVCS(p + "/src/" + v + "/") { + if !importsCache[v] { + importsCache[v] = true + pkgConf.Deps = append(pkgConf.Deps, &node.Node{ + ImportPath: v, + }) + + if _, ok := utils.CheckIsExistInGOPATH(importPath); ok { isInstalled = true - break } - } - if !isInstalled && !importsCache[v] { - importsCache[v] = true - uninstallList = append(uninstallList, v) + if !isInstalled { + uninstallList = append(uninstallList, v) + } } } isInstalled = false @@ -121,8 +125,24 @@ func runCheck(cmd *Command, args []string) { cmdArgs[1] = k executeCommand("go", cmdArgs) } + } + + // Generate configure file. + if !utils.IsExist("gopm.json") { + fw, err := os.Create("gopm.json") + if err != nil { + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] runCheck -> %s\n", PromptMsg["OpenFile"]), err)) + return + } + defer fw.Close() - // Generate configure file. + fbytes, err := json.MarshalIndent(&pkgConf, "", "\t") + if err != nil { + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] runCheck -> %s\n", PromptMsg["ParseJSON"]), err)) + return + } + fw.Write(fbytes) + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("$ %s\n", PromptMsg["GenerateConfig"]), importPath)) } } @@ -155,32 +175,3 @@ func checkImportsByRoot(rootPath, importPath string) (imports []string, err erro return imports, err } - -// checkIsExistWithVCS returns false if directory only has VCS folder, -// or doesn't exist. -func checkIsExistWithVCS(path string) bool { - // Check if directory exist. - if !utils.IsExist(path) { - return false - } - - // Check if only has VCS folder. - dirs, err := utils.GetDirsInfo(path) - if err != nil { - utils.ColorPrint(fmt.Sprintf("[ERROR] checkIsExistWithVCS -> [ %s ]", err)) - return false - } - - if len(dirs) > 1 { - return true - } else if len(dirs) == 0 { - return false - } - - switch dirs[0].Name() { - case ".git", ".hg", ".svn": - return false - } - - return true -} diff --git a/cmd/install.go b/cmd/install.go index fec538be6..939f20aff 100644 --- a/cmd/install.go +++ b/cmd/install.go @@ -12,6 +12,7 @@ import ( "os" "os/exec" "regexp" + "strconv" "strings" "github.com/GPMGo/gopm/doc" @@ -131,12 +132,19 @@ func runInstall(cmd *Command, args []string) { if len(nodes) > 0 { // Check with users if continue. utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("%s\n", PromptMsg["BundleInfo"]), bundle)) - for _, n := range nodes { - fmt.Printf("[%s] -> %s: %s.\n", n.ImportPath, n.Type, n.Value) + for i, n := range nodes { + fmt.Printf("%d.[%s] -> %s: %s.\n", i+1, n.ImportPath, n.Type, n.Value) } fmt.Printf(fmt.Sprintf("%s\n", PromptMsg["ContinueDownload"])) var option string fmt.Fscan(os.Stdin, &option) + // Chekc if it is a index. + num, err := strconv.Atoi(option) + if err == nil && num > 0 && num <= len(nodes) { + nodes = nodes[num-1 : num] + break + } + if strings.ToLower(option) != "y" { os.Exit(0) return @@ -229,6 +237,14 @@ func downloadPackages(nodes []*node.Node) { for _, n := range nodes { // Check if it is a valid remote path. if utils.IsValidRemotePath(n.ImportPath) { + if !CmdInstall.Flags["-u"] { + // Check if package has been downloaded. + if _, ok := utils.CheckIsExistInGOPATH(n.ImportPath); ok { + fmt.Printf(fmt.Sprintf("%s\n", PromptMsg["SkipInstalled"]), n.ImportPath) + continue + } + } + if !downloadCache[n.ImportPath] { // Download package. nod, imports := downloadPackage(n) diff --git a/cmd/remove.go b/cmd/remove.go index 82567dda5..fe06d4392 100644 --- a/cmd/remove.go +++ b/cmd/remove.go @@ -9,6 +9,7 @@ import ( "fmt" "os" "runtime" + "strconv" "strings" "github.com/GPMGo/gopm/utils" @@ -51,6 +52,13 @@ func runRemove(cmd *Command, args []string) { fmt.Printf(fmt.Sprintf("%s\n", PromptMsg["ContinueRemove"])) var option string fmt.Fscan(os.Stdin, &option) + // Chekc if it is a index. + num, err := strconv.Atoi(option) + if err == nil && num > 0 && num <= len(nodes) { + nodes = nodes[num-1 : num] + break + } + if strings.ToLower(option) != "y" { os.Exit(0) return diff --git a/cmd/search.go b/cmd/search.go index d8db58ff3..8b840e557 100644 --- a/cmd/search.go +++ b/cmd/search.go @@ -84,7 +84,7 @@ func runSearch(cmd *Command, args []string) { buf.WriteString("-> " + k) // Check if has been installed. for _, path := range paths { - if checkIsExistWithVCS(path + "/src/" + k + "/") { + if utils.CheckIsExistWithVCS(path + "/src/" + k + "/") { installStr := " [Installed]" if !isWindws { installStr = strings.Replace(installStr, "[", diff --git a/cmd/struct.go b/cmd/struct.go index c1cbc8326..909639aaa 100644 --- a/cmd/struct.go +++ b/cmd/struct.go @@ -25,6 +25,11 @@ var ( LocalBundles []*doc.Bundle ) +// gopmConfig represents the package config file in correspoding directory. +type gopmConfig struct { + Deps []*node.Node +} + type tomlConfig struct { Title, Version string Lang string `toml:"user_language"` diff --git a/conf/gopm.toml b/conf/gopm.toml index 5fea79884..e2b5e27fc 100644 --- a/conf/gopm.toml +++ b/conf/gopm.toml @@ -1,7 +1,7 @@ # This is a configuration file for gpm with toml format. title = "gpm(Go Package Manager)" -version = "v0.2.4 Build 0525" +version = "v0.2.6 Build 0527" user_language = "en-US" #user_language = "zh-CN" auto_backup = true diff --git a/gopm.json b/gopm.json new file mode 100644 index 000000000..d9592c63d --- /dev/null +++ b/gopm.json @@ -0,0 +1,16 @@ +{ + "Deps": [ + { + "import_path": "github.com/BurntSushi/toml", + "type": "", + "value": "", + "deps": null + }, + { + "import_path": "github.com/GPMGo/node", + "type": "", + "value": "", + "deps": null + } + ] +} \ No newline at end of file diff --git a/i18n/en-US/prompt.txt b/i18n/en-US/prompt.txt index 74ea739ed..5543be5bf 100644 --- a/i18n/en-US/prompt.txt +++ b/i18n/en-US/prompt.txt @@ -21,7 +21,8 @@ NoPackage=Please list at least one package/bundle/snapshot. DownloadPath=Packages will be downloaded to GOPATH(%s). InstallStatus=Installing package: %s. BundleInfo=Bundle(%s) contains following nodes: -ContinueDownload=Continue to download?(Y/n). +ContinueDownload=Continue to download?(Y/n or index). +SkipInstalled=Skipped installed pakcage: %s. SkipDownloaded=Skipped downloaded package: %s. SkipInvalidPath=Skipped invalid import path: %s. DownloadStatus=Downloading package: %s. @@ -30,5 +31,6 @@ NoKeyword=Cannot search without a keyword. ContinueRemove=Continue to remove?(Y/n). InvalidPath=Cannot find package in current path. MissingImports=Following packages are missing: +GenerateConfig=Auto-generated configuration file for package: %s. CheckExDeps=You enabled check dependencies in example. SearchResult=search results \ No newline at end of file diff --git a/i18n/zh-CN/prompt.txt b/i18n/zh-CN/prompt.txt index 445e19e69..f4b88adb3 100644 --- a/i18n/zh-CN/prompt.txt +++ b/i18n/zh-CN/prompt.txt @@ -21,7 +21,8 @@ NoPackage=请列出至少一个包、集合或快照. DownloadPath=所有包将会被下载至 GOPATH(%s). InstallStatus=正在安装包: %s. BundleInfo=集合 (%s) 包含以下结点: -ContinueDownload=是否继续下载?(Y/n). +ContinueDownload=是否继续下载?(Y/n 或索引). +SkipInstalled=忽略已安装包: %s. SkipDownloaded=忽略已下载包: %s. SkipInvalidPath=忽略无效的导入路径: %s. DownloadStatus=正在下载包: %s. @@ -30,5 +31,6 @@ NoKeyword=没有关键字,无法搜索. ContinueRemove=是否继续删除?(Y/n). InvalidPath=无法在当前目录中找到包. MissingImports=下列依赖包未找到: +GenerateConfig=已自动生成包配置文件: %s. CheckExDeps=已激活示例代码依赖检查. SearchResult=搜索结果 \ No newline at end of file diff --git a/utils/utils.go b/utils/utils.go index 362919d6b..2627a7de3 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -46,6 +46,47 @@ func IsExist(path string) bool { return err == nil || os.IsExist(err) } +// CheckIsExistWithVCS returns false if directory only has VCS folder, +// or doesn't exist. +func CheckIsExistWithVCS(path string) bool { + // Check if directory exist. + if !IsExist(path) { + return false + } + + // Check if only has VCS folder. + dirs, err := GetDirsInfo(path) + if err != nil { + ColorPrint(fmt.Sprintf("[ERROR] CheckIsExistWithVCS -> [ %s ]", err)) + return false + } + + if len(dirs) > 1 { + return true + } else if len(dirs) == 0 { + return false + } + + switch dirs[0].Name() { + case ".git", ".hg", ".svn": + return false + } + + return true +} + +// CheckIsExistInGOPATH checks if given package import path exists in any path in GOPATH/src, +// and returns corresponding GOPATH. +func CheckIsExistInGOPATH(importPath string) (string, bool) { + paths := GetGOPATH() + for _, p := range paths { + if CheckIsExistWithVCS(p + "/src/" + importPath + "/") { + return p, true + } + } + return "", false +} + // GetGOPATH returns all paths in GOPATH variable. func GetGOPATH() []string { gopath := os.Getenv("GOPATH")