Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
- Rename the bundled Sentry Cocoa cinterop package prefix from `cocoapods` to `cocoa` ([#557](https://github.com/getsentry/sentry-kotlin-multiplatform/pull/557))
- If you imported `cocoapods.Sentry.*` directly in Apple source sets, replace it with `cocoa.Sentry.*`. Code using public SDK types such as `SentryPlatformOptions` is unaffected.

### Features

- Auto-install Sentry Cocoa for Apple targets when the spm4Kmp plugin (`io.github.frankois944.spmForKmp`) is applied ([#559](https://github.com/getsentry/sentry-kotlin-multiplatform/pull/559))

### Internal

- Build the Apple SDK against Sentry Cocoa via SwiftPM (spm4Kmp) instead of the Kotlin CocoaPods plugin ([#557](https://github.com/getsentry/sentry-kotlin-multiplatform/pull/557))
Expand Down
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,43 @@ Use the Kotlin Multiplatform and Cocoa SDK combinations listed in the table belo

For detailed usage, check out the [Kotlin Multiplatform Documentation](https://docs.sentry.io/platforms/kotlin-multiplatform/).

### Apple linking via spm4Kmp (Gradle plugin)

If you apply the [spm4Kmp](https://github.com/frankois944/spm4Kmp) plugin (`io.github.frankois944.spmForKmp`)
alongside the Sentry Kotlin Multiplatform Gradle plugin, the matching Sentry Cocoa version is added to
your Apple targets automatically — you don't need to declare the Sentry Swift package yourself:

```kotlin
plugins {
kotlin("multiplatform")
id("io.github.frankois944.spmForKmp")
id("io.sentry.kotlin.multiplatform.gradle")
}
```

You can override the version or opt out (for example if you configure the Sentry Swift package
manually):

```kotlin
sentryKmp {
autoInstall {
spm {
// enabled = false // opt out of the automatic Sentry Cocoa Swift package
// sentryCocoaVersion = "8.58.2" // override the default version
}
}
}
Comment thread
buenaflor marked this conversation as resolved.
```

> [!NOTE]
> The Sentry Swift package is registered as soon as the Apple targets are created, so place the
> `sentryKmp { }` block **before** the `kotlin { }` block — otherwise the opt-out (including the
> global `autoInstall.enabled` flag) and version override have no effect.

Consumers that don't use spm4Kmp keep the existing behavior: the CocoaPods auto-install (when the
Kotlin CocoaPods plugin is applied) or the `linker { frameworkPath / xcodeprojPath }` fallback for
plain SPM-in-Xcode setups.

## Samples

For detailed information on how to build and run the samples, check out our `README.md` in the
Expand Down
23 changes: 2 additions & 21 deletions scripts/update-cocoa.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,12 @@ cd $(dirname "$0")/../

config_file='buildSrc/src/main/java/Config.kt'
plugin_properties_file='sentry-kotlin-multiplatform-gradle-plugin/gradle.properties'
spm_sample_pbxproj_file='sentry-samples/kmp-app-spm/iosApp.xcodeproj/project.pbxproj'
spm_sample_project='sentry-samples/kmp-app-spm/iosApp.xcodeproj'
spm_sample_scheme='iosApp'

config_content=$(cat $config_file)
plugin_properties_content=$(cat $plugin_properties_file)
pbxproj_content=$(cat $spm_sample_pbxproj_file)

config_regex='(sentryCocoaVersion *= *)"([0-9\.]+)"'
plugin_properties_regex='(sentryCocoaVersion *= *)([0-9\.]+)'
# Matches the sentry-cocoa SwiftPM pin in the SPM sample, e.g. `version = 8.58.2;`
pbxproj_regex='(version = )([0-9\.]+)(;)'

if ! [[ $config_content =~ $config_regex ]]; then
echo "Failed to find the Cocoa version in $config_file"
Expand All @@ -34,13 +28,6 @@ fi
plugin_properties_whole_match=${BASH_REMATCH[0]}
plugin_properties_var_name=${BASH_REMATCH[1]}

if ! [[ $pbxproj_content =~ $pbxproj_regex ]]; then
echo "Failed to find the sentry-cocoa SwiftPM version in $spm_sample_pbxproj_file"
exit 1
fi

pbxproj_whole_match=${BASH_REMATCH[0]}

case $1 in
get-version)
# We only require to return the version number of one of the files
Expand All @@ -58,14 +45,8 @@ set-version)
newValue="${plugin_properties_var_name}$2"
echo "${plugin_properties_content/${plugin_properties_whole_match}/$newValue}" >$plugin_properties_file

# Update the sentry-cocoa SwiftPM pin in the SPM sample Xcode project
newValue="version = $2;"
echo "${pbxproj_content/${pbxproj_whole_match}/$newValue}" >$spm_sample_pbxproj_file

# Refresh the SPM sample lockfiles (Package.resolved) so the pinned revision
# matches the new version.
echo "Resolving SwiftPM dependencies for the SPM sample..."
xcodebuild -resolvePackageDependencies -project $spm_sample_project -scheme $spm_sample_scheme
# The SPM sample needs no update: it gets Sentry Cocoa through the Gradle plugin's
# spm4Kmp auto-install, which is versioned from the two files above.
;;
*)
echo "Unknown argument $1"
Expand Down
21 changes: 21 additions & 0 deletions sentry-kotlin-multiplatform-gradle-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import io.gitlab.arturbosch.detekt.Detekt
import org.gradle.api.attributes.java.TargetJvmVersion
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

Expand All @@ -20,8 +21,13 @@ dependencies {
compileOnly(kotlin("stdlib"))
compileOnly(gradleApi())
compileOnly(kotlin("gradle-plugin"))
// Compile against the spm4Kmp DSL so we can auto-configure the Sentry Cocoa Swift
// package when a consumer applies the spm4Kmp plugin. compileOnly: only used when
// the consumer also brings the plugin onto the classpath.
compileOnly(libs.spmForKmp)

testImplementation(kotlin("gradle-plugin"))
testImplementation(libs.spmForKmp)
testImplementation(libs.junit)
testImplementation(libs.junit.params)
testImplementation(libs.mockk)
Expand All @@ -37,6 +43,21 @@ java {
targetCompatibility = JavaVersion.VERSION_11
}

// spm4Kmp's implementation artifact is published for Java 17. It is only a compileOnly dependency
// (used solely when a consumer also applies the spm4Kmp plugin, which itself requires JDK 17), so we
// request Java 17-compatible variants on the compile/test classpaths while still producing Java 11
// bytecode. This keeps the published plugin runnable on JDK 11 for consumers that don't use spm4Kmp.
listOf("compileClasspath", "testCompileClasspath", "testRuntimeClasspath").forEach { configurationName ->
configurations.named(configurationName).configure {
attributes {
attribute(
TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE,
JavaVersion.VERSION_17.majorVersion.toInt()
)
}
}
}

tasks.withType<KotlinCompile>().configureEach { compilerOptions { jvmTarget.set(JvmTarget.JVM_11) } }

gradlePlugin {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pluginPublish = "1.3.1"
buildConfig = "5.5.1"
vanniktechPublish = "0.30.0"
kover = "0.9.1"
spmForKmp = "1.9.3"

[plugins]
detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt"}
Expand All @@ -19,3 +20,4 @@ junit = "org.junit.jupiter:junit-jupiter-api:5.10.3"
junit-params = "org.junit.jupiter:junit-jupiter-params:5.10.3"
mockk = "io.mockk:mockk:1.13.12"
truth = { module = "com.google.truth:truth", version = "1.4.4" }
spmForKmp = { module = "io.github.frankois944.spmForKmp:io.github.frankois944.spmForKmp.gradle.plugin", version.ref = "spmForKmp" }
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ dependencyResolutionManagement {
repositories {
google()
mavenCentral()
// Hosts the spm4Kmp plugin marker + implementation (compiled against for spm4Kmp auto-install)
gradlePluginPortal()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,25 @@ abstract class AutoInstallExtension @Inject constructor(project: Project) {
private val objects = project.objects

/**
* Enable auto-installation of the Sentry dependencies through [CocoapodsAutoInstallExtension]
* and [SourceSetAutoInstallExtension].
* Enable auto-installation of the Sentry dependencies through [CocoapodsAutoInstallExtension],
* [Spm4KmpAutoInstallExtension] and [SourceSetAutoInstallExtension].
*
* Disabling this will prevent the plugin from auto installing any dependency.
*
* The spm4Kmp auto-install registers the Sentry Swift package as soon as each Apple target is
* created, so to disable it this flag must be set before the `kotlin { }` block declares the
* Apple targets — setting it afterwards only disables the CocoaPods and commonMain installs.
*
* Defaults to true.
*/
val enabled: Property<Boolean> = objects.property(Boolean::class.java).convention(true)

val cocoapods: CocoapodsAutoInstallExtension =
objects.newInstance(CocoapodsAutoInstallExtension::class.java, project)

val spm: Spm4KmpAutoInstallExtension =
objects.newInstance(Spm4KmpAutoInstallExtension::class.java, project)

val commonMain: SourceSetAutoInstallExtension =
objects.newInstance(SourceSetAutoInstallExtension::class.java, project)
}
Loading
Loading