Browse Source

strings add i18n support

pull/103/head
Unknown 12 years ago
parent
commit
4ee4552d17
  1. 2
      README.md
  2. 8
      build.go
  3. 2
      conf/gpm.toml
  4. 1
      doc/error.go
  5. 64
      gpm.go
  6. 28
      i18n/en-US/prompt.txt
  7. 48
      install.go
  8. 185
      models/models.go

2
README.md

@ -12,8 +12,6 @@ gpm(Go Package Manager) is a Go package manage tool for search, install, update
## Todo ## Todo
- All errors should have specific title for exactly where were created.
- Add i18n support for all strings.
- Command `build` add current path to GOPATH temporary. - Command `build` add current path to GOPATH temporary.
- Add gpm working principle design. - Add gpm working principle design.
- Add support for downloading tarballs from user sources. - Add support for downloading tarballs from user sources.

8
build.go

@ -44,17 +44,17 @@ func runBuild(cmd *Command, args []string) {
if utils.IsExist(wd + "/" + proName) { if utils.IsExist(wd + "/" + proName) {
err := os.Remove(wd + "/" + proName) err := os.Remove(wd + "/" + proName)
if err != nil { if err != nil {
fmt.Printf("Fail to remove file in current directory: %s.\n", err) fmt.Printf(fmt.Sprintf("ERROR: %s\n", promptMsg["RemoveFile"]), err)
return return
} }
} }
err := os.Rename(v+"/bin/"+proName, wd+"/"+proName) err := os.Rename(v+"/bin/"+proName, wd+"/"+proName)
if err == nil { if err == nil {
fmt.Printf("Moved file from $GOPATH(%s) to current directory(%s).\n", v, wd) fmt.Printf(fmt.Sprintf("%s\n", promptMsg["MovedFile"]), v, wd)
return return
} else {
fmt.Printf("Fail to move file from $GOPATH(%s) to current directory: %s.\n", v, err)
} }
fmt.Printf(fmt.Sprintf("%s\n", promptMsg["MoveFile"]), v, wd)
break break
} }
} }

2
conf/gpm.toml

@ -1,7 +1,7 @@
# This is a configuration file for gpm with toml format. # This is a configuration file for gpm with toml format.
title = "gpm(Go Package Manager)" title = "gpm(Go Package Manager)"
version = "v0.1.2 Build 0522" version = "v0.1.3 Build 0522"
username = "" username = ""
password = "" password = ""
user_language = "en-US" user_language = "en-US"

1
doc/error.go

@ -10,7 +10,6 @@ import (
var ( var (
errNotModified = errors.New("package not modified") errNotModified = errors.New("package not modified")
ErrNoMatch = errors.New("no match")
errUpdateTimeout = errors.New("update timeout") errUpdateTimeout = errors.New("update timeout")
) )

64
gpm.go

@ -28,10 +28,16 @@ import (
var ( var (
config tomlConfig config tomlConfig
appPath string // Application path. appPath string // Application path.
)
var (
localNodes []*doc.Node localNodes []*doc.Node
localBundles []*doc.Bundle localBundles []*doc.Bundle
) )
// Use for i18n, key is prompt code, value is corresponding message.
var promptMsg map[string]string
type tomlConfig struct { type tomlConfig struct {
Title, Version string Title, Version string
Username, Password string Username, Password string
@ -93,7 +99,7 @@ func getAppPath() bool {
// Look up executable in PATH variable. // Look up executable in PATH variable.
appPath, _ = exec.LookPath("gpm") appPath, _ = exec.LookPath("gpm")
if len(appPath) == 0 { if len(appPath) == 0 {
fmt.Printf("getAppPath(): Unable to indicate current execute path.") fmt.Printf("ERROR: getAppPath -> Unable to indicate current execute path.\n")
return false return false
} }
@ -104,17 +110,47 @@ func getAppPath() bool {
return true return true
} }
// loadPromptMsg loads prompt messages according to user language.
func loadPromptMsg(lang string) bool {
promptMsg = make(map[string]string)
// 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)
return false
}
defer f.Close()
// Read prompt messages.
fi, _ := f.Stat()
promptBytes := make([]byte, fi.Size())
f.Read(promptBytes)
promptStrs := strings.Split(string(promptBytes), "\n")
for _, p := range promptStrs {
i := strings.Index(p, "=")
if i > -1 {
promptMsg[p[:i]] = p[i+1:]
}
}
return true
}
// loadUsage loads usage according to user language. // loadUsage loads usage according to user language.
func loadUsage(lang string) bool { func loadUsage(lang string) bool {
if !loadPromptMsg(lang) {
return false
}
// Load main usage. // Load main usage.
f, err := os.Open(appPath + "i18n/" + lang + "/usage.tpl") f, err := os.Open(appPath + "i18n/" + lang + "/usage.tpl")
if err != nil { if err != nil {
fmt.Printf("loadUsage(): Fail to load main usage: %s.\n", err) fmt.Printf(fmt.Sprintf("ERROR: loadUsage -> %s\n", promptMsg["LoadCommandUsage"]), "main", err)
return false return false
} }
defer f.Close() defer f.Close()
// Read command usages. // Read main usages.
fi, _ := f.Stat() fi, _ := f.Stat()
usageBytes := make([]byte, fi.Size()) usageBytes := make([]byte, fi.Size())
f.Read(usageBytes) f.Read(usageBytes)
@ -124,17 +160,19 @@ func loadUsage(lang string) bool {
for _, cmd := range commands { for _, cmd := range commands {
f, err := os.Open(appPath + "i18n/" + lang + "/usage_" + cmd.Name() + ".txt") f, err := os.Open(appPath + "i18n/" + lang + "/usage_" + cmd.Name() + ".txt")
if err != nil { if err != nil {
fmt.Printf("loadUsage(): Fail to load usage(%s): %s.\n", cmd.Name(), err) fmt.Printf(fmt.Sprintf("ERROR: loadUsage -> %s\n", promptMsg["LoadCommandUsage"]), cmd.Name(), err)
return false return false
} }
defer f.Close() defer f.Close()
// Read usage. // Read usage.
fi, _ := f.Stat() fi, _ := f.Stat()
usageBytes := make([]byte, fi.Size()) usageBytes := make([]byte, fi.Size())
f.Read(usageBytes) f.Read(usageBytes)
usages := strings.Split(string(usageBytes), "|||") usages := strings.Split(string(usageBytes), "|||")
if len(usages) < 2 { if len(usages) < 2 {
fmt.Printf("loadUsage(): nacceptable usage file: %s.\n", cmd.Name()) fmt.Printf(
fmt.Sprintf("ERROR: loadUsage -> %s\n", promptMsg["ReadCoammndUsage"]), cmd.Name())
return false return false
} }
cmd.Short = usages[0] cmd.Short = usages[0]
@ -151,14 +189,14 @@ func loadLocalNodes() bool {
} else { } else {
fr, err := os.Open(appPath + "data/nodes.json") fr, err := os.Open(appPath + "data/nodes.json")
if err != nil { if err != nil {
fmt.Println(err) fmt.Printf(fmt.Sprintf("ERROR: loadLocalNodes -> %s\n", promptMsg["LoadLocalData"]), err)
return false return false
} }
defer fr.Close() defer fr.Close()
err = json.NewDecoder(fr).Decode(&localNodes) err = json.NewDecoder(fr).Decode(&localNodes)
if err != nil && err != io.EOF { if err != nil && err != io.EOF {
fmt.Println(err) fmt.Printf(fmt.Sprintf("ERROR: loadLocalNodes -> %s\n", promptMsg["ParseJSON"]), err)
return false return false
} }
} }
@ -170,14 +208,14 @@ func loadLocalBundles() bool {
// Find all bundles. // Find all bundles.
dir, err := os.Open(appPath + "repo/bundles/") dir, err := os.Open(appPath + "repo/bundles/")
if err != nil { if err != nil {
fmt.Println(err) fmt.Printf(fmt.Sprintf("ERROR: loadLocalBundles -> %s\n", promptMsg["OpenFile"]), err)
return false return false
} }
defer dir.Close() defer dir.Close()
fis, err := dir.Readdir(0) fis, err := dir.Readdir(0)
if err != nil { if err != nil {
fmt.Println(err) fmt.Printf(fmt.Sprintf("ERROR: loadLocalBundles -> %s\n", promptMsg["OpenFile"]), err)
return false return false
} }
@ -186,7 +224,7 @@ func loadLocalBundles() bool {
if !fi.IsDir() && strings.HasSuffix(fi.Name(), ".json") { if !fi.IsDir() && strings.HasSuffix(fi.Name(), ".json") {
fr, err := os.Open(appPath + "repo/bundles/" + fi.Name()) fr, err := os.Open(appPath + "repo/bundles/" + fi.Name())
if err != nil { if err != nil {
fmt.Println(err) fmt.Printf(fmt.Sprintf("ERROR: loadLocalBundles -> %s\n", promptMsg["OpenFile"]), err)
return false return false
} }
@ -194,7 +232,7 @@ func loadLocalBundles() bool {
err = json.NewDecoder(fr).Decode(bundle) err = json.NewDecoder(fr).Decode(bundle)
fr.Close() fr.Close()
if err != nil && err != io.EOF { if err != nil && err != io.EOF {
fmt.Println(err) fmt.Printf(fmt.Sprintf("ERROR: loadLocalBundles -> %s\n", promptMsg["ParseJSON"]), err)
return false return false
} }
@ -219,7 +257,7 @@ func initialize() bool {
// Load configuration. // Load configuration.
if _, err := toml.DecodeFile(appPath+"conf/gpm.toml", &config); err != nil { if _, err := toml.DecodeFile(appPath+"conf/gpm.toml", &config); err != nil {
fmt.Println(err) fmt.Printf("initialize -> Fail to load configuration[ %s ]\n", err)
return false return false
} }
@ -269,7 +307,7 @@ func main() {
} }
// Uknown commands. // Uknown commands.
fmt.Fprintf(os.Stderr, "gpm: unknown subcommand %q\nRun 'gpm help' for usage.\n", args[0]) fmt.Fprintf(os.Stderr, fmt.Sprintf("%s\n", promptMsg["UnknownCommand"]), args[0])
setExitStatus(2) setExitStatus(2)
exit() exit()
} }

28
i18n/en-US/prompt.txt

@ -0,0 +1,28 @@
LoadCommandUsage=Fail to load command(%s) usage[ %s ]
ReadCoammndUsage=Unacceptable command(%s) usage file.
LoadLocalData=Fail to load local data[ %s ]
ParseJSON=Fail to parse JSON[ %s ]
OpenFile=Fail to open file[ %s ]
RemoveFile=Fail to remove file[ %s ]
UnknownCommand=gpm: Unknown command %q. Run 'gpm help' for usage.
MoveFile=Fail to move file from $GOPATH(%s) to current directory(%s).
UnknownFlag=Unknown flag: %s.
DownloadError=Fail to download package(%s)[ %s ]
NotFoundError=Import path prefix matches known service, but regexp does not.
ErrNoMatch=Unsupported VCS platform.
MovedFile=Moved file from $GOPATH(%s) to current directory(%s).
PureDownload=You enabled pure download.
DownloadOnly=You enabled download without installing.
DownloadExDeps=You enabled download dependencies in example.
DownloadFromSrcs=You enabled download from sources.
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).
SkipDownloaded=Skipped downloaded package: %s.
SkipInvalidPath=Skipped invalid import path: %s.
InstallByGoGet=Installing package(%s) through 'go get'.
NoVCSTool=No version control tool is available, pure download enabled!
DownloadStatus=Downloading package: %s.

48
install.go

@ -6,6 +6,7 @@ package main
import ( import (
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"net/http" "net/http"
"os" "os"
@ -44,13 +45,13 @@ func init() {
func printPrompt(flag string) { func printPrompt(flag string) {
switch flag { switch flag {
case "-p": case "-p":
fmt.Printf("You enabled pure download.\n") fmt.Printf(fmt.Sprintf("%s\n", promptMsg["PureDownload"]))
case "-d": case "-d":
fmt.Printf("You enabled download without installing.\n") fmt.Printf(fmt.Sprintf("%s\n", promptMsg["DownloadOnly"]))
case "-e": case "-e":
fmt.Printf("You enabled download dependencies in example.\n") fmt.Printf(fmt.Sprintf("%s\n", promptMsg["DownloadExDeps"]))
case "-s": case "-s":
fmt.Printf("You enabled download from sources.\n") fmt.Printf(fmt.Sprintf("%s\n", promptMsg["DownloadFromSrcs"]))
} }
} }
@ -71,7 +72,7 @@ func checkFlags(args []string) int {
cmdInstall.Flags[f] = true cmdInstall.Flags[f] = true
printPrompt(f) printPrompt(f)
} else { } else {
fmt.Printf("Unknown flag: %s.\n", f) fmt.Printf(fmt.Sprintf("%s\n", promptMsg["UnknownFlag"]), f)
return -1 return -1
} }
num = i + 1 num = i + 1
@ -103,7 +104,7 @@ func runInstall(cmd *Command, args []string) {
// Check length of arguments. // Check length of arguments.
if len(args) < 1 { if len(args) < 1 {
fmt.Printf("Please list at least one package/bundle/snapshot.\n") fmt.Printf(fmt.Sprintf("%s\n", promptMsg["NoPackage"]))
return return
} }
@ -111,7 +112,7 @@ func runInstall(cmd *Command, args []string) {
checkVCSTool() checkVCSTool()
installGOPATH = utils.GetBestMatchGOPATH(appPath) installGOPATH = utils.GetBestMatchGOPATH(appPath)
fmt.Printf("Packages will be downloaded to GOPATH(%s).\n", installGOPATH) fmt.Printf(fmt.Sprintf("%s\n", promptMsg["DownloadPath"]), installGOPATH)
// Generate temporary nodes. // Generate temporary nodes.
nodes := make([]*doc.Node, len(args)) nodes := make([]*doc.Node, len(args))
@ -129,7 +130,7 @@ func runInstall(cmd *Command, args []string) {
cmdArgs = append(cmdArgs, "<blank>") cmdArgs = append(cmdArgs, "<blank>")
for k := range downloadCache { for k := range downloadCache {
fmt.Printf("Installing package: %s.\n", k) fmt.Printf(fmt.Sprintf("%s\n", promptMsg["InstallStatus"]), k)
cmdArgs[1] = k cmdArgs[1] = k
executeGoCommand(cmdArgs) executeGoCommand(cmdArgs)
} }
@ -137,11 +138,15 @@ func runInstall(cmd *Command, args []string) {
// Save local nodes to file. // Save local nodes to file.
fw, err := os.Create(appPath + "data/nodes.json") fw, err := os.Create(appPath + "data/nodes.json")
if err != nil { if err != nil {
fmt.Println(err) fmt.Printf(fmt.Sprintf("ERROR: runInstall -> %s\n", promptMsg["OpenFile"]), err)
return return
} }
defer fw.Close() defer fw.Close()
fbytes, _ := json.MarshalIndent(&localNodes, "", "\t") fbytes, err := json.MarshalIndent(&localNodes, "", "\t")
if err != nil {
fmt.Printf(fmt.Sprintf("ERROR: runInstall -> %s\n", promptMsg["ParseJSON"]), err)
return
}
fw.Write(fbytes) fw.Write(fbytes)
} }
@ -183,14 +188,13 @@ func downloadPackages(nodes []*doc.Node) {
case n.ImportPath[0] == 'B': case n.ImportPath[0] == 'B':
// Check local bundles. // Check local bundles.
bnodes := checkLocalBundles(n.ImportPath[1:]) bnodes := checkLocalBundles(n.ImportPath[1:])
if len(nodes) > 0 { if len(bnodes) > 0 {
// Check with users if continue. // Check with users if continue.
fmt.Printf("Bundle(%s) contains following nodes:\n", fmt.Printf(fmt.Sprintf("%s\n", promptMsg["BundleInfo"]), n.ImportPath[1:])
n.ImportPath[1:])
for _, bn := range bnodes { for _, bn := range bnodes {
fmt.Printf("[%s] -> %s: %s.\n", bn.ImportPath, bn.Type, bn.Value) fmt.Printf("[%s] -> %s: %s.\n", bn.ImportPath, bn.Type, bn.Value)
} }
fmt.Print("Continue to download?(Y/n).") fmt.Printf(fmt.Sprintf("%s", promptMsg["ContinueDownload"]))
var option string var option string
fmt.Fscan(os.Stdin, &option) fmt.Fscan(os.Stdin, &option)
if strings.ToLower(option) != "y" { if strings.ToLower(option) != "y" {
@ -225,11 +229,11 @@ func downloadPackages(nodes []*doc.Node) {
saveNode(node) saveNode(node)
} }
} else { } else {
fmt.Printf("Skipped downloaded package: %s.\n", n.ImportPath) fmt.Printf(fmt.Sprintf("%s\n", promptMsg["SkipDownloaded"]), n.ImportPath)
} }
default: default:
// Invalid import path. // Invalid import path.
fmt.Printf("Skipped invalid import path: %s.\n", n.ImportPath) fmt.Printf(fmt.Sprintf("%s\n", promptMsg["SkipInvalidPath"]), n.ImportPath)
} }
} }
} }
@ -254,7 +258,7 @@ func downloadPackage(node *doc.Node) (*doc.Node, []string) {
switch { switch {
case !cmdInstall.Flags["-p"] && case !cmdInstall.Flags["-p"] &&
((node.ImportPath[0] == 'g' && isHasGit) || (node.ImportPath[0] == 'c' && isHasHg)): // github.com, code.google.com ((node.ImportPath[0] == 'g' && isHasGit) || (node.ImportPath[0] == 'c' && isHasHg)): // github.com, code.google.com
fmt.Printf("Installing package(%s) through 'go get'.\n", node.ImportPath) fmt.Printf(fmt.Sprintf("%s\n", promptMsg["InstallByGoGet"]), node.ImportPath)
args := checkGoGetFlags() args := checkGoGetFlags()
args = append(args, node.ImportPath) args = append(args, node.ImportPath)
executeGoCommand(args) executeGoCommand(args)
@ -262,16 +266,16 @@ func downloadPackage(node *doc.Node) (*doc.Node, []string) {
default: // Pure download. default: // Pure download.
if !cmdInstall.Flags["-p"] { if !cmdInstall.Flags["-p"] {
cmdInstall.Flags["-p"] = true cmdInstall.Flags["-p"] = true
fmt.Printf("No version control tool is available, pure download enabled!\n") fmt.Printf(fmt.Sprintf("%s\n", promptMsg["NoVCSTool"]))
} }
fmt.Printf("Downloading package: %s.\n", node.ImportPath) fmt.Printf(fmt.Sprintf("%s\n", promptMsg["InstallByGoGet"]), node.ImportPath)
// Mark as donwloaded. // Mark as donwloaded.
downloadCache[node.ImportPath] = true downloadCache[node.ImportPath] = true
imports, err := pureDownload(node) imports, err := pureDownload(node)
if err != nil { if err != nil {
fmt.Printf("Fail to download package(%s) with error: %s.\n", node.ImportPath, err) fmt.Printf(fmt.Sprintf("%s\n", promptMsg["DownloadError"]), node.ImportPath, err)
return nil, nil return nil, nil
} }
@ -317,7 +321,7 @@ func pureDownload(node *doc.Node) ([]string, error) {
if m == nil { if m == nil {
if s.prefix != "" { if s.prefix != "" {
return nil, return nil,
doc.NotFoundError{"Import path prefix matches known service, but regexp does not."} doc.NotFoundError{fmt.Sprintf("%s\n", promptMsg["NotFoundError"])}
} }
continue continue
} }
@ -329,5 +333,5 @@ func pureDownload(node *doc.Node) ([]string, error) {
} }
return s.get(doc.HttpClient, match, installGOPATH, node, cmdInstall.Flags) return s.get(doc.HttpClient, match, installGOPATH, node, cmdInstall.Flags)
} }
return nil, doc.ErrNoMatch return nil, errors.New(fmt.Sprintf("%s\n", promptMsg["NotFoundError"]))
} }

185
models/models.go

@ -1,185 +0,0 @@
// 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 models implemented database access funtions.
package models
import (
"database/sql"
"errors"
//"os"
"strconv"
"strings"
"time"
"github.com/coocood/qbs"
_ "github.com/mattn/go-sqlite3"
)
const (
DB_NAME = "./data/gowalker.db"
_SQLITE3_DRIVER = "sqlite3"
)
// PkgInfo is package information.
type PkgInfo struct {
Id int64
Path string `qbs:"index"` // Import path of package.
AbsPath string
Imports []string
Note string
Created time.Time `qbs:"index"` // Time when information last updated.
Commit string // Revision tag and project tags.
}
func connDb() *qbs.Qbs {
// 'sql.Open' only returns error when unknown driver, so it's not necessary to check in other places.
db, err := sql.Open(_SQLITE3_DRIVER, DB_NAME)
if err != nil {
//beego.Error("models.connDb():", err)
}
q := qbs.New(db, qbs.NewSqlite3())
return q
}
func setMg() (*qbs.Migration, error) {
db, err := sql.Open(_SQLITE3_DRIVER, DB_NAME)
mg := qbs.NewMigration(db, DB_NAME, qbs.NewSqlite3())
return mg, err
}
/*func init() {
// Initialize database.
os.Mkdir("./data", os.ModePerm)
// Connect to database.
q := connDb()
defer q.Db.Close()
mg, err := setMg()
if err != nil {
beego.Error("models.init():", err)
}
defer mg.Db.Close()
// Create data tables.
mg.CreateTableIfNotExists(new(PkgInfo))
beego.Trace("Initialized database ->", DB_NAME)
}*/
// GetProInfo returns package information from database.
func GetPkgInfo(path string) (*PkgInfo, error) {
// Check path length to reduce connect times.
if len(path) == 0 {
return nil, errors.New("models.GetPkgInfo(): Empty path as not found.")
}
// Connect to database.
q := connDb()
defer q.Db.Close()
pinfo := new(PkgInfo)
err := q.WhereEqual("path", path).Find(pinfo)
return pinfo, err
}
// GetGroupPkgInfo returns group of package infomration in order to reduce database connect times.
func GetGroupPkgInfo(paths []string) ([]*PkgInfo, error) {
// Connect to database.
q := connDb()
defer q.Db.Close()
pinfos := make([]*PkgInfo, 0, len(paths))
for _, v := range paths {
if len(v) > 0 {
pinfo := new(PkgInfo)
err := q.WhereEqual("path", v).Find(pinfo)
if err == nil {
pinfos = append(pinfos, pinfo)
} else {
pinfos = append(pinfos, &PkgInfo{Path: v})
}
}
}
return pinfos, nil
}
// GetPkgInfoById returns package information from database by pid.
func GetPkgInfoById(pid int) (*PkgInfo, error) {
// Connect to database.
q := connDb()
defer q.Db.Close()
pinfo := new(PkgInfo)
err := q.WhereEqual("id", pid).Find(pinfo)
return pinfo, err
}
// GetGroupPkgInfoById returns group of package infomration by pid in order to reduce database connect times.
// The formatted pid looks like '$<pid>|', so we need to cut '$' here.
func GetGroupPkgInfoById(pids []string) ([]*PkgInfo, error) {
// Connect to database.
q := connDb()
defer q.Db.Close()
pinfos := make([]*PkgInfo, 0, len(pids))
for _, v := range pids {
if len(v) > 1 {
pid, err := strconv.Atoi(v[1:])
if err == nil {
pinfo := new(PkgInfo)
err = q.WhereEqual("id", pid).Find(pinfo)
if err == nil {
pinfos = append(pinfos, pinfo)
}
}
}
}
return pinfos, nil
}
// DeleteProject deletes everything about the path in database, and update import information.
func DeleteProject(path string) error {
// Check path length to reduce connect times. (except launchpad.net)
if path[0] != 'l' && len(strings.Split(path, "/")) <= 2 {
return errors.New("models.DeleteProject(): Short path as not needed.")
}
// Connect to database.
q := connDb()
defer q.Db.Close()
var i1 int64
// Delete package information.
info := new(PkgInfo)
err := q.WhereEqual("path", path).Find(info)
if err == nil {
i1, err = q.Delete(info)
if err != nil {
//beego.Error("models.DeleteProject(): Information:", err)
}
}
if i1 > 0 {
//beego.Info("models.DeleteProject(", path, i1, ")")
}
return nil
}
// SearchDoc returns packages information that contain keyword
func SearchDoc(key string) ([]*PkgInfo, error) {
// Connect to database.
q := connDb()
defer q.Db.Close()
var pkgInfos []*PkgInfo
condition := qbs.NewCondition("path like ?", "%"+key+"%")
err := q.Condition(condition).OrderBy("path").FindAll(&pkgInfos)
return pkgInfos, err
}
Loading…
Cancel
Save