-
Notifications
You must be signed in to change notification settings - Fork 4
/
main.go
107 lines (94 loc) · 3.03 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package main
import (
"context"
"flag"
"fmt"
"github.com/rm3l/gh-org-repo-sync/internal/github"
"github.com/rm3l/gh-org-repo-sync/internal/reposync"
"golang.org/x/sync/errgroup"
"log"
"os"
"strings"
"time"
)
const defaultBatchSize = 50
var nbRepos int
func main() {
start := time.Now()
defer func() {
log.Println("[info] done handling", nbRepos, "repositories in", time.Since(start))
}()
var dryRun bool
var query string
var batchSize int
var output string
var protocol string
var force bool
flag.BoolVar(&dryRun, "dry-run", false,
`dry run mode. to display the repos that will get cloned or updated,
without actually performing those actions`)
flag.StringVar(&query, "query", "",
`GitHub search query, to filter the Organization repositories.
Example: "language:Go stars:>10 pushed:>2010-11-12"
See https://bit.ly/3HurHe3 for more details on the search syntax`)
flag.IntVar(&batchSize, "batch-size", defaultBatchSize,
"the number of elements to retrieve at once. Must not exceed 100")
flag.StringVar(&protocol, "protocol", string(reposync.SystemProtocol),
fmt.Sprintf("the protocol to use for cloning. Possible values: %s, %s, %s.", reposync.SystemProtocol,
reposync.SSHProtocol, reposync.HTTPSProtocol))
flag.StringVar(&output, "output", ".", "the output path")
flag.BoolVar(&force, "force", false,
`whether to force sync repositories.
Caution: this will hard-reset the branch of the destination repository to match the source repository.`)
flag.Usage = func() {
//goland:noinspection GoUnhandledErrorResult
fmt.Fprintln(os.Stderr, "Usage: gh org-repo-sync <organization> [options]")
fmt.Println("Options: ")
flag.PrintDefaults()
}
if len(os.Args) < 2 {
//goland:noinspection GoUnhandledErrorResult
fmt.Fprintln(os.Stderr, "missing organization")
flag.Usage()
os.Exit(1)
}
organization := os.Args[1]
if organization == "-h" || organization == "-help" || organization == "--help" {
flag.Usage()
os.Exit(1)
} else {
// Ignore errors since flag.CommandLine is set for ExitOnError.
_ = flag.CommandLine.Parse(os.Args[2:])
}
if batchSize <= 0 || batchSize > 100 {
//goland:noinspection GoUnhandledErrorResult
fmt.Fprintf(os.Stderr, "invalid batch size (%d). Must be strictly higher than 0 and less than 100",
batchSize)
os.Exit(1)
}
cloneProtocol := reposync.CloneProtocol(strings.ToLower(protocol))
repositories, err := github.GetOrganizationRepos(organization, query, batchSize)
if err != nil {
log.Fatal(err)
}
nbRepos = len(repositories)
log.Println("[debug] found", nbRepos, "repositories")
if nbRepos == 0 {
return
}
g, ctx := errgroup.WithContext(context.Background())
for _, repository := range repositories {
g.Go(func(repo github.RepositoryInfo) func() error {
return func() error {
err := reposync.HandleRepository(ctx, dryRun, output, organization, repo, cloneProtocol, force)
if err != nil {
return fmt.Errorf("error while handling repo %q: %w", repo.Name, err)
}
return nil
}
}(repository))
}
if err := g.Wait(); err != nil {
panic(err)
}
}