Initial commit
This commit is contained in:
121
applepy.spec
Normal file
121
applepy.spec
Normal file
@@ -0,0 +1,121 @@
|
||||
# PyInstaller spec: `pip install -e ".[bundle]"` then `pyinstaller applepy.spec`
|
||||
# Produces dist/applepy (one-folder) with bundled applepy data (JSON, optional compliance trees).
|
||||
# Run scripts/vendor_compliance_assets.sh before building to embed mSCP + Lynis (not in git).
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from PyInstaller.utils.hooks import collect_data_files
|
||||
|
||||
# Root of the repo when building; PyInstaller defines SPECPATH (not __file__) for .spec evaluation.
|
||||
_SPEC_DIR = Path(SPECPATH)
|
||||
|
||||
|
||||
def _mscp_data_files_excluding_generated(mscp: Path) -> list[tuple[str, str]]:
|
||||
"""
|
||||
Per-file datas for mSCP: omit ``build/`` (output from generate_guidance on the host) and ``.git``.
|
||||
|
||||
Shipping ``build/`` bloats the bundle and, after ``sudo dist/.../applepy``, can leave root-owned
|
||||
trees that break the next PyInstaller clean of ``dist/applepy``.
|
||||
"""
|
||||
prefix = Path("applepy/data/macos_security")
|
||||
out: list[tuple[str, str]] = []
|
||||
for p in mscp.rglob("*"):
|
||||
if not p.is_file():
|
||||
continue
|
||||
try:
|
||||
rel = p.relative_to(mscp)
|
||||
except ValueError:
|
||||
continue
|
||||
parts = rel.parts
|
||||
if not parts:
|
||||
continue
|
||||
if parts[0] == "build" or parts[0] == ".git":
|
||||
continue
|
||||
if ".git" in parts:
|
||||
continue
|
||||
dest_dir = str(prefix / rel.parent)
|
||||
out.append((str(p), dest_dir))
|
||||
return out
|
||||
|
||||
|
||||
def _applepy_datas_excluding_mscp_tree() -> list[tuple[str, str]]:
|
||||
"""Package data from ``collect_data_files`` minus ``macos_security`` (re-added below, with filters)."""
|
||||
return [(s, d) for s, d in collect_data_files("applepy") if "macos_security" not in Path(s).parts]
|
||||
|
||||
|
||||
def _optional_mscp_datas() -> list[tuple[str, str]]:
|
||||
mscp = _SPEC_DIR / "applepy" / "data" / "macos_security"
|
||||
if not (mscp / "scripts" / "generate_guidance.py").is_file():
|
||||
return []
|
||||
return _mscp_data_files_excluding_generated(mscp)
|
||||
|
||||
|
||||
# Lynis and other ``applepy/data`` trees stay on the collect_data_files side; mSCP is merged once here
|
||||
# without ``.git`` or ``build/`` (avoids bloated bundles and root-owned build dirs after sudo runs).
|
||||
datas = _applepy_datas_excluding_mscp_tree() + _optional_mscp_datas()
|
||||
|
||||
a = Analysis(
|
||||
["applepy/__main__.py"],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=datas,
|
||||
hiddenimports=[
|
||||
"openpyxl",
|
||||
"yaml",
|
||||
"_yaml",
|
||||
"xlwt",
|
||||
# mSCP generate_guidance.py (run via runpy in frozen binary): explicit stdlib names as well as the hook module.
|
||||
"uuid",
|
||||
"zipfile",
|
||||
"applepy.pyi_mscp_stdlib",
|
||||
"applepy.check_progress",
|
||||
"applepy.checks",
|
||||
"applepy.checks.mdm.jamf",
|
||||
"applepy.checks.mdm.kandji",
|
||||
"applepy.catalog_cache",
|
||||
"applepy.mscp_audit_parse",
|
||||
|
||||
"applepy.checks.fs_posture",
|
||||
"applepy.checks.plan_extras",
|
||||
"applepy.checks.privesc",
|
||||
"applepy.checks.pyobjc_surface",
|
||||
"applepy.checks.listening_ports",
|
||||
"plistlib",
|
||||
"sqlite3",
|
||||
"objc",
|
||||
"Foundation",
|
||||
"AppKit",
|
||||
],
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
noarchive=False,
|
||||
)
|
||||
pyz = PYZ(a.pure)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
[],
|
||||
exclude_binaries=True,
|
||||
name="applepy",
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=False,
|
||||
console=True,
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
)
|
||||
coll = COLLECT(
|
||||
exe,
|
||||
a.binaries,
|
||||
a.datas,
|
||||
strip=False,
|
||||
upx=False,
|
||||
name="applepy",
|
||||
)
|
||||
Reference in New Issue
Block a user