9fd04b0ce4
Add the owner-only AF_UNIX Reyna CLI privacy host, strict signed-app installation, and typed native routing for Calendar, Contacts, and Reminders.\n\nAdd bounded system-status paths and config-only direct local-service wrappers. Preserve MacMiniMCP pending explicit cutover approval.\n\nApple Notes is intentionally deferred: no native Notes operations, Apple Events declaration, or Automation helper are included; legacy Notes handling remains untouched.
541 lines
20 KiB
Python
541 lines
20 KiB
Python
"""TDD for secure explicit prebuilt signed app install bridge — no DerivedData scan, no secret leak."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import plistlib
|
|
import stat
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
from typer.testing import CliRunner
|
|
|
|
from reyna_cli.cli import app
|
|
|
|
runner = CliRunner()
|
|
|
|
|
|
def _mock_proc(rc=0, stdout="", stderr=""):
|
|
from types import SimpleNamespace
|
|
|
|
return SimpleNamespace(returncode=rc, stdout=stdout, stderr=stderr)
|
|
|
|
|
|
def _make_fake_app_bundle(base: Path, bundle_name: str = "Reyna CLI.app", bundle_id: str = "com.reyna.cli.privacy-host"):
|
|
"""Create a minimal .app bundle directory with Info.plist and executable."""
|
|
from reyna_cli import app_bundle as ab
|
|
|
|
bundle = base / bundle_name
|
|
contents = bundle / "Contents"
|
|
macos = contents / "MacOS"
|
|
macos.mkdir(parents=True, exist_ok=True)
|
|
exe = macos / "ReynaCLIHost"
|
|
exe.write_bytes(b"fakebinarycontent")
|
|
exe.chmod(0o755)
|
|
plist_dict = ab.build_app_bundle_info_plist_dict()
|
|
# allow custom bundle_id for negative tests
|
|
if bundle_id != plist_dict.get("CFBundleIdentifier"):
|
|
plist_dict = dict(plist_dict)
|
|
plist_dict["CFBundleIdentifier"] = bundle_id
|
|
with open(contents / "Info.plist", "wb") as f:
|
|
plistlib.dump(plist_dict, f)
|
|
return bundle
|
|
|
|
|
|
# ----------------------------------------------------------------------
|
|
# app_bundle layer
|
|
# ----------------------------------------------------------------------
|
|
|
|
|
|
def test_validate_app_bundle_at_path_success(tmp_path):
|
|
from reyna_cli import app_bundle as ab
|
|
|
|
src_root = tmp_path / "src"
|
|
src_root.mkdir()
|
|
bundle = _make_fake_app_bundle(src_root)
|
|
|
|
def run_ok(args, cwd=None, **kwargs):
|
|
if args[:3] == ["codesign", "--verify", "--deep"]:
|
|
return _mock_proc(rc=0)
|
|
if args[:2] == ["codesign", "-dv"]:
|
|
return _mock_proc(rc=0, stderr="TeamIdentifier=TEAM123\nAuthority=Apple Development: Foo (TEAM123)\n")
|
|
return _mock_proc(rc=0)
|
|
|
|
res = ab.validate_app_bundle_at_path(bundle, runner=run_ok)
|
|
assert res["ok"] is True
|
|
assert res["signature_verified"] is True
|
|
assert res["is_ad_hoc"] is False
|
|
assert res["bundle_identifier_matches"] is True
|
|
|
|
|
|
def test_validate_app_bundle_at_path_rejects_relative(tmp_path):
|
|
from reyna_cli import app_bundle as ab
|
|
|
|
rel = Path("relative/Reyna CLI.app")
|
|
res = ab.validate_app_bundle_at_path(rel)
|
|
assert res["ok"] is False
|
|
assert any("absolute" in e.lower() for e in res["errors"])
|
|
|
|
|
|
def test_validate_app_bundle_at_path_rejects_wrong_suffix(tmp_path):
|
|
from reyna_cli import app_bundle as ab
|
|
|
|
p = tmp_path / "notapp"
|
|
p.mkdir()
|
|
res = ab.validate_app_bundle_at_path(p)
|
|
assert res["ok"] is False
|
|
assert any(".app" in e.lower() for e in res["errors"])
|
|
|
|
|
|
def test_validate_app_bundle_at_path_rejects_symlink(tmp_path):
|
|
from reyna_cli import app_bundle as ab
|
|
|
|
real_root = tmp_path / "real"
|
|
real_root.mkdir()
|
|
bundle = _make_fake_app_bundle(real_root)
|
|
link = tmp_path / "Reyna CLI.app"
|
|
link.symlink_to(bundle)
|
|
|
|
res = ab.validate_app_bundle_at_path(link)
|
|
assert res["ok"] is False
|
|
assert any("symlink" in e.lower() for e in res["errors"])
|
|
|
|
|
|
def test_validate_app_bundle_at_path_rejects_ad_hoc(tmp_path):
|
|
from reyna_cli import app_bundle as ab
|
|
|
|
src_root = tmp_path / "src"
|
|
src_root.mkdir()
|
|
bundle = _make_fake_app_bundle(src_root)
|
|
|
|
def run_adhoc(args, cwd=None, **kwargs):
|
|
if args[:3] == ["codesign", "--verify", "--deep"]:
|
|
return _mock_proc(rc=0)
|
|
if args[:2] == ["codesign", "-dv"]:
|
|
return _mock_proc(rc=0, stderr="Signature=adhoc\nTeamIdentifier=not set\n")
|
|
return _mock_proc(rc=0)
|
|
|
|
res = ab.validate_app_bundle_at_path(bundle, runner=run_adhoc)
|
|
assert res["ok"] is False
|
|
assert res["is_ad_hoc"] is True
|
|
|
|
|
|
def test_install_prebuilt_app_bundle_success_no_xcodebuild(tmp_path):
|
|
from reyna_cli import app_bundle as ab
|
|
|
|
src_root = tmp_path / "gui-build"
|
|
src_root.mkdir()
|
|
bundle = _make_fake_app_bundle(src_root)
|
|
|
|
repo_root = tmp_path / "repo"
|
|
repo_root.mkdir()
|
|
|
|
calls = []
|
|
|
|
def runner(args, cwd=None, **kwargs):
|
|
assert isinstance(args, list)
|
|
calls.append(list(args))
|
|
if args and args[0] == "xcodebuild":
|
|
raise AssertionError("xcodebuild must NOT be called on prebuilt path")
|
|
if args[:3] == ["codesign", "--verify", "--deep"]:
|
|
return _mock_proc(rc=0)
|
|
if args[:2] == ["codesign", "-dv"]:
|
|
return _mock_proc(rc=0, stderr="TeamIdentifier=TEAM123\n")
|
|
return _mock_proc(rc=0)
|
|
|
|
res = ab.install_prebuilt_app_bundle(source_bundle_path=bundle, repo_root=repo_root, runner=runner)
|
|
assert res["ok"] is True
|
|
assert res["action"] == "install_prebuilt_app_bundle"
|
|
assert "signature_verified" in res
|
|
# Must have copied to dist
|
|
dist_bundle = repo_root / "native" / "ReynaCLIHost" / "dist" / "Reyna CLI.app"
|
|
assert dist_bundle.exists()
|
|
assert (dist_bundle / "Contents" / "MacOS" / "ReynaCLIHost").exists()
|
|
# No xcodebuild calls
|
|
assert all(c[0] != "xcodebuild" for c in calls)
|
|
# Must have called codesign validation for source and copy (at least 2 verifies)
|
|
verify_calls = [c for c in calls if c[:3] == ["codesign", "--verify", "--deep"]]
|
|
assert len(verify_calls) >= 2
|
|
|
|
|
|
def test_install_prebuilt_app_bundle_invalid_prevents_copy(tmp_path, monkeypatch):
|
|
from reyna_cli import app_bundle as ab
|
|
|
|
src_root = tmp_path / "gui-build"
|
|
src_root.mkdir()
|
|
bundle = _make_fake_app_bundle(src_root)
|
|
|
|
repo_root = tmp_path / "repo"
|
|
repo_root.mkdir()
|
|
|
|
def runner_bad(args, cwd=None, **kwargs):
|
|
if args[:3] == ["codesign", "--verify", "--deep"]:
|
|
return _mock_proc(rc=1, stderr="verify fail")
|
|
if args[:2] == ["codesign", "-dv"]:
|
|
return _mock_proc(rc=0, stderr="TeamIdentifier=not set\n")
|
|
return _mock_proc(rc=0)
|
|
|
|
# Patch copy to detect if called
|
|
copied = {"called": False}
|
|
original_copy = ab._copy_app_bundle_atomic
|
|
|
|
def tracking_copy(src, dst):
|
|
copied["called"] = True
|
|
return original_copy(src, dst)
|
|
|
|
monkeypatch.setattr(ab, "_copy_app_bundle_atomic", tracking_copy)
|
|
|
|
res = ab.install_prebuilt_app_bundle(source_bundle_path=bundle, repo_root=repo_root, runner=runner_bad)
|
|
assert res["ok"] is False
|
|
assert copied["called"] is False, "must not copy if source validation fails"
|
|
dist_bundle = repo_root / "native" / "ReynaCLIHost" / "dist" / "Reyna CLI.app"
|
|
assert not dist_bundle.exists()
|
|
|
|
|
|
def test_install_prebuilt_app_bundle_rejects_symlink_and_relative(tmp_path):
|
|
from reyna_cli import app_bundle as ab
|
|
|
|
real_root = tmp_path / "real"
|
|
real_root.mkdir()
|
|
bundle = _make_fake_app_bundle(real_root)
|
|
link = tmp_path / "Reyna CLI.app"
|
|
link.symlink_to(bundle)
|
|
|
|
repo_root = tmp_path / "repo"
|
|
repo_root.mkdir()
|
|
|
|
def runner(args, cwd=None, **kwargs):
|
|
return _mock_proc(rc=0)
|
|
|
|
res_link = ab.install_prebuilt_app_bundle(source_bundle_path=link, repo_root=repo_root, runner=runner)
|
|
assert res_link["ok"] is False
|
|
assert "symlink" in res_link["error"].lower()
|
|
|
|
# Relative
|
|
rel = Path("relative/Reyna CLI.app")
|
|
res_rel = ab.install_prebuilt_app_bundle(source_bundle_path=rel, repo_root=repo_root, runner=runner)
|
|
assert res_rel["ok"] is False
|
|
assert "absolute" in res_rel["error"].lower()
|
|
|
|
# Wrong suffix
|
|
wrong = tmp_path / "wrong.appstuff"
|
|
wrong.mkdir()
|
|
res_suffix = ab.install_prebuilt_app_bundle(source_bundle_path=wrong, repo_root=repo_root, runner=runner)
|
|
assert res_suffix["ok"] is False
|
|
assert ".app" in res_suffix["error"].lower()
|
|
|
|
|
|
def test_install_prebuilt_no_secret_leak_in_result(tmp_path):
|
|
from reyna_cli import app_bundle as ab
|
|
|
|
src_root = tmp_path / "src"
|
|
src_root.mkdir()
|
|
bundle = _make_fake_app_bundle(src_root)
|
|
|
|
repo_root = tmp_path / "repo"
|
|
repo_root.mkdir()
|
|
|
|
secret_team = "TEAM_SUPERSECRET123"
|
|
|
|
def runner(args, cwd=None, **kwargs):
|
|
if args[:3] == ["codesign", "--verify", "--deep"]:
|
|
return _mock_proc(rc=0, stdout=f"Authority=Secret {secret_team}")
|
|
if args[:2] == ["codesign", "-dv"]:
|
|
return _mock_proc(rc=0, stderr=f"TeamIdentifier={secret_team}\nAuthority=Apple Development: Foo ({secret_team})\n")
|
|
return _mock_proc(rc=0)
|
|
|
|
res = ab.install_prebuilt_app_bundle(source_bundle_path=bundle, repo_root=repo_root, runner=runner)
|
|
assert res["ok"] is True
|
|
# Stringified result must not contain raw team identifier output (we filter generically)
|
|
# Our runner purposely returns secret in stderr, but result should not echo stderr verbatim
|
|
import json
|
|
|
|
res_str = json.dumps(res)
|
|
# The implementation stores no raw codesign output, only booleans
|
|
assert "Authority=Apple" not in res_str
|
|
assert secret_team not in res_str or res.get("validation", {}).get("signature_verified") is True and secret_team not in str(res.get("validation", {}).get("errors", []))
|
|
|
|
|
|
# ----------------------------------------------------------------------
|
|
# privacy_host layer — prebuilt route
|
|
# ----------------------------------------------------------------------
|
|
|
|
|
|
def test_privacy_host_install_prebuilt_success_no_xcodebuild(tmp_path):
|
|
from reyna_cli import privacy_host as ph_mod, app_bundle as ab_mod
|
|
|
|
src_root = tmp_path / "gui"
|
|
src_root.mkdir()
|
|
src_bundle = _make_fake_app_bundle(src_root)
|
|
|
|
repo_root = tmp_path / "repo"
|
|
repo_root.mkdir()
|
|
sock = tmp_path / "priv" / "reyna-cli.sock"
|
|
plist = tmp_path / "LaunchAgents" / "com.reyna.cli.privacy-host.plist"
|
|
logd = tmp_path / "Logs"
|
|
|
|
calls = []
|
|
|
|
def fake_runner(args, cwd=None, **kwargs):
|
|
assert isinstance(args, list)
|
|
calls.append(list(args))
|
|
if args and args[0] == "xcodebuild":
|
|
raise AssertionError("xcodebuild must not be called when prebuilt path supplied")
|
|
if args[:3] == ["codesign", "--verify", "--deep"]:
|
|
return _mock_proc(rc=0)
|
|
if args[:2] == ["codesign", "-dv"]:
|
|
return _mock_proc(rc=0, stderr="TeamIdentifier=TEAM123\n")
|
|
return _mock_proc(rc=0)
|
|
|
|
result = ph_mod.install_privacy_host_service(
|
|
runner=fake_runner,
|
|
uid=501,
|
|
repo_root=repo_root,
|
|
socket_path=sock,
|
|
plist_path=plist,
|
|
log_dir=logd,
|
|
prebuilt_app_bundle_path=src_bundle,
|
|
)
|
|
|
|
assert result["ok"] is True
|
|
assert plist.exists()
|
|
# No xcodebuild
|
|
assert all(c[0] != "xcodebuild" for c in calls)
|
|
# Must have bootout+bootstrap
|
|
assert ["launchctl", "bootout", "gui/501/com.reyna.cli.privacy-host"] in calls
|
|
assert ["launchctl", "bootstrap", "gui/501", str(plist)] in calls
|
|
# Dist bundle exists
|
|
dist_bundle = repo_root / "native" / "ReynaCLIHost" / "dist" / "Reyna CLI.app"
|
|
assert dist_bundle.exists()
|
|
|
|
|
|
def test_privacy_host_install_prebuilt_invalid_prevents_plist_and_launchctl(tmp_path):
|
|
from reyna_cli import privacy_host as ph_mod
|
|
|
|
src_root = tmp_path / "gui"
|
|
src_root.mkdir()
|
|
src_bundle = _make_fake_app_bundle(src_root)
|
|
|
|
repo_root = tmp_path / "repo"
|
|
repo_root.mkdir()
|
|
sock = tmp_path / "priv" / "reyna-cli.sock"
|
|
plist = tmp_path / "LaunchAgents" / "com.reyna.cli.privacy-host.plist"
|
|
logd = tmp_path / "Logs"
|
|
|
|
calls = []
|
|
|
|
def fake_runner(args, cwd=None, **kwargs):
|
|
calls.append(list(args))
|
|
if args[:3] == ["codesign", "--verify", "--deep"]:
|
|
return _mock_proc(rc=1, stderr="fail")
|
|
if args[:2] == ["codesign", "-dv"]:
|
|
return _mock_proc(rc=0, stderr="TeamIdentifier=not set\nSignature=adhoc\n")
|
|
return _mock_proc(rc=0)
|
|
|
|
result = ph_mod.install_privacy_host_service(
|
|
runner=fake_runner,
|
|
uid=501,
|
|
repo_root=repo_root,
|
|
socket_path=sock,
|
|
plist_path=plist,
|
|
log_dir=logd,
|
|
prebuilt_app_bundle_path=src_bundle,
|
|
)
|
|
|
|
assert result["ok"] is False
|
|
assert not plist.exists(), "plist must not be written if prebuilt validation fails"
|
|
# No launchctl should have been called
|
|
launch_calls = [c for c in calls if c and c[0] == "launchctl"]
|
|
assert len(launch_calls) == 0, f"launchctl must not be called on invalid source, got {launch_calls}"
|
|
|
|
|
|
def test_privacy_host_install_prebuilt_rejects_symlink_and_relative(tmp_path):
|
|
from reyna_cli import privacy_host as ph_mod
|
|
|
|
real_root = tmp_path / "real"
|
|
real_root.mkdir()
|
|
real_bundle = _make_fake_app_bundle(real_root)
|
|
|
|
repo_root = tmp_path / "repo"
|
|
repo_root.mkdir()
|
|
plist = tmp_path / "LaunchAgents" / "com.reyna.cli.privacy-host.plist"
|
|
|
|
link = tmp_path / "Reyna CLI.app"
|
|
link.symlink_to(real_bundle)
|
|
|
|
def runner(args, cwd=None, **kwargs):
|
|
return _mock_proc(rc=0)
|
|
|
|
res_link = ph_mod.install_privacy_host_service(
|
|
runner=runner,
|
|
uid=501,
|
|
repo_root=repo_root,
|
|
plist_path=plist,
|
|
prebuilt_app_bundle_path=link,
|
|
)
|
|
assert res_link["ok"] is False
|
|
assert "symlink" in res_link["error"].lower()
|
|
|
|
# Relative
|
|
rel = Path("relative/Reyna CLI.app")
|
|
res_rel = ph_mod.install_privacy_host_service(
|
|
runner=runner,
|
|
uid=501,
|
|
repo_root=repo_root,
|
|
plist_path=plist,
|
|
prebuilt_app_bundle_path=rel,
|
|
)
|
|
assert res_rel["ok"] is False
|
|
assert "absolute" in res_rel["error"].lower()
|
|
|
|
|
|
def test_privacy_host_install_default_still_calls_xcodebuild(tmp_path):
|
|
from reyna_cli import privacy_host as ph_mod, app_bundle as ab_mod
|
|
|
|
repo_root = tmp_path / "repo"
|
|
repo_root.mkdir()
|
|
(repo_root / "native" / "ReynaCLIHost" / "ReynaCLIHost.xcodeproj").mkdir(parents=True)
|
|
(repo_root / "native" / "ReynaCLIHost" / "ReynaCLIHost").mkdir(parents=True, exist_ok=True)
|
|
(repo_root / "native" / "ReynaCLIHost" / "ReynaCLIHost" / "Info.plist").write_text("<plist></plist>")
|
|
|
|
derived = repo_root / "native" / "ReynaCLIHost" / "build" / "DerivedData"
|
|
built_app = derived / "Build" / "Products" / "Release" / "Reyna CLI.app"
|
|
(built_app / "Contents" / "MacOS").mkdir(parents=True)
|
|
(built_app / "Contents" / "MacOS" / "ReynaCLIHost").write_bytes(b"bin")
|
|
with open(built_app / "Contents" / "Info.plist", "wb") as f:
|
|
plistlib.dump(ab_mod.build_app_bundle_info_plist_dict(), f)
|
|
|
|
sock = tmp_path / "priv" / "reyna-cli.sock"
|
|
plist = tmp_path / "LaunchAgents" / "com.reyna.cli.privacy-host.plist"
|
|
logd = tmp_path / "Logs"
|
|
|
|
calls = []
|
|
|
|
def fake_runner(args, cwd=None, **kwargs):
|
|
calls.append(list(args))
|
|
if args and args[0] == "xcodebuild":
|
|
return _mock_proc(rc=0)
|
|
if args[:3] == ["codesign", "--verify", "--deep"]:
|
|
return _mock_proc(rc=0)
|
|
if args[:2] == ["codesign", "-dv"]:
|
|
return _mock_proc(rc=0, stderr="TeamIdentifier=TEAM123\n")
|
|
return _mock_proc(rc=0)
|
|
|
|
result = ph_mod.install_privacy_host_service(
|
|
runner=fake_runner,
|
|
uid=501,
|
|
repo_root=repo_root,
|
|
socket_path=sock,
|
|
plist_path=plist,
|
|
log_dir=logd,
|
|
signing_identity="Test ID",
|
|
prebuilt_app_bundle_path=None,
|
|
)
|
|
assert result["ok"] is True
|
|
xcode_calls = [c for c in calls if c and c[0] == "xcodebuild"]
|
|
assert len(xcode_calls) >= 1, "default install must still call xcodebuild"
|
|
|
|
|
|
# ----------------------------------------------------------------------
|
|
# CLI wiring
|
|
# ----------------------------------------------------------------------
|
|
|
|
|
|
def test_cli_install_has_app_bundle_option():
|
|
res = runner.invoke(app, ["privacy-host", "install", "--help"])
|
|
assert res.exit_code == 0
|
|
out = res.stdout.lower()
|
|
assert "app-bundle" in out
|
|
|
|
|
|
def test_cli_install_app_bundle_prebuilt_success_mocked(tmp_path, monkeypatch):
|
|
from reyna_cli import privacy_host as ph_mod
|
|
|
|
src_root = tmp_path / "gui"
|
|
src_root.mkdir()
|
|
src_bundle = _make_fake_app_bundle(src_root)
|
|
|
|
captured = {}
|
|
|
|
def fake_install(prebuilt_app_bundle_path=None, **kwargs):
|
|
captured["prebuilt"] = prebuilt_app_bundle_path
|
|
assert prebuilt_app_bundle_path is not None
|
|
assert Path(prebuilt_app_bundle_path).is_absolute()
|
|
assert str(prebuilt_app_bundle_path).endswith(".app")
|
|
return {"ok": True, "action": "install", "app_bundle_path": str(prebuilt_app_bundle_path)}
|
|
|
|
monkeypatch.setattr(ph_mod, "install_privacy_host_service", lambda **kw: fake_install(**kw))
|
|
|
|
res = runner.invoke(app, ["privacy-host", "install", "--app-bundle", str(src_bundle), "--json"])
|
|
assert res.exit_code == 0, res.stdout + res.stderr
|
|
assert captured["prebuilt"] == src_bundle
|
|
|
|
|
|
def test_cli_install_app_bundle_rejects_relative_and_symlink(tmp_path, monkeypatch):
|
|
from reyna_cli import privacy_host as ph_mod
|
|
|
|
# Should fail at CLI layer before calling service, for relative
|
|
def should_not_be_called(**kwargs):
|
|
raise AssertionError("service must not be called when CLI rejects path")
|
|
|
|
monkeypatch.setattr(ph_mod, "install_privacy_host_service", lambda **kw: should_not_be_called(**kw))
|
|
|
|
# Relative
|
|
res_rel = runner.invoke(app, ["privacy-host", "install", "--app-bundle", "relative/Reyna CLI.app", "--json"])
|
|
assert res_rel.exit_code != 0
|
|
assert "absolute" in res_rel.stdout.lower()
|
|
|
|
# Symlink
|
|
real_root = tmp_path / "real"
|
|
real_root.mkdir()
|
|
real_bundle = _make_fake_app_bundle(real_root)
|
|
link = tmp_path / "Reyna CLI.app"
|
|
link.symlink_to(real_bundle)
|
|
|
|
res_link = runner.invoke(app, ["privacy-host", "install", "--app-bundle", str(link), "--json"])
|
|
assert res_link.exit_code != 0
|
|
assert "symlink" in res_link.stdout.lower()
|
|
|
|
|
|
def test_cli_install_default_no_app_bundle_calls_build(tmp_path, monkeypatch):
|
|
from reyna_cli import privacy_host as ph_mod
|
|
|
|
captured = {}
|
|
|
|
def fake_install(prebuilt_app_bundle_path=None, **kwargs):
|
|
captured["prebuilt"] = prebuilt_app_bundle_path
|
|
return {"ok": True, "action": "install", "app_bundle_path": "/fake/dist/Reyna CLI.app"}
|
|
|
|
monkeypatch.setattr(ph_mod, "install_privacy_host_service", lambda **kw: fake_install(**kw))
|
|
|
|
res = runner.invoke(app, ["privacy-host", "install", "--json"])
|
|
assert res.exit_code == 0, res.stdout + res.stderr
|
|
assert captured["prebuilt"] is None, "default should not pass prebuilt path"
|
|
|
|
|
|
def test_no_deriveddata_scan_in_prebuilt_code():
|
|
from pathlib import Path
|
|
|
|
src_app_bundle = Path("/Users/adolforeyna/Projects/reyna-cli/src/reyna_cli/app_bundle.py").read_text()
|
|
src_privacy_host = Path("/Users/adolforeyna/Projects/reyna-cli/src/reyna_cli/privacy_host.py").read_text()
|
|
# Prebuilt functions must not scan DerivedData automatically
|
|
# They should not listdir or glob DerivedData without explicit path
|
|
# Check that install_prebuilt_app_bundle does not reference DerivedData path discovery
|
|
assert "install_prebuilt_app_bundle" in src_app_bundle
|
|
# Ensure function body does not contain DerivedData scan (like os.walk or glob of DerivedData)
|
|
# Simple heuristic: function definition area should not contain "DerivedData" search
|
|
import re
|
|
|
|
# Extract install_prebuilt function
|
|
m = re.search(r"def install_prebuilt_app_bundle.*?^def ", src_app_bundle, flags=re.DOTALL | re.MULTILINE)
|
|
if m:
|
|
func_text = m.group(0)
|
|
# Should not contain "DerivedData" except maybe in comments about NOT using it
|
|
# Allow at most trivial mention, but not listdir/glob
|
|
assert "glob" not in func_text.lower() or "deriveddata" not in func_text.lower()
|
|
assert "os.scandir" not in func_text.lower()
|
|
assert "os.walk" not in func_text.lower()
|
|
# privacy_host prebuilt path should not call build_app_bundle
|
|
# It should have conditional: if prebuilt_app_bundle_path is not None -> install_prebuilt, else build
|
|
assert "prebuilt_app_bundle_path" in src_privacy_host
|