scaffld 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. scaffld/__init__.py +7 -0
  2. scaffld/__main__.py +8 -0
  3. scaffld/builtins/python-api/files/.github/workflows/ci.yml +26 -0
  4. scaffld/builtins/python-api/files/.gitignore +25 -0
  5. scaffld/builtins/python-api/files/.pre-commit-config.yaml +14 -0
  6. scaffld/builtins/python-api/files/LICENSE +1 -0
  7. scaffld/builtins/python-api/files/README.md +29 -0
  8. scaffld/builtins/python-api/files/pyproject.toml +30 -0
  9. scaffld/builtins/python-api/files/src/{{ package_name }}/__init__.py +7 -0
  10. scaffld/builtins/python-api/files/src/{{ package_name }}/app.py +21 -0
  11. scaffld/builtins/python-api/files/tests/test_app.py +17 -0
  12. scaffld/builtins/python-api/template.toml +4 -0
  13. scaffld/builtins/python-cli/files/.github/workflows/ci.yml +26 -0
  14. scaffld/builtins/python-cli/files/.gitignore +25 -0
  15. scaffld/builtins/python-cli/files/.pre-commit-config.yaml +14 -0
  16. scaffld/builtins/python-cli/files/LICENSE +1 -0
  17. scaffld/builtins/python-cli/files/README.md +30 -0
  18. scaffld/builtins/python-cli/files/pyproject.toml +29 -0
  19. scaffld/builtins/python-cli/files/src/{{ package_name }}/__init__.py +7 -0
  20. scaffld/builtins/python-cli/files/src/{{ package_name }}/cli.py +29 -0
  21. scaffld/builtins/python-cli/files/tests/test_cli.py +15 -0
  22. scaffld/builtins/python-cli/template.toml +4 -0
  23. scaffld/builtins/python-lib/files/.github/workflows/ci.yml +26 -0
  24. scaffld/builtins/python-lib/files/.gitignore +25 -0
  25. scaffld/builtins/python-lib/files/.pre-commit-config.yaml +14 -0
  26. scaffld/builtins/python-lib/files/LICENSE +1 -0
  27. scaffld/builtins/python-lib/files/README.md +31 -0
  28. scaffld/builtins/python-lib/files/pyproject.toml +27 -0
  29. scaffld/builtins/python-lib/files/src/{{ package_name }}/__init__.py +16 -0
  30. scaffld/builtins/python-lib/files/tests/test_{{ package_name }}.py +9 -0
  31. scaffld/builtins/python-lib/template.toml +4 -0
  32. scaffld/cli.py +291 -0
  33. scaffld/context.py +82 -0
  34. scaffld/generator.py +107 -0
  35. scaffld/licenses.py +97 -0
  36. scaffld/naming.py +105 -0
  37. scaffld/render.py +156 -0
  38. scaffld/templates.py +119 -0
  39. scaffld-0.1.0.dist-info/METADATA +219 -0
  40. scaffld-0.1.0.dist-info/RECORD +44 -0
  41. scaffld-0.1.0.dist-info/WHEEL +5 -0
  42. scaffld-0.1.0.dist-info/entry_points.txt +2 -0
  43. scaffld-0.1.0.dist-info/licenses/LICENSE +21 -0
  44. scaffld-0.1.0.dist-info/top_level.txt +1 -0
scaffld/__init__.py ADDED
@@ -0,0 +1,7 @@
1
+ """scaffld -- scaffold new projects in seconds with a friendly TUI."""
2
+
3
+ from __future__ import annotations
4
+
5
+ __version__ = "0.1.0"
6
+
7
+ __all__ = ["__version__"]
scaffld/__main__.py ADDED
@@ -0,0 +1,8 @@
1
+ """Enable ``python -m scaffld``."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from .cli import main
6
+
7
+ if __name__ == "__main__":
8
+ main()
@@ -0,0 +1,26 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ python-version: ["3.9", "3.10", "3.11", "3.12"]
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - name: Set up Python ${{ matrix.python-version }}
18
+ uses: actions/setup-python@v5
19
+ with:
20
+ python-version: ${{ matrix.python-version }}
21
+ - name: Install
22
+ run: |
23
+ python -m pip install --upgrade pip
24
+ pip install -e ".[dev]"
25
+ - name: Test
26
+ run: pytest -q
@@ -0,0 +1,25 @@
1
+ # Byte-compiled / optimized
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .eggs/
6
+ build/
7
+ dist/
8
+
9
+ # Virtual environments
10
+ .venv/
11
+ venv/
12
+ env/
13
+
14
+ # Test & coverage
15
+ .pytest_cache/
16
+ .coverage
17
+ htmlcov/
18
+ .tox/
19
+ .mypy_cache/
20
+ .ruff_cache/
21
+
22
+ # Editors / OS
23
+ .idea/
24
+ .vscode/
25
+ .DS_Store
@@ -0,0 +1,14 @@
1
+ repos:
2
+ - repo: https://github.com/astral-sh/ruff-pre-commit
3
+ rev: v0.6.9
4
+ hooks:
5
+ - id: ruff
6
+ args: [--fix]
7
+ - id: ruff-format
8
+ - repo: https://github.com/pre-commit/pre-commit-hooks
9
+ rev: v4.6.0
10
+ hooks:
11
+ - id: end-of-file-fixer
12
+ - id: trailing-whitespace
13
+ - id: check-yaml
14
+ - id: check-toml
@@ -0,0 +1 @@
1
+ {{ license_text }}
@@ -0,0 +1,29 @@
1
+ # {{ project_name }}
2
+
3
+ {{ description }}
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ python -m venv .venv && source .venv/bin/activate
9
+ pip install -e ".[dev]"
10
+ ```
11
+
12
+ ## Run
13
+
14
+ ```bash
15
+ uvicorn {{ package_name }}.app:app --reload
16
+ # GET http://127.0.0.1:8000/health -> {"status": "ok"}
17
+ # GET http://127.0.0.1:8000/greet/you -> {"message": "Hello, you!"}
18
+ ```
19
+
20
+ ## Development
21
+
22
+ ```bash
23
+ pytest
24
+ ```
25
+ {% if has_license %}
26
+ ## License
27
+
28
+ {{ license }}. See [LICENSE](LICENSE).
29
+ {% endif %}
@@ -0,0 +1,30 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "{{ project_slug }}"
7
+ version = "0.1.0"
8
+ description = "{{ description }}"
9
+ readme = "README.md"
10
+ requires-python = ">={{ python_version }}"
11
+ {% if has_license %}license = "{{ license }}"
12
+ license-files = ["LICENSE"]
13
+ {% endif %}authors = [{ name = "{{ author }}"{% if has_email %}, email = "{{ author_email }}"{% endif %} }]
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "Framework :: FastAPI",
17
+ ]
18
+ dependencies = [
19
+ "fastapi>=0.110",
20
+ "uvicorn[standard]>=0.29",
21
+ ]
22
+
23
+ [project.optional-dependencies]
24
+ dev = ["pytest>=8.0", "httpx>=0.27"]
25
+
26
+ [tool.setuptools.packages.find]
27
+ where = ["src"]
28
+
29
+ [tool.pytest.ini_options]
30
+ testpaths = ["tests"]
@@ -0,0 +1,7 @@
1
+ """{{ description }}"""
2
+
3
+ from __future__ import annotations
4
+
5
+ __version__ = "0.1.0"
6
+
7
+ __all__ = ["__version__"]
@@ -0,0 +1,21 @@
1
+ """FastAPI application for {{ project_name }}."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from fastapi import FastAPI
6
+
7
+ from . import __version__
8
+
9
+ app = FastAPI(title="{{ project_name }}", version=__version__)
10
+
11
+
12
+ @app.get("/health")
13
+ def health() -> dict[str, str]:
14
+ """Liveness probe."""
15
+ return {"status": "ok"}
16
+
17
+
18
+ @app.get("/greet/{name}")
19
+ def greet(name: str) -> dict[str, str]:
20
+ """Greet ``name``."""
21
+ return {"message": f"Hello, {name}!"}
@@ -0,0 +1,17 @@
1
+ from fastapi.testclient import TestClient
2
+
3
+ from {{ package_name }}.app import app
4
+
5
+ client = TestClient(app)
6
+
7
+
8
+ def test_health() -> None:
9
+ response = client.get("/health")
10
+ assert response.status_code == 200
11
+ assert response.json() == {"status": "ok"}
12
+
13
+
14
+ def test_greet() -> None:
15
+ response = client.get("/greet/{{ project_name }}")
16
+ assert response.status_code == 200
17
+ assert response.json() == {"message": "Hello, {{ project_name }}!"}
@@ -0,0 +1,4 @@
1
+ [template]
2
+ name = "python-api"
3
+ kind = "api"
4
+ description = "FastAPI service with a health route, typed handlers, and CI."
@@ -0,0 +1,26 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ python-version: ["3.9", "3.10", "3.11", "3.12"]
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - name: Set up Python ${{ matrix.python-version }}
18
+ uses: actions/setup-python@v5
19
+ with:
20
+ python-version: ${{ matrix.python-version }}
21
+ - name: Install
22
+ run: |
23
+ python -m pip install --upgrade pip
24
+ pip install -e ".[dev]"
25
+ - name: Test
26
+ run: pytest -q
@@ -0,0 +1,25 @@
1
+ # Byte-compiled / optimized
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .eggs/
6
+ build/
7
+ dist/
8
+
9
+ # Virtual environments
10
+ .venv/
11
+ venv/
12
+ env/
13
+
14
+ # Test & coverage
15
+ .pytest_cache/
16
+ .coverage
17
+ htmlcov/
18
+ .tox/
19
+ .mypy_cache/
20
+ .ruff_cache/
21
+
22
+ # Editors / OS
23
+ .idea/
24
+ .vscode/
25
+ .DS_Store
@@ -0,0 +1,14 @@
1
+ repos:
2
+ - repo: https://github.com/astral-sh/ruff-pre-commit
3
+ rev: v0.6.9
4
+ hooks:
5
+ - id: ruff
6
+ args: [--fix]
7
+ - id: ruff-format
8
+ - repo: https://github.com/pre-commit/pre-commit-hooks
9
+ rev: v4.6.0
10
+ hooks:
11
+ - id: end-of-file-fixer
12
+ - id: trailing-whitespace
13
+ - id: check-yaml
14
+ - id: check-toml
@@ -0,0 +1 @@
1
+ {{ license_text }}
@@ -0,0 +1,30 @@
1
+ # {{ project_name }}
2
+
3
+ {{ description }}
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ python -m venv .venv && source .venv/bin/activate
9
+ pip install -e ".[dev]"
10
+ ```
11
+
12
+ ## Usage
13
+
14
+ ```bash
15
+ {{ project_slug }} World
16
+ # -> Hello, World!
17
+
18
+ {{ project_slug }} --version
19
+ ```
20
+
21
+ ## Development
22
+
23
+ ```bash
24
+ pytest
25
+ ```
26
+ {% if has_license %}
27
+ ## License
28
+
29
+ {{ license }}. See [LICENSE](LICENSE).
30
+ {% endif %}
@@ -0,0 +1,29 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "{{ project_slug }}"
7
+ version = "0.1.0"
8
+ description = "{{ description }}"
9
+ readme = "README.md"
10
+ requires-python = ">={{ python_version }}"
11
+ {% if has_license %}license = "{{ license }}"
12
+ license-files = ["LICENSE"]
13
+ {% endif %}authors = [{ name = "{{ author }}"{% if has_email %}, email = "{{ author_email }}"{% endif %} }]
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "Environment :: Console",
17
+ ]
18
+
19
+ [project.optional-dependencies]
20
+ dev = ["pytest>=8.0"]
21
+
22
+ [project.scripts]
23
+ {{ project_slug }} = "{{ package_name }}.cli:main"
24
+
25
+ [tool.setuptools.packages.find]
26
+ where = ["src"]
27
+
28
+ [tool.pytest.ini_options]
29
+ testpaths = ["tests"]
@@ -0,0 +1,7 @@
1
+ """{{ description }}"""
2
+
3
+ from __future__ import annotations
4
+
5
+ __version__ = "0.1.0"
6
+
7
+ __all__ = ["__version__"]
@@ -0,0 +1,29 @@
1
+ """Command-line interface for {{ project_name }}."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ from typing import Optional, Sequence
7
+
8
+ from . import __version__
9
+
10
+
11
+ def build_parser() -> argparse.ArgumentParser:
12
+ parser = argparse.ArgumentParser(
13
+ prog="{{ project_slug }}",
14
+ description="{{ description }}",
15
+ )
16
+ parser.add_argument("--version", action="version", version=f"%(prog)s {__version__}")
17
+ parser.add_argument("name", nargs="?", default="world", help="who to greet")
18
+ return parser
19
+
20
+
21
+ def main(argv: Optional[Sequence[str]] = None) -> int:
22
+ """Entry point. Returns a process exit code."""
23
+ args = build_parser().parse_args(argv)
24
+ print(f"Hello, {args.name}!")
25
+ return 0
26
+
27
+
28
+ if __name__ == "__main__":
29
+ raise SystemExit(main())
@@ -0,0 +1,15 @@
1
+ from {{ package_name }}.cli import build_parser, main
2
+
3
+
4
+ def test_default_greeting(capsys) -> None:
5
+ assert main([]) == 0
6
+ assert capsys.readouterr().out.strip() == "Hello, world!"
7
+
8
+
9
+ def test_named_greeting(capsys) -> None:
10
+ assert main(["scaffld"]) == 0
11
+ assert capsys.readouterr().out.strip() == "Hello, scaffld!"
12
+
13
+
14
+ def test_parser_builds() -> None:
15
+ assert build_parser().prog == "{{ project_slug }}"
@@ -0,0 +1,4 @@
1
+ [template]
2
+ name = "python-cli"
3
+ kind = "cli"
4
+ description = "Zero-dependency argparse CLI with a console-script entry point."
@@ -0,0 +1,26 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ python-version: ["3.9", "3.10", "3.11", "3.12"]
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - name: Set up Python ${{ matrix.python-version }}
18
+ uses: actions/setup-python@v5
19
+ with:
20
+ python-version: ${{ matrix.python-version }}
21
+ - name: Install
22
+ run: |
23
+ python -m pip install --upgrade pip
24
+ pip install -e ".[dev]"
25
+ - name: Test
26
+ run: pytest -q
@@ -0,0 +1,25 @@
1
+ # Byte-compiled / optimized
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .eggs/
6
+ build/
7
+ dist/
8
+
9
+ # Virtual environments
10
+ .venv/
11
+ venv/
12
+ env/
13
+
14
+ # Test & coverage
15
+ .pytest_cache/
16
+ .coverage
17
+ htmlcov/
18
+ .tox/
19
+ .mypy_cache/
20
+ .ruff_cache/
21
+
22
+ # Editors / OS
23
+ .idea/
24
+ .vscode/
25
+ .DS_Store
@@ -0,0 +1,14 @@
1
+ repos:
2
+ - repo: https://github.com/astral-sh/ruff-pre-commit
3
+ rev: v0.6.9
4
+ hooks:
5
+ - id: ruff
6
+ args: [--fix]
7
+ - id: ruff-format
8
+ - repo: https://github.com/pre-commit/pre-commit-hooks
9
+ rev: v4.6.0
10
+ hooks:
11
+ - id: end-of-file-fixer
12
+ - id: trailing-whitespace
13
+ - id: check-yaml
14
+ - id: check-toml
@@ -0,0 +1 @@
1
+ {{ license_text }}
@@ -0,0 +1,31 @@
1
+ # {{ project_name }}
2
+
3
+ {{ description }}
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ python -m venv .venv && source .venv/bin/activate
9
+ pip install -e ".[dev]"
10
+ ```
11
+
12
+ ## Usage
13
+
14
+ ```python
15
+ from {{ package_name }} import greet
16
+
17
+ print(greet("{{ project_name }}"))
18
+ # -> Hello, {{ project_name }}!
19
+ ```
20
+
21
+ ## Development
22
+
23
+ ```bash
24
+ pytest # run the test suite
25
+ pre-commit install # optional: format & lint on commit
26
+ ```
27
+ {% if has_license %}
28
+ ## License
29
+
30
+ {{ license }}. See [LICENSE](LICENSE).
31
+ {% endif %}
@@ -0,0 +1,27 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "{{ project_slug }}"
7
+ version = "0.1.0"
8
+ description = "{{ description }}"
9
+ readme = "README.md"
10
+ requires-python = ">={{ python_version }}"
11
+ {% if has_license %}license = "{{ license }}"
12
+ license-files = ["LICENSE"]
13
+ {% endif %}authors = [{ name = "{{ author }}"{% if has_email %}, email = "{{ author_email }}"{% endif %} }]
14
+ keywords = []
15
+ classifiers = [
16
+ "Programming Language :: Python :: 3",
17
+ "Typing :: Typed",
18
+ ]
19
+
20
+ [project.optional-dependencies]
21
+ dev = ["pytest>=8.0"]
22
+
23
+ [tool.setuptools.packages.find]
24
+ where = ["src"]
25
+
26
+ [tool.pytest.ini_options]
27
+ testpaths = ["tests"]
@@ -0,0 +1,16 @@
1
+ """{{ description }}"""
2
+
3
+ from __future__ import annotations
4
+
5
+ __version__ = "0.1.0"
6
+
7
+ __all__ = ["__version__", "greet"]
8
+
9
+
10
+ def greet(name: str = "world") -> str:
11
+ """Return a friendly greeting.
12
+
13
+ >>> greet("{{ project_name }}")
14
+ 'Hello, {{ project_name }}!'
15
+ """
16
+ return f"Hello, {name}!"
@@ -0,0 +1,9 @@
1
+ from {{ package_name }} import greet
2
+
3
+
4
+ def test_greet_default() -> None:
5
+ assert greet() == "Hello, world!"
6
+
7
+
8
+ def test_greet_name() -> None:
9
+ assert greet("{{ project_name }}") == "Hello, {{ project_name }}!"
@@ -0,0 +1,4 @@
1
+ [template]
2
+ name = "python-lib"
3
+ kind = "library"
4
+ description = "Importable Python library: src/ layout, typed API, tests, and CI."