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
602 stars 112 forks source link

is there any scaffolding already done for this (for example with cookiecutter)? #940

Closed Laurentiu-Andronache closed 3 years ago

Laurentiu-Andronache commented 4 years ago

I'm looking to build a package that's simultaneously a library, a CLI and a CLU. cmd2 seems perfect for the task, but I'd love to use some already existing scaffolding that has proper organization and proper code quality standards. Is there such a thing?

kotfu commented 4 years ago

We don't have any scaffolding or templates yet, although I think we should keep this issue open as the vehicle to create one. However, I have another project called tomcatmanager which offers a python library, a CLU, and a CLI using cmd2. It might give you some ideas about how to construct your application.

One note about the design of tomcatmanager. To avoid duplication of code logic, commands given on the command line (CLU mode) are just passed through to the CLI. There are two key classes, one is the library, the other is the cmd2 subclass which is the interactive CLI.

When operating as a CLU, you have to strip off the command line arguments and pass them into the cmd2 based CLI interpreter, and then get the exit codes back out so you get useful exit codes in the shell. This design has many benefits (command syntax is always the same in CLU and CLI, no duplication of code, etc), but it's a little tricky to make work exactly right as a CLU.

I advise taking a look at main.py to see how that works. The two key elements are argparse.REMAINDER, and onecmd_plus_hooks(). You will also need to set up entry_points in setup.py.

Hope this is helpful.

Laurentiu-Andronache commented 4 years ago

It's very helpful, thank you.

tleonhardt commented 4 years ago

@Laurentiu-Andronache Your question is a good one and it makes me thing that we should probably work on adding some documentation about overall application patterns and recommended best-practices for using cmd2.

I recently helped some coworkers setup a package that is essentially exactly what you are talking about - a library, a CLI and a CLU and we followed a very different overall architectural pattern than @kotfu followed for tomcatmanager. In our case we had a bunch of pre-existing legacy CLU scripts which used argparse for parsing command-line arguments and we wanted to tie everything together into an interactive CLI for convenience of distribution and discoverability.

First we did some mild refactoring of the existing CLU scripts so that there were functions like the following for a script foo:

Then we added a super thin do_foo() method to the CLI which uses the cmd2 argparse decorator and get_foo_parser() to setup the parsing and inside just calls foo(args).

NOTE: If we were writing all of the code from scratch and didn't already have the existing CLU scripts, then I think the approach @kotfu outlined above is probably a better one.

For the library we kept that in a separate package and then had a combined package for the CLI/CLU.

Some overall lessons learned regarding best practices:

Laurentiu-Andronache commented 4 years ago

Ultimately, we will still need that cookiecutter that you can just install in 2 seconds. And link to it in the documentation....

jayrod commented 3 years ago

I also believe that the plugin example should be a cookiecutter template as well. Ideally both templates would be linked together so that you could quickly stand up a CLI as a framework and then if needed create a bunch of plugins for it that are also separate projects.

tleonhardt commented 3 years ago

@jayrod I don't know the first ting about cookiecutter, but if you want to move forward with your example, I'm pretty sure others would be happy to polish it up a little. So where are cookie cutter templates typically published? As part of cookiecutter? As part of the package, e.g. cmd2? Or are they published separately?

jayrod commented 3 years ago

So where are cookie cutter templates typically published? As part of cookiecutter? As part of the package, e.g. cmd2? Or are they published separately?

They should be published separately on github. I imagine there might be a basic cookiecutter project and one that is a plugin project.

jayrod commented 3 years ago

My cookiecutter uses a custom plugin setup that I stole from one of the other projects that used cmd2. Perhaps the best practice should be to use the cmd2-plugin project already in the repo ??

tleonhardt commented 3 years ago

I'd recommend keeping any cookie cutter templates somewhere underneath the the python-cmd2 GitHub Organization for discoverability. I'd be fine with them being in the main repo under the plugins or in a separate repository. If anyone wants to help out, let us know and we can get you the access you need.

jayrod commented 3 years ago

