clone and sync complete

This commit is contained in:
Zoker 2020-07-08 23:55:32 +08:00
parent 4c254a2c23
commit 09d8e17937
2 changed files with 60 additions and 44 deletions

View File

@ -3,6 +3,7 @@ package platform
import (
"encoding/json"
"fmt"
"os"
"strconv"
"strings"
"sync"
@ -16,7 +17,7 @@ import (
)
type RepoResult struct {
local string
source string
uri string
status int
error string
@ -73,7 +74,7 @@ func syncGitee(c *gcli.Command, args []string) error {
}
// check repodir and print projects to ensure
repos := share.ReadyToAuth(args[0], c.Name)
repos, source, orgPath := share.ReadyToAuth(args[0], c.Name)
if repos == nil {
return nil
}
@ -147,8 +148,20 @@ func syncGitee(c *gcli.Command, args []string) error {
}
// sync code
fmt.Println("\n", "Syncing Projects to Gitee, Please Wait...")
syncRes := multiSync(avaiRepo, auth, asExi)
var tmpDir string
if source == "local" {
fmt.Println("\n", "Syncing Projects to Gitee, Please Wait...")
} else {
currentDir, _ := os.Getwd()
tmpDir = fmt.Sprintf("%s/up2GitX-%s-%s", currentDir, source, orgPath)
if err := os.MkdirAll(tmpDir, 0755); err !=nil {
color.Red.Println(err.Error())
return nil
}
fmt.Printf("\nA tmp repo dir `%s` created for tmp repositories, you can remove it after sync successed\n", tmpDir)
fmt.Println("Cloning and Uploading Projects to Gitee, Please Wait...")
}
syncRes := multiSync(avaiRepo, auth, asExi, tmpDir)
showSyncRes(syncRes)
return nil
}
@ -159,18 +172,19 @@ func askForAccount() (string, bool, *http.BasicAuth) {
if len(email) == 0 || len(password) == 0 {
return "Email or Password must be provided!", false, nil
} else {
// replace your client_id and client_secret from Gitee
params := fmt.Sprintf(`{
"grant_type": "password",
"username": "%s",
"password": "%s",
"client_id": "xxxx", // client id from Gitee
"client_secret": "xxxx", // client secret from Gitee
"client_id": "xxxx",
"client_secret": "xxxx",
"scope": "user_info projects groups enterprises"
}`, email, password)
var paramsJson map[string]interface{}
json.Unmarshal([]byte(params), &paramsJson)
result, err := share.Post("https://gitee.com/oauth/token", paramsJson)
result, err := share.PostForm("https://gitee.com/oauth/token", paramsJson)
if err != nil {
return err.Error(), false, nil
@ -287,7 +301,7 @@ func createProject(path string, public string, token string, np []string, repoRe
uri = fmt.Sprintf("https://gitee.com/%s/%s.git", np[1], repoPath)
}
mutex.Lock()
*repoRes = append(*repoRes, RepoResult{local: path, uri: uri, status: eType, error: errMsg})
*repoRes = append(*repoRes, RepoResult{source: path, uri: uri, status: eType, error: errMsg})
mutex.Unlock()
}
@ -344,7 +358,7 @@ func printRepo(repoRes []RepoResult, status int) int {
} else {
result = item.uri
}
p = fmt.Sprintf("Dir: (%s)\n Status: %s\n Result: ", item.local, repoStatus)
p = fmt.Sprintf("Source: (%s)\n Status: %s\n Result: ", item.source, repoStatus)
colorRepo(status, p)
colorResult(status, result)
fmt.Printf(SPL)
@ -367,7 +381,7 @@ func printSync(syncRes []RepoResult, status int) {
} else {
result = item.error
}
p = fmt.Sprintf("Dir: (%s)\n Gitee: %s\n Result: ", item.local, item.uri)
p = fmt.Sprintf("Source: (%s)\n Gitee: %s\n Result: ", item.source, item.uri)
colorRepo(EXIST, p)
colorResult(item.status, result)
fmt.Printf(SPL)
@ -416,7 +430,7 @@ func colorResult(status int, p string) {
}
}
func multiSync(avaiRepo []RepoResult, auth *http.BasicAuth, force string) (syncRes []RepoResult) {
func multiSync(avaiRepo []RepoResult, auth *http.BasicAuth, force string, tmpDir string) (syncRes []RepoResult) {
step := progress.Bar(len(avaiRepo))
var wg sync.WaitGroup
var mutex = &sync.Mutex{}
@ -426,7 +440,7 @@ func multiSync(avaiRepo []RepoResult, auth *http.BasicAuth, force string) (syncR
wg.Add(len(avaiRepo))
for w := 1; w <= WORKER; w++ {
go multiSyncWorker(avais, auth, force, &syncRes, &wg, mutex, step)
go multiSyncWorker(avais, auth, force, &syncRes, &wg, mutex, step, tmpDir)
}
for _, p := range avaiRepo {
@ -441,9 +455,9 @@ func multiSync(avaiRepo []RepoResult, auth *http.BasicAuth, force string) (syncR
return syncRes
}
func multiSyncWorker(avais chan RepoResult, auth *http.BasicAuth, force string, syncRes *[]RepoResult, wg *sync.WaitGroup, mutex *sync.Mutex, step *progress.Progress) {
func multiSyncWorker(avais chan RepoResult, auth *http.BasicAuth, force string, syncRes *[]RepoResult, wg *sync.WaitGroup, mutex *sync.Mutex, step *progress.Progress, tmpDir string) {
for item := range avais {
err := share.SyncRepo(auth, item.local, item.uri, force)
err := share.SyncRepo(auth, item.source, item.uri, force, tmpDir)
if err != nil {
item.status = ERROR
item.error = err.Error()

View File

@ -7,7 +7,6 @@ import (
"io"
"io/ioutil"
NetHttp "net/http"
"net/url"
"os"
"path/filepath"
"regexp"
@ -213,7 +212,7 @@ func repoSize(path string) (float32, bool, error) {
return sizeMB, outOf1G, err
}
func ReadyToAuth(repoDir string, platform string) []string {
func ReadyToAuth(repoDir string, platform string) ([]string, string, string) {
if platform == "gitee" {
reg, err := regexp.Compile(`^github:.+`)
if err == nil && reg.MatchString(repoDir) {
@ -225,13 +224,13 @@ func ReadyToAuth(repoDir string, platform string) []string {
}
inPut, _ := interact.ReadLine("\nCheck if this repositories are what you expected, ready to the next step? (y/n) ")
if inPut == "y" {
return repos
return repos, repoDir[:6], repoDir[7:]
} else {
ExitMessage()
}
}
return nil, "", ""
}
return nil
}
if FileExists(repoDir) {
@ -243,7 +242,7 @@ func ReadyToAuth(repoDir string, platform string) []string {
printRepos(reposLocal)
inPut, _ := interact.ReadLine("\nCheck if this repositories are what you expected, ready to the next step? (y/n) ")
if inPut == "y" {
return repos
return repos, "local", ""
} else {
ExitMessage()
}
@ -251,7 +250,7 @@ func ReadyToAuth(repoDir string, platform string) []string {
} else {
color.Red.Println("The path you provided is not a dir or not exists")
}
return nil
return nil, "", ""
}
func ExitMessage() {
@ -285,26 +284,6 @@ func Get(url string) (map[string]interface{}, error) {
return result, nil
}
func Post(uri string, params map[string]interface{}) (map[string]interface{}, error) {
data := url.Values{}
for k, v := range params {
data.Add(k, v.(string))
}
response, err := NetHttp.PostForm(uri, data)
if err != nil {
color.Red.Printf("Request failed, Error: %s \n", err.Error())
return nil, err
}
defer response.Body.Close()
body, _ := ioutil.ReadAll(response.Body)
var result map[string]interface{}
json.Unmarshal(body, &result)
return result, nil
}
func PostForm(uri string, params map[string]interface{}) (map[string]interface{}, error) {
data := ""
for k, v := range params {
@ -366,12 +345,35 @@ func selectOne(items []string, ques string) string {
return interact.SelectOne(ques, items, "",)
}
func SyncRepo(auth *http.BasicAuth ,local string, uri string, force string) error {
var forceStr string
func SyncRepo(auth *http.BasicAuth ,source string, uri string, force string, tmpDir string) error {
var forceStr, repoPath, rHead string
// if project from api, clone it before pushing to target
if tmpDir != "" {
rHead = "remotes/origin"
repoSplit := strings.Split(source, "/")
repoName := repoSplit[len(repoSplit) - 1]
repoPath = fmt.Sprintf("%s/%s", tmpDir, repoName)
if r, err := git.PlainOpen(repoPath); err == nil { // fetch if repo exists
r.Fetch(&git.FetchOptions{
RefSpecs: []config.RefSpec{"refs/*:refs/*"},
})
} else {
_, err := git.PlainClone(repoPath, true, &git.CloneOptions{
URL: source,
RecurseSubmodules: git.DefaultSubmoduleRecursionDepth,
})
if err != nil {
return err
}
}
} else {
rHead = "heads"
repoPath = source
}
// generate a tmp remote
remote := fmt.Sprintf("up2GitX-%d", time.Now().Unix())
r, err := git.PlainOpen(local)
r, err := git.PlainOpen(repoPath)
if err != nil {
return err
}
@ -392,7 +394,7 @@ func SyncRepo(auth *http.BasicAuth ,local string, uri string, force string) erro
default:
forceStr = ""
}
rHeadStrings := fmt.Sprintf("%srefs/%s/*:refs/%s/*", forceStr, "heads", "heads")
rHeadStrings := fmt.Sprintf("%srefs/%s/*:refs/%s/*", forceStr, rHead, "heads")
rTagStrings := fmt.Sprintf("%srefs/%s/*:refs/%s/*", forceStr, "tags", "tags")
rHeads := config.RefSpec(rHeadStrings)
rTags := config.RefSpec(rTagStrings)