Skip to content

Commit 5db2228

Browse files
authored
[5.9] Fix Swift SDK bundles not working due to quarantine (#6427)
Cherry-picked from 738f5f3 When using `swift experimental-sdk install` subcommand with bundle archives or bundles unpacked from archives downloaded manually in the browser, installed executables are quarantined and trigger an error message when used by `swift build` Steps To Reproduce: 1. Download a destination bundle archive 2. Unpack and install the bundle with `swift experimental-destination install` 3. Confirm that the destination is installed and note its ID with `swift experimental-destination list` 4. Build using the newly installed destination with `swift build --experimental-destination-selector <destination-id>` Actual result: Building with this destination triggers an error: "`swift-driver` cannot be opened because the developer cannot be verified." rdar://107392863
1 parent 566d0dd commit 5db2228

File tree

3 files changed

+31
-7
lines changed

3 files changed

+31
-7
lines changed

Sources/PackageModel/Destination.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ public enum DestinationError: Swift.Error {
5050
/// A destination with this artifact ID is already installed. Can't install a new bundle with this artifact,
5151
/// installed artifact IDs are expected to be unique.
5252
case destinationArtifactAlreadyInstalled(installedBundleName: String, newBundleName: String, artifactID: String)
53+
54+
#if os(macOS)
55+
/// Quarantine attribute should be removed by the `xattr` command from an installed bundle.
56+
case quarantineAttributePresent(bundlePath: AbsolutePath)
57+
#endif
5358
}
5459

5560
extension DestinationError: CustomStringConvertible {
@@ -91,6 +96,17 @@ extension DestinationError: CustomStringConvertible {
9196
`\(installedBundleName)`. Can't install a new bundle `\(newBundleName)` with this artifact, artifact IDs \
9297
are expected to be unique across all installed Swift SDK bundles.
9398
"""
99+
#if os(macOS)
100+
case .quarantineAttributePresent(let bundlePath):
101+
return """
102+
Quarantine attribute is present on a Swift SDK bundle at path `\(bundlePath)`. If you're certain that the \
103+
bundle was downloaded from a trusted source, you can remove the attribute with this command:
104+
105+
xattr -d -r -s com.apple.quarantine "\(bundlePath)"
106+
107+
and try to install this bundle again.
108+
"""
109+
#endif
94110
}
95111
}
96112
}

Sources/PackageModel/SwiftSDKBundle.swift

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212

1313
import Basics
1414

15-
import func TSCBasic.tsc_await
16-
import func TSCBasic.withTemporaryDirectory
17-
import protocol TSCBasic.FileSystem
1815
import struct Foundation.URL
1916
import struct TSCBasic.AbsolutePath
17+
import protocol TSCBasic.FileSystem
2018
import struct TSCBasic.RegEx
19+
import func TSCBasic.tsc_await
20+
import func TSCBasic.withTemporaryDirectory
2121

2222
/// Represents an `.artifactbundle` on the filesystem that contains a Swift SDK.
2323
public struct SwiftSDKBundle {
@@ -124,7 +124,7 @@ public struct SwiftSDKBundle {
124124

125125
return selectedDestination
126126
}
127-
127+
128128
/// Installs a destination bundle from a given path or URL to a destinations installation directory.
129129
/// - Parameters:
130130
/// - bundlePathOrURL: A string passed on the command line, which is either an absolute or relative to a current
@@ -249,6 +249,13 @@ public struct SwiftSDKBundle {
249249
_ archiver: some Archiver,
250250
_ observabilityScope: ObservabilityScope
251251
) throws {
252+
#if os(macOS)
253+
// Check the quarantine attribute on bundles downloaded manually in the browser.
254+
guard !fileSystem.hasAttribute(.quarantine, bundlePath) else {
255+
throw DestinationError.quarantineAttributePresent(bundlePath: bundlePath)
256+
}
257+
#endif
258+
252259
let unpackedBundlePath = try unpackIfNeeded(
253260
bundlePath: bundlePath,
254261
destinationsDirectory: destinationsDirectory,
@@ -363,7 +370,8 @@ extension ArtifactsArchiveMetadata {
363370

364371
do {
365372
let destinations = try Destination.decode(
366-
fromFile: variantConfigurationPath, fileSystem: fileSystem, observabilityScope: observabilityScope
373+
fromFile: variantConfigurationPath, fileSystem: fileSystem,
374+
observabilityScope: observabilityScope
367375
)
368376

369377
variants.append(.init(metadata: variantMetadata, swiftSDKs: destinations))
@@ -382,7 +390,7 @@ extension ArtifactsArchiveMetadata {
382390
}
383391
}
384392

385-
extension Array where Element == SwiftSDKBundle {
393+
extension [SwiftSDKBundle] {
386394
/// Select a destination with a given artifact ID from a `self` array of available destinations.
387395
/// - Parameters:
388396
/// - id: artifact ID of the destination to look up.

Tests/PackageModelTests/SwiftSDKBundleTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ final class SwiftSDKBundleTests: XCTestCase {
7070
let invalidPath = "foobar"
7171
do {
7272
try SwiftSDKBundle.install(
73-
bundlePathOrURL: "foobar",
73+
bundlePathOrURL: invalidPath,
7474
destinationsDirectory: destinationsDirectory,
7575
fileSystem,
7676
archiver,

0 commit comments

Comments
 (0)