141 lines
5.0 KiB
JavaScript
141 lines
5.0 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* One-shot Fix: fügt die fehlende "Embed App Extensions" Build-Phase ins
|
|
* existierende Xcode-Projekt ein, ohne den ganzen Prebuild zu wiederholen.
|
|
*
|
|
* Wird auch in `with-rebreak-protection-ios.js` als Logik referenziert,
|
|
* damit zukünftige Prebuilds das richtig hinkriegen.
|
|
*
|
|
* Usage: node scripts/fix-embed-extension.js
|
|
*/
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const xcode = require('xcode');
|
|
|
|
const PROJECT_ROOT = path.resolve(__dirname, '..');
|
|
const PBXPROJ = path.join(PROJECT_ROOT, 'ios', 'Rebreak.xcodeproj', 'project.pbxproj');
|
|
const TARGET_NAME = 'RebreakURLFilter';
|
|
|
|
if (!fs.existsSync(PBXPROJ)) {
|
|
console.error('❌ pbxproj not found at:', PBXPROJ);
|
|
process.exit(1);
|
|
}
|
|
|
|
const project = xcode.project(PBXPROJ);
|
|
project.parseSync();
|
|
|
|
// 1) Find Main + Extension targets
|
|
const mainTarget = project.getFirstTarget();
|
|
if (!mainTarget) {
|
|
console.error('❌ no main target found');
|
|
process.exit(1);
|
|
}
|
|
const mainTargetUuid = mainTarget.uuid;
|
|
const extTargetUuid = project.findTargetKey(TARGET_NAME);
|
|
if (!extTargetUuid) {
|
|
console.error(`❌ Extension target "${TARGET_NAME}" not found`);
|
|
process.exit(1);
|
|
}
|
|
|
|
console.log(`✓ Main target: ${mainTarget.firstTarget.name} (${mainTargetUuid})`);
|
|
console.log(`✓ Extension target: ${TARGET_NAME} (${extTargetUuid})`);
|
|
|
|
// 2) Check existing Embed phase
|
|
const buildPhases = project.hash.project.objects.PBXNativeTarget[mainTargetUuid].buildPhases || [];
|
|
const copyFilesPhases = project.hash.project.objects.PBXCopyFilesBuildPhase || {};
|
|
|
|
let hasEmbedPhase = false;
|
|
for (const key of Object.keys(copyFilesPhases)) {
|
|
const phase = copyFilesPhases[key];
|
|
if (typeof phase !== 'object') continue;
|
|
if (!buildPhases.some((bp) => bp.value === key)) continue;
|
|
// dstSubfolderSpec kann String '13' oder Number 13 sein — beide checken
|
|
if (phase.dstSubfolderSpec === 13 || phase.dstSubfolderSpec === '13') {
|
|
hasEmbedPhase = true;
|
|
console.log(`✓ Embed phase already exists: ${key}`);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (hasEmbedPhase) {
|
|
console.log('✓ Already has Embed App Extensions phase');
|
|
} else {
|
|
console.log('→ Adding Embed App Extensions phase to main target...');
|
|
const newPhase = project.addBuildPhase(
|
|
[`${TARGET_NAME}.appex`],
|
|
'PBXCopyFilesBuildPhase',
|
|
'Embed App Extensions',
|
|
mainTargetUuid,
|
|
'app_extension',
|
|
);
|
|
const phaseObj = project.hash.project.objects.PBXCopyFilesBuildPhase[newPhase.uuid];
|
|
if (phaseObj && phaseObj.dstSubfolderSpec !== 13 && phaseObj.dstSubfolderSpec !== '13') {
|
|
phaseObj.dstSubfolderSpec = 13;
|
|
phaseObj.dstPath = '';
|
|
}
|
|
}
|
|
|
|
// Target-Dependency: Main → Extension (zwingt Build-Order)
|
|
console.log('→ Ensuring target dependency (Main → Extension)...');
|
|
const mainObj = project.hash.project.objects.PBXNativeTarget[mainTargetUuid];
|
|
const existingDeps = mainObj.dependencies || [];
|
|
const dependencyTargets = project.hash.project.objects.PBXTargetDependency || {};
|
|
const hasDepToExt = existingDeps.some((dep) => {
|
|
const depObj = dependencyTargets[dep.value];
|
|
return depObj && depObj.target === extTargetUuid;
|
|
});
|
|
if (!hasDepToExt) {
|
|
project.addTargetDependency(mainTargetUuid, [extTargetUuid]);
|
|
console.log('✓ Target dependency added');
|
|
} else {
|
|
console.log('✓ Target dependency already exists');
|
|
}
|
|
|
|
// Save & exit (von hier — die ursprüngliche save-Logik unten wurde durch dieses Block ersetzt)
|
|
fs.writeFileSync(PBXPROJ, project.writeSync());
|
|
console.log('✅ Saved pbxproj');
|
|
console.log('Now: in Xcode → Cmd+Shift+K (clean) → Cmd+B (build)');
|
|
process.exit(0);
|
|
|
|
// 3) Add Embed phase
|
|
console.log('→ Adding Embed App Extensions phase to main target...');
|
|
const newPhase = project.addBuildPhase(
|
|
[`${TARGET_NAME}.appex`],
|
|
'PBXCopyFilesBuildPhase',
|
|
'Embed App Extensions',
|
|
mainTargetUuid,
|
|
'app_extension',
|
|
);
|
|
console.log(`✓ New phase UUID: ${newPhase.uuid}`);
|
|
|
|
// 4) Verify dstSubfolderSpec was set correctly
|
|
const phaseObj = project.hash.project.objects.PBXCopyFilesBuildPhase[newPhase.uuid];
|
|
if (phaseObj && phaseObj.dstSubfolderSpec !== 13 && phaseObj.dstSubfolderSpec !== '13') {
|
|
console.log(
|
|
`⚠️ dstSubfolderSpec was ${phaseObj.dstSubfolderSpec}, forcing to 13`,
|
|
);
|
|
phaseObj.dstSubfolderSpec = 13;
|
|
phaseObj.dstPath = '';
|
|
}
|
|
|
|
// 5) Add target dependency: Main → Extension
|
|
// Sorgt dafür dass Xcode die Extension VOR der Main-App baut.
|
|
console.log('→ Adding target dependency: Main → Extension...');
|
|
try {
|
|
project.addTargetDependency(mainTargetUuid, [extTargetUuid]);
|
|
console.log('✓ Target dependency added');
|
|
} catch (e) {
|
|
console.log('⚠️ Target dependency might already exist:', e.message);
|
|
}
|
|
|
|
// 6) Add Extension's appex to the main app's Frameworks/PBXFileReference linkage
|
|
// so Xcode knows where to find it during embedding.
|
|
// (xcode npm package's addBuildPhase handles file references automatically
|
|
// if the .appex was registered via addTarget — sollte schon da sein.)
|
|
|
|
// 7) Save
|
|
fs.writeFileSync(PBXPROJ, project.writeSync());
|
|
console.log('✅ Saved pbxproj');
|
|
console.log('');
|
|
console.log('Now rebuild in Xcode (Cmd+B). The .appex should be embedded into Rebreak.app/PlugIns/');
|