diff --git a/README.md b/README.md index 54ab15b33..2b95db977 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ USAGE: gopm [global options] command [command options] [arguments...] VERSION: - 0.6.4.0318 + 0.6.5.0320 COMMANDS: get fetch remote package(s) and dependencies to local repository diff --git a/cmd/gen.go b/cmd/gen.go index fe504a9f9..3b31516d4 100644 --- a/cmd/gen.go +++ b/cmd/gen.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 // not use this file except in compliance with the License. You may obtain @@ -58,11 +58,12 @@ func runGen(ctx *cli.Context) { targetPath := parseTarget(gf.MustValue("target", "path")) // Get and set dependencies. - imports := doc.GetAllImports([]string{workDir}, targetPath, ctx.Bool("example")) + imports := doc.GetAllImports([]string{workDir}, targetPath, ctx.Bool("example"), false) for _, p := range imports { p = doc.GetProjectPath(p) // Skip subpackage(s) of current project. - if strings.HasSuffix(workDir, p) || strings.HasPrefix(p, targetPath) { + if strings.HasSuffix(strings.Replace(workDir, "\\", "/", -1), p) || + strings.HasPrefix(p, targetPath) { continue } diff --git a/cmd/get.go b/cmd/get.go index 252d4c3a0..d747502e6 100644 --- a/cmd/get.go +++ b/cmd/get.go @@ -123,7 +123,7 @@ func getByGopmfile(ctx *cli.Context) { targetPath := parseTarget(gf.MustValue("target", "path")) // Get dependencies. - imports := doc.GetAllImports([]string{workDir}, targetPath, ctx.Bool("example")) + imports := doc.GetAllImports([]string{workDir}, targetPath, ctx.Bool("example"), false) nodes := make([]*doc.Node, 0, len(imports)) for _, p := range imports { @@ -316,12 +316,12 @@ func downloadPackage(ctx *cli.Context, nod *doc.Node) (*doc.Node, []string) { 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) + imports = doc.GetAllImports([]string{gopathDir}, nod.RootPath, false, 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.RootPath, ctx.Bool("example"), false) } nod.Revision = doc.LocalNodes.MustValue(nod.RootPath, "value") imports, err = doc.PureDownload(nod, installRepoPath, ctx) //CmdGet.Flags) diff --git a/cmd/gopath.go b/cmd/gopath.go index aac6b7457..1c5c321cb 100644 --- a/cmd/gopath.go +++ b/cmd/gopath.go @@ -1,3 +1,17 @@ +// Copyright 2013-2014 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 cmd import ( @@ -35,7 +49,7 @@ func getGopmPkgs(dirPath string, isTest bool) (pkgs map[string]*doc.Pkg, err err } } - imports := doc.GetAllImports([]string{dirPath}, ".", false) + imports := doc.GetAllImports([]string{dirPath}, ".", false, false) pkgs = make(map[string]*doc.Pkg) for _, name := range imports { if name == "C" { diff --git a/cmd/install.go b/cmd/install.go index f83aff7bb..7d8af31a0 100644 --- a/cmd/install.go +++ b/cmd/install.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 // not use this file except in compliance with the License. You may obtain @@ -83,8 +83,7 @@ func runInstall(ctx *cli.Context) { var installRepos []string if ctx.Bool("pkg") { curPath, _ := filepath.Abs(".") - installRepos = doc.GetAllImports([]string{curPath}, - ".", ctx.Bool("example")) + installRepos = doc.GetAllImports([]string{curPath}, ".", ctx.Bool("example"), false) } else { if len(target) == 0 { target = pkgName diff --git a/doc/utils.go b/doc/utils.go index 98243d8d3..7ff1fc8a1 100644 --- a/doc/utils.go +++ b/doc/utils.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 // not use this file except in compliance with the License. You may obtain @@ -15,11 +15,16 @@ package doc import ( + "bytes" "go/build" + "io" + "io/ioutil" "os" "path" + "path/filepath" "regexp" "strings" + "time" "github.com/Unknwon/com" @@ -49,16 +54,43 @@ func GetDirsInfo(rootPath string) ([]os.FileInfo, error) { return dirs, nil } -// GetImports returns package denpendencies. -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()) - } +// A Source describles a Source code file. +type Source struct { + SrcName string + SrcData []byte +} + +func (s *Source) Name() string { return s.SrcName } +func (s *Source) Size() int64 { return int64(len(s.SrcData)) } +func (s *Source) Mode() os.FileMode { return 0 } +func (s *Source) ModTime() time.Time { return time.Time{} } +func (s *Source) IsDir() bool { return false } +func (s *Source) Sys() interface{} { return nil } +func (s *Source) Data() []byte { return s.SrcData } + +type Context struct { + build.Context + importPath string + srcFiles map[string]*Source +} + +func (ctx *Context) readDir(dir string) ([]os.FileInfo, error) { + fis := make([]os.FileInfo, 0, len(ctx.srcFiles)) + for _, src := range ctx.srcFiles { + fis = append(fis, src) } + return fis, nil +} +func (ctx *Context) openFile(path string) (r io.ReadCloser, err error) { + if src, ok := ctx.srcFiles[filepath.Base(path)]; ok { + return ioutil.NopCloser(bytes.NewReader(src.Data())), nil + } + return nil, os.ErrNotExist +} + +// GetImports returns package denpendencies. +func GetImports(absPath, importPath string, example, test bool) []string { fis, err := GetDirsInfo(absPath) if err != nil { log.Error("", "Fail to get directory's information") @@ -66,23 +98,57 @@ func GetImports(absPath, importPath string, example bool) []string { } absPath += "/" - imports := make([]string, 0, len(pkg.Imports)) - for _, p := range pkg.Imports { - if !IsGoRepoPath(p) && !strings.HasPrefix(p, importPath) { - imports = append(imports, p) - } - } + ctx := new(Context) + ctx.importPath = importPath + ctx.srcFiles = make(map[string]*Source) + ctx.Context = build.Default + ctx.JoinPath = path.Join + ctx.IsAbsPath = path.IsAbs + ctx.ReadDir = ctx.readDir + ctx.OpenFile = ctx.openFile // TODO: Load too much, need to make sure which is imported which are not. - dirs := make([]string, 0, len(imports)) + dirs := make([]string, 0, 10) for _, fi := range fis { - if fi.IsDir() && !strings.Contains(fi.Name(), VENDOR) { + if strings.Contains(fi.Name(), VENDOR) { + continue + } + + if fi.IsDir() { dirs = append(dirs, absPath+fi.Name()) + continue + } else if !test && strings.HasSuffix(fi.Name(), "_test.go") { + continue + } else if !strings.HasSuffix(fi.Name(), ".go") || strings.HasPrefix(fi.Name(), ".") || + strings.HasPrefix(fi.Name(), "_") { + continue + } + src := &Source{SrcName: fi.Name()} + src.SrcData, err = ioutil.ReadFile(absPath + fi.Name()) + if err != nil { + log.Error("", "Fail to read file") + log.Fatal("", err.Error()) + } + ctx.srcFiles[fi.Name()] = src + } + + pkg, err := ctx.ImportDir(absPath, build.AllowBinary) + if err != nil { + if _, ok := err.(*build.NoGoError); !ok { + 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)...) + imports = append(imports, GetAllImports(dirs, importPath, example, test)...) } return imports } @@ -95,11 +161,11 @@ func isVcsPath(dirPath string) bool { } // GetAllImports returns all imports in given directory and all sub-directories. -func GetAllImports(dirs []string, importPath string, example bool) (imports []string) { +func GetAllImports(dirs []string, importPath string, example, test bool) (imports []string) { for _, d := range dirs { if !isVcsPath(d) && !(!example && strings.Contains(d, "example")) { - imports = append(imports, GetImports(d, importPath, example)...) + imports = append(imports, GetImports(d, importPath, example, test)...) } } return imports diff --git a/gopm.go b/gopm.go index 3e6385f00..072f2299b 100644 --- a/gopm.go +++ b/gopm.go @@ -29,9 +29,10 @@ import ( // Test that go1.1 tag above is included in builds. main.go refers to this definition. const go11tag = true -const APP_VER = "0.6.4.0318" +const APP_VER = "0.6.5.0320" -// //cmd.CmdSearch, +// cmd.CmdTest, +// cmd.CmdSearch, // cmdClean, // cmdDoc, // cmdEnv, @@ -39,7 +40,6 @@ const APP_VER = "0.6.4.0318" // cmdList, // cmdTool, // cmdVet, -// } func init() { runtime.GOMAXPROCS(runtime.NumCPU()) @@ -59,7 +59,6 @@ func main() { cmd.CmdInstall, cmd.CmdUpdate, cmd.CmdConfig, - //cmd.CmdTest, } app.Flags = append(app.Flags, []cli.Flag{ cli.BoolFlag{"noterm", "disable color output"},