// getDepList get list of dependencies in root path format and nature order. func getDepList(ctx *cli.Context, target, pkgPath, vendor string) ([]string, error) { vendorSrc := path.Join(vendor, "src") rootPath := doc.GetRootPath(target) // If work directory is not in GOPATH, then need to setup a vendor path. if !setting.HasGOPATHSetting || !strings.HasPrefix(pkgPath, setting.InstallGopath) { // Make link of self. log.Debug("Linking %s...", rootPath) from := pkgPath to := path.Join(vendorSrc, rootPath) if setting.Debug { log.Debug("Linking from %s to %s", from, to) } if err := autoLink(from, to); err != nil { return nil, err } } imports, err := doc.ListImports(target, rootPath, vendor, pkgPath, ctx.String("tags"), ctx.Bool("test")) if err != nil { return nil, err } list := make([]string, 0, len(imports)) for _, name := range imports { name = doc.GetRootPath(name) if !base.IsSliceContainsStr(list, name) { list = append(list, name) } } sort.Strings(list) return list, nil }
func runTest(ctx *cli.Context) { if err := setup(ctx); err != nil { errors.SetError(err) return } if err := linkVendors(ctx, ""); err != nil { errors.SetError(err) return } log.Info("Testing...") cmdArgs := []string{"go", "test"} if len(ctx.String("tags")) > 0 { cmdArgs = append(cmdArgs, "-tags") cmdArgs = append(cmdArgs, ctx.String("tags")) } cmdArgs = append(cmdArgs, ctx.Args()...) if err := execCmd(setting.DefaultVendor, setting.WorkDir, cmdArgs...); err != nil { errors.SetError(fmt.Errorf("fail to run program: %v", err)) return } log.Info("Command executed successfully!") }
func runInstall(ctx *cli.Context) { if err := setup(ctx); err != nil { errors.SetError(err) return } if err := linkVendors(ctx, ""); err != nil { errors.SetError(err) return } // Get target name. gfPath := path.Join(setting.WorkDir, setting.GOPMFILE) _, target, err := parseGopmfile(gfPath) if err != nil { errors.SetError(fmt.Errorf("fail to parse gopmfile: %v", err)) return } log.Info("Installing...") cmdArgs := []string{"go", "install"} if ctx.Bool("verbose") { cmdArgs = append(cmdArgs, "-v") } if len(ctx.String("tags")) > 0 { cmdArgs = append(cmdArgs, "-tags") cmdArgs = append(cmdArgs, ctx.String("tags")) } cmdArgs = append(cmdArgs, target) if err := execCmd(setting.DefaultVendor, setting.WorkDir, cmdArgs...); err != nil { errors.SetError(fmt.Errorf("fail to run program: %v", err)) return } log.Info("Command executed successfully!") }
func buildBinary(ctx *cli.Context, args ...string) error { _, target, err := parseGopmfile(setting.GOPMFILE) if err != nil { return err } if err := linkVendors(ctx, ""); err != nil { return err } log.Info("Building...") cmdArgs := []string{"go", "build"} cmdArgs = append(cmdArgs, args...) if len(ctx.String("o")) > 0 { cmdArgs = append(cmdArgs, "-o") cmdArgs = append(cmdArgs, ctx.String("o")) } if len(ctx.String("tags")) > 0 { cmdArgs = append(cmdArgs, "-tags") cmdArgs = append(cmdArgs, ctx.String("tags")) } if err := execCmd(setting.DefaultVendor, setting.WorkDir, cmdArgs...); err != nil { return fmt.Errorf("fail to build program: %v", err) } if setting.IsWindowsXP { fName := path.Base(target) binName := fName + ".exe" os.Remove(binName) exePath := path.Join(setting.DefaultVendorSrc, target, binName) if base.IsFile(exePath) { if err := os.Rename(exePath, path.Join(setting.WorkDir, binName)); err != nil { return fmt.Errorf("fail to move binary: %v", err) } } else { log.Warn("No binary generated") } } return nil }
func runBin(ctx *cli.Context) { if err := setup(ctx); err != nil { errors.SetError(err) return } if len(ctx.Args()) != 1 { errors.SetError(fmt.Errorf("Incorrect number of arguments for command: should have 1")) return } // Check if given directory exists if specified. if ctx.IsSet("dir") && !base.IsDir(ctx.String("dir")) { errors.SetError(fmt.Errorf("Indicated path does not exist or not a directory")) return } // Backup exsited .vendor. if base.IsExist(setting.VENDOR) { os.Rename(setting.VENDOR, setting.VENDOR+".bak") defer func() { os.Rename(setting.VENDOR+".bak", setting.VENDOR) }() } // Parse package version. info := ctx.Args().First() pkgPath := info n := doc.NewNode(pkgPath, doc.BRANCH, "", "", true) if i := strings.Index(info, "@"); i > -1 { pkgPath = info[:i] var err error tp, val, dwn, err := validPkgInfo(info[i+1:]) if err != nil { errors.SetError(err) return } n = doc.NewNode(pkgPath, tp, val, dwn, !ctx.Bool("download")) } // Check package name. if !strings.Contains(pkgPath, "/") { tmpPath, err := setting.GetPkgFullPath(pkgPath) if err != nil { errors.SetError(err) return } if tmpPath != pkgPath { n = doc.NewNode(tmpPath, n.Type, n.Value, n.DownloadURL, n.IsGetDeps) } } if err := downloadPackages(".", ctx, []*doc.Node{n}); err != nil { errors.SetError(err) return } // Check if previous steps were successful. if !n.IsExist() { errors.SetError(fmt.Errorf("Download steps weren't successful")) return } tmpVendor := path.Join("vendor", path.Base(n.RootPath)) os.RemoveAll(tmpVendor) os.RemoveAll(setting.VENDOR) defer func() { os.RemoveAll(tmpVendor) os.RemoveAll(setting.VENDOR) }() // FIXME: should use .gopm/temp path. if err := autoLink(n.InstallPath, tmpVendor); err != nil { errors.SetError(fmt.Errorf("Fail to link slef: %v", err)) return } os.Chdir(tmpVendor) oldWorkDir := setting.WorkDir setting.WorkDir = path.Join(setting.WorkDir, tmpVendor) if !setting.Debug { defer func() { os.Chdir(oldWorkDir) os.RemoveAll("vendor") os.RemoveAll(setting.VENDOR) }() } // if err := buildBinary(ctx); err != nil { // errors.SetError(err) // return // } if err := linkVendors(ctx, n.ImportPath); err != nil { errors.SetError(err) return } log.Info("Installing...") cmdArgs := []string{"go", "install"} if ctx.Bool("verbose") { cmdArgs = append(cmdArgs, "-v") } if len(ctx.String("tags")) > 0 { cmdArgs = append(cmdArgs, "-tags") cmdArgs = append(cmdArgs, ctx.String("tags")) } cmdArgs = append(cmdArgs, n.ImportPath) if err := execCmd(setting.DefaultVendor, setting.WorkDir, cmdArgs...); err != nil { errors.SetError(fmt.Errorf("fail to run program: %v", err)) return } gf, _, err := parseGopmfile(setting.GOPMFILE) if err != nil { errors.SetError(err) return } // Because build command moved binary to root path. binName := path.Base(n.ImportPath) binPath := path.Join(setting.DefaultVendor, "bin", path.Base(n.ImportPath)) if runtime.GOOS == "windows" { binName += ".exe" } // Move binary to given directory. movePath := oldWorkDir if ctx.IsSet("dir") { movePath = ctx.String("dir") } else if base.IsGoTool(n.ImportPath) { movePath = path.Join(runtime.GOROOT(), "pkg/tool", runtime.GOOS+"_"+runtime.GOARCH) if !base.IsExist(binPath) { log.Info("Command executed successfully!") fmt.Println("Binary has been built into: " + movePath) return } } if !base.IsFile(binPath) { errors.SetError(fmt.Errorf("Previous steps weren't successful or the project does not contain main package")) return } if base.IsExist(path.Join(movePath, binName)) { if err := os.Remove(path.Join(movePath, binName)); err != nil { log.Warn("Cannot remove binary in work directory: %v", err) } } if err := os.Rename(binPath, movePath+"/"+binName); err != nil { errors.SetError(fmt.Errorf("Fail to move binary: %v", err)) return } os.Chmod(movePath+"/"+binName, os.ModePerm) includes := strings.Split(gf.MustValue("res", "include"), "|") if len(includes) > 0 { log.Info("Copying resources to %s", movePath) for _, include := range includes { if base.IsDir(include) { os.RemoveAll(path.Join(movePath, include)) if err := base.CopyDir(include, filepath.Join(movePath, include)); err != nil { errors.AppendError(errors.NewErrCopyResource(include)) } } } } log.Info("Command executed successfully!") fmt.Println("Binary has been built into: " + movePath) }
func linkVendors(ctx *cli.Context, optTarget string) error { gfPath := path.Join(setting.WorkDir, setting.GOPMFILE) gf, target, err := parseGopmfile(gfPath) if err != nil { return fmt.Errorf("fail to parse gopmfile: %v", err) } if len(optTarget) > 0 { target = optTarget } rootPath := doc.GetRootPath(target) // TODO: local support. // Make link of self. log.Debug("Linking %s...", rootPath) from := setting.WorkDir to := path.Join(setting.DefaultVendorSrc, rootPath) if setting.Debug { log.Debug("Linking from %s to %s", from, to) } if err := autoLink(from, to); err != nil { return fmt.Errorf("fail to link self: %v", err) } // Check and loads dependency packages. log.Debug("Loading dependencies...") imports, err := doc.ListImports(target, rootPath, setting.DefaultVendor, setting.WorkDir, ctx.String("tags"), ctx.Bool("test")) if err != nil { return fmt.Errorf("fail to list imports: %v", err) } stack := make([]*doc.Pkg, len(imports)) for i, name := range imports { name := doc.GetRootPath(name) tp, val, _, err := validPkgInfo(gf.MustValue("deps", name)) if err != nil { return fmt.Errorf("fail to validate package(%s): %v", name, err) } stack[i] = doc.NewPkg(name, tp, val) } // FIXME: at least link once, need a set lastIdx := len(stack) - 1 for lastIdx >= 0 { pkg := stack[lastIdx] linkPath := path.Join(setting.DefaultVendorSrc, pkg.RootPath) if setting.Debug { log.Debug("Import path: %s", pkg.ImportPath) log.Debug("Linking path: %s", linkPath) } if base.IsExist(linkPath) { stack = stack[:lastIdx] lastIdx = len(stack) - 1 continue } if pkg.IsEmptyVal() && setting.HasGOPATHSetting && base.IsExist(path.Join(setting.InstallGopath, pkg.RootPath)) { stack = stack[:lastIdx] lastIdx = len(stack) - 1 continue } venderPath := path.Join(setting.InstallRepoPath, pkg.RootPath+pkg.ValSuffix()) if !base.IsExist(venderPath) && pkg.RootPath != "C" { //import "C" is cgo return fmt.Errorf("package not installed: %s", pkg.RootPath+pkg.VerSuffix()) } log.Debug("Linking %s...", pkg.RootPath+pkg.ValSuffix()) if err := autoLink(venderPath, linkPath); err != nil { return fmt.Errorf("fail to link dependency(%s): %v", pkg.RootPath, err) } stack = stack[:lastIdx] gf, target, err := parseGopmfile(path.Join(linkPath, setting.GOPMFILE)) if err != nil { return fmt.Errorf("fail to parse gopmfile(%s): %v", linkPath, err) } // parseGopmfile only returns right target when parse work directory. target = pkg.RootPath rootPath := target imports, err := doc.ListImports(target, rootPath, setting.DefaultVendor, linkPath, ctx.String("tags"), ctx.Bool("test")) if err != nil { errors.SetError(err) } for _, name := range imports { if name == "C" { continue } name := doc.GetRootPath(name) tp, val, _, err := validPkgInfo(gf.MustValue("deps", name)) if err != nil { return fmt.Errorf("fail to validate package(%s): %v", name, err) } stack = append(stack, doc.NewPkg(name, tp, val)) } lastIdx = len(stack) - 1 } return nil }