Skip to content

Commit f9ea654

Browse files
🔧 Tweak brew output parsing
Improved the accuracy of the brew output. Often, when multiple console messages were returned, the progress prompt in the PHP version manager would display the earliest found step, not the latest, thus unfortunately misrepresenting the progress of the installation steps. This fixes that by reversing the return order, but also extracts relevant information from the commands, too, so that contextual info is now included (for pouring, installing and downloading steps). (This makes it a little bit more transparent for the end user to find out what is taking up all this time. I wish that Homebrew was faster, too, but there's a reason I'm not using statically compiled PHP for this project. Either way, this is a nice QoL change.)
1 parent 8677628 commit f9ea654

File tree

3 files changed

+56
-10
lines changed

3 files changed

+56
-10
lines changed

phpmon/Domain/Integrations/Homebrew/Commands/BrewCommand.swift

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,68 @@ protocol BrewCommand {
1616

1717
extension BrewCommand {
1818
internal func reportInstallationProgress(_ text: String) -> (Double, String)? {
19-
if text.contains("Fetching") {
19+
// Special cases: downloading a manifest is effectively fetching metadata
20+
if text.contains("==> Downloading") && text.contains("/manifests/") {
2021
return (0.1, "phpman.steps.fetching".localized)
2122
}
22-
if text.contains("Downloading") {
23-
return (0.25, "phpman.steps.downloading".localized)
23+
24+
// Logical progress evaluation (reverse order for accuracy)
25+
if text.contains("==> Summary") {
26+
return (0.90, "phpman.steps.summary".localized)
2427
}
25-
if text.contains("Installing") {
28+
if text.contains("==> Pouring") {
29+
if let subject = extractContext(from: text) {
30+
return (0.80, "phpman.steps.pouring".localized + "\n(\(subject))")
31+
}
32+
return (0.80, "phpman.steps.pouring".localized)
33+
}
34+
if text.contains("==> Installing") {
35+
if let subject = extractContext(from: text) {
36+
return (0.60, "phpman.steps.installing".localized + "\n(\(subject))")
37+
}
2638
return (0.60, "phpman.steps.installing".localized)
2739
}
28-
if text.contains("Pouring") {
29-
return (0.80, "phpman.steps.pouring".localized)
40+
if text.contains("==> Downloading") {
41+
if let subject = extractContext(from: text) {
42+
return (0.25, "phpman.steps.downloading".localized + "\n(\(subject))")
43+
}
44+
return (0.25, "phpman.steps.downloading".localized)
3045
}
31-
if text.contains("Summary") {
32-
return (0.90, "phpman.steps.summary".localized)
46+
if text.contains("==> Fetching") {
47+
return (0.1, "phpman.steps.fetching".localized)
3348
}
3449
return nil
3550
}
3651

52+
internal func extractContext(from text: String) -> String? {
53+
var pattern = #""#
54+
if text.contains("==> Fetching") {
55+
pattern = #"==> Fetching (\S+)"#
56+
}
57+
if text.contains("==> Downloading") {
58+
pattern = #"==> Downloading (\S+)"#
59+
}
60+
if text.contains("==> Installing") {
61+
pattern = #"==> Installing (\S+)"#
62+
}
63+
if text.contains("==> Pouring") {
64+
pattern = #"==> Pouring (\S+)"#
65+
}
66+
67+
guard let regex = try? NSRegularExpression(pattern: pattern) else {
68+
return nil
69+
}
70+
71+
let range = NSRange(text.startIndex..<text.endIndex, in: text)
72+
if let match = regex.firstMatch(in: text, options: [], range: range) {
73+
if let formulaRange = Range(match.range(at: 1), in: text) {
74+
return String(text[formulaRange])
75+
}
76+
}
77+
78+
return nil
79+
}
80+
3781
internal func run(_ command: String, _ onProgress: @escaping (BrewCommandProgress) -> Void) async throws {
3882
var loggedMessages: [String] = []
3983

phpmon/Domain/SwiftUI/Common/BlockingOverlayView.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,12 @@ struct BlockingOverlayView<Content: View>: View {
3838
.bold()
3939
.foregroundColor(.primary)
4040
.padding(.top, 8)
41+
.multilineTextAlignment(.center)
4142
Text(detailText)
4243
.font(.system(size: 11))
4344
.foregroundColor(.primary)
4445
.padding(.top, -4)
46+
.multilineTextAlignment(.center)
4547
}.padding(60)
4648
}
4749
}

phpmon/en.lproj/Localizable.strings

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,11 +201,11 @@ You may be asked for your password during the uninstallation process if file per
201201
"phpman.operations.updating" = "Installing updates...";
202202
"phpman.operations.installing" = "Installing %@...";
203203

204-
"phpman.steps.fetching" = "Fetching...";
204+
"phpman.steps.fetching" = "Fetching some package metadata...";
205205
"phpman.steps.downloading" = "Downloading package data...";
206206
"phpman.steps.installing" = "Installing some package data...";
207207
"phpman.steps.pouring" = "Pouring... This can take a while...";
208-
"phpman.steps.summary" = "Some package has finished installing...";
208+
"phpman.steps.summary" = "Please wait a moment...";
209209

210210
"phpman.services.loading" = "Loading...";
211211
"phpman.services.not_installed" = "A key service is not installed.";

0 commit comments

Comments
 (0)