refactor(templates): drop README from cookiecutter templates (#272)
* refactor(templates): remove README.md from cookiecutter templates * test(templates): drop README expectations, expect WARN instead * docs(skills): note README is generated post-init via repo-readme * docs(skills): repo-readme creates README from scratch post-init * fix(templates): drop readme field from pyproject after README removal --------- Co-authored-by: opencode-agent <agent@opencode.local>
This commit is contained in:
parent
70b8203704
commit
ca2a04ce47
9 changed files with 55 additions and 260 deletions
|
|
@ -112,6 +112,11 @@ Tool вернёт отчёт: `Project: <type>`, 7 групп `[OK]/[WARN]/[FAIL
|
||||||
`Рекомендации:`. Покажи отчёт юзеру. Если tool вернул `⚠️ ...failed` → WARN,
|
`Рекомендации:`. Покажи отчёт юзеру. Если tool вернул `⚠️ ...failed` → WARN,
|
||||||
продолжай без отчёта.
|
продолжай без отчёта.
|
||||||
|
|
||||||
|
> README у свежего проекта отсутствует (issue #269) — README генерируется
|
||||||
|
> позже через repo-readme skill по ручному вызову. Поэтому группа README
|
||||||
|
> даст WARN «README.md отсутствует» (не FAIL, exit code 0 в non-blocking
|
||||||
|
> режиме). Это ожидаемое поведение, не ошибка — упомяни в отчёте.
|
||||||
|
|
||||||
### Шаг 6: Финальный репорт
|
### Шаг 6: Финальный репорт
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
@ -119,6 +124,7 @@ Project <project_name> created at ./<project_name>/.
|
||||||
GitHub: https://github.com/<owner>/<project_name>
|
GitHub: https://github.com/<owner>/<project_name>
|
||||||
Branch protection: main (PR + required_status_checks + linear history)
|
Branch protection: main (PR + required_status_checks + linear history)
|
||||||
Project-status: <summary из шага 5>
|
Project-status: <summary из шага 5>
|
||||||
|
README: отсутствует (WARN у project-status) — появится позже через repo-readme
|
||||||
Дальше: /run-pipeline для реализации фич, или /spec для генерации spec.
|
Дальше: /run-pipeline для реализации фич, или /spec для генерации spec.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -206,6 +212,11 @@ Template FIX (ниже), передав путь и описание пробл
|
||||||
заблокирован deny).
|
заблокирован deny).
|
||||||
7. Верни: "done: project created at ./<project_name>/, git init + initial commit".
|
7. Верни: "done: project created at ./<project_name>/, git init + initial commit".
|
||||||
|
|
||||||
|
README.md в рендеренном проекте НЕТ (issue #269) — шаблоны его больше не
|
||||||
|
содержат. README появится позже через repo-readme skill по ручному вызову
|
||||||
|
(сначала юзер смотрит контент и cover.png из draw-image). project-status на
|
||||||
|
свежем проекте даст WARN по отсутствующему README — это ожидаемо, не чинить.
|
||||||
|
|
||||||
Если найдёшь баг вне scope — загрузи skill `bug-discovery` через
|
Если найдёшь баг вне scope — загрузи skill `bug-discovery` через
|
||||||
`skill("bug-discovery")` и следуй протоколу. НЕ чини баг сам.
|
`skill("bug-discovery")` и следуй протоколу. НЕ чини баг сам.
|
||||||
```
|
```
|
||||||
|
|
@ -331,7 +342,8 @@ Cookiecutter templates доступны для: `backend`, `fullstack`, `cli`
|
||||||
- `project-status` tool — read-only oracle, ALLOWED для оркестратора (как
|
- `project-status` tool — read-only oracle, ALLOWED для оркестратора (как
|
||||||
`pipeline-status` / `spec-status`).
|
`pipeline-status` / `spec-status`).
|
||||||
- init flow порядок: cookiecutter → git init/commit → gh repo create → branch
|
- init flow порядок: cookiecutter → git init/commit → gh repo create → branch
|
||||||
protection → project-status. Не меняй порядок.
|
protection → project-status. Не меняй порядок. README в init flow НЕ
|
||||||
|
генерируется — только по ручному вызову repo-readme (issue #269).
|
||||||
- check flow: project-status → отчёт → рекомендации → subagents (последовательно).
|
- check flow: project-status → отчёт → рекомендации → subagents (последовательно).
|
||||||
- Subagent error → 1 retry, потом STOP + report.
|
- Subagent error → 1 retry, потом STOP + report.
|
||||||
- Совместим с spec-pipeline: Phase 8 EXECUTE (spec/SKILL.md Template I) может
|
- Совместим с spec-pipeline: Phase 8 EXECUTE (spec/SKILL.md Template I) может
|
||||||
|
|
|
||||||
|
|
@ -201,9 +201,10 @@ switcher `[English]` / `[Русский]`, заголовок `## 🇷🇺 Ру
|
||||||
## 6. Независимость от project-template
|
## 6. Независимость от project-template
|
||||||
|
|
||||||
- Скилл `project-template` (init flow) создаёт проект через cookiecutter —
|
- Скилл `project-template` (init flow) создаёт проект через cookiecutter —
|
||||||
шаблон уже включает `README.md` с базовой структурой.
|
шаблоны README.md НЕ содержат (issue #269): свежий проект рождается без
|
||||||
- `repo-readme` (через тулзу `create-readme`) **наполняет** его
|
README.
|
||||||
стандартизированным контентом (delimiter tags, bilingual, cover).
|
- `repo-readme` (через тулзу `create-readme`) **создаёт** полный README с нуля
|
||||||
|
(delimiter tags, bilingual, cover) по ручному вызову после init.
|
||||||
- Может применяться к существующим репо без `project-template` — тулза
|
- Может применяться к существующим репо без `project-template` — тулза
|
||||||
перезапишет `README.md` (локально) или обновит через GitHub API (с SHA).
|
перезапишет `README.md` (локально) или обновит через GitHub API (с SHA).
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,67 +0,0 @@
|
||||||
# 🚀 {{ cookiecutter.project_name }}
|
|
||||||
|
|
||||||
> Language switcher: **[English](#-english)** | **[Русский](#-русский)**
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
<!-- tagline-en:start -->
|
|
||||||
{{ cookiecutter.description }}
|
|
||||||
<!-- tagline-en:end -->
|
|
||||||
|
|
||||||
<!-- summary-en:start -->
|
|
||||||
{{ cookiecutter.description }}
|
|
||||||
<!-- summary-en:end -->
|
|
||||||
|
|
||||||
## 🇺🇸 English
|
|
||||||
|
|
||||||
<!-- features-en:start -->
|
|
||||||
- FastAPI backend with Tortoise ORM
|
|
||||||
- Pydantic-settings configuration
|
|
||||||
- Ruff + mypy strict + pytest
|
|
||||||
- Pre-commit hooks
|
|
||||||
<!-- features-en:end -->
|
|
||||||
|
|
||||||
### ⚡ Quick Start
|
|
||||||
|
|
||||||
```bash
|
|
||||||
uv sync --extra dev
|
|
||||||
uv run uvicorn main:app --reload
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 💬 Support and contacts / Поддержка и контакты
|
|
||||||
|
|
||||||
👉 **[slaid098.dev/contacts](https://slaid098.dev/contacts)**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🇷🇺 Русский
|
|
||||||
|
|
||||||
<!-- tagline-ru:start -->
|
|
||||||
{{ cookiecutter.description }}
|
|
||||||
<!-- tagline-ru:end -->
|
|
||||||
|
|
||||||
<!-- summary-ru:start -->
|
|
||||||
{{ cookiecutter.description }}
|
|
||||||
<!-- summary-ru:end -->
|
|
||||||
|
|
||||||
<!-- features-ru:start -->
|
|
||||||
- Бэкенд на FastAPI с Tortoise ORM
|
|
||||||
- Конфигурация через pydantic-settings
|
|
||||||
- Ruff + mypy strict + pytest
|
|
||||||
- Pre-commit хуки
|
|
||||||
<!-- features-ru:end -->
|
|
||||||
|
|
||||||
### ⚡ Быстрый старт
|
|
||||||
|
|
||||||
```bash
|
|
||||||
uv sync --extra dev
|
|
||||||
uv run uvicorn main:app --reload
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 💬 Support and contacts / Поддержка и контакты
|
|
||||||
|
|
||||||
👉 **[slaid098.dev/contacts](https://slaid098.dev/contacts)**
|
|
||||||
|
|
@ -6,7 +6,6 @@ build-backend = "hatchling.build"
|
||||||
name = "{{ cookiecutter.project_name }}"
|
name = "{{ cookiecutter.project_name }}"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
description = "{{ cookiecutter.description }}"
|
description = "{{ cookiecutter.description }}"
|
||||||
readme = "README.md"
|
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
requires-python = ">={{ cookiecutter.python_version }}"
|
requires-python = ">={{ cookiecutter.python_version }}"
|
||||||
authors = [{ name = "slaid098" }]
|
authors = [{ name = "slaid098" }]
|
||||||
|
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
||||||
# 🚀 {{ cookiecutter.project_name }}
|
|
||||||
|
|
||||||
> Language switcher: **[English](#-english)** | **[Русский](#-русский)**
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
<!-- tagline-en:start -->
|
|
||||||
{{ cookiecutter.description }}
|
|
||||||
<!-- tagline-en:end -->
|
|
||||||
|
|
||||||
<!-- summary-en:start -->
|
|
||||||
{{ cookiecutter.description }}
|
|
||||||
<!-- summary-en:end -->
|
|
||||||
|
|
||||||
## 🇺🇸 English
|
|
||||||
|
|
||||||
<!-- features-en:start -->
|
|
||||||
- Typer-based CLI with rich output
|
|
||||||
- Ruff + mypy strict + pytest
|
|
||||||
- Pre-commit hooks
|
|
||||||
<!-- features-en:end -->
|
|
||||||
|
|
||||||
### ⚡ Quick Start
|
|
||||||
|
|
||||||
```bash
|
|
||||||
uv sync --extra dev
|
|
||||||
{{ cookiecutter.project_name }} --help
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 💬 Support and contacts / Поддержка и контакты
|
|
||||||
|
|
||||||
👉 **[slaid098.dev/contacts](https://slaid098.dev/contacts)**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🇷🇺 Русский
|
|
||||||
|
|
||||||
<!-- tagline-ru:start -->
|
|
||||||
{{ cookiecutter.description }}
|
|
||||||
<!-- tagline-ru:end -->
|
|
||||||
|
|
||||||
<!-- summary-ru:start -->
|
|
||||||
{{ cookiecutter.description }}
|
|
||||||
<!-- summary-ru:end -->
|
|
||||||
|
|
||||||
<!-- features-ru:start -->
|
|
||||||
- CLI на Typer с rich-выводом
|
|
||||||
- Ruff + mypy strict + pytest
|
|
||||||
- Pre-commit хуки
|
|
||||||
<!-- features-ru:end -->
|
|
||||||
|
|
||||||
### ⚡ Быстрый старт
|
|
||||||
|
|
||||||
```bash
|
|
||||||
uv sync --extra dev
|
|
||||||
{{ cookiecutter.project_name }} --help
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 💬 Support and contacts / Поддержка и контакты
|
|
||||||
|
|
||||||
👉 **[slaid098.dev/contacts](https://slaid098.dev/contacts)**
|
|
||||||
|
|
@ -6,7 +6,6 @@ build-backend = "hatchling.build"
|
||||||
name = "{{ cookiecutter.project_name }}"
|
name = "{{ cookiecutter.project_name }}"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
description = "{{ cookiecutter.description }}"
|
description = "{{ cookiecutter.description }}"
|
||||||
readme = "README.md"
|
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
requires-python = ">={{ cookiecutter.python_version }}"
|
requires-python = ">={{ cookiecutter.python_version }}"
|
||||||
authors = [{ name = "slaid098" }]
|
authors = [{ name = "slaid098" }]
|
||||||
|
|
|
||||||
|
|
@ -1,67 +0,0 @@
|
||||||
# 🚀 {{ cookiecutter.project_name }}
|
|
||||||
|
|
||||||
> Language switcher: **[English](#-english)** | **[Русский](#-русский)**
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
<!-- tagline-en:start -->
|
|
||||||
{{ cookiecutter.description }}
|
|
||||||
<!-- tagline-en:end -->
|
|
||||||
|
|
||||||
<!-- summary-en:start -->
|
|
||||||
{{ cookiecutter.description }}
|
|
||||||
<!-- summary-en:end -->
|
|
||||||
|
|
||||||
## 🇺🇸 English
|
|
||||||
|
|
||||||
<!-- features-en:start -->
|
|
||||||
- FastAPI backend (Tortoise ORM) + SvelteKit frontend (Svelte 5 runes)
|
|
||||||
- pydantic-settings configuration; JS frontend with Biome + Knip + Vitest + Playwright e2e
|
|
||||||
- Ruff + mypy strict + pytest (backend); SvelteKit + Vitest (frontend)
|
|
||||||
- Pre-commit hooks (backend); Biome + Knip (frontend)
|
|
||||||
<!-- features-en:end -->
|
|
||||||
|
|
||||||
### ⚡ Quick Start
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd backend && uv sync --extra dev && uv run uvicorn main:app --reload
|
|
||||||
cd frontend && npm install && npm run dev
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 💬 Support and contacts / Поддержка и контакты
|
|
||||||
|
|
||||||
👉 **[slaid098.dev/contacts](https://slaid098.dev/contacts)**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🇷🇺 Русский
|
|
||||||
|
|
||||||
<!-- tagline-ru:start -->
|
|
||||||
{{ cookiecutter.description }}
|
|
||||||
<!-- tagline-ru:end -->
|
|
||||||
|
|
||||||
<!-- summary-ru:start -->
|
|
||||||
{{ cookiecutter.description }}
|
|
||||||
<!-- summary-ru:end -->
|
|
||||||
|
|
||||||
<!-- features-ru:start -->
|
|
||||||
- Бэкенд FastAPI (Tortoise ORM) + фронтенд SvelteKit (Svelte 5 runes)
|
|
||||||
- Конфигурация через pydantic-settings; JS-фронтенд с Biome + Knip + Vitest + Playwright e2e
|
|
||||||
- Ruff + mypy strict + pytest (бэкенд); SvelteKit + Vitest (фронтенд)
|
|
||||||
- Pre-commit хуки (бэкенд); Biome + Knip (фронтенд)
|
|
||||||
<!-- features-ru:end -->
|
|
||||||
|
|
||||||
### ⚡ Быстрый старт
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd backend && uv sync --extra dev && uv run uvicorn main:app --reload
|
|
||||||
cd frontend && npm install && npm run dev
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 💬 Support and contacts / Поддержка и контакты
|
|
||||||
|
|
||||||
👉 **[slaid098.dev/contacts](https://slaid098.dev/contacts)**
|
|
||||||
|
|
@ -6,7 +6,6 @@ build-backend = "hatchling.build"
|
||||||
name = "{{ cookiecutter.project_name }}"
|
name = "{{ cookiecutter.project_name }}"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
description = "{{ cookiecutter.description }}"
|
description = "{{ cookiecutter.description }}"
|
||||||
readme = "README.md"
|
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
requires-python = ">={{ cookiecutter.python_version }}"
|
requires-python = ">={{ cookiecutter.python_version }}"
|
||||||
authors = [{ name = "slaid098" }]
|
authors = [{ name = "slaid098" }]
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,6 @@ def test_backend_structure_full(render):
|
||||||
".python-version",
|
".python-version",
|
||||||
"env.example",
|
"env.example",
|
||||||
".gitignore",
|
".gitignore",
|
||||||
"README.md",
|
|
||||||
"LICENSE",
|
"LICENSE",
|
||||||
".pre-commit-config.yaml",
|
".pre-commit-config.yaml",
|
||||||
".github/workflows/ci.yml",
|
".github/workflows/ci.yml",
|
||||||
|
|
@ -201,7 +200,6 @@ def test_cli_structure(render):
|
||||||
expected = [
|
expected = [
|
||||||
"pyproject.toml",
|
"pyproject.toml",
|
||||||
".python-version",
|
".python-version",
|
||||||
"README.md",
|
|
||||||
"LICENSE",
|
"LICENSE",
|
||||||
".github/workflows/ci.yml",
|
".github/workflows/ci.yml",
|
||||||
"src/cl/__init__.py",
|
"src/cl/__init__.py",
|
||||||
|
|
@ -263,7 +261,6 @@ def test_fullstack_structure(render):
|
||||||
# removed: counter.svelte.js, Header.svelte, jsconfig.json, +page.js
|
# removed: counter.svelte.js, Header.svelte, jsconfig.json, +page.js
|
||||||
# root CI runs both
|
# root CI runs both
|
||||||
assert (render / ".github/workflows/ci.yml").exists()
|
assert (render / ".github/workflows/ci.yml").exists()
|
||||||
assert (render / "README.md").exists()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
|
|
@ -400,46 +397,6 @@ def test_fullstack_uses_typescript(render):
|
||||||
assert "tw-animate" not in deps or "tw-animate-css" in deps
|
assert "tw-animate" not in deps or "tw-animate-css" in deps
|
||||||
|
|
||||||
|
|
||||||
# ── README delimiter tags (create-readme standard) ──────────────────────────
|
|
||||||
|
|
||||||
|
|
||||||
README_REQUIRED_TAGS = [
|
|
||||||
"<!-- tagline-en:start -->",
|
|
||||||
"<!-- tagline-en:end -->",
|
|
||||||
"<!-- tagline-ru:start -->",
|
|
||||||
"<!-- tagline-ru:end -->",
|
|
||||||
"<!-- summary-en:start -->",
|
|
||||||
"<!-- summary-en:end -->",
|
|
||||||
"<!-- features-en:start -->",
|
|
||||||
"<!-- features-en:end -->",
|
|
||||||
"<!-- summary-ru:start -->",
|
|
||||||
"<!-- summary-ru:end -->",
|
|
||||||
"<!-- features-ru:start -->",
|
|
||||||
"<!-- features-ru:end -->",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
"template_name, extra_context",
|
|
||||||
[
|
|
||||||
("backend", {"project_name": "be"}),
|
|
||||||
("cli", {"project_name": "cl"}),
|
|
||||||
("fullstack", {"project_name": "fs"}),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
def test_readme_has_delimiter_tags(render):
|
|
||||||
"""README must contain all 12 delimiter tags + standard headers."""
|
|
||||||
content = (render / "README.md").read_text()
|
|
||||||
for tag in README_REQUIRED_TAGS:
|
|
||||||
assert tag in content, f"missing tag: {tag}"
|
|
||||||
assert "# 🚀 " in content
|
|
||||||
assert "## 🇺🇸 English" in content
|
|
||||||
assert "## 🇷🇺 Русский" in content
|
|
||||||
assert "[English](#-english)" in content
|
|
||||||
assert "[Русский](#-русский)" in content
|
|
||||||
assert "assets/cover.png" in content
|
|
||||||
|
|
||||||
|
|
||||||
# ── pyproject.toml completeness ──────────────────────────────────────────────
|
# ── pyproject.toml completeness ──────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -462,6 +419,9 @@ def test_pyproject_has_required_sections(render):
|
||||||
]
|
]
|
||||||
for section in required:
|
for section in required:
|
||||||
assert section in content, f"missing section: {section}"
|
assert section in content, f"missing section: {section}"
|
||||||
|
assert 'readme = "README.md"' not in content, (
|
||||||
|
"README.md is absent (issue #269) — readme field must not reference it"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("template_name, extra_context", [("backend", {"project_name": "be"})])
|
@pytest.mark.parametrize("template_name, extra_context", [("backend", {"project_name": "be"})])
|
||||||
|
|
@ -471,6 +431,29 @@ def test_backend_pytest_asyncio_auto(render):
|
||||||
assert 'asyncio_mode = "auto"' in pyproject
|
assert 'asyncio_mode = "auto"' in pyproject
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"template_name, extra_context",
|
||||||
|
[
|
||||||
|
("backend", {"project_name": "be"}),
|
||||||
|
("cli", {"project_name": "cl"}),
|
||||||
|
("fullstack", {"project_name": "fs", "use_db": "yes"}),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_pyproject_no_readme_field(render, template_name):
|
||||||
|
"""pyproject must not reference README.md (issue #269 — README is absent).
|
||||||
|
|
||||||
|
hatchling fails the build when ``readme = "README.md"`` points to a
|
||||||
|
missing file, so the field must be dropped entirely.
|
||||||
|
"""
|
||||||
|
if template_name == "fullstack":
|
||||||
|
content = (render / "backend" / "pyproject.toml").read_text()
|
||||||
|
else:
|
||||||
|
content = (render / "pyproject.toml").read_text()
|
||||||
|
assert 'readme = "README.md"' not in content, (
|
||||||
|
"README.md is absent (issue #269) — readme field must not reference it"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# ── nested src/<package>/ layout (issue #241) ──────────────────────────────────
|
# ── nested src/<package>/ layout (issue #241) ──────────────────────────────────
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -559,8 +542,13 @@ def _run_status_checks(repo_root: Path, fast: bool = True) -> tuple[str, list[ps
|
||||||
"template_name, extra_context",
|
"template_name, extra_context",
|
||||||
[("backend", {"project_name": "be", "use_db": "yes", "use_auth": "yes"})],
|
[("backend", {"project_name": "be", "use_db": "yes", "use_auth": "yes"})],
|
||||||
)
|
)
|
||||||
def test_backend_project_status_quality_and_readme_pass(render):
|
def test_backend_project_status_quality_and_infra_pass(render):
|
||||||
"""Backend template passes the quality + README + infra checks.
|
"""Backend template passes the quality + infra checks.
|
||||||
|
|
||||||
|
README is intentionally absent (issue #269 — generated later via
|
||||||
|
repo-readme/create-readme on manual call), so the README group yields
|
||||||
|
WARN, not FAIL (non-blocking). Coverage of the WARN behavior lives in
|
||||||
|
``test_readme_absent_is_warn``.
|
||||||
|
|
||||||
Note: the structure check (``src/api/v1`` flat layout) expects the layout
|
Note: the structure check (``src/api/v1`` flat layout) expects the layout
|
||||||
from issue #2 — out of scope for this PR. The nested ``src/<pkg>/api/v1``
|
from issue #2 — out of scope for this PR. The nested ``src/<pkg>/api/v1``
|
||||||
|
|
@ -573,12 +561,6 @@ def test_backend_project_status_quality_and_readme_pass(render):
|
||||||
assert by_name["ruff"].status == ps.CheckStatus.OK
|
assert by_name["ruff"].status == ps.CheckStatus.OK
|
||||||
assert by_name["mypy"].status == ps.CheckStatus.OK
|
assert by_name["mypy"].status == ps.CheckStatus.OK
|
||||||
assert by_name["pytest"].status == ps.CheckStatus.OK
|
assert by_name["pytest"].status == ps.CheckStatus.OK
|
||||||
# README delimiter tags + standard headers must pass
|
|
||||||
assert by_name["12 delimiter tags"].status == ps.CheckStatus.OK
|
|
||||||
assert by_name["# 🚀 "].status == ps.CheckStatus.OK
|
|
||||||
assert by_name["## 🇺🇸 English"].status == ps.CheckStatus.OK
|
|
||||||
assert by_name["## 🇷🇺 Русский"].status == ps.CheckStatus.OK
|
|
||||||
assert by_name["[English](#-english)"].status == ps.CheckStatus.OK
|
|
||||||
# infra: ci.yml + LICENSE + pre-commit
|
# infra: ci.yml + LICENSE + pre-commit
|
||||||
assert by_name[".github/workflows/ci.yml"].status == ps.CheckStatus.OK
|
assert by_name[".github/workflows/ci.yml"].status == ps.CheckStatus.OK
|
||||||
assert by_name["LICENSE"].status == ps.CheckStatus.OK
|
assert by_name["LICENSE"].status == ps.CheckStatus.OK
|
||||||
|
|
@ -605,11 +587,13 @@ def test_pyproject_quality_checks_pass(render):
|
||||||
"template_name, extra_context",
|
"template_name, extra_context",
|
||||||
[("backend", {"project_name": "be"}), ("cli", {"project_name": "cl"})],
|
[("backend", {"project_name": "be"}), ("cli", {"project_name": "cl"})],
|
||||||
)
|
)
|
||||||
def test_readme_check_passes(render):
|
def test_readme_absent_is_warn(render):
|
||||||
"""README delimiter-tag check passes in the rendered project."""
|
"""README.md is intentionally absent (issue #269) — project-status yields
|
||||||
|
WARN, not FAIL (non-blocking, exit 0)."""
|
||||||
_, checks = _run_status_checks(render)
|
_, checks = _run_status_checks(render)
|
||||||
by_name = {c.name: c for c in checks}
|
by_name = {c.name: c for c in checks}
|
||||||
assert by_name["12 delimiter tags"].status == ps.CheckStatus.OK
|
assert by_name["README.md"].status == ps.CheckStatus.WARN
|
||||||
|
assert "12 delimiter tags" not in by_name
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue