Skip to content

Commit

Permalink
Add alias support and update help func output to include it. (#23)
Browse files Browse the repository at this point in the history
* update help command string output and add alias support

* update readme to remove aliases from todo
  • Loading branch information
thatstoasty authored Apr 28, 2024
1 parent 39bfd29 commit 21faf5d
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 22 deletions.
15 changes: 9 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ fn print_information(command: CommandArc, args: List[String]) -> None:
fn get_cat_fact(command: CommandArc, args: List[String]) -> Error:
var flags = command[].get_all_flags()[]
var flags = command[].flags[]
var lover = flags.get_as_bool("lover")
if lover and lover.value():
if lover and lover.value()[]:
print("Hello fellow cat lover!")
try:
Expand All @@ -54,7 +54,7 @@ fn get_cat_fact(command: CommandArc, args: List[String]) -> Error:
if not count:
return Error("Count flag was not found.")
var body = response.json()
for i in range(count.value()):
for i in range(count.value()[]):
print(body[i]["text"])
else:
return Error("Request failed!")
Expand Down Expand Up @@ -98,8 +98,8 @@ fn init() -> None:
description="Get some cat facts!",
erroring_run=get_cat_fact,
)
cat_command.flags.add_int_flag[name="count", shorthand="c", usage="Number of facts to get."]()
cat_command.flags.add_bool_flag[name="lover", shorthand="l", usage="Are you a cat lover?"]()
cat_command.add_int_flag(name="count", shorthand="c", usage="Number of facts to get.")
cat_command.add_bool_flag(name="lover", shorthand="l", usage="Are you a cat lover?")
var dog_command = Command(
name="dog",
Expand All @@ -116,7 +116,6 @@ fn init() -> None:
fn main() -> None:
init()
```

Start by navigating to the `nested` example directory.
Expand Down Expand Up @@ -201,7 +200,11 @@ Usage information will be printed the console by passing the `--help` flag.

- Add find suggestion logic to `Command` struct.
- Enable required flags.
- Add flag groups and mutually exclusive flags.
- Add subcommand groups.
- Enable usage function to return the results of a usage function upon calling wrong functions or commands.
- Replace print usage with writers to enable stdout/stderr/file writing.
- Update default help command to improve available commands and flags section.

### Improvements

Expand Down
Empty file added examples/aliases/__init__.mojo
Empty file.
30 changes: 30 additions & 0 deletions examples/aliases/root.mojo
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from memory._arc import Arc
from prism import Flag, Command, CommandArc
from prism.vector import to_string


fn test(command: CommandArc, args: List[String]) -> None:
print("Pass tool, object, or thing as a subcommand!")


fn tool_func(command: CommandArc, args: List[String]) -> None:
print("My tool!")


fn init() -> None:
var root_command = Command(
name="my",
description="This is a dummy command!",
run=test,
)

var tool_command = Command(
name="tool", description="This is a dummy command!", run=tool_func, aliases=List[String]("object", "thing")
)

root_command.add_command(tool_command)
root_command.execute()


fn main() -> None:
init()
49 changes: 33 additions & 16 deletions prism/command.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -24,28 +24,32 @@ fn get_args_as_list() -> List[String]:

fn default_help(command: Arc[Command]) -> String:
"""Prints the help information for the command."""
var cmd = command[]
var builder = StringBuilder()
_ = builder.write_string(cmd.description)
_ = builder.write_string("\n\n")
_ = builder.write_string(command[].description)

if command[].aliases:
_ = builder.write_string("\n\nAliases:")
_ = builder.write_string(sprintf("\n %s", to_string(command[].aliases)))

# Build usage statement arguments depending on the command's children and flags.
var full_command = cmd._full_command()
_ = builder.write_string(sprintf("Usage:\n %s%s", full_command, String(" [args]")))
if len(cmd.children) > 0:
var full_command = command[]._full_command()
_ = builder.write_string(sprintf("\n\nUsage:\n %s%s", full_command, String(" [args]")))
if len(command[].children) > 0:
_ = builder.write_string(" [command]")
if len(cmd.flags[]) > 0:
if len(command[].flags[]) > 0:
_ = builder.write_string(" [flags]")

_ = builder.write_string("\n\nAvailable commands:\n")
for child in cmd.children:
_ = builder.write_string(sprintf(" %s\n", str(child[][])))
if command[].children:
_ = builder.write_string("\n\nAvailable commands:\n")
for child in command[].children:
_ = builder.write_string(sprintf(" %s\n", str(child[][])))

_ = builder.write_string("\nAvailable flags:\n")
for flag in cmd.flag_list():
_ = builder.write_string(sprintf(" -%s, --%s %s\n", flag[][].shorthand, flag[][].name, flag[][].usage))
if command[].flag_list():
_ = builder.write_string("\n\nAvailable flags:\n")
for flag in command[].flag_list():
_ = builder.write_string(sprintf(" -%s, --%s %s\n", flag[][].shorthand, flag[][].name, flag[][].usage))

_ = builder.write_string(sprintf('Use "%s [command] --help" for more information about a command.', full_command))
_ = builder.write_string(sprintf('\nUse "%s [command] --help" for more information about a command.', full_command))
return str(builder)


Expand All @@ -70,7 +74,7 @@ fn parse_command_from_args(start: Command) -> (Command, List[String]):

for arg in args:
for command_ref in children:
if command_ref[][].name == arg[]:
if command_ref[][].name == arg[] or contains(command_ref[][].aliases, arg[]):
command = command_ref[][]
children = command.children
leftover_args_start_index += 1
Expand Down Expand Up @@ -100,12 +104,19 @@ struct Command(CollectionElement):
erroring_run: The function to run when the command is executed that returns an error.
erroring_pre_run: The function to run before the command is executed that returns an error.
erroring_post_run: The function to run after the command is executed that returns an error.
persisting_pre_run: The function to run before the command is executed. This persists to children.
persisting_post_run: The function to run after the command is executed. This persists to children.
persisting_erroring_pre_run: The function to run before the command is executed that returns an error. This persists to children.
persisting_erroring_post_run: The function to run after the command is executed that returns an error. This persists to children.
help: The function to generate help text for the command.
"""

var name: String
var description: String

# Aliases that can be used instead of the first word in name.
var aliases: List[String]

# Generates help text.
var help: HelpFunction

Expand Down Expand Up @@ -145,6 +156,7 @@ struct Command(CollectionElement):
inout self,
name: String,
description: String,
aliases: List[String] = List[String](),
valid_args: List[String] = List[String](),
run: Optional[CommandFunction] = None,
pre_run: Optional[CommandFunction] = None,
Expand All @@ -163,6 +175,7 @@ struct Command(CollectionElement):

self.name = name
self.description = description
self.aliases = aliases

self.help = help

Expand Down Expand Up @@ -200,6 +213,7 @@ struct Command(CollectionElement):
name: String,
description: String,
arg_validator: ArgValidator,
aliases: List[String] = List[String](),
valid_args: List[String] = List[String](),
run: Optional[CommandFunction] = None,
pre_run: Optional[CommandFunction] = None,
Expand All @@ -218,6 +232,7 @@ struct Command(CollectionElement):

self.name = name
self.description = description
self.aliases = aliases

self.help = help

Expand Down Expand Up @@ -250,6 +265,7 @@ struct Command(CollectionElement):
fn __copyinit__(inout self, existing: Self):
self.name = existing.name
self.description = existing.description
self.aliases = existing.aliases

self.help = existing.help

Expand Down Expand Up @@ -279,6 +295,7 @@ struct Command(CollectionElement):
fn __moveinit__(inout self, owned existing: Self):
self.name = existing.name^
self.description = existing.description^
self.aliases = existing.aliases^

self.help = existing.help

Expand Down Expand Up @@ -306,7 +323,7 @@ struct Command(CollectionElement):
self.parent = existing.parent^

fn __str__(self) -> String:
return "(Name: " + self.name + ", Description: " + self.description + ")"
return sprintf("(Name: %s, Description: %s)", self.name, self.description)

fn __repr__(inout self) -> String:
var parent_name: String = ""
Expand Down
2 changes: 2 additions & 0 deletions run_examples.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mkdir ./temp
mojo package prism -I ./external -o ./temp/prism.mojopkg

echo -e "Building binaries for all examples...\n"
mojo build examples/aliases/root.mojo -o temp/aliases
mojo build examples/hello_world/root.mojo -o temp/hello_world
mojo build examples/nested/nested.mojo -o temp/nested
mojo build examples/printer/printer.mojo -o temp/printer
Expand All @@ -15,6 +16,7 @@ mkdir -p temp/examples/read_csv/ && cp examples/read_csv/file.csv temp/examples/

echo -e "Executing examples...\n"
cd temp
./aliases my thing
./hello_world say hello
./nested get cat --count 5 -l
./printer "sample-text" --formatting=underline
Expand Down

0 comments on commit 21faf5d

Please sign in to comment.