diff --git a/cmd/gen.go b/cmd/gen.go index 013af44ea..90444330c 100644 --- a/cmd/gen.go +++ b/cmd/gen.go @@ -1,6 +1,18 @@ package cmd +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 = gen +} + // scan a directory and gen a gopm file -func gen(dir string) { +func gen(cmd *Command, args []string) { } diff --git a/cmd/get.go b/cmd/get.go index 162507280..9d598910f 100644 --- a/cmd/get.go +++ b/cmd/get.go @@ -1,6 +1,8 @@ package cmd import ( + "archive/zip" + //"errors" "fmt" "io" "net/http" @@ -18,12 +20,6 @@ var CmdGet = &Command{ Get downloads and installs the packages named by the import paths, along with their dependencies. -The -d flag instructs get to stop after downloading the packages; that is, -it instructs get not to install the packages. - -The -fix flag instructs get to run the fix tool on the downloaded packages -before resolving dependencies or building the code. - The -u flag instructs get to use the network to update the named packages and their dependencies. By default, get uses the network to check out missing packages but does not use it to look for updates to existing packages. @@ -39,10 +35,10 @@ retrieves the most recent version of the package. For more about specifying packages, see 'go help packages'. -For more about how 'go get' finds source code to -download, see 'go help remote'. +For more about how 'gopm get' finds source code to +download, see 'gopm help'. -See also: go build, go install, go clean. +See also: gopm build, gopm install, gopm clean. `, } @@ -53,9 +49,23 @@ func init() { CmdGet.Run = runGet } +func isStandalone() bool { + return true +} + func runGet(cmd *Command, args []string) { if len(args) > 0 { - getDirect(args[0], "trunk") + var ver string = TRUNK + if len(args) == 2 { + ver = args[1] + } + pkg := NewPkg(args[0], ver) + if isStandalone() { + getDirect(pkg) + } else { + fmt.Println("Not implemented.") + //getSource(pkgName) + } } } @@ -81,6 +91,7 @@ func fileExists(dir string) bool { } func download(url string, localfile string) error { + fmt.Println("Downloading", url, "...") resp, err := http.Get(url) if err != nil { return err @@ -108,36 +119,96 @@ func download(url string, localfile string) error { return nil } -func getPackage(pkgName string, ver string, url string) error { +/*func extractPkg(pkg *Pkg, update bool) error { + gopath := os.Getenv("GOPATH") + var childDirs []string = strings.Split(pkg.Name, "/") + + if pkg.Ver != TRUNK { + childDirs[len(childDirs)-1] = fmt.Sprintf("%v_%v_%v", childDirs[len(childDirs)-1], pkg.Ver, pkg.VerId) + } + srcDir = path.Join(gopath, childDir...) + + if !update { + if dirExists(srcDir) { + return nil + } + err = os.MkdirAll(localdir, 0777) + if err != nil { + return err + } + } else { + if dirExists(srcDir) { + os.Remove(localdir) + } else { + err = os.MkdirAll(localdir, 0777) + if err != nil { + return err + } + } + } + + // Iterate through the files in the archive, + // printing some of their contents. + for _, f := range r.File { + fmt.Printf("Contents of %s:\n", f.Name) + rc, err := f.Open() + if err != nil { + return err + } + + _, err = io.Copy(os.Stdout, rc) + if err != nil { + return err + } + rc.Close() + } + return nil +}*/ + +func getPackage(pkg *Pkg, url string) error { curUser, err := user.Current() if err != nil { return err } reposDir = strings.Replace(reposDir, "~", curUser.HomeDir, -1) - localdir := path.Join(reposDir, pkgName) + localdir := path.Join(reposDir, pkg.Name) localdir, err = filepath.Abs(localdir) if err != nil { return err } - localfile := path.Join(localdir, "trunk.zip") + urls := strings.Split(url, ".") - return download(url, localfile) -} + localfile := path.Join(localdir, fmt.Sprintf("%v.%v", pkg.VerSimpleString(), urls[len(urls)-1])) -func getDirect(pkgName string, ver string) error { - urlTempl := "https://codeload.%v/zip/master" - //urlTempl := "https://%v/archive/master.zip" - url := fmt.Sprintf(urlTempl, pkgName) + err = download(url, localfile) + if err != nil { + return err + } - return getPackage(pkgName, ver, url) + r, err := zip.OpenReader(localfile) + if err != nil { + return err + } + defer r.Close() + + if pkg.Ver != TRUNK { + return nil + } + + //return extractPkg(pkg) + return nil } -func getFromSource(pkgName string, ver string, source string) error { +func getDirect(pkg *Pkg) error { + return getPackage(pkg, pkg.Source.PkgUrl(pkg.Name, pkg.VerString())) +} + +/*func getFromSource(pkgName string, ver string, source string) error { urlTempl := "https://%v/%v" //urlTempl := "https://%v/archive/master.zip" url := fmt.Sprintf(urlTempl, source, pkgName) return getPackage(pkgName, ver, url) -} +}*/ diff --git a/cmd/repos.go b/cmd/repos.go deleted file mode 100644 index 0ec557b27..000000000 --- a/cmd/repos.go +++ /dev/null @@ -1,11 +0,0 @@ -package cmd - -type Repos interface { - Url(pkgName string, ver string) string -} - -type GithubRepos interface { -} - -type GitLabRepos interface { -} diff --git a/cmd/source.go b/cmd/source.go new file mode 100644 index 000000000..89378c3d1 --- /dev/null +++ b/cmd/source.go @@ -0,0 +1,99 @@ +package cmd + +import ( + //"errors" + "fmt" + "strings" +) + +const ( + TRUNK = "trunk" + TAG = "tag" + BRANCH = "branch" + COMMIT = "commit" +) + +var ( + downloadCache map[string]bool + sources []Source = []Source{ + &GithubSource{}, + } +) + +func getSource(pkgName string) Source { + for _, source := range sources { + if source.HasPkg(pkgName) { + return source + } + } + return nil +} + +type Source interface { + PkgUrl(pkgName string, ver string) string + HasPkg(pkgName string) bool +} + +type Pkg struct { + Source Source + Name string + Ver string + VerId string +} + +func (p *Pkg) VerSimpleString() string { + if p.VerId != "" { + return p.VerId + } + return p.Ver +} + +func (p *Pkg) VerString() string { + if p.VerId == "" { + return p.Ver + } + return fmt.Sprintf("%v:%v", p.Ver, p.VerId) +} + +func NewPkg(pkgName string, ver string) *Pkg { + vers := strings.Split(ver, ":") + if len(vers) > 2 { + return nil + } + + var verId string + if len(vers) == 2 { + verId = vers[1] + } + + return &Pkg{ + getSource(pkgName), pkgName, vers[0], verId, + } +} + +type GithubSource struct { +} + +func (s *GithubSource) PkgUrl(pkgName string, ver string) string { + vers := strings.Split(ver, ":") + var verPath string + switch strings.ToLower(vers[0]) { + case TRUNK: + verPath = "master" + case TAG, COMMIT, BRANCH: + if len(vers) != 2 { + return "" + } + verPath = vers[1] + default: + return "" + } + return fmt.Sprintf("https://%v/archive/%v.zip", pkgName, verPath) +} + +func (s *GithubSource) HasPkg(pkgName string) bool { + return strings.HasPrefix(pkgName, "github.com") +} + +type GitLabSource struct { +} diff --git a/features_CN.md b/features_CN.md new file mode 100644 index 000000000..88b010ac3 --- /dev/null +++ b/features_CN.md @@ -0,0 +1,159 @@ +gopm +==== + +* [总体设计目标](#10) +* [Go包版本说明](#20) +* [各命令的目标和作用](#30) + * [gopm help](#31) + * [gopm sources](#32) + * [gopm list](#33) + * [gopm get](#34) + * [gopm rm](#35) + * [gopm search](#36) + * [gopm doc](#37) + * [gopm serve](#38) + * [gopm sync](#39) + * [gopm import](#40) + * [gopm gen](#41) + * [gopm build](#42) + * [gopm run](#43) + * [gopm test](#44) +* [gopmspec文件格式](#50) + + +#总体设计目标 + +1. 支持go语言的版本管理 +2. 支持文档管理 +3. 支持本地源服务器 +4. 本地源服务器同时支持公共包和私有包 +5. 支持依赖管理 +6. 支持从github, code.google.com, gitLab, 等常见的源码托管服务下载 + + +#Go包版本说明 + +版本分为四种: + +* []: 表示的是当前最新版本即trunk +* branch: 表示的是某个分支 +* tag: 表示的是某个tag +* commit: 表示的是某个reversion + +#配置文件说明 + +默认没有配置文件,当系统第一次启动时检测homedir/.gopm/config,看是否存在,如果不存在则自动创建此配置文件。 +配置文件内容如下: +[sources] +http://gopm.io + +[repos] +~/.gopm/repos + + + +#各命令的目标和作用 + + +###gopm help + +显示当前可用的命令,以下命令中,[]表示可选,{}表示是参数 + + +###gopm sources [add|rm [{url}]] + +* [] 列出当前可用的所有源,默认为http://gopm.io/ +* add url 添加一个源到本地 +* rm url 删除一个源到本地,如果没有任何源,则自己成为一个独立的服务器,类似gopm.io + + +###gopm list [{packagename}[:{version}]] + +* [] 列出所有本地的包 +* packagename 显示指定名称的包的详细信息 + + +###gopm get [-u] [{packagename} [{version}]] [-f {gopmfile}] + +* [] 查找当前目录下的所有.gopmfile文件,根据文件的描述下载所有的包 +* packagename 从源中下载某个包 +* -u packagename 从源中更新某个包 +* -f gopmfile 根据指定的文件来下载包 + + +###gopm rm {packagename}[:{version}] + +去除一个包,如果不加版本标示,则删除该包的所有版本 + + +###gopm search {keyword} + +根据关键词查找包 + + +###gopm doc [-b] {packagename}[:{version}] + +* [] 显示一个包的文档 +* -b 在默认浏览器中显示该包的文档 + + +###gopm serve [-p {port}] + +将本地仓库作为服务对外提供,如果没有-p,则端口为80,如果有,则端口为指定端口,该服务是一个web服务,通过浏览器也可以进行浏览。 + + +###gopm sync [-u] + +[] 如果当前配置了源,则从可用的源中同步所有的包信息和包内容的最新版本到本地仓库; + 如果当前没有配置任何源,则将所有已有的包从源头进行更新 +-u 仅更新本地仓库已经有的包,不包含本地仓库没有的包 + + +###gopm import [{url}|{filepath}] + +将某个地址或者本地的包导入到本地仓库中,url应为可支持的源码托管站点或者gitLab + + +###gopm gen [{gopmfile}] + +扫描当前目录下的go工程,并自动生成一个.gopmspec的文件依赖文档,如果未指定,则文件名为.gopmspec,如果指定了,则为指定的文件名 + + +###gopm build [-u] + +此命令依赖于go build + +1. 如果当前没有.gopmspec文件,则扫描当前的go工程的依赖,自动生成.gopmspec文档 +2. 根据.gopmspec文件自动下载所有需要的包,如果加了-u参数,则同时更新所有的包 +3. 根据.gopmspec文件自动切换gopath中的相关版本 +4. 调用go build对工程进行编译 + + +###gopm run [{gofile}] + +此命令依赖于go run + +调用gopm build在临时文件夹生成可执行文件,并设置程序当前目录为当前目录,并执行 + + +###gopm test + +此命令依赖于go test + +调用gopm build在临时文件夹生成可执行的测试文件,并设置程序当前目录为当前目录,并执行 + + +#gopmspec文件格式 + +.gopmspec文件的格式类似一个ini文件,当前分为两个section。 +build段内的依赖保存的是go build所需要依赖的所有包,一行一个,可用 =, >=等等,如果什么符号都没有,就是取最新版本 + +``` +[build] +xweb +beego = tag:0.1 +xorm >= branch:0.2 + +[test] +testing +``` diff --git a/go11.go b/go11.go deleted file mode 100644 index 4d76df32e..000000000 --- a/go11.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.1 - -package main - -// Test that go1.1 tag above is included in builds. main.go refers to this definition. -const go11tag = true \ No newline at end of file diff --git a/gopm.go b/gopm.go index d8966d61b..ae96d216b 100644 --- a/gopm.go +++ b/gopm.go @@ -23,9 +23,15 @@ import ( "unicode" "unicode/utf8" - "github.com/gpmgo/gopm/cmd" + //"github.com/gpmgo/gopm/cmd" + "./cmd" ) +// +build go1.1 + +// Test that go1.1 tag above is included in builds. main.go refers to this definition. +const go11tag = true + var ( config map[string]interface{} ) @@ -33,14 +39,15 @@ var ( // Commands lists the available commands and help topics. // The order here is the order in which they are printed by 'go help'. var commands = []*cmd.Command{ - /*cmdBuild, + cmd.CmdGet, + /*cmd.CmdGen, + cmdBuild, cmdClean, cmdDoc, cmdEnv, cmdFix, - cmdFmt,*/ - cmd.CmdGet, - /*cmdInstall, + cmdFmt, + cmdInstall, cmdList, cmdRun, cmdTest,