koa-init/main.go

272 lines
4.8 KiB
Go
Raw Normal View History

2019-12-18 10:08:07 +00:00
package main
import (
2019-12-19 03:28:26 +00:00
"archive/zip"
2019-12-18 10:08:07 +00:00
"encoding/json"
"errors"
"flag"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"net/url"
"os"
"path"
2019-12-19 03:28:26 +00:00
"path/filepath"
2019-12-18 10:08:07 +00:00
"strings"
"git.trj.tw/golang/utils"
"github.com/sirupsen/logrus"
)
var version string
var workdir string
var downloadDir = os.TempDir()
2019-12-19 03:28:26 +00:00
var fileName = "koatmpl.zip"
2019-12-18 10:08:07 +00:00
func init() {
flag.StringVar(&version, "version", "", "template version")
flag.StringVar(&workdir, "wd", "", "working directory")
flag.Parse()
}
const apiHost = "https://git.trj.tw"
2019-12-19 03:28:26 +00:00
const apiPath = "/api/v1/repos/nodejs/koa-template/releases"
2019-12-18 10:08:07 +00:00
type Commit struct {
URL string `json:"url"`
SHA string `json:"sha"`
}
type Tag struct {
Name string `json:"name"`
ID string `json:"id"`
Commit Commit `json:"commit"`
ZipballURL string `json:"zipball_url"`
TarballURL string `json:"tarball_url"`
}
2019-12-19 03:28:26 +00:00
type Asset struct {
ID int `json:"id"`
Name string `json:"name"`
Size int64 `json:"size"`
DownloadCount int `json:"download_count"`
CreatedAt string `json:"created_at"`
UUID string `json:"uuid"`
BrowserDownloadURL string `json:"browser_download_url"`
}
type Release struct {
ID int `json:"id"`
TagName string `json:"tag_name"`
TargetCommitish string `json:"target_commitish"`
Name string `json:"name"`
Body string `json:"body"`
URL string `json:"url"`
TarballURL string `json:"tarball_url"`
ZipballURL string `json:"zipball_url"`
Draft bool `json:"draft"`
Prerelease bool `json:"prerelease"`
CreatedAt string `json:"created_at"`
PublishedAt string `json:"published_at"`
Assets []Asset `json:"assets"`
}
2019-12-18 10:08:07 +00:00
func main() {
args := flag.Args()
if len(workdir) > 0 {
workdir = utils.ParsePath(workdir)
if !utils.IsDir(workdir) {
log.Fatalf("target directory not exists")
}
}
if len(args) == 0 {
// download
2019-12-19 03:28:26 +00:00
err := downloadZipball()
2019-12-18 10:08:07 +00:00
if err != nil {
log.Fatal(err)
}
2019-12-19 03:28:26 +00:00
err = Unzip()
2019-12-18 10:08:07 +00:00
if err != nil {
log.Fatal(err)
}
fmt.Println("Success")
return
}
switch strings.ToLower(args[0]) {
case "list":
list, err := getTagList()
if err != nil {
log.Fatal(err)
}
2019-12-19 03:28:26 +00:00
fmt.Println("Release:")
for _, v := range list {
fmt.Println(v)
}
2019-12-18 10:08:07 +00:00
break
default:
log.Fatalf("argv not match")
}
}
2019-12-19 03:28:26 +00:00
func Unzip() (err error) {
2019-12-18 10:08:07 +00:00
wd, err := os.Getwd()
if err != nil {
return err
}
if len(workdir) > 0 {
wd = workdir
}
2019-12-19 03:28:26 +00:00
r, err := zip.OpenReader(path.Join(downloadDir, fileName))
2019-12-18 10:08:07 +00:00
if err != nil {
2019-12-19 03:28:26 +00:00
return
2019-12-18 10:08:07 +00:00
}
2019-12-19 03:28:26 +00:00
defer r.Close()
2019-12-18 10:08:07 +00:00
2019-12-19 03:28:26 +00:00
for _, f := range r.File {
fpath := filepath.Join(wd, f.Name)
if !strings.HasPrefix(fpath, filepath.Clean(wd)+string(os.PathSeparator)) {
return fmt.Errorf("%s: illegal file path", fpath)
}
2019-12-18 10:08:07 +00:00
2019-12-19 03:28:26 +00:00
if f.FileInfo().IsDir() {
if err := os.MkdirAll(fpath, 0775); err != nil {
return err
}
continue
}
2019-12-18 10:08:07 +00:00
2019-12-19 03:28:26 +00:00
if err := os.MkdirAll(filepath.Dir(fpath), 0775); err != nil && err != os.ErrExist {
return err
2019-12-18 10:08:07 +00:00
}
2019-12-19 03:28:26 +00:00
outFile, err := os.Create(fpath)
2019-12-18 10:08:07 +00:00
if err != nil {
return err
}
2019-12-19 03:28:26 +00:00
defer outFile.Close()
2019-12-18 10:08:07 +00:00
2019-12-19 03:28:26 +00:00
rc, err := f.Open()
if err != nil {
return err
}
defer rc.Close()
2019-12-18 10:08:07 +00:00
2019-12-19 03:28:26 +00:00
_, err = io.Copy(outFile, rc)
if err != nil {
return err
2019-12-18 10:08:07 +00:00
}
2019-12-19 03:28:26 +00:00
2019-12-18 10:08:07 +00:00
}
return
}
2019-12-19 03:28:26 +00:00
func downloadZipball() (err error) {
2019-12-18 10:08:07 +00:00
latest := true
if len(version) > 0 {
latest = false
}
tags, err := getList()
if err != nil {
return
}
if len(tags) == 0 {
return errors.New("no release tag")
}
link := ""
if latest == false {
for _, v := range tags {
2019-12-19 03:28:26 +00:00
if v.TagName == version {
for _, it := range v.Assets {
if it.Name == "release.zip" {
link = it.BrowserDownloadURL
}
}
2019-12-18 10:08:07 +00:00
}
}
} else {
2019-12-19 03:28:26 +00:00
for _, v := range tags[0].Assets {
if v.Name == "release.zip" {
link = v.BrowserDownloadURL
}
}
}
if len(link) == 0 {
return errors.New("get download link fail")
2019-12-18 10:08:07 +00:00
}
resp, err := http.DefaultClient.Get(link)
if err != nil {
return
}
defer resp.Body.Close()
f, err := os.Create(path.Join(downloadDir, fileName))
if err != nil {
return
}
_, err = io.Copy(f, resp.Body)
if err != nil {
return
}
return
}
2019-12-19 03:28:26 +00:00
func getList() (tags []Release, err error) {
2019-12-18 10:08:07 +00:00
u, err := url.Parse(apiHost)
if err != nil {
return
}
u, err = u.Parse(apiPath)
if err != nil {
return
}
req, err := http.NewRequest("GET", u.String(), nil)
if err != nil {
return
}
logrus.Debugf("Try send request to api: %s\n", u.String())
resp, err := http.DefaultClient.Do(req)
if err != nil {
return
}
defer resp.Body.Close()
2019-12-19 03:28:26 +00:00
body := make([]Release, 0)
2019-12-18 10:08:07 +00:00
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
return
}
err = json.Unmarshal(b, &body)
if err != nil {
return
}
return body, nil
}
func getTagList() (tags []string, err error) {
body, err := getList()
tags = make([]string, 0, len(body))
for _, v := range body {
2019-12-19 03:28:26 +00:00
tags = append(tags, v.TagName)
2019-12-18 10:08:07 +00:00
}
return
}