@@ -8,43 +8,71 @@ import (
88 "os/exec"
99 "path/filepath"
1010 "regexp"
11+ "strings"
1112 "text/template"
1213
1314 kingpin "gopkg.in/alecthomas/kingpin.v2"
1415)
1516
1617var (
18+ dir = kingpin .Flag ("dir" , "The name of the directory to clone into" ).Short ('d' ).Default ("." ).String ()
1719 dryRun = kingpin .Flag ("dry-run" , "Dry run" ).Bool ()
20+ reposFile = kingpin .Flag ("file" , "Repo is GitHub classroom repo" ).Short ('f' ).ExistingFile ()
1821 classroom = kingpin .Flag ("classroom" , "Repo is GitHub classroom repo" ).Bool ()
1922 jobs = kingpin .Flag ("jobs" , "The number of repos fetched at the same time" ).Short ('j' ).Default ("8" ).Int ()
2023 verbose = kingpin .Flag ("verbose" , "Verbose" ).Bool ()
2124 mrconfig = kingpin .Flag ("mrconfig" , "Create a myrepos .mrconfig file in the output directory" ).Default ("true" ).Bool ()
2225
2326 nwo = kingpin .Arg ("repo" , "GitHub owner/repo" ).String ()
24- dir = kingpin .Arg ("directory" , "The name of the directory to clone into" ).Default ("." ).String ()
2527
2628 repoRE = regexp .MustCompile (`^(?:https://github\.com/)?([^/]+)/([^/]+)$` )
2729)
2830
2931func main () {
3032 kingpin .Parse ()
31- if * nwo == "" {
33+ switch {
34+ case * reposFile == "" && * nwo == "" :
3235 kingpin .FatalUsage ("repo is a required argument" )
33- }
34- m := repoRE .FindStringSubmatch (* nwo )
35- if m == nil {
36- kingpin .FatalUsage ("repo must be in the format owner/repo" )
37- }
38- owner , name := m [1 ], m [2 ]
39- if err := run (owner , name ); err != nil {
40- kingpin .FatalIfError (err , "" )
36+
37+ case * reposFile != "" && * nwo != "" :
38+ kingpin .FatalUsage ("--file and repo are exclusive" )
39+ case * nwo != "" :
40+ m := repoRE .FindStringSubmatch (* nwo )
41+ if m == nil {
42+ kingpin .FatalUsage ("repo must be in the format owner/repo" )
43+ }
44+ owner , name := m [1 ], m [2 ]
45+ kingpin .FatalIfError (run (owner , name ), "" )
46+ case * reposFile != "" :
47+ kingpin .FatalIfError (runWithFiles (* reposFile ), "" )
4148 }
4249}
4350
4451type repoEntry struct {
4552 Dir , URL string
4653}
4754
55+ func runWithFiles (reposFile string ) error {
56+ dat , err := ioutil .ReadFile (reposFile )
57+ if err != nil {
58+ return err
59+ }
60+ var entries []repoEntry
61+ re := regexp .MustCompile (`(?m)^(?:https://github\.com/)?([^/]+)/(.+?)(?:\.git)?\s*(?:#.*)?$` )
62+ for _ , m := range re .FindAllStringSubmatch (string (dat ), - 1 ) {
63+ entries = append (entries , repoEntry {Dir : m [1 ], URL : strings .TrimSpace (m [0 ])})
64+ }
65+ if err := cloneRepos (entries , * dir ); err != nil {
66+ return err
67+ }
68+ if * mrconfig {
69+ if err := writeMrConfig (entries , * dir ); err != nil {
70+ return err
71+ }
72+ }
73+ return nil
74+ }
75+
4876func run (owner , name string ) error {
4977 repos , err := queryRepos (owner , name )
5078 if err != nil {
@@ -56,6 +84,7 @@ func run(owner, name string) error {
5684 prep = "without"
5785 }
5886 fmt .Fprintf (os .Stderr , "No entries. Try again %s the --classroom option.\n " , prep )
87+ return nil
5988 }
6089 var entries []repoEntry
6190 for _ , repo := range repos {
@@ -84,10 +113,12 @@ func queryRepos(owner, name string) ([]repoRecord, error) {
84113}
85114
86115func repoAuthor (repo repoRecord , name string ) string {
87- if * classroom {
116+ switch * classroom {
117+ case true :
88118 return repo .Name [len (name )+ 1 :]
119+ default :
120+ return repo .Owner
89121 }
90- return repo .Owner
91122}
92123
93124func cloneRepos (repos []repoEntry , dir string ) error {
@@ -105,13 +136,13 @@ func cloneRepos(repos []repoEntry, dir string) error {
105136 go func (repo repoEntry ) {
106137 sem <- true
107138 defer func () { <- sem }()
108- // dst := filepath.Join(dir, repo.owner)
109139 args := []string {"git" , "clone" , repo .URL , repo .Dir }
110140 if * dryRun {
111141 args = append ([]string {"echo" }, args ... )
112142 // time.Sleep(time.Second)
113143 }
114144 cmd := exec .Command (args [0 ], args [1 :]... )
145+ cmd .Dir = dir
115146 stdoutStderr , err := cmd .CombinedOutput ()
116147 if err != nil {
117148 errors <- fmt .Errorf ("%s: %s while trying to clone %s" , err , stdoutStderr , repo .URL )
0 commit comments