diff --git a/README.md b/README.md index 31fd984..0675595 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,16 @@ #### 概述 1. 除特殊说明外,正常组件使用时在程序引导时调整用组件的Init进行配置初始化,使用New方法进行组件实例获取。 + +#### 组件下载工具 +1. 安装 +> go install myschools.me/suguo/norm/my:latest +2. 使用 +> my -dl mysql + #### 组件实现 * MySQL > "gorm.io/driver/mysql" > "gorm.io/gorm" > "gorm.io/gorm/logger" - > "gorm.io/plugin/dbresolver" \ No newline at end of file + > "gorm.io/plugin/dbresolver" diff --git a/my/main.go b/my/main.go new file mode 100644 index 0000000..f71eb25 --- /dev/null +++ b/my/main.go @@ -0,0 +1,120 @@ +/* +Author: suguo.yao(ysg@myschools.me) +Description: 用于从myschools.me中下载标准组件 +*/ +package main + +import ( + "flag" + "fmt" + "io" + "io/ioutil" + "net/http" + "os" + "path/filepath" + "regexp" + "strings" + "sync" + "time" +) + +const GITEA = "https://myschools.me" +const PATH = "/suguo/norm/src/branch/master" + +var path string + +func init() { + flag.StringVar(&path, "dl", "", "下载组件名") +} + +func main() { + flag.Parse() + if path == "" { + panic("下载组件名指定") + } + var client http.Client + var wg sync.WaitGroup + start := time.Now() + dl(client, path, &wg) + wg.Wait() + fmt.Printf("total time: %.2f s\n", float64(time.Since(start))/float64(time.Second)) +} + +// get all file link and download it +func dl(client http.Client, path string, wg *sync.WaitGroup) { + if !isExist(path) { + os.MkdirAll(path, 0775) + } + + url := fmt.Sprintf("%s%s/%s", GITEA, PATH, path) + html, err := getHtml(client, url) + if err != nil { + fmt.Printf("get html error: %s", err.Error()) + return + } + urlPattern := regexp.MustCompile(fmt.Sprintf(`%s/%s/\S*go`, PATH, path)) + links := urlPattern.FindAllSubmatch(html, -1) + for _, link := range links { + tmp := strings.Split(string(link[0]), "/") + filename := tmp[len(tmp)-1] + wg.Add(1) + go downloadFile(client, path, filename, wg) + + } +} + +// download file +func downloadFile(client http.Client, path, filename string, wg *sync.WaitGroup) { + defer wg.Done() + fmt.Println("start to download: ", filename) + fileURL := fmt.Sprintf("%s/suguo/norm/raw/branch/master/%s/%s", GITEA, path, filename) + resp, err := client.Get(fileURL) + if err != nil { + fmt.Printf("download file %s failed due to: %s\n", filename, err.Error()) + return + } + defer resp.Body.Close() + var buff [1024]byte + // 创建文件 + file, err := os.Create(filepath.Join(path, filename)) + if err != nil { + fmt.Printf("create file: %s error\n", filename) + return + } + defer file.Close() + // 写入文件 + for { + n, err := resp.Body.Read(buff[:]) + if err != nil { + if err == io.EOF { + file.Write(buff[:n]) + break + } + fmt.Println("error: ", err) + os.Remove(filepath.Join(path, filename)) + return + } + file.Write(buff[:n]) + } + fmt.Println("finish download:", filename) +} + +// get html source +func getHtml(client http.Client, url string) ([]byte, error) { + resp, err := client.Get(url) + if err != nil { + return nil, err + } + defer resp.Body.Close() + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + return data, nil +} + +// if file or directory exits +func isExist(path string) bool { + _, err := os.Stat(path) + return !os.IsNotExist(err) +}