cmdargs
cmdargs copied to clipboard
Inconsistency in handling boolean arguments
It seems both --flag=value
and --flag value
style works for all argument types except booleans. Here is a small example to reproduce.
It could probably be made smaller by relying on implicits, but I am afraid of leaving things implicit, so everything is explicit. :)
{-# LANGUAGE DeriveDataTypeable #-}
module Test where
import Data.Data ( Data, Typeable )
import System.Console.CmdArgs
data Test
= Foo
{ flagS :: String
, flagI :: Int
, flagB :: Bool
}
deriving (Eq, Ord, Show, Data, Typeable)
ui :: Test
ui = modes
[ Foo
{ flagS
= "abc"
&= typ "STR"
&= name "flag-s"
&= name "s"
&= explicit
&= help "flag s"
, flagI
= 0
&= typ "INT"
&= name "flag-i"
&= name "i"
&= explicit
&= help "flag i"
, flagB
= True
&= typ "BOOL"
&= name "flag-b"
&= name "b"
&= explicit
&= help "flag b"
} &= name "foo"
&= explicit
&= help "do some foo"
] &= program "test"
&= helpArg [explicit, name "help"]
&= versionArg [explicit, name "version"]
&= summary "This is a test program"
&= help "This is a test program"
main :: IO ()
main = do
cli <- cmdArgs ui
print cli
test.sh
$ cat test.sh
stack runhaskell Test.hs -- -s X
stack runhaskell Test.hs -- -s=X
stack runhaskell Test.hs -- --flag-s X
stack runhaskell Test.hs -- --flag-s=X
stack runhaskell Test.hs -- -i 42
stack runhaskell Test.hs -- -i=42
stack runhaskell Test.hs -- --flag-i 42
stack runhaskell Test.hs -- --flag-i=42
stack runhaskell Test.hs -- -b off
stack runhaskell Test.hs -- -b=off
stack runhaskell Test.hs -- --flag-b off
stack runhaskell Test.hs -- --flag-b=off
$ bash test.sh
Foo {flagS = "X", flagI = 0, flagB = True}
Foo {flagS = "X", flagI = 0, flagB = True}
Foo {flagS = "X", flagI = 0, flagB = True}
Foo {flagS = "X", flagI = 0, flagB = True}
Foo {flagS = "abc", flagI = 42, flagB = True}
Foo {flagS = "abc", flagI = 42, flagB = True}
Foo {flagS = "abc", flagI = 42, flagB = True}
Foo {flagS = "abc", flagI = 42, flagB = True}
Unhandled argument, none expected: off
Foo {flagS = "abc", flagI = 0, flagB = False}
Unhandled argument, none expected: off
Foo {flagS = "abc", flagI = 0, flagB = False}
That inconsistency is actually deliberate, see https://hackage.haskell.org/package/cmdargs-0.10.20/docs/System-Console-CmdArgs-Explicit.html#v:FlagOptRare. Boolean arguments go into the rare category since normally you want to leave them unadorned, and have --flag off
be two separate arguments.