github.com/seh/gb@v0.4.4-0.20160724065125-065d2b2b1ba1/package.go (about) 1 package gb 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 "strings" 8 9 "github.com/constabulary/gb/internal/importer" 10 "github.com/pkg/errors" 11 ) 12 13 // Package represents a resolved package from the Project with respect to the Context. 14 type Package struct { 15 *Context 16 *importer.Package 17 TestScope bool 18 ExtraIncludes string // hook for test 19 Stale bool // is the package out of date wrt. its cached copy 20 Imports []*Package 21 } 22 23 // newPackage creates a resolved Package without setting pkg.Stale. 24 func newPackage(ctx *Context, p *importer.Package) (*Package, error) { 25 pkg := &Package{ 26 Context: ctx, 27 Package: p, 28 } 29 for _, i := range p.Imports { 30 dep, ok := ctx.pkgs[i] 31 if !ok { 32 return nil, errors.Errorf("newPackage(%q): could not locate dependant package %q ", p.Name, i) 33 } 34 pkg.Imports = append(pkg.Imports, dep) 35 } 36 return pkg, nil 37 } 38 39 // isMain returns true if this is a command, not being built in test scope, and 40 // not the testmain itself. 41 func (p *Package) isMain() bool { 42 if p.TestScope { 43 return strings.HasSuffix(p.ImportPath, "testmain") 44 } 45 return p.Name == "main" 46 } 47 48 func (p *Package) String() string { 49 return fmt.Sprintf("%v", struct { 50 Name, ImportPath, Dir string 51 }{ 52 p.Name, p.ImportPath, p.Dir, 53 }) 54 } 55 56 // Complete indicates if this is a pure Go package 57 func (p *Package) Complete() bool { 58 // If we're giving the compiler the entire package (no C etc files), tell it that, 59 // so that it can give good error messages about forward declarations. 60 // Exceptions: a few standard packages have forward declarations for 61 // pieces supplied behind-the-scenes by package runtime. 62 extFiles := len(p.CgoFiles) + len(p.CFiles) + len(p.CXXFiles) + len(p.MFiles) + len(p.SFiles) + len(p.SysoFiles) + len(p.SwigFiles) + len(p.SwigCXXFiles) 63 if p.Standard { 64 switch p.ImportPath { 65 case "bytes", "net", "os", "runtime/pprof", "sync", "time": 66 extFiles++ 67 } 68 } 69 return extFiles == 0 70 } 71 72 // Binfile returns the destination of the compiled target of this command. 73 func (pkg *Package) Binfile() string { 74 // TODO(dfc) should have a check for package main, or should be merged in to objfile. 75 target := filepath.Join(pkg.Bindir(), binname(pkg)) 76 if pkg.TestScope { 77 target = filepath.Join(pkg.Workdir(), filepath.FromSlash(pkg.ImportPath), "_test", binname(pkg)) 78 } 79 80 // if this is a cross compile or GOOS/GOARCH are both defined or there are build tags, add ctxString. 81 if pkg.isCrossCompile() || (os.Getenv("GOOS") != "" && os.Getenv("GOARCH") != "") { 82 target += "-" + pkg.ctxString() 83 } else if len(pkg.buildtags) > 0 { 84 target += "-" + strings.Join(pkg.buildtags, "-") 85 } 86 87 if pkg.gotargetos == "windows" { 88 target += ".exe" 89 } 90 return target 91 }