moto/generator/main.go

191 lines
3.9 KiB
Go
Raw Normal View History

2024-12-13 16:09:02 +08:00
package main
import (
"archive/tar"
"bytes"
"compress/gzip"
"errors"
"flag"
"fmt"
"io"
"net/http"
"os"
"path"
"runtime"
"strconv"
"strings"
"time"
)
var (
packageNameFlag = flag.String("package-name", "github.com/golang/example", "Application package name")
versionFlag = flag.String("version", "v0.0.1", "Application package version")
)
var (
oldPackageName = "git.nobla.cn/golang/moto"
)
func writeFile(dstFile string, r io.Reader) (err error) {
var (
fp *os.File
)
if fp, err = os.Create(dstFile); err != nil {
return
}
defer fp.Close()
_, err = io.Copy(fp, r)
return
}
func extractFile(file string, dirname string) (err error) {
var (
prefix string
fp *os.File
gzipReader *gzip.Reader
)
// 清理路径字符串
dirname = path.Clean(dirname)
// 打开压缩文件
if fp, err = os.Open(file); err != nil {
return
}
defer fp.Close()
// 执行解压操作
if gzipReader, err = gzip.NewReader(fp); err != nil {
return
}
defer gzipReader.Close()
tarReader := tar.NewReader(gzipReader)
for {
header, errRead := tarReader.Next()
if errRead != nil {
if errors.Is(errRead, io.EOF) {
break
}
err = errRead
break
}
if header.Typeflag == tar.TypeXGlobalHeader {
continue
}
fileInfo := header.FileInfo()
if prefix == "" && header.Typeflag == tar.TypeDir {
prefix = header.Name
continue
}
filename := path.Join(dirname, strings.TrimPrefix(header.Name, prefix))
if header.Typeflag == tar.TypeDir {
if err = os.MkdirAll(filename, fileInfo.Mode().Perm()); err != nil {
return
}
if runtime.GOOS != "windows" {
if err = os.Chmod(filename, fileInfo.Mode().Perm()); err != nil {
return
}
}
} else {
if err = writeFile(filename, tarReader); err != nil {
return err
}
if runtime.GOOS != "windows" {
if err = os.Chmod(filename, fileInfo.Mode().Perm()); err != nil {
return
}
}
}
}
return nil
}
func downloadPackage(version string, dirname string) (err error) {
var (
uri string
res *http.Response
)
uri = "https://git.nobla.cn/golang/moto/archive/" + version + ".tar.gz"
if res, err = http.Get(uri); err != nil {
return
}
defer func() {
res.Body.Close()
}()
if res.StatusCode != http.StatusOK {
err = errors.New(res.Status)
return
}
filename := path.Join(os.TempDir(), strconv.FormatInt(time.Now().UnixMilli(), 10)+".tar.gz")
if err = writeFile(filename, res.Body); err != nil {
return
}
err = extractFile(filename, dirname)
return
}
func replaceFiles(dirname string, source, replace string) (err error) {
var (
buf []byte
files []os.DirEntry
)
if files, err = os.ReadDir(dirname); err != nil {
if errors.Is(err, io.EOF) {
return nil
}
return err
}
sb := []byte(source)
rb := []byte(replace)
for _, file := range files {
if file.Name() == "." || file.Name() == ".." {
continue
}
filename := path.Join(dirname, file.Name())
if file.IsDir() {
err = replaceFiles(filename, source, replace)
} else {
if buf, err = os.ReadFile(filename); err == nil {
buf = bytes.ReplaceAll(buf, sb, rb)
os.WriteFile(filename, buf, 064)
}
}
}
return
}
func main() {
var (
pos int
err error
dirname string
appname string
packageName string
)
flag.Parse()
packageName = *packageNameFlag
pos = strings.LastIndexByte(packageName, '/')
if pos == -1 {
fmt.Println("package name invalid")
os.Exit(1)
}
appname = packageName[pos:]
if dirname, err = os.Getwd(); err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
dirname = path.Join(dirname, appname)
if err = os.MkdirAll(dirname, 0755); err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
if err = downloadPackage(*versionFlag, dirname); err != nil {
fmt.Println("download file error:" + err.Error())
os.Exit(1)
}
if err = replaceFiles(dirname, oldPackageName, packageName); err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
fmt.Println("Create project successful !!!")
}