Browse Source

Merge branch 'dev' of https://github.com/gpmgo/gopm into dev

pull/103/head
Lunny Xiao 11 years ago
parent
commit
6cf99c7e25
  1. 20
      cmd/get.go
  2. 260
      cmd/update.go
  3. 14
      doc/conf.go
  4. 4
      gopm.go

20
cmd/get.go

@ -355,19 +355,12 @@ func updateByVcs(vcs, dirPath string) error {
switch vcs {
case "git":
stdout, _, err := com.ExecCmd("git", "status")
branch, _, err := com.ExecCmd("git", "rev-parse", "--abbrev-ref", "HEAD")
if err != nil {
log.Error("", "Error occurs when 'git status'")
log.Error("", "Error occurs when 'git rev-parse --abbrev-ref HEAD'")
log.Error("", "\t"+err.Error())
}
i := strings.Index(stdout, "\n")
if i == -1 {
log.Error("", "Empty result for 'git status'")
return nil
}
branch := strings.TrimPrefix(stdout[:i], "# On branch ")
_, _, err = com.ExecCmd("git", "pull", "origin", branch)
if err != nil {
log.Error("", "Error occurs when 'git pull origin "+branch+"'")
@ -392,7 +385,14 @@ func updateByVcs(vcs, dirPath string) error {
log.Error("", "Error: "+stderr)
}
case "svn":
log.Error("", "Error: not support svn yet")
_, stderr, err := com.ExecCmd("svn", "update")
if err != nil {
log.Error("", "Error occurs when 'svn update'")
log.Error("", "\t"+err.Error())
}
if len(stderr) > 0 {
log.Error("", "Error: "+stderr)
}
}
return nil
}

260
cmd/update.go

@ -15,13 +15,14 @@
package cmd
import (
"encoding/json"
"fmt"
"net/http"
"os"
"os/exec"
"path"
"path/filepath"
"runtime"
"strings"
"github.com/Unknwon/com"
"github.com/codegangsta/cli"
@ -32,160 +33,175 @@ import (
var CmdUpdate = cli.Command{
Name: "update",
Usage: "update self",
Description: `Command bin downloads and links dependencies according to gopmfile,
and build executable binary to work directory
Usage: "check and update gopm resources including itself",
Description: `Command update checks updates of resources and gopm itself.
gopm update
Can only specify one each time, and only works for projects that
contains main package`,
Resources will be updated automatically after executed this command,
but you have to confirm before updaing gopm itself.`,
Action: runUpdate,
Flags: []cli.Flag{
cli.BoolFlag{"verbose, v", "show process details"},
},
}
func exePath() string {
file, _ := exec.LookPath(os.Args[0])
path, _ := filepath.Abs(file)
file, err := exec.LookPath(os.Args[0])
if err != nil {
log.Error("Update", "Fail to execute exec.LookPath")
log.Fatal("", err.Error())
}
path, err := filepath.Abs(file)
if err != nil {
log.Error("Update", "Fail to get absolutely path")
log.Fatal("", err.Error())
}
return path
}
func runUpdate(ctx *cli.Context) {
doc.LoadPkgNameList(doc.HomeDir + "/data/pkgname.list")
type version struct {
Gopm int
PackageNameList int `json:"package_name_list"`
}
installRepoPath = doc.HomeDir + "/repos"
func runUpdate(ctx *cli.Context) {
setup(ctx)
// Check arguments.
num := 0
isAnythingUpdated := false
// Load local version info.
localVerInfo := loadLocalVerInfo()
if len(ctx.Args()) != num {
log.Error("Update", "Fail to start command")
log.Fatal("", "Invalid argument number")
// 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())
}
// 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:])
// 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())
}
_, err = com.SaveFile(path.Join(doc.HomeDir, doc.PKG_NAME_LIST_PATH), data)
if 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
}
// 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")
// Gopm.
if remoteVerInfo.Gopm > localVerInfo.Gopm {
log.Log("Updating gopm...%v > %v",
localVerInfo.Gopm, remoteVerInfo.Gopm)
installRepoPath = doc.HomeDir + "/repos"
tmpDirPath := path.Join(doc.HomeDir, "temp")
tmpBinPath := path.Join(tmpDirPath, "gopm")
if runtime.GOOS == "windows" {
tmpBinPath += ".exe"
}
pkgPath = name
}
// Get code.
stdout, _, _ := com.ExecCmd("gopm", "get", info)
if len(stdout) > 0 {
fmt.Print(stdout)
}
os.MkdirAll(tmpDirPath, os.ModePerm)
os.Remove(tmpBinPath)
// Fetch code.
stdout, stderr, err := com.ExecCmd("gopm", "bin", "-u", "-d",
"github.com/gpmgo/gopm", tmpDirPath)
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.
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")
// 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(workDir, "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"`,
tmpBinPath, movePath, tmpBinPath, 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{"a.bat"}, 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
}
wd, err := os.Getwd()
// Save JSON.
f, err := os.Create(path.Join(doc.HomeDir, doc.VER_PATH))
if err != nil {
log.Error("Bin", "Fail to get work directory")
log.Error("Update", "Fail to create VERSION.json")
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")
if err := json.NewEncoder(f).Encode(&remoteVerInfo); err != nil {
log.Error("Update", "Fail to encode VERSION.json")
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 !isAnythingUpdated {
log.Log("Nothing need to be updated")
}
}
if len(pkgName) == 0 {
_, pkgName = filepath.Split(pkgPath)
}
func loadLocalVerInfo() (ver version) {
verPath := path.Join(doc.HomeDir, doc.VER_PATH)
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")
// First time run should not exist.
if !com.IsExist(verPath) {
return ver
}
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())
}
f, err := os.Open(verPath)
if err != nil {
log.Error("Update", "Fail to open VERSION.json")
log.Fatal("", err.Error())
}
log.Log("Changing work directory back to %s", wd)
os.Chdir(wd)
log.Success("SUCC", "Update", "Command execute successfully!")
if err := json.NewDecoder(f).Decode(&ver); err != nil {
log.Error("Update", "Fail to decode VERSION.json")
log.Fatal("", err.Error())
}
return ver
}

14
doc/conf.go

@ -27,8 +27,10 @@ import (
)
const (
GOPM_FILE_NAME = ".gopmfile"
RawHomeDir = "~/.gopm"
GOPM_FILE_NAME = ".gopmfile"
PKG_NAME_LIST_PATH = "data/pkgname.list"
VER_PATH = "data/VERSION.json"
RawHomeDir = "~/.gopm"
)
var (
@ -47,7 +49,7 @@ func init() {
HomeDir = strings.Replace(RawHomeDir, "~", hd, -1)
LoadLocalNodes()
LoadPkgNameList(HomeDir + "/data/pkgname.list")
LoadPkgNameList(path.Join(HomeDir, PKG_NAME_LIST_PATH))
}
// NewGopmfile loads gopmgile in given directory.
@ -78,9 +80,13 @@ func LoadPkgNameList(filePath string) {
}
pkgs := strings.Split(string(data), "\n")
for _, line := range pkgs {
for i, line := range pkgs {
infos := strings.Split(line, "=")
if len(infos) != 2 {
// Last item might be empty line.
if i == len(pkgs)-1 {
continue
}
log.Error("", "Fail to parse package name: "+line)
log.Fatal("", "Invalid package name information")
}

4
gopm.go

@ -29,7 +29,7 @@ import (
// Test that go1.1 tag above is included in builds. main.go refers to this definition.
const go11tag = true
const APP_VER = "0.6.1.0110"
const APP_VER = "0.6.2.0113"
// //cmd.CmdSearch,
// cmdClean,
@ -57,7 +57,7 @@ func main() {
cmd.CmdRun,
cmd.CmdBuild,
cmd.CmdInstall,
//cmd.CmdUpdate,
cmd.CmdUpdate,
//cmd.CmdTest,
}
app.Flags = append(app.Flags, []cli.Flag{

Loading…
Cancel
Save