예제 #1
0
파일: run.go 프로젝트: nashtsai/gopm
func runRun(ctx *cli.Context) {
	setup(ctx)

	// Get GOPATH.
	installGopath = com.GetGOPATHs()[0]
	if com.IsDir(installGopath) {
		isHasGopath = true
		log.Log("Indicated GOPATH: %s", installGopath)
		installGopath += "/src"
	}

	genNewGoPath(ctx, false)

	log.Trace("Running...")

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

	log.Success("SUCC", "run", "Command executed successfully!")
}
예제 #2
0
파일: get.go 프로젝트: josephyzhou/gopm
func getByPath(ctx *cli.Context) {
	nodes := make([]*doc.Node, 0, len(ctx.Args()))
	for _, info := range ctx.Args() {
		pkgPath := info
		node := doc.NewNode(pkgPath, pkgPath, doc.BRANCH, "", true)

		if i := strings.Index(info, "@"); i > -1 {
			pkgPath = info[:i]
			tp, ver := validPath(info[i+1:])
			node = doc.NewNode(pkgPath, pkgPath, tp, ver, true)
		}

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

		nodes = append(nodes, node)
	}

	downloadPackages(ctx, nodes)
	doc.SaveLocalNodes()

	log.Log("%d package(s) downloaded, %d failed", downloadCount, failConut)
}
예제 #3
0
파일: get.go 프로젝트: josephyzhou/gopm
func getByGopmfile(ctx *cli.Context) {
	// Check if gopmfile exists and generate one if not.
	if !com.IsFile(".gopmfile") {
		runGen(ctx)
	}
	gf := doc.NewGopmfile(".")

	targetPath := parseTarget(gf.MustValue("target", "path"))
	// Get dependencies.
	imports := doc.GetAllImports([]string{workDir}, targetPath, ctx.Bool("example"))

	nodes := make([]*doc.Node, 0, len(imports))
	for _, p := range imports {
		p = doc.GetProjectPath(p)
		// Skip subpackage(s) of current project.
		if isSubpackage(p, targetPath) {
			continue
		}
		node := doc.NewNode(p, p, doc.BRANCH, "", true)

		// Check if user specified the version.
		if v, err := gf.GetValue("deps", p); err == nil && len(v) > 0 {
			node.Type, node.Value = validPath(v)
		}
		nodes = append(nodes, node)
	}

	downloadPackages(ctx, nodes)
	doc.SaveLocalNodes()

	log.Log("%d package(s) downloaded, %d failed", downloadCount, failConut)
}
예제 #4
0
파일: get.go 프로젝트: nashtsai/gopm
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)
	}
}
예제 #5
0
파일: build.go 프로젝트: jexwn/gopm
func runBuild(ctx *cli.Context) {
	setup(ctx)

	// Get GOPATH.
	installGopath = com.GetGOPATHs()[0]
	if com.IsDir(installGopath) {
		isHasGopath = true
		log.Log("Indicated GOPATH: %s", installGopath)
		installGopath += "/src"
	}

	buildBinary(ctx, ctx.Args()...)
	log.Success("SUCC", "build", "Command executed successfully!")
}
예제 #6
0
파일: get.go 프로젝트: josephyzhou/gopm
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)
}
예제 #7
0
파일: gopath.go 프로젝트: kulasama/gopm
func execCmd(gopath, curPath string, args ...string) error {
	cwd, err := os.Getwd()
	if err != nil {
		log.Error("", "Fail to get work directory:")
		log.Fatal("", "\t"+err.Error())
	}

	log.Log("Changing work directory to %s", curPath)
	err = os.Chdir(curPath)
	if err != nil {
		log.Error("", "Fail to change work directory:")
		log.Fatal("", "\t"+err.Error())
	}
	defer func() {
		log.Log("Changing work directory back to %s", cwd)
		os.Chdir(cwd)
	}()

	err = os.Chdir(curPath)
	if err != nil {
		log.Error("", "Fail to change work directory:")
		log.Fatal("", "\t"+err.Error())
	}

	oldGoPath = os.Getenv("GOPATH")
	log.Log("Setting GOPATH to %s", gopath)

	sep := ":"
	if runtime.GOOS == "windows" {
		sep = ";"
	}
	err = os.Setenv("GOPATH", gopath+sep+oldGoPath)
	if err != nil {
		log.Error("", "Fail to setting GOPATH:")
		log.Fatal("", "\t"+err.Error())
	}
	defer func() {
		log.Log("Setting GOPATH back to %s", oldGoPath)
		os.Setenv("GOPATH", oldGoPath)
	}()

	cmd := exec.Command(args[0], args[1:]...)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	log.Log("===== application outputs start =====\n")

	err = cmd.Run()

	log.Log("====== application outputs end ======")
	return err
}
예제 #8
0
파일: vcs.go 프로젝트: puma007/gopm
// PureDownload downloads package without version control.
func PureDownload(nod *Node, installRepoPath string, ctx *cli.Context) ([]string, error) {
	for _, s := range services {
		if s.get == nil || !strings.HasPrefix(nod.DownloadURL, s.prefix) {
			continue
		}
		m := s.pattern.FindStringSubmatch(nod.DownloadURL)
		if m == nil {
			if s.prefix != "" {
				return nil, errors.New("Cannot match package service prefix by given path")
			}
			continue
		}
		match := map[string]string{"importPath": nod.DownloadURL}
		for i, n := range s.pattern.SubexpNames() {
			if n != "" {
				match[n] = m[i]
			}
		}
		return s.get(HttpClient, match, installRepoPath, nod, ctx)
	}

	log.Log("Cannot match any service, getting dynamic...")
	return getDynamic(HttpClient, nod, installRepoPath, ctx)
}
예제 #9
0
파일: install.go 프로젝트: nashtsai/gopm
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!")
}
예제 #10
0
파일: google.go 프로젝트: nashtsai/gopm
// getGoogleDoc downloads raw files from code.google.com.
func getGoogleDoc(client *http.Client, match map[string]string, installRepoPath string, nod *Node, ctx *cli.Context) ([]string, error) {
	setupGoogleMatch(match)
	// Check version control.
	if err := getGoogleVCS(client, match); err != nil {
		return nil, errors.New("fail to get vcs " + nod.ImportPath + " : " + err.Error())
	}

	switch nod.Type {
	case BRANCH:
		if len(nod.Value) == 0 {
			match["tag"] = defaultTags[match["vcs"]]

			// Only get and check revision with the latest version.
			p, err := com.HttpGetBytes(client,
				com.Expand("http://{subrepo}{dot}{repo}.googlecode.com/{vcs}{dir}/?r={tag}", match), nil)
			if err != nil {
				log.Error("GET", "Fail to get revision")
				log.Error("", err.Error())
				break
			}

			if m := googleRevisionRe.FindSubmatch(p); m == nil {
				log.Error("GET", "Fail to get revision")
				log.Error("", err.Error())
			} else {
				etag := string(m[1])
				if etag == nod.Revision {
					log.Log("GET Package hasn't changed: %s", nod.ImportPath)
					return nil, nil
				}
				nod.Revision = etag
			}

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

	var installPath string
	projectPath := GetProjectPath(nod.ImportPath)
	if nod.ImportPath == nod.DownloadURL {
		suf := "." + nod.Value
		if len(suf) == 1 {
			suf = ""
		}
		installPath = installRepoPath + "/" + projectPath + suf
	} else {
		installPath = installRepoPath + "/" + projectPath
	}

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

	if match["vcs"] == "svn" {
		com.ColorLog("[WARN] SVN detected, may take very long time.\n")

		rootPath := com.Expand("http://{subrepo}{dot}{repo}.googlecode.com/{vcs}", match)
		d, f := path.Split(rootPath)
		err := downloadFiles(client, match, d, installPath+"/", match["tag"],
			[]string{f + "/"})
		if err != nil {
			return nil, errors.New("Fail to download " + nod.ImportPath + " : " + err.Error())
		}
	}

	p, err := com.HttpGetBytes(client, com.Expand("http://{subrepo}{dot}{repo}.googlecode.com/archive/{tag}.zip", match), nil)
	if err != nil {
		return nil, errors.New("Fail to download " + nod.ImportPath + " : " + err.Error())
	}

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

	nameLen := strings.Index(r.File[0].Name, "/")
	dirPrefix := match["dir"]
	if len(dirPrefix) != 0 {
		dirPrefix = dirPrefix[1:] + "/"
	}

	dirs := make([]string, 0, 5)
	for _, f := range r.File {
		absPath := strings.Replace(f.Name, f.Name[:nameLen], installPath, 1)

		// Create diretory before create file.
		dir := path.Dir(absPath)
		if !checkDir(dir, dirs) && !(!ctx.Bool("example") && strings.Contains(absPath, "example")) {
			dirs = append(dirs, dir+"/")
			os.MkdirAll(dir+"/", os.ModePerm)
		}

		// 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
		}

		_, err = com.SaveFile(absPath, fbytes)
		if err != nil {
			return nil, err
		}
	}

	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
}
예제 #11
0
파일: exec.go 프로젝트: kulasama/gopm
func runExec(ctx *cli.Context) {
	setup(ctx)

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

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

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

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

	node.ImportPath = pkgPath
	node.DownloadURL = pkgPath

	if len(node.Value) == 0 && com.IsFile(".gopmfile") {
		// Specify version by gopmfile.
		gf := doc.NewGopmfile(".")
		info, err := gf.GetValue("exec", pkgPath)
		if err == nil && len(info) > 0 {
			node.Type, node.Value = validPath(info)
		}
	}

	// Check if binary exists.
	binPath := path.Join(doc.HomeDir, "bins", node.ImportPath, path.Base(node.ImportPath)+versionSuffix(node.Value))
	log.Log("Binary path: %s", binPath)

	if !com.IsFile(binPath) {
		// Calling bin command.
		args := []string{"bin", "-d"}
		if ctx.Bool("verbose") {
			args = append(args, "-v")
		}
		if ctx.Bool("update") {
			args = append(args, "-u")
		}
		args = append(args, node.ImportPath+"@"+node.Type+":"+node.Value)
		args = append(args, path.Dir(binPath))
		stdout, stderr, err := com.ExecCmd("gopm", args...)
		if err != nil {
			log.Error("exec", "Building binary failed:")
			log.Fatal("", "\t"+err.Error())
		}
		if len(stderr) > 0 {
			fmt.Print(stderr)
		}
		if len(stdout) > 0 {
			fmt.Print(stdout)
		}
	}
	fmt.Printf("%+v\n", node)

	return
	stdout, stderr, err := com.ExecCmd(binPath, ctx.Args()[1:]...)
	if err != nil {
		log.Error("exec", "Calling binary failed:")
		log.Fatal("", "\t"+err.Error())
	}
	if len(stderr) > 0 {
		fmt.Print(stderr)
	}
	if len(stdout) > 0 {
		fmt.Print(stdout)
	}
}
예제 #12
0
파일: run.go 프로젝트: kulasama/gopm
func runRun(ctx *cli.Context) {
	setup(ctx)
	//support unix only
	if ctx.Bool("local") {
		var localPath string
		var err error
		var wd string
		var gf *goconfig.ConfigFile
		wd, _ = os.Getwd()
		for wd != "/" {
			gf, _ = goconfig.LoadConfigFile(".gopmfile")
			if gf != nil {
				localPath = gf.MustValue("project", "localPath")
			}
			if localPath != "" {
				break
			}
			os.Chdir("..")
			wd, _ = os.Getwd()
		}
		if wd == "/" {
			log.Fatal("run", "no gopmfile in the directory or parent directory")
		}
		argss := gf.MustValue("run", "cmd")
		if localPath == "" {
			log.Fatal("run", "No localPath set")
		}
		args := strings.Split(argss, " ")
		argsLen := len(args)
		for i := 0; i < argsLen; i++ {
			strings.Trim(args[i], " ")
		}
		if len(args) < 2 {
			log.Fatal("run", "cmd arguments less than 2")
		}
		err = execCmd(localPath, localPath, args...)
		if err != nil {
			log.Error("run", "Fail to run program:")
			log.Fatal("", "\t"+err.Error())
		}
		return
	}
	// Get GOPATH.
	installGopath = com.GetGOPATHs()[0]
	if com.IsDir(installGopath) {
		isHasGopath = true
		log.Log("Indicated GOPATH: %s", installGopath)
		installGopath += "/src"
	}
	// run command with gopm repos context
	// need version control , auto link to GOPATH/src repos
	genNewGoPath(ctx, false)
	defer os.RemoveAll(doc.VENDOR)

	log.Trace("Running...")

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

	log.Success("SUCC", "run", "Command executed successfully!")
}
예제 #13
0
파일: get.go 프로젝트: josephyzhou/gopm
// 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(ctx *cli.Context, nodes []*doc.Node) {
	// Check all packages, they may be raw packages path.
	for _, n := range nodes {
		// Check if local reference
		if n.Type == doc.LOCAL {
			continue
		}
		// Check if it is a valid remote path or C.
		if n.ImportPath == "C" {
			continue
		} else if !doc.IsValidRemotePath(n.ImportPath) {
			// Invalid import path.
			log.Error("download", "Skipped invalid package: "+fmt.Sprintf("%s@%s:%s",
				n.ImportPath, n.Type, doc.CheckNodeValue(n.Value)))
			failConut++
			continue
		}

		// Valid import path.
		gopathDir := path.Join(installGopath, n.ImportPath)
		n.RootPath = doc.GetProjectPath(n.ImportPath)
		installPath := path.Join(installRepoPath, n.RootPath) + versionSuffix(n.Value)

		if isSubpackage(n.RootPath, ".") {
			continue
		}

		// Indicates whether need to download package again.
		if n.IsFixed() && com.IsExist(installPath) {
			n.IsGetDepsOnly = true
		}

		if !ctx.Bool("update") {
			// Check if package has been downloaded.
			if (len(n.Value) == 0 && !ctx.Bool("remote") && com.IsExist(gopathDir)) ||
				com.IsExist(installPath) {
				log.Trace("Skipped installed package: %s@%s:%s",
					n.ImportPath, n.Type, doc.CheckNodeValue(n.Value))

				// Only copy when no version control.
				if ctx.Bool("gopath") && com.IsExist(installPath) ||
					len(getVcsName(gopathDir)) == 0 {
					copyToGopath(installPath, gopathDir)
				}
				continue
			} else {
				doc.LocalNodes.SetValue(n.RootPath, "value", "")
			}
		}

		if downloadCache[n.RootPath] {
			log.Trace("Skipped downloaded package: %s@%s:%s",
				n.ImportPath, n.Type, doc.CheckNodeValue(n.Value))
			continue
		}

		// Download package.
		nod, imports := downloadPackage(ctx, n)
		if len(imports) > 0 {
			var gf *goconfig.ConfigFile

			// Check if has gopmfile.
			if com.IsFile(installPath + "/" + doc.GOPM_FILE_NAME) {
				log.Log("Found gopmfile: %s@%s:%s",
					n.ImportPath, n.Type, doc.CheckNodeValue(n.Value))
				gf = doc.NewGopmfile(installPath)
			}

			// Need to download dependencies.
			// Generate temporary nodes.
			nodes := make([]*doc.Node, len(imports))
			for i := range nodes {
				nodes[i] = doc.NewNode(imports[i], imports[i], doc.BRANCH, "", true)

				if gf == nil {
					continue
				}

				// Check if user specified the version.
				if v, err := gf.GetValue("deps", imports[i]); err == nil && len(v) > 0 {
					nodes[i].Type, nodes[i].Value = validPath(v)
				}
			}
			downloadPackages(ctx, nodes)
		}

		// Only save package information with specific commit.
		if nod == nil {
			continue
		}

		// Save record in local nodes.
		log.Success("SUCC", "GET", fmt.Sprintf("%s@%s:%s",
			n.ImportPath, n.Type, doc.CheckNodeValue(n.Value)))
		downloadCount++

		// Only save non-commit node.
		if len(nod.Value) == 0 && len(nod.Revision) > 0 {
			doc.LocalNodes.SetValue(nod.RootPath, "value", nod.Revision)
		}

		if ctx.Bool("gopath") && com.IsExist(installPath) && !ctx.Bool("update") &&
			len(getVcsName(path.Join(installGopath, nod.RootPath))) == 0 {
			copyToGopath(installPath, gopathDir)
		}
	}
}
예제 #14
0
파일: update.go 프로젝트: nashtsai/gopm
func runUpdate(ctx *cli.Context) {
	doc.LoadPkgNameList(doc.HomeDir + "/data/pkgname.list")

	installRepoPath = doc.HomeDir + "/repos"

	// Check arguments.
	num := 0

	if len(ctx.Args()) != num {
		log.Error("Update", "Fail to start command")
		log.Fatal("", "Invalid argument number")
	}

	// Parse package version.
	info := "github.com/gpmgo/gopm"
	pkgPath := info
	ver := ""
	var err error
	if i := strings.Index(info, "@"); i > -1 {
		pkgPath = info[:i]
		_, ver = validPath(info[i+1:])
	}

	// Check package name.
	if !strings.Contains(pkgPath, "/") {
		name, ok := doc.PackageNameList[pkgPath]
		if !ok {
			log.Error("Update", "Invalid package name: "+pkgPath)
			log.Fatal("", "No match in the package name list")
		}
		pkgPath = name
	}

	// Get code.
	stdout, _, _ := com.ExecCmd("gopm", "get", info)
	if len(stdout) > 0 {
		fmt.Print(stdout)
	}

	// Check if previous steps were successful.
	repoPath := installRepoPath + "/" + pkgPath
	if len(ver) > 0 {
		repoPath += "." + ver
	}
	if !com.IsDir(repoPath) {
		log.Error("Bin", "Fail to continue command")
		log.Fatal("", "Previous steps weren't successful")
	}

	wd, err := os.Getwd()
	if err != nil {
		log.Error("Bin", "Fail to get work directory")
		log.Fatal("", err.Error())
	}

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

	// Build application.
	stdout, _, _ = com.ExecCmd("gopm", "build")
	if len(stdout) > 0 {
		fmt.Print(stdout)
	}
	defer func() {
		// Clean files.
		os.RemoveAll(path.Join(repoPath, doc.VENDOR))
	}()

	// 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)
		}
	}

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

	binName := path.Base(pkgName)
	if runtime.GOOS == "windows" {
		binName += ".exe"
	}
	binPath := path.Join(doc.VENDOR, "src", pkgPath, binName)
	if !com.IsFile(binPath) {
		log.Error("Update", "Fail to continue command")
		log.Fatal("", "Previous steps weren't successful or the project does not contain main package")
	}

	movePath := exePath()
	fmt.Print(movePath)

	// Move binary to given directory.
	if runtime.GOOS != "windows" {
		err = os.Rename(binPath, movePath)
		if err != nil {
			log.Error("Update", "Fail to move binary")
			log.Fatal("", err.Error())
		}
		os.Chmod(movePath+"/"+binName, os.ModePerm)
	} else {
		batPath := filepath.Join(wd, "a.bat")
		f, err := os.Create(batPath)
		if err != nil {
			log.Error("Update", "Fail to generate bat file")
			log.Fatal("", err.Error())
		}
		f.WriteString(fmt.Sprintf(`ping -n 1 127.0.0.1>nul\ncopy "%v" "%v"\ndel "%v"\ndel "%v"`,
			binPath, movePath, binPath, batPath))
		f.Close()

		attr := &os.ProcAttr{
			Dir: wd,
			Env: os.Environ(),
			//Files: []*os.File{nil, nil, nil},
			Files: []*os.File{os.Stdin, os.Stdout, os.Stderr},
		}

		_, err = os.StartProcess(batPath, []string{"a.bat"}, attr)
		if err != nil {
			log.Error("Update", "Fail to start bat process")
			log.Fatal("", err.Error())
		}
	}

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

	log.Success("SUCC", "Update", "Command execute successfully!")
}
예제 #15
0
파일: update.go 프로젝트: kulasama/gopm
func runUpdate(ctx *cli.Context) {
	setup(ctx)

	isAnythingUpdated := false
	// Load local version info.
	localVerInfo := loadLocalVerInfo()

	// Get remote version info.
	var remoteVerInfo version
	if err := com.HttpGetJSON(http.DefaultClient, "http://gopm.io/VERSION.json", &remoteVerInfo); err != nil {
		log.Error("Update", "Fail to fetch VERSION.json")
		log.Fatal("", err.Error())
	}

	// Package name list.
	if remoteVerInfo.PackageNameList > localVerInfo.PackageNameList {
		log.Log("Updating pkgname.list...%v > %v",
			localVerInfo.PackageNameList, remoteVerInfo.PackageNameList)
		data, err := com.HttpGetBytes(http.DefaultClient, "https://raw2.github.com/gpmgo/docs/master/pkgname.list", nil)
		if err != nil {
			log.Error("Update", "Fail to update pkgname.list")
			log.Fatal("", err.Error())
		}

		if err = com.WriteFile(path.Join(doc.HomeDir, doc.PKG_NAME_LIST_PATH), data); err != nil {
			log.Error("Update", "Fail to save pkgname.list")
			log.Fatal("", err.Error())
		}
		log.Log("Update pkgname.list to %v succeed!", remoteVerInfo.PackageNameList)
		isAnythingUpdated = true
	}

	// Gopm.
	if remoteVerInfo.Gopm > localVerInfo.Gopm {
		log.Log("Updating gopm...%v > %v",
			localVerInfo.Gopm, remoteVerInfo.Gopm)
		installRepoPath = doc.HomeDir + "/repos"

		tmpDirPath := filepath.Join(doc.HomeDir, "temp")
		tmpBinPath := filepath.Join(tmpDirPath, "gopm")
		if runtime.GOOS == "windows" {
			tmpBinPath += ".exe"
		}

		os.MkdirAll(tmpDirPath, os.ModePerm)
		os.Remove(tmpBinPath)

		// Fetch code.
		args := []string{"bin", "-u", "-d"}
		if ctx.Bool("verbose") {
			args = append(args, "-v")
		}
		args = append(args, []string{"github.com/gpmgo/gopm", tmpDirPath}...)
		stdout, stderr, err := com.ExecCmd("gopm", args...)
		if err != nil {
			log.Error("Update", "Fail to execute 'gopm bin -u -d github.com/gpmgo/gopm "+tmpDirPath+"'")
			log.Fatal("", err.Error())
		}
		if len(stderr) > 0 {
			fmt.Print(stderr)
		}
		if len(stdout) > 0 {
			fmt.Print(stdout)
		}

		// Check if previous steps were successful.
		if !com.IsExist(tmpBinPath) {
			log.Error("Update", "Fail to continue command")
			log.Fatal("", "Previous steps weren't successful, no binary produced")
		}

		movePath := exePath()
		log.Log("New binary will be replaced for %s", movePath)
		// Move binary to given directory.
		if runtime.GOOS != "windows" {
			err := os.Rename(tmpBinPath, movePath)
			if err != nil {
				log.Error("Update", "Fail to move binary")
				log.Fatal("", err.Error())
			}
			os.Chmod(movePath+"/"+path.Base(tmpBinPath), os.ModePerm)
		} else {
			batPath := filepath.Join(tmpDirPath, "update.bat")
			f, err := os.Create(batPath)
			if err != nil {
				log.Error("Update", "Fail to generate bat file")
				log.Fatal("", err.Error())
			}
			f.WriteString("@echo off\r\n")
			f.WriteString(fmt.Sprintf("ping -n 1 127.0.0.1>nul\r\ncopy \"%v\" \"%v\" >nul\r\ndel \"%v\" >nul\r\n\r\n",
				tmpBinPath, movePath, tmpBinPath))
			//f.WriteString(fmt.Sprintf("del \"%v\"\r\n", batPath))
			f.Close()

			attr := &os.ProcAttr{
				Dir:   workDir,
				Env:   os.Environ(),
				Files: []*os.File{os.Stdin, os.Stdout, os.Stderr},
			}

			_, err = os.StartProcess(batPath, []string{batPath}, attr)
			if err != nil {
				log.Error("Update", "Fail to start bat process")
				log.Fatal("", err.Error())
			}
		}

		log.Success("SUCC", "Update", "Command execute successfully!")
		isAnythingUpdated = true
	}

	// Save JSON.
	f, err := os.Create(path.Join(doc.HomeDir, doc.VER_PATH))
	if err != nil {
		log.Error("Update", "Fail to create VERSION.json")
		log.Fatal("", err.Error())
	}
	if err := json.NewEncoder(f).Encode(&remoteVerInfo); err != nil {
		log.Error("Update", "Fail to encode VERSION.json")
		log.Fatal("", err.Error())
	}

	if !isAnythingUpdated {
		log.Log("Nothing need to be updated")
	}
	log.Log("Exit old gopm")
}
예제 #16
0
파일: gopath.go 프로젝트: kulasama/gopm
func genNewGoPath(ctx *cli.Context, isTest bool) {
	var err error
	curPath, err = os.Getwd()
	if err != nil {
		log.Error("", "Fail to get work directory:")
		log.Fatal("", "\t"+err.Error())
	}
	log.Trace("Current Path: 0 %s", curPath)

	installRepoPath = doc.HomeDir + "/repos"

	if com.IsFile(curPath + "/" + doc.GOPM_FILE_NAME) {
		log.Trace("Loading gopmfile...")
		gf := doc.NewGopmfile(curPath)

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

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

	cachePkgs := make(map[string]*doc.Pkg)
	if err = getChildPkgs(ctx, curPath, nil, cachePkgs, isTest); err != nil {
		log.Error("", "Fail to get child pakcages:")
		log.Fatal("", "\t"+err.Error())
	}

	newGoPath = filepath.Join(curPath, doc.VENDOR)
	newGoPathSrc := filepath.Join(newGoPath, "src")
	os.RemoveAll(newGoPathSrc)
	os.MkdirAll(newGoPathSrc, os.ModePerm)

	for name, pkg := range cachePkgs {
		suf := versionSuffix(pkg.Value)

		var oldPath string
		if pkg.Type == doc.LOCAL {
			oldPath, _ = filepath.Abs(pkg.Value)
		} else {
			oldPath = filepath.Join(installRepoPath, name) + suf
		}

		newPath := filepath.Join(newGoPathSrc, name)
		paths := strings.Split(name, "/")
		var isExistP, isCurChild bool
		if name == pkgName {
			continue
		}

		for i := 0; i < len(paths)-1; i++ {
			pName := strings.Join(paths[:len(paths)-1-i], "/")
			if _, ok := cachePkgs[pName]; ok {
				isExistP = true
				break
			}
			if pkgName == pName {
				isCurChild = true
				break
			}
		}
		if isCurChild {
			continue
		}

		if !isExistP && (len(pkg.Value) > 0 || ctx.Bool("remote") ||
			!com.IsDir(filepath.Join(installGopath, pkg.ImportPath))) {
			log.Log("Linking %s", name+suf)
			err = autoLink(oldPath, newPath)
			if err != nil {
				log.Error("", "Fail to make link:")
				log.Fatal("", "\t"+err.Error())
			}
		}
	}

	newCurPath = filepath.Join(newGoPathSrc, pkgName)
	log.Log("Linking %s", pkgName)
	err = autoLink(curPath, newCurPath)
	if err != nil {
		log.Error("", "Fail to make link:")
		log.Fatal("", "\t"+err.Error())
	}
}
예제 #17
0
파일: bin.go 프로젝트: puma007/gopm
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)
}
예제 #18
0
파일: github.go 프로젝트: kulasama/gopm
// 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
}
예제 #19
0
파일: get.go 프로젝트: kulasama/gopm
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")
	}
}