(pages: list[str] | str | None = None, codesigner: CodeSign | None = None)
| 486 | |
| 487 | |
| 488 | def create_plugins(pages: list[str] | str | None = None, codesigner: CodeSign | None = None): |
| 489 | def _build_xcode_projects(xcodeproj_dirs: list[Path]): |
| 490 | xcodebuild = shutil.which("xcodebuild") |
| 491 | if not xcodebuild: |
| 492 | raise RuntimeError( |
| 493 | "Plugin directory contains an uncompiled project, but xcodebuild is not available." |
| 494 | ) |
| 495 | try: |
| 496 | subprocess.run([xcodebuild, "--help"], check=True, capture_output=True) |
| 497 | except subprocess.CalledProcessError: |
| 498 | raise RuntimeError( |
| 499 | "Plugin directory contains an uncompiled project, " |
| 500 | "but xcodebuild requires XCode to compile plugins." |
| 501 | ) |
| 502 | for xcodeproj in xcodeproj_dirs: |
| 503 | build_cmd = [ |
| 504 | xcodebuild, |
| 505 | "-project", |
| 506 | str(xcodeproj), |
| 507 | f"CONFIGURATION_BUILD_DIR={PLUGINS_DIR}", |
| 508 | # do not create dSYM debug symbols directory |
| 509 | "DEBUG_INFORMATION_FORMAT=", |
| 510 | ] |
| 511 | explained_check_call(build_cmd) |
| 512 | |
| 513 | if not pages: |
| 514 | return |
| 515 | elif isinstance(pages, str): |
| 516 | pages = [pages] |
| 517 | |
| 518 | fresh_dir(PLUGINS_DIR) |
| 519 | |
| 520 | for page in pages: |
| 521 | xcodeproj_dirs = [ |
| 522 | file.resolve() for file in Path(page).iterdir() if file.suffix == ".xcodeproj" |
| 523 | ] |
| 524 | if xcodeproj_dirs: |
| 525 | _build_xcode_projects(xcodeproj_dirs) |
| 526 | else: |
| 527 | plugin_name = os.path.basename(page) |
| 528 | page_in_plugins = join(PLUGINS_DIR, plugin_name) |
| 529 | shutil.copytree(page, page_in_plugins) |
| 530 | |
| 531 | if codesigner: |
| 532 | with NamedTemporaryFile(suffix=".plist", delete=False) as entitlements: |
| 533 | plist = { |
| 534 | "com.apple.security.cs.allow-unsigned-executable-memory": True, |
| 535 | "com.apple.security.cs.disable-library-validation": True, |
| 536 | } |
| 537 | plist_dump(plist, entitlements) |
| 538 | |
| 539 | for path in Path(PLUGINS_DIR).iterdir(): |
| 540 | codesigner.sign_bundle(path, entitlements=entitlements.name) |
| 541 | os.unlink(entitlements.name) |
| 542 | |
| 543 | plugins = [file.name for file in Path(PLUGINS_DIR).iterdir()] |
| 544 | with open(join(PLUGINS_DIR, "InstallerSections.plist"), "wb") as f: |
| 545 | plist = { |
no test coverage detected