-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: improve cli #3
Changes from 1 commit
b3d4b9e
a69693b
6082b8c
93e12d2
fdc3cf9
ef05377
eb577a9
83ee496
1a666c0
62445a9
65a20c0
f99b690
9837448
0831c8e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"python.testing.pytestArgs": [ | ||
"tests" | ||
], | ||
"python.testing.unittestEnabled": false, | ||
"python.testing.pytestEnabled": true | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Variables | ||
PYTHON := pdm run python | ||
PYTEST := pdm run pytest | ||
BLACK := pdm run black | ||
FIND := find | ||
|
||
# Directories | ||
SRC_DIR := src | ||
TEST_DIR := tests | ||
|
||
# Targets | ||
.PHONY: clean test run | ||
|
||
|
||
#Format the files | ||
format: | ||
$(BLACK) $(SRC_DIR) | ||
|
||
# Clean target to delete __pycache__ directories | ||
clean: | ||
$(FIND) . -type d -name "__pycache__" -exec rm -rf {} + | ||
|
||
test: | ||
$(PYTEST) $(TEST_DIR) -vv -s --showlocals |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,13 +7,13 @@ project using the Litestar CLI. | |
|
||
When the litestar-manage module is installed, it will extend the Litestar native CLI. To create a starter project, run the following command: | ||
|
||
``` | ||
```bash | ||
litestar project init --app-name MyProject | ||
``` | ||
|
||
This command is used to initialize a Litestar project named MyProject in the current working directory. MyProject will have the following tree structure: | ||
|
||
``` | ||
```bash | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a specific reason behind this change? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks cleaner in my opinion, I can remove it if you want |
||
app/ | ||
├─ templates/ | ||
│ ├─ index.html | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -306,6 +306,7 @@ distribution = true | |
[tool.pdm.dev-dependencies] | ||
dev = [ | ||
"litestar[standard,cryptography,jinja]>=2.9.1", | ||
"black>=24.8.0", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The project uses ruff for linting. Remove black dependency and lint the PR using ruff. |
||
] | ||
lint = [ | ||
"pyright>=1.1.376", | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,12 +10,17 @@ | |
from litestar_manage.venv_builder import PipVenvBuilder, init_venv | ||
|
||
|
||
@group(cls=LitestarGroup, name="project") | ||
def project_group() -> None: | ||
"""Manage Scaffolding Tasks.""" | ||
def is_project_initialized() -> bool: | ||
output_dir = Path.cwd() | ||
return (output_dir / "src").exists() or (output_dir / "venv").exists() | ||
|
||
|
||
@click.group(cls=LitestarGroup) | ||
def cli(): | ||
pass | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is meant to be an extension of the LItestar's CLI, so it doesn't really make sense for the group to be named CLI. Rename this group back to |
||
|
||
@project_group.command(name="init", help="Initialize a new Litestar project.") | ||
|
||
@cli.command(name="new", help="Initialize a new Litestar project.") | ||
@option( | ||
"--app-name", | ||
type=str, | ||
|
@@ -31,14 +36,38 @@ def project_group() -> None: | |
def init_project(app_name: str, venv: str | None) -> None: | ||
"""CLI command to initialize a Litestar project""" | ||
|
||
template_dir = Path(__file__).parent / "template" | ||
template_dir = Path(__file__).parent / "templates" / "app" | ||
output_dir = Path.cwd() | ||
ctx = RenderingContext(app_name=app_name) | ||
|
||
if is_project_initialized(): | ||
click.echo("Project already initialized.") | ||
return | ||
|
||
ctx = RenderingContext(app_name=app_name) | ||
render_template(template_dir, output_dir, ctx, run_ruff=True) | ||
|
||
packages_to_install = ["litestar"] | ||
venv_name = "venv" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't want to make assumptions about what the virtual environment name is, nor do we want to hard code that assumption. Factor out the virtual environment name into a constant and possibly make a list of possible venv names to check against. |
||
if venv == "pip": | ||
builder = PipVenvBuilder() | ||
init_venv(output_dir / venv_name, builder, packages_to_install) | ||
init_venv(output_dir / "venv", builder, packages_to_install) | ||
|
||
|
||
@cli.command(name="resource") | ||
@option( | ||
"--resource-name", | ||
"-n", | ||
type=str, | ||
required=True, | ||
) | ||
def generate_resource(resource_name: str) -> None: | ||
"""CLI command to generate a new resource (controller, service, dto, models, repository)""" | ||
|
||
if not is_project_initialized(): | ||
click.echo("Project not initialized. Please initialize the project first.") | ||
return | ||
|
||
template_dir = Path(__file__).parent / "templates" / "resource" | ||
output_dir = Path.cwd() / "src" / f"{resource_name.lower()}" | ||
ctx = RenderingContext(app_name=resource_name) | ||
|
||
render_template(template_dir, output_dir, ctx, run_ruff=True) |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
from typing import Dict | ||
|
||
from litestar import Controller, get | ||
from litestar.di import Provide | ||
from litestar.enums import MediaType | ||
from litestar.status_codes import HTTP_200_OK | ||
from src.app_service import AppService, provide_app_service | ||
|
||
|
||
class AppController(Controller): | ||
"""App controller.""" | ||
|
||
dependencies = {"app_service": Provide(provide_app_service)} | ||
|
||
@get(path="/", status_code=HTTP_200_OK, media_type=MediaType.JSON) | ||
async def index(self, app_service: AppService) -> Dict: | ||
"""App index""" | ||
return await app_service.app_info() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
from typing import Dict | ||
|
||
|
||
class AppService: | ||
"""App Service""" | ||
|
||
app_name = "" | ||
app_version = "0.1.0" | ||
|
||
async def app_info(self) -> Dict[str, str]: | ||
"""Return info about the app""" | ||
return {"app_name": self.app_name, "verion": self.app_version} | ||
|
||
|
||
def provide_app_service(): | ||
return AppService() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
from litestar.controller import Controller | ||
|
||
|
||
class {{app_name.capitalize()}}Controller(Controller): | ||
"""{{app_name.capitalize()}} Controller""" | ||
pass |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
from advanced_alchemy.extensions.litestar.dto import SQLAlchemyDTO, SQLAlchemyDTOConfig | ||
|
||
from src.{{app_name.lower()}}.models import {{app_name.capitalize()}} | ||
|
||
|
||
class {{app_name.capitalize()}}DTO(SQLAlchemyDTO[{{app_name.capitalize()}}]): | ||
""" | ||
{{app_name.capitalize()}} DTO | ||
""" | ||
config = SQLAlchemyDTOConfig() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from litestar.contrib.sqlalchemy.base import BigIntAuditBase | ||
from sqlalchemy.orm import Mapped, mapped_column, relationship | ||
|
||
|
||
class {{app_name.capitalize()}}(BigIntAuditBase): | ||
"""{{app_name.capitalize()}} in DB model""" | ||
pass |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from litestar.contrib.sqlalchemy.repository import SQLAlchemyAsyncRepository | ||
|
||
|
||
class {{app_name.capitalize()}}Repository(SQLAlchemyAsyncRepository[{{app_name.capitalize()}}]): # pylint: disable=duplicate-bases | ||
"""{{app_name.capitalize()}} SQLAlchemy Repository.""" | ||
|
||
model_type = {{app_name.capitalize()}} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
from advanced_alchemy.service import SQLAlchemyAsyncRepositoryService | ||
from src.{{app_name.lower()}}.repository import {{app_name.capitalize()}}Repository | ||
from src.{{app_name.lower()}}.models import {{app_name.capitalize()}} | ||
from typing import Any | ||
|
||
class {{app_name.capitalize()}}Service(SQLAlchemyAsyncRepositoryService[{{app_name.capitalize()}}]): | ||
""" {{app_name.capitalize()}} Service""" | ||
|
||
repository_type = {{app_name.capitalize()}}Repository | ||
|
||
def __init__(self, **repo_kwargs: Any) -> None: | ||
self.repository: {{app_name.capitalize()}}Repository = self.repository_type(**repo_kwargs) #type ignore | ||
self.model_type = self.repository.model_type |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
from pathlib import Path | ||
|
||
TEMPLATE_DIR = Path(__file__).parent.parent / "src" / "litestar_manage" / "template" | ||
TEMPLATE_DIR = Path(__file__).parent.parent / "src" / "litestar_manage" / "templates" / "app" | ||
RESOURCE_DIR = Path(__file__).parent.parent / "src" / "litestar_manage" / "templates" / "resource" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove IDE configuration files from the commit.