Prism: A Budding CLI Library!

Last thread was closed due to lack of updates, but Prism has been updated to support Mojo 0.26.2!

Inspired by: Cobra and urfave/cli!

Mojo Version
Build Status
Test Status
License: MIT

There’s lot’s of examples in the README and in the examples directory, but here’s a full-ish API example:

from std.sys import exit, stderr

from prism import Command, Flag, FlagSet, Version, no_args, read_args


fn base(args: List[String], flags: FlagSet) -> None:
    print("Pass a subcommand!")


fn connect(args: List[String], flags: FlagSet) raises -> None:
    if host := flags.get_string("host"):
        print("Connecting to", host.value())
    else:
        raise Error("Error: Exit Code 2")


fn my_exit(e: Error) -> None:
    print(e, file=stderr)
    if String(e) == "Error: Exit Code 2":
        print("Exiting with code 2")
        exit(2)
    else:
        exit(1)


fn allow_hosts(args: List[String], flags: FlagSet) raises -> None:
    var hosts = flags.get_string_list("hosts")
    if not hosts:
        print("Received no names to print.")
        return

    print("Allowing: ", hosts.value())


fn version(version: String) -> String:
    return "MyCLI version: " + version


fn validate_hosts(value: String) raises -> None:
    var approved_hosts: List[String] = ["localhost", "0.0.0.0", "192.168.1.1"]
    var hosts = value.split(" ")
    for host in hosts:
        if String(host) not in approved_hosts:
            raise Error(
                "ValueError: Host provided is not permitted.\nReceived: ",
                host,
                " Approved: ",
                approved_hosts,
            )


fn main() -> None:
    var cli = Command(
        name="connector",
        usage="Base Command.",
        run=base,
        exit=my_exit,
        version=Version("0.1.0", action=version),
        suggest=True,
        flags=[
            Flag.bool(name="required", shorthand="r0", usage="Always required.", required=True, persistent=True),
            Flag.string(
                name="host",
                shorthand="h",
                usage="Host",
                persistent=True,
                environment_variable="CONNECTOR_HOST",
                file_path="~/.myapp/config",
                default="localhost",
            ),
            Flag.string(
                name="port",
                shorthand="p",
                usage="Port",
                persistent=True,
            ),
            Flag.bool(
                name="automation",
                shorthand="a",
                usage="In automation?",
                persistent=True,
            ),
            Flag.bool(
                name="verbose",
                shorthand="vv",
                usage="Verbose output.",
                persistent=True,
            ),
        ],
        flags_required_together=["host", "port"],
        children=[
            Command(
                name="connect",
                usage="Connect to a database.",
                run=connect,
                aliases=["db-connect"],
                flags=[
                    Flag.bool(
                        name="also",
                        shorthand="a",
                        usage="Also always required.",
                        required=True,
                    ),
                    Flag.string(
                        name="uri",
                        shorthand="u",
                        usage="URI",
                    ),
                ],
                arg_validator=no_args,
                suggest=True,
            ),
            Command(
                name="allow",
                usage="Add hosts to the allow list!",
                run=allow_hosts,
                flags=[
                    Flag.string_list(
                        name="hosts",
                        shorthand="hl",
                        usage="Hosts to add to the allowlist.",
                        default=["localhost", "0.0.0.0"],
                        action=validate_hosts,
                    )
                ],
            ),
        ],
    )
    cli.execute(read_args())

Some alternatives:

4 Likes