litestar
litestar copied to clipboard
Enhancement: Add a CLI
We should consider adding a CLI that will allow users to quickly scaffold a project with a default folder / file structure, readme, tooling etc.
A good example is the NestJS CLI.
I'd like to discuss this proposal in this issue.
poetry new is the first example that stands out to me. They have cleo.
We should consider adding a CLI that will allow users to quickly scaffold a project with a default folder / file structure, readme, tooling etc.
I think it is a great idea in context of Starlite project.
A good example is the NestJS CLI.
I really like the one that Vue 3 has: https://vuejs.org/guide/quick-start.html#local. Very powerful yet approachable.
Ok. So, let's talk about structure-
Given that you probably want to install a CLI as as a global executable outside your project, I think it might be a good idea to separate it out into its own package and publish it separately. I know sometimes the CLi is a part of the app, but I think here it's going to be an issue - the CLI should be independent from the starlite version IMO.
We should consider whether we want to split it to a different repo, or simply a folder in this repo.
Pros of different repo:
- Separation of concerns
- No shared dev dependencies
- Simpler release process
- No need for a monorepo or similar construct
Cons:
- A separate code base might make it harder to contribute, e.g. issues etc.
- Stars are spread across repos.
- No code sharing is possible (no biggy on this case)
Is there anything similar to npm init in Python world? Maybe just cookiecutter?
What about using cookiecutter together with clap? So you could create a separate repo for the template but still integrate the cli into the "main" repo while using cookiecutter as a base.
I'm open to this idea. I have no experience working with these tools tbh.
Alright I could do a proposal. In general do you care about dependencies in this project? For example is it a problem for using click instead of the default arg-parser?
Would it also mean cookiecutter was a dependency of the standard install?
It will be an extra dependency I assume, so it shouldnt be a problem.
Yes if we would integrate that here. As Goldziher said, I also dont see any problem from my side. But let me propose something and then we can have a further look into how to integrate it
Go for it man, I look forward to seeing your proposal. Thanks for getting involved!
What would be a good project-structure? I think something like this:
src # project root
├── admin-cli.py
├── main.py
├── /config # project configuration
│ ├── base.py # project settings
│ ├── local.py # local settings
│ ├── prod.py # production settings
├── /my_app
│ ├── controller.py
│ ├── model.py
│ ├── /tests
Easiest would be to include the folderstructure as some template, or have it in a zip.
The files itself could contain {{variables}} , which can be replaced using jinja2.
What would be a good project-structure? I think something like this:
src # project root ├── admin-cli.py ├── main.py ├── /config # project configuration │ ├── base.py # project settings │ ├── local.py # local settings │ ├── prod.py # production settings ├── /my_app │ ├── controller.py │ ├── model.py │ ├── /testsEasiest would be to include the folderstructure as some template, or have it in a zip. The files itself could contain
{{variables}}, which can be replaced usingjinja2.
cookie-cutter is a good option for generation.
As for the structure - I think @cofin and @peterschutt have some opinions there.
cookie-cutter is a good option for generation.
cookie-cutter is nice, but then it can only do one thing: build a project-structure. Cookie-cutter does more or less the same: take a template folderstructure, and search/replace with Jinja, and copy it to some destination.
When I read cli, I think of a command-line application that could be extended with new commands as well.
For example, in Django there are about 20 commands (startproject, startapp, clear_cache, create_superuser,... ), and each module can easily add new ones. (Such a cli could even call cookiecutter in the background if you really want to use that )
Cookiecutter can also run pre and post-generation callbacks but it would probably be best to call cookiecutter instead of having it do the calling
I dont have a strong opinion one way or the other - whatever works best.
Assigning this to myself
Ok, so for the CLI we need to flush out some requirements before we proceed. I will be closing this issue and create a discussion instead.
Reopening this because of popular demand
Todo
- [x] Basic CLI framework
- [x] CLI commands
- [x] Running an application
- [x] Application autodiscovery
- [x] Routing table overview
- [x] Utils to register commands dynamically
After experimenting with the CLI, and trying it out as a separate package I've come to the conclusion that it's not necessary or desirable for the following reasons:
Publishing it as a standalone package means that it should not have a hard dependency on Starlite. This also means that every code that interacts with Starlite needs to be imported within the commands that use it, leading to quite a bit of messy code. You can see this here
This decoupling also means that there's effectively only one command that's going to be usable when invoked outside of an already existing Starlite project: The command to create a new Starlite project.
Since there is only one command that doesn't depend on a Starlite installation (i.e. doesn't interact with an application instance) I think moving forward it makes most sense to publish a separate utility for this command. It really is its own thing and has, neither conceptually, code or usage wise, anything to do with the rest of the CLI. I propose we create a create-starlite-app package, that can simply be run e.g. with pipx run create-starlite-app and include the CLI parts that interact with an existing application with the regular starlite package.
This approach also means less dependencies required for each package (the only dependency they'd have in common would be click), which is always a nice thing and we could potentially include the CLI by default instead of an extra.