Browse Source

Merge pull request #6 from gpmgo/dev

Dev
pull/103/head
Joe Chen 11 years ago
parent
commit
7f65753d41
  1. 22
      README.md
  2. 1
      cmd/build.go
  3. 20
      cmd/cmd.go
  4. 10
      cmd/gen.go
  5. 272
      cmd/get.go
  6. 2
      cmd/gopath.go
  7. 18
      doc/struct.go
  8. 7
      gopm.go

22
README.md

@ -19,21 +19,21 @@ USAGE:
gopm [global options] command [command options] [arguments...] gopm [global options] command [command options] [arguments...]
VERSION: VERSION:
0.6.0.1209 0.6.1.0110
COMMANDS: COMMANDS:
get fetch remote package(s) and dependencies to local repository get fetch remote package(s) and dependencies to local repository
bin download and link dependencies and build executable binary bin download and link dependencies and build executable binary
gen generate a gopmfile according current Go project gen generate a gopmfile according current Go project
run link dependencies and go run run link dependencies and go run
build link dependencies and go build build link dependencies and go build
install link dependencies and go install install link dependencies and go install
help, h Shows a list of commands or help for one command help, h Shows a list of commands or help for one command
GLOBAL OPTIONS: GLOBAL OPTIONS:
--noterm disable color output --noterm disable color output
--version, -v print the version --version, -v print the version
--help, -h show help --help, -h show help
``` ```

1
cmd/build.go

@ -34,6 +34,7 @@ and execute 'go build'
gopm build <go build commands>`, gopm build <go build commands>`,
Action: runBuild, Action: runBuild,
Flags: []cli.Flag{ Flags: []cli.Flag{
cli.BoolFlag{"update, u", "update pakcage(s) and dependencies if any"},
cli.BoolFlag{"verbose, v", "show process details"}, cli.BoolFlag{"verbose, v", "show process details"},
}, },
} }

20
cmd/cmd.go

@ -1,4 +1,4 @@
// Copyright 2013 gopm authors. // Copyright 2013-2014 gopm authors.
// //
// Licensed under the Apache License, Version 2.0 (the "License"): you may // 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 // not use this file except in compliance with the License. You may obtain
@ -57,24 +57,22 @@ func validPath(info string) (string, string) {
l := len(infos) l := len(infos)
switch { switch {
case l == 1: case l == 1:
// for local imports // For local imports.
if com.IsFile(infos[0]) { if com.IsFile(infos[0]) {
return doc.LOCAL, infos[0] return doc.LOCAL, infos[0]
} }
return doc.BRANCH, ""
case l == 2: case l == 2:
switch infos[1] { switch infos[1] {
case doc.TRUNK, doc.MASTER, doc.DEFAULT: case doc.TRUNK, doc.MASTER, doc.DEFAULT:
infos[1] = "" infos[1] = ""
} }
return infos[0], infos[1] return infos[0], infos[1]
default:
log.Error("", "Cannot parse dependency version:")
log.Error("", "\t"+info)
log.Help("Try 'gopm help get' to get more information")
return "", ""
} }
log.Error("", "Cannot parse dependency version:")
log.Error("", "\t"+info)
log.Help("Try 'gopm help get' to get more information")
return "", ""
} }
func versionSuffix(value string) string { func versionSuffix(value string) string {
@ -83,3 +81,7 @@ func versionSuffix(value string) string {
} }
return "" return ""
} }
func isSubpackage(rootPath, targetPath string) bool {
return strings.HasSuffix(workDir, rootPath) || strings.HasPrefix(rootPath, targetPath)
}

10
cmd/gen.go

@ -41,7 +41,6 @@ Make sure you run this command in the root path of a go project.`,
}, },
} }
// scan a directory and gen a gopm file
func runGen(ctx *cli.Context) { func runGen(ctx *cli.Context) {
setup(ctx) setup(ctx)
@ -55,15 +54,18 @@ func runGen(ctx *cli.Context) {
log.Fatal("", "\t"+err.Error()) log.Fatal("", "\t"+err.Error())
} }
targetPath := parseTarget(gf.MustValue("target", "path"))
// Get dependencies. // Get dependencies.
imports := doc.GetAllImports([]string{workDir}, imports := doc.GetAllImports([]string{workDir}, targetPath, ctx.Bool("example"))
parseTarget(gf.MustValue("target", "path")), ctx.Bool("example"))
for _, p := range imports { for _, p := range imports {
p = doc.GetProjectPath(p) p = doc.GetProjectPath(p)
if strings.HasSuffix(workDir, p) { // Skip subpackage(s) of current project.
if strings.HasSuffix(workDir, p) || strings.HasPrefix(p, targetPath) {
continue continue
} }
// Check if user specified the version.
if value := gf.MustValue("deps", p); len(value) == 0 { if value := gf.MustValue("deps", p); len(value) == 0 {
gf.SetValue("deps", p, "") gf.SetValue("deps", p, "")
} }

272
cmd/get.go

@ -1,4 +1,4 @@
// Copyright 2013 gopm authors. // Copyright 2013-2014 gopm authors.
// //
// Licensed under the Apache License, Version 2.0 (the "License"): you may // 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 // not use this file except in compliance with the License. You may obtain
@ -69,7 +69,6 @@ func init() {
func runGet(ctx *cli.Context) { func runGet(ctx *cli.Context) {
setup(ctx) setup(ctx)
// Check conflicts. // Check conflicts.
if ctx.Bool("gopath") && ctx.Bool("remote") { if ctx.Bool("gopath") && ctx.Bool("remote") {
log.Error("get", "Command options have conflicts") log.Error("get", "Command options have conflicts")
@ -100,7 +99,7 @@ func runGet(ctx *cli.Context) {
} }
// The gopm local repository. // The gopm local repository.
installRepoPath = doc.HomeDir + "/repos" installRepoPath = path.Join(doc.HomeDir, "repos")
log.Log("Local repository path: %s", installRepoPath) log.Log("Local repository path: %s", installRepoPath)
// Check number of arguments to decide which function to call. // Check number of arguments to decide which function to call.
@ -119,11 +118,17 @@ func getByGopmfile(ctx *cli.Context) {
} }
gf := doc.NewGopmfile(".") gf := doc.NewGopmfile(".")
targetPath := parseTarget(gf.MustValue("target", "path"))
// Get dependencies. // Get dependencies.
imports := doc.GetAllImports([]string{workDir}, imports := doc.GetAllImports([]string{workDir}, targetPath, ctx.Bool("example"))
parseTarget(gf.MustValue("target", "path")), ctx.Bool("example"))
nodes := make([]*doc.Node, 0, len(imports)) nodes := make([]*doc.Node, 0, len(imports))
for _, p := range imports { for _, p := range imports {
p = doc.GetProjectPath(p)
// Skip subpackage(s) of current project.
if isSubpackage(p, targetPath) {
continue
}
node := doc.NewNode(p, p, doc.BRANCH, "", true) node := doc.NewNode(p, p, doc.BRANCH, "", true)
// Check if user specified the version. // Check if user specified the version.
@ -166,12 +171,20 @@ func getByPath(ctx *cli.Context) {
} }
func copyToGopath(srcPath, destPath string) { func copyToGopath(srcPath, destPath string) {
importPath := strings.TrimPrefix(destPath, installGopath+"/")
if len(getVcsName(destPath)) > 0 {
log.Warn("Package in GOPATH has version control: %s", importPath)
return
}
os.RemoveAll(destPath) os.RemoveAll(destPath)
err := com.CopyDir(srcPath, destPath) err := com.CopyDir(srcPath, destPath)
if err != nil { if err != nil {
log.Error("download", "Fail to copy to GOPATH:") log.Error("download", "Fail to copy to GOPATH:")
log.Fatal("", "\t"+err.Error()) log.Fatal("", "\t"+err.Error())
} }
log.Log("Package copied to GOPATH: %s", importPath)
} }
// downloadPackages downloads packages with certain commit, // downloadPackages downloads packages with certain commit,
@ -184,91 +197,103 @@ func downloadPackages(ctx *cli.Context, nodes []*doc.Node) {
if n.Type == doc.LOCAL { if n.Type == doc.LOCAL {
continue continue
} }
// Check if it is a valid remote path. // Check if it is a valid remote path or C.
if doc.IsValidRemotePath(n.ImportPath) { if n.ImportPath == "C" {
gopathDir := path.Join(installGopath, n.ImportPath) continue
n.RootPath = doc.GetProjectPath(n.ImportPath) } else if !doc.IsValidRemotePath(n.ImportPath) {
installPath := path.Join(installRepoPath, n.RootPath) + // Invalid import path.
versionSuffix(n.Value) log.Error("download", "Skipped invalid package: "+fmt.Sprintf("%s@%s:%s",
n.ImportPath, n.Type, doc.CheckNodeValue(n.Value)))
if !ctx.Bool("update") { failConut++
// Check if package has been downloaded. continue
if (len(n.Value) == 0 && !ctx.Bool("remote") && com.IsExist(gopathDir)) || }
com.IsExist(installPath) {
log.Trace("Skipped installed package: %s@%s:%s", // Valid import path.
n.ImportPath, n.Type, doc.CheckNodeValue(n.Value)) gopathDir := path.Join(installGopath, n.ImportPath)
n.RootPath = doc.GetProjectPath(n.ImportPath)
if ctx.Bool("gopath") && com.IsExist(installPath) { installPath := path.Join(installRepoPath, n.RootPath) + versionSuffix(n.Value)
copyToGopath(installPath, gopathDir)
log.Log("Package copied to GOPATH: %s", n.ImportPath) if isSubpackage(n.RootPath, ".") {
} continue
continue }
} else {
doc.LocalNodes.SetValue(n.RootPath, "value", "") // Indicates whether need to download package again.
if n.IsFixed() && com.IsExist(installPath) {
n.IsGetDepsOnly = true
}
if !ctx.Bool("update") {
// Check if package has been downloaded.
if (len(n.Value) == 0 && !ctx.Bool("remote") && com.IsExist(gopathDir)) ||
com.IsExist(installPath) {
log.Trace("Skipped installed package: %s@%s:%s",
n.ImportPath, n.Type, doc.CheckNodeValue(n.Value))
// Only copy when no version control.
if ctx.Bool("gopath") && com.IsExist(installPath) ||
len(getVcsName(gopathDir)) == 0 {
copyToGopath(installPath, gopathDir)
} }
continue
} else {
doc.LocalNodes.SetValue(n.RootPath, "value", "")
} }
}
if !downloadCache[n.RootPath] { if downloadCache[n.RootPath] {
// Download package. log.Trace("Skipped downloaded package: %s@%s:%s",
nod, imports := downloadPackage(ctx, n) n.ImportPath, n.Type, doc.CheckNodeValue(n.Value))
if len(imports) > 0 { continue
var gf *goconfig.ConfigFile }
// Check if has gopmfile // Download package.
if com.IsFile(installPath + "/" + doc.GOPM_FILE_NAME) { nod, imports := downloadPackage(ctx, n)
log.Log("Found gopmfile: %s@%s:%s", if len(imports) > 0 {
n.ImportPath, n.Type, doc.CheckNodeValue(n.Value)) var gf *goconfig.ConfigFile
gf = doc.NewGopmfile(installPath) // Check if has gopmfile.
} if com.IsFile(installPath + "/" + doc.GOPM_FILE_NAME) {
log.Log("Found gopmfile: %s@%s:%s",
// Need to download dependencies. n.ImportPath, n.Type, doc.CheckNodeValue(n.Value))
// Generate temporary nodes. gf = doc.NewGopmfile(installPath)
nodes := make([]*doc.Node, len(imports)) }
for i := range nodes {
nodes[i] = doc.NewNode(imports[i], imports[i], doc.BRANCH, "", true) // Need to download dependencies.
// Generate temporary nodes.
if gf == nil { nodes := make([]*doc.Node, len(imports))
continue for i := range nodes {
} nodes[i] = doc.NewNode(imports[i], imports[i], doc.BRANCH, "", true)
// Check if user specified the version. if gf == nil {
if v, err := gf.GetValue("deps", imports[i]); err == nil && continue
len(v) > 0 {
nodes[i].Type, nodes[i].Value = validPath(v)
}
}
downloadPackages(ctx, nodes)
} }
// Only save package information with specific commit. // Check if user specified the version.
if nod != nil { if v, err := gf.GetValue("deps", imports[i]); err == nil && len(v) > 0 {
// Save record in local nodes. nodes[i].Type, nodes[i].Value = validPath(v)
log.Success("SUCC", "GET", fmt.Sprintf("%s@%s:%s",
n.ImportPath, n.Type, doc.CheckNodeValue(n.Value)))
downloadCount++
// Only save non-commit node.
if len(nod.Value) == 0 && len(nod.Revision) > 0 {
doc.LocalNodes.SetValue(nod.RootPath, "value", nod.Revision)
}
if ctx.Bool("gopath") && com.IsExist(installPath) {
copyToGopath(installPath, gopathDir)
log.Log("Package copied to GOPATH: %s", n.ImportPath)
}
} }
} else {
log.Trace("Skipped downloaded package: %s@%s:%s",
n.ImportPath, n.Type, doc.CheckNodeValue(n.Value))
} }
} else if n.ImportPath == "C" { downloadPackages(ctx, nodes)
}
// Only save package information with specific commit.
if nod == nil {
continue continue
} else { }
// Invalid import path.
log.Error("download", "Skipped invalid package: "+fmt.Sprintf("%s@%s:%s", // Save record in local nodes.
n.ImportPath, n.Type, doc.CheckNodeValue(n.Value))) log.Success("SUCC", "GET", fmt.Sprintf("%s@%s:%s",
failConut++ n.ImportPath, n.Type, doc.CheckNodeValue(n.Value)))
downloadCount++
// Only save non-commit node.
if len(nod.Value) == 0 && len(nod.Revision) > 0 {
doc.LocalNodes.SetValue(nod.RootPath, "value", nod.Revision)
}
if ctx.Bool("gopath") && com.IsExist(installPath) && !ctx.Bool("update") &&
len(getVcsName(path.Join(installGopath, nod.RootPath))) == 0 {
copyToGopath(installPath, gopathDir)
} }
} }
} }
@ -280,8 +305,23 @@ func downloadPackage(ctx *cli.Context, nod *doc.Node) (*doc.Node, []string) {
// Mark as donwloaded. // Mark as donwloaded.
downloadCache[nod.RootPath] = true downloadCache[nod.RootPath] = true
nod.Revision = doc.LocalNodes.MustValue(nod.RootPath, "value") // Check if only need to use VCS tools.
imports, err := doc.PureDownload(nod, installRepoPath, ctx) //CmdGet.Flags) var imports []string
var err error
gopathDir := path.Join(installGopath, nod.RootPath)
vcs := getVcsName(gopathDir)
if ctx.Bool("update") && ctx.Bool("gopath") && len(vcs) > 0 {
err = updateByVcs(vcs, gopathDir)
imports = doc.GetAllImports([]string{gopathDir}, nod.RootPath, false)
} else {
// If package has revision and exist, then just check dependencies.
if nod.IsGetDepsOnly {
return nod, doc.GetAllImports([]string{path.Join(installRepoPath, nod.RootPath) + versionSuffix(nod.Value)},
nod.RootPath, ctx.Bool("example"))
}
nod.Revision = doc.LocalNodes.MustValue(nod.RootPath, "value")
imports, err = doc.PureDownload(nod, installRepoPath, ctx) //CmdGet.Flags)
}
if err != nil { if err != nil {
log.Error("get", "Fail to download pakage: "+nod.ImportPath) log.Error("get", "Fail to download pakage: "+nod.ImportPath)
@ -292,3 +332,67 @@ func downloadPackage(ctx *cli.Context, nod *doc.Node) (*doc.Node, []string) {
} }
return nod, imports return nod, imports
} }
func getVcsName(dirPath string) string {
switch {
case com.IsExist(path.Join(dirPath, ".git")):
return "git"
case com.IsExist(path.Join(dirPath, ".hg")):
return "hg"
case com.IsExist(path.Join(dirPath, ".svn")):
return "svn"
}
return ""
}
func updateByVcs(vcs, dirPath string) error {
err := os.Chdir(dirPath)
if err != nil {
log.Error("Update by VCS", "Fail to change work directory:")
log.Fatal("", "\t"+err.Error())
}
defer os.Chdir(workDir)
switch vcs {
case "git":
stdout, _, err := com.ExecCmd("git", "status")
if err != nil {
log.Error("", "Error occurs when 'git status'")
log.Error("", "\t"+err.Error())
}
i := strings.Index(stdout, "\n")
if i == -1 {
log.Error("", "Empty result for 'git status'")
return nil
}
branch := strings.TrimPrefix(stdout[:i], "# On branch ")
_, _, err = com.ExecCmd("git", "pull", "origin", branch)
if err != nil {
log.Error("", "Error occurs when 'git pull origin "+branch+"'")
log.Error("", "\t"+err.Error())
}
case "hg":
_, stderr, err := com.ExecCmd("hg", "pull")
if err != nil {
log.Error("", "Error occurs when 'hg pull'")
log.Error("", "\t"+err.Error())
}
if len(stderr) > 0 {
log.Error("", "Error: "+stderr)
}
_, stderr, err = com.ExecCmd("hg", "up")
if err != nil {
log.Error("", "Error occurs when 'hg up'")
log.Error("", "\t"+err.Error())
}
if len(stderr) > 0 {
log.Error("", "Error: "+stderr)
}
case "svn":
log.Error("", "Error: not support svn yet")
}
return nil
}

2
cmd/gopath.go

@ -101,7 +101,7 @@ func getChildPkgs(ctx *cli.Context, cpath string, ppkg *doc.Pkg, cachePkgs map[s
if pkgName != "" && strings.HasPrefix(pkg.ImportPath, pkgName) { if pkgName != "" && strings.HasPrefix(pkg.ImportPath, pkgName) {
newPath = filepath.Join(curPath, strings.TrimPrefix(pkg.ImportPath, pkgName)) newPath = filepath.Join(curPath, strings.TrimPrefix(pkg.ImportPath, pkgName))
} else { } else {
if !com.IsExist(newPath) { if !com.IsExist(newPath) || ctx.Bool("update") {
node := doc.NewNode(pkg.ImportPath, pkg.ImportPath, node := doc.NewNode(pkg.ImportPath, pkg.ImportPath,
pkg.Type, pkg.Value, true) pkg.Type, pkg.Value, true)
nodes := []*doc.Node{node} nodes := []*doc.Node{node}

18
doc/struct.go

@ -42,6 +42,15 @@ type Pkg struct {
Value string // Branch, tag, commit or local. Value string // Branch, tag, commit or local.
} }
// If the package is fixed and no need to updated.
// For commit, tag and local, it's fixed. For branch
func (pkg *Pkg) IsFixed() bool {
if pkg.Type == BRANCH || len(pkg.Value) == 0 {
return false
}
return true
}
func (pkg *Pkg) VerString() string { func (pkg *Pkg) VerString() string {
if pkg.Value == "" { if pkg.Value == "" {
return pkg.Type return pkg.Type
@ -59,10 +68,11 @@ func NewDefaultPkg(importPath string) *Pkg {
type Node struct { type Node struct {
Pkg Pkg
DownloadURL string DownloadURL string
Synopsis string Synopsis string
IsGetDeps bool IsGetDeps bool
Revision string IsGetDepsOnly bool
Revision string
} }
func NewNode(importPath, downloadUrl, tp, value string, isGetDeps bool) *Node { func NewNode(importPath, downloadUrl, tp, value string, isGetDeps bool) *Node {

7
gopm.go

@ -1,4 +1,4 @@
// Copyright 2013 gopm authors. // Copyright 2013-2014 gopm authors.
// //
// Licensed under the Apache License, Version 2.0 (the "License"): you may // 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 // not use this file except in compliance with the License. You may obtain
@ -12,7 +12,7 @@
// License for the specific language governing permissions and limitations // License for the specific language governing permissions and limitations
// under the License. // under the License.
// gopm(Go Package Manager) is a Go package manage tool for search, install, update and share packages in Go. // gopm(Go Package Manager) is a Go package manage tool for searching, installing, updating and sharing your packages in Go.
package main package main
import ( import (
@ -29,7 +29,7 @@ import (
// Test that go1.1 tag above is included in builds. main.go refers to this definition. // Test that go1.1 tag above is included in builds. main.go refers to this definition.
const go11tag = true const go11tag = true
const APP_VER = "0.6.0.1210" const APP_VER = "0.6.1.0110"
// //cmd.CmdSearch, // //cmd.CmdSearch,
// cmdClean, // cmdClean,
@ -37,7 +37,6 @@ const APP_VER = "0.6.0.1210"
// cmdEnv, // cmdEnv,
// cmdFix, // cmdFix,
// cmdList, // cmdList,
// cmdTest,
// cmdTool, // cmdTool,
// cmdVet, // cmdVet,
// } // }

Loading…
Cancel
Save