You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

258 lines
6.0 KiB

11 years ago
package cmd
import (
"errors"
11 years ago
"go/build"
11 years ago
"os"
11 years ago
"os/exec"
11 years ago
"path/filepath"
"runtime"
11 years ago
"strings"
"github.com/Unknwon/com"
"github.com/codegangsta/cli"
"github.com/gpmgo/gopm/doc"
"github.com/gpmgo/gopm/log"
11 years ago
)
11 years ago
var isWindowsXP = false
11 years ago
func getGopmPkgs(dirPath string, isTest bool) (pkgs map[string]*doc.Pkg, err error) {
11 years ago
absPath, err := filepath.Abs(dirPath)
if err != nil {
log.Error("", "Fail to get absolute path of work directory:")
log.Fatal("", "\t"+err.Error())
11 years ago
}
var builds map[string]string
if com.IsFile(absPath + "/" + doc.GOPM_FILE_NAME) {
11 years ago
gf := doc.NewGopmfile(absPath)
if builds, err = gf.GetSection("deps"); err != nil {
builds = nil
}
}
imports := doc.GetAllImports([]string{dirPath}, ".", false)
11 years ago
pkgs = make(map[string]*doc.Pkg)
11 years ago
for _, name := range imports {
if name == "C" {
continue
}
11 years ago
if !doc.IsGoRepoPath(name) {
if builds != nil {
11 years ago
if info, ok := builds[name]; ok {
// Check version.
if i := strings.Index(info, ":"); i > -1 {
pkgs[name] = &doc.Pkg{
ImportPath: name,
Type: info[:i],
Value: info[i+1:],
}
continue
}
11 years ago
}
}
pkgs[name] = doc.NewDefaultPkg(name)
}
}
return pkgs, nil
11 years ago
}
func pkgInCache(name string, cachePkgs map[string]*doc.Pkg) bool {
_, ok := cachePkgs[name]
return ok
}
func autoLink(oldPath, newPath string) error {
newPPath, _ := filepath.Split(newPath)
os.MkdirAll(newPPath, os.ModePerm)
return makeLink(oldPath, newPath)
}
11 years ago
func getChildPkgs(ctx *cli.Context, cpath string, ppkg *doc.Pkg, cachePkgs map[string]*doc.Pkg, isTest bool) error {
pkgs, err := getGopmPkgs(cpath, isTest)
11 years ago
if err != nil {
return errors.New("Fail to get gopmfile deps: " + err.Error())
11 years ago
}
for name, pkg := range pkgs {
pkg.RootPath = doc.GetProjectPath(pkg.ImportPath)
if !pkgInCache(pkg.RootPath, cachePkgs) {
11 years ago
var newPath string
if !build.IsLocalImport(name) {
suf := versionSuffix(pkg.Value)
pkgPath := strings.Replace(
pkg.ImportPath, pkg.RootPath, pkg.RootPath+suf, 1)
newPath = filepath.Join(installRepoPath, pkgPath)
if len(suf) == 0 && !ctx.Bool("remote") &&
com.IsDir(filepath.Join(installGopath, pkgPath)) {
newPath = filepath.Join(installGopath, pkgPath)
}
11 years ago
if pkgName != "" && strings.HasPrefix(pkg.ImportPath, pkgName) {
newPath = filepath.Join(curPath, pkgPath)
11 years ago
} else {
if !com.IsExist(newPath) {
11 years ago
node := doc.NewNode(pkg.ImportPath, pkg.ImportPath,
pkg.Type, pkg.Value, true)
11 years ago
nodes := []*doc.Node{node}
downloadPackages(ctx, nodes)
11 years ago
// TODO: Should handler download failed
11 years ago
}
}
} else {
newPath, err = filepath.Abs(name)
if err != nil {
return err
}
}
cachePkgs[pkg.RootPath] = pkg
11 years ago
err = getChildPkgs(ctx, newPath, pkg, cachePkgs, false)
11 years ago
if err != nil {
return err
}
}
}
11 years ago
return nil
}
11 years ago
var pkgName string
var curPath string
11 years ago
var newCurPath string
var newGoPath string
11 years ago
var oldGoPath string
11 years ago
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())
11 years ago
}
log.Log("Changing work directory to %s", curPath)
11 years ago
err = os.Chdir(curPath)
if err != nil {
log.Error("", "Fail to change work directory:")
log.Fatal("", "\t"+err.Error())
11 years ago
}
defer func() {
log.Log("Changing work directory back to %s", cwd)
os.Chdir(cwd)
}()
11 years ago
err = os.Chdir(curPath)
11 years ago
if err != nil {
log.Error("", "Fail to change work directory:")
log.Fatal("", "\t"+err.Error())
11 years ago
}
11 years ago
oldGoPath = os.Getenv("GOPATH")
log.Log("Setting GOPATH to %s", gopath)
11 years ago
sep := ":"
11 years ago
if runtime.GOOS == "windows" {
sep = ";"
}
err = os.Setenv("GOPATH", gopath+sep+oldGoPath)
11 years ago
if err != nil {
log.Error("", "Fail to setting GOPATH:")
log.Fatal("", "\t"+err.Error())
11 years ago
}
defer func() {
log.Log("Setting GOPATH back to %s", oldGoPath)
os.Setenv("GOPATH", oldGoPath)
}()
11 years ago
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
11 years ago
}
11 years ago
11 years ago
func genNewGoPath(ctx *cli.Context, isTest bool) {
11 years ago
var err error
curPath, err = os.Getwd()
if err != nil {
log.Error("", "Fail to get work directory:")
log.Fatal("", "\t"+err.Error())
11 years ago
}
installRepoPath = doc.HomeDir + "/repos"
if com.IsFile(curPath + "/" + doc.GOPM_FILE_NAME) {
11 years ago
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)
11 years ago
err = getChildPkgs(ctx, curPath, nil, cachePkgs, isTest)
11 years ago
if err != nil {
log.Error("", "Fail to get child pakcages:")
log.Fatal("", "\t"+err.Error())
11 years ago
}
newGoPath = filepath.Join(curPath, doc.VENDOR)
11 years ago
newGoPathSrc := filepath.Join(newGoPath, "src")
os.RemoveAll(newGoPathSrc)
os.MkdirAll(newGoPathSrc, os.ModePerm)
11 years ago
for name, pkg := range cachePkgs {
suf := versionSuffix(pkg.Value)
11 years ago
oldPath := filepath.Join(installRepoPath, name) + suf
11 years ago
newPath := filepath.Join(newGoPathSrc, name)
paths := strings.Split(name, "/")
var isExistP bool
var isCurChild bool
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)) {
11 years ago
log.Log("Linking %s", name+suf)
11 years ago
err = autoLink(oldPath, newPath)
if err != nil {
log.Error("", "Fail to make link:")
log.Fatal("", "\t"+err.Error())
11 years ago
}
}
}
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())
11 years ago
}
11 years ago
}