Browse Source

clean code: install.go

pull/103/head
Unknown 12 years ago
parent
commit
bf5c32e91e
  1. 2
      README.md
  2. 2
      README_ZH.md
  3. 2
      conf/gpm.toml
  4. 32
      doc/github.go
  5. 149
      doc/walker.go
  6. 6
      gpm.go
  7. 3
      i18n/en-US/usage_install.txt
  8. 164
      install.go
  9. 2
      utils/utils.go

2
README.md

@ -3,4 +3,4 @@ gpm - Go Package Manager
![GPMGo_Logo](https://raw.github.com/GPMGo/gpm-site/master/static/img/gpmgo2.png?raw=true) ![GPMGo_Logo](https://raw.github.com/GPMGo/gpm-site/master/static/img/gpmgo2.png?raw=true)
gpm(Go Package Manager) is a Go package manage tool for search, install, update and share packages in Go. gpm(Go Package Manager) is a Go package manage tool for search, install, update, save and share your packages in Go.

2
README_ZH.md

@ -3,4 +3,4 @@ gpm - Go 项目管理工具
![GPMGo_Logo](https://raw.github.com/GPMGo/gpm-site/master/static/img/gpmgo2.png?raw=true) ![GPMGo_Logo](https://raw.github.com/GPMGo/gpm-site/master/static/img/gpmgo2.png?raw=true)
gpm(Go 项目管理工具) 是一款涵盖搜索、安装、更新以及分享 Go 项目的管理工具。 gpm(Go 项目管理工具) 是一款涵盖搜索、安装、更新、保存以及分享 Go 项目的管理工具。

2
conf/gpm.toml

@ -1,5 +1,5 @@
# 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.0.1 Build 0517" version = "v0.0.2 Build 0519"
user_language = "en-US" user_language = "en-US"

32
doc/github.go

@ -5,17 +5,17 @@
package doc package doc
import ( import (
"archive/zip" /*"archive/zip"
"bytes" "bytes"
"fmt" "fmt"
"io" "io"*/
"net/http" "net/http"
"os" /*"os"
"path" "path"*/
"regexp" "regexp"
"strings" //"strings"
"github.com/GPMGo/gpm/utils" //"github.com/GPMGo/gpm/utils"
) )
var ( var (
@ -28,8 +28,8 @@ func SetGithubCredentials(id, secret string) {
githubCred = "client_id=" + id + "&client_secret=" + secret githubCred = "client_id=" + id + "&client_secret=" + secret
} }
func GetGithubDoc(client *http.Client, match map[string]string, commit string) (*Package, error) { func GetGithubDoc(client *http.Client, match map[string]string, commit string) (*Package, []string, error) {
SetGithubCredentials("1862bcb265171f37f36c", "308d71ab53ccd858416cfceaed52d5d5b7d53c5f") /*SetGithubCredentials("1862bcb265171f37f36c", "308d71ab53ccd858416cfceaed52d5d5b7d53c5f")
match["cred"] = githubCred match["cred"] = githubCred
var refs []*struct { var refs []*struct {
@ -130,14 +130,14 @@ func GetGithubDoc(client *http.Client, match map[string]string, commit string) (
data: fbytes, data: fbytes,
}) })
}*/ }*/
} /* }
pkg := &Package{ pkg := &Package{
ImportPath: importPath, ImportPath: importPath,
AbsPath: installPath, AbsPath: installPath,
Commit: commit, Commit: commit,
Dirs: dirs, Dirs: dirs,
} }*/
return pkg, nil return nil, nil, nil
} }

149
doc/walker.go

@ -1,149 +0,0 @@
// Copyright 2011 Gary Burd
// Copyright 2013 Unknown
//
// Licensed under the Apache License, Version 2.0 (the "License"): you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
package doc
import (
"bytes"
"errors"
"fmt"
"go/ast"
"go/build"
"go/parser"
"go/token"
"io"
"io/ioutil"
"os"
"path"
"regexp"
"runtime"
"strings"
"time"
"github.com/GPMGo/gpm/models"
)
type sliceWriter struct{ p *[]byte }
func (w sliceWriter) Write(p []byte) (int, error) {
*w.p = append(*w.p, p...)
return len(p), nil
}
func (w *walker) readDir(dir string) ([]os.FileInfo, error) {
if dir != w.pinfo.Path {
panic("unexpected")
}
fis := make([]os.FileInfo, 0, len(w.srcs))
for _, src := range w.srcs {
fis = append(fis, src)
}
return fis, nil
}
func (w *walker) openFile(path string) (io.ReadCloser, error) {
if strings.HasPrefix(path, w.pinfo.Path+"/") {
if src, ok := w.srcs[path[len(w.pinfo.Path)+1:]]; ok {
return ioutil.NopCloser(bytes.NewReader(src.data)), nil
}
}
panic("unexpected")
}
func simpleImporter(imports map[string]*ast.Object, path string) (*ast.Object, error) {
pkg := imports[path]
if pkg == nil {
// Guess the package name without importing it. Start with the last
// element of the path.
name := path[strings.LastIndex(path, "/")+1:]
// Trim commonly used prefixes and suffixes containing illegal name
// runes.
name = strings.TrimSuffix(name, ".go")
name = strings.TrimSuffix(name, "-go")
name = strings.TrimPrefix(name, "go.")
name = strings.TrimPrefix(name, "go-")
name = strings.TrimPrefix(name, "biogo.")
// It's also common for the last element of the path to contain an
// extra "go" prefix, but not always. TODO: examine unresolved ids to
// detect when trimming the "go" prefix is appropriate.
pkg = ast.NewObj(ast.Pkg, name)
pkg.Data = ast.NewScope(nil)
imports[path] = pkg
}
return pkg, nil
}
var buildPicPattern = regexp.MustCompile(`\[+!+\[+([a-zA-Z ]*)+\]+\(+[a-zA-z]+://[^\s]*`)
// build generates data from source files.
/*func (w *walker) build(srcs []*source) (*models.PkgInfo, error) {
// Set created time.
w.pinfo.Created = time.Now().UTC()
// Add source files to walker, I skipped references here.
w.srcs = make(map[string]*source)
for _, src := range srcs {
w.srcs[src.name] = src
}
w.fset = token.NewFileSet()
// Find the package and associated files.
ctxt := build.Context{
GOOS: runtime.GOOS,
GOARCH: runtime.GOARCH,
CgoEnabled: true,
JoinPath: path.Join,
IsAbsPath: path.IsAbs,
SplitPathList: func(list string) []string { return strings.Split(list, ":") },
IsDir: func(path string) bool { panic("unexpected") },
HasSubdir: func(root, dir string) (rel string, ok bool) { panic("unexpected") },
ReadDir: func(dir string) (fi []os.FileInfo, err error) { return w.readDir(dir) },
OpenFile: func(path string) (r io.ReadCloser, err error) { return w.openFile(path) },
Compiler: "gc",
}
bpkg, err := ctxt.ImportDir(w.pinfo.Path, 0)
// Continue if there are no Go source files; we still want the directory info.
_, nogo := err.(*build.NoGoError)
if err != nil {
if nogo {
err = nil
} else {
return w.pinfo, errors.New("doc.walker.build(): " + err.Error())
}
}
// Parse the Go files
files := make(map[string]*ast.File)
for _, name := range append(bpkg.GoFiles, bpkg.CgoFiles...) {
file, err := parser.ParseFile(w.fset, name, w.srcs[name].data, parser.ParseComments)
if err != nil {
//beego.Error("doc.walker.build():", err)
continue
}
files[name] = file
}
w.pinfo.Imports = bpkg.Imports
fmt.Println(w.pinfo)
// beego.Info("doc.walker.build(", pdoc.ImportPath, "), Goroutine #", runtime.NumGoroutine())
return w.pinfo, err
}
*/

6
gpm.go

@ -23,9 +23,8 @@ import (
) )
var ( var (
config tomlConfig config tomlConfig
appPath string // Application path. appPath string // Application path.
isWindows bool // Indicates if current system is windows.
) )
type tomlConfig struct { type tomlConfig struct {
@ -93,7 +92,6 @@ func getAppPath() bool {
} }
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
isWindows = true
// Replace all '\' to '/'. // Replace all '\' to '/'.
appPath = strings.Replace(filepath.Dir(appPath), "\\", "/", -1) + "/" appPath = strings.Replace(filepath.Dir(appPath), "\\", "/", -1) + "/"
} }

