Skip to content

Async package registry tests #7135

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

Merged
merged 2 commits into from
Nov 29, 2023
Merged
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
2 changes: 1 addition & 1 deletion Sources/Basics/Concurrency/ConcurrencyHelpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ extension DispatchQueue {
}

/// Bridges between potentially blocking methods that take a result completion closure and async/await
public func safe_async<T, ErrorType: Error>(_ body: @escaping (@escaping (Result<T, ErrorType>) -> Void) -> Void) async throws -> T {
public func safe_async<T, ErrorType: Error>(_ body: @Sendable @escaping (@Sendable @escaping (Result<T, ErrorType>) -> Void) -> Void) async throws -> T {
try await withCheckedThrowingContinuation { continuation in
// It is possible that body make block indefinitely on a lock, sempahore,
// or similar then synchrously call the completion handler. For full safety
Expand Down
1 change: 1 addition & 0 deletions Sources/Basics/FileSystem/TemporaryFile.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ public func withTemporaryDirectory<Result>(
/// return value for the `withTemporaryDirectory` function.
///
/// - Throws: An error when creating directory and rethrows all errors from `body`.
@discardableResult
public func withTemporaryDirectory<Result>(
fileSystem: FileSystem = localFileSystem,
dir: AbsolutePath? = nil,
Expand Down
51 changes: 49 additions & 2 deletions Sources/PackageRegistry/ChecksumTOFU.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,30 @@ struct PackageVersionChecksumTOFU {
}

// MARK: - source archive

func validateSourceArchive(
registry: Registry,
package: PackageIdentity.RegistryIdentity,
version: Version,
checksum: String,
timeout: DispatchTimeInterval?,
observabilityScope: ObservabilityScope,
callbackQueue: DispatchQueue
) async throws {
try await safe_async {
self.validateSourceArchive(
registry: registry,
package: package,
version: version,
checksum: checksum,
timeout: timeout,
observabilityScope: observabilityScope,
callbackQueue: callbackQueue,
completion: $0
)
}
}

@available(*, noasync, message: "Use the async alternative")
func validateSourceArchive(
registry: Registry,
package: PackageIdentity.RegistryIdentity,
Expand Down Expand Up @@ -135,7 +158,31 @@ struct PackageVersionChecksumTOFU {
}

// MARK: - manifests

func validateManifest(
registry: Registry,
package: PackageIdentity.RegistryIdentity,
version: Version,
toolsVersion: ToolsVersion?,
checksum: String,
timeout: DispatchTimeInterval?,
observabilityScope: ObservabilityScope,
callbackQueue: DispatchQueue
) async throws {
try await safe_async {
self.validateManifest(
registry: registry,
package: package,
version: version,
toolsVersion: toolsVersion,
checksum: checksum,
timeout: timeout,
observabilityScope: observabilityScope,
callbackQueue: callbackQueue,
completion: $0
)
}
}
@available(*, noasync, message: "Use the async alternative")
func validateManifest(
registry: Registry,
package: PackageIdentity.RegistryIdentity,
Expand Down
196 changes: 195 additions & 1 deletion Sources/PackageRegistry/RegistryClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,25 @@ public final class RegistryClient: Cancellable {
callback: completion
)
}

public func getPackageMetadata(
package: PackageIdentity,
timeout: DispatchTimeInterval? = .none,
observabilityScope: ObservabilityScope,
callbackQueue: DispatchQueue
) async throws -> PackageMetadata {
try await safe_async {
self.getPackageMetadata(
package: package,
timeout: timeout,
observabilityScope: observabilityScope,
callbackQueue: callbackQueue,
completion: $0
)
}
}

@available(*, noasync, message: "Use the async alternative")
public func getPackageMetadata(
package: PackageIdentity,
timeout: DispatchTimeInterval? = .none,
Expand Down Expand Up @@ -260,7 +278,29 @@ public final class RegistryClient: Cancellable {
)
}
}

public func getPackageVersionMetadata(
package: PackageIdentity,
version: Version,
timeout: DispatchTimeInterval? = .none,
fileSystem: FileSystem,
observabilityScope: ObservabilityScope,
callbackQueue: DispatchQueue
) async throws -> PackageVersionMetadata {
try await safe_async {
self.getPackageVersionMetadata(
package: package,
version: version,
timeout: timeout,
fileSystem: fileSystem,
observabilityScope: observabilityScope,
callbackQueue: callbackQueue,
completion: $0
)
}
}

@available(*, noasync, message: "Use the async alternative")
public func getPackageVersionMetadata(
package: PackageIdentity,
version: Version,
Expand Down Expand Up @@ -462,6 +502,26 @@ public final class RegistryClient: Cancellable {
}
}

public func getAvailableManifests(
package: PackageIdentity,
version: Version,
timeout: DispatchTimeInterval? = .none,
observabilityScope: ObservabilityScope,
callbackQueue: DispatchQueue
) async throws -> [String: (toolsVersion: ToolsVersion, content: String?)]{
try await safe_async {
self.getAvailableManifests(
package: package,
version: version,
timeout: timeout,
observabilityScope: observabilityScope,
callbackQueue: callbackQueue,
completion: $0
)
}
}

@available(*, noasync, message: "Use the async alternative")
public func getAvailableManifests(
package: PackageIdentity,
version: Version,
Expand Down Expand Up @@ -689,7 +749,28 @@ public final class RegistryClient: Cancellable {
}
}
}

public func getManifestContent(
package: PackageIdentity,
version: Version,
customToolsVersion: ToolsVersion?,
timeout: DispatchTimeInterval? = .none,
observabilityScope: ObservabilityScope,
callbackQueue: DispatchQueue
) async throws -> String {
try await safe_async {
self.getManifestContent(
package: package,
version: version,
customToolsVersion: customToolsVersion,
timeout: timeout,
observabilityScope: observabilityScope,
callbackQueue: callbackQueue,
completion: $0
)
}
}

@available(*, noasync, message: "Use the async alternative")
public func getManifestContent(
package: PackageIdentity,
version: Version,
Expand Down Expand Up @@ -898,7 +979,32 @@ public final class RegistryClient: Cancellable {
}
}
}
public func downloadSourceArchive(
package: PackageIdentity,
version: Version,
destinationPath: AbsolutePath,
progressHandler: ((_ bytesReceived: Int64, _ totalBytes: Int64?) -> Void)?,
timeout: DispatchTimeInterval? = .none,
fileSystem: FileSystem,
observabilityScope: ObservabilityScope,
callbackQueue: DispatchQueue
) async throws {
try await safe_async {
self.downloadSourceArchive(
package: package,
version: version,
destinationPath: destinationPath,
progressHandler: progressHandler,
timeout: timeout,
fileSystem: fileSystem,
observabilityScope: observabilityScope,
callbackQueue: callbackQueue,
completion: $0
)
}
}

@available(*, noasync, message: "Use the async alternative")
public func downloadSourceArchive(
package: PackageIdentity,
version: Version,
Expand Down Expand Up @@ -1189,7 +1295,25 @@ public final class RegistryClient: Cancellable {
}
}
}

public func lookupIdentities(
scmURL: SourceControlURL,
timeout: DispatchTimeInterval? = .none,
observabilityScope: ObservabilityScope,
callbackQueue: DispatchQueue
) async throws -> Set<PackageIdentity> {
try await safe_async {
self.lookupIdentities(
scmURL: scmURL,
timeout: timeout,
observabilityScope: observabilityScope,
callbackQueue: callbackQueue,
completion: $0
)
}
}

@available(*, noasync, message: "Use the async alternative")
public func lookupIdentities(
scmURL: SourceControlURL,
timeout: DispatchTimeInterval? = .none,
Expand Down Expand Up @@ -1294,7 +1418,25 @@ public final class RegistryClient: Cancellable {
)
}
}

public func login(
loginURL: URL,
timeout: DispatchTimeInterval? = .none,
observabilityScope: ObservabilityScope,
callbackQueue: DispatchQueue
) async throws {
try await safe_async {
self.login(
loginURL: loginURL,
timeout: timeout,
observabilityScope: observabilityScope,
callbackQueue: callbackQueue,
completion: $0
)
}
}

@available(*, noasync, message: "Use the async alternative")
public func login(
loginURL: URL,
timeout: DispatchTimeInterval? = .none,
Expand Down Expand Up @@ -1331,7 +1473,41 @@ public final class RegistryClient: Cancellable {
}
}
}

public func publish(
registryURL: URL,
packageIdentity: PackageIdentity,
packageVersion: Version,
packageArchive: AbsolutePath,
packageMetadata: AbsolutePath?,
signature: [UInt8]?,
metadataSignature: [UInt8]?,
signatureFormat: SignatureFormat?,
timeout: DispatchTimeInterval? = .none,
fileSystem: FileSystem,
observabilityScope: ObservabilityScope,
callbackQueue: DispatchQueue
) async throws -> PublishResult {
try await safe_async {
self.publish(
registryURL: registryURL,
packageIdentity: packageIdentity,
packageVersion: packageVersion,
packageArchive: packageArchive,
packageMetadata: packageMetadata,
signature: signature,
metadataSignature: metadataSignature,
signatureFormat: signatureFormat,
timeout: timeout,
fileSystem: fileSystem,
observabilityScope: observabilityScope,
callbackQueue: callbackQueue,
completion: $0
)
}
}

@available(*, noasync, message: "Use the async alternative")
public func publish(
registryURL: URL,
packageIdentity: PackageIdentity,
Expand Down Expand Up @@ -1499,8 +1675,26 @@ public final class RegistryClient: Cancellable {
)
}
}

func checkAvailability(
registry: Registry,
timeout: DispatchTimeInterval? = .none,
observabilityScope: ObservabilityScope,
callbackQueue: DispatchQueue
) async throws -> AvailabilityStatus {
try await safe_async {
self.checkAvailability(
registry: registry,
timeout: timeout,
observabilityScope: observabilityScope,
callbackQueue: callbackQueue,
completion: $0
)
}
}

// marked internal for testing
@available(*, noasync, message: "Use the async alternative")
func checkAvailability(
registry: Registry,
timeout: DispatchTimeInterval? = .none,
Expand Down
20 changes: 20 additions & 0 deletions Sources/PackageRegistry/RegistryDownloadsManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,27 @@ public class RegistryDownloadsManager: Cancellable {
self.registryClient = registryClient
self.delegate = delegate
}

public func lookup(
package: PackageIdentity,
version: Version,
observabilityScope: ObservabilityScope,
delegateQueue: DispatchQueue,
callbackQueue: DispatchQueue
) async throws -> AbsolutePath {
try await safe_async {
self.lookup(
package: package,
version: version,
observabilityScope: observabilityScope,
delegateQueue: delegateQueue,
callbackQueue: callbackQueue,
completion: $0
)
}
}

@available(*, noasync, message: "Use the async alternative")
public func lookup(
package: PackageIdentity,
version: Version,
Expand Down
Loading