I'd be more than willing to start from scratch. My cookie cutter template at the moment is a bit of a mess.

jayrod commented 3 years ago

So I started over and created a new cookiecutter project using the firstapp cmd2 example. As I started going down the meta project rabbit hole I can see how others might benefit from such a project. The template provides for a clean setup and install that is fairly basic.

I modeled it after the cookiecutter pypackage project and I think I'll just add it to my repo.

jayrod commented 3 years ago

@Laurentiu-Andronache

I just re-worked the cookiecutter template into a new repo. My old personal template was highly suggestive of the way I like to work and probably a bit complex for a starting place. The new repo name also reflects my intention to create other similar templates. This template is simple and basic

https://github.com/jayrod/cookiecutter-python-cmd2

I would like to make another template that is linux focused and will be XDGBDS compliant. This will allow me to start off with CMD2 features like default start up alias commands. The above repo is super super early in development but I am open for all issue requests and suggestions.

tleonhardt commented 3 years ago

Whenever you are happy with your template(s), please submit a PR that adds info on how to use them to the README and/or Sphinx docs.

jayrod commented 3 years ago

The project is actually at a decent place at the moment. I'd love some feedback on how far to go with it. It is a stripped down example of how to create a package around the basic_cmd2 example. I'm not sure exactly how to incorporate testing into it but I'd welcome some insights there.

I plan to add nox testing and bumpversion to the template as well but those items seem less worrisome.

jayrod commented 3 years ago

What is a CR btw??

tleonhardt commented 3 years ago

Ah sorry about the confusion. CR == Code Review, which in my mind is equivalent to a PR == Pull Request. To me, the two terms are synonymous. I think CR is a better term because it is more descriptive of the overall process. However, I try to stick with PR on GitHub to avoid confusion. But every now and then I slip up.

I'll take a look at your cookiecutter project sometime this weekend.

tleonhardt commented 3 years ago

@jayrod I tried running the cookie cutter template and got a crash due to an unhandled exception. I created an issue for it: https://github.com/jayrod/cookiecutter-python-cmd2/issues/11

tleonhardt commented 3 years ago

@jayrod After you pushed the doc instruction fix, I was able to create a basic cmd2 application using it. From taking a quick look, the code it generates looks OK to me. I'll experiment with it more later.

jayrod commented 3 years ago

@tleonhardt I polished it up today as well. I removed the isort dependency from the cookiecutter generation process and instead added it to the generated application. I also updated the Readme documentation with an ascii cinema walkthrough and finally (what I'm a bit happy with) is that I added a functional test case that works with pytest using the cmd2_ext_test plugin.

So you can use the cookiecutter template to quickly create a cmd2 application based on one of three examples and hit the ground runnings.

I think there are some smaller issues to work out with the documentation and I could perhaps go further and make it easy to deploy the app using a makefile or something but for the most part it's good to go.

I appreciate you taking a look at it.

jayrod commented 3 years ago

I got a little crazy and created a new template based on my plugin needs.

https://github.com/jayrod/cookiecutter-python-cmd2-ext-plug

It creates a base application that's ready to install and a sample plugin that's also installed in a separate package. It uses pluginlib to tie the two together via dynamic CommandSets.

I'm really happy with how it turned out and just how easy CMD2 made it.

tleonhardt commented 3 years ago

@Laurentiu-Andronache Can you please take a look at the cookiecutter templates that @jayrod has created?

I think these satisfy the request in this issue. But I would like some confirmation if possible.

tleonhardt commented 3 years ago

@jayrod I love that you made the advanced cookiecutter example that also creates a plugin and uses dynamic CommandSets!

jayrod commented 3 years ago

@jayrod I love that you made the advanced cookiecutter example that also creates a plugin and uses dynamic CommandSets!

Thanks, I also just added a second type of plugins that allows for Settables from afar as well. So you can define a CommandSet AND Settables to go along with them.

tleonhardt commented 3 years ago

Since there are now two nice cookiecutter templates and links to them from the README, I'm going to close this issue.