From acf85479726bcb6421cad768cbf237dbeed01174 Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 23 May 2013 21:12:29 -0400 Subject: [PATCH] add command check for checking dependencies. --- README.md | 17 +++-- check.go | 128 ++++++++++++++++++++++++++++++++++ conf/gpm.toml | 1 + doc/bitbucket.go | 2 +- doc/github.go | 14 +++- doc/google.go | 2 +- doc/launchpad.go | 2 +- doc/vcs.go | 14 +++- gpm.go | 8 ++- i18n/en-US/prompt.txt | 5 +- i18n/en-US/usage_check.txt | 9 +++ i18n/zh-CN/prompt.txt | 5 +- i18n/zh-CN/usage_check.txt | 9 +++ install.go | 17 +++-- repo/bundles/test_bundle.json | 4 +- utils/utils.go | 2 +- 16 files changed, 219 insertions(+), 20 deletions(-) create mode 100644 check.go create mode 100644 i18n/en-US/usage_check.txt create mode 100644 i18n/zh-CN/usage_check.txt diff --git a/README.md b/README.md index 3f7d408c1..f7ef845e2 100644 --- a/README.md +++ b/README.md @@ -32,18 +32,21 @@ This application still in experiment, any change could happen, but it doesn't af ### v0.2.* -- Command `check` is for checking and downloading all missing dependencies. - i18n support for Chinese. - Add template projects for testing commands. - Add feature auto-catch if run under GOPATH/bin. ### Future +- Command `check` add feature to update or generate gopack.json. +- Command `install` generates dependencies configuration file. +- Command `build` use dependencies configuration file to build with specific versions of dependencies, if VCS tools are available, simply use `checkout`. +- Command `install` and `remove` give number to let user choose operate one package. - Command `search` add flags `-n` and `-o` for number of list items and offset. - Command `update` is for checking updates. - Command `sync` is for sync packages in two computers, support client and server mode through ssh. - Command `init` is for auto-configuring Go develop environment. -- Command `install` and `remove` and `update` backup data(up to 100 records) before executing. +- Command `install` and `remove` and `update` backup data(up to 50 records) before executing. - Command `rollback` is for rolling back to certain operation. - Add feature "struct generator". - Command `remove` add flag `-d` for removing dependencies at the same time. @@ -57,14 +60,20 @@ This application still in experiment, any change could happen, but it doesn't af - Add support for downloading tarballs from user sources. - After downloaded all packages in bundles or snapshots, need to check if all dependencies have been downloaded as well. - Download package from code.google.com only support hg as version control system, probably support git and svn. -- Command `install` add support for downloading code from git.oschina.net, gitcafe.com, *.codeplex.com; +- Command `install` add support for downloading code from git.oschina.net, gitcafe.com, *.codeplex.com. - Command `install` add support for downloading by tag and branch for packages in git.oschina.net, gitcafe.com. - Command `install` and `remove` add bundle parse code for getting data from server. - Command `install` and `remove` add snapshot parse code for downloading or removing snapshot. - Add built-in application version in order to backup data when users update. - Add gpm working principle design. - Command `install -c` add arguments for add more exts. +- Command `install` save tarball add support for packages in code.google.com, bitbucket.org, launchpad.net, git.oschina.net, gitcafe.com, *.codeplex.com. + +## Credits + +- Source files that contain code that is from [gopkgdoc](https://github.com/garyburd/gopkgdoc) is honored in specific. +- Idea that support packages build revision is inspired by [gopack](https://github.com/d2fn/gopack). ## License -[MIT-STYLE](LICENSE), source files that contain code that is from [gopkgdoc](https://github.com/garyburd/gopkgdoc) is honored in specific. +[MIT-STYLE](LICENSE). diff --git a/check.go b/check.go new file mode 100644 index 000000000..3e7b44210 --- /dev/null +++ b/check.go @@ -0,0 +1,128 @@ +// Copyright (c) 2013 GPMGo Members. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package main + +import ( + "fmt" + "os" + "runtime" + "strings" + + "github.com/GPMGo/gpm/doc" + "github.com/GPMGo/gpm/utils" +) + +var cmdCheck = &Command{ + UsageLine: "check [check flags] [packages]", +} + +func init() { + cmdCheck.Run = runCheck +} + +// printCheckPrompt prints prompt information to users to +// let them know what's going on. +func printCheckPrompt(flag string) { + switch flag { + + } +} + +func runCheck(cmd *Command, args []string) { + // Check flags. + num := checkFlags(cmd.Flags, config.AutoEnable.Check, args, printCheckPrompt) + if num == -1 { + return + } + args = args[num:] + + wd, _ := os.Getwd() + // Guess import path. + gopath := utils.GetBestMatchGOPATH(wd) + "/src/" + if len(wd) <= len(gopath) { + fmt.Printf(fmt.Sprintf("%s\n", promptMsg["InvalidPath"])) + return + } + + importPath := wd[len(gopath):] + imports, err := doc.CheckImports(wd+"/", importPath) + if err != nil { + fmt.Printf(fmt.Sprintf("%s\n", promptMsg["CheckImports"]), err) + return + } + + if len(imports) == 0 { + return + } + + 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 !strings.HasPrefix(v, importPath) { + for _, p := range paths { + if utils.IsExist(p + "/src/" + v + "/") { + isInstalled = true + break + } + } + + if !isInstalled { + uninstallList = append(uninstallList, v) + } + } + } + + // Check if need to install packages. + if len(uninstallList) > 0 { + 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"])) + var option string + fmt.Fscan(os.Stdin, &option) + if strings.ToLower(option) != "y" { + os.Exit(0) + } + + installGOPATH = utils.GetBestMatchGOPATH(appPath) + fmt.Printf(fmt.Sprintf("%s\n", promptMsg["DownloadPath"]), installGOPATH) + // Generate temporary nodes. + nodes := make([]*doc.Node, len(uninstallList)) + for i := range nodes { + nodes[i] = new(doc.Node) + nodes[i].ImportPath = uninstallList[i] + } + // Download packages. + downloadPackages(nodes) + + // Install packages all together. + var cmdArgs []string + cmdArgs = append(cmdArgs, "install") + cmdArgs = append(cmdArgs, "") + + paths := utils.GetGOPATH() + pkgPath := "/pkg/" + runtime.GOOS + "_" + runtime.GOARCH + "/" + for _, k := range uninstallList { + // Delete old packages. + for _, p := range paths { + os.RemoveAll(p + pkgPath + k + "/") + os.Remove(p + pkgPath + k + ".a") + } + } + + for _, k := range uninstallList { + fmt.Printf(fmt.Sprintf("%s\n", promptMsg["InstallStatus"]), k) + cmdArgs[1] = k + executeCommand("go", cmdArgs) + } + + // Generate configure file. + } +} diff --git a/conf/gpm.toml b/conf/gpm.toml index 8c1335071..49fd7a16e 100644 --- a/conf/gpm.toml +++ b/conf/gpm.toml @@ -4,6 +4,7 @@ title = "gpm(Go Package Manager)" version = "v0.1.9 Build 0523" user_language = "en-US" #user_language = "zh-CN" +auto_backup = true [account] username = "" diff --git a/doc/bitbucket.go b/doc/bitbucket.go index ce3d21e0f..68887176e 100644 --- a/doc/bitbucket.go +++ b/doc/bitbucket.go @@ -168,7 +168,7 @@ func GetBitbucketDoc(client *http.Client, match map[string]string, installGOPATH // Check if need to check imports. if isCheckImport { for _, d := range dirs { - importPkgs, err := checkImports(d+"/", match["importPath"]) + importPkgs, err := CheckImports(d+"/", match["importPath"]) if err != nil { return nil, err } diff --git a/doc/github.go b/doc/github.go index 781ba3485..d33e00592 100644 --- a/doc/github.go +++ b/doc/github.go @@ -166,7 +166,7 @@ func GetGithubDoc(client *http.Client, match map[string]string, installGOPATH st // Check if need to check imports. if isCheckImport { for _, d := range dirs { - importPkgs, err := checkImports(d, match["importPath"]) + importPkgs, err := CheckImports(d, match["importPath"]) if err != nil { return nil, err } @@ -174,5 +174,17 @@ func GetGithubDoc(client *http.Client, match map[string]string, installGOPATH st } } + /*fpath := appPath + "repo/tarballs/" + node.ImportPath + "-" + node.Value + ".zip" + // Save tarball. + if autoBackup && !utils.IsExist(fpath) { + os.MkdirAll(path.Dir(fpath)+"/", os.ModePerm) + f, err := os.Create(fpath) + if err != nil { + return nil, err + } + defer f.Close() + _, err = f.Write(p) + }*/ + return imports, err } diff --git a/doc/google.go b/doc/google.go index 478da887b..b87aca9e4 100644 --- a/doc/google.go +++ b/doc/google.go @@ -164,7 +164,7 @@ func GetGoogleDoc(client *http.Client, match map[string]string, installGOPATH st for _, d := range dirs { if d.IsDir() && !(!cmdFlags["-e"] && strings.Contains(d.Name(), "example")) { absPath := installPath + "/" + d.Name() + "/" - importPkgs, err := checkImports(absPath, match["importPath"]) + importPkgs, err := CheckImports(absPath, match["importPath"]) if err != nil { return nil, err } diff --git a/doc/launchpad.go b/doc/launchpad.go index bfff56019..d614b2bb5 100644 --- a/doc/launchpad.go +++ b/doc/launchpad.go @@ -130,7 +130,7 @@ func GetLaunchpadDoc(client *http.Client, match map[string]string, installGOPATH // Check if need to check imports. if isCheckImport { for _, d := range dirs { - importPkgs, err := checkImports(d+"/", match["importPath"]) + importPkgs, err := CheckImports(d+"/", match["importPath"]) if err != nil { return nil, err } diff --git a/doc/vcs.go b/doc/vcs.go index 452322935..8a1628249 100644 --- a/doc/vcs.go +++ b/doc/vcs.go @@ -18,6 +18,16 @@ import ( "strings" ) +var ( + appPath string + autoBackup bool +) + +func SetAppConfig(path string, backup bool) { + appPath = path + autoBackup = backup +} + // TODO: specify with command line flag const repoRoot = "/tmp/gddo" @@ -178,7 +188,7 @@ func expand(template string, match map[string]string, subs ...string) string { } // checkImports checks package denpendencies. -func checkImports(absPath, importPath string) (importPkgs []string, err error) { +func CheckImports(absPath, importPath string) (importPkgs []string, err error) { dir, err := os.Open(absPath) if err != nil { return nil, err @@ -203,7 +213,7 @@ func checkImports(absPath, importPath string) (importPkgs []string, err error) { fbytes := make([]byte, fi.Size()) _, err = f.Read(fbytes) f.Close() - //fmt.Println(d+fi.Name(), fi.Size(), n) + if err != nil { return nil, err } diff --git a/gpm.go b/gpm.go index 0eb017d69..1bf546b2f 100644 --- a/gpm.go +++ b/gpm.go @@ -41,12 +41,13 @@ 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 []string + Build, Install, Search, Check []string } type account struct { @@ -104,6 +105,7 @@ var commands = []*Command{ cmdSearch, cmdInstall, cmdRemove, + cmdCheck, } // getAppPath returns application execute path for current process. @@ -119,6 +121,8 @@ func getAppPath() bool { // Replace all '\' to '/'. appPath = strings.Replace(filepath.Dir(appPath), "\\", "/", -1) + "/" } + + doc.SetAppConfig(appPath, config.AutoBackup) return true } @@ -287,6 +291,8 @@ func initialize() bool { // Create bundle and snapshot directories. os.MkdirAll(appPath+"repo/bundles/", os.ModePerm) os.MkdirAll(appPath+"repo/snapshots/", os.ModePerm) + // Create local tarball directories. + os.MkdirAll(appPath+"repo/tarballs/", os.ModePerm) // Initialize local data. if !loadLocalNodes() || !loadLocalBundles() { diff --git a/i18n/en-US/prompt.txt b/i18n/en-US/prompt.txt index 8c3d44954..22174b006 100644 --- a/i18n/en-US/prompt.txt +++ b/i18n/en-US/prompt.txt @@ -11,6 +11,7 @@ DownloadError=Fail to download package(%s)[ %s ] NotFoundError=Import path prefix matches known service, but regexp does not. ErrNoMatch=Unsupported project hosting. PackageNotFound=Cannot find package: %s. +CheckImports=Fail to check dependencies[ %s ] MovedFile=SUCCESS: Moved file from $GOPATH(%s) to current directory(%s). PureDownload=You enabled pure download. @@ -30,4 +31,6 @@ NoVCSTool=No version control tool is available, pure download enabled! DownloadStatus=Downloading package: %s. RemovePackage=Removing package: %s. NoKeyword=Cannot search without a keyword. -ContinueRemove=Continue to remove?(Y/n). \ No newline at end of file +ContinueRemove=Continue to remove?(Y/n). +InvalidPath=Cannot find package in current path. +MissingImports=Following packages are missing: \ No newline at end of file diff --git a/i18n/en-US/usage_check.txt b/i18n/en-US/usage_check.txt new file mode 100644 index 000000000..a49b5d38a --- /dev/null +++ b/i18n/en-US/usage_check.txt @@ -0,0 +1,9 @@ +check packages dependencies||| +Check checks packages dependencies if have been installed +and generate configure file. + +The check flags are: + + +The list flags accept a space-separated list of strings. To embed spaces +in an element in the list, surround it with either single or double quotes. diff --git a/i18n/zh-CN/prompt.txt b/i18n/zh-CN/prompt.txt index 007be2a05..3bc857c3c 100644 --- a/i18n/zh-CN/prompt.txt +++ b/i18n/zh-CN/prompt.txt @@ -11,6 +11,7 @@ DownloadError=下载包 (%s) 失败 [ %s ] NotFoundError=合法的源代码托管平台,但正则匹配失败. ErrNoMatch=不被支持的源代码托管平台. PackageNotFound=无法找到包: %s. +CheckImports=一百遍检查失败 [ %s ] MovedFile=SUCCESS: 成功将文件从 $GOPATH(%s) 移动至当前目录 (%s). PureDownload=已激活纯净下载模式. @@ -30,4 +31,6 @@ NoVCSTool=未找到合适的版本控制工具,已激活纯净下载模式! DownloadStatus=正在下载包: %s. RemovePackage=正在删除包: %s. NoKeyword=没有关键字,无法搜索. -ContinueRemove=是否继续删除?(Y/n). \ No newline at end of file +ContinueRemove=是否继续删除?(Y/n). +InvalidPath=无法在当前目录中找到包. +MissingImports=下列依赖包未找到: \ No newline at end of file diff --git a/i18n/zh-CN/usage_check.txt b/i18n/zh-CN/usage_check.txt new file mode 100644 index 000000000..a49b5d38a --- /dev/null +++ b/i18n/zh-CN/usage_check.txt @@ -0,0 +1,9 @@ +check packages dependencies||| +Check checks packages dependencies if have been installed +and generate configure file. + +The check flags are: + + +The list flags accept a space-separated list of strings. To embed spaces +in an element in the list, surround it with either single or double quotes. diff --git a/install.go b/install.go index 92ac1db65..8f4d677ec 100644 --- a/install.go +++ b/install.go @@ -12,6 +12,7 @@ import ( "os" "os/exec" "regexp" + "runtime" "strings" "github.com/GPMGo/gpm/doc" @@ -140,6 +141,16 @@ func runInstall(cmd *Command, args []string) { cmdArgs = append(cmdArgs, "install") cmdArgs = append(cmdArgs, "") + paths := utils.GetGOPATH() + pkgPath := "/pkg/" + runtime.GOOS + "_" + runtime.GOARCH + "/" + for k := range downloadCache { + // Delete old packages. + for _, p := range paths { + os.RemoveAll(p + pkgPath + k + "/") + os.Remove(p + pkgPath + k + ".a") + } + } + for k := range downloadCache { fmt.Printf(fmt.Sprintf("%s\n", promptMsg["InstallStatus"]), k) cmdArgs[1] = k @@ -160,8 +171,6 @@ func runInstall(cmd *Command, args []string) { } fw.Write(fbytes) } - - fmt.Println("Well done.") } // chekcDeps checks dependencies of nodes. @@ -336,7 +345,7 @@ func pureDownload(node *doc.Node) ([]string, error) { if m == nil { if s.prefix != "" { return nil, - doc.NotFoundError{fmt.Sprintf("%s\n", promptMsg["NotFoundError"])} + doc.NotFoundError{fmt.Sprintf("%s", promptMsg["NotFoundError"])} } continue } @@ -348,5 +357,5 @@ func pureDownload(node *doc.Node) ([]string, error) { } return s.get(doc.HttpClient, match, installGOPATH, node, cmdInstall.Flags) } - return nil, errors.New(fmt.Sprintf("%s\n", promptMsg["NotFoundError"])) + return nil, errors.New(fmt.Sprintf("%s", promptMsg["NotFoundError"])) } diff --git a/repo/bundles/test_bundle.json b/repo/bundles/test_bundle.json index ffba780d3..e8bbceb01 100644 --- a/repo/bundles/test_bundle.json +++ b/repo/bundles/test_bundle.json @@ -38,8 +38,8 @@ }, { "import_path": "github.com/coocood/qbs", - "type": "branch", - "value": "master", + "type": "commit", + "value": "afbf6b7370d76dc479f8d3f9ce9e802ce2c34cf2", "deps": null }, { diff --git a/utils/utils.go b/utils/utils.go index dcdb7ca6a..d7685b207 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -387,7 +387,7 @@ func GetBestMatchGOPATH(appPath string) string { paths := GetGOPATH() for _, p := range paths { if strings.HasPrefix(p, appPath) { - return p + return strings.Replace(p, "\\", "/", -1) } } return paths[0]