Skip to content

Commit 07499e4

Browse files
authored
build(shared-core): resolve a local XCFramework when FLIPCASH_SHARED_CORE_LOCAL is set (#1389)
Android compiles :kmp:shared-core from source, so a Kotlin change shows up in the next Android build. iOS consumes it as a published XCFramework pinned by version, so the same change needed the publish workflow, a moved tag, and a bumped pin before it could be tried at all. That cost is about to be paid per iteration: the derivation and bonding-curve moves are far more iterative than the beachhead was. The switch goes in the package manifest rather than in the app, because the app reaches SharedCoreKit twice — FlipcashUI depends on it, and Code.xcodeproj carries its own remote package reference for the app target's direct import. Overriding one leaves the other on the published package and resolution fails on duplicate SharedCore/SharedCoreKit targets. The publish job copies this manifest verbatim into the SPM repo, so the tagged copy the app resolves carries the same conditional and both consumers follow it. The path is rewritten relative to the package root because SwiftPM rejects an absolute binary-target path, and the published manifest is checked out into DerivedData with no Kotlin next to it. Loop and verification: docs/shared-core-local-development.md in the orchestrator.
1 parent a435a13 commit 07499e4

2 files changed

Lines changed: 45 additions & 5 deletions

File tree

‎kmp/shared-core/spm/.gitignore‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Left behind by `swift package` / `xcodebuild` runs against this package.
2+
.build/
3+
.swiftpm/

‎kmp/shared-core/spm/Package.swift‎

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// swift-tools-version:5.9
22
import PackageDescription
3+
import Foundation
34

45
// The publish job rewrites this block — everything else in this file is ours. Note the
56
// tags are load-bearing: KMMBridge looks for them verbatim and fails the publish if
@@ -10,6 +11,46 @@ let remoteKotlinChecksum = "b86241d770fa186e44eec4c9ff0ff092d54cf66329828485d243
1011
let packageName = "SharedCore"
1112
// END KMMBRIDGE BLOCK
1213

14+
// FLIPCASH_SHARED_CORE_LOCAL points at a code-android-app checkout and swaps the published
15+
// XCFramework for one assembled from that checkout's Kotlin, so a Kotlin change can be tried
16+
// from an iOS build without cutting a release and moving a tag:
17+
//
18+
// ./gradlew :kmp:shared-core:assembleSharedCoreReleaseXCFramework
19+
//
20+
// This manifest is what gets published, so the override also works from the tagged copy the
21+
// iOS app resolves — nothing on the iOS side has to change. That copy sits in DerivedData, and
22+
// SwiftPM only accepts a binary target path relative to the package root, so the absolute path
23+
// the variable gives us is rewritten as a relative one from wherever the manifest was checked
24+
// out to.
25+
//
26+
// The publish workflow never sets the variable, so CI always resolves the binary target
27+
// through the URL and checksum above.
28+
func relativePath(from base: String, to target: String) -> String {
29+
let from = (base as NSString).resolvingSymlinksInPath.split(separator: "/").map(String.init)
30+
let to = (target as NSString).resolvingSymlinksInPath.split(separator: "/").map(String.init)
31+
var shared = 0
32+
while shared < from.count, shared < to.count, from[shared] == to[shared] { shared += 1 }
33+
return (Array(repeating: "..", count: from.count - shared) + to[shared...]).joined(separator: "/")
34+
}
35+
36+
let sharedCoreLocalRoot = ProcessInfo.processInfo.environment["FLIPCASH_SHARED_CORE_LOCAL"]
37+
.map { ($0 as NSString).expandingTildeInPath }
38+
.flatMap { $0.isEmpty ? nil : $0 }
39+
40+
let binaryTarget: Target = sharedCoreLocalRoot.map {
41+
.binaryTarget(
42+
name: packageName,
43+
path: relativePath(
44+
from: Context.packageDirectory,
45+
to: "\($0)/kmp/shared-core/build/XCFrameworks/release/\(packageName).xcframework"
46+
)
47+
)
48+
} ?? .binaryTarget(
49+
name: packageName,
50+
url: remoteKotlinUrl,
51+
checksum: remoteKotlinChecksum
52+
)
53+
1354
let package = Package(
1455
name: packageName,
1556
platforms: [
@@ -25,11 +66,7 @@ let package = Package(
2566
),
2667
],
2768
targets: [
28-
.binaryTarget(
29-
name: packageName,
30-
url: remoteKotlinUrl,
31-
checksum: remoteKotlinChecksum
32-
),
69+
binaryTarget,
3370
.target(
3471
name: "SharedCoreKit",
3572
dependencies: [.target(name: packageName)]

0 commit comments

Comments
 (0)