in cmd/zoekt-mirror-github/main.go [55:183]
func main() {
dest := flag.String("dest", "", "destination directory")
githubURL := flag.String("url", "", "GitHub Enterprise url. If not set github.com will be used as the host.")
org := flag.String("org", "", "organization to mirror")
user := flag.String("user", "", "user to mirror")
token := flag.String("token",
filepath.Join(os.Getenv("HOME"), ".github-token"),
"file holding API token.")
forks := flag.Bool("forks", false, "also mirror forks.")
deleteRepos := flag.Bool("delete", false, "delete missing repos")
namePattern := flag.String("name", "", "only clone repos whose name matches the given regexp.")
excludePattern := flag.String("exclude", "", "don't mirror repos whose names match this regexp.")
topics := topicsFlag{}
flag.Var(&topics, "topic", "only clone repos whose have one of given topics. You can add multiple topics by setting this more than once.")
excludeTopics := topicsFlag{}
flag.Var(&excludeTopics, "exclude_topic", "don't clone repos whose have one of given topics. You can add multiple topics by setting this more than once.")
flag.Parse()
if *dest == "" {
log.Fatal("must set --dest")
}
if *githubURL == "" && *org == "" && *user == "" {
log.Fatal("must set either --org or --user when github.com is used as host")
}
var host string
var apiBaseURL string
var client *github.Client
if *githubURL != "" {
rootURL, err := url.Parse(*githubURL)
if err != nil {
log.Fatal(err)
}
host = rootURL.Host
apiPath, err := url.Parse("/api/v3/")
if err != nil {
log.Fatal(err)
}
apiBaseURL = rootURL.ResolveReference(apiPath).String()
client, err = github.NewEnterpriseClient(apiBaseURL, apiBaseURL, nil)
if err != nil {
log.Fatal(err)
}
} else {
host = "github.com"
apiBaseURL = "https://github.com/"
client = github.NewClient(nil)
}
destDir := filepath.Join(*dest, host)
if err := os.MkdirAll(destDir, 0o755); err != nil {
log.Fatal(err)
}
if *token != "" {
content, err := ioutil.ReadFile(*token)
if err != nil {
log.Fatal(err)
}
ts := oauth2.StaticTokenSource(
&oauth2.Token{
AccessToken: strings.TrimSpace(string(content)),
})
tc := oauth2.NewClient(context.Background(), ts)
if *githubURL != "" {
client, err = github.NewEnterpriseClient(apiBaseURL, apiBaseURL, tc)
if err != nil {
log.Fatal(err)
}
} else {
client = github.NewClient(tc)
}
}
reposFilters := reposFilters{
topics: topics,
excludeTopics: excludeTopics,
}
var repos []*github.Repository
var err error
if *org != "" {
repos, err = getOrgRepos(client, *org, reposFilters)
} else if *user != "" {
repos, err = getUserRepos(client, *user, reposFilters)
} else {
log.Printf("no user or org specified, cloning all repos.")
repos, err = getUserRepos(client, "", reposFilters)
}
if err != nil {
log.Fatal(err)
}
if !*forks {
trimmed := repos[:0]
for _, r := range repos {
if r.Fork == nil || !*r.Fork {
trimmed = append(trimmed, r)
}
}
repos = trimmed
}
filter, err := gitindex.NewFilter(*namePattern, *excludePattern)
if err != nil {
log.Fatal(err)
}
{
trimmed := repos[:0]
for _, r := range repos {
if filter.Include(*r.Name) {
trimmed = append(trimmed, r)
}
}
repos = trimmed
}
if err := cloneRepos(destDir, repos); err != nil {
log.Fatalf("cloneRepos: %v", err)
}
if *deleteRepos {
if err := deleteStaleRepos(*dest, filter, repos, *org+*user); err != nil {
log.Fatalf("deleteStaleRepos: %v", err)
}
}
}