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.

271 lines
6.2 KiB

11 years ago
package cmd
import (
"errors"
"fmt"
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
}
}
pkg, err := build.ImportDir(dirPath, build.AllowBinary)
if err != nil {
return map[string]*doc.Pkg{}, errors.New("Fail to get imports: " + err.Error())
11 years ago
}
pkgs = make(map[string]*doc.Pkg)
11 years ago
var imports []string = pkg.Imports
if isTest {
imports = append(imports, pkg.TestImports...)
}
for _, name := range imports {
if name == "C" {
//panic("nonono")
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 {
//pkgs := strings.Split(name, "/")
_, 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 {
var suf string
if ppkg != nil {
suf = versionSuffix(ppkg.Value)
}
pkgs, err := getGopmPkgs(cpath+suf, 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 {
if !pkgInCache(name, cachePkgs) {
var newPath string
if !build.IsLocalImport(name) {
11 years ago
suf := versionSuffix(pkg.Value)
11 years ago
newPath = filepath.Join(installRepoPath, pkg.ImportPath)
if len(pkg.Value) == 0 && !ctx.Bool("remote") {
newPath = filepath.Join(installGopath, pkg.ImportPath)
}
11 years ago
if pkgName != "" && strings.HasPrefix(pkg.ImportPath, pkgName) {
11 years ago
newPath = filepath.Join(curPath, pkg.ImportPath[len(pkgName)+1:]+suf)
11 years ago
} else {
11 years ago
if !com.IsExist(newPath + suf) {
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
}
}
11 years ago
err = getChildPkgs(ctx, newPath, pkg, cachePkgs, false)
11 years ago
if err != nil {
return err
}
}
}
if ppkg != nil && !build.IsLocalImport(ppkg.ImportPath) {
cachePkgs[ppkg.ImportPath] = ppkg
}
11 years ago
return nil
}
11 years ago
var pkgName string
var curPath string
11 years ago
var newCurPath string
var newGoPath string
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
}
oldGoPath := os.Getenv("GOPATH")
log.Log("Setting GOPATH to %s", gopath)
11 years ago
sep := ":"
if runtime.GOOS == "windos" {
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()
fmt.Println()
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")) {
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
}