@@ -506,6 +506,39 @@ func TestHelp(t *testing.T) {
506506 },
507507 wantErr : false ,
508508 },
509+ {
510+ name : "flag with env var" ,
511+ options : []cli.Option {
512+ cli .OverrideArgs ([]string {"--help" }),
513+ cli .Short ("A test command" ),
514+ cli .Flag (new (bool ), "force" , 'f' , "Force something" , cli.Env [bool ]("MYTOOL_FORCE" )),
515+ cli .Run (func (_ context.Context , _ * cli.Command ) error { return nil }),
516+ },
517+ wantErr : false ,
518+ },
519+ {
520+ name : "flags with multiple env vars" ,
521+ options : []cli.Option {
522+ cli .OverrideArgs ([]string {"--help" }),
523+ cli .Short ("A test command" ),
524+ cli .Flag (new (bool ), "force" , 'f' , "Force something" , cli.Env [bool ]("MYTOOL_FORCE" )),
525+ cli .Flag (new (int ), "count" , 'c' , "A much longer usage description here" , cli.Env [int ]("MYTOOL_COUNT" )),
526+ cli .Flag (new (string ), "name" , 'n' , "Name" , cli.Env [string ]("MYTOOL_NAME" )),
527+ cli .Run (func (_ context.Context , _ * cli.Command ) error { return nil }),
528+ },
529+ wantErr : false ,
530+ },
531+ {
532+ name : "flag with default and env var" ,
533+ options : []cli.Option {
534+ cli .OverrideArgs ([]string {"--help" }),
535+ cli .Short ("A test command" ),
536+ cli .Flag (new (int ), "count" , 'c' , "Count things" , cli .FlagDefault (5 ), cli.Env [int ]("MYTOOL_COUNT" )),
537+ cli .Flag (new (string ), "name" , 'n' , "A name" , cli.Env [string ]("MYTOOL_NAME" )),
538+ cli .Run (func (_ context.Context , _ * cli.Command ) error { return nil }),
539+ },
540+ wantErr : false ,
541+ },
509542 }
510543
511544 for _ , tt := range tests {
@@ -852,6 +885,85 @@ func TestExecuteNilCommand(t *testing.T) {
852885 }
853886}
854887
888+ func TestEnvFlag (t * testing.T ) {
889+ tests := []struct {
890+ name string
891+ setup func (t * testing.T )
892+ stdout string
893+ errMsg string
894+ args []string
895+ wantErr bool
896+ }{
897+ {
898+ name : "bool flag set via env var" ,
899+ setup : func (t * testing.T ) {
900+ t .Setenv ("MYTOOL_FORCE" , "true" )
901+ },
902+ stdout : "force: true\n " ,
903+ args : []string {},
904+ wantErr : false ,
905+ },
906+ {
907+ name : "CLI bool flag overrides env var" ,
908+ setup : func (t * testing.T ) {
909+ t .Setenv ("MYTOOL_FORCE" , "true" )
910+ },
911+ stdout : "force: false\n " ,
912+ args : []string {"--force=false" },
913+ wantErr : false ,
914+ },
915+ {
916+ name : "env var not set leaves flag at default" ,
917+ stdout : "force: false\n " ,
918+ args : []string {},
919+ wantErr : false ,
920+ },
921+ {
922+ name : "invalid env var value propagates error through Execute" ,
923+ setup : func (t * testing.T ) {
924+ t .Setenv ("MYTOOL_FORCE" , "notabool" )
925+ },
926+ args : []string {},
927+ wantErr : true ,
928+ errMsg : `failed to parse command flags: could not set flag from env: env var MYTOOL_FORCE: parse error: flag "force" received invalid value "notabool" (expected bool): strconv.ParseBool: parsing "notabool": invalid syntax` ,
929+ },
930+ }
931+
932+ for _ , tt := range tests {
933+ t .Run (tt .name , func (t * testing.T ) {
934+ if tt .setup != nil {
935+ tt .setup (t )
936+ }
937+
938+ var force bool
939+
940+ stdout := & bytes.Buffer {}
941+
942+ cmd , err := cli .New ("test" ,
943+ cli .Stdout (stdout ),
944+ cli .Flag (& force , "force" , flag .NoShortHand , "Force something" , cli.Env [bool ]("MYTOOL_FORCE" )),
945+ cli .OverrideArgs (tt .args ),
946+ cli .Run (func (ctx context.Context , cmd * cli.Command ) error {
947+ fmt .Fprintf (cmd .Stdout (), "force: %v\n " , force )
948+ return nil
949+ }),
950+ )
951+ test .Ok (t , err )
952+
953+ err = cmd .Execute (t .Context ())
954+ test .WantErr (t , err , tt .wantErr )
955+
956+ if tt .wantErr && tt .errMsg != "" {
957+ test .Equal (t , err .Error (), tt .errMsg )
958+ }
959+
960+ if ! tt .wantErr {
961+ test .Equal (t , stdout .String (), tt .stdout )
962+ }
963+ })
964+ }
965+ }
966+
855967// The order in which we apply options shouldn't matter, this test
856968// shuffles the order of the options and asserts the Command we get
857969// out behaves the same as a baseline.
0 commit comments