@@ -522,18 +522,26 @@ func (cmd *Command) Run(ctx context.Context, osArgs []string) (deferErr error) {
522
522
523
523
if cmd .Action == nil {
524
524
cmd .Action = helpCommandAction
525
- } else if len (cmd .Arguments ) > 0 {
526
- rargs := cmd .Args ().Slice ()
527
- tracef ("calling argparse with %[1]v" , rargs )
528
- for _ , arg := range cmd .Arguments {
529
- var err error
530
- rargs , err = arg .Parse (rargs )
531
- if err != nil {
532
- tracef ("calling with %[1]v (cmd=%[2]q)" , err , cmd .Name )
533
- return err
525
+ } else {
526
+ if err := cmd .checkPersistentRequiredFlags (); err != nil {
527
+ cmd .isInError = true
528
+ _ = ShowSubcommandHelp (cmd )
529
+ return err
530
+ }
531
+
532
+ if len (cmd .Arguments ) > 0 {
533
+ rargs := cmd .Args ().Slice ()
534
+ tracef ("calling argparse with %[1]v" , rargs )
535
+ for _ , arg := range cmd .Arguments {
536
+ var err error
537
+ rargs , err = arg .Parse (rargs )
538
+ if err != nil {
539
+ tracef ("calling with %[1]v (cmd=%[2]q)" , err , cmd .Name )
540
+ return err
541
+ }
534
542
}
543
+ cmd .parsedArgs = & stringSliceArgs {v : rargs }
535
544
}
536
- cmd .parsedArgs = & stringSliceArgs {v : rargs }
537
545
}
538
546
539
547
if err := cmd .Action (ctx , cmd ); err != nil {
@@ -840,26 +848,59 @@ func (cmd *Command) lookupFlagSet(name string) *flag.FlagSet {
840
848
return nil
841
849
}
842
850
851
+ func (cmd * Command ) checkRequiredFlag (f Flag ) (bool , string ) {
852
+ if rf , ok := f .(RequiredFlag ); ok && rf .IsRequired () {
853
+ flagPresent := false
854
+ flagName := ""
855
+
856
+ for _ , key := range f .Names () {
857
+ flagName = key
858
+
859
+ if cmd .IsSet (strings .TrimSpace (key )) {
860
+ flagPresent = true
861
+ }
862
+ }
863
+
864
+ if ! flagPresent && flagName != "" {
865
+ return false , flagName
866
+ }
867
+ }
868
+ return true , ""
869
+ }
870
+
843
871
func (cmd * Command ) checkRequiredFlags () requiredFlagsErr {
844
872
tracef ("checking for required flags (cmd=%[1]q)" , cmd .Name )
845
873
846
874
missingFlags := []string {}
847
875
848
876
for _ , f := range cmd .Flags {
849
- if rf , ok := f .(RequiredFlag ); ok && rf .IsRequired () {
850
- flagPresent := false
851
- flagName := ""
877
+ if pf , ok := f .(PersistentFlag ); ! ok || ! pf .IsPersistent () {
878
+ if ok , name := cmd .checkRequiredFlag (f ); ! ok {
879
+ missingFlags = append (missingFlags , name )
880
+ }
881
+ }
882
+ }
852
883
853
- for _ , key := range f . Names () {
854
- flagName = key
884
+ if len ( missingFlags ) != 0 {
885
+ tracef ( "found missing required flags %[1]q (cmd=%[2]q)" , missingFlags , cmd . Name )
855
886
856
- if cmd .IsSet (strings .TrimSpace (key )) {
857
- flagPresent = true
858
- }
859
- }
887
+ return & errRequiredFlags {missingFlags : missingFlags }
888
+ }
889
+
890
+ tracef ("all required flags set (cmd=%[1]q)" , cmd .Name )
891
+
892
+ return nil
893
+ }
894
+
895
+ func (cmd * Command ) checkPersistentRequiredFlags () requiredFlagsErr {
896
+ tracef ("checking for required flags (cmd=%[1]q)" , cmd .Name )
897
+
898
+ missingFlags := []string {}
860
899
861
- if ! flagPresent && flagName != "" {
862
- missingFlags = append (missingFlags , flagName )
900
+ for _ , f := range cmd .appliedFlags {
901
+ if pf , ok := f .(PersistentFlag ); ok && pf .IsPersistent () {
902
+ if ok , name := cmd .checkRequiredFlag (f ); ! ok {
903
+ missingFlags = append (missingFlags , name )
863
904
}
864
905
}
865
906
}
0 commit comments