Skip to content

Commit ee386f3

Browse files
authored
Destinations: use UniversalArchiver in install command (swiftlang#6392)
Fixes `.tar.gz` archives support in `experimental-destination install` subcommand. Tweaks multi-component extensions calculation so that at most last 2 components are taken into consideration. This fixes an issue with bundle names that have dots. For example, for `5.7.3-RELEASE_ubuntu_22.04_aarch64.tar.gz` previously `allExtensions` returned `7.3-RELEASE_ubuntu_22.04_aarch64.tar.gz`, and that didn't match any of the archivers, even though the actual extension was valid. rdar://107485048
1 parent aadb688 commit ee386f3

File tree

4 files changed

+21
-12
lines changed

4 files changed

+21
-12
lines changed

Sources/Basics/Archiver/UniversalArchiver.swift

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ public struct UniversalArchiver: Archiver {
2020

2121
/// Errors specific to the implementation of ``UniversalArchiver``.
2222
enum Error: Swift.Error {
23-
case unknownFormat(String, AbsolutePath)
23+
case unknownFormat([String], AbsolutePath)
2424
case noFileNameExtension(AbsolutePath)
2525

2626
var description: String {
2727
switch self {
2828
case .unknownFormat(let ext, let path):
29-
return "unknown format with extension \(ext) at path `\(path)`"
29+
return "unknown format with extension \(ext.joined(separator: ".")) at path `\(path)`"
3030
case .noFileNameExtension(let path):
3131
return "file at path `\(path)` has no extension to detect archival format from"
3232
}
@@ -55,15 +55,22 @@ public struct UniversalArchiver: Archiver {
5555
}
5656

5757
private func archiver(for archivePath: AbsolutePath) throws -> any Archiver {
58-
guard let extensions = archivePath.allExtensions else {
58+
guard var extensions = archivePath.allExtensions, extensions.count > 0 else {
5959
throw Error.noFileNameExtension(archivePath)
6060
}
6161

62-
guard let archiver = self.formatMapping[extensions] else {
63-
throw Error.unknownFormat(extensions, archivePath)
62+
// None of the archivers support extensions with more than 2 extension components
63+
if extensions.count > 2 {
64+
extensions = extensions.suffix(2)
6465
}
6566

66-
return archiver
67+
if let archiver = self.formatMapping[extensions.joined(separator: ".")] {
68+
return archiver
69+
} else if let lastExtension = extensions.last, let archiver = self.formatMapping[lastExtension] {
70+
return archiver
71+
} else {
72+
throw Error.unknownFormat(extensions, archivePath)
73+
}
6774
}
6875

6976
public func extract(

Sources/Basics/FileSystem/Path+Extensions.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ extension AbsolutePath {
4040
}
4141

4242
/// Unlike ``AbsolutePath//extension``, this property returns all characters after the first `.` character in a
43-
/// `````. If no dot character is present in the filename or first dot is the last character, `nil` is returned.
44-
var allExtensions: String? {
43+
/// filename. If no dot character is present in the filename or first dot is the last character, `nil` is returned.
44+
var allExtensions: [String]? {
4545
guard let firstDot = basename.firstIndex(of: ".") else {
4646
return nil
4747
}
@@ -54,6 +54,6 @@ extension AbsolutePath {
5454

5555
extensions.removeFirst()
5656

57-
return extensions
57+
return extensions.split(separator: ".").map(String.init)
5858
}
5959
}

Sources/CrossCompilationDestinationsTool/InstallDestination.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,13 @@ public struct InstallDestination: DestinationCommand {
4343
_ destinationsDirectory: AbsolutePath,
4444
_ observabilityScope: ObservabilityScope
4545
) throws {
46+
let cancellator = Cancellator(observabilityScope: observabilityScope)
47+
cancellator.installSignalHandlers()
4648
try DestinationBundle.install(
4749
bundlePathOrURL: bundlePathOrURL,
4850
destinationsDirectory: destinationsDirectory,
4951
self.fileSystem,
50-
ZipArchiver(fileSystem: self.fileSystem),
52+
UniversalArchiver(self.fileSystem, cancellator),
5153
observabilityScope
5254
)
5355
}

Sources/PackageModel/DestinationBundle.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,13 +225,13 @@ public struct DestinationBundle {
225225
throw DestinationError.destinationBundleAlreadyInstalled(bundleName: unpackedBundleName)
226226
}
227227

228-
print("\(bundleName) is assumed to be an archive, unpacking...")
229-
230228
// If there's no archive extension on the bundle name, assuming it's not archived and returning the same path.
231229
guard unpackedBundleName != bundleName else {
232230
return bundlePath
233231
}
234232

233+
print("\(bundleName) is assumed to be an archive, unpacking...")
234+
235235
try tsc_await { archiver.extract(from: bundlePath, to: temporaryDirectory, completion: $0) }
236236

237237
return temporaryDirectory.appending(component: unpackedBundleName)

0 commit comments

Comments
 (0)