package main import ( "bytes" "encoding/json" "flag" "fmt" "io/ioutil" "log" "net/http" "os" "gopkg.in/ini.v1" ) // GetConfig fetch configuration func GetConfig(config *Config) { var configfile string var globalconfig GlobalConfig var githubconfig GitHubConfig var gogsconfig GogsConfig flag.Usage = Usage flag.StringVar(&configfile, "configfile", "github-to-gogs.ini", "config file to use with github-to-gogs section") flag.Parse() cfg, err := ini.Load(configfile) HandleFatalError(err) globalsection := cfg.Section("global") githubsection := cfg.Section("github") gogssection := cfg.Section("gogs") globalconfig.UserAgent = globalsection.Key("user_agent").String() globalconfig.RequestTimeout, err = globalsection.Key("request_timeout").Duration() HandleError(err) githubconfig.StarsPages = githubsection.Key("stars_pages").String() githubconfig.MaxPagesNumber, err = githubsection.Key("max_pages_number").Int() HandleError(err) githubconfig.AuthUsername = githubsection.Key("auth_username").String() githubconfig.AuthPassword = githubsection.Key("auth_password").String() githubconfig.ContentType = githubsection.Key("content_type").String() gogsconfig.UID = -1 gogsconfig.Username = gogssection.Key("username").String() gogsconfig.DestUsername = gogssection.Key("dest_username").String() gogsconfig.RepoURLTmpl = gogssection.Key("repo_url_tmpl").String() gogsconfig.OrgsURLTmpl = gogssection.Key("orgs_url_tmpl").String() gogsconfig.MigrateURL = gogssection.Key("migrate_url").String() gogsconfig.AuthToken = gogssection.Key("auth_token").String() gogsconfig.ContentType = gogssection.Key("content_type").String() gogsconfig.Mirror, err = gogssection.Key("mirror").Bool() HandleError(err) *config = Config{globalconfig: globalconfig, githubconfig: githubconfig, gogsconfig: gogsconfig} } // GetReposFromGitHub get starred repositories from github func GetReposFromGitHub(config *Config) []GitHubRepo { var repolist []GitHubRepo var repo []GitHubRepo for num := 1; num <= config.githubconfig.MaxPagesNumber; num++ { url := fmt.Sprintf(config.githubconfig.StarsPages, config.githubconfig.AuthUsername, num) resp := InvokeGitHub(config, url) err := json.Unmarshal(*GetResponseBody(resp), &repo) HandleError(err) for _, elem := range repo { repolist = append(repolist, elem) } } fmt.Println("Repositories from Github fetched !") return repolist } // InvokeGitHub ... func InvokeGitHub(config *Config, url string) *http.Response { req, err := http.NewRequest("GET", url, nil) HandleError(err) req.Header.Add("Content-Type", config.githubconfig.ContentType) req.Header.Set("User-Agent", config.globalconfig.UserAgent) req.SetBasicAuth(config.githubconfig.AuthUsername, config.githubconfig.AuthPassword) client := &http.Client{} resp, err := client.Do(req) HandleError(err) return resp } // GetResponseBody converts http responses bodies as bytes slice func GetResponseBody(resp *http.Response) *[]byte { bodyBytes, err := ioutil.ReadAll(resp.Body) HandleError(err) return &bodyBytes } // CheckGogsExistingRepo checks if there's an existing repository in gogs func CheckGogsExistingRepo(config *Config, repo GitHubRepo) bool { var isExists bool gogsrepourl := fmt.Sprintf(config.gogsconfig.RepoURLTmpl, config.gogsconfig.DestUsername, repo.Name) req, err := http.NewRequest("GET", gogsrepourl, nil) req.Header.Set("Authorization", config.gogsconfig.AuthToken) req.Header.Set("User-Agent", config.globalconfig.UserAgent) client := &http.Client{} resp, err := client.Do(req) HandleError(err) if resp.StatusCode == 200 { isExists = true } else { isExists = false } return isExists } // GetGogsUserUID get the logued user identifier func GetGogsUserUID(config *Config) { var gogsorg GogsOrg gogsrepourl := fmt.Sprintf(config.gogsconfig.OrgsURLTmpl, config.gogsconfig.DestUsername) req, err := http.NewRequest("GET", gogsrepourl, nil) req.Header.Set("Authorization", config.gogsconfig.AuthToken) req.Header.Set("User-Agent", config.globalconfig.UserAgent) client := &http.Client{} resp, err := client.Do(req) HandleError(err) err = json.Unmarshal(*GetResponseBody(resp), &gogsorg) HandleError(err) config.gogsconfig.UID = gogsorg.ID } // MigrateReposToGogs migrates input repositories to gogs func MigrateReposToGogs(config *Config, repolist []GitHubRepo) { fmt.Println("Migrate repos to Gogs...") client := &http.Client{} for _, elem := range repolist { if !CheckGogsExistingRepo(config, elem) { jsondata := fmt.Sprintf(`{"uid" : %d, "repo_name" : "%s" , "mirror" : %v, "clone_addr" : "%s"}`, config.gogsconfig.UID, elem.Name, true, elem.CloneURL) fmt.Println(fmt.Sprintf("Migrating repo %s to gogs rest api", elem.Name)) req, err := http.NewRequest("POST", config.gogsconfig.MigrateURL, bytes.NewBufferString(jsondata)) HandleError(err) req.Header.Add("Content-Type", config.gogsconfig.ContentType) req.Header.Set("User-Agent", config.globalconfig.UserAgent) req.Header.Set("Authorization", config.gogsconfig.AuthToken) client.Timeout = config.globalconfig.RequestTimeout _, err = client.Do(req) HandleFatalError(err) } else { fmt.Println(fmt.Sprintf("Not migrating, %s exists in gogs", elem.Name)) } } } // HandleError handles errors to return err func HandleError(err error) { if err != nil { log.Println(err) } } // HandleFatalError fatal errors func HandleFatalError(err error) { if err != nil { log.Fatal(err) os.Exit(2) } } // Usage displays possible arguments func Usage() { flag.PrintDefaults() os.Exit(1) }