From 3d5805b1b599b2609a18ef3befe0fbd976be02bf Mon Sep 17 00:00:00 2001 From: Unknown Date: Sat, 25 May 2013 13:58:48 -0400 Subject: [PATCH] add search result color highlight --- README.md | 2 +- conf/gopm.toml | 2 +- doc/http.go | 2 +- gopm.go | 24 +++--- search.go | 18 ++++- utils/utils.go | 209 ++++++++++++++++++++++++++++--------------------- 6 files changed, 149 insertions(+), 108 deletions(-) diff --git a/README.md b/README.md index c2c0b3cdf..4feef5d2d 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ This application still in experiment, any change could happen, but it doesn't af ### v0.3.* -- Command `search` result add keyword highlight. +- Command `search` add flag `-a` to show results of sub-packages, not just search by project name. - 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 `check` add feature to update or generate gopack.json. diff --git a/conf/gopm.toml b/conf/gopm.toml index f6d1d8122..5eb1bbde8 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.2 Build 0524" +version = "v0.2.3 Build 0525" user_language = "en-US" #user_language = "zh-CN" auto_backup = true diff --git a/doc/http.go b/doc/http.go index f0506ac12..34e6b3e3f 100644 --- a/doc/http.go +++ b/doc/http.go @@ -18,7 +18,7 @@ import ( var userAgent = "go application" var ( - dialTimeout = flag.Duration("dial_timeout", 30*time.Second, "Timeout for dialing an HTTP connection.") + dialTimeout = flag.Duration("dial_timeout", 10*time.Second, "Timeout for dialing an HTTP connection.") readTimeout = flag.Duration("read_timeout", 10*time.Second, "Timeoout for reading an HTTP response.") writeTimeout = flag.Duration("write_timeout", 5*time.Second, "Timeout writing an HTTP request.") ) diff --git a/gopm.go b/gopm.go index 13ee6e052..75cf5faa4 100644 --- a/gopm.go +++ b/gopm.go @@ -125,7 +125,7 @@ func getAppPath() bool { } if len(appPath) == 0 { - fmt.Printf("ERROR: getAppPath -> Unable to indicate current execute path.\n") + utils.ColorPrint("[ERROR] getAppPath ->[ Unable to indicate current execute path. ]\n") return false } @@ -146,7 +146,7 @@ func loadPromptMsg(lang string) bool { // Load prompt messages. f, err := os.Open(appPath + "i18n/" + lang + "/prompt.txt") if err != nil { - fmt.Printf("ERROR: loadUsage -> Fail to load prompt messages[ %s ]\n", err) + utils.ColorPrint(fmt.Sprintf("[ERROR] loadUsage -> Fail to load prompt messages[ %s ]\n", err)) return false } defer f.Close() @@ -174,7 +174,7 @@ func loadUsage(lang string) bool { // Load main usage. f, err := os.Open(appPath + "i18n/" + lang + "/usage.tpl") if err != nil { - fmt.Printf(fmt.Sprintf("ERROR: loadUsage -> %s\n", promptMsg["LoadCommandUsage"]), "main", err) + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] loadUsage -> %s\n", promptMsg["LoadCommandUsage"]), "main", err)) return false } defer f.Close() @@ -189,7 +189,7 @@ func loadUsage(lang string) bool { for _, cmd := range commands { f, err := os.Open(appPath + "i18n/" + lang + "/usage_" + cmd.Name() + ".txt") if err != nil { - fmt.Printf(fmt.Sprintf("ERROR: loadUsage -> %s\n", promptMsg["LoadCommandUsage"]), cmd.Name(), err) + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] loadUsage -> %s\n", promptMsg["LoadCommandUsage"]), cmd.Name(), err)) return false } defer f.Close() @@ -200,8 +200,8 @@ func loadUsage(lang string) bool { f.Read(usageBytes) usages := strings.Split(string(usageBytes), "|||") if len(usages) < 2 { - fmt.Printf( - fmt.Sprintf("ERROR: loadUsage -> %s\n", promptMsg["ReadCoammndUsage"]), cmd.Name()) + utils.ColorPrint(fmt.Sprintf( + fmt.Sprintf("[ERROR] loadUsage -> %s\n", promptMsg["ReadCoammndUsage"]), cmd.Name())) return false } cmd.Short = usages[0] @@ -218,14 +218,14 @@ func loadLocalNodes() bool { } else { fr, err := os.Open(appPath + "data/nodes.json") if err != nil { - fmt.Printf(fmt.Sprintf("ERROR: loadLocalNodes -> %s\n", promptMsg["LoadLocalData"]), err) + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] loadLocalNodes -> %s\n", promptMsg["LoadLocalData"]), err)) return false } defer fr.Close() err = json.NewDecoder(fr).Decode(&localNodes) if err != nil && err != io.EOF { - fmt.Printf(fmt.Sprintf("ERROR: loadLocalNodes -> %s\n", promptMsg["ParseJSON"]), err) + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] loadLocalNodes -> %s\n", promptMsg["ParseJSON"]), err)) return false } } @@ -237,14 +237,14 @@ func loadLocalBundles() bool { // Find all bundles. dir, err := os.Open(appPath + "repo/bundles/") if err != nil { - fmt.Printf(fmt.Sprintf("ERROR: loadLocalBundles -> %s\n", promptMsg["OpenFile"]), err) + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] loadLocalBundles -> %s\n", promptMsg["OpenFile"]), err)) return false } defer dir.Close() fis, err := dir.Readdir(0) if err != nil { - fmt.Printf(fmt.Sprintf("ERROR: loadLocalBundles -> %s\n", promptMsg["OpenFile"]), err) + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] loadLocalBundles -> %s\n", promptMsg["OpenFile"]), err)) return false } @@ -253,7 +253,7 @@ func loadLocalBundles() bool { if !fi.IsDir() && strings.HasSuffix(fi.Name(), ".json") { fr, err := os.Open(appPath + "repo/bundles/" + fi.Name()) if err != nil { - fmt.Printf(fmt.Sprintf("ERROR: loadLocalBundles -> %s\n", promptMsg["OpenFile"]), err) + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] loadLocalBundles -> %s\n", promptMsg["OpenFile"]), err)) return false } @@ -261,7 +261,7 @@ func loadLocalBundles() bool { err = json.NewDecoder(fr).Decode(bundle) fr.Close() if err != nil && err != io.EOF { - fmt.Printf(fmt.Sprintf("ERROR: loadLocalBundles -> %s\n", promptMsg["ParseJSON"]), err) + utils.ColorPrint(fmt.Sprintf(fmt.Sprintf("[ERROR] loadLocalBundles -> %s\n", promptMsg["ParseJSON"]), err)) return false } diff --git a/search.go b/search.go index 2e7b099ec..5001a9152 100644 --- a/search.go +++ b/search.go @@ -6,9 +6,11 @@ package main import ( "fmt" + "runtime" "strings" "github.com/GPMGo/gopm/doc" + "github.com/GPMGo/gopm/utils" ) var cmdSearch = &Command{ @@ -42,8 +44,20 @@ func runSearch(cmd *Command, args []string) { } // Search from server, and list results. - results, _ := doc.HttpGetBytes(doc.HttpClient, "http://gowalker.org/search?raw=true&q="+args[0], nil) - pkgs := strings.Split(string(results), "|||") + results, err := doc.HttpGetBytes(doc.HttpClient, "http://gowalker.org/search?raw=true&q="+args[0], nil) + if err != nil { + utils.ColorPrint(fmt.Sprintf("[ERROR] runSearch -> [ %s ]\n", err)) + return + } + + resultStr := string(results) + + if runtime.GOOS != "windows" { + // Set color highlight. + resultStr = strings.Replace(resultStr, args[0], fmt.Sprintf(utils.PureStartColor, utils.Yellow)+args[0]+utils.EndColor, -1) + } + + pkgs := strings.Split(resultStr, "|||") for _, p := range pkgs { i := strings.Index(p, "$") if i > -1 { diff --git a/utils/utils.go b/utils/utils.go index 9e859b4b1..910dac3ae 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -5,6 +5,7 @@ package utils import ( + "fmt" "os" "path" "regexp" @@ -12,12 +13,129 @@ import ( "strings" ) +const ( + PureStartColor = "\033[%dm" + StartColor = "(\033[%dm" + Gray = uint8(90) + Red = uint8(91) + Green = uint8(92) + Yellow = uint8(93) + Blue = uint8(94) + Magenta = uint8(95) + //NRed = uint8(31) // Normal + EndColor = "\033[0m" +) + +// ColorPrint prints colorful log print, doesn't work in windows. +// content in () with yellow, content in [] with read. +func ColorPrint(log string) { + // Make sure it's not windows. + if runtime.GOOS != "windows" { + log = strings.Replace(log, "[", fmt.Sprintf(StartColor, Red), -1) + log = strings.Replace(log, "]", EndColor+"]", -1) + log = strings.Replace(log, "(", fmt.Sprintf(StartColor, Green), -1) + log = strings.Replace(log, ")", EndColor+")", -1) + } + fmt.Print(log) +} + // IsExist returns if a file or directory exists func IsExist(path string) bool { _, err := os.Stat(path) return err == nil || os.IsExist(err) } +// GetGOPATH returns all paths in GOPATH variable. +func GetGOPATH() []string { + gopath := os.Getenv("GOPATH") + var paths []string + if runtime.GOOS == "windows" { + gopath = strings.Replace(gopath, "\\", "/", -1) + paths = strings.Split(gopath, ";") + } else { + paths = strings.Split(gopath, ":") + } + return paths +} + +// GetGOPATH returns best matched GOPATH. +func GetBestMatchGOPATH(appPath string) string { + paths := GetGOPATH() + for _, p := range paths { + if strings.HasPrefix(p, appPath) { + return strings.Replace(p, "\\", "/", -1) + } + } + return paths[0] +} + +// GetProjectPath returns project path of import path. +func GetProjectPath(importPath string) (projectPath string) { + projectPath = importPath + + // Check project hosting. + switch { + case strings.HasPrefix(importPath, "github.com"): + projectPath = joinPath(importPath, 3) + case strings.HasPrefix(importPath, "code.google.com"): + projectPath = joinPath(importPath, 3) + case strings.HasPrefix(importPath, "bitbucket.org"): + projectPath = joinPath(importPath, 3) + case strings.HasPrefix(importPath, "launchpad.net"): + projectPath = joinPath(importPath, 2) + } + + return projectPath +} + +func joinPath(importPath string, num int) string { + subdirs := strings.Split(importPath, "/") + if len(subdirs) > num { + return strings.Join(subdirs[:num], "/") + } + return importPath +} + +// GetExecuteName returns work directory and possible execute name according work directory. +func GetExecuteName(wd string) string { + wd = strings.Replace(wd, "\\", "/", -1) + execName := path.Base(wd) + if runtime.GOOS == "windows" { + execName += ".exe" + } + return execName +} + +var ( + readmePat = regexp.MustCompile(`^[Rr][Ee][Aa][Dd][Mm][Ee](?:$|\.)`) + licensePat = regexp.MustCompile(`^[Ll][Ii][Cc][En][Nn][Ss][Ee]`) +) + +func IsDocFile(n string) bool { + if (strings.HasSuffix(n, ".go") || strings.HasSuffix(n, ".h") || strings.HasSuffix(n, ".c")) && + n[0] != '_' && n[0] != '.' { + return true + } + + 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 +} + var validTLD = map[string]bool{ // curl http://data.iana.org/TLD/tlds-alpha-by-domain.txt | sed -e '/#/ d' -e 's/.*/"&": true,/' | tr [:upper:] [:lower:] ".ac": true, @@ -369,30 +487,6 @@ func IsValidRemotePath(importPath string) bool { return true } -// GetGOPATH returns all paths in GOPATH variable. -func GetGOPATH() []string { - gopath := os.Getenv("GOPATH") - var paths []string - if runtime.GOOS == "windows" { - gopath = strings.Replace(gopath, "\\", "/", -1) - paths = strings.Split(gopath, ";") - } else { - paths = strings.Split(gopath, ":") - } - return paths -} - -// GetGOPATH returns best matched GOPATH. -func GetBestMatchGOPATH(appPath string) string { - paths := GetGOPATH() - for _, p := range paths { - if strings.HasPrefix(p, appPath) { - return strings.Replace(p, "\\", "/", -1) - } - } - return paths[0] -} - var standardPath = map[string]bool{ "builtin": true, @@ -541,70 +635,3 @@ var standardPath = map[string]bool{ func IsGoRepoPath(importPath string) bool { return standardPath[importPath] } - -// GetProjectPath returns project path of import path. -func GetProjectPath(importPath string) (projectPath string) { - projectPath = importPath - - // Check project hosting. - switch { - case strings.HasPrefix(importPath, "github.com"): - projectPath = joinPath(importPath, 3) - case strings.HasPrefix(importPath, "code.google.com"): - projectPath = joinPath(importPath, 3) - case strings.HasPrefix(importPath, "bitbucket.org"): - projectPath = joinPath(importPath, 3) - case strings.HasPrefix(importPath, "launchpad.net"): - projectPath = joinPath(importPath, 2) - } - - return projectPath -} - -func joinPath(importPath string, num int) string { - subdirs := strings.Split(importPath, "/") - if len(subdirs) > num { - return strings.Join(subdirs[:num], "/") - } - return importPath -} - -// GetExecuteName returns work directory and possible execute name according work directory. -func GetExecuteName(wd string) string { - wd = strings.Replace(wd, "\\", "/", -1) - execName := path.Base(wd) - if runtime.GOOS == "windows" { - execName += ".exe" - } - return execName -} - -var ( - readmePat = regexp.MustCompile(`^[Rr][Ee][Aa][Dd][Mm][Ee](?:$|\.)`) - licensePat = regexp.MustCompile(`^[Ll][Ii][Cc][En][Nn][Ss][Ee]`) -) - -func IsDocFile(n string) bool { - if (strings.HasSuffix(n, ".go") || strings.HasSuffix(n, ".h") || strings.HasSuffix(n, ".c")) && - n[0] != '_' && n[0] != '.' { - return true - } - - 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 -}