func main() { args := os.Args[1:] switch { case len(args) < 1, args[0] == "-h", args[0] == "-help": fs.Usage() os.Exit(1) case args[0] == "help": help(args[1:]) return case projectroot == "": gb.Fatalf("don't run this binary directly, it is meant to be run as 'gb vendor ...'") default: } root, err := cmd.FindProjectroot(projectroot) if err != nil { gb.Fatalf("could not locate project root: %v", err) } project := gb.NewProject(root, gb.SourceDir(filepath.Join(root, "src")), gb.SourceDir(filepath.Join(root, "vendor", "src"))) gb.Debugf("project root %q", project.Projectdir()) for _, command := range commands { if command.Name == args[0] && command.Runnable() { // add extra flags if necessary if command.AddFlags != nil { command.AddFlags(fs) } if command.FlagParse != nil { err = command.FlagParse(fs, args) } else { err = fs.Parse(args[1:]) } if err != nil { gb.Fatalf("could not parse flags: %v", err) } args = fs.Args() // reset args to the leftovers from fs.Parse gb.Debugf("args: %v", args) ctx, err := project.NewContext( gb.GcToolchain(), ) if err != nil { gb.Fatalf("unable to construct context: %v", err) } if err := command.Run(ctx, args); err != nil { gb.Fatalf("command %q failed: %v", command.Name, err) } return } } gb.Fatalf("unknown command %q ", args[0]) }
// ResolvePackagesWithTests is similar to ResolvePackages however // it also loads the test and external test packages of args into // the context. func ResolvePackagesWithTests(r Resolver, paths ...string) ([]*gb.Package, error) { var pkgs []*gb.Package for _, path := range paths { path = relImportPath(r.Srcdirs()[0], path) pkg, err := r.ResolvePackageWithTests(path) if err != nil { if _, ok := err.(*build.NoGoError); ok { gb.Debugf("skipping %q", path) continue } return pkgs, fmt.Errorf("failed to resolve package %q: %v", path, err) } pkgs = append(pkgs, pkg) } return pkgs, nil }
// NewContext creates a gb.Context for the project root. func NewContext(projectroot string, options ...func(*gb.Context) error) (*gb.Context, error) { if projectroot == "" { return nil, fmt.Errorf("project root is blank") } root, err := FindProjectroot(projectroot) if err != nil { return nil, fmt.Errorf("could not locate project root: %v", err) } project := gb.NewProject(root, gb.SourceDir(filepath.Join(root, "src")), gb.SourceDir(filepath.Join(root, "vendor", "src")), ) gb.Debugf("project root %q", project.Projectdir()) return project.NewContext(options...) }
// loadTestFuncs returns the testFuncs describing the tests that will be run. func loadTestFuncs(ptest *build.Package) (*testFuncs, error) { t := &testFuncs{ Package: ptest, } gb.Debugf("loadTestFuncs: %v, %v", ptest.TestGoFiles, ptest.XTestGoFiles) for _, file := range ptest.TestGoFiles { if err := t.load(filepath.Join(ptest.Dir, file), "_test", &t.ImportTest, &t.NeedTest); err != nil { return nil, err } } for _, file := range ptest.XTestGoFiles { if err := t.load(filepath.Join(ptest.Dir, file), "_xtest", &t.ImportXtest, &t.NeedXtest); err != nil { return nil, err } } return t, nil }
// RunCommand detects the project root, parses flags and runs the Command. func RunCommand(fs *flag.FlagSet, cmd *Command, projectroot, goroot string, args []string) error { if cmd.AddFlags != nil { cmd.AddFlags(fs) } if err := fs.Parse(args); err != nil { fs.Usage() os.Exit(1) } args = fs.Args() // reset to the remaining arguments ctx, err := NewContext(projectroot, gb.GcToolchain()) if err != nil { return fmt.Errorf("unable to construct context: %v", err) } gb.Debugf("args: %v", args) return cmd.Run(ctx, args) }
func list(ctx *gb.Context, args []string) error { gb.Debugf("list: %v", args) if formatStdin { var formatBuffer bytes.Buffer io.Copy(&formatBuffer, os.Stdin) format = formatBuffer.String() } args = cmd.ImportPaths(ctx, cmd.MustGetwd(), args) pkgs, err := cmd.ResolvePackages(ctx, args...) if err != nil { gb.Fatalf("unable to resolve: %v", err) } if jsonOutput { views := make([]*PackageView, 0, len(pkgs)) for _, pkg := range pkgs { views = append(views, NewPackageView(pkg)) } encoder := json.NewEncoder(os.Stdout) if err := encoder.Encode(views); err != nil { return fmt.Errorf("Error occurred during json encoding: %v", err) } } else { tmpl, err := template.New("list").Parse(format) if err != nil { return fmt.Errorf("unable to parse template %q: %v", format, err) } for _, pkg := range pkgs { if err := tmpl.Execute(os.Stdout, pkg); err != nil { return fmt.Errorf("unable to execute template: %v", err) } fmt.Fprintln(os.Stdout) } } return nil }
increases verbosity, effectively lowering the output level from INFO to DEBUG. -ldflags 'flag list' arguments to pass on each linker invocation. -gcflags 'arg list' arguments to pass on each go tool compile invocation. The list flags accept a space-separated list of strings. To embed spaces in an element in the list, surround it with either single or double quotes. For more about specifying packages, see 'gb help packages'. For more about where packages and binaries are installed, run 'gb help project'.`, Run: func(ctx *gb.Context, args []string) error { // TODO(dfc) run should take a *gb.Context not a *gb.Project t0 := time.Now() ctx.Force = F ctx.SkipInstall = FF defer func() { gb.Debugf("build duration: %v %v", time.Since(t0), ctx.Statistics.String()) }() pkgs, err := cmd.ResolvePackages(ctx, args...) if err != nil { ctx.Destroy() return err } if err := gb.Build(pkgs...); err != nil { ctx.Destroy() return err } return ctx.Destroy() }, AddFlags: addBuildFlags, }
func testPackage(targets map[string]gb.PkgTarget, pkg *gb.Package, flags []string) gb.Target { var gofiles []string gofiles = append(gofiles, pkg.GoFiles...) gofiles = append(gofiles, pkg.TestGoFiles...) var cgofiles []string cgofiles = append(cgofiles, pkg.CgoFiles...) var imports []string imports = append(imports, pkg.Package.Imports...) imports = append(imports, pkg.Package.TestImports...) name := pkg.Name if name == "main" { // rename the main package to its package name for testing. name = filepath.Base(filepath.FromSlash(pkg.ImportPath)) } // internal tests testpkg := gb.NewPackage(pkg.Context, &build.Package{ Name: name, ImportPath: pkg.ImportPath, Dir: pkg.Dir, SrcRoot: pkg.SrcRoot, GoFiles: gofiles, CFiles: pkg.CFiles, CgoFiles: cgofiles, TestGoFiles: pkg.TestGoFiles, // passed directly to buildTestMain XTestGoFiles: pkg.XTestGoFiles, // passed directly to buildTestMain CgoCFLAGS: pkg.CgoCFLAGS, CgoCPPFLAGS: pkg.CgoCPPFLAGS, CgoCXXFLAGS: pkg.CgoCXXFLAGS, CgoLDFLAGS: pkg.CgoLDFLAGS, CgoPkgConfig: pkg.CgoPkgConfig, Imports: imports, }) // build dependencies deps := gb.BuildDependencies(targets, testpkg) testpkg.Scope = "test" testpkg.Stale = true testobj := gb.Compile(testpkg, deps...) // external tests if len(pkg.XTestGoFiles) > 0 { xtestpkg := gb.NewPackage(pkg.Context, &build.Package{ Name: name, ImportPath: pkg.ImportPath + "_test", Dir: pkg.Dir, GoFiles: pkg.XTestGoFiles, Imports: pkg.XTestImports, }) // build external test dependencies deps := gb.BuildDependencies(targets, xtestpkg) xtestpkg.Scope = "test" xtestpkg.Stale = true xtestpkg.ExtraIncludes = filepath.Join(pkg.Workdir(), filepath.FromSlash(pkg.ImportPath), "_test") testobj = gb.Compile(xtestpkg, append(deps, testobj)...) } testmain, err := buildTestMain(testpkg) if err != nil { return gb.ErrTarget{err} } buildmain := gb.Ld(testmain, gb.Compile(testmain, testobj)) cmd := exec.Command(testmain.Binfile()+".test", flags...) cmd.Dir = pkg.Dir // tests run in the original source directory cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr gb.Debugf("scheduling run of %v", cmd.Args) return pkg.Run(cmd, buildmain) }
func main() { args := os.Args if len(args) < 2 || args[1] == "-h" { fs.Usage() os.Exit(1) } name := args[1] if name == "help" { help(args[2:]) return } command, ok := commands[name] if (command != nil && !command.Runnable()) || !ok { if _, err := lookupPlugin(name); err != nil { gb.Errorf("unknown command %q", name) fs.Usage() os.Exit(1) } command = commands["plugin"] } // add extra flags if necessary if command.AddFlags != nil { command.AddFlags(fs) } var err error if command.FlagParse != nil { err = command.FlagParse(fs, args) } else { err = fs.Parse(args[2:]) } if err != nil { gb.Fatalf("could not parse flags: %v", err) } args = fs.Args() // reset args to the leftovers from fs.Parse if command == commands["plugin"] { args = append([]string{name}, args...) } cwd, err := filepath.Abs(cwd) // if cwd was passed in via -R, make sure it is absolute if err != nil { gb.Fatalf("could not make project root absolute: %v", err) } ctx, err := cmd.NewContext( cwd, // project root gb.GcToolchain(), gb.Gcflags(gcflags), gb.Ldflags(ldflags), ) if err != nil { gb.Fatalf("unable to construct context: %v", err) } if command.ParseArgs != nil { args = command.ParseArgs(ctx, ctx.Projectdir(), args) } else { args = cmd.ImportPaths(ctx, ctx.Projectdir(), args) } gb.Debugf("args: %v", args) if err := command.Run(ctx, args); err != nil { gb.Fatalf("command %q failed: %v", name, err) } }