scripts/ had ~80 flat files. Entry points (ci_*.sh, codegen.sh, run_tests.sh, format_native.sh, setup_hooks.sh, upload-symbols.*) and the shared pubspec_version.py stay at the root; checkers, generators, maestro tooling and release tooling move into subdirectories with their tests. Updated every reference: workflow steps, guard-test glob, Docker COPY paths and .dockerignore whitelist, website audit path, dart test imports, and regenerated the five outputs whose headers embed generator paths.
127 lines
4.7 KiB
Python
Executable File
127 lines
4.7 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import importlib.util
|
|
import json
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
SCRIPT = Path(__file__).with_name("check_apple_spm_locks.py")
|
|
SPEC = importlib.util.spec_from_file_location("check_apple_spm_locks", SCRIPT)
|
|
CHECKER = importlib.util.module_from_spec(SPEC)
|
|
assert SPEC.loader is not None
|
|
SPEC.loader.exec_module(CHECKER)
|
|
|
|
GOOD_VERSION = "8.58.3"
|
|
GOOD_REVISION = "dad229c665bfd043c5d80ac7aa77717cbd19a1c3"
|
|
|
|
|
|
class AppleSpmLockCheckerTest(unittest.TestCase):
|
|
def setUp(self) -> None:
|
|
self.temporary = tempfile.TemporaryDirectory()
|
|
self.root = Path(self.temporary.name)
|
|
self._write_package_config()
|
|
self._write_manifests(GOOD_VERSION)
|
|
self._write_all_locks(GOOD_VERSION, GOOD_REVISION)
|
|
|
|
def tearDown(self) -> None:
|
|
self.temporary.cleanup()
|
|
|
|
def _write_package_config(self, root_uri: str = "../packages/sentry_flutter") -> None:
|
|
path = self.root / ".dart_tool/package_config.json"
|
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
path.write_text(
|
|
json.dumps(
|
|
{
|
|
"configVersion": 2,
|
|
"packages": [{"name": "sentry_flutter", "rootUri": root_uri}],
|
|
}
|
|
),
|
|
encoding="utf-8",
|
|
)
|
|
|
|
def _write_manifests(self, version: str) -> None:
|
|
source = f'.package(url: "https://github.com/getsentry/sentry-cocoa", exact: "{version}")\n'
|
|
for platform in ("ios", "macos"):
|
|
path = self.root / f"packages/sentry_flutter/{platform}/sentry_flutter/Package.swift"
|
|
path.parent.mkdir(parents=True)
|
|
path.write_text(source, encoding="utf-8")
|
|
|
|
def _lock_payload(self, version: str, revision: str) -> dict:
|
|
return {
|
|
"originHash": "fixture",
|
|
"pins": [
|
|
{
|
|
"identity": "sentry-cocoa",
|
|
"kind": "remoteSourceControl",
|
|
"location": "https://github.com/getsentry/sentry-cocoa",
|
|
"state": {"revision": revision, "version": version},
|
|
}
|
|
],
|
|
"version": 2,
|
|
}
|
|
|
|
def _write_lock(self, relative: Path, version: str, revision: str) -> None:
|
|
path = self.root / relative
|
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
path.write_text(json.dumps(self._lock_payload(version, revision)), encoding="utf-8")
|
|
|
|
def _write_all_locks(self, version: str, revision: str) -> None:
|
|
for paths in CHECKER.LOCK_PAIRS.values():
|
|
for path in paths:
|
|
self._write_lock(path, version, revision)
|
|
|
|
def test_consistent_graph_passes_library_and_cli(self) -> None:
|
|
self.assertEqual([], CHECKER.validate(self.root))
|
|
completed = subprocess.run(
|
|
[sys.executable, str(SCRIPT), "--root", str(self.root)],
|
|
check=False,
|
|
capture_output=True,
|
|
text=True,
|
|
)
|
|
self.assertEqual(0, completed.returncode, completed.stdout + completed.stderr)
|
|
self.assertIn("Apple SwiftPM locks match", completed.stdout)
|
|
|
|
def test_absolute_file_uri_resolves_sentry_manifests(self) -> None:
|
|
self._write_package_config((self.root / "packages/sentry_flutter").resolve().as_uri())
|
|
|
|
self.assertEqual([], CHECKER.validate(self.root))
|
|
|
|
def test_reports_project_workspace_version_mismatch(self) -> None:
|
|
workspace = CHECKER.LOCK_PAIRS["iOS"][1]
|
|
self._write_lock(workspace, "8.58.0", "old")
|
|
|
|
errors = CHECKER.validate(self.root)
|
|
|
|
self.assertTrue(any(str(workspace) in error and "sentry-cocoa" in error for error in errors))
|
|
self.assertTrue(any("iOS SwiftPM locks differ" in error for error in errors))
|
|
|
|
def test_reports_all_locks_stale_against_manifests(self) -> None:
|
|
self._write_all_locks("8.58.0", "old")
|
|
|
|
errors = CHECKER.validate(self.root)
|
|
|
|
self.assertEqual(4, sum("manifest requires exactly 8.58.3" in error for error in errors))
|
|
|
|
def test_reports_same_version_with_different_revision(self) -> None:
|
|
workspace = CHECKER.LOCK_PAIRS["macOS"][1]
|
|
self._write_lock(workspace, GOOD_VERSION, "different")
|
|
|
|
errors = CHECKER.validate(self.root)
|
|
|
|
self.assertTrue(any("macOS SwiftPM locks differ" in error and "sentry-cocoa" in error for error in errors))
|
|
self.assertTrue(any("state differs" in error for error in errors))
|
|
|
|
def test_reports_missing_resolved_package_inputs(self) -> None:
|
|
(self.root / ".dart_tool/package_config.json").unlink()
|
|
|
|
errors = CHECKER.validate(self.root)
|
|
|
|
self.assertTrue(any("flutter pub get first" in error for error in errors))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|