Skip to content

Commit

Permalink
feat: minimal working prototype
Browse files Browse the repository at this point in the history
- do not use src layout for the template app
- run ruff in silent mode
- typing improvements for ruff
- add missing packages
  • Loading branch information
ch-iv committed Aug 19, 2024
1 parent 8cf4d62 commit 9a0bafe
Show file tree
Hide file tree
Showing 14 changed files with 159 additions and 81 deletions.
129 changes: 80 additions & 49 deletions pdm.lock

Large diffs are not rendered by default.

36 changes: 20 additions & 16 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ authors = [
dependencies = [
"ruff>=0.5.4",
"Jinja2>=3.1.4",
"rich-click>=1.8.3",
"litestar[cryptography,standard]>=2.10.0",
]
requires-python = ">=3.8"
readme = "README.md"
Expand All @@ -17,19 +19,6 @@ license = {text = "MIT"}
requires = ["pdm-backend"]
build-backend = "pdm.backend"

[tool.pdm]
distribution = true

[tool.pdm.dev-dependencies]
dev = [
"litestar[standard,cryptography,jinja]>=2.9.1",
]
lint = [
"pyright>=1.1.376",
"mypy>=1.11.1",
"pre-commit>=3.5.0",
]

[project.scripts]
litestar = "litestar_manage.__main__:run_cli"

Expand Down Expand Up @@ -203,7 +192,7 @@ exclude = '''(?x)(
|^dist/
|^.venv/
|^node_modules/
|^migrations/
|^src/litestar_manage/template/
)
'''
implicit_reexport = false
Expand All @@ -214,6 +203,7 @@ warn_return_any = true
warn_unreachable = true
warn_unused_configs = true
warn_unused_ignores = true
mypy_path = "src/litestar_manage/stubs/"

[[tool.mypy.overrides]]
disallow_untyped_decorators = false
Expand Down Expand Up @@ -244,8 +234,8 @@ module = ["app.db.migrations.*", "app.lib.dto.*"]


[tool.pyright]
exclude = ["litestar_manage/template"]
include = ["litestar_manage", "tests"]
exclude = ["src/litestar_manage/template"]
include = ["src/litestar_manage", "tests"]

[tool.git-cliff.changelog]
body = """
Expand Down Expand Up @@ -309,3 +299,17 @@ sort_commits = "oldest"
split_commits = false
tag_pattern = "v[0-9]*"
topo_order = false

[tool.pdm]
distribution = true

[tool.pdm.dev-dependencies]
dev = [
"litestar[standard,cryptography,jinja]>=2.9.1",
]
lint = [
"pyright>=1.1.376",
"mypy>=1.11.1",
"pre-commit>=3.5.0",
"types-click>=7.1.8",
]
6 changes: 5 additions & 1 deletion src/litestar_manage/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
# SPDX-License-Identifier: MIT
from __future__ import annotations

from typing import cast

from rich_click import RichCommand


def run_cli() -> None:
"""Application Entrypoint."""
Expand All @@ -22,7 +26,7 @@ def run_cli() -> None:
print(exc) # noqa: T201
sys.exit(1)
else:
litestar_group.add_command(project_group)
litestar_group.add_command(cast(RichCommand, project_group))
run_litestar_cli()


Expand Down
3 changes: 1 addition & 2 deletions src/litestar_manage/cli.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from __future__ import annotations

import os
from pathlib import Path

from click import group, option
Expand All @@ -23,7 +22,7 @@ def project_group() -> None:
def init_project(app_name: str) -> None:
"""CLI command to initialize a Litestar project"""
template_dir = Path(__file__).parent / "template"
output_dir = Path(os.getcwd())
output_dir = Path.cwd()
ctx = RenderingContext(app_name=app_name)

render_template(template_dir, output_dir, ctx, run_ruff=True)
64 changes: 52 additions & 12 deletions src/litestar_manage/renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,23 @@
import os
import shutil
import subprocess
import sys
import sysconfig
from dataclasses import dataclass
from pathlib import Path
from typing import List

from jinja2 import Template
from ruff.__main__ import find_ruff_bin


def render_template(
template_dir: Path, output_dir: Path, ctx: RenderingContext, run_ruff: bool = True
template_dir: Path,
output_dir: Path,
ctx: RenderingContext,
run_ruff: bool = True,
) -> None:
"""Renders a template from template_dir to output_dir using the provided context.
Optionally runs ruff on the generated files."""
Optionally runs ruff on the generated files.
"""
_render_jinja_dir(template_dir, output_dir, ctx)

if run_ruff:
Expand All @@ -25,9 +29,10 @@ def render_template(
"I",
"--fix",
"--unsafe-fixes",
"--silent",
str(output_dir.absolute()),
)
_run_ruff("format", str(output_dir.absolute()))
_run_ruff("format", "--silent", str(output_dir.absolute()))


@dataclass
Expand All @@ -38,8 +43,10 @@ class RenderingContext:


def _render_jinja_dir(
input_directory: Path, output_directory: Path, ctx: RenderingContext
) -> List[Path]:
input_directory: Path,
output_directory: Path,
ctx: RenderingContext,
) -> list[Path]:
"""Recursively renders all files in the input directory to the output directory,
while preserving the file-tree structure. Returns the list of paths to the created files.
Expand All @@ -63,9 +70,11 @@ def _render_jinja_dir(

if render_body:
with (
open(path, "r", encoding="utf-8") as input_file,
open(
output_directory / rendered_name, "w", encoding="utf-8"
Path.open(path, encoding="utf-8") as input_file,
Path.open(
output_directory / rendered_name,
"w",
encoding="utf-8",
) as output_file,
):
output_file.write(Template(input_file.read()).render(ctx.__dict__))
Expand All @@ -77,13 +86,44 @@ def _render_jinja_dir(

elif path.is_dir():
files_written.extend(
_render_jinja_dir(path, output_directory / rendered_name, ctx)
_render_jinja_dir(path, output_directory / rendered_name, ctx),
)

return files_written


def find_ruff_bin() -> Path:
"""Return the ruff binary path."""

ruff_exe = Path("ruff" + sysconfig.get_config_var("EXE"))

scripts_path = Path(sysconfig.get_path("scripts")) / ruff_exe
if scripts_path.is_file():
return scripts_path

if sys.version_info >= (3, 10): # noqa: UP036
user_scheme = sysconfig.get_preferred_scheme("user")
elif os.name == "nt":
user_scheme = "nt_user"
elif sys.platform == "darwin" and sys._framework:
user_scheme = "osx_framework_user"
else:
user_scheme = "posix_user"

user_path = Path(sysconfig.get_path("scripts", scheme=user_scheme)) / ruff_exe
if user_path.is_file():
return user_path

# Search in `bin` adjacent to package root (as created by `pip install --target`).
pkg_root = Path(__file__).parent.parent
target_path = pkg_root / "bin" / ruff_exe
if target_path.is_file():
return target_path

raise FileNotFoundError(scripts_path)


def _run_ruff(*options: str) -> None:
"""Runs ruff with provided options"""
ruff = os.fsdecode(find_ruff_bin())
subprocess.run([ruff, *options])
subprocess.run([ruff, *options], check=False)
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def create_app() -> Litestar:
from app.controllers.web import WebController

logging_middleware_config = LoggingMiddlewareConfig()
session_config = CookieBackendConfig(secret=urandom(16)) # type: ignore
session_config = CookieBackendConfig(secret=urandom(16))

return Litestar(
route_handlers=[
Expand Down
File renamed without changes.
Empty file.

0 comments on commit 9a0bafe

Please sign in to comment.