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. 204
      cmd/update.go
  3. 10
      doc/conf.go
  4. 4
      gopm.go

20
cmd/get.go

@ -355,19 +355,12 @@ func updateByVcs(vcs, dirPath string) error {
switch vcs { switch vcs {
case "git": case "git":
stdout, _, err := com.ExecCmd("git", "status") branch, _, err := com.ExecCmd("git", "rev-parse", "--abbrev-ref", "HEAD")
if err != nil { 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()) 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) _, _, err = com.ExecCmd("git", "pull", "origin", branch)
if err != nil { if err != nil {
log.Error("", "Error occurs when 'git pull origin "+branch+"'") log.Error("", "Error occurs when 'git pull origin "+branch+"'")
@ -392,7 +385,14 @@ func updateByVcs(vcs, dirPath string) error {
log.Error("", "Error: "+stderr) log.Error("", "Error: "+stderr)
} }
case "svn": 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 return nil
} }

204
cmd/update.go

@ -15,13 +15,14 @@
package cmd package cmd
import ( import (
"encoding/json"
"fmt" "fmt"
"net/http"
"os" "os"
"os/exec" "os/exec"
"path" "path"
"path/filepath" "path/filepath"
"runtime" "runtime"
"strings"
"github.com/Unknwon/com" "github.com/Unknwon/com"
"github.com/codegangsta/cli" "github.com/codegangsta/cli"
@ -32,148 +33,128 @@ import (
var CmdUpdate = cli.Command{ var CmdUpdate = cli.Command{
Name: "update", Name: "update",
Usage: "update self", Usage: "check and update gopm resources including itself",
Description: `Command bin downloads and links dependencies according to gopmfile, Description: `Command update checks updates of resources and gopm itself.
and build executable binary to work directory
gopm update gopm update
Can only specify one each time, and only works for projects that Resources will be updated automatically after executed this command,
contains main package`, but you have to confirm before updaing gopm itself.`,
Action: runUpdate, Action: runUpdate,
Flags: []cli.Flag{
cli.BoolFlag{"verbose, v", "show process details"},
},
} }
func exePath() string { func exePath() string {
file, _ := exec.LookPath(os.Args[0]) file, err := exec.LookPath(os.Args[0])
path, _ := filepath.Abs(file) 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 return path
} }
func runUpdate(ctx *cli.Context) { type version struct {
doc.LoadPkgNameList(doc.HomeDir + "/data/pkgname.list") Gopm int
PackageNameList int `json:"package_name_list"`
}
installRepoPath = doc.HomeDir + "/repos" func runUpdate(ctx *cli.Context) {
setup(ctx)
// Check arguments. isAnythingUpdated := false
num := 0 // Load local version info.
localVerInfo := loadLocalVerInfo()
if len(ctx.Args()) != num { // Get remote version info.
log.Error("Update", "Fail to start command") var remoteVerInfo version
log.Fatal("", "Invalid argument number") 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. // Package name list.
info := "github.com/gpmgo/gopm" if remoteVerInfo.PackageNameList > localVerInfo.PackageNameList {
pkgPath := info log.Log("Updating pkgname.list...%v > %v",
ver := "" localVerInfo.PackageNameList, remoteVerInfo.PackageNameList)
var err error data, err := com.HttpGetBytes(http.DefaultClient, "https://raw2.github.com/gpmgo/docs/master/pkgname.list", nil)
if i := strings.Index(info, "@"); i > -1 { if err != nil {
pkgPath = info[:i] log.Error("Update", "Fail to update pkgname.list")
_, ver = validPath(info[i+1:]) log.Fatal("", err.Error())
} }
_, err = com.SaveFile(path.Join(doc.HomeDir, doc.PKG_NAME_LIST_PATH), data)
// Check package name. if err != nil {
if !strings.Contains(pkgPath, "/") { log.Error("Update", "Fail to save pkgname.list")
name, ok := doc.PackageNameList[pkgPath] log.Fatal("", err.Error())
if !ok {
log.Error("Update", "Invalid package name: "+pkgPath)
log.Fatal("", "No match in the package name list")
} }
pkgPath = name log.Log("Update pkgname.list to %v succeed!", remoteVerInfo.PackageNameList)
isAnythingUpdated = true
} }
// Get code. // Gopm.
stdout, _, _ := com.ExecCmd("gopm", "get", info) if remoteVerInfo.Gopm > localVerInfo.Gopm {
if len(stdout) > 0 { log.Log("Updating gopm...%v > %v",
fmt.Print(stdout) localVerInfo.Gopm, remoteVerInfo.Gopm)
} installRepoPath = doc.HomeDir + "/repos"
// Check if previous steps were successful. tmpDirPath := path.Join(doc.HomeDir, "temp")
repoPath := installRepoPath + "/" + pkgPath tmpBinPath := path.Join(tmpDirPath, "gopm")
if len(ver) > 0 { if runtime.GOOS == "windows" {
repoPath += "." + ver tmpBinPath += ".exe"
}
if !com.IsDir(repoPath) {
log.Error("Bin", "Fail to continue command")
log.Fatal("", "Previous steps weren't successful")
} }
wd, err := os.Getwd() 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 { if err != nil {
log.Error("Bin", "Fail to get work directory") log.Error("Update", "Fail to execute 'gopm bin -u -d github.com/gpmgo/gopm "+tmpDirPath+"'")
log.Fatal("", err.Error()) log.Fatal("", err.Error())
} }
if len(stderr) > 0 {
// Change to repository path. fmt.Print(stderr)
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 { if len(stdout) > 0 {
fmt.Print(stdout) fmt.Print(stdout)
} }
defer func() {
// Clean files.
os.RemoveAll(path.Join(repoPath, doc.VENDOR))
}()
// Check if previous steps were successful. // Check if previous steps were successful.
if com.IsFile(doc.GOPM_FILE_NAME) { if !com.IsExist(tmpBinPath) {
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.Error("Update", "Fail to continue command")
log.Fatal("", "Previous steps weren't successful or the project does not contain main package") log.Fatal("", "Previous steps weren't successful, no binary produced")
} }
movePath := exePath() movePath := exePath()
fmt.Print(movePath) log.Log("New binary will be replaced for %s", movePath)
// Move binary to given directory. // Move binary to given directory.
if runtime.GOOS != "windows" { if runtime.GOOS != "windows" {
err = os.Rename(binPath, movePath) err := os.Rename(tmpBinPath, movePath)
if err != nil { if err != nil {
log.Error("Update", "Fail to move binary") log.Error("Update", "Fail to move binary")
log.Fatal("", err.Error()) log.Fatal("", err.Error())
} }
os.Chmod(movePath+"/"+binName, os.ModePerm) os.Chmod(movePath+"/"+path.Base(tmpBinPath), os.ModePerm)
} else { } else {
batPath := filepath.Join(wd, "a.bat") batPath := filepath.Join(workDir, "a.bat")
f, err := os.Create(batPath) f, err := os.Create(batPath)
if err != nil { if err != nil {
log.Error("Update", "Fail to generate bat file") log.Error("Update", "Fail to generate bat file")
log.Fatal("", err.Error()) log.Fatal("", err.Error())
} }
f.WriteString(fmt.Sprintf(`ping -n 1 127.0.0.1>nul\ncopy "%v" "%v"\ndel "%v"\ndel "%v"`, f.WriteString(fmt.Sprintf(`ping -n 1 127.0.0.1>nul\ncopy "%v" "%v"\ndel "%v"\ndel "%v"`,
binPath, movePath, binPath, batPath)) tmpBinPath, movePath, tmpBinPath, batPath))
f.Close() f.Close()
attr := &os.ProcAttr{ attr := &os.ProcAttr{
Dir: wd, Dir: workDir,
Env: os.Environ(), Env: os.Environ(),
//Files: []*os.File{nil, nil, nil},
Files: []*os.File{os.Stdin, os.Stdout, os.Stderr}, Files: []*os.File{os.Stdin, os.Stdout, os.Stderr},
} }
@ -184,8 +165,43 @@ func runUpdate(ctx *cli.Context) {
} }
} }
log.Log("Changing work directory back to %s", wd)
os.Chdir(wd)
log.Success("SUCC", "Update", "Command execute successfully!") 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")
}
}
func loadLocalVerInfo() (ver version) {
verPath := path.Join(doc.HomeDir, doc.VER_PATH)
// First time run should not exist.
if !com.IsExist(verPath) {
return ver
}
f, err := os.Open(verPath)
if err != nil {
log.Error("Update", "Fail to open VERSION.json")
log.Fatal("", err.Error())
}
if err := json.NewDecoder(f).Decode(&ver); err != nil {
log.Error("Update", "Fail to decode VERSION.json")
log.Fatal("", err.Error())
}
return ver
} }

10
doc/conf.go

@ -28,6 +28,8 @@ import (
const ( const (
GOPM_FILE_NAME = ".gopmfile" GOPM_FILE_NAME = ".gopmfile"
PKG_NAME_LIST_PATH = "data/pkgname.list"
VER_PATH = "data/VERSION.json"
RawHomeDir = "~/.gopm" RawHomeDir = "~/.gopm"
) )
@ -47,7 +49,7 @@ func init() {
HomeDir = strings.Replace(RawHomeDir, "~", hd, -1) HomeDir = strings.Replace(RawHomeDir, "~", hd, -1)
LoadLocalNodes() LoadLocalNodes()
LoadPkgNameList(HomeDir + "/data/pkgname.list") LoadPkgNameList(path.Join(HomeDir, PKG_NAME_LIST_PATH))
} }
// NewGopmfile loads gopmgile in given directory. // NewGopmfile loads gopmgile in given directory.
@ -78,9 +80,13 @@ func LoadPkgNameList(filePath string) {
} }
pkgs := strings.Split(string(data), "\n") pkgs := strings.Split(string(data), "\n")
for _, line := range pkgs { for i, line := range pkgs {
infos := strings.Split(line, "=") infos := strings.Split(line, "=")
if len(infos) != 2 { 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.Error("", "Fail to parse package name: "+line)
log.Fatal("", "Invalid package name information") 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. // Test that go1.1 tag above is included in builds. main.go refers to this definition.
const go11tag = true const go11tag = true
const APP_VER = "0.6.1.0110" const APP_VER = "0.6.2.0113"
// //cmd.CmdSearch, // //cmd.CmdSearch,
// cmdClean, // cmdClean,
@ -57,7 +57,7 @@ func main() {
cmd.CmdRun, cmd.CmdRun,
cmd.CmdBuild, cmd.CmdBuild,
cmd.CmdInstall, cmd.CmdInstall,
//cmd.CmdUpdate, cmd.CmdUpdate,
//cmd.CmdTest, //cmd.CmdTest,
} }
app.Flags = append(app.Flags, []cli.Flag{ app.Flags = append(app.Flags, []cli.Flag{

Loading…
Cancel
Save