Browse Source

Done get and gen

pull/103/head
Unknown 11 years ago
parent
commit
1c63ab0979
  1. 5
      .gopmfile
  2. 53
      README.md
  3. 1
      cmd/cmd.go
  4. 102
      cmd/gen.go
  5. 59
      cmd/get.go
  6. 93
      doc/conf.go
  7. 40
      doc/gopmfile.go
  8. 38
      doc/utils.go
  9. 5
      gopm.go

5
.gopmfile

@ -2,3 +2,8 @@
path=github.com/gpmgo/gopm
[deps]
github.com/codegangsta/cli=
github.com/Unknwon/com=
github.com/Unknwon/goconfig=
github.com/aybabtme/color=

53
README.md

@ -30,51 +30,26 @@ The executable will be produced under `$GOPATH/bin` in your file system; for glo
- When build program with `gopm build` or `gopm install`, everything just happen in its own GOPATH and do not bother anything you've done.
* Put your Go project on anywhere you want.
# Quick start
1. Show the command help
```
gopm help
```
2. Show gopm version
```
gopm version
```
3. Get a package
```
gopm get github.com/gpmgo/gopm
```
4. Search a package
```
gopm search gopm
```
5. Build a project, the build's arguments are the same as go build. But it will check all the dependencies and dowload them.
# Commands
```
<change to project directory>
gopm build
```
NAME:
gopm - Go Package Manager
6. Run a go file
USAGE:
gopm [global options] command [command options] [arguments...]
```
<change to project directory>
gopm run main.go
```
VERSION:
0.5.2.1109
7. Install
COMMANDS:
get fetch remote package(s) and dependencies to local repository
gen generate a gopmfile according current go project
help, h Shows a list of commands or help for one command
```
<change to project directory>
gopm install
GLOBAL OPTIONS:
--version print the version
--help, -h show help
```

1
cmd/cmd.go

@ -22,7 +22,6 @@ import (
var (
AppPath string
reposDir string = "~/.gopm/repos"
)
// A Command is an implementation of a go command

102
cmd/gen.go

@ -15,93 +15,63 @@
package cmd
import (
"github.com/Unknwon/com"
"go/build"
"os"
"path"
"runtime"
"strings"
)
var CmdGen = &Command{
UsageLine: "gen [.gopmfile]",
Short: "generate a gopmfile according current go project",
Long: `
generate a gopmfile according current go project
`,
}
func init() {
CmdGen.Run = runGen
CmdGen.Flags = map[string]bool{}
}
"github.com/Unknwon/com"
"github.com/Unknwon/goconfig"
"github.com/codegangsta/cli"
func printGenPrompt(flag string) {
}
"github.com/gpmgo/gopm/doc"
"github.com/gpmgo/gopm/log"
)
func isStdPkg(pkgName string) bool {
return com.IsExist(path.Join(path.Join(runtime.GOROOT(), "src/pkg"), pkgName))
}
var CmdGen = cli.Command{
Name: "gen",
Usage: "generate a gopmfile according current go project",
Description: `Command gen gets dependencies and generates a gopmfile
func getPkgs(path string, inludeSys bool) ([]string, error) {
pkg, err := build.ImportDir(path, build.AllowBinary)
if err != nil {
return []string{}, err
}
gopm gen
if inludeSys {
return pkg.Imports, nil
} else {
pkgs := make([]string, 0)
for _, name := range pkg.Imports {
if !isStdPkg(name) {
pkgs = append(pkgs, name)
}
}
return pkgs, nil
}
Make sure you run this command in the root path of a go project.`,
Action: runGen,
Flags: []cli.Flag{
cli.BoolFlag{"example", "download dependencies for example(s)"},
},
}
// scan a directory and gen a gopm file
func runGen(cmd *Command, args []string) {
func runGen(ctx *cli.Context) {
if !com.IsExist(".gopmfile") {
os.Create(".gopmfile")
}
var gopmFile string = ".gopmfile"
if len(args) > 0 {
gopmFile = args[0]
gf, err := goconfig.LoadConfigFile(".gopmfile")
if err != nil {
log.Error("Gen", "Fail to load gopmfile")
log.Fatal("", err.Error())
}
curPath, err := os.Getwd()
if err != nil {
com.ColorLog("[ERRO] %v.\n", err)
return
log.Error("Gen", "Fail to get work directory")
log.Fatal("", err.Error())
}
gopmPath := path.Join(curPath, gopmFile)
// Get dependencies.
imports := doc.GetAllImports([]string{curPath},
gf.MustValue("target", "path"), ctx.Bool("example"))
if com.IsExist(gopmPath) {
com.ColorLog("[WARN] %v already existed.\n", gopmFile)
return
for _, p := range imports {
if _, err := gf.GetValue("deps", doc.GetProjectPath(p)); err != nil {
gf.SetValue("deps", doc.GetProjectPath(p), " ")
}
// search the project and gen gopmfile
pkgs, err := getPkgs(curPath, false)
if err != nil {
com.ColorLog("[ERRO] %v.\n", err)
return
}
f, err := os.OpenFile(gopmPath, os.O_RDWR|os.O_CREATE, 0700)
err = goconfig.SaveConfigFile(gf, ".gopmfile")
if err != nil {
com.ColorLog("[ERRO] %v.\n", err)
return
log.Error("Gen", "Fail to save gopmfile")
log.Fatal("", err.Error())
}
defer f.Close()
contents := "[build]\n" + strings.Join(pkgs, "\n")
_, err = f.WriteString(contents)
if err != nil {
com.ColorLog("[ERRO] %v.\n", err)
return
}
com.ColorLog("[INFO] %v generated successfully.\n", gopmFile)
log.Success("SUCC", "Gen", "Generate gopmfile successful!")
}

59
cmd/get.go

@ -22,6 +22,7 @@ import (
"strings"
"github.com/Unknwon/com"
"github.com/Unknwon/goconfig"
"github.com/codegangsta/cli"
"github.com/gpmgo/gopm/doc"
@ -66,7 +67,10 @@ func runGet(ctx *cli.Context) {
log.Fatal("", err.Error())
}
installRepoPath = strings.Replace(reposDir, "~", hd, -1)
doc.HomeDir = strings.Replace(doc.HomeDir, "~", hd, -1)
doc.LoadPkgNameList(doc.HomeDir + "/data/pkgname.list")
installRepoPath = doc.HomeDir + "/repos"
log.Log("Local repository path: %s", installRepoPath)
// Check number of arguments.
@ -102,7 +106,7 @@ func getByGopmfile(ctx *cli.Context) {
node := doc.NewNode(p, p, doc.BRANCH, "", true)
// Check if user specified the version.
if v, err := gf.GetValue("deps", p); err == nil {
if v, err := gf.GetValue("deps", p); err == nil && len(v) > 0 {
tp, ver, err := validPath(v)
if err != nil {
log.Error("", "Fail to parse version")
@ -116,6 +120,13 @@ func getByGopmfile(ctx *cli.Context) {
downloadPackages(ctx, nodes)
if doc.LocalNodes != nil {
if err := goconfig.SaveConfigFile(doc.LocalNodes,
doc.HomeDir+doc.LocalNodesFile); err != nil {
log.Error("Get", "Fail to save localnodes.list")
}
}
log.Log("%d package(s) downloaded, %d failed",
downloadCount, failConut)
}
@ -151,6 +162,13 @@ func getByPath(ctx *cli.Context) {
downloadPackages(ctx, nodes)
if doc.LocalNodes != nil {
if err := goconfig.SaveConfigFile(doc.LocalNodes,
doc.HomeDir+doc.LocalNodesFile); err != nil {
log.Error("Get", "Fail to save localnodes.list")
}
}
log.Log("%d package(s) downloaded, %d failed",
downloadCount, failConut)
}
@ -163,12 +181,13 @@ func downloadPackages(ctx *cli.Context, nodes []*doc.Node) {
for _, n := range nodes {
// Check if it is a valid remote path.
if doc.IsValidRemotePath(n.ImportPath) {
if !ctx.Bool("force") {
// Check if package has been downloaded.
installPath := installRepoPath + "/" + doc.GetProjectPath(n.ImportPath)
if len(n.Value) > 0 {
installPath += "." + n.Value
}
if !ctx.Bool("force") {
// Check if package has been downloaded.
if com.IsExist(installPath) {
log.Trace("Skipped installed package: %s@%s:%s",
n.ImportPath, n.Type, doc.CheckNodeValue(n.Value))
@ -180,13 +199,37 @@ func downloadPackages(ctx *cli.Context, nodes []*doc.Node) {
// Download package.
nod, imports := downloadPackage(n)
if len(imports) > 0 {
// TODO: 检查是否有 gopmfile
var gf *goconfig.ConfigFile
// Check if has gopmfile
if com.IsFile(installPath + "/.gopmfile") {
log.Log("Found gopmgile: %s@%s:%s",
n.ImportPath, n.Type, doc.CheckNodeValue(n.Value))
gf = doc.NewGopmfile(installPath + "/.gopmfile")
}
// Need to download dependencies.
// Generate temporary nodes.
nodes := make([]*doc.Node, len(imports))
for i := range nodes {
nodes[i] = doc.NewNode(imports[i], imports[i], doc.BRANCH, "", true)
if gf == nil {
continue
}
// Check if user specified the version.
if v, err := gf.GetValue("deps", imports[i]); err == nil &&
len(v) > 0 {
tp, ver, err := validPath(v)
if err != nil {
log.Error("Download", "Fail to parse version")
log.Fatal("", err.Error())
}
nodes[i].Type = tp
nodes[i].Value = ver
}
}
downloadPackages(ctx, nodes)
}
@ -198,8 +241,10 @@ func downloadPackages(ctx *cli.Context, nodes []*doc.Node) {
n.ImportPath, n.Type, doc.CheckNodeValue(n.Value)))
downloadCount++
// TODO: 保存包信息
//saveNode(nod)
// Only save non-commit node.
if len(nod.Value) == 0 {
doc.SaveNode(nod)
}
}
} else {
log.Trace("Skipped downloaded package: %s@%s:%s",

93
doc/conf.go

@ -0,0 +1,93 @@
// Copyright 2013 gopm authors.
//
// 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 (
"os"
"strings"
"github.com/Unknwon/com"
"github.com/Unknwon/goconfig"
"github.com/gpmgo/gopm/log"
)
const (
GopmFileName = ".gopmfile"
)
var (
HomeDir = "~/.gopm"
LocalNodesFile = "/data/localnodes.list"
LocalNodes *goconfig.ConfigFile
)
func NewGopmfile(dirPath string) *goconfig.ConfigFile {
gf, err := goconfig.LoadConfigFile(dirPath + "/" + GopmFileName)
if err != nil {
log.Error("", "Fail to load gopmfile")
log.Fatal("", err.Error())
}
return gf
}
var PackageNameList map[string]string
func LoadPkgNameList(filePath string) {
PackageNameList = make(map[string]string)
// If file does not exist, simply ignore.
if !com.IsFile(filePath) {
return
}
data, err := com.ReadFile(filePath)
if err != nil {
log.Error("Package name list", "Fail to read file")
log.Fatal("", err.Error())
}
pkgs := strings.Split(string(data), "\n")
for _, line := range pkgs {
infos := strings.Split(line, "=")
if len(infos) != 2 {
log.Error("", "Fail to parse package name: "+line)
log.Fatal("", "Invalid package name information")
}
PackageNameList[strings.TrimSpace(infos[0])] =
strings.TrimSpace(infos[1])
}
}
func SaveNode(nod *Node) {
if LocalNodes == nil {
if !com.IsDir(HomeDir + "/data") {
os.Mkdir(HomeDir+"/data", os.ModePerm)
}
if !com.IsFile(HomeDir + LocalNodesFile) {
os.Create(HomeDir + LocalNodesFile)
}
var err error
LocalNodes, err = goconfig.LoadConfigFile(HomeDir + LocalNodesFile)
if err != nil {
log.Error("Save node", "Fail to load localnodes.list")
log.Fatal("", err.Error())
}
}
LocalNodes.SetValue(nod.ImportPath, "value", nod.Value)
}

40
doc/gopmfile.go

@ -1,40 +0,0 @@
// Copyright 2013 gopm authors.
//
// 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 (
"github.com/Unknwon/goconfig"
"github.com/gpmgo/gopm/log"
)
const (
GopmFileName = ".gopmfile"
)
func NewGopmfile(dirPath string) *goconfig.ConfigFile {
gf, err := goconfig.LoadConfigFile(dirPath + "/" + GopmFileName)
if err != nil {
log.Error("", "Fail to load gopmfile")
log.Fatal("", err.Error())
}
return gf
}
var PackageNameList map[string]string
func init() {
PackageNameList = make(map[string]string)
}

38
doc/utils.go

@ -15,6 +15,7 @@
package doc
import (
"go/build"
"os"
"path"
"regexp"
@ -44,42 +45,31 @@ func GetDirsInfo(rootPath string) []os.FileInfo {
}
// GetImports returns package denpendencies.
func GetImports(absPath, importPath string, example bool) (imports []string) {
func GetImports(absPath, importPath string, example bool) []string {
pkg, err := build.ImportDir(absPath, build.AllowBinary)
if err != nil {
if _, ok := err.(*build.NoGoError); !ok {
log.Error("", "Fail to get imports")
log.Fatal("", err.Error())
}
}
fis := GetDirsInfo(absPath)
absPath += "/"
dirs := make([]string, 0)
files := make([]*source, 0, 10)
for _, fi := range fis {
if fi.IsDir() {
dirs = append(dirs, absPath+fi.Name())
continue
}
if strings.HasSuffix(fi.Name(), ".go") {
data, err := com.ReadFile(absPath + fi.Name())
if err != nil {
log.Error("", "Fail to read file")
log.Fatal("", err.Error())
}
files = append(files, &source{
name: fi.Name(),
data: data,
})
}
}
var err error
if len(files) > 0 {
w := &walker{ImportPath: importPath}
imports, err = w.build(files, nil)
if err != nil {
log.Error("", "Fail to get imports")
log.Fatal("", err.Error())
imports := make([]string, 0, len(pkg.Imports))
for _, p := range pkg.Imports {
if !IsGoRepoPath(p) && !strings.HasPrefix(p, importPath) {
imports = append(imports, p)
}
}
if len(dirs) > 0 {
imports = append(imports, GetAllImports(dirs, importPath, example)...)
}

5
gopm.go

@ -19,7 +19,6 @@ import (
"os"
"runtime"
//"github.com/Unknwon/com"
"github.com/codegangsta/cli"
"github.com/gpmgo/gopm/cmd"
@ -30,10 +29,9 @@ import (
// Test that go1.1 tag above is included in builds. main.go refers to this definition.
const go11tag = true
const APP_VER = "0.5.1.1108"
const APP_VER = "0.5.3.1109"
// //cmd.CmdSearch,
// cmd.CmdGen,
// cmd.CmdRun,
// cmd.CmdBuild,
// cmd.CmdInstall,
@ -59,6 +57,7 @@ func main() {
app.Version = APP_VER
app.Commands = []cli.Command{
cmd.CmdGet,
cmd.CmdGen,
}
app.Run(os.Args)
}

Loading…
Cancel
Save