mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-10 13:33:24 -05:00
fix: require the jsonschema format checkers
This commit is contained in:
1 parent
892cff38bc
commit
e9653069a2
7 files changed
+59
-5
No files matched your search
@@ -84,7 +84,7 @@ jobs:
|
|||||||
|
|
||||||
# mkdocs-material >= 9.7.5 caps mkdocs < 2; the upper bound keeps a major
|
# mkdocs-material >= 9.7.5 caps mkdocs < 2; the upper bound keeps a major
|
||||||
# theme release from changing the site without a deliberate bump here.
|
# theme release from changing the site without a deliberate bump here.
|
||||||
- run: pip install pyyaml jsonschema==4.26.0 "mkdocs-material>=9.7.5,<10" "pymdown-extensions>=10.14"
|
- run: pip install pyyaml "jsonschema[format-nongpl]==4.26.0" "mkdocs-material>=9.7.5,<10" "pymdown-extensions>=10.14"
|
||||||
|
|
||||||
- name: Validate data contracts
|
- name: Validate data contracts
|
||||||
run: python scripts/validate_schemas.py
|
run: python scripts/validate_schemas.py
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ jobs:
|
|||||||
python-version: "3.12"
|
python-version: "3.12"
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pip install pyyaml jsonschema==4.26.0
|
run: pip install pyyaml "jsonschema[format-nongpl]==4.26.0"
|
||||||
|
|
||||||
- name: Validate platform configs and emulator profiles
|
- name: Validate platform configs and emulator profiles
|
||||||
run: python scripts/validate_schemas.py --source-only
|
run: python scripts/validate_schemas.py --source-only
|
||||||
@@ -127,7 +127,7 @@ jobs:
|
|||||||
python-version: "3.12"
|
python-version: "3.12"
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pip install pyyaml jsonschema==4.26.0
|
run: pip install pyyaml "jsonschema[format-nongpl]==4.26.0"
|
||||||
|
|
||||||
# The exporter fidelity cases compare what we hand back against the
|
# The exporter fidelity cases compare what we hand back against the
|
||||||
# file each platform publishes, so they need those files. They skip
|
# file each platform publishes, so they need those files. They skip
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@ dependencies = [
|
|||||||
# and the CI contract check are the only callers, and no user path imports it.
|
# and the CI contract check are the only callers, and no user path imports it.
|
||||||
[project.optional-dependencies]
|
[project.optional-dependencies]
|
||||||
dev = [
|
dev = [
|
||||||
"jsonschema>=4.23",
|
"jsonschema[format-nongpl]>=4.23",
|
||||||
]
|
]
|
||||||
# The site build the repo generates and documents. Both were hard
|
# The site build the repo generates and documents. Both were hard
|
||||||
# requirements of deploy-site.yml and of wiki/release-process.md while being
|
# requirements of deploy-site.yml and of wiki/release-process.md while being
|
||||||
|
|||||||
@@ -804,7 +804,9 @@ def _check_fbneo(cache_dir: str, offline: bool) -> Finding:
|
|||||||
|
|
||||||
# --- CI toolchain -----------------------------------------------------------
|
# --- CI toolchain -----------------------------------------------------------
|
||||||
|
|
||||||
_PIN_RE = re.compile(r'"?([A-Za-z0-9_.\-]+)((?:[<>=!~]=?[^,"\s]+)(?:,[<>=!~]=?[^,"\s]+)*)?"?')
|
_PIN_RE = re.compile(
|
||||||
|
r'"?([A-Za-z0-9_.\-]+)(?:\[[^\]]*\])?((?:[<>=!~]=?[^,"\s]+)(?:,[<>=!~]=?[^,"\s]+)*)?"?'
|
||||||
|
)
|
||||||
_USES_RE = re.compile(r"uses:\s*([\w.\-]+/[\w.\-]+)@([0-9a-f]{40})\s*(?:#\s*(\S+))?")
|
_USES_RE = re.compile(r"uses:\s*([\w.\-]+/[\w.\-]+)@([0-9a-f]{40})\s*(?:#\s*(\S+))?")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -254,6 +254,20 @@ def _semantic_install_checks(path: Path, manifest: dict) -> list[str]:
|
|||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def unchecked_formats() -> list[str]:
|
||||||
|
"""Formats the schemas declare that this jsonschema install cannot check.
|
||||||
|
|
||||||
|
date-time and uri need the format extras; without them the ten format
|
||||||
|
constraints of the published schemas were accepted unread.
|
||||||
|
"""
|
||||||
|
used = {
|
||||||
|
match
|
||||||
|
for path in SCHEMAS.glob("*.json")
|
||||||
|
for match in re.findall(r'"format"\s*:\s*"([^"]+)"', path.read_text(encoding="utf-8"))
|
||||||
|
}
|
||||||
|
return sorted(used - set(FormatChecker().checkers))
|
||||||
|
|
||||||
|
|
||||||
def main() -> int:
|
def main() -> int:
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
@@ -263,6 +277,16 @@ def main() -> int:
|
|||||||
)
|
)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
unchecked = unchecked_formats()
|
||||||
|
if unchecked:
|
||||||
|
# jsonschema skips a format it has no checker for, silently.
|
||||||
|
print(
|
||||||
|
f"ERROR no checker for format(s) {', '.join(unchecked)}: "
|
||||||
|
'install "jsonschema[format-nongpl]"',
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
return 1
|
||||||
|
|
||||||
errors: list[str] = []
|
errors: list[str] = []
|
||||||
errors.extend(
|
errors.extend(
|
||||||
_validate_yaml_directory(ROOT / "emulators", "emulator.schema.json")
|
_validate_yaml_directory(ROOT / "emulators", "emulator.schema.json")
|
||||||
|
|||||||
@@ -570,6 +570,26 @@ class PipelineRegressions(unittest.TestCase):
|
|||||||
self.assertTrue(full_models, truth_runs)
|
self.assertTrue(full_models, truth_runs)
|
||||||
|
|
||||||
|
|
||||||
|
class SchemaFormatsAreChecked(unittest.TestCase):
|
||||||
|
"""date-time and uri need jsonschema's format extras; without them the
|
||||||
|
published format constraints were accepted unread."""
|
||||||
|
|
||||||
|
@unittest.skipUnless(HAS_JSONSCHEMA, "validating a schema needs jsonschema")
|
||||||
|
def test_a_missing_checker_is_named(self):
|
||||||
|
import validate_schemas
|
||||||
|
|
||||||
|
empty = mock.Mock(checkers={})
|
||||||
|
with mock.patch.object(validate_schemas, "FormatChecker", return_value=empty):
|
||||||
|
self.assertEqual(validate_schemas.unchecked_formats(), ["date-time", "uri"])
|
||||||
|
|
||||||
|
def test_every_install_asks_for_the_extras(self):
|
||||||
|
for path in (".github/workflows/validate.yml", ".github/workflows/deploy-site.yml",
|
||||||
|
"pyproject.toml"):
|
||||||
|
text = (ROOT / path).read_text(encoding="utf-8")
|
||||||
|
with self.subTest(path=path):
|
||||||
|
self.assertNotRegex(text, r"jsonschema(?!\[format)[=>]")
|
||||||
|
|
||||||
|
|
||||||
class ResolverRegressions(unittest.TestCase):
|
class ResolverRegressions(unittest.TestCase):
|
||||||
def _database(self, entries: dict[str, Path], suffix: str | None = None) -> dict:
|
def _database(self, entries: dict[str, Path], suffix: str | None = None) -> dict:
|
||||||
files = {}
|
files = {}
|
||||||
|
|||||||
@@ -318,5 +318,13 @@ class RepeatedDestinations(unittest.TestCase):
|
|||||||
self.assertEqual(diff.files_changed, ["pce/syscard3.pce"])
|
self.assertEqual(diff.files_changed, ["pce/syscard3.pce"])
|
||||||
|
|
||||||
|
|
||||||
|
class PinsWithExtras(unittest.TestCase):
|
||||||
|
def test_an_extras_bracket_keeps_its_pin(self):
|
||||||
|
from check_freshness import parse_pip_pins # noqa: PLC0415
|
||||||
|
|
||||||
|
pins = parse_pip_pins(' run: pip install pyyaml "jsonschema[format-nongpl]==4.26.0"')
|
||||||
|
self.assertEqual(pins["jsonschema"], "==4.26.0")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
Reference in new issue
Block a user