python-cmd2 / cmd2

cmd2 - quickly build feature-rich and user-friendly interactive command line applications in Python
https://cmd2.readthedocs.io/en/stable/
MIT License
610 stars 115 forks source link

Update cmd2 examples to reflect latest API changes #1000

Open anselor opened 4 years ago

anselor commented 4 years ago

We've made a lot of significant improvements in recent releases but some of our examples are still lagging behind a lot. There are cases where the examples no longer represent the easiest/cleanest solution or what we currently consider to be best practices when using cmd2.

Example Action Notes
alias_startup.py
arg_decorators.py remove/combine? Seems very similar to decorator_example.py
arg_print.py
argparse_completion.py
async_printing.py
basic.py Compare with first_app.py and hello_cmd2.py
basic_completion.py
cmd2_history.dat
cmd_as_argument.py Seems similar to decorator_example.py
colors.py
custom_parser.py
decorator_example.py remove/combine? Seems very similar to arg_decorators.py and decorator_example.py
dynamic_commands.py
environment.py
event_loops.py
example.py Also seems to overlap a lot with decorator_example.py
exit_code.py
first_app.py remove/combine? Seems similar to hello_cmd2.py
hello_cmd2.py remove/combine? Seems similar to first_app.py
help_categories.py
hooks.py
initialization.py
issue986.py
migrating.py
modular_commands_basic.py
modular_commands_dynamic.py
modular_commands_main.py
modular_subcommands.py
override_parser.py
paged_output.py
persistent_history.py
pirate.py
plumbum_colors.py
python_scripting.py
remove_builtin_commands.py
remove_settable.py
subcommands.py Update Use modular_subcommands.py as reference.
* swap getattr(args, 'func') for args.cmd2_handler.get()
table_creation.py
unicode_commands.py
jayrod commented 3 years ago

Can you give some guidelines on how one can "assess" an example. I definitely would like to jump in on one or two examples and rewrite them. Not sure where to start though.

kmvanbrunt commented 3 years ago

First check if the example matches the current API. We are usually pretty good about updating examples when APIs change, but I wouldn't be surprised if some examples are broken.

Then determine if you think the example is self-explanatory to a newcomer. This is subjective, but if you think you can make an example more clear, feel free to submit it.

anselor commented 3 years ago

@jayrod One of the things is we have examples that span a range of API changes over time.

We have some that are somewhat redundant in that they are copies/tweaks of another example. In these cases, it may make more sense to combine into a single example with lots of comments explaining the different things being demonstrated.

We probably also have some that are no longer representative of how we would recommend developers implement something based on the latest API improvements.

For example, today we would probably recommend you register/unregister CommandSets instead of manually hiding/showing commands.

kmvanbrunt commented 3 years ago

@anselor

For example, today we would probably recommend you register/unregister CommandSets instead of manually hiding/showing commands.

That's an interesting thing to bring up and could make for a good example. The CLI I work on is a good case for using CommandSets alongside enabling/disabling commands. The CommandSet feature allows me to easily place command functions and their respective resources in their own files. But my CLI has two modes, and in one mode a whole category of these commands aren't available. I could register/unregister their CommandSets each time a user switches modes. However, using the enabling/disabling command feature allows me to provide a custom message if a user tries to run a command which doesn't exist in the current mode.

So instead of it saying, "foo is not a recognized command, alias, or macro" a user is shown something like "foo is only available when in bar mode". Now they know to switch to the proper mode instead of being confused as to why a command no longer exists.

There are certainly other cases, like uninstalling a plugin, where I would want to unregister a CommandSet instead of just disabling commands.

jayrod commented 3 years ago

@kmvanbrunt

First check if the example matches the current API.

Soo.... how would I figure out which examples you speak of ;)

kmvanbrunt commented 3 years ago

@jayrod I used Pycharm to inspect the code in the examples directory. It found an "Unresolved reference" error in colors.py that I just fixed.

Doesn't look like there are any other API errors.