158 lines
5.7 KiB
JavaScript
158 lines
5.7 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Post-prebuild script: adds SentrySPM Swift Package to the watch target.
|
|
*
|
|
* Run after `expo prebuild`:
|
|
* node scripts/add-sentry-watch.js
|
|
*/
|
|
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
|
|
const SENTRY_REPO_URL = "https://github.com/getsentry/sentry-cocoa.git";
|
|
const SENTRY_MIN_VERSION = "9.25.0";
|
|
const SENTRY_PRODUCT = "Sentry";
|
|
|
|
function genUuid() {
|
|
const hex = "0123456789ABCDEF";
|
|
let id = "";
|
|
for (let i = 0; i < 24; i++) id += hex[Math.floor(Math.random() * 16)];
|
|
return id;
|
|
}
|
|
|
|
const projectRoot = path.resolve(__dirname, "..");
|
|
const pbxprojPath = path.join(
|
|
projectRoot,
|
|
"ios",
|
|
"SwimBuddy.xcodeproj",
|
|
"project.pbxproj"
|
|
);
|
|
|
|
if (!fs.existsSync(pbxprojPath)) {
|
|
console.error("project.pbxproj not found. Run expo prebuild first.");
|
|
process.exit(1);
|
|
}
|
|
|
|
let content = fs.readFileSync(pbxprojPath, "utf-8");
|
|
|
|
// Already added?
|
|
if (content.includes(SENTRY_REPO_URL)) {
|
|
console.log("SentrySPM already present.");
|
|
process.exit(0);
|
|
}
|
|
|
|
// ── Find watch target UUID ──
|
|
const watchTargetMatch = content.match(
|
|
/(\w{24})\s*\/\* SwimBuddy Watch \*\/\s*=\s*\{\s*\n\s*isa = PBXNativeTarget;\s*\n\s*buildConfigurationList = \w+ /
|
|
);
|
|
if (!watchTargetMatch) {
|
|
console.error("Watch target not found");
|
|
process.exit(1);
|
|
}
|
|
const watchTargetUuid = watchTargetMatch[1];
|
|
console.log(`Watch target: ${watchTargetUuid}`);
|
|
|
|
// ── Find watch target's Frameworks build phase UUID ──
|
|
const watchTargetBlock = content.match(
|
|
new RegExp(
|
|
`${watchTargetUuid}\\s*\\/\\* SwimBuddy Watch \\*\\/\\s*=\\s*\\{[\\s\\S]*?buildPhases\\s*=\\s*\\(([\\s\\S]*?)\\);`
|
|
)
|
|
);
|
|
if (!watchTargetBlock) {
|
|
console.error("Cannot parse watch target buildPhases");
|
|
process.exit(1);
|
|
}
|
|
const fwPhaseMatch = watchTargetBlock[1].match(/(\w{24})\s*\/\* Frameworks \*\//);
|
|
if (!fwPhaseMatch) {
|
|
console.error("Watch Frameworks phase not found");
|
|
process.exit(1);
|
|
}
|
|
const watchFwPhaseId = fwPhaseMatch[1];
|
|
console.log(`Watch Frameworks phase: ${watchFwPhaseId}`);
|
|
|
|
// ── Generate UUIDs ──
|
|
const pkgRefId = genUuid();
|
|
const prodDepId = genUuid();
|
|
const buildFileId = genUuid();
|
|
|
|
// ── 1. PBXBuildFile (single-line format) ──
|
|
const buildFileLine = `\t\t${buildFileId} /* ${SENTRY_PRODUCT} in Frameworks */ = {isa = PBXBuildFile; productRef = ${prodDepId} /* ${SENTRY_PRODUCT} */; };`;
|
|
content = content.replace(
|
|
/\/\* End PBXBuildFile section \*\//,
|
|
`${buildFileLine}\n/* End PBXBuildFile section */`
|
|
);
|
|
|
|
// ── 2. XCRemoteSwiftPackageReference section ──
|
|
const pkgRefLine = `\t\t${pkgRefId} /* XCRemoteSwiftPackageReference "sentry-cocoa" */ = {isa = XCRemoteSwiftPackageReference; repositoryURL = "${SENTRY_REPO_URL}"; requirement = {kind = "upToNextMajorVersion"; minimumVersion = "${SENTRY_MIN_VERSION}"; }; };`;
|
|
|
|
if (!content.includes("/* Begin XCRemoteSwiftPackageReference section */")) {
|
|
content = content.replace(
|
|
/\/\* End PBXProject section \*\//,
|
|
`/* Begin XCRemoteSwiftPackageReference section */\n${pkgRefLine}\n/* End XCRemoteSwiftPackageReference section */\n/* End PBXProject section */`
|
|
);
|
|
} else {
|
|
content = content.replace(
|
|
/\/\* End XCRemoteSwiftPackageReference section \*\//,
|
|
`${pkgRefLine}\n/* End XCRemoteSwiftPackageReference section */`
|
|
);
|
|
}
|
|
|
|
// ── 3. XCSwiftPackageProductDependency section ──
|
|
const prodDepLine = `\t\t${prodDepId} /* ${SENTRY_PRODUCT} */ = {isa = XCSwiftPackageProductDependency; package = ${pkgRefId} /* XCRemoteSwiftPackageReference "sentry-cocoa" */; productName = ${SENTRY_PRODUCT}; };`;
|
|
|
|
if (!content.includes("/* Begin XCSwiftPackageProductDependency section */")) {
|
|
content = content.replace(
|
|
/\/\* End XCRemoteSwiftPackageReference section \*\//,
|
|
`/* Begin XCSwiftPackageProductDependency section */\n${prodDepLine}\n/* End XCSwiftPackageProductDependency section */\n/* End XCRemoteSwiftPackageReference section */`
|
|
);
|
|
} else {
|
|
content = content.replace(
|
|
/\/\* End XCSwiftPackageProductDependency section \*\//,
|
|
`${prodDepLine}\n/* End XCSwiftPackageProductDependency section */`
|
|
);
|
|
}
|
|
|
|
// ── 4. Add to watch Frameworks build phase ──
|
|
const fwPhasePattern = new RegExp(
|
|
`(${watchFwPhaseId}\\s*\\/\\* Frameworks \\*\\/ = \\{[\\s\\S]*?files = \\()[\\s\\S]*?(\\);[\\s\\S]*?runOnlyForDeploymentPostprocessing)`
|
|
);
|
|
const fwMatch = content.match(fwPhasePattern);
|
|
if (fwMatch) {
|
|
const insertLine = `\n\t\t\t\t${buildFileId} /* ${SENTRY_PRODUCT} in Frameworks */,`;
|
|
content = content.replace(fwPhasePattern, `$1${fwMatch[0].includes(buildFileId) ? "" : insertLine}$2`);
|
|
} else {
|
|
console.error("Cannot insert into watch Frameworks build phase");
|
|
process.exit(1);
|
|
}
|
|
|
|
// ── 5. packageReferences in PBXProject ──
|
|
const pkgRefComment = `${pkgRefId} /* XCRemoteSwiftPackageReference "sentry-cocoa" */`;
|
|
if (!content.includes("packageReferences = (")) {
|
|
content = content.replace(
|
|
/(targets\s*=\s*\([^)]*\);)/,
|
|
`$1\n\t\t\tpackageReferences = (\n\t\t\t\t${pkgRefComment},\n\t\t\t);`
|
|
);
|
|
} else {
|
|
content = content.replace(
|
|
/(packageReferences\s*=\s*\()/,
|
|
`$1\n\t\t\t\t${pkgRefComment},`
|
|
);
|
|
}
|
|
|
|
// ── 6. packageProductDependencies on watch target ──
|
|
const prodDepComment = `${prodDepId} /* ${SENTRY_PRODUCT} */`;
|
|
// Find the watch target block and check if packageProductDependencies exists
|
|
const wtPattern = new RegExp(
|
|
`(${watchTargetUuid}\\s*\\/\\* SwimBuddy Watch \\*\\/ = \\{[\\s\\S]*?fileSystemSynchronizedGroups = \\([\\s\\S]*?\\);[\\s\\S]*?)(name = )`
|
|
);
|
|
const wtMatch = content.match(wtPattern);
|
|
if (wtMatch && !content.includes("packageProductDependencies")) {
|
|
content = content.replace(
|
|
wtPattern,
|
|
`$1\n\t\t\tpackageProductDependencies = (\n\t\t\t\t${prodDepComment},\n\t\t\t);\n\t\t$2`
|
|
);
|
|
}
|
|
|
|
fs.writeFileSync(pbxprojPath, content);
|
|
console.log("SentrySPM added to watch target successfully.");
|