Skip to content

Commit 838ed31

Browse files
committed
chore: allow local builds/packs to use local spm
Keeps the release builds using the tagged ios-spm remote artifacts while allowing local development as well. [skip ci]
1 parent 268178c commit 838ed31

2 files changed

Lines changed: 111 additions & 0 deletions

File tree

build_npm_ios.sh

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,45 @@ node ./scripts/stamp-template-version.mjs \
2020
"$OUTPUT_DIR/framework/__PROJECT_NAME__.xcodeproj/project.pbxproj" \
2121
"$NPM_VERSION"
2222

23+
# Local builds have no ios-spm release tag to resolve, so by default (outside
24+
# CI) rewrite the template to a LOCAL SwiftPM package over the xcframeworks
25+
# just built into dist/. Force with NS_SPM_LOCAL=1, disable with NS_SPM_LOCAL=0.
26+
# The resulting .tgz embeds an absolute path into this checkout — local
27+
# `ns platform add ios --framework-path=dist/nativescript-ios-*.tgz` use only.
28+
if [[ "${NS_SPM_LOCAL:-}" == "1" || ( -z "${CI:-}" && "${NS_SPM_LOCAL:-}" != "0" ) ]]; then
29+
LOCAL_SPM_DIR="$(pwd)/dist/local-spm"
30+
rm -rf "$LOCAL_SPM_DIR"
31+
mkdir -p "$LOCAL_SPM_DIR"
32+
cp -R "dist/NativeScript.xcframework" "$LOCAL_SPM_DIR/"
33+
cp -R "dist/TKLiveSync.xcframework" "$LOCAL_SPM_DIR/"
34+
cat > "$LOCAL_SPM_DIR/Package.swift" <<'EOF'
35+
// swift-tools-version: 5.10
36+
// Local dev override of github.com/NativeScript/ios-spm: same product shape,
37+
// but binaryTargets point at the freshly built xcframeworks in this folder.
38+
import PackageDescription
39+
40+
let package = Package(
41+
name: "NativeScriptSDK",
42+
platforms: [
43+
.iOS(.v13),
44+
.macCatalyst(.v13),
45+
],
46+
products: [
47+
.library(name: "NativeScript", targets: ["NativeScript", "TKLiveSync"]),
48+
.library(name: "NativeScriptSDK", targets: ["NativeScript", "TKLiveSync"]),
49+
],
50+
dependencies: [],
51+
targets: [
52+
.binaryTarget(name: "NativeScript", path: "NativeScript.xcframework"),
53+
.binaryTarget(name: "TKLiveSync", path: "TKLiveSync.xcframework"),
54+
]
55+
)
56+
EOF
57+
node ./scripts/stamp-template-local-spm.mjs \
58+
"$OUTPUT_DIR/framework/__PROJECT_NAME__.xcodeproj/project.pbxproj" \
59+
"$LOCAL_SPM_DIR"
60+
fi
61+
2362
# Build-time metadata generator is still shipped in npm (Phase 1). See the
2463
# distribution plan for moving this to an on-demand artifact (Phase 2).
2564
mkdir -p "$OUTPUT_DIR/framework/internal/metadata-generator-x86_64"
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#!/usr/bin/env node
2+
// Stamp a packaged project template to consume the runtime via a LOCAL SwiftPM
3+
// package instead of the released ios-spm tag (the D6 "dev/offline override"
4+
// from SPM_DISTRIBUTION_PLAN.md).
5+
//
6+
// Local `npm run build-ios` produces xcframeworks in dist/ but no ios-spm
7+
// release tag, so the template's XCRemoteSwiftPackageReference (exactVersion
8+
// pinned by stamp-template-version.mjs) can never resolve. This script rewrites
9+
// that reference into an XCLocalSwiftPackageReference pointing at the local-spm
10+
// package the build just created (dist/local-spm — Package.swift + binary
11+
// targets over the built xcframeworks).
12+
//
13+
// The resulting npm package is machine-specific (it embeds an absolute path
14+
// into this checkout) and is only meant for `ns platform add ios
15+
// --framework-path=dist/nativescript-ios-<version>.tgz` style local testing.
16+
//
17+
// Usage: node scripts/stamp-template-local-spm.mjs <project.pbxproj> <abs-path-to-local-spm>
18+
import fs from "node:fs";
19+
import path from "node:path";
20+
21+
const [, , pbxPath, localSpmPath] = process.argv;
22+
23+
if (!pbxPath || !localSpmPath) {
24+
console.error("Usage: stamp-template-local-spm.mjs <project.pbxproj> <abs-path-to-local-spm>");
25+
process.exit(1);
26+
}
27+
28+
if (!path.isAbsolute(localSpmPath)) {
29+
console.error(`local-spm path must be absolute, got: ${localSpmPath}`);
30+
process.exit(1);
31+
}
32+
33+
if (!fs.existsSync(path.join(localSpmPath, "Package.swift"))) {
34+
console.error(`No Package.swift found in ${localSpmPath} — run the runtime build first.`);
35+
process.exit(1);
36+
}
37+
38+
let contents = fs.readFileSync(pbxPath, "utf8");
39+
40+
const REMOTE_REF_RE =
41+
/\/\* Begin XCRemoteSwiftPackageReference section \*\/[\s\S]*?\/\* End XCRemoteSwiftPackageReference section \*\//;
42+
43+
if (!REMOTE_REF_RE.test(contents)) {
44+
console.error(`No XCRemoteSwiftPackageReference section found in ${pbxPath} (already stamped local?).`);
45+
process.exit(1);
46+
}
47+
48+
// The template uses a fixed UUID for the package reference; keep it so the
49+
// packageReferences list and product dependency keep resolving.
50+
const refUuidMatch = contents.match(/([0-9A-F]{24}) \/\* XCRemoteSwiftPackageReference "ios-spm" \*\//);
51+
if (!refUuidMatch) {
52+
console.error(`Could not find the "ios-spm" package reference UUID in ${pbxPath}.`);
53+
process.exit(1);
54+
}
55+
const refUuid = refUuidMatch[1];
56+
57+
contents = contents.replace(
58+
REMOTE_REF_RE,
59+
`/* Begin XCLocalSwiftPackageReference section */
60+
\t\t${refUuid} /* XCLocalSwiftPackageReference "local-spm" */ = {
61+
\t\t\tisa = XCLocalSwiftPackageReference;
62+
\t\t\trelativePath = ${JSON.stringify(localSpmPath)};
63+
\t\t};
64+
/* End XCLocalSwiftPackageReference section */`
65+
);
66+
67+
// Update the comment annotations everywhere the reference UUID appears
68+
// (packageReferences list + XCSwiftPackageProductDependency).
69+
contents = contents.split(`${refUuid} /* XCRemoteSwiftPackageReference "ios-spm" */`).join(`${refUuid} /* XCLocalSwiftPackageReference "local-spm" */`);
70+
71+
fs.writeFileSync(pbxPath, contents);
72+
console.log(`Stamped ${pbxPath} → local SwiftPM package at ${localSpmPath}`);

0 commit comments

Comments
 (0)