예제 #1
0
파일: list.go 프로젝트: swan-go/gopm
// 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
}
예제 #2
0
파일: utils.go 프로젝트: swan-go/gopm
// ListImports checks and returns a list of imports of given import path and options.
func ListImports(importPath, rootPath, vendorPath, srcPath, tags string, isTest bool) ([]string, error) {
	oldGOPATH := os.Getenv("GOPATH")
	sep := ":"
	if runtime.GOOS == "windows" {
		sep = ";"
	}

	ctxt := build.Default
	ctxt.BuildTags = strings.Split(tags, " ")
	ctxt.GOPATH = vendorPath + sep + oldGOPATH
	if setting.Debug {
		log.Debug("Import/root path: %s : %s", importPath, rootPath)
		log.Debug("Context GOPATH: %s", ctxt.GOPATH)
		log.Debug("Source path: %s", srcPath)
	}
	pkg, err := ctxt.Import(importPath, srcPath, build.AllowBinary)
	if err != nil {
		if _, ok := err.(*build.NoGoError); !ok && importPath != "C" {
			//import "C" is cgo
			return nil, fmt.Errorf("fail to get imports(%s): %v", importPath, err)
		}
		log.Warn("Getting imports: %v", err)
	}

	rawImports := pkg.Imports
	numImports := len(rawImports)
	if isTest {
		rawImports = append(rawImports, pkg.TestImports...)
		numImports = len(rawImports)
	}
	imports := make([]string, 0, numImports)
	for _, name := range rawImports {
		if IsGoRepoPath(name) {
			continue
		} else if strings.HasPrefix(name, rootPath) {
			moreImports, err := ListImports(name, rootPath, vendorPath, srcPath, tags, isTest)
			if err != nil {
				return nil, err
			}
			imports = append(imports, moreImports...)
			continue
		}
		if setting.Debug {
			log.Debug("Found dependency: %s", name)
		}
		imports = append(imports, name)
	}
	return imports, nil
}
예제 #3
0
파일: struct.go 프로젝트: swan-go/gopm
func (n *Node) DownloadByGoGet(ctx *cli.Context, u *url.URL) error {
	baseDir := path.Join(setting.HomeDir, ".gopm/temp/goget")
	os.MkdirAll(baseDir, os.ModePerm)
	defer func() {
		os.RemoveAll(baseDir)
	}()

	oriGopath := os.Getenv("GOPATH")
	os.Setenv("GOPATH", baseDir)
	fmt.Println(baseDir)
	defer func() {
		os.Setenv("GOPATH", oriGopath)
	}()

	log.Debug("RUN 'go get %s'", n.RootPath)
	_, stderr, err := base.ExecCmdDir(baseDir, "go", "get", n.RootPath)
	if err != nil {
		log.Error("Error occurs when 'go get" + n.RootPath + "'")
		log.Error("\t" + stderr)
		return errors.New(stderr)
	}
	tmpPath := path.Join(baseDir, "src", n.RootPath)
	if !n.IsEmptyVal() {
		base.ExecCmdDir(tmpPath, "git", "checkout", n.Value)
		if err != nil {
			log.Error("Error occurs when 'git checkout" + n.Value + "'")
			log.Error("\t" + stderr)
			return errors.New(stderr)
		}
	}
	os.MkdirAll(path.Dir(n.InstallPath), os.ModePerm)
	os.Rename(tmpPath, n.InstallPath)
	return nil
}
예제 #4
0
파일: struct.go 프로젝트: swan-go/gopm
// DownloadGopm downloads remote package from gopm registry.
func (n *Node) DownloadGopm(ctx *cli.Context) error {
	// Custom DownloadURL
	if u, _ := CustomDownloadURL(n.DownloadURL); u != nil {
		switch u.Scheme {
		case "git+ssh", "git+https", "git+http":
			return n.DownloadByGit(ctx, u)
		case "go+get":
			return n.DownloadByGoGet(ctx, u)
		}
	}

	// Localsize repository
	for _, localize := range setting.Localizes {
		if strings.HasPrefix(n.RootPath, localize.Domain) {
			return n.DownloadLocalRepository(ctx, localize)
		}
	}

	// Fetch latest version, check if package has been changed.
	if n.Type == BRANCH && n.IsEmptyVal() {
		resp, err := http.Get(fmt.Sprintf("%s%s?pkgname=%s",
			setting.RegistryUrl, setting.URL_API_REVISION, n.RootPath))
		if err != nil {
			return fmt.Errorf("fail to make request: %v", err)
		}
		if resp.StatusCode != 200 {
			var apiErr ApiError
			if err = json.NewDecoder(resp.Body).Decode(&apiErr); err != nil {
				return fmt.Errorf("fail to decode response JSON: %v", err)
			}
			return errors.New(apiErr.Error)
		}
		var apiResp ApiResponse
		if err = json.NewDecoder(resp.Body).Decode(&apiResp); err != nil {
			return fmt.Errorf("fail to decode response JSON: %v", err)
		}
		if n.Revision == apiResp.Sha {
			log.Info("Package(%s) hasn't been changed", n.RootPath)
			return nil
		}
		n.Revision = apiResp.Sha
	}

	resp, err := http.Get(fmt.Sprintf("%s%s?pkgname=%s&revision=%s",
		setting.RegistryUrl, setting.URL_API_DOWNLOAD, n.RootPath, n.Value))
	if err != nil {
		return fmt.Errorf("fail to make request: %v", err)
	}
	if resp.StatusCode != 200 {
		var apiErr ApiError
		if err = json.NewDecoder(resp.Body).Decode(&apiErr); err != nil {
			return fmt.Errorf("fail to decode response JSON: %v", err)
		}
		return errors.New(apiErr.Error)
	}

	tmpPath := path.Join(setting.HomeDir, ".gopm/temp/archive",
		n.RootPath+"-"+base.ToStr(time.Now().Nanosecond())+".zip")
	defer os.Remove(tmpPath)
	if setting.Debug {
		log.Debug("Temp archive path: %s", tmpPath)
	}

	os.MkdirAll(path.Dir(tmpPath), os.ModePerm)
	fw, err := os.Create(tmpPath)
	if err != nil {
		return err
	}
	if _, err = io.Copy(fw, resp.Body); err != nil {
		return fmt.Errorf("fail to save archive: %v", err)
	}
	fw.Close()

	// Remove old files.
	os.RemoveAll(n.InstallPath)
	os.MkdirAll(path.Dir(n.InstallPath), os.ModePerm)

	var rootDir string
	var extractFn = func(fullName string, fi os.FileInfo) error {
		if len(rootDir) == 0 {
			rootDir = strings.Split(fullName, "/")[0]
		}
		return nil
	}

	if err := zip.ExtractToFunc(tmpPath, path.Dir(n.InstallPath), extractFn); err != nil {
		return fmt.Errorf("fail to extract archive: %v", err)
	} else if err = os.Rename(path.Join(path.Dir(n.InstallPath), rootDir),
		n.InstallPath); err != nil {
		return fmt.Errorf("fail to rename directory: %v", err)
	}
	return nil
}
예제 #5
0
파일: run.go 프로젝트: swan-go/gopm
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
}