// Compile returns an Action representing the steps required to compile this package. func Compile(pkg *Package, deps ...*Action) (*Action, error) { var gofiles []string gofiles = append(gofiles, pkg.GoFiles...) // step 1. are there any .c files that we have to run cgo on ? var ofiles []string // additional ofiles to pack if len(pkg.CgoFiles) > 0 { cgoACTION, cgoOFILES, cgoGOFILES, err := cgo(pkg) if err != nil { return nil, err } gofiles = append(gofiles, cgoGOFILES...) ofiles = append(ofiles, cgoOFILES...) deps = append(deps, cgoACTION) } if len(gofiles) == 0 { return nil, fmt.Errorf("compile %q: no go files supplied", pkg.ImportPath) } // step 2. compile all the go files for this package, including pkg.CgoFiles compile := Action{ Name: fmt.Sprintf("compile: %s", pkg.ImportPath), Deps: deps, Run: func() error { return gc(pkg, gofiles) }, } // step 3. are there any .s files to assemble. var assemble []*Action for _, sfile := range pkg.SFiles { sfile := sfile ofile := filepath.Join(pkg.Workdir(), pkg.ImportPath, stripext(sfile)+".6") assemble = append(assemble, &Action{ Name: fmt.Sprintf("asm: %s/%s", pkg.ImportPath, sfile), Run: func() error { t0 := time.Now() err := pkg.tc.Asm(pkg, pkg.Dir, ofile, filepath.Join(pkg.Dir, sfile)) pkg.Record("asm", time.Since(t0)) return err }, // asm depends on compile because compile will generate the local go_asm.h Deps: []*Action{&compile}, }) ofiles = append(ofiles, ofile) } // step 4. add system object files. for _, syso := range pkg.SysoFiles { ofiles = append(ofiles, filepath.Join(pkg.Dir, syso)) } build := &compile // Do we need to pack ? Yes, replace build action with pack. if len(ofiles) > 0 { pack := Action{ Name: fmt.Sprintf("pack: %s", pkg.ImportPath), Deps: []*Action{ &compile, }, Run: func() error { // collect .o files, ofiles always starts with the gc compiled object. // TODO(dfc) objfile(pkg) should already be at the top of this set ofiles = append( []string{objfile(pkg)}, ofiles..., ) // pack t0 := time.Now() err := pkg.tc.Pack(pkg, ofiles...) pkg.Record("pack", time.Since(t0)) return err }, } pack.Deps = append(pack.Deps, assemble...) build = &pack } // should this package be cached if pkg.Install && !pkg.TestScope { build = &Action{ Name: fmt.Sprintf("install: %s", pkg.ImportPath), Deps: []*Action{build}, Run: func() error { return fileutils.Copyfile(installpath(pkg), objfile(pkg)) }, } } // if this is a main package, add a link stage if pkg.isMain() { build = &Action{ Name: fmt.Sprintf("link: %s", pkg.ImportPath), Deps: []*Action{build}, Run: func() error { return link(pkg) }, } } if !pkg.TestScope { // if this package is not compiled in test scope, then // log the name of the package when complete. build.Run = logInfoFn(build.Run, pkg.ImportPath) } return build, nil }
func main() { // setup application returns *settings ... settings := setup() // create new cli app app := cli.NewApp() app.Version = lxb.Version app.Name = "lxb" app.Usage = `Scaffolding, vendoring and task runner for Go projects. Apart from the reserved commands all others are forwarded to the Task Runner.` // action of lxb app.Action = func(c *cli.Context) { // show Help when no args were passed. if len(c.Args()) == 0 { cli.ShowAppHelp(c) return } // only in GOPATH start task runner if !isGoPath(settings) { log.Fatal("Error: Project is not in GOPATH.") } // start the task runner // task passed in arguments startTaskRunner(c.Args()) } // sub commands for lxb app.Commands = []cli.Command{ { Name: "create", Usage: "Create a project in working directory.", Flags: []cli.Flag{ cli.BoolTFlag{ Name: "git", Usage: "git initial commit. --git=false for disable.", }, }, Action: func(c *cli.Context) { // Only in GOPATH create a project if !isGoPath(settings) { log.Fatal("Error: Project is not in GOPATH.") } settings.GitFlag = c.Bool("git") // create new project if err := createNewProject(settings); err != nil { log.Fatal(err) } log.Printf("Project %s has been created.", settings.ProjectName) }, }, { Name: "backup", Usage: "Backup glide.yaml and glide.lock files.", Action: func(c *cli.Context) { // glide.yaml and glide.lock paths srcYaml := filepath.Join(settings.Root, "glide.yaml") srcLock := filepath.Join(settings.Root, "glide.lock") dstYaml := filepath.Join(settings.Root, "glide.yaml.bak") dstLock := filepath.Join(settings.Root, "glide.lock.bak") // check if glide.yaml file exists okYaml, err := utils.PathExists(srcYaml) if err != nil { log.Fatal(err) } // check if glide.lock file exists okLock, err := utils.PathExists(srcLock) if err != nil { log.Fatal(err) } // not found glide.yaml if !okYaml { log.Println("No backup created, can not find glide.yaml file.") return } // create backup from glide.yaml if err := fileutils.Copyfile(dstYaml, srcYaml); err != nil { log.Fatal(err) } // if glide.lock exists save this file if okLock { if err := fileutils.Copyfile(dstLock, srcLock); err != nil { log.Fatal(err) } } log.Println("Backup from glide.yaml and glide.lock successfully created.") }, }, { Name: "restore", Usage: "Restore glide.yaml and glide.lock files and install.", Action: func(c *cli.Context) { // glide.yaml and glide.lock paths srcYaml := filepath.Join(settings.Root, "glide.yaml.bak") srcLock := filepath.Join(settings.Root, "glide.lock.bak") dstYaml := filepath.Join(settings.Root, "glide.yaml") dstLock := filepath.Join(settings.Root, "glide.lock") // check if backup files exists okYaml, err := utils.PathExists(srcYaml) if err != nil { log.Fatal(err) } // check if glide.lock file exists okLock, err := utils.PathExists(srcLock) if err != nil { log.Fatal(err) } // not found backup if !okYaml { log.Println("No backup restored, can not find glide.yaml.bak file.") return } // restore backups log.Println("Restore glide.yaml.bak -> glide.yaml") if err := fileutils.Copyfile(dstYaml, srcYaml); err != nil { log.Fatal(err) } // if glide.lock.bak exists restore this file if okLock { if err := fileutils.Copyfile(dstLock, srcLock); err != nil { log.Fatal(err) } } // install vendors log.Println("Install the vendors.") if err := utils.CmdRun("glide", "install"); err != nil { log.Fatal(err) } // delete old backups log.Println("Delete backup files") if err := os.Remove(srcYaml); err != nil { log.Fatal(err) } // if glide.lock.bak exists delete this file if okLock { if err := os.Remove(srcLock); err != nil { log.Fatal(err) } } log.Println("Restore vendors successfully.") }, }, } app.Run(os.Args) }