ohad / collie Goto Github PK
View Code? Open in Web Editor NEWCommand line interface library in Idris
License: Other
Command line interface library in Idris
License: Other
Commands can expect environment variables to be set, and these are available to the handler.
The environment variables can be typed, and will be parsed before being handed to the handler.
(proposed by @eayus )
Using a large number of subcommands seems to give the type checker trouble, and results in very long + high memory usage compile times. For example, consider the program below with 6 subcommands. On my machine, this uses 10G+ of memory, and I haven't managed to get it to finish type checking yet. It seems that compilation time is exponential wrt. the number of subcommands. I'm using the latest Idris2 pull.
module Slow
import Collie
mainCommand : Command "main"
mainCommand = MkCommand
{ description = ""
, subcommands = [ "x1" ::= basic "" none
, "x2" ::= basic "" none
, "x3" ::= basic "" none
, "x4" ::= basic "" none
, "x5" ::= basic "" none
, "x6" ::= basic "" none ]
, modifiers = []
, arguments = none }
main' : Slow.mainCommand ~~> IO ()
main' = [
\_ => putStrLn "Invalid command",
"x1" ::= [ ?x1 ],
"x2" ::= [ ?x2 ],
"x3" ::= [ ?x3 ],
"x4" ::= [ ?x4 ],
"x5" ::= [ ?x5 ],
"x6" ::= [ ?x6 ] ]
main : IO ()
main = Slow.mainCommand .handleWith main'
This is a self-contained file distilled from @mattpolzin's.
To call using
idris2 -p contrib -p collie Command.idr
module Command
import Collie
idv : Command "idv"
idv = MkCommand
{ description = ""
, subcommands =
[ "--help" ::= basic "Print this help text." none
, "list" ::= basic "List all installed and available Idris 2 versions." none
, "install" ::= installCommand
]
, modifiers = []
, arguments = none
}
where
installCommand : Command "install"
installCommand = MkCommand
{ name = "install"
, description = ""
, subcommands = []
, modifiers = ["--api" ::= flag ""]
, arguments = MkArguments False (Some String) Right
}
selectCommand : Command "select"
selectCommand = MkCommand
{ name = "select"
, description = ""
, subcommands =
[ "system" ::= basic "" none ]
, modifiers = []
, arguments = MkArguments False (Some String) Right
}
handleCommand' : Command.idv ~~> IO ()
handleCommand' =
[ const (putStrLn "Expected a subcommand.")
, "--help" ::= [ const $ putStrLn idv.usage ]
, "list" ::= [ const $ putStrLn "list" ]
, "install" ::= [ (\args => case args.arguments of
Nothing => putStrLn "fail"
Just version => if args.modifiers.project "--api"
then putStrLn "install plus API"
else putStrLn "just install"
) ]
]
Cf. how it's implemented in Idris:
https://github.com/idris-lang/Idris2/blob/main/src/Idris/SetOptions.idr#L187-L189
At the moment we only guarantee that there are no duplicates but we should replace
the String
type with one with stronger guarantees (using fromString
to provide
backwards compatible surface syntax).
Here are some (debatable) constraints:
--
or -
Thanks for this great start to a CLI library!
Currently, the usage output does not explicitly give an indication of the argument a command takes. It would be nice to show arguments using some familiar syntax to indicate required vs. optional (like <required>
and [optional]
).
I had expected that arguments (a la the arguments
field of the Command
record) would be required or at least I would have a way to indicate if they were required or not, but my first pass at adding a single argument resulted in a command that will succeed to parse whether the argument is given or not.
Is there a way to make a command fail to parse when an argument is absent instead of resulting in successful command parsing with Nothing
as the argument value?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.