Пример #1
0
func buildBinary(ctx *cli.Context, args ...string) {
	genNewGoPath(ctx, false)

	log.Trace("Building...")

	cmdArgs := []string{"go", "build"}
	cmdArgs = append(cmdArgs, args...)
	err := execCmd(newGoPath, newCurPath, cmdArgs...)
	if err != nil {
		log.Error("build", "fail to build program:")
		log.Fatal("", "\t"+err.Error())
	}

	if isWindowsXP {
		fName := path.Base(pkgName)
		binName := fName + ".exe"
		os.Remove(binName)
		exePath := filepath.Join(curPath, doc.VENDOR, "src", pkgName, binName)
		if com.IsFile(exePath) {
			err = os.Rename(exePath, filepath.Join(curPath, binName))
			if err != nil {
				log.Error("build", "fail to move binary:")
				log.Fatal("", "\t"+err.Error())
			}
		} else {
			log.Warn("No binary generated")
		}
	}
}
Пример #2
0
func copyToGopath(srcPath, destPath string) {
	importPath := strings.TrimPrefix(destPath, installGopath+"/")
	if len(getVcsName(destPath)) > 0 {
		log.Warn("Package in GOPATH has version control: %s", importPath)
		return
	}

	os.RemoveAll(destPath)
	err := com.CopyDir(srcPath, destPath)
	if err != nil {
		log.Error("download", "Fail to copy to GOPATH:")
		log.Fatal("", "\t"+err.Error())
	}

	log.Log("Package copied to GOPATH: %s", importPath)
}
Пример #3
0
func runGet(ctx *cli.Context) {
	setup(ctx)

	// Check conflicts.
	if ctx.Bool("gopath") && ctx.Bool("remote") {
		log.Error("get", "Command options have conflicts")
		log.Error("", "Following options are not supposed to use at same time:")
		log.Error("", "\t'--gopath, -g' '--remote, -r'")
		log.Help("Try 'gopm help get' to get more information")
	}

	if !ctx.Bool("remote") {
		// Get GOPATH.
		installGopath = com.GetGOPATHs()[0]
		if com.IsDir(installGopath) {
			isHasGopath = true
			log.Log("Indicated GOPATH: %s", installGopath)
			installGopath += "/src"
		} else {
			if ctx.Bool("gopath") {
				log.Error("get", "Invalid GOPATH path")
				log.Error("", "GOPATH does not exist or is not a directory:")
				log.Error("", "\t"+installGopath)
				log.Help("Try 'go help gopath' to get more information")
			} else {
				// It's OK that no GOPATH setting
				// when user does not specify to use.
				log.Warn("No GOPATH setting available")
			}
		}
	}

	// The gopm local repository.
	installRepoPath = doc.HomeDir + "/repos"
	log.Log("Local repository path: %s", installRepoPath)

	// Check number of arguments to decide which function to call.
	switch len(ctx.Args()) {
	case 0:
		getByGopmfile(ctx)
	default:
		getByPath(ctx)
	}
}
Пример #4
0
// GetDirsInfo returns os.FileInfo of all sub-directories in root path.
func GetDirsInfo(rootPath string) ([]os.FileInfo, error) {
	if !com.IsDir(rootPath) {
		log.Warn("Directory %s does not exist", rootPath)
		return []os.FileInfo{}, nil
	}

	rootDir, err := os.Open(rootPath)
	if err != nil {
		return nil, err
	}
	defer rootDir.Close()

	dirs, err := rootDir.Readdir(0)
	if err != nil {
		return nil, err
	}

	return dirs, nil
}
Пример #5
0
// getGithubDoc downloads tarball from github.com.
func getGithubDoc(client *http.Client, match map[string]string, installRepoPath string, nod *Node, ctx *cli.Context) ([]string, error) {
	match["cred"] = GetGithubCredentials()

	// Check downlaod type.
	switch nod.Type {
	case BRANCH:
		if len(nod.Value) == 0 {
			match["sha"] = MASTER

			// Only get and check revision with the latest version.
			var refs []*struct {
				Ref    string
				Url    string
				Object struct {
					Sha  string
					Type string
					Url  string
				}
			}

			err := com.HttpGetJSON(client, com.Expand("https://api.github.com/repos/{owner}/{repo}/git/refs?{cred}", match), &refs)
			if err != nil {
				if strings.Contains(err.Error(), "403") {
					break
				}
				log.Warn("GET", "Fail to get revision")
				log.Warn("", err.Error())
				break
			}

			var etag string
		COMMIT_LOOP:
			for _, ref := range refs {
				switch {
				case strings.HasPrefix(ref.Ref, "refs/heads/master"):
					etag = ref.Object.Sha
					break COMMIT_LOOP
				}
			}
			if etag == nod.Revision {
				log.Log("GET Package hasn't changed: %s", nod.ImportPath)
				return nil, nil
			}
			nod.Revision = etag

		} else {
			match["sha"] = nod.Value
		}
	case TAG, COMMIT:
		match["sha"] = nod.Value
	default:
		return nil, errors.New("Unknown node type: " + nod.Type)
	}

	// We use .zip here.
	// zip: https://github.com/{owner}/{repo}/archive/{sha}.zip
	// tarball: https://github.com/{owner}/{repo}/tarball/{sha}

	// Downlaod archive.
	p, err := com.HttpGetBytes(client, com.Expand("https://github.com/{owner}/{repo}/archive/{sha}.zip", match), nil)
	if err != nil {
		return nil, errors.New("Fail to donwload Github repo -> " + err.Error())
	}

	shaName := com.Expand("{repo}-{sha}", match)
	if nod.Type == "tag" {
		shaName = strings.Replace(shaName, "-v", "-", 1)
	}

	var installPath string
	if nod.ImportPath == nod.DownloadURL {
		suf := "." + nod.Value
		if len(suf) == 1 {
			suf = ""
		}
		projectPath := com.Expand("github.com/{owner}/{repo}", match)
		installPath = installRepoPath + "/" + projectPath + suf
		nod.ImportPath = projectPath
	} else {
		installPath = installRepoPath + "/" + nod.ImportPath
	}

	// Remove old files.
	os.RemoveAll(installPath + "/")
	os.MkdirAll(installPath+"/", os.ModePerm)

	r, err := zip.NewReader(bytes.NewReader(p), int64(len(p)))
	if err != nil {
		return nil, errors.New(nod.ImportPath + " -> new zip: " + err.Error())
	}

	dirs := make([]string, 0, 5)
	// Need to add root path because we cannot get from tarball.
	dirs = append(dirs, installPath+"/")
	for _, f := range r.File {
		absPath := strings.Replace(f.Name, shaName, installPath, 1)
		// Create diretory before create file.
		os.MkdirAll(path.Dir(absPath)+"/", os.ModePerm)

	compareDir:
		switch {
		case strings.HasSuffix(absPath, "/"): // Directory.
			// Check if current directory is example.
			if !(!ctx.Bool("example") && strings.Contains(absPath, "example")) {
				for _, d := range dirs {
					if d == absPath {
						break compareDir
					}
				}
				dirs = append(dirs, absPath)
			}
		default:
			// Get file from archive.
			r, err := f.Open()
			if err != nil {
				return nil, err
			}

			fbytes := make([]byte, f.FileInfo().Size())
			_, err = io.ReadFull(r, fbytes)
			if err != nil {
				return nil, err
			}

			if err = com.WriteFile(absPath, fbytes); err != nil {
				return nil, err
			}

			// Set modify time.
			os.Chtimes(absPath, f.ModTime(), f.ModTime())
		}
	}

	var imports []string

	// Check if need to check imports.
	if nod.IsGetDeps {
		for _, d := range dirs {
			importPkgs, err := CheckImports(d, match["importPath"], nod)
			if err != nil {
				return nil, err
			}
			imports = append(imports, importPkgs...)
		}
	}
	return imports, err
}
Пример #6
0
func runInstall(ctx *cli.Context) {
	setup(ctx)

	var target string
	switch len(ctx.Args()) {
	case 0:
		if !com.IsFile(".gopmfile") {
			break
		}

		gf := doc.NewGopmfile(".")
		target = gf.MustValue("target", "path")
	case 1:
		target = ctx.Args()[0]
	default:
		log.Fatal("install", "Too many arguments")
	}

	// Get GOPATH.
	installGopath = com.GetGOPATHs()[0]
	if com.IsDir(installGopath) {
		isHasGopath = true
		log.Log("Indicated GOPATH: %s", installGopath)
		installGopath += "/src"
	} else {
		if ctx.Bool("gopath") {
			log.Error("get", "Invalid GOPATH path")
			log.Error("", "GOPATH does not exist or is not a directory:")
			log.Error("", "\t"+installGopath)
			log.Help("Try 'go help gopath' to get more information")
		} else {
			// It's OK that no GOPATH setting
			// when user does not specify to use.
			log.Warn("No GOPATH setting available")
		}
	}

	genNewGoPath(ctx, false)

	var installRepos []string
	if ctx.Bool("pkg") {
		curPath, _ := filepath.Abs(".")
		installRepos = doc.GetAllImports([]string{curPath},
			".", ctx.Bool("example"))
	} else {
		if len(target) == 0 {
			target = pkgName
		}

		installRepos = []string{target}
	}

	log.Trace("Installing...")

	for _, repo := range installRepos {
		cmdArgs := []string{"go", "install"}

		if ctx.Bool("verbose") {
			cmdArgs = append(cmdArgs, "-v")
		}
		cmdArgs = append(cmdArgs, repo)
		err := execCmd(newGoPath, newCurPath, cmdArgs...)
		if err != nil {
			log.Error("install", "Fail to install program:")
			log.Fatal("", "\t"+err.Error())
		}
	}

	log.Success("SUCC", "install", "Command executed successfully!")
}
Пример #7
0
func runBin(ctx *cli.Context) {
	setup(ctx)

	if len(ctx.Args()) == 0 {
		log.Error("bin", "Cannot start command:")
		log.Fatal("", "\tNo package specified")
	}

	installRepoPath = doc.HomeDir + "/repos"
	log.Log("Local repository path: %s", installRepoPath)

	// Check arguments.
	num := 1
	if ctx.Bool("dir") {
		num = 2
	}
	if len(ctx.Args()) != num {
		log.Error("bin", "Cannot start command:")
		log.Fatal("", "\tMissing indicated path to build binary")
	}

	// Check if given directory exists.
	if ctx.Bool("dir") && !com.IsDir(ctx.Args()[1]) {
		log.Error("bin", "Cannot start command:")
		log.Fatal("", "\tIndicated path does not exist or is not a directory")
	}

	// Parse package version.
	info := ctx.Args()[0]
	pkgPath := info
	node := doc.NewNode(pkgPath, pkgPath, doc.BRANCH, "", true)
	var err error
	if i := strings.Index(info, "@"); i > -1 {
		pkgPath = info[:i]
		node.ImportPath = pkgPath
		node.DownloadURL = pkgPath
		node.Type, node.Value = validPath(info[i+1:])
	}

	// Check package name.
	if !strings.Contains(pkgPath, "/") {
		pkgPath = doc.GetPkgFullPath(pkgPath)
	}

	// Get code.
	downloadPackages(ctx, []*doc.Node{node})

	// Check if previous steps were successful.
	repoPath := installRepoPath + "/" + pkgPath + versionSuffix(node.Value)
	if !com.IsDir(repoPath) {
		log.Error("bin", "Cannot continue command:")
		log.Fatal("", "\tPrevious steps weren't successful")
	}

	wd, err := os.Getwd()
	if err != nil {
		log.Error("bin", "Cannot get work directory:")
		log.Fatal("", "\t"+err.Error())
	}

	// Change to repository path.
	log.Log("Changing work directory to %s", repoPath)
	if err = os.Chdir(repoPath); err != nil {
		log.Error("bin", "Fail to change work directory:")
		log.Fatal("", "\t"+err.Error())
	}

	// Build application.
	buildBinary(ctx)
	defer func() {
		// Clean files.
		os.RemoveAll(path.Join(repoPath, doc.VENDOR))
	}()

	includes := make([]string, 0, 3)
	// Check if previous steps were successful.
	if com.IsFile(doc.GOPM_FILE_NAME) {
		log.Trace("Loading gopmfile...")
		gf := doc.NewGopmfile(".")

		var err error
		pkgName, err = gf.GetValue("target", "path")
		if err == nil {
			log.Log("Target name: %s", pkgName)
		}

		includes = strings.Split(gf.MustValue("res", "include"), "|")
	}

	if len(pkgName) == 0 {
		_, pkgName = filepath.Split(pkgPath)
	}

	// Because build command moved binary to root path.
	binName := path.Base(pkgName)
	if runtime.GOOS == "windows" {
		binName += ".exe"
	}
	if !com.IsFile(binName) {
		log.Error("bin", "Binary does not exist:")
		log.Error("", "\t"+binName)
		log.Fatal("", "\tPrevious steps weren't successful or the project does not contain main package")
	}

	// Move binary to given directory.
	movePath := wd
	if ctx.Bool("dir") {
		movePath = ctx.Args()[1]
	}

	if com.IsExist(movePath + "/" + binName) {
		if err = os.Remove(movePath + "/" + binName); err != nil {
			log.Warn("Cannot remove binary in work directory:")
			log.Warn("\t %s", err)
		}
	}

	if err = os.Rename(binName, movePath+"/"+binName); err != nil {
		log.Error("bin", "Fail to move binary:")
		log.Fatal("", "\t"+err.Error())
	}
	os.Chmod(movePath+"/"+binName, os.ModePerm)

	if len(includes) > 0 {
		log.Log("Copying resources to %s", movePath)
		for _, include := range includes {
			if com.IsDir(include) {
				if err = com.CopyDir(include, filepath.Join(movePath, include)); err != nil {
					log.Error("bin", "Fail to copy following resource:")
					log.Error("", "\t"+include)
				}
			}
		}
	}

	log.Log("Changing work directory back to %s", wd)
	os.Chdir(wd)

	log.Success("SUCC", "bin", "Command executed successfully!")
	fmt.Println("Binary has been built into: " + movePath)
}
Пример #8
0
// build gets imports from source files.
func (w *walker) build(srcs []*source, nod *Node) ([]string, error) {
	// Add source files to walker, I skipped references here.
	w.srcs = make(map[string]*source)
	for _, src := range srcs {
		w.srcs[src.name] = src
	}

	w.fset = token.NewFileSet()

	// Find the package and associated files.
	ctxt := build.Context{
		GOOS:          runtime.GOOS,
		GOARCH:        runtime.GOARCH,
		CgoEnabled:    true,
		JoinPath:      path.Join,
		IsAbsPath:     path.IsAbs,
		SplitPathList: func(list string) []string { return strings.Split(list, ":") },
		IsDir:         func(path string) bool { panic("unexpected") },
		HasSubdir:     func(root, dir string) (rel string, ok bool) { panic("unexpected") },
		ReadDir:       func(dir string) (fi []os.FileInfo, err error) { return w.readDir(dir) },
		OpenFile:      func(path string) (r io.ReadCloser, err error) { return w.openFile(path) },
		Compiler:      "gc",
	}

	bpkg, err := ctxt.ImportDir(w.ImportPath, 0)
	// Continue if there are no Go source files; we still want the directory info.
	_, nogo := err.(*build.NoGoError)
	if err != nil {
		if nogo {
			err = nil
		} else {
			log.Warn("walker: %s", err.Error())
			return nil, nil
		}
	}

	// Parse the Go files

	files := make(map[string]*ast.File)
	for _, name := range append(bpkg.GoFiles, bpkg.CgoFiles...) {
		file, err := parser.ParseFile(w.fset, name, w.srcs[name].data, parser.ParseComments)
		if err != nil {
			//beego.Error("doc.walker.build():", err)
			continue
		}
		files[name] = file
	}

	w.ImportPath = strings.Replace(w.ImportPath, "\\", "/", -1)
	var imports []string
	for _, v := range bpkg.Imports {
		// Skip strandard library.
		if !IsGoRepoPath(v) &&
			(GetProjectPath(v) != GetProjectPath(w.ImportPath)) {
			imports = append(imports, v)
		}
	}

	apkg, _ := ast.NewPackage(w.fset, files, simpleImporter, nil)

	mode := doc.Mode(0)
	if w.ImportPath == "builtin" {
		mode |= doc.AllDecls
	}

	pdoc := doc.New(apkg, w.ImportPath, mode)

	if nod != nil {
		nod.Synopsis = Synopsis(pdoc.Doc)
		if i := strings.Index(nod.Synopsis, "\n"); i > -1 {
			nod.Synopsis = nod.Synopsis[:i]
		}
	}

	return imports, err
}
Пример #9
0
func runGet(ctx *cli.Context) {
	setup(ctx)
	// Check conflicts.
	if ctx.Bool("gopath") && ctx.Bool("remote") ||
		ctx.Bool("local") && ctx.Bool("remote") ||
		ctx.Bool("gopath") && ctx.Bool("local") {
		e := " "
		if ctx.Bool("gopath") {
			e += "--gopth,-g "
		}
		if ctx.Bool("remote") {
			e += "--remote,-r "
		}
		if ctx.Bool("local") {
			e += "--local,-l "
		}
		log.Error("get", "Command options have conflicts")
		log.Error("", "Following options are not supposed to use at same time:")
		log.Error("", "\t"+e)
		log.Help("Try 'gopm help get' to get more information")
	}

	if !ctx.Bool("remote") {
		// Get GOPATH.
		installGopath = com.GetGOPATHs()[0]
		if com.IsDir(installGopath) {
			isHasGopath = true
			log.Log("Indicated GOPATH: %s", installGopath)
			installGopath += "/src"
		} else {
			if ctx.Bool("gopath") {
				log.Error("get", "Invalid GOPATH path")
				log.Error("", "GOPATH does not exist or is not a directory:")
				log.Error("", "\t"+installGopath)
				log.Help("Try 'go help gopath' to get more information")
			} else {
				// It's OK that no GOPATH setting
				// when user does not specify to use.
				log.Warn("No GOPATH setting available")
			}
		}
		// if flag local set use localPath as GOPATH
		if ctx.Bool("local") {
			if !com.IsExist(".gopmfile") {
				runGen(ctx)
			}
			gf, err := goconfig.LoadConfigFile(".gopmfile")
			if err != nil {
				log.Fatal("get", err.Error())
			} else {
				installGopath = gf.MustValue("project", "localPath")
				if installGopath == "" {
					os.Remove(".gopmfile")
					log.Fatal("get", "unexpected localPath or no localPath exists")
				}
				installGopath += "/src"
			}
		}
	}

	// The gopm local repository.
	installRepoPath = path.Join(doc.HomeDir, "repos")
	log.Log("Local repository path: %s", installRepoPath)

	// Check number of arguments to decide which function to call.
	switch len(ctx.Args()) {
	case 0:
		getByGopmfile(ctx)
	case 1:
		getByPath(ctx)
	default:
		log.Error("get", "too many arguments")
		log.Help("Try 'gopm help get' to get more information")
	}
}