code-standards 7.33.0__tar.gz → 8.1.1__tar.gz
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.
- {code_standards-7.33.0 → code_standards-8.1.1}/.gitignore +1 -1
- {code_standards-7.33.0 → code_standards-8.1.1}/PKG-INFO +8 -5
- {code_standards-7.33.0 → code_standards-8.1.1}/README.md +3 -1
- {code_standards-7.33.0 → code_standards-8.1.1}/pyproject.toml +6 -4
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/api.py +49 -27
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/cli/main.py +108 -12
- code_standards-8.1.1/src/sarj_standards/configs/cli-reference.v1.json +1 -0
- code_standards-8.1.1/src/sarj_standards/configs/eslint-selected-rules.mjs +46 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/configs/eslint.peers.json +2 -2
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/configs/eslint.strict.mjs +15 -9
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/configs/rule-calibration-campaign.v1.json +4 -4
- code_standards-8.1.1/src/sarj_standards/configs/rule-level-source.mjs +62 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/adoption/transaction.py +12 -3
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/linting/analysis.py +4 -1
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/linting/external.py +32 -1
- code_standards-8.1.1/src/sarj_standards/libs/linting/scheduling.py +43 -0
- code_standards-8.1.1/src/sarj_standards/libs/linting/text_rule_base.py +86 -0
- code_standards-8.1.1/src/sarj_standards/libs/linting/text_rules/_registry.py +12 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/linting/textlint.py +13 -71
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/release/causality.py +19 -6
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/release/publish.py +2 -1
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/release/tags.py +5 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/repository/config_generation.py +6 -3
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/repository/docs.py +43 -3
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/repository/ruff_freshness.py +1 -0
- code_standards-8.1.1/src/sarj_standards/libs/repository/rule_authoring.py +311 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/repository/rule_catalog_artifact.py +61 -19
- code_standards-8.1.1/src/sarj_standards/libs/repository/rule_checkout.py +45 -0
- code_standards-8.1.1/src/sarj_standards/libs/repository/rule_examples.py +173 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/repository/rule_inventory_artifact.py +10 -3
- code_standards-8.1.1/src/sarj_standards/libs/repository/rule_level_source.py +202 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/repository/rule_lifecycle.py +49 -20
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/repository/rule_maintenance.py +15 -5
- code_standards-8.1.1/src/sarj_standards/libs/repository/rule_registration.py +235 -0
- code_standards-8.1.1/src/sarj_standards/libs/rules/contracts.py +21 -0
- code_standards-8.1.1/src/sarj_standards/py.typed +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/schemas/rule-catalog.v1.json +1 -1
- code_standards-7.33.0/src/sarj_standards/configs/cli-reference.v1.json +0 -1
- code_standards-7.33.0/src/sarj_standards/libs/repository/rule_authoring.py +0 -247
- code_standards-7.33.0/src/sarj_standards/libs/repository/rule_level_source.py +0 -117
- code_standards-7.33.0/src/sarj_standards/libs/rules/contracts.py +0 -395
- {code_standards-7.33.0 → code_standards-8.1.1}/LICENSE +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/__init__.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/__main__.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/_meta.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/cli/__init__.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/configs/Mintfile.mobile.strict +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/configs/basedpyright.python315-watch.json +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/configs/basedpyright.strict.json +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/configs/detekt.strict.yml +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/configs/doctor.config.json +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/configs/eslint-compact-formatter.mjs +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/configs/eslint.application.mjs +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/configs/ktlint.strict.editorconfig +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/configs/markdownlint.strict.yaml +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/configs/mobile-tools.versions.json +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/configs/mobsf.strict.yml +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/configs/pyright.strict.json +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/configs/ruff.application.toml +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/configs/ruff.python315-watch.toml +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/configs/ruff.strict.toml +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/configs/rule-inventory.v1.json +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/configs/rule-ledger.json +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/configs/shellcheck.strict.rc +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/configs/swiftformat.strict +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/configs/swiftlint.strict.yml +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/configs/taplo.strict.toml +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/configs/yamllint.strict.yaml +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/__init__.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/adoption/__init__.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/adoption/configs.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/adoption/doctor.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/adoption/exclusions.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/adoption/hooks.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/adoption/launcher.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/adoption/lifecycle.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/adoption/manifest.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/adoption/packagemanager.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/adoption/retired_suppressions.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/adoption/scaffold.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/adoption/service.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/adoption/upgrade.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/adoption/uvtool.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/catalogs/__init__.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/catalogs/slack_automations.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/corpus/__init__.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/corpus/manifest.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/corpus/snapshot.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/diagnostics/__init__.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/diagnostics/analysis.schema.json +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/diagnostics/baseline.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/diagnostics/models.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/diagnostics/serialize.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/diagnostics/source.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/filesystem.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/json_boundary.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/linting/__init__.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/linting/library_policy.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/linting/mobile_tools.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/linting/policy.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/linting/repo_standards.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/linting/runner.py +0 -0
- {code_standards-7.33.0/src/sarj_standards/libs/repository → code_standards-8.1.1/src/sarj_standards/libs/linting/text_rules}/__init__.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/release/__init__.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/release/_values.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/release/artifacts.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/release/changes.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/release/process.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/release/registry.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/release/release_age.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/release/retirement.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/release/rollout.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/release/typescript.py +0 -0
- /code_standards-7.33.0/src/sarj_standards/py.typed → /code_standards-8.1.1/src/sarj_standards/libs/repository/__init__.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/repository/cli_reference_artifact.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/repository/comment_corpus.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/repository/hooks.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/repository/ledger.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/repository/repository.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/repository/rule_changes.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/repository/third_party_catalog_artifact.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/rules/__init__.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/rules/catalog.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/rules/corpus_runner.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/rules/evaluation.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/setup/__init__.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/setup/repository.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/typed_containers.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/libs/yaml_boundary.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/schemas/__init__.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/schemas/_paths.py +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/schemas/rule-catalog.v1.schema.json +0 -0
- {code_standards-7.33.0 → code_standards-8.1.1}/src/sarj_standards/schemas/slack-automations.v1.schema.json +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: code-standards
|
|
3
|
-
Version:
|
|
3
|
+
Version: 8.1.1
|
|
4
4
|
Summary: One deterministic quality gate for Sarj Python, TypeScript, Swift, Kotlin, shell, SQL, IaC, and repository policy.
|
|
5
5
|
Project-URL: Homepage, https://code-standards.sarj.ai/
|
|
6
6
|
Project-URL: Documentation, https://code-standards.sarj.ai/cli/
|
|
@@ -27,9 +27,10 @@ Requires-Dist: pydantic==2.13.5
|
|
|
27
27
|
Requires-Dist: pyyaml==6.0.3
|
|
28
28
|
Requires-Dist: repo-standards==6.0.1
|
|
29
29
|
Requires-Dist: ruff==0.16.8
|
|
30
|
-
Requires-Dist: sarj-iac-lint==0.
|
|
31
|
-
Requires-Dist: sarj-python-lint==
|
|
32
|
-
Requires-Dist: sarj-
|
|
30
|
+
Requires-Dist: sarj-iac-lint==0.16.0
|
|
31
|
+
Requires-Dist: sarj-python-lint==1.1.1
|
|
32
|
+
Requires-Dist: sarj-rule-contracts==0.1.0
|
|
33
|
+
Requires-Dist: sarj-sql-lint==0.18.0
|
|
33
34
|
Requires-Dist: semgrep==1.178.0
|
|
34
35
|
Requires-Dist: shellcheck-py==0.11.0.1; (sys_platform == 'darwin' and platform_machine == 'arm64') or (sys_platform == 'darwin' and platform_machine == 'x86_64') or (sys_platform == 'linux' and platform_machine == 'x86_64') or (sys_platform == 'win32' and platform_machine == 'AMD64')
|
|
35
36
|
Requires-Dist: typer==0.27.2
|
|
@@ -56,6 +57,8 @@ code-standards doctor
|
|
|
56
57
|
code-standards update
|
|
57
58
|
```
|
|
58
59
|
|
|
59
|
-
Use repeatable `check --rule ENGINE:ID` selectors to check only selected Sarj custom rules. Exclusions, baselines, and severities still apply; upstream rules such as Ruff IDs are not supported. Native linters execute only selected rules
|
|
60
|
+
Use repeatable `check --rule ENGINE:ID` selectors to check only selected Sarj custom rules. Exclusions, baselines, and severities still apply; upstream rules such as Ruff IDs are not supported. Native linters and ESLint execute only selected rules. ESLint retains configured parsers, options, severities, and suppression directives.
|
|
61
|
+
|
|
62
|
+
`check --jobs 2` overlaps native analysis with the external-tool pipeline. The default is `--jobs 1`; external tools remain sequential and report ordering is deterministic.
|
|
60
63
|
|
|
61
64
|
[Documentation](https://code-standards.sarj.ai/) · [Source](https://github.com/sarj-ai/code-standards)
|
|
@@ -19,6 +19,8 @@ code-standards doctor
|
|
|
19
19
|
code-standards update
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
Use repeatable `check --rule ENGINE:ID` selectors to check only selected Sarj custom rules. Exclusions, baselines, and severities still apply; upstream rules such as Ruff IDs are not supported. Native linters execute only selected rules
|
|
22
|
+
Use repeatable `check --rule ENGINE:ID` selectors to check only selected Sarj custom rules. Exclusions, baselines, and severities still apply; upstream rules such as Ruff IDs are not supported. Native linters and ESLint execute only selected rules. ESLint retains configured parsers, options, severities, and suppression directives.
|
|
23
|
+
|
|
24
|
+
`check --jobs 2` overlaps native analysis with the external-tool pipeline. The default is `--jobs 1`; external tools remain sequential and report ordering is deterministic.
|
|
23
25
|
|
|
24
26
|
[Documentation](https://code-standards.sarj.ai/) · [Source](https://github.com/sarj-ai/code-standards)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "code-standards"
|
|
3
|
-
version = "
|
|
3
|
+
version = "8.1.1"
|
|
4
4
|
description = "One deterministic quality gate for Sarj Python, TypeScript, Swift, Kotlin, shell, SQL, IaC, and repository policy."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.14"
|
|
@@ -16,6 +16,7 @@ classifiers = [
|
|
|
16
16
|
"Topic :: Software Development :: Quality Assurance",
|
|
17
17
|
]
|
|
18
18
|
dependencies = [
|
|
19
|
+
"sarj-rule-contracts==0.1.0",
|
|
19
20
|
"pathspec==1.1.1",
|
|
20
21
|
"basedpyright==1.40.1",
|
|
21
22
|
"deptry==0.25.1",
|
|
@@ -28,9 +29,9 @@ dependencies = [
|
|
|
28
29
|
"ruff==0.16.8",
|
|
29
30
|
"semgrep==1.178.0",
|
|
30
31
|
"shellcheck-py==0.11.0.1; (sys_platform == 'darwin' and platform_machine == 'arm64') or (sys_platform == 'darwin' and platform_machine == 'x86_64') or (sys_platform == 'linux' and platform_machine == 'x86_64') or (sys_platform == 'win32' and platform_machine == 'AMD64')",
|
|
31
|
-
"sarj-iac-lint==0.
|
|
32
|
-
"sarj-python-lint==
|
|
33
|
-
"sarj-sql-lint==0.
|
|
32
|
+
"sarj-iac-lint==0.16.0",
|
|
33
|
+
"sarj-python-lint==1.1.1",
|
|
34
|
+
"sarj-sql-lint==0.18.0",
|
|
34
35
|
"typer==0.27.2",
|
|
35
36
|
]
|
|
36
37
|
|
|
@@ -66,6 +67,7 @@ dev = [
|
|
|
66
67
|
"pytest>=9.1.1",
|
|
67
68
|
]
|
|
68
69
|
[tool.uv.sources]
|
|
70
|
+
sarj-rule-contracts = { path = "../contracts", editable = true }
|
|
69
71
|
# Development uses the sibling packages while wheel smoke tests resolve the
|
|
70
72
|
# same exact, already-published versions declared above.
|
|
71
73
|
sarj-iac-lint = { path = "../iac", editable = true }
|
|
@@ -63,6 +63,7 @@ from .libs.linting.library_policy import (
|
|
|
63
63
|
)
|
|
64
64
|
from .libs.linting.policy import Policy
|
|
65
65
|
from .libs.linting.runner import group_paths, run as check
|
|
66
|
+
from .libs.linting.scheduling import analyze_groups
|
|
66
67
|
from .libs.rules import RuleEngine, RuleId, RuleSelection, RuleSelector
|
|
67
68
|
from .libs.typed_containers import is_object_list, is_object_mapping
|
|
68
69
|
|
|
@@ -238,7 +239,7 @@ class Standards:
|
|
|
238
239
|
return _operation_result(max(source_status, eslint_status, 1 if findings else 0), findings=findings)
|
|
239
240
|
return _operation_result(_verify(self.root))
|
|
240
241
|
|
|
241
|
-
def analyze(
|
|
242
|
+
def analyze(
|
|
242
243
|
self,
|
|
243
244
|
paths: Sequence[str] | None = None,
|
|
244
245
|
*,
|
|
@@ -250,7 +251,10 @@ class Standards:
|
|
|
250
251
|
react_doctor_triggered: bool = False,
|
|
251
252
|
include_react_doctor: bool = True,
|
|
252
253
|
pass_on_unpruned_eslint_suppressions: bool = False,
|
|
254
|
+
jobs: int = 1,
|
|
253
255
|
) -> AnalysisReport:
|
|
256
|
+
if jobs not in {1, 2}:
|
|
257
|
+
return _failed_analysis(self.root, "invalid-input", "analysis jobs must be 1 or 2")
|
|
254
258
|
try:
|
|
255
259
|
normalized_trust = TrustMode(trust)
|
|
256
260
|
normalized_mode = AnalysisMode(mode)
|
|
@@ -277,19 +281,24 @@ class Standards:
|
|
|
277
281
|
react_doctor_full_scan = not staged and (
|
|
278
282
|
requested_paths is None or any(Path(path) == Path() for path in requested_paths)
|
|
279
283
|
)
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
284
|
+
|
|
285
|
+
def native_analysis() -> tuple[ToolReport, ...]:
|
|
286
|
+
native = analyze_paths(
|
|
287
|
+
active_selected,
|
|
288
|
+
root=self.root,
|
|
289
|
+
policy=selection_policy,
|
|
290
|
+
grouped=selected_groups,
|
|
291
|
+
rule_selection=rule_selection,
|
|
292
|
+
)
|
|
293
|
+
if rule_selection is None:
|
|
294
|
+
native = _with_library_policy(self.root, native, active_selected, selection_policy)
|
|
295
|
+
if rule_selection is None and normalized_mode is AnalysisMode.POLICY:
|
|
296
|
+
native = _with_repository_analysis(self.root, native, staged=staged)
|
|
297
|
+
return native.tools
|
|
298
|
+
|
|
291
299
|
coverage = _selection_coverage(self.root, selected, active_selected, selected_groups, rule_selection)
|
|
292
300
|
if not external:
|
|
301
|
+
native = report_from_tools(self.root, native_analysis())
|
|
293
302
|
_native_typescript_coverage(selected_groups, adopted, rule_selection, coverage)
|
|
294
303
|
if normalized_mode in {AnalysisMode.POLICY, AnalysisMode.OBSERVE}:
|
|
295
304
|
native = _with_warning_severity(native, _warning_rule_keys())
|
|
@@ -305,21 +314,26 @@ class Standards:
|
|
|
305
314
|
CoverageDisposition.NOT_REQUESTED,
|
|
306
315
|
)
|
|
307
316
|
)
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
317
|
+
|
|
318
|
+
def external_analysis() -> tuple[ToolReport, ...]:
|
|
319
|
+
return _selected_external_analysis(
|
|
320
|
+
active_selected,
|
|
321
|
+
root=self.root,
|
|
322
|
+
selected_groups=selected_groups,
|
|
323
|
+
adopted=adopted,
|
|
324
|
+
selection_policy=selection_policy,
|
|
325
|
+
rule_selection=rule_selection,
|
|
326
|
+
normalized_trust=normalized_trust,
|
|
327
|
+
include_react_doctor=include_react_doctor,
|
|
328
|
+
react_doctor_triggered=react_doctor_triggered,
|
|
329
|
+
staged=staged,
|
|
330
|
+
react_doctor_full_scan=react_doctor_full_scan,
|
|
331
|
+
pass_on_unpruned_eslint_suppressions=pass_on_unpruned_eslint_suppressions,
|
|
332
|
+
)
|
|
333
|
+
|
|
334
|
+
combined = report_from_tools(
|
|
335
|
+
self.root, analyze_groups(self.root, native_analysis, external_analysis, jobs=jobs)
|
|
321
336
|
)
|
|
322
|
-
combined = report_from_tools(self.root, (*native.tools, *external_reports))
|
|
323
337
|
if normalized_mode in {AnalysisMode.POLICY, AnalysisMode.OBSERVE}:
|
|
324
338
|
combined = _with_warning_severity(combined, _warning_rule_keys())
|
|
325
339
|
return _with_coverage(
|
|
@@ -335,8 +349,9 @@ class Standards:
|
|
|
335
349
|
mode: AnalysisMode | str = AnalysisMode.POLICY,
|
|
336
350
|
rules: Sequence[str | RuleSelector] | None = None,
|
|
337
351
|
staged: bool = False,
|
|
352
|
+
jobs: int = 1,
|
|
338
353
|
) -> AnalysisReport:
|
|
339
|
-
return self.analyze(paths, external=external, trust=trust, mode=mode, rules=rules, staged=staged)
|
|
354
|
+
return self.analyze(paths, external=external, trust=trust, mode=mode, rules=rules, staged=staged, jobs=jobs)
|
|
340
355
|
|
|
341
356
|
def fix(self) -> Result:
|
|
342
357
|
from .libs.adoption import ( # ruff: ignore[import-outside-top-level] -- selected operation only
|
|
@@ -603,6 +618,11 @@ def _selected_external_analysis(
|
|
|
603
618
|
react_doctor_full_scan: bool,
|
|
604
619
|
pass_on_unpruned_eslint_suppressions: bool,
|
|
605
620
|
) -> tuple[ToolReport, ...]:
|
|
621
|
+
rule_ids = (
|
|
622
|
+
frozenset(str(value) for value in rule_selection.ids_for(RuleEngine.ESLINT))
|
|
623
|
+
if rule_selection is not None
|
|
624
|
+
else None
|
|
625
|
+
)
|
|
606
626
|
run_eslint = rule_selection is None or RuleEngine.ESLINT in rule_selection.engines
|
|
607
627
|
external_reports = (
|
|
608
628
|
(
|
|
@@ -615,6 +635,7 @@ def _selected_external_analysis(
|
|
|
615
635
|
frozenset({"eslint"}) if rule_selection is not None else frozenset(adopted.enabled_capabilities)
|
|
616
636
|
),
|
|
617
637
|
grouped=selected_groups,
|
|
638
|
+
rule_ids=rule_ids,
|
|
618
639
|
include_react_doctor=include_react_doctor and rule_selection is None,
|
|
619
640
|
force_react_doctor=react_doctor_triggered,
|
|
620
641
|
react_doctor_staged=staged,
|
|
@@ -628,6 +649,7 @@ def _selected_external_analysis(
|
|
|
628
649
|
trust=normalized_trust,
|
|
629
650
|
capabilities=frozenset({"eslint"}) if rule_selection is not None else None,
|
|
630
651
|
grouped=selected_groups,
|
|
652
|
+
rule_ids=rule_ids,
|
|
631
653
|
include_react_doctor=include_react_doctor and rule_selection is None,
|
|
632
654
|
force_react_doctor=react_doctor_triggered,
|
|
633
655
|
react_doctor_staged=staged,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from dataclasses import dataclass, field
|
|
3
|
+
from dataclasses import asdict, dataclass, field
|
|
4
4
|
from datetime import timedelta
|
|
5
5
|
from enum import StrEnum
|
|
6
6
|
from functools import lru_cache
|
|
@@ -122,6 +122,7 @@ class _Args:
|
|
|
122
122
|
roots: list[Path] = field(default_factory=list)
|
|
123
123
|
include_text: Path | None = None
|
|
124
124
|
rules_cmd: str = ""
|
|
125
|
+
repeats: int = 5
|
|
125
126
|
rule_category: str = ""
|
|
126
127
|
rule_summary: str = ""
|
|
127
128
|
apply_rule: bool = False
|
|
@@ -145,6 +146,7 @@ class _Args:
|
|
|
145
146
|
release_exclude_file: list[Path] = field(default_factory=list)
|
|
146
147
|
output: Path | None = None
|
|
147
148
|
external: bool = False
|
|
149
|
+
jobs: int = 1
|
|
148
150
|
trust: str = "safe"
|
|
149
151
|
trust_repository_code: bool = False
|
|
150
152
|
before: str = ""
|
|
@@ -156,6 +158,7 @@ class _Args:
|
|
|
156
158
|
hooks: manifest.HookManager | None = None
|
|
157
159
|
show_cmd: str = ""
|
|
158
160
|
catalog_cmd: str = ""
|
|
161
|
+
typescript_built: bool = False
|
|
159
162
|
exclude_cmd: str = ""
|
|
160
163
|
exclude_kind: str = ""
|
|
161
164
|
value: str = ""
|
|
@@ -1000,6 +1003,7 @@ def cmd_verify(args: _Args) -> int:
|
|
|
1000
1003
|
root,
|
|
1001
1004
|
None if adopted is None else adopted.verify_paths,
|
|
1002
1005
|
raw=adopted is None,
|
|
1006
|
+
jobs=args.jobs,
|
|
1003
1007
|
trusted=args.trust_repository_code,
|
|
1004
1008
|
)
|
|
1005
1009
|
|
|
@@ -1076,7 +1080,7 @@ def cmd_check(args: _Args) -> int:
|
|
|
1076
1080
|
return health_status
|
|
1077
1081
|
args.files = [path for path in args.files if runner.accepts_hook_path(Path(path), root=root)]
|
|
1078
1082
|
if not args.files and not scope.react_doctor_triggered:
|
|
1079
|
-
return _run_canonical_check(root, (), trusted=args.trust_repository_code, staged=True)
|
|
1083
|
+
return _run_canonical_check(root, (), trusted=args.trust_repository_code, staged=True, jobs=args.jobs)
|
|
1080
1084
|
if args.output_format != "text":
|
|
1081
1085
|
return _check_machine_output(args, root, scope)
|
|
1082
1086
|
return _check_text_output(args, root, scope)
|
|
@@ -1090,6 +1094,7 @@ def _check_selected_rules(args: _Args, root: Path, scope: _CheckScope) -> int:
|
|
|
1090
1094
|
paths = args.files if args.files or args.staged or scope.pull_request_scoped else None
|
|
1091
1095
|
report = Standards(root).analyze(
|
|
1092
1096
|
paths,
|
|
1097
|
+
jobs=args.jobs,
|
|
1093
1098
|
rules=args.selected_rules,
|
|
1094
1099
|
external=any(selector.engine.value == "eslint" for selector in args.selected_rules),
|
|
1095
1100
|
trust=TrustMode.TRUSTED if args.trust_repository_code else TrustMode.SAFE,
|
|
@@ -1110,8 +1115,9 @@ def _check_text_output(args: _Args, root: Path, scope: _CheckScope) -> int:
|
|
|
1110
1115
|
(),
|
|
1111
1116
|
trusted=args.trust_repository_code,
|
|
1112
1117
|
react_doctor_triggered=True,
|
|
1118
|
+
jobs=args.jobs,
|
|
1113
1119
|
)
|
|
1114
|
-
return _run_canonical_check(root, (), trusted=args.trust_repository_code)
|
|
1120
|
+
return _run_canonical_check(root, (), trusted=args.trust_repository_code, jobs=args.jobs)
|
|
1115
1121
|
if not args.files:
|
|
1116
1122
|
return cmd_verify(args)
|
|
1117
1123
|
check_options: dict[str, bool] = {
|
|
@@ -1120,7 +1126,7 @@ def _check_text_output(args: _Args, root: Path, scope: _CheckScope) -> int:
|
|
|
1120
1126
|
}
|
|
1121
1127
|
if scope.react_doctor_triggered:
|
|
1122
1128
|
check_options["react_doctor_triggered"] = True
|
|
1123
|
-
return _run_canonical_check(root, list(args.files), **check_options)
|
|
1129
|
+
return _run_canonical_check(root, list(args.files), jobs=args.jobs, **check_options)
|
|
1124
1130
|
|
|
1125
1131
|
|
|
1126
1132
|
@dataclass(slots=True)
|
|
@@ -1229,6 +1235,7 @@ def _check_machine_output(args: _Args, root: Path, scope: _CheckScope) -> int:
|
|
|
1229
1235
|
report = Standards(root).analyze(
|
|
1230
1236
|
(),
|
|
1231
1237
|
external=True,
|
|
1238
|
+
jobs=args.jobs,
|
|
1232
1239
|
trust=TrustMode.TRUSTED if args.trust_repository_code else TrustMode.SAFE,
|
|
1233
1240
|
mode=AnalysisMode.POLICY,
|
|
1234
1241
|
react_doctor_triggered=scope.react_doctor_triggered,
|
|
@@ -1308,6 +1315,7 @@ def _run_canonical_check(
|
|
|
1308
1315
|
trusted: bool = False,
|
|
1309
1316
|
staged: bool = False,
|
|
1310
1317
|
react_doctor_triggered: bool = False,
|
|
1318
|
+
jobs: int = 1,
|
|
1311
1319
|
) -> int:
|
|
1312
1320
|
from sarj_standards.api import AnalysisMode, Standards, TrustMode # ruff: ignore[import-outside-top-level]
|
|
1313
1321
|
from sarj_standards.libs.diagnostics import to_text # ruff: ignore[import-outside-top-level]
|
|
@@ -1315,6 +1323,7 @@ def _run_canonical_check(
|
|
|
1315
1323
|
report = Standards(root).analyze(
|
|
1316
1324
|
paths,
|
|
1317
1325
|
external=True,
|
|
1326
|
+
jobs=jobs,
|
|
1318
1327
|
trust=TrustMode.TRUSTED if trusted else TrustMode.SAFE,
|
|
1319
1328
|
mode=AnalysisMode.RAW if raw else AnalysisMode.POLICY,
|
|
1320
1329
|
staged=staged,
|
|
@@ -1337,6 +1346,7 @@ def cmd_analyze(args: _Args) -> int:
|
|
|
1337
1346
|
return 2
|
|
1338
1347
|
report = Standards(root).analyze(
|
|
1339
1348
|
args.files or None,
|
|
1349
|
+
jobs=args.jobs,
|
|
1340
1350
|
external=args.external,
|
|
1341
1351
|
trust=args.trust,
|
|
1342
1352
|
mode=AnalysisMode(args.analysis_mode),
|
|
@@ -1359,6 +1369,7 @@ def cmd_rule_evaluate(args: _Args) -> int:
|
|
|
1359
1369
|
return 2
|
|
1360
1370
|
report = Standards(root).analyze(
|
|
1361
1371
|
args.files or None,
|
|
1372
|
+
jobs=args.jobs,
|
|
1362
1373
|
external=any(selector.engine.value == "eslint" for selector in args.selected_rules),
|
|
1363
1374
|
trust=TrustMode.TRUSTED if args.trust_repository_code else TrustMode.SAFE,
|
|
1364
1375
|
mode=(AnalysisMode.CORPUS if args.evaluation_scope is _EvaluationScope.CORPUS else AnalysisMode.POLICY),
|
|
@@ -1548,6 +1559,7 @@ def cmd_observe(args: _Args) -> int:
|
|
|
1548
1559
|
return 2
|
|
1549
1560
|
report = Standards(root).analyze(
|
|
1550
1561
|
args.files or None,
|
|
1562
|
+
jobs=args.jobs,
|
|
1551
1563
|
external=any(selector.engine.value == "eslint" for selector in args.selected_rules),
|
|
1552
1564
|
trust=TrustMode.TRUSTED if args.trust_repository_code else TrustMode.SAFE,
|
|
1553
1565
|
mode=AnalysisMode.OBSERVE,
|
|
@@ -2621,6 +2633,7 @@ class _ExcludeKind(StrEnum):
|
|
|
2621
2633
|
|
|
2622
2634
|
|
|
2623
2635
|
class _ReleaseTargetChoice(StrEnum):
|
|
2636
|
+
CONTRACTS = "contracts"
|
|
2624
2637
|
TYPESCRIPT = "typescript"
|
|
2625
2638
|
BOOTSTRAP = "bootstrap"
|
|
2626
2639
|
PYTHON = "python"
|
|
@@ -2837,6 +2850,9 @@ def build_app(handler: Callable[[_Args], int] = _dispatch) -> typer.Typer:
|
|
|
2837
2850
|
help="allow executable repository ESLint configuration (generated hooks and CI set this explicitly)",
|
|
2838
2851
|
),
|
|
2839
2852
|
] = False,
|
|
2853
|
+
jobs: Annotated[
|
|
2854
|
+
int, typer.Option("--jobs", min=1, max=2, help="overlap native and external analysis (default: 1)")
|
|
2855
|
+
] = 1,
|
|
2840
2856
|
staged: Annotated[
|
|
2841
2857
|
bool,
|
|
2842
2858
|
typer.Option(
|
|
@@ -2861,6 +2877,7 @@ def build_app(handler: Callable[[_Args], int] = _dispatch) -> typer.Typer:
|
|
|
2861
2877
|
_Args(
|
|
2862
2878
|
dest=_command_root(ctx),
|
|
2863
2879
|
cmd="check",
|
|
2880
|
+
jobs=jobs,
|
|
2864
2881
|
trust_repository_code=trust_repository_code,
|
|
2865
2882
|
staged=staged,
|
|
2866
2883
|
selected_rules=selected_rules if selected_rules is not None else [],
|
|
@@ -3725,6 +3742,31 @@ def build_app(handler: Callable[[_Args], int] = _dispatch) -> typer.Typer:
|
|
|
3725
3742
|
)
|
|
3726
3743
|
)
|
|
3727
3744
|
|
|
3745
|
+
@group_maintain_rules.command("bench", help="measure native Python analysis with diagnostic and source digests")
|
|
3746
|
+
def command_maintain_rules_bench(
|
|
3747
|
+
ctx: typer.Context,
|
|
3748
|
+
files: Annotated[list[str], typer.Argument(help="Python files or directories")],
|
|
3749
|
+
*,
|
|
3750
|
+
repeats: Annotated[int, typer.Option(min=1)] = 5,
|
|
3751
|
+
selected_rules: Annotated[
|
|
3752
|
+
list[RuleSelector] | None,
|
|
3753
|
+
typer.Option(
|
|
3754
|
+
"--rule", parser=_parse_rule_selector, help="python:ID selector; defaults to all Python rules"
|
|
3755
|
+
),
|
|
3756
|
+
] = None,
|
|
3757
|
+
) -> int:
|
|
3758
|
+
return handler(
|
|
3759
|
+
_Args(
|
|
3760
|
+
dest=_command_root(ctx),
|
|
3761
|
+
cmd="maintain",
|
|
3762
|
+
repo_cmd="rules",
|
|
3763
|
+
rules_cmd="bench",
|
|
3764
|
+
files=files,
|
|
3765
|
+
repeats=repeats,
|
|
3766
|
+
selected_rules=selected_rules or [],
|
|
3767
|
+
)
|
|
3768
|
+
)
|
|
3769
|
+
|
|
3728
3770
|
@group_maintain_rules.command("changes", help="compare rule inventory and policy between two Git revisions")
|
|
3729
3771
|
def command_maintain_rules_changes(
|
|
3730
3772
|
ctx: typer.Context,
|
|
@@ -3806,6 +3848,11 @@ def build_app(handler: Callable[[_Args], int] = _dispatch) -> typer.Typer:
|
|
|
3806
3848
|
@group_maintain_catalog.command("check", help="verify the public catalog matches every live rule")
|
|
3807
3849
|
def command_maintain_catalog_check(
|
|
3808
3850
|
ctx: typer.Context,
|
|
3851
|
+
*,
|
|
3852
|
+
typescript_built: Annotated[
|
|
3853
|
+
bool,
|
|
3854
|
+
typer.Option("--typescript-built", help="reuse the TypeScript build completed by this verification run"),
|
|
3855
|
+
] = False,
|
|
3809
3856
|
) -> int:
|
|
3810
3857
|
return handler(
|
|
3811
3858
|
_Args(
|
|
@@ -3813,6 +3860,7 @@ def build_app(handler: Callable[[_Args], int] = _dispatch) -> typer.Typer:
|
|
|
3813
3860
|
cmd="maintain",
|
|
3814
3861
|
repo_cmd="catalog",
|
|
3815
3862
|
catalog_cmd="check",
|
|
3863
|
+
typescript_built=typescript_built,
|
|
3816
3864
|
)
|
|
3817
3865
|
)
|
|
3818
3866
|
|
|
@@ -3972,8 +4020,11 @@ def _run_repo_check(args: _Args) -> int:
|
|
|
3972
4020
|
|
|
3973
4021
|
|
|
3974
4022
|
def _run_repo_sync_ledger(args: _Args) -> int:
|
|
3975
|
-
from sarj_standards.libs.repository import rule_maintenance # ruff: ignore[import-outside-top-level]
|
|
4023
|
+
from sarj_standards.libs.repository import rule_checkout, rule_maintenance # ruff: ignore[import-outside-top-level]
|
|
3976
4024
|
|
|
4025
|
+
rule_checkout.ensure_current(
|
|
4026
|
+
_resolve_dest(args.dest), ("maintain", "sync-ledger", *(("--check",) if args.check else ())), all_engines=True
|
|
4027
|
+
)
|
|
3977
4028
|
result = rule_maintenance.sync_ledger(_resolve_dest(args.dest), check=args.check)
|
|
3978
4029
|
print(result.message)
|
|
3979
4030
|
return result.status
|
|
@@ -4010,8 +4061,17 @@ def _run_repo_hooks(args: _Args) -> int:
|
|
|
4010
4061
|
|
|
4011
4062
|
|
|
4012
4063
|
def _run_repo_rules(args: _Args) -> int:
|
|
4013
|
-
from sarj_standards.libs.repository import rule_inventory_artifact # ruff: ignore[import-outside-top-level]
|
|
4064
|
+
from sarj_standards.libs.repository import rule_checkout, rule_inventory_artifact # ruff: ignore[import-outside-top-level]
|
|
4014
4065
|
|
|
4066
|
+
if args.selector is not None and args.rules_cmd in {"new", "verify", "prepare", "stage-warning", "promote-error"}:
|
|
4067
|
+
rule_checkout.ensure_current(
|
|
4068
|
+
_resolve_dest(args.dest),
|
|
4069
|
+
("maintain", "rules", args.rules_cmd, str(args.selector)),
|
|
4070
|
+
engine=args.selector.engine,
|
|
4071
|
+
all_engines=args.rules_cmd in {"prepare", "stage-warning", "promote-error"},
|
|
4072
|
+
)
|
|
4073
|
+
if args.rules_cmd in {"sync", "check"}:
|
|
4074
|
+
rule_checkout.ensure_current(_resolve_dest(args.dest), ("maintain", "rules", args.rules_cmd), all_engines=True)
|
|
4015
4075
|
if args.rules_cmd == "manifest":
|
|
4016
4076
|
print(json.dumps(rule_inventory_artifact.load(), indent=2))
|
|
4017
4077
|
return 0
|
|
@@ -4019,6 +4079,8 @@ def _run_repo_rules(args: _Args) -> int:
|
|
|
4019
4079
|
return _run_repo_rules_changes(args)
|
|
4020
4080
|
if args.rules_cmd == "evaluate":
|
|
4021
4081
|
return cmd_rule_evaluate(args)
|
|
4082
|
+
if args.rules_cmd == "bench":
|
|
4083
|
+
return _run_repo_rules_bench(args)
|
|
4022
4084
|
if args.rules_cmd == "new":
|
|
4023
4085
|
return _run_repo_rules_new(args)
|
|
4024
4086
|
if args.rules_cmd == "verify":
|
|
@@ -4030,10 +4092,38 @@ def _run_repo_rules(args: _Args) -> int:
|
|
|
4030
4092
|
return result.status
|
|
4031
4093
|
|
|
4032
4094
|
|
|
4095
|
+
def _run_repo_rules_bench(args: _Args) -> int:
|
|
4096
|
+
from sarj_python_lint.benchmark import measure # ruff: ignore[import-outside-top-level] -- benchmark-only dependency
|
|
4097
|
+
from sarj_python_lint.rules import REGISTRY # ruff: ignore[import-outside-top-level] -- benchmark selection
|
|
4098
|
+
|
|
4099
|
+
for selector in args.selected_rules:
|
|
4100
|
+
if selector.engine.value != "python" or selector.rule_id not in REGISTRY:
|
|
4101
|
+
print(f"error: benchmark requires a registered python:ID selector: {selector}", file=sys.stderr)
|
|
4102
|
+
return 2
|
|
4103
|
+
root = _resolve_dest(args.dest)
|
|
4104
|
+
try:
|
|
4105
|
+
result = measure(
|
|
4106
|
+
[root / path for path in args.files],
|
|
4107
|
+
[selector.rule_id for selector in args.selected_rules] or None,
|
|
4108
|
+
repeats=args.repeats,
|
|
4109
|
+
)
|
|
4110
|
+
except (OSError, ValueError, RuntimeError) as exc:
|
|
4111
|
+
print(f"error: benchmark failed: {exc}", file=sys.stderr)
|
|
4112
|
+
return 2
|
|
4113
|
+
print(json.dumps(asdict(result), indent=2))
|
|
4114
|
+
return 0
|
|
4115
|
+
|
|
4116
|
+
|
|
4033
4117
|
def _run_repo_catalog(args: _Args) -> int:
|
|
4034
|
-
from sarj_standards.libs.repository import rule_catalog_artifact # ruff: ignore[import-outside-top-level]
|
|
4118
|
+
from sarj_standards.libs.repository import rule_catalog_artifact, rule_checkout # ruff: ignore[import-outside-top-level]
|
|
4035
4119
|
|
|
4036
|
-
|
|
4120
|
+
root = _resolve_dest(args.dest)
|
|
4121
|
+
rule_checkout.ensure_current(root, ("maintain", "catalog", args.catalog_cmd), all_engines=True)
|
|
4122
|
+
if args.typescript_built:
|
|
4123
|
+
projection = rule_catalog_artifact.typescript_specs(root, already_built=True)
|
|
4124
|
+
result = rule_catalog_artifact.sync(root, check=args.catalog_cmd == "check", typescript=projection)
|
|
4125
|
+
else:
|
|
4126
|
+
result = rule_catalog_artifact.sync(root, check=args.catalog_cmd == "check")
|
|
4037
4127
|
print(result.message)
|
|
4038
4128
|
return result.status
|
|
4039
4129
|
|
|
@@ -4150,7 +4240,7 @@ def _run_repo_release_publish(args: _Args, root: Path) -> int:
|
|
|
4150
4240
|
|
|
4151
4241
|
target = args.release_target
|
|
4152
4242
|
match target:
|
|
4153
|
-
case "typescript" | "bootstrap" | "python" | "sql" | "iac" | "standards" | "tsconfig":
|
|
4243
|
+
case "typescript" | "bootstrap" | "contracts" | "python" | "sql" | "iac" | "standards" | "tsconfig":
|
|
4154
4244
|
publish_target = target
|
|
4155
4245
|
case _:
|
|
4156
4246
|
return 2
|
|
@@ -4218,7 +4308,7 @@ def _run_repo_rules_verify(args: _Args) -> int:
|
|
|
4218
4308
|
msg = "verify requires a rule selector"
|
|
4219
4309
|
raise TypeError(msg)
|
|
4220
4310
|
try:
|
|
4221
|
-
result = rule_authoring.verify(_resolve_dest(args.dest), args.selector)
|
|
4311
|
+
result = rule_authoring.verify(_resolve_dest(args.dest), args.selector, run_tests=True)
|
|
4222
4312
|
except (OSError, TypeError, ValueError, RuntimeError) as exc:
|
|
4223
4313
|
print(f"error: cannot verify rule: {exc}", file=sys.stderr)
|
|
4224
4314
|
return 2
|
|
@@ -4232,22 +4322,28 @@ def _run_repo_rules_stage_warning(args: _Args) -> int:
|
|
|
4232
4322
|
if args.selector is None: # pragma: no cover - Typer requires the positional value
|
|
4233
4323
|
msg = f"{args.rules_cmd} requires a rule selector"
|
|
4234
4324
|
raise TypeError(msg)
|
|
4325
|
+
typescript = None
|
|
4235
4326
|
if args.rules_cmd == "prepare":
|
|
4236
4327
|
from sarj_standards.libs.repository import ( # ruff: ignore[import-outside-top-level]
|
|
4237
4328
|
rule_authoring,
|
|
4238
4329
|
)
|
|
4239
4330
|
|
|
4240
4331
|
try:
|
|
4241
|
-
verified = rule_authoring.verify(_resolve_dest(args.dest), args.selector)
|
|
4332
|
+
verified = rule_authoring.verify(_resolve_dest(args.dest), args.selector, run_tests=True)
|
|
4242
4333
|
except (OSError, TypeError, ValueError, RuntimeError) as exc:
|
|
4243
4334
|
print(f"error: cannot verify rule before preparation: {exc}", file=sys.stderr)
|
|
4244
4335
|
return 2
|
|
4245
4336
|
if verified.status != 0:
|
|
4246
4337
|
print(verified.message)
|
|
4247
4338
|
return verified.status
|
|
4339
|
+
typescript = verified.typescript
|
|
4248
4340
|
try:
|
|
4249
4341
|
operation = rule_lifecycle.promote_error if args.rules_cmd == "promote-error" else rule_lifecycle.stage_warning
|
|
4250
|
-
result =
|
|
4342
|
+
result = (
|
|
4343
|
+
operation(_resolve_dest(args.dest), args.selector, check=args.check)
|
|
4344
|
+
if typescript is None
|
|
4345
|
+
else operation(_resolve_dest(args.dest), args.selector, check=args.check, typescript=typescript)
|
|
4346
|
+
)
|
|
4251
4347
|
except (OSError, TypeError, ValueError, RuntimeError) as exc:
|
|
4252
4348
|
print(f"error: cannot update rule lifecycle: {exc}", file=sys.stderr)
|
|
4253
4349
|
return 2
|