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 runtime downloading #585

Merged
merged 1 commit into from
Jun 28, 2024
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
36 changes: 30 additions & 6 deletions Xcodes/Backend/AppState+Runtimes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ extension AppState {
self.setInstallationStep(of: runtime, to: .installing)
}
switch runtime.contentType {
case .cryptexDiskImage:
// not supported yet (do we need to for old packages?)
throw "Installing via cryptexDiskImage not support - please install manually from \(downloadedURL.description)"
case .package:
// not supported yet (do we need to for old packages?)
throw "Installing via package not support - please install manually from \(downloadedURL.description)"
Expand All @@ -80,19 +83,31 @@ extension AppState {
Logger.appState.error("Error downloading runtime: \(error.localizedDescription)")
DispatchQueue.main.async {
self.error = error
self.presentedAlert = .generic(title: localizeString("Alert.Install.Error.Title"), message: error.legibleLocalizedDescription)
if let error = error as? String {
self.presentedAlert = .generic(title: localizeString("Alert.Install.Error.Title"), message: error)
} else {
self.presentedAlert = .generic(title: localizeString("Alert.Install.Error.Title"), message: error.legibleLocalizedDescription)
}
}
}
}
}

func downloadRunTimeFull(runtime: DownloadableRuntime) async throws -> URL {
guard let source = runtime.source else {
throw "Invalid runtime source"
}

guard let downloadPath = runtime.downloadPath else {
throw "Invalid runtime downloadPath"
}

// sets a proper cookie for runtimes
try await validateADCSession(path: runtime.downloadPath)
try await validateADCSession(path: downloadPath)

let downloader = Downloader(rawValue: UserDefaults.standard.string(forKey: "downloader") ?? "aria2") ?? .aria2

let url = URL(string: runtime.source)!
let url = URL(string: source)!
let expectedRuntimePath = Path.xcodesApplicationSupport/"\(url.lastPathComponent)"
// aria2 downloads directly to the destination (instead of into /tmp first) so we need to make sure that the download isn't incomplete
let aria2DownloadMetadataPath = expectedRuntimePath.parent/(expectedRuntimePath.basename() + ".aria2")
Expand Down Expand Up @@ -123,9 +138,15 @@ extension AppState {
}

public func downloadRuntimeWithAria2(_ runtime: DownloadableRuntime, to destination: Path, aria2Path: Path) -> AsyncThrowingStream<Progress, Error> {
let cookies = AppleAPI.Current.network.session.configuration.httpCookieStorage?.cookies(for: runtime.url) ?? []
guard let url = runtime.url else {
return AsyncThrowingStream<Progress, Error> { continuation in
continuation.finish(throwing: "Invalid or non existant runtime url")
}
}

let cookies = AppleAPI.Current.network.session.configuration.httpCookieStorage?.cookies(for: url) ?? []

return Current.shell.downloadWithAria2Async(aria2Path, runtime.url, destination, cookies)
return Current.shell.downloadWithAria2Async(aria2Path, url, destination, cookies)
}


Expand All @@ -140,7 +161,10 @@ extension AppState {
runtimePublishers[runtime.identifier] = nil

// If the download is cancelled by the user, clean up the download files that aria2 creates.
let url = URL(string: runtime.source)!
guard let source = runtime.source else {
return
}
let url = URL(string: source)!
let expectedRuntimePath = Path.xcodesApplicationSupport/"\(url.lastPathComponent)"
let aria2DownloadMetadataPath = expectedRuntimePath.parent/(expectedRuntimePath.basename() + ".aria2")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public struct DownloadableRuntimesResponse: Codable {
public struct DownloadableRuntime: Codable, Identifiable, Hashable {
public let category: Category
public let simulatorVersion: SimulatorVersion
public let source: String
public let source: String?
public let dictionaryVersion: Int
public let contentType: ContentType
public let platform: Platform
Expand All @@ -21,11 +21,14 @@ public struct DownloadableRuntime: Codable, Identifiable, Hashable {
public let hostRequirements: HostRequirements?
public let name: String
public let authentication: Authentication?
public var url: URL {
return URL(string: source)!
public var url: URL? {
if let source {
return URL(string: source)!
}
return nil
}
public var downloadPath: String {
url.path
public var downloadPath: String? {
url?.path
}

// dynamically updated - not decoded
Expand Down Expand Up @@ -117,6 +120,7 @@ extension DownloadableRuntime {
public enum ContentType: String, Codable {
case diskImage = "diskImage"
case package = "package"
case cryptexDiskImage = "cryptexDiskImage"
}

public enum Platform: String, Codable {
Expand Down
11 changes: 8 additions & 3 deletions Xcodes/XcodesKit/Sources/XcodesKit/Services/RuntimeService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,14 @@ public struct RuntimeService {

// Apple gives a plist for download
let (data, _) = try await networkService.requestData(urlRequest, validators: [])
let decodedResponse = try PropertyListDecoder().decode(DownloadableRuntimesResponse.self, from: data)

return decodedResponse
do {
let decodedResponse = try PropertyListDecoder().decode(DownloadableRuntimesResponse.self, from: data)
return decodedResponse
} catch {
print("error: \(error)")
throw error
}

}

public func installedRuntimes() async throws -> [InstalledRuntime] {
Expand Down
Loading