Skip to content

Commit ec4dc2b

Browse files
committed
runtime clean up
1 parent 6ffce23 commit ec4dc2b

9 files changed

Lines changed: 107 additions & 62 deletions

File tree

Xcodes.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@
101101
CAFFFED8259CDA5000903F81 /* XcodeListViewRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAFFFED7259CDA5000903F81 /* XcodeListViewRow.swift */; };
102102
E689540325BE8C64000EBCEA /* DockProgress in Frameworks */ = {isa = PBXBuildFile; productRef = E689540225BE8C64000EBCEA /* DockProgress */; };
103103
E81D7EA02805250100A205FC /* Collection+.swift in Sources */ = {isa = PBXBuildFile; fileRef = E81D7E9F2805250100A205FC /* Collection+.swift */; };
104+
E832EAF82B0FBCF4001B570D /* RuntimeInstallationStepDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E832EAF72B0FBCF4001B570D /* RuntimeInstallationStepDetailView.swift */; };
104105
E872EE4E2808D4F100D3DD8B /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = E872EE502808D4F100D3DD8B /* Localizable.strings */; };
105106
E87AB3C52939B65E00D72F43 /* Hardware.swift in Sources */ = {isa = PBXBuildFile; fileRef = E87AB3C42939B65E00D72F43 /* Hardware.swift */; };
106107
E87DD6EB25D053FA00D86808 /* Progress+.swift in Sources */ = {isa = PBXBuildFile; fileRef = E87DD6EA25D053FA00D86808 /* Progress+.swift */; };
@@ -300,6 +301,7 @@
300301
CAFFFEEE259CEAC400903F81 /* RingProgressViewStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RingProgressViewStyle.swift; sourceTree = "<group>"; };
301302
E2AFDCCA28F024D000864ADD /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = "<group>"; };
302303
E81D7E9F2805250100A205FC /* Collection+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Collection+.swift"; sourceTree = "<group>"; };
304+
E832EAF72B0FBCF4001B570D /* RuntimeInstallationStepDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuntimeInstallationStepDetailView.swift; sourceTree = "<group>"; };
303305
E856BB73291EDD3D00DC438B /* XcodesKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = XcodesKit; path = Xcodes/XcodesKit; sourceTree = "<group>"; };
304306
E872EE4F2808D4F100D3DD8B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
305307
E87AB3C42939B65E00D72F43 /* Hardware.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Hardware.swift; sourceTree = "<group>"; };
@@ -623,6 +625,7 @@
623625
children = (
624626
CAFBDC67259A308B003DCC5A /* InfoPane.swift */,
625627
E8E98A9525D863D700EC89A0 /* InstallationStepDetailView.swift */,
628+
E832EAF72B0FBCF4001B570D /* RuntimeInstallationStepDetailView.swift */,
626629
);
627630
path = InfoPane;
628631
sourceTree = "<group>";
@@ -875,6 +878,7 @@
875878
CA452BB0259FD9770072DFA4 /* ProgressIndicator.swift in Sources */,
876879
CAFE4AB425B7D3AF0064FE51 /* AdvancedPreferencePane.swift in Sources */,
877880
CA9FF84E2595079F00E47BAF /* ScrollingTextView.swift in Sources */,
881+
E832EAF82B0FBCF4001B570D /* RuntimeInstallationStepDetailView.swift in Sources */,
878882
CABFA9C12592EEEA00380FEE /* Version+.swift in Sources */,
879883
E8D655C0288DD04700A139C2 /* SelectedActionType.swift in Sources */,
880884
36741BFD291E4FDB00A85AAE /* DownloadPreferencePane.swift in Sources */,

Xcodes/Backend/AppState+Install.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -499,9 +499,9 @@ extension AppState {
499499
Current.notificationManager.scheduleNotification(title: xcode.id.appleDescription, body: step.description, category: .normal)
500500
}
501501
}
502+
502503
func setInstallationStep(of runtime: DownloadableRuntime, to step: RuntimeInstallationStep) {
503504
DispatchQueue.main.async {
504-
505505
guard let index = self.downloadableRuntimes.firstIndex(where: { $0.identifier == runtime.identifier }) else { return }
506506
self.downloadableRuntimes[index].installState = .installing(step)
507507

Xcodes/Backend/AppState+Runtimes.swift

Lines changed: 24 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,18 @@ extension AppState {
4949
Task {
5050
do {
5151
try await downloadRunTimeFull(runtime: runtime)
52+
53+
DispatchQueue.main.async {
54+
guard let index = self.downloadableRuntimes.firstIndex(where: { $0.identifier == runtime.identifier }) else { return }
55+
self.downloadableRuntimes[index].installState = .installed
56+
}
5257
}
5358
catch {
5459
Logger.appState.error("Error downloading runtime: \(error.localizedDescription)")
60+
DispatchQueue.main.async {
61+
self.error = error
62+
self.presentedAlert = .generic(title: localizeString("Alert.Install.Error.Title"), message: error.legibleLocalizedDescription)
63+
}
5564
}
5665
}
5766

@@ -83,22 +92,31 @@ extension AppState {
8392
let downloader = Downloader(rawValue: UserDefaults.standard.string(forKey: "downloader") ?? "aria2") ?? .aria2
8493
Logger.appState.info("Downloading \(runtime.visibleIdentifier) with \(downloader)")
8594

95+
8696
let url = try await self.downloadRuntime(for: runtime, downloader: downloader, progressChanged: { [unowned self] progress in
8797
DispatchQueue.main.async {
8898
self.setInstallationStep(of: runtime, to: .downloading(progress: progress))
8999
}
90100
}).async()
91101

92102
Logger.appState.debug("Done downloading: \(url)")
93-
//self.setInstallationStep(of: runtime, to: .downloading(progress: progress))
103+
DispatchQueue.main.async {
104+
self.setInstallationStep(of: runtime, to: .installing)
105+
}
94106
switch runtime.contentType {
95107
case .package:
96-
try await self.installFromPackage(dmgURL: url, runtime: runtime)
108+
// not supported yet (do we need to for old packages?)
109+
throw "Installing via package not support - please install manually from \(url.description)"
97110
case .diskImage:
98111
try await self.installFromImage(dmgURL: url)
112+
DispatchQueue.main.async {
113+
self.setInstallationStep(of: runtime, to: .trashingArchive)
114+
}
115+
try Current.files.removeItem(at: url)
99116
}
100117
}
101118

119+
@MainActor
102120
func downloadRuntime(for runtime: DownloadableRuntime, downloader: Downloader, progressChanged: @escaping (Progress) -> Void) -> AnyPublisher<URL, Error> {
103121
// Check to see if the dmg is in the expected path in case it was downloaded but failed to install
104122

@@ -139,9 +157,9 @@ extension AppState {
139157
.setFailureType(to: Error.self)
140158
.eraseToAnyPublisher()
141159

142-
// return downloadXcodeWithURLSession(
143-
// availableXcode,
144-
// to: destination,
160+
// return downloadRuntimeWithURLSession(
161+
// runtime,
162+
// to: expectedRuntimePath,
145163
// progressChanged: progressChanged
146164
// )
147165
}
@@ -163,36 +181,8 @@ extension AppState {
163181
.eraseToAnyPublisher()
164182
}
165183

166-
167184
public func installFromImage(dmgURL: URL) async throws {
168-
169-
try? self.runtimeService.installRuntimeImage(dmgURL: dmgURL)
170-
171-
}
172-
173-
public func installFromPackage(dmgURL: URL, runtime: DownloadableRuntime) async throws {
174-
Logger.appState.info("Mounting DMG")
175-
176-
do {
177-
let mountedUrl = try await self.runtimeService.mountDMG(dmgUrl: dmgURL)
178-
179-
// 2-Get the first path under the mounted path, should be a .pkg
180-
let pkgPath = Path(url: mountedUrl)!.ls().first!
181-
try Path.xcodesCaches.mkdir().setCurrentUserAsOwner()
182-
183-
let expandedPkgPath = Path.xcodesCaches/runtime.identifier
184-
//try expandedPkgPath.mkdir()
185-
Logger.appState.info("PKG Path: \(pkgPath)")
186-
Logger.appState.info("Expanded PKG Path: \(expandedPkgPath)")
187-
//try? Current.files.removeItem(at: expandedPkgPath.url)
188-
189-
// 5-Expand (not install) the pkg to temporary path
190-
try await self.runtimeService.expand(pkgPath: pkgPath, expandedPkgPath: expandedPkgPath)
191-
//try await self.runtimeService.unmountDMG(mountedURL: mountedUrl)
192-
193-
} catch {
194-
Logger.appState.error("Error installing runtime: \(error.localizedDescription)")
195-
}
185+
try await self.runtimeService.installRuntimeImage(dmgURL: dmgURL)
196186
}
197187
}
198188

Xcodes/Backend/Environment.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,12 @@ public struct Files {
240240
return nil
241241
}
242242
}
243+
244+
public var write: (Data, URL) throws -> Void = { try $0.write(to: $1) }
245+
246+
public func write(_ data: Data, to url: URL) throws {
247+
try write(data, url)
248+
}
243249
}
244250

245251
private func _installedXcodes(destination: Path) -> [InstalledXcode] {

Xcodes/Frontend/InfoPane/InfoPane.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,8 +288,7 @@ struct InfoPane: View {
288288
switch runtime.installState {
289289

290290
case .installing(let installationStep):
291-
Text("INSTALLING")
292-
InstallationStepDetailView(installationStep: installationStep)
291+
RuntimeInstallationStepDetailView(installationStep: installationStep)
293292
.fixedSize(horizontal: false, vertical: true)
294293
default:
295294
EmptyView()
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//
2+
// RuntimeInstallationStepDetailView.swift
3+
// Xcodes
4+
//
5+
// Created by Matt Kiazyk on 2023-11-23.
6+
// Copyright © 2023 Robots and Pencils. All rights reserved.
7+
//
8+
9+
import SwiftUI
10+
import XcodesKit
11+
12+
struct RuntimeInstallationStepDetailView: View {
13+
let installationStep: RuntimeInstallationStep
14+
15+
var body: some View {
16+
VStack(alignment: .leading, spacing: 0) {
17+
Text(String(format: localizeString("InstallationStepDescription"), installationStep.stepNumber, installationStep.stepCount, installationStep.message))
18+
19+
switch installationStep {
20+
case let .downloading(progress):
21+
ObservingProgressIndicator(
22+
progress,
23+
controlSize: .regular,
24+
style: .bar,
25+
showsAdditionalDescription: true
26+
)
27+
28+
case .installing, .trashingArchive:
29+
ProgressView()
30+
.scaleEffect(0.5)
31+
}
32+
}
33+
}
34+
}
35+
36+
#Preview("Downloading") {
37+
RuntimeInstallationStepDetailView(
38+
installationStep: .downloading(
39+
progress: configure(Progress()) {
40+
$0.kind = .file
41+
$0.fileOperationKind = .downloading
42+
$0.estimatedTimeRemaining = 123
43+
$0.totalUnitCount = 11944848484
44+
$0.completedUnitCount = 848444920
45+
$0.throughput = 9211681
46+
}
47+
))
48+
}
49+
#Preview("Installing") {
50+
RuntimeInstallationStepDetailView(
51+
installationStep: .installing
52+
)
53+
}

Xcodes/XcodesKit/Sources/XcodesKit/Models/Runtimes/RuntimeInstallState.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import Path
1111
public enum RuntimeInstallState: Equatable {
1212
case notInstalled
1313
case installing(RuntimeInstallationStep)
14-
case installed(Path)
14+
case installed
1515

1616
var notInstalled: Bool {
1717
switch self {

Xcodes/XcodesKit/Sources/XcodesKit/Models/Runtimes/RuntimeInstallationStep.swift

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,8 @@ import Foundation
99

1010
public enum RuntimeInstallationStep: Equatable, CustomStringConvertible {
1111
case downloading(progress: Progress)
12-
case unarchiving
13-
case moving(destination: String)
12+
case installing
1413
case trashingArchive
15-
case checkingSecurity
16-
case finishing
1714

1815
public var description: String {
1916
"(\(stepNumber)/\(stepCount)) \(message)"
@@ -23,29 +20,20 @@ public enum RuntimeInstallationStep: Equatable, CustomStringConvertible {
2320
switch self {
2421
case .downloading:
2522
return localizeString("Downloading")
26-
case .unarchiving:
27-
return localizeString("Unarchiving")
28-
case .moving(let destination):
29-
return String(format: localizeString("Moving"), destination)
23+
case .installing:
24+
return localizeString("Installing")
3025
case .trashingArchive:
3126
return localizeString("TrashingArchive")
32-
case .checkingSecurity:
33-
return localizeString("CheckingSecurity")
34-
case .finishing:
35-
return localizeString("Finishing")
3627
}
3728
}
3829

3930
public var stepNumber: Int {
4031
switch self {
4132
case .downloading: return 1
42-
case .unarchiving: return 2
43-
case .moving: return 3
44-
case .trashingArchive: return 4
45-
case .checkingSecurity: return 5
46-
case .finishing: return 6
33+
case .installing: return 2
34+
case .trashingArchive: return 3
4735
}
4836
}
4937

50-
public var stepCount: Int { 6 }
38+
public var stepCount: Int { 3 }
5139
}

Xcodes/XcodesKit/Sources/XcodesKit/Services/RuntimeService.swift

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,8 @@ public struct RuntimeService {
5454
}
5555
}
5656

57-
public func installRuntimeImage(dmgURL: URL) throws {
58-
Task {
59-
_ = try await Current.shell.installRuntimeImage(dmgURL)
60-
}
57+
public func installRuntimeImage(dmgURL: URL) async throws {
58+
_ = try await Current.shell.installRuntimeImage(dmgURL)
6159
}
6260

6361
public func mountDMG(dmgUrl: URL) async throws -> URL {
@@ -72,13 +70,20 @@ public struct RuntimeService {
7270
}
7371

7472
public func unmountDMG(mountedURL: URL) async throws {
75-
let url = try await Current.shell.unmountDmg(mountedURL)
73+
_ = try await Current.shell.unmountDmg(mountedURL)
7674
}
7775

7876
public func expand(pkgPath: Path, expandedPkgPath: Path) async throws {
7977
_ = try await Current.shell.expandPkg(pkgPath.url, expandedPkgPath.url)
8078
}
81-
79+
80+
public func createPkg(pkgPath: Path, expandedPkgPath: Path) async throws {
81+
_ = try await Current.shell.createPkg(pkgPath.url, expandedPkgPath.url)
82+
}
83+
84+
public func installPkg(pkgPath: Path, expandedPkgPath: Path) async throws {
85+
_ = try await Current.shell.installPkg(pkgPath.url, expandedPkgPath.url.absoluteString)
86+
}
8287
}
8388

8489
extension String: Error {}

0 commit comments

Comments
 (0)