Beispiel #1
0
// 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

	if projectroot == "" {
		return fmt.Errorf("project root is blank")
	}

	root, err := FindProjectroot(projectroot)
	if err != nil {
		return fmt.Errorf("could not locate project root: %v", err)
	}
	project := gb.NewProject(root)

	gb.Debugf("project root %q", project.Projectdir())

	ctx, err := project.NewContext(
		gb.GcToolchain(),
	)
	if err != nil {
		return fmt.Errorf("unable to construct context: %v", err)
	}
	gb.Debugf("args: %v", args)
	return cmd.Run(ctx, args)
}
Beispiel #2
0
func main() {
	root, err := cmd.FindProjectroot(projectroot)
	if err != nil {
		gb.Fatalf("could not locate project root: %v", err)
	}
	project := gb.NewProject(root)
	gb.Debugf("project root %q", project.Projectdir())

	args := os.Args[1:]
	if len(args) < 1 || args[0] == "-h" {
		fs.Usage()
		os.Exit(1)
	}

	if args[0] == "help" {
		help(args[1:])
		return
	}

	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])
}
Beispiel #3
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
}
Beispiel #4
0
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
}
Beispiel #5
0
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"]
		args = append([]string{"plugin"}, args...)
	}

	// 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
	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)
	}

	root, err := cmd.FindProjectroot(cwd)
	if err != nil {
		gb.Fatalf("could not locate project root: %v", err)
	}
	project := gb.NewProject(root)

	gb.Debugf("project root %q", project.Projectdir())

	ctx, err := project.NewContext(
		gb.GcToolchain(),
		gb.Ldflags(ldflags),
	)
	if err != nil {
		gb.Fatalf("unable to construct context: %v", err)
	}

	if command.ParseArgs != nil {
		args = command.ParseArgs(ctx, root, args)
	} else {
		args = cmd.ImportPaths(ctx, root, args)
	}

	gb.Debugf("args: %v", args)
	if err := command.Run(ctx, args); err != nil {
		gb.Fatalf("command %q failed: %v", name, err)
	}
}
Beispiel #6
0
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)
}
Beispiel #7
0
	Short:     "test packages",
	Long: `
'gb test' automates testing the packages named by the import paths.

'gb test' recompiles each package along with any files with names matching
the file pattern "*_test.go".

See 'go help test'

`,
	Run: func(ctx *gb.Context, args []string) error {
		t0 := time.Now()
		ctx.Force = F
		ctx.SkipInstall = FF
		defer func() {
			gb.Debugf("test duration: %v %v", time.Since(t0), ctx.Statistics.String())
		}()
		pkgs, err := cmd.ResolvePackagesWithTests(ctx, args...)
		if err != nil {
			return err
		}
		if err := cmd.Test(cmd.TestFlags(tfs), pkgs...); err != nil {
			return err
		}
		return ctx.Destroy()
	},
	AddFlags: addTestFlags,
	FlagParse: func(flags *flag.FlagSet, args []string) error {
		var err error
		args, tfs, err = cmd.TestFlagsExtraParse(args[2:])
		if err != nil {