package main import ( "archive/tar" "compress/gzip" "encoding/json" "errors" "flag" "fmt" "io" "io/ioutil" "log" "net/http" "net/url" "os" "path" "strings" "git.trj.tw/golang/utils" "github.com/sirupsen/logrus" ) var version string var workdir string var downloadDir = os.TempDir() var fileName = "koatmpl.tar" func init() { flag.StringVar(&version, "version", "", "template version") flag.StringVar(&workdir, "wd", "", "working directory") flag.Parse() } const apiHost = "https://git.trj.tw" const apiPath = "/api/v1/repos/nodejs/koa-template/tags" 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"` } 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 err := downloadTarball() if err != nil { log.Fatal(err) } err = extractTarball() 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) } fmt.Println(list) break default: log.Fatalf("argv not match") } } func extractTarball() (err error) { wd, err := os.Getwd() if err != nil { return err } if len(workdir) > 0 { wd = workdir } f, err := os.Open(path.Join(downloadDir, fileName)) if err != nil { return err } defer f.Close() gzf, err := gzip.NewReader(f) if err != nil { return err } defer gzf.Close() reader := tar.NewReader(gzf) for { header, err := reader.Next() if err == io.EOF { break } if err != nil { fmt.Println("err :::: ", err) return err } name := header.Name switch header.Typeflag { case tar.TypeDir: fmt.Println("Directory: ", name) err = os.Mkdir(path.Join(wd, name), 0775) if err != nil { return err } break case tar.TypeReg: fmt.Println("Regular FIle: ", name) data := make([]byte, header.Size) _, err = reader.Read(data) if err != nil { return err } err = ioutil.WriteFile(path.Join(wd, name), data, 664) if err != nil { return err } break default: fmt.Printf("%s : %c %s %s\n", "Unable to figure out type", header.Typeflag, "in file", name) } } return } func downloadTarball() (err error) { 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 { if v.Name == version { link = v.TarballURL } } if len(link) == 0 { return errors.New("version not match") } } else { link = tags[0].TarballURL } 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 } func getList() (tags []Tag, err error) { 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() body := make([]Tag, 0) b, err := ioutil.ReadAll(resp.Body) if err != nil { return } fmt.Println(string(b)) 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 { tags = append(tags, v.Name) } return }