func LoadLocalize() error { if !base.IsFile(LocalizeConfigFile) { os.MkdirAll(path.Dir(LocalizeConfigFile), os.ModePerm) os.Create(LocalizeConfigFile) } data := struct { Domain map[string]*struct { Depth int Download string } }{} if err := gcfg.ReadFileInto(&data, LocalizeConfigFile); err != nil { return err } for domain, config := range data.Domain { if config.Depth <= 0 { config.Depth = 3 } Localizes = append(Localizes, &goconfig.Localize{ Domain: domain, RootDepth: config.Depth, Download: config.Download, }) } return nil }
func runList(ctx *cli.Context) { if err := setup(ctx); err != nil { errors.SetError(err) return } if !setting.HasGOPATHSetting && !base.IsFile(setting.DefaultGopmfile) { log.Warn("Dependency list may contain package itself without GOPATH setting and gopmfile.") } gf, target, err := parseGopmfile(setting.DefaultGopmfile) if err != nil { errors.SetError(err) return } list, err := getDepList(ctx, target, setting.WorkDir, setting.DefaultVendor) if err != nil { errors.SetError(err) return } fmt.Printf("Dependency list(%d):\n", len(list)) for _, name := range list { fmt.Printf("-> %s%s\n", name, verSuffix(gf, name)) } }
// LoadGopmfile loads and returns given gopmfile. func LoadGopmfile(fileName string) (*goconfig.ConfigFile, error) { if !base.IsFile(fileName) { return goconfig.LoadFromData([]byte("")) } gf, err := goconfig.LoadConfigFile(fileName) if err != nil { return nil, fmt.Errorf("Fail to load gopmfile: %v", err) } return gf, nil }
func LoadLocalNodes() (err error) { if !base.IsFile(LocalNodesFile) { os.MkdirAll(path.Dir(LocalNodesFile), os.ModePerm) os.Create(LocalNodesFile) } LocalNodes, err = goconfig.LoadConfigFile(LocalNodesFile) if err != nil { return fmt.Errorf("fail to load localnodes.list: %v", err) } return nil }
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 }
// LoadPkgNameList loads package name pairs. func LoadPkgNameList() error { if !base.IsFile(PkgNameListFile) { return nil } data, err := ioutil.ReadFile(PkgNameListFile) if err != nil { return fmt.Errorf("fail to load package name list: %v", err) } pkgs := strings.Split(string(data), "\n") for i, line := range pkgs { infos := strings.Split(line, "=") if len(infos) != 2 { // Last item might be empty line. if i == len(pkgs)-1 { continue } return fmt.Errorf("fail to parse package name: %v", line) } PackageNameList[strings.TrimSpace(infos[0])] = strings.TrimSpace(infos[1]) } return nil }
func runGen(ctx *cli.Context) { if err := setup(ctx); err != nil { errors.SetError(err) return } gfPath := path.Join(setting.WorkDir, setting.GOPMFILE) if !setting.HasGOPATHSetting && !base.IsFile(gfPath) { log.Warn("Dependency list may contain package itself without GOPATH setting and gopmfile.") } gf, target, err := parseGopmfile(gfPath) if err != nil { errors.SetError(err) return } list, err := getDepList(ctx, target, setting.WorkDir, setting.DefaultVendor) if err != nil { errors.SetError(err) return } for _, name := range list { // Check if user has specified the version. if val := gf.MustValue("deps", name); len(val) == 0 { gf.SetValue("deps", name, "") } } // Check resources. if _, err = gf.GetValue("res", "include"); err != nil { resList := make([]string, 0, len(setting.CommonRes)) for _, res := range setting.CommonRes { if base.IsExist(res) { resList = append(resList, res) } } gf.SetValue("res", "include", strings.Join(resList, "|")) } if err = setting.SaveGopmfile(gf, gfPath); err != nil { errors.SetError(err) return } if ctx.Bool("local") { localGopath := gf.MustValue("project", "local_gopath") if len(localGopath) == 0 { localGopath = "./vendor" gf.SetValue("project", "local_gopath", localGopath) if err = setting.SaveGopmfile(gf, gfPath); err != nil { errors.SetError(err) return } } for _, name := range []string{"src", "pkg", "bin"} { os.MkdirAll(path.Join(localGopath, name), os.ModePerm) } } log.Info("Generate gopmfile successfully!") }
// downloadPackages downloads packages with certain commit, // if the commit is empty string, then it downloads all dependencies, // otherwise, it only downloada package with specific commit only. func downloadPackages(target string, ctx *cli.Context, nodes []*doc.Node) (err error) { for _, n := range nodes { // Check if it is a valid remote path or C. if n.ImportPath == "C" { continue } else if !base.IsValidRemotePath(n.ImportPath) { // Invalid import path. if setting.LibraryMode { errors.AppendError(errors.NewErrInvalidPackage(n.VerString())) } log.Error("Skipped invalid package: " + n.VerString()) failConut++ continue } // Valid import path. if isSubpackage(n.RootPath, target) { continue } // Indicates whether need to download package or update. if n.IsFixed() && n.IsExist() { n.IsGetDepsOnly = true } if downloadCache.Get(n.VerString()) { if !skipCache.Get(n.VerString()) { skipCache.Set(n.VerString()) log.Debug("Skipped downloaded package: %s", n.VerString()) } continue } if !ctx.Bool("update") { // Check if package has been downloaded. if n.IsExist() { if !skipCache.Get(n.VerString()) { skipCache.Set(n.VerString()) log.Info("%s", n.InstallPath) log.Debug("Skipped installed package: %s", n.VerString()) } // Only copy when no version control. if !copyCache.Get(n.VerString()) && (ctx.Bool("gopath") || ctx.Bool("local")) { copyCache.Set(n.VerString()) if err = n.CopyToGopath(); err != nil { return err } } continue } else { setting.LocalNodes.SetValue(n.RootPath, "value", "") } } // Download package. nod, imports, err := downloadPackage(ctx, n) if err != nil { return err } for _, name := range imports { var gf *goconfig.ConfigFile gfPath := path.Join(n.InstallPath, setting.GOPMFILE) // Check if has gopmfile. if base.IsFile(gfPath) { log.Info("Found gopmfile: %s", n.VerString()) var err error gf, _, err = parseGopmfile(gfPath) if err != nil { return fmt.Errorf("fail to parse gopmfile(%s): %v", gfPath, err) } } // Need to download dependencies. // Generate temporary nodes. nodes := make([]*doc.Node, len(imports)) for i := range nodes { nodes[i] = doc.NewNode(name, doc.BRANCH, "", "", !ctx.Bool("download")) if gf == nil { continue } // Check if user specified the version. if v := gf.MustValue("deps", imports[i]); len(v) > 0 { nodes[i].Type, nodes[i].Value, nodes[i].DownloadURL, err = validPkgInfo(v) if err != nil { return err } } } if err = downloadPackages(target, ctx, nodes); err != nil { return err } } // Only save package information with specific commit. if nod == nil { continue } // Save record in local nodes. log.Info("Got %s", n.VerString()) downloadCount++ // Only save non-commit node. if nod.IsEmptyVal() && len(nod.Revision) > 0 { setting.LocalNodes.SetValue(nod.RootPath, "value", nod.Revision) } // If update set downloadPackage will use VSC tools to download the package, // else just download to local repository and copy to GOPATH. if !nod.HasVcs() && !copyCache.Get(n.RootPath) && (ctx.Bool("gopath") || ctx.Bool("local")) { copyCache.Set(n.RootPath) if err = nod.CopyToGopath(); err != nil { return err } } } 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) }