3
i18n/en-US/usage_install.txt

@ -18,6 +18,7 @@ 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. in an element in the list, surround it with either single or double quotes.
For more about specifying packages, see 'go help packages'. For more about specifying packages, see 'go help packages'.
For more about hash, see 'gpm help hash'. For more about bundle, see 'gpm help bundle'.
For more about snapshot, see 'gpm help snapshot'.
See also: gpm build. See also: gpm build.

164
install.go

@ -21,7 +21,7 @@ var (
) )
var cmdInstall = &Command{ var cmdInstall = &Command{
UsageLine: "install [install flags] <packages|hash>", UsageLine: "install [install flags] <packages|bundles|snapshots>",
} }
func init() { func init() {
@ -34,88 +34,145 @@ func init() {
} }
} }
func runInstall(cmd *Command, args []string) { // printPrompt prints prompt information to users to
// Check if has flags. // let them know what's going on.
num := 0 func printPrompt(flag string) {
switch flag {
case "-p":
fmt.Printf("You enabled pure download.\n")
case "-d":
fmt.Printf("You enabled download without installing.\n")
}
}
// checkFlags checks if the flag exists with correct format.
func checkFlags(args []string) int {
num := 0 // Number of valid flags, use to cut out.
for i, f := range args { for i, f := range args {
if strings.Index(f, "-") > -1 { // Check flag prefix '-'.
// Deal with flags. if !strings.HasPrefix(f, "-") {
if _, ok := cmdInstall.Flags[f]; ok { // Not a flag, finish check process.
cmdInstall.Flags[f] = true break
printPrompt(f)
} else {
fmt.Printf("Unknown flag: %s.\n", f)
return
}
num = i + 1
} }
// Check if it a valid flag.
/* Here we use ok pattern to check it because
this way can avoid same flag appears multiple times.*/
if _, ok := cmdInstall.Flags[f]; ok {
cmdInstall.Flags[f] = true
printPrompt(f)
} else {
fmt.Printf("Unknown flag: %s.\n", f)
return -1
}
num = i + 1
}
return num
}
// checkVCSTool checks if users have installed version control tools.
func checkVCSTool() {
// git.
if _, err := exec.LookPath("git"); err == nil {
isHasGit = true
}
// hg.
if _, err := exec.LookPath("hg"); err == nil {
isHasHg = true
}
// svn.
}
func runInstall(cmd *Command, args []string) {
// Check flags.
num := checkFlags(args)
if num == -1 {
return
} }
// Cut out flag.
args = args[num:] args = args[num:]
// Check length of arguments. // Check length of arguments.
if len(args) < 1 { if len(args) < 1 {
fmt.Printf("Please list at least one package.\n") fmt.Printf("Please list at least one package/bundle/snapshot.\n")
return return
} }
// Check version control tools. // Check version control tools.
_, err := exec.LookPath("git") checkVCSTool()
if err == nil {
isHasGit = true
}
_, err = exec.LookPath("hg")
if err == nil {
isHasHg = true
}
// Install package(s). // Download packages.
for _, p := range args { commits := make([]string, len(args))
// Check if it is a hash string. downloadPackages(args, commits)
// TODO
// Check if it is vaild remote path. // Install packages all together.
if !utils.IsValidRemotePath(p) { fmt.Println("Well done.")
fmt.Printf("Invalid remote path: %s.\n", p)
} else {
downloadPackage(p, "")
}
}
} }
func printPrompt(flag string) { // downloadPackages downloads packages with certain commit,
switch flag { // if the commit is empty string, then it downloads all dependencies,
case "-p": // otherwise, it only downloada package with specific commit only.
fmt.Println("You enabled pure download.") func downloadPackages(pkgs, commits []string) {
case "-d": // Check all packages, they may be bundles, snapshots or raw packages path.
fmt.Println("You enabled download without installing.") for i, p := range pkgs {
// Check if it is a bundle or snapshot.
switch {
case p[0] == 'B':
// TODO: api.GetBundleInfo()
case p[0] == 'S':
// TODO: api.GetSnapshotInfo()
case utils.IsValidRemotePath(p) && !downloadCache[p]:
// Download package.
pkg, imports := downloadPackage(p, commits[i])
if imports != nil {
// Need to download dependencies.
tags := make([]string, len(imports))
downloadPackages(imports, tags)
continue
}
// Only save package information with specific commit.
if pkg != nil {
// Save record in local database.
fmt.Printf("Saved information: %s:%s.\n", pkg.ImportPath, pkg.Commit)
}
default:
// Invalid import path.
fmt.Printf("Skipped invalid import path: %s.\n", p)
}
} }
} }
// downloadPackage download package either use version control tools or not. // downloadPackage download package either use version control tools or not.
func downloadPackage(path, commit string) { func downloadPackage(path, commit string) (pkg *doc.Package, imports []string) {
// Check if use version control tools. // Check if use version control tools.
switch { switch {
case !cmdInstall.Flags["-p"] && case !cmdInstall.Flags["-p"] &&
((path[0] == 'g' && isHasGit) || (path[0] == 'c' && isHasHg)): // github.com, code.google.com ((path[0] == 'g' && isHasGit) || (path[0] == 'c' && isHasHg)): // github.com, code.google.com
fmt.Printf("Installing package(%s) through 'go get'.\n", path)
args := checkGoGetFlags() args := checkGoGetFlags()
args = append(args, path) args = append(args, path)
fmt.Printf("Installing package: %s.\n", path)
executeGoCommand(args) executeGoCommand(args)
return nil, nil
default: // Pure download. default: // Pure download.
if !cmdInstall.Flags["-p"] { if !cmdInstall.Flags["-p"] {
fmt.Printf("No version control tool available, pure download enabled!\n") cmdInstall.Flags["-p"] = true
fmt.Printf("No version control tool is available, pure download enabled!\n")
} }
fmt.Printf("Downloading package: %s.\n", path) fmt.Printf("Downloading package: %s.\n", path)
pkg, err := pureDownload(path, commit) // Mark as donwloaded.
downloadCache[path] = true
var err error
pkg, imports, err = pureDownload(path, commit)
if err != nil { if err != nil {
fmt.Printf("Fail to download package(%s) with error: %s.\n", path, err) fmt.Printf("Fail to download package(%s) with error: %s.\n", path, err)
return nil, nil
} else { } else {
fmt.Println(pkg) fmt.Println(pkg)
fmt.Printf("Checking imports(%s).\n", path) fmt.Printf("Downloaded package: %s.\n", path)
return pkg, imports
fmt.Printf("Installing package: %s.\n", path)
} }
} }
} }
@ -137,7 +194,7 @@ func checkGoGetFlags() (args []string) {
type service struct { type service struct {
pattern *regexp.Regexp pattern *regexp.Regexp
prefix string prefix string
get func(*http.Client, map[string]string, string) (*doc.Package, error) get func(*http.Client, map[string]string, string) (*doc.Package, []string, error)
} }
// services is the list of source code control services handled by gopkgdoc. // services is the list of source code control services handled by gopkgdoc.
@ -148,8 +205,8 @@ var services = []*service{
//{launchpadPattern, "launchpad.net/", getLaunchpadDoc}, //{launchpadPattern, "launchpad.net/", getLaunchpadDoc},
} }
// pureDownload downloads package without control control. // pureDownload downloads package without version control.
func pureDownload(path, commit string) (pinfo *doc.Package, err error) { func pureDownload(path, commit string) (pinfo *doc.Package, imports []string, err error) {
for _, s := range services { for _, s := range services {
if s.get == nil || !strings.HasPrefix(path, s.prefix) { if s.get == nil || !strings.HasPrefix(path, s.prefix) {
continue continue
@ -157,7 +214,8 @@ func pureDownload(path, commit string) (pinfo *doc.Package, err error) {
m := s.pattern.FindStringSubmatch(path) m := s.pattern.FindStringSubmatch(path)
if m == nil { if m == nil {
if s.prefix != "" { if s.prefix != "" {
return nil, doc.NotFoundError{"Import path prefix matches known service, but regexp does not."} return nil, nil,
doc.NotFoundError{"Import path prefix matches known service, but regexp does not."}
} }
continue continue
} }
@ -169,5 +227,5 @@ func pureDownload(path, commit string) (pinfo *doc.Package, err error) {
} }
return s.get(doc.HttpClient, match, commit) return s.get(doc.HttpClient, match, commit)
} }
return nil, doc.ErrNoMatch return nil, nil, doc.ErrNoMatch
} }

2
utils/utils.go

@ -369,7 +369,7 @@ func IsValidRemotePath(importPath string) bool {
return true return true
} }
// GetGOPATHs return all GOPATH in system. // GetGOPATH return all GOPATH in system.
func GetGOPATH() []string { func GetGOPATH() []string {
gopath := os.Getenv("GOPATH") gopath := os.Getenv("GOPATH")
var paths []string var paths []string

Loading…
Cancel
Save