1 Star 0 Fork 0

白龙鱼 / gopm

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
update.go 5.82 KB
一键复制 编辑 原始数据 按行查看 历史
Unknown 提交于 2014-05-24 03:22 . Fix bugs
// Copyright 2013 gopm authors.
//
// Licensed under the Apache License, Version 2.0 (the "License"): you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
package cmd
import (
"encoding/json"
"fmt"
"net/http"
"os"
"os/exec"
"path"
"path/filepath"
"runtime"
"github.com/Unknwon/com"
"github.com/codegangsta/cli"
"github.com/gpmgo/gopm/doc"
"github.com/gpmgo/gopm/log"
)
var CmdUpdate = cli.Command{
Name: "update",
Usage: "check and update gopm resources including itself",
Description: `Command update checks updates of resources and gopm itself.
gopm update
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, 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
}
type version struct {
Gopm int
PackageNameList int `json:"package_name_list"`
}
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")
}
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
}
1
https://gitee.com/linqianxu/gopm.git
git@gitee.com:linqianxu/gopm.git
linqianxu
gopm
gopm
v0.6.5

搜索帮助