@@ -9,11 +9,12 @@ import (
99 "runtime/pprof"
1010 "strconv"
1111
12+ "github.com/spf13/pflag"
13+
1214 "github.com/github/git-sizer/git"
15+ "github.com/github/git-sizer/internal/refopts"
1316 "github.com/github/git-sizer/isatty"
1417 "github.com/github/git-sizer/sizes"
15-
16- "github.com/spf13/pflag"
1718)
1819
1920const Usage = `usage: git-sizer [OPTS]
@@ -79,150 +80,6 @@ const Usage = `usage: git-sizer [OPTS]
7980var ReleaseVersion string
8081var BuildVersion string
8182
82- type filterValue struct {
83- // filter is the filter that will be modified if this option
84- // is used.
85- filter * git.ReferenceFilter
86-
87- // combiner specifies how the filter generated by this option
88- // is combined with the existing filter; i.e., does it cause
89- // the matching references to be included or excluded?
90- combiner git.Combiner
91-
92- // pattern, if it is set, is the pattern (prefix or regexp) to
93- // be matched. If it is not set, then the user must supply the
94- // pattern.
95- pattern string
96-
97- // regexp specifies whether `pattern` should be interpreted as
98- // a regexp (as opposed to a prefix).
99- regexp bool
100- }
101-
102- func (v * filterValue ) Set (s string ) error {
103- var filter git.ReferenceFilter
104- combiner := v .combiner
105-
106- var pattern string
107- if v .pattern != "" {
108- // The pattern is fixed for this option:
109- pattern = v .pattern
110-
111- // It's not really expected, but if the user supplied a
112- // `false` boolean value, invert the polarity:
113- b , err := strconv .ParseBool (s )
114- if err != nil {
115- return err
116- }
117- if ! b {
118- combiner = combiner .Inverted ()
119- }
120- } else {
121- // The user must supply the pattern.
122- pattern = s
123- }
124-
125- if v .regexp {
126- var err error
127- filter , err = git .RegexpFilter (pattern )
128- if err != nil {
129- return fmt .Errorf ("invalid regexp: %q" , s )
130- }
131- } else {
132- filter = git .PrefixFilter (pattern )
133- }
134-
135- * v .filter = combiner .Combine (* v .filter , filter )
136-
137- return nil
138- }
139-
140- func (v * filterValue ) Get () interface {} {
141- return nil
142- }
143-
144- func (v * filterValue ) String () string {
145- return ""
146- }
147-
148- func (v * filterValue ) Type () string {
149- if v .pattern != "" {
150- return "bool"
151- } else if v .regexp {
152- return "regexp"
153- } else {
154- return "prefix"
155- }
156- }
157-
158- type filterGroupValue struct {
159- filter * git.ReferenceFilter
160- repo * git.Repository
161- }
162-
163- func (v * filterGroupValue ) Set (name string ) error {
164- // At this point, it is not yet certain that the command was run
165- // inside a Git repository. If not, ignore this option (the
166- // command will error out anyway).
167- if v .repo == nil {
168- fmt .Fprintf (
169- os .Stderr ,
170- "warning: not in Git repository; ignoring '--refgroup' option.\n " ,
171- )
172- return nil
173- }
174-
175- config , err := v .repo .Config (fmt .Sprintf ("refgroup.%s" , name ))
176- if err != nil {
177- return err
178- }
179- for _ , entry := range config .Entries {
180- switch entry .Key {
181- case "include" :
182- * v .filter = git .Include .Combine (
183- * v .filter , git .PrefixFilter (entry .Value ),
184- )
185- case "includeregexp" :
186- filter , err := git .RegexpFilter (entry .Value )
187- if err != nil {
188- return fmt .Errorf (
189- "invalid regular expression for 'refgroup.%s.%s': %w" ,
190- name , entry .Key , err ,
191- )
192- }
193- * v .filter = git .Include .Combine (* v .filter , filter )
194- case "exclude" :
195- * v .filter = git .Exclude .Combine (
196- * v .filter , git .PrefixFilter (entry .Value ),
197- )
198- case "excluderegexp" :
199- filter , err := git .RegexpFilter (entry .Value )
200- if err != nil {
201- return fmt .Errorf (
202- "invalid regular expression for 'refgroup.%s.%s': %w" ,
203- name , entry .Key , err ,
204- )
205- }
206- * v .filter = git .Exclude .Combine (* v .filter , filter )
207- default :
208- // Ignore unrecognized keys.
209- }
210- }
211- return nil
212- }
213-
214- func (v * filterGroupValue ) Get () interface {} {
215- return nil
216- }
217-
218- func (v * filterGroupValue ) String () string {
219- return ""
220- }
221-
222- func (v * filterGroupValue ) Type () string {
223- return "name"
224- }
225-
22683func main () {
22784 err := mainImplementation (os .Args [1 :])
22885 if err != nil {
@@ -239,8 +96,6 @@ func mainImplementation(args []string) error {
23996 var threshold sizes.Threshold = 1
24097 var progress bool
24198 var version bool
242- var filter git.ReferenceFilter
243- var showRefs bool
24499
245100 // Try to open the repository, but it's not an error yet if this
246101 // fails, because the user might only be asking for `--help`.
@@ -254,88 +109,6 @@ func mainImplementation(args []string) error {
254109 fmt .Print (Usage )
255110 }
256111
257- flags .Var (
258- & filterValue {& filter , git .Include , "" , false }, "include" ,
259- "include specified references" ,
260- )
261- flags .Var (
262- & filterValue {& filter , git .Include , "" , true }, "include-regexp" ,
263- "include references matching the specified regular expression" ,
264- )
265- flags .Var (
266- & filterValue {& filter , git .Exclude , "" , false }, "exclude" ,
267- "exclude specified references" ,
268- )
269- flags .Var (
270- & filterValue {& filter , git .Exclude , "" , true }, "exclude-regexp" ,
271- "exclude references matching the specified regular expression" ,
272- )
273-
274- flag := flags .VarPF (
275- & filterValue {& filter , git .Include , "refs/heads" , false }, "branches" , "" ,
276- "process all branches" ,
277- )
278- flag .NoOptDefVal = "true"
279-
280- flag = flags .VarPF (
281- & filterValue {& filter , git .Exclude , "refs/heads" , false }, "no-branches" , "" ,
282- "exclude all branches" ,
283- )
284- flag .NoOptDefVal = "true"
285-
286- flag = flags .VarPF (
287- & filterValue {& filter , git .Include , "refs/tags" , false }, "tags" , "" ,
288- "process all tags" ,
289- )
290- flag .NoOptDefVal = "true"
291-
292- flag = flags .VarPF (
293- & filterValue {& filter , git .Exclude , "refs/tags" , false }, "no-tags" , "" ,
294- "exclude all tags" ,
295- )
296- flag .NoOptDefVal = "true"
297-
298- flag = flags .VarPF (
299- & filterValue {& filter , git .Include , "refs/remotes" , false }, "remotes" , "" ,
300- "process all remote-tracking references" ,
301- )
302- flag .NoOptDefVal = "true"
303-
304- flag = flags .VarPF (
305- & filterValue {& filter , git .Exclude , "refs/remotes" , false }, "no-remotes" , "" ,
306- "exclude all remote-tracking references" ,
307- )
308- flag .NoOptDefVal = "true"
309-
310- flag = flags .VarPF (
311- & filterValue {& filter , git .Include , "refs/notes" , false }, "notes" , "" ,
312- "process all git-notes references" ,
313- )
314- flag .NoOptDefVal = "true"
315-
316- flag = flags .VarPF (
317- & filterValue {& filter , git .Exclude , "refs/notes" , false }, "no-notes" , "" ,
318- "exclude all git-notes references" ,
319- )
320- flag .NoOptDefVal = "true"
321-
322- flag = flags .VarPF (
323- & filterValue {& filter , git .Include , "refs/stash" , true }, "stash" , "" ,
324- "process refs/stash" ,
325- )
326- flag .NoOptDefVal = "true"
327-
328- flag = flags .VarPF (
329- & filterValue {& filter , git .Exclude , "refs/stash" , true }, "no-stash" , "" ,
330- "exclude refs/stash" ,
331- )
332- flag .NoOptDefVal = "true"
333-
334- flag = flags .VarPF (
335- & filterGroupValue {& filter , repo }, "refgroup" , "" ,
336- "process references in refgroup defined by gitconfig" ,
337- )
338-
339112 flags .VarP (
340113 sizes .NewThresholdFlagValue (& threshold , 0 ),
341114 "verbose" , "v" , "report all statistics, whether concerning or not" ,
@@ -376,14 +149,20 @@ func mainImplementation(args []string) error {
376149 atty = false
377150 }
378151 flags .BoolVar (& progress , "progress" , atty , "report progress to stderr" )
379- flags .BoolVar (& showRefs , "show-refs" , false , "list the references being processed" )
380152 flags .BoolVar (& version , "version" , false , "report the git-sizer version number" )
381153 flags .Var (& NegatedBoolValue {& progress }, "no-progress" , "suppress progress output" )
382154 flags .Lookup ("no-progress" ).NoOptDefVal = "true"
383155
384156 flags .StringVar (& cpuprofile , "cpuprofile" , "" , "write cpu profile to file" )
385157 flags .MarkHidden ("cpuprofile" )
386158
159+ var rgb refopts.RefGroupBuilder
160+ var configger refopts.Configger
161+ if repo != nil {
162+ configger = repo
163+ }
164+ rgb .AddRefopts (flags , configger )
165+
387166 flags .SortFlags = false
388167
389168 err = flags .Parse (args )
@@ -469,20 +248,12 @@ func mainImplementation(args []string) error {
469248 progress = v
470249 }
471250
472- if filter == nil {
473- filter = git .AllReferencesFilter
474- }
475-
476- if showRefs {
477- fmt .Fprintf (os .Stderr , "References (included references marked with '+'):\n " )
478- filter = showRefFilter {filter }
479- }
480-
481- rg := refGrouper {
482- filter : filter ,
251+ rg , err := rgb .Finish ()
252+ if err != nil {
253+ return err
483254 }
484255
485- historySize , err := sizes .ScanRepositoryUsingGraph (repo , & rg , nameStyle , progress )
256+ historySize , err := sizes .ScanRepositoryUsingGraph (repo , rg , nameStyle , progress )
486257 if err != nil {
487258 return fmt .Errorf ("error scanning repository: %s" , err )
488259 }
@@ -511,29 +282,3 @@ func mainImplementation(args []string) error {
511282
512283 return nil
513284}
514-
515- type refGrouper struct {
516- filter git.ReferenceFilter
517- }
518-
519- func (rg * refGrouper ) Categorize (refname string ) (bool , []sizes.RefGroupSymbol ) {
520- return rg .filter .Filter (refname ), nil
521- }
522-
523- func (rg * refGrouper ) Groups () []sizes.RefGroup {
524- return nil
525- }
526-
527- type showRefFilter struct {
528- f git.ReferenceFilter
529- }
530-
531- func (f showRefFilter ) Filter (refname string ) bool {
532- b := f .f .Filter (refname )
533- if b {
534- fmt .Fprintf (os .Stderr , "+ %s\n " , refname )
535- } else {
536- fmt .Fprintf (os .Stderr , " %s\n " , refname )
537- }
538- return b
539- }
0 commit comments