github.com/gsquire/gb@v0.4.4-0.20161112235727-3982dc872064/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  }