commander-cli 0.2.0.1 → 0.3.0.0
raw patch · 4 files changed
+19/−33 lines, 4 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Options.Commander: data Usage :: * -> *
- Options.Commander: instance Options.Commander.HasProgram p => Options.Commander.HasProgram (Options.Commander.Usage p)
- Options.Commander: toplevel :: forall s p m a. (HasProgram p, KnownSymbol s, MonadIO m) => ProgramT p m a -> ProgramT (Named s & (("help" & Usage (Named s & p)) + p)) m a
+ Options.Commander: toplevel :: forall s p m a. (HasProgram p, KnownSymbol s, MonadIO m) => ProgramT p m () -> ProgramT (Named s & (("help" & Raw) + p)) m ()
- Options.Commander: usage :: HasProgram p => ProgramT (Usage p) m a
+ Options.Commander: usage :: forall p m a. (MonadIO m, HasProgram p) => ProgramT Raw m ()
Files
- README.md +4/−4
- app/Main.hs +4/−6
- commander-cli.cabal +2/−1
- src/Options/Commander.hs +9/−22
README.md view
@@ -16,16 +16,16 @@ ```haskell file :: ProgramT File IO-file = sub (arg \file -> arg \contents -> raw $ writeFile file contents) - :+: sub (arg \file -> raw $ readFile file >>= putStrLn)+file = sub (arg $ \file -> arg $ \contents -> raw $ writeFile file contents) + :+: sub (arg $ \file -> raw $ readFile file >>= putStrLn) ``` I can write a term of this type without specifying the File type by using the TypeApplications extension. ```haskell-file = sub @"writer" (arg @"file" \file -> arg @"contents" \contents -> raw $ writeFile file contents)- :+: sub @"reader" (arg @"file" \file -> raw $ readFile file >>= putStrLn)+file = sub @"writer" (arg @"file" $ \file -> arg @"contents" $ \contents -> raw $ writeFile file contents)+ :+: sub @"reader" (arg @"file" $ \file -> raw $ readFile file >>= putStrLn) ``` The library consists of a few basic types which are important for understanding
app/Main.hs view
@@ -20,16 +20,14 @@ import Data.Either type TaskManager- = Named "task-manager" & ( - "help" & Usage (Named "task-manager" & TaskManagerBasic)- + TaskManagerBasic)--type TaskManagerBasic- = "edit" & TaskProgram+ = Named "task-manager" &+ ( "help" & Raw+ + "edit" & TaskProgram + "open" & TaskProgram + "close" & TaskProgram + "tasks" & Raw + "priorities" & Raw+ ) type TaskProgram = Arg "task-name" String & Raw
commander-cli.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.4 name: commander-cli-version: 0.2.0.1+version: 0.3.0.0 synopsis: A command line argument/option parser library built around a monadic metaphor description: A command line argument/option parser library built around a monadic metaphor. homepage: https://github.com/SamuelSchlesinger/commander-cli@@ -17,6 +17,7 @@ library exposed-modules: Options.Commander other-extensions: ViewPatterns,+ DerivingVia, StandaloneDeriving, GeneralizedNewtypeDeriving, DerivingStrategies,
src/Options/Commander.hs view
@@ -54,9 +54,9 @@ -- ** Run CLI Programs command, command_, -- ** CLI Combinators- arg, opt, raw, sub, named, flag, toplevel, usage, (<+>),+ arg, opt, raw, sub, named, flag, toplevel, (<+>), usage, -- ** Type Level CLI Description- type (&), type (+), Arg, Opt, Named, Usage, Raw, Flag,+ type (&), type (+), Arg, Opt, Named, Raw, Flag, -- ** HasProgram(run, hoist, invocations), ProgramT(ArgProgramT, unArgProgramT,@@ -65,7 +65,6 @@ SubProgramT, unSubProgramT, NamedProgramT, unNamedProgramT, FlagProgramT, unFlagProgramT,- UsageProgramT, (:+:) ), -- ** The CommanderT Monad@@ -167,11 +166,6 @@ -- sake of documentation. data Named :: Symbol -> * --- | The type level usage combinator, taking a program type as an argument--- and being interpreted as a program which prints out all of the--- invocations of that particular program.-data Usage :: * -> *- -- | The type level program sequencing combinator, taking two program types -- and sequencing them one after another. data (&) :: k -> * -> *@@ -363,15 +357,6 @@ hoist n (RawProgramT m) = RawProgramT (n m) invocations = [mempty] -instance HasProgram p => HasProgram (Usage p) where- data ProgramT (Usage p) m a = UsageProgramT- run _ = Action $ \s -> do- liftIO $ do- putStrLn "usage:"- void . traverse (putStrLn . unpack) $ invocations @p- return (Defeat, s)- hoist _ _ = UsageProgramT- invocations = [mempty] instance (KnownSymbol name, KnownSymbol option, HasProgram p, Unrender t) => HasProgram (Opt option name t & p) where newtype ProgramT (Opt option name t & p) m a = OptProgramT { unOptProgramT :: Maybe t -> ProgramT p m a }@@ -483,9 +468,9 @@ -- | A convenience combinator that constructs the program I often want -- to run out of a program I want to write. toplevel :: forall s p m a. (HasProgram p, KnownSymbol s, MonadIO m) - => ProgramT p m a - -> ProgramT (Named s & ("help" & Usage (Named s & p) + p)) m a-toplevel p = named (sub usage :+: p) where+ => ProgramT p m () + -> ProgramT (Named s & ("help" & Raw + p)) m ()+toplevel p = named (sub (usage @(Named s & (p + "help" & Raw))) <+> p) -- | The command line program which consists of trying to enter one and -- then trying the other.@@ -496,5 +481,7 @@ -- | A meta-combinator that takes a type-level description of a command -- line program and produces a simple usage program.-usage :: HasProgram p => ProgramT (Usage p) m a-usage = UsageProgramT+usage :: forall p m a. (MonadIO m, HasProgram p) => ProgramT Raw m ()+usage = raw $ do+ liftIO $ putStrLn "usage:"+ void . traverse (liftIO . putStrLn . unpack) $ invocations @p