feat(scripts): add MOBILE_FIRST_MARKERS + _check_mobile_first check
This commit is contained in:
parent
43975cb593
commit
e4ddbb38af
2 changed files with 62 additions and 0 deletions
|
|
@ -673,6 +673,50 @@ def _check_frontend_stack(ctx: RepoCtx) -> CheckResult | None:
|
||||||
return CheckResult(CheckStatus.OK, "frontend stack", "Tailwind + shadcn-svelte + TS detected")
|
return CheckResult(CheckStatus.OK, "frontend stack", "Tailwind + shadcn-svelte + TS detected")
|
||||||
|
|
||||||
|
|
||||||
|
def _check_mobile_first(ctx: RepoCtx) -> CheckResult | None:
|
||||||
|
"""Fullstack mobile-first guarantee (issue #278): PWA manifest + mobile
|
||||||
|
Playwright + axe-core accessibility.
|
||||||
|
|
||||||
|
Returns ``None`` if ``frontend/package.json`` does not exist (the missing
|
||||||
|
package.json WARN is surfaced separately by ``_check_type_specific_structure``).
|
||||||
|
Returns ``None`` for non-fullstack types — the caller only invokes this for
|
||||||
|
FULLSTACK. Otherwise returns OK when all markers are present, or WARN with
|
||||||
|
the missing marker list (never FAIL — issue #275 all-WARN contract).
|
||||||
|
|
||||||
|
Markers (``MOBILE_FIRST_MARKERS``):
|
||||||
|
* ``frontend/static/manifest.webmanifest`` exists
|
||||||
|
* ``frontend/src/app.html`` contains both "viewport" and "manifest"
|
||||||
|
* ``frontend/tests/e2e/mobile.spec.ts`` exists
|
||||||
|
* ``frontend/tests/e2e/accessibility.spec.ts`` exists
|
||||||
|
* ``@axe-core/playwright`` in ``frontend/package.json`` devDependencies
|
||||||
|
"""
|
||||||
|
pkg_path = ctx.root / "frontend" / "package.json"
|
||||||
|
if not pkg_path.exists():
|
||||||
|
return None
|
||||||
|
missing: list[str] = []
|
||||||
|
for rel in project_contract.MOBILE_FIRST_MARKERS["fullstack_files"]:
|
||||||
|
if not (ctx.root / rel).exists():
|
||||||
|
missing.append(rel)
|
||||||
|
app_html = read_text("frontend/src/app.html", ctx) or ""
|
||||||
|
for marker in project_contract.MOBILE_FIRST_MARKERS["fullstack_app_html_markers"]:
|
||||||
|
if marker not in app_html:
|
||||||
|
missing.append(f"frontend/src/app.html ({marker})")
|
||||||
|
try:
|
||||||
|
pkg = json.loads(pkg_path.read_text(encoding="utf-8-sig"))
|
||||||
|
except (json.JSONDecodeError, OSError):
|
||||||
|
pkg = {}
|
||||||
|
dev_deps = pkg.get("devDependencies", {}) if isinstance(pkg, dict) else {}
|
||||||
|
if "@axe-core/playwright" not in dev_deps:
|
||||||
|
missing.append("@axe-core/playwright in package.json devDependencies")
|
||||||
|
if missing:
|
||||||
|
return CheckResult(
|
||||||
|
CheckStatus.WARN,
|
||||||
|
"mobile-first",
|
||||||
|
"missing " + ", ".join(missing),
|
||||||
|
)
|
||||||
|
return CheckResult(CheckStatus.OK, "mobile-first", "PWA + mobile Playwright + a11y detected")
|
||||||
|
|
||||||
|
|
||||||
def _check_type_specific_structure(ptype: ProjectType, ctx: RepoCtx) -> list[CheckResult]:
|
def _check_type_specific_structure(ptype: ProjectType, ctx: RepoCtx) -> list[CheckResult]:
|
||||||
"""Type-specific extra checks beyond the expected dirs list."""
|
"""Type-specific extra checks beyond the expected dirs list."""
|
||||||
results: list[CheckResult] = []
|
results: list[CheckResult] = []
|
||||||
|
|
@ -688,6 +732,9 @@ def _check_type_specific_structure(ptype: ProjectType, ctx: RepoCtx) -> list[Che
|
||||||
frontend_stack = _check_frontend_stack(ctx)
|
frontend_stack = _check_frontend_stack(ctx)
|
||||||
if frontend_stack is not None:
|
if frontend_stack is not None:
|
||||||
results.append(frontend_stack)
|
results.append(frontend_stack)
|
||||||
|
mobile = _check_mobile_first(ctx)
|
||||||
|
if mobile is not None:
|
||||||
|
results.append(mobile)
|
||||||
if ptype == ProjectType.CLI:
|
if ptype == ProjectType.CLI:
|
||||||
results.append(_check_cli_package(ctx))
|
results.append(_check_cli_package(ctx))
|
||||||
flat = _check_flat_layout(ptype, ctx)
|
flat = _check_flat_layout(ptype, ctx)
|
||||||
|
|
|
||||||
|
|
@ -78,3 +78,18 @@ FRONTEND_STACK_MARKERS: dict[str, list[str]] = {
|
||||||
"fullstack_package_deps": ["tailwindcss", "bits-ui"],
|
"fullstack_package_deps": ["tailwindcss", "bits-ui"],
|
||||||
"fullstack_files": ["frontend/components.json", "frontend/tsconfig.json"],
|
"fullstack_files": ["frontend/components.json", "frontend/tsconfig.json"],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Fullstack mobile-first markers (project-status _check_mobile_first, issue #278).
|
||||||
|
# Distinct from FRONTEND_STACK_MARKERS so the stack check stays focused on the
|
||||||
|
# Tailwind/shadcn/TS trio. Keys:
|
||||||
|
# fullstack_files — paths (relative to repo root) that must exist
|
||||||
|
# for PWA + mobile Playwright + a11y to be present.
|
||||||
|
# fullstack_app_html_markers — substrings that must appear in app.html <head>.
|
||||||
|
MOBILE_FIRST_MARKERS: dict[str, list[str]] = {
|
||||||
|
"fullstack_files": [
|
||||||
|
"frontend/static/manifest.webmanifest",
|
||||||
|
"frontend/tests/e2e/mobile.spec.ts",
|
||||||
|
"frontend/tests/e2e/accessibility.spec.ts",
|
||||||
|
],
|
||||||
|
"fullstack_app_html_markers": ["viewport", "manifest"],
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue