Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Swift SDK bundles not working due to quarantine #6426

Merged
merged 10 commits into from
May 11, 2023
5 changes: 3 additions & 2 deletions Sources/Basics/FileSystem/FileSystem+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import struct TSCBasic.ByteString
import struct TSCBasic.FileInfo
import class TSCBasic.FileLock
import enum TSCBasic.FileMode
import enum TSCBasic.FileSystemAttribute
import protocol TSCBasic.FileSystem
import var TSCBasic.localFileSystem
import protocol TSCBasic.WritableByteStream
Expand Down Expand Up @@ -71,8 +72,8 @@ extension FileSystem {

/// Returns `true` if a given path has a quarantine attribute applied if when file system supports this attribute.
/// Returns `false` if such attribute is not applied or it isn't supported.
public func hasQuarantineAttribute(_ path: AbsolutePath) -> Bool {
self.hasQuarantineAttribute(path.underlying)
public func hasAttribute(_ name: FileSystemAttribute, _ path: AbsolutePath) -> Bool {
self.hasAttribute(name, path.underlying)
}

/// Get the contents of the given directory, in an undefined order.
Expand Down
16 changes: 16 additions & 0 deletions Sources/PackageModel/Destination.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ public enum DestinationError: Swift.Error {
/// A destination with this artifact ID is already installed. Can't install a new bundle with this artifact,
/// installed artifact IDs are expected to be unique.
case destinationArtifactAlreadyInstalled(installedBundleName: String, newBundleName: String, artifactID: String)

#if os(macOS)
/// Quarantine attribute should be removed by the `xattr` command from an installed bundle.
case quarantineAttributePresent(bundlePath: AbsolutePath)
#endif
}

extension DestinationError: CustomStringConvertible {
Expand Down Expand Up @@ -93,6 +98,17 @@ extension DestinationError: CustomStringConvertible {
`\(installedBundleName)`. Can't install a new bundle `\(newBundleName)` with this artifact, artifact IDs \
are expected to be unique across all installed Swift SDK bundles.
"""
#if os(macOS)
case .quarantineAttributePresent(let bundlePath):
return """
Quarantine attribute is present on a Swift SDK bundle at path `\(bundlePath)`. If you're certain that the \
bundle was downloaded from a trusted source, you can remove the attribute with this command:

xattr -d -r -s com.apple.quarantine "\(bundlePath)"

and try to install this bundle again.
"""
#endif
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions Sources/PackageModel/SwiftSDKBundle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import Basics

import protocol TSCBasic.FileSystem
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: sort imports

import struct Foundation.URL
import struct TSCBasic.RegEx

Expand Down Expand Up @@ -245,6 +246,13 @@ public struct SwiftSDKBundle {
_ archiver: some Archiver,
_ observabilityScope: ObservabilityScope
) throws {
#if os(macOS)
// Check the quarantine attribute on bundles downloaded manually in the browser.
guard fileSystem.hasAttribute(.quarantine, bundlePath.underlying) else {
throw DestinationError.quarantineAttributePresent(bundlePath: bundlePath)
}
#endif

let unpackedBundlePath = try unpackIfNeeded(
bundlePath: bundlePath,
destinationsDirectory: destinationsDirectory,
Expand Down