diff --git a/check.go b/check.go index c8007bef4..a4fa71dee 100644 --- a/check.go +++ b/check.go @@ -7,7 +7,6 @@ package main import ( "fmt" "os" - "runtime" "strings" "github.com/GPMGo/gpm/doc" @@ -20,13 +19,17 @@ var cmdCheck = &Command{ func init() { cmdCheck.Run = runCheck + cmdCheck.Flags = map[string]bool{ + "-e": false, + } } // printCheckPrompt prints prompt information to users to // let them know what's going on. func printCheckPrompt(flag string) { switch flag { - + case "-e": + fmt.Printf(fmt.Sprintf("%s\n", promptMsg["CheckExDeps"])) } } @@ -42,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("%s\n", promptMsg["InvalidPath"])) + fmt.Printf(fmt.Sprintf("runCheck -> %s\n", promptMsg["InvalidPath"])) return } importPath := wd[len(gopath):] - imports, err := doc.CheckImports(wd+"/", importPath) + imports, err := checkImportsByRoot(wd+"/", importPath) if err != nil { - fmt.Printf(fmt.Sprintf("%s\n", promptMsg["CheckImports"]), err) + fmt.Printf(fmt.Sprintf("runCheck -> %s\n", promptMsg["CheckImports"]), err) return } @@ -57,6 +60,7 @@ func runCheck(cmd *Command, args []string) { return } + importsCache := make(map[string]bool) uninstallList := make([]string, 0) isInstalled := false // Check if dependencies have been installed. @@ -66,16 +70,18 @@ func runCheck(cmd *Command, args []string) { // Make sure it doesn't belong to same project. if utils.GetProjectPath(v) != utils.GetProjectPath(importPath) { for _, p := range paths { - if utils.IsExist(p + "/src/" + v + "/") { + if checkIsExistWithVCS(p + "/src/" + v + "/") { isInstalled = true break } } - if !isInstalled { + if !isInstalled && !importsCache[v] { + importsCache[v] = true uninstallList = append(uninstallList, v) } } + isInstalled = false } // Check if need to install packages. @@ -102,21 +108,13 @@ func runCheck(cmd *Command, args []string) { // Download packages. downloadPackages(nodes) + removePackageFiles("", uninstallList) + // 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 @@ -126,3 +124,60 @@ func runCheck(cmd *Command, args []string) { // Generate configure file. } } + +// checkImportsByRoot checks imports of packages from root path, +// and recursion checks all sub-directories. +func checkImportsByRoot(rootPath, importPath string) (imports []string, err error) { + // Check imports of root path. + importPkgs, err := doc.CheckImports(rootPath, importPath) + if err != nil { + return nil, err + } + imports = append(imports, importPkgs...) + + // Check sub-directories. + dirs, err := utils.GetDirsInfo(rootPath) + if err != nil { + return nil, err + } + + for _, d := range dirs { + if d.IsDir() && + !(!cmdCheck.Flags["-e"] && strings.Contains(d.Name(), "example")) { + importPkgs, err := checkImportsByRoot(rootPath+d.Name()+"/", importPath) + if err != nil { + return nil, err + } + imports = append(imports, importPkgs...) + } + } + + 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 { + fmt.Printf("checkIsExistWithVCS -> [ %s ]", err) + return false + } + + if len(dirs) != 1 { + return true + } + + switch dirs[0].Name() { + case ".git", ".hg", ".svn": + return false + } + + return true +} diff --git a/conf/gpm.toml b/conf/gpm.toml index 5555f5cc3..f6d1d8122 100644 --- a/conf/gpm.toml +++ b/conf/gpm.toml @@ -1,7 +1,7 @@ # This is a configuration file for gpm with toml format. title = "gpm(Go Package Manager)" -version = "v0.2.1 Build 0524" +version = "v0.2.2 Build 0524" user_language = "en-US" #user_language = "zh-CN" auto_backup = true @@ -13,4 +13,7 @@ github_access_token = "" [auto_enable] build = [] -install = [] \ No newline at end of file +install = [] +search = [] +remove = [] +check = [] \ No newline at end of file diff --git a/doc/google.go b/doc/google.go index f49e8a5a0..a0a19df07 100644 --- a/doc/google.go +++ b/doc/google.go @@ -152,13 +152,7 @@ func GetGoogleDoc(client *http.Client, match map[string]string, installGOPATH st // Check if need to check imports. if isCheckImport { - rootdir, err := os.Open(installPath + "/") - if err != nil { - return nil, err - } - defer rootdir.Close() - - dirs, err := rootdir.Readdir(0) + dirs, err := utils.GetDirsInfo(installPath + "/") if err != nil { return nil, err } diff --git a/doc/walker.go b/doc/walker.go index 4371a2fe2..e225bba81 100644 --- a/doc/walker.go +++ b/doc/walker.go @@ -124,6 +124,7 @@ func (w *walker) build(srcs []*source) ([]string, error) { files[name] = file } + w.ImportPath = strings.Replace(w.ImportPath, "\\", "/", -1) var imports []string for _, v := range bpkg.Imports { // Skip strandard library. diff --git a/i18n/en-US/prompt.txt b/i18n/en-US/prompt.txt index 22174b006..b3cdf7086 100644 --- a/i18n/en-US/prompt.txt +++ b/i18n/en-US/prompt.txt @@ -33,4 +33,5 @@ RemovePackage=Removing package: %s. NoKeyword=Cannot search without a keyword. ContinueRemove=Continue to remove?(Y/n). InvalidPath=Cannot find package in current path. -MissingImports=Following packages are missing: \ No newline at end of file +MissingImports=Following packages are missing: +CheckExDeps=You enabled check dependencies in example. \ No newline at end of file diff --git a/i18n/en-US/usage_check.txt b/i18n/en-US/usage_check.txt index 028dbdfe6..c6b45bb19 100644 --- a/i18n/en-US/usage_check.txt +++ b/i18n/en-US/usage_check.txt @@ -4,5 +4,7 @@ and generate configure file. The check flags are: + -e + check dependencies for examples. The list flags accept a space-separated list of strings. \ No newline at end of file diff --git a/i18n/zh-CN/prompt.txt b/i18n/zh-CN/prompt.txt index 3bc857c3c..d3ae329f4 100644 --- a/i18n/zh-CN/prompt.txt +++ b/i18n/zh-CN/prompt.txt @@ -33,4 +33,5 @@ RemovePackage=正在删除包: %s. NoKeyword=没有关键字,无法搜索. ContinueRemove=是否继续删除?(Y/n). InvalidPath=无法在当前目录中找到包. -MissingImports=下列依赖包未找到: \ No newline at end of file +MissingImports=下列依赖包未找到: +CheckExDeps=已激活示例代码依赖检查. \ No newline at end of file diff --git a/i18n/zh-CN/usage_check.txt b/i18n/zh-CN/usage_check.txt index 59b3f7c24..52e267b30 100644 --- a/i18n/zh-CN/usage_check.txt +++ b/i18n/zh-CN/usage_check.txt @@ -3,5 +3,7 @@ Check 命令用于检查并安装缺失的依赖包,并生成依赖配置文 下列参数可用于 check 命令: + -e + 检查示例代码的依赖包. 多个参数通过空格来间隔. diff --git a/install.go b/install.go index 60aa121e0..0a2a10259 100644 --- a/install.go +++ b/install.go @@ -12,7 +12,6 @@ import ( "os" "os/exec" "regexp" - "runtime" "strings" "github.com/GPMGo/gpm/doc" @@ -136,21 +135,18 @@ func runInstall(cmd *Command, args []string) { downloadPackages(nodes) if !cmdInstall.Flags["-d"] && cmdInstall.Flags["-p"] { + // Remove old files. + uninstallList := make([]string, 0, len(downloadCache)) + for k := range downloadCache { + uninstallList = append(uninstallList, k) + } + removePackageFiles("", uninstallList) + // 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 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 diff --git a/remove.go b/remove.go index 2a00a6558..9ae764196 100644 --- a/remove.go +++ b/remove.go @@ -142,18 +142,9 @@ func removePackage(node *doc.Node) (*doc.Node, []string) { } } - pkgPath := "/pkg/" + runtime.GOOS + "_" + runtime.GOARCH + "/" + node.ImportPath - // Remove file in GOPATH/pkg - if len(gopath) == 0 { - for _, v := range paths { - if utils.IsExist(v + pkgPath + "/") { - gopath = v - } - } - } + pkgList := []string{node.ImportPath} + removePackageFiles(gopath, pkgList) - os.RemoveAll(gopath + pkgPath + "/") - os.Remove(gopath + pkgPath + ".a") return node, nil } } @@ -162,3 +153,22 @@ func removePackage(node *doc.Node) (*doc.Node, []string) { fmt.Printf(fmt.Sprintf("%s\n", promptMsg["PackageNotFound"]), node.ImportPath) return nil, nil } + +// removePackageFiles removes package files in $GOPATH/pkg. +func removePackageFiles(gopath string, pkgList []string) { + var paths []string + // Check if need to find GOPATH. + if len(gopath) == 0 { + paths = utils.GetGOPATH() + } else { + paths = append(paths, gopath) + } + + pkgPath := "/pkg/" + runtime.GOOS + "_" + runtime.GOARCH + "/" + for _, p := range pkgList { + for _, g := range paths { + os.RemoveAll(g + pkgPath + p + "/") + os.Remove(g + pkgPath + p + ".a") + } + } +} diff --git a/utils/utils.go b/utils/utils.go index d7685b207..9e859b4b1 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -592,3 +592,19 @@ func IsDocFile(n string) bool { return readmePat.MatchString(n) || licensePat.MatchString(n) } + +// GetDirsInfo returns os.FileInfo of all sub-directories in root path. +func GetDirsInfo(rootPath string) ([]os.FileInfo, error) { + rootDir, err := os.Open(rootPath) + if err != nil { + return nil, err + } + defer rootDir.Close() + + dirs, err := rootDir.Readdir(0) + if err != nil { + return nil, err + } + + return dirs, err +}