Skip to content

Commit ff61d8c

Browse files
🚀 Version 6.2.2
2 parents 8790b30 + da41673 commit ff61d8c

File tree

20 files changed

+969
-40
lines changed

20 files changed

+969
-40
lines changed

PHP Monitor.xcodeproj/project.pbxproj

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,7 @@
864864
/* End PBXContainerItemProxy section */
865865

866866
/* Begin PBXFileReference section */
867+
0336CAAF2B0D0CDA009A1034 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = "<group>"; };
867868
03E36FE628D9219000636F7F /* ActiveShell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveShell.swift; sourceTree = "<group>"; };
868869
5420395826135DC100FB00FA /* PreferencesVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesVC.swift; sourceTree = "<group>"; };
869870
5420395E2613607600FB00FA /* Preferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = "<group>"; };
@@ -2267,6 +2268,7 @@
22672268
de,
22682269
"pt-PT",
22692270
Base,
2271+
fr,
22702272
);
22712273
mainGroup = C41C1B2A22B0097F00E7CF16;
22722274
packageReferences = (
@@ -3247,6 +3249,7 @@
32473249
C4FC8D442A4981BC00FBBD16 /* nl */,
32483250
C4DD662A2A4A1B4E00D6A731 /* de */,
32493251
C4622F572A7593CB0016F8FB /* pt-PT */,
3252+
0336CAAF2B0D0CDA009A1034 /* fr */,
32503253
);
32513254
name = Localizable.strings;
32523255
sourceTree = "<group>";
@@ -3520,7 +3523,7 @@
35203523
CODE_SIGN_IDENTITY = "Apple Development";
35213524
CODE_SIGN_STYLE = Automatic;
35223525
COMBINE_HIDPI_IMAGES = YES;
3523-
CURRENT_PROJECT_VERSION = 1346;
3526+
CURRENT_PROJECT_VERSION = 1350;
35243527
DEAD_CODE_STRIPPING = YES;
35253528
DEBUG = YES;
35263529
DEVELOPMENT_TEAM = 8M54J5J787;
@@ -3533,7 +3536,7 @@
35333536
"@executable_path/../Frameworks",
35343537
);
35353538
MACOSX_DEPLOYMENT_TARGET = 12.4;
3536-
MARKETING_VERSION = 6.2.1;
3539+
MARKETING_VERSION = 6.2.2;
35373540
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon;
35383541
PRODUCT_MODULE_NAME = PHP_Monitor;
35393542
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -3551,7 +3554,7 @@
35513554
CODE_SIGN_IDENTITY = "Apple Development";
35523555
CODE_SIGN_STYLE = Automatic;
35533556
COMBINE_HIDPI_IMAGES = YES;
3554-
CURRENT_PROJECT_VERSION = 1346;
3557+
CURRENT_PROJECT_VERSION = 1350;
35553558
DEAD_CODE_STRIPPING = YES;
35563559
DEBUG = NO;
35573560
DEVELOPMENT_TEAM = 8M54J5J787;
@@ -3564,7 +3567,7 @@
35643567
"@executable_path/../Frameworks",
35653568
);
35663569
MACOSX_DEPLOYMENT_TARGET = 12.4;
3567-
MARKETING_VERSION = 6.2.1;
3570+
MARKETING_VERSION = 6.2.2;
35683571
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon;
35693572
PRODUCT_MODULE_NAME = PHP_Monitor;
35703573
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -3791,7 +3794,7 @@
37913794
CODE_SIGN_IDENTITY = "Apple Development";
37923795
CODE_SIGN_STYLE = Automatic;
37933796
COMBINE_HIDPI_IMAGES = YES;
3794-
CURRENT_PROJECT_VERSION = 1346;
3797+
CURRENT_PROJECT_VERSION = 1350;
37953798
DEAD_CODE_STRIPPING = YES;
37963799
DEBUG = NO;
37973800
DEVELOPMENT_TEAM = 8M54J5J787;
@@ -3804,7 +3807,7 @@
38043807
"@executable_path/../Frameworks",
38053808
);
38063809
MACOSX_DEPLOYMENT_TARGET = 12.4;
3807-
MARKETING_VERSION = 6.2.1;
3810+
MARKETING_VERSION = 6.2.2;
38083811
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.dev;
38093812
PRODUCT_MODULE_NAME = PHP_Monitor;
38103813
PRODUCT_NAME = "$(TARGET_NAME) DEV";
@@ -3907,7 +3910,7 @@
39073910
CODE_SIGN_IDENTITY = "Apple Development";
39083911
CODE_SIGN_STYLE = Automatic;
39093912
COMBINE_HIDPI_IMAGES = YES;
3910-
CURRENT_PROJECT_VERSION = 1346;
3913+
CURRENT_PROJECT_VERSION = 1350;
39113914
DEAD_CODE_STRIPPING = YES;
39123915
DEBUG = YES;
39133916
DEVELOPMENT_TEAM = 8M54J5J787;
@@ -3920,7 +3923,7 @@
39203923
"@executable_path/../Frameworks",
39213924
);
39223925
MACOSX_DEPLOYMENT_TARGET = 12.4;
3923-
MARKETING_VERSION = 6.2.1;
3926+
MARKETING_VERSION = 6.2.2;
39243927
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.dev;
39253928
PRODUCT_MODULE_NAME = PHP_Monitor;
39263929
PRODUCT_NAME = "$(TARGET_NAME) DEV";
@@ -4023,7 +4026,7 @@
40234026
CODE_SIGN_IDENTITY = "Apple Development";
40244027
CODE_SIGN_STYLE = Automatic;
40254028
COMBINE_HIDPI_IMAGES = YES;
4026-
CURRENT_PROJECT_VERSION = 1346;
4029+
CURRENT_PROJECT_VERSION = 1350;
40274030
DEAD_CODE_STRIPPING = YES;
40284031
DEBUG = YES;
40294032
DEVELOPMENT_TEAM = 8M54J5J787;
@@ -4036,7 +4039,7 @@
40364039
"@executable_path/../Frameworks",
40374040
);
40384041
MACOSX_DEPLOYMENT_TARGET = 12.4;
4039-
MARKETING_VERSION = 6.2.1;
4042+
MARKETING_VERSION = 6.2.2;
40404043
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.eap;
40414044
PRODUCT_MODULE_NAME = PHP_Monitor;
40424045
PRODUCT_NAME = "$(TARGET_NAME) EAP";
@@ -4204,7 +4207,7 @@
42044207
CODE_SIGN_IDENTITY = "Apple Development";
42054208
CODE_SIGN_STYLE = Automatic;
42064209
COMBINE_HIDPI_IMAGES = YES;
4207-
CURRENT_PROJECT_VERSION = 1346;
4210+
CURRENT_PROJECT_VERSION = 1350;
42084211
DEAD_CODE_STRIPPING = YES;
42094212
DEBUG = NO;
42104213
DEVELOPMENT_TEAM = 8M54J5J787;
@@ -4217,7 +4220,7 @@
42174220
"@executable_path/../Frameworks",
42184221
);
42194222
MACOSX_DEPLOYMENT_TARGET = 12.4;
4220-
MARKETING_VERSION = 6.2.1;
4223+
MARKETING_VERSION = 6.2.2;
42214224
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.eap;
42224225
PRODUCT_MODULE_NAME = PHP_Monitor;
42234226
PRODUCT_NAME = "$(TARGET_NAME) EAP";

phpmon/Common/PHP/PHP Version/PhpEnvironments.swift

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,36 @@ class PhpEnvironments {
2929
/**
3030
Determine which PHP version the `php` formula is aliased to.
3131
*/
32-
func determinePhpAlias() async {
32+
@MainActor func determinePhpAlias() async {
3333
let brewPhpAlias = await Shell.pipe("\(Paths.brew) info php --json").out
3434

3535
self.homebrewPackage = try! JSONDecoder().decode(
3636
[HomebrewPackage].self,
3737
from: brewPhpAlias.data(using: .utf8)!
3838
).first!
3939

40-
Log.info("[BREW] On your system, the `php` formula means version \(homebrewPackage.version)!")
40+
PhpEnvironments.brewPhpAlias = self.homebrewPackage.version
41+
Log.info("[BREW] On your system, the `php` formula means version \(homebrewPackage.version).")
42+
43+
// Check if that version actually corresponds to an older version
44+
let phpConfigExecutablePath = "\(Paths.optPath)/php/bin/php-config"
45+
if FileSystem.fileExists(phpConfigExecutablePath) {
46+
let longVersionString = Command.execute(
47+
path: phpConfigExecutablePath,
48+
arguments: ["--version"],
49+
trimNewlines: false
50+
).trimmingCharacters(in: .whitespacesAndNewlines)
51+
52+
if let version = try? VersionNumber.parse(longVersionString) {
53+
PhpEnvironments.brewPhpAlias = version.short
54+
if version.short != homebrewPackage.version {
55+
Log.info("[BREW] An older version of `php` is actually installed (\(version.short)).")
56+
}
57+
} else {
58+
Log.warn("Could not determine the actual version of the php binary; assuming Homebrew is correct.")
59+
PhpEnvironments.brewPhpAlias = homebrewPackage.version
60+
}
61+
}
4162
}
4263

4364
// MARK: - Properties
@@ -77,7 +98,12 @@ class PhpEnvironments {
7798

7899
As such, we take that information from Homebrew.
79100
*/
80-
static var brewPhpAlias: String {
101+
static var brewPhpAlias: String = ""
102+
103+
/**
104+
It's possible for the alias to be newer than the actual installed version of PHP.
105+
*/
106+
static var homebrewBrewPhpAlias: String {
81107
if PhpEnvironments.shared.homebrewPackage == nil { return "8.2" }
82108

83109
return PhpEnvironments.shared.homebrewPackage.version
@@ -144,7 +170,12 @@ class PhpEnvironments {
144170

145171
// Avoid inserting a duplicate
146172
if !supportedVersions.contains(phpAlias) && FileSystem.fileExists("\(Paths.optPath)/php/bin/php") {
147-
supportedVersions.insert(phpAlias)
173+
let phpAliasInstall = PhpInstallation(phpAlias)
174+
// Before inserting, ensure that the actual output matches the alias
175+
// if that isn't the case, our formula remains out-of-date
176+
if !phpAliasInstall.missingBinary {
177+
supportedVersions.insert(phpAlias)
178+
}
148179
}
149180

150181
availablePhpVersions = Array(supportedVersions)

phpmon/Common/PHP/PhpInstallation.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ class PhpInstallation {
1212

1313
var versionNumber: VersionNumber
1414

15+
var missingBinary: Bool = false
16+
1517
var isHealthy: Bool = true
1618

1719
/**
@@ -35,6 +37,10 @@ class PhpInstallation {
3537
// The parser should always work, or the string has to be very unusual.
3638
// If so, the app SHOULD crash, so that the users report what's up.
3739
self.versionNumber = try! VersionNumber.parse(longVersionString)
40+
} else {
41+
// Keep track that the `php-config` binary is missing; this often means there's a mismatch between
42+
// the `php` version alias and the actual installed version (e.g. you haven't upgraded `php`)
43+
missingBinary = true
3844
}
3945

4046
if FileSystem.fileExists(phpExecutablePath) {

phpmon/Common/Testables/TestableConfiguration.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ public struct TestableConfiguration: Codable {
6363
: .fake(.binary),
6464
"/opt/homebrew/Cellar/php/\(version.long)/bin/php-config"
6565
: .fake(.binary),
66-
"/opt/homebrew/etc/php/\(version.short)/php-fpm.d/www.conf"
67-
: .fake(.text),
66+
// "/opt/homebrew/etc/php/\(version.short)/php-fpm.d/www.conf"
67+
// : .fake(.text),
6868
"/opt/homebrew/etc/php/\(version.short)/php-fpm.d/valet-fpm.conf"
6969
: .fake(.text),
7070
"/opt/homebrew/etc/php/\(version.short)/php.ini"
@@ -94,7 +94,7 @@ public struct TestableConfiguration: Codable {
9494
/opt/homebrew/etc/php/\(version.short)/conf.d/php-memory-limits.ini,
9595
"""
9696
} else {
97-
97+
self.shellOutput["sudo /opt/homebrew/bin/brew services stop php@\(version.short)"] = .instant("")
9898
self.shellOutput["ls /opt/homebrew/opt | grep php@"] =
9999
BatchFakeShellOutput.instant(
100100
self.secondaryPhpVersions

phpmon/Domain/Integrations/Homebrew/Brew.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ class Brew {
4646
/// Each formula for each PHP version that can be installed.
4747
public static let phpVersionFormulae = [
4848
"8.4": "shivammathur/php/php@8.4",
49-
"8.3": "shivammathur/php/php@8.3", // TODO: when php@8.3 lands in stable, update this
49+
"8.3": "php@8.3",
5050
"8.2": "php@8.2",
5151
"8.1": "php@8.1",
52-
"8.0": "php@8.0",
52+
"8.0": "shivammathur/php/php@8.0",
5353
"7.4": "shivammathur/php/php@7.4",
5454
"7.3": "shivammathur/php/php@7.3",
5555
"7.2": "shivammathur/php/php@7.2",

phpmon/Domain/Integrations/Homebrew/BrewFormula.swift

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import Foundation
1010

11-
struct BrewFormula {
11+
struct BrewFormula: Equatable {
1212
/// Name of the formula.
1313
let name: String
1414

@@ -48,6 +48,25 @@ struct BrewFormula {
4848
return upgradeVersion != nil
4949
}
5050

51+
/// Whether this formula alias is different.
52+
var hasUpgradedFormulaAlias: Bool {
53+
return self.shortVersion == PhpEnvironments.homebrewBrewPhpAlias
54+
&& PhpEnvironments.homebrewBrewPhpAlias != PhpEnvironments.brewPhpAlias
55+
}
56+
57+
var unavailableAfterUpgrade: Bool {
58+
if installedVersion == nil || upgradeVersion == nil {
59+
return false
60+
}
61+
62+
if let installed = try? VersionNumber.parse(self.installedVersion!),
63+
let upgrade = try? VersionNumber.parse(self.upgradeVersion!) {
64+
return upgrade.short != installed.short
65+
}
66+
67+
return false
68+
}
69+
5170
/// The associated Homebrew folder with this PHP formula.
5271
var homebrewFolder: String {
5372
let resolved = name
@@ -60,7 +79,7 @@ struct BrewFormula {
6079
/// The short version associated with this formula, if installed.
6180
var shortVersion: String? {
6281
guard let version = self.installedVersion else {
63-
return nil
82+
return self.displayName.replacingOccurrences(of: "PHP ", with: "")
6483
}
6584

6685
return VersionNumber.make(from: version)?.short ?? nil

phpmon/Domain/Integrations/Homebrew/BrewFormulaeHandler.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ extension HandlesBrewFormulae {
1717
public func refreshPhpVersions(loadOutdated: Bool) async {
1818
let items = await loadPhpVersions(loadOutdated: loadOutdated)
1919
Task { @MainActor in
20+
await PhpEnvironments.shared.determinePhpAlias()
2021
Brew.shared.formulae.phpVersions = items
2122
}
2223
}
@@ -43,7 +44,8 @@ class BrewFormulaeHandler: HandlesBrewFormulae {
4344
}
4445

4546
return Brew.phpVersionFormulae.map { (version, formula) in
46-
let fullVersion = PhpEnvironments.shared.cachedPhpInstallations[version]?.versionNumber.text
47+
let fullVersion = PhpEnvironments.shared.cachedPhpInstallations[version]?
48+
.versionNumber.text
4749

4850
var upgradeVersion: String?
4951

@@ -53,13 +55,15 @@ class BrewFormulaeHandler: HandlesBrewFormulae {
5355
})?.current_version
5456
}
5557

56-
return BrewFormula(
58+
let formula = BrewFormula(
5759
name: formula,
5860
displayName: "PHP \(version)",
5961
installedVersion: fullVersion,
6062
upgradeVersion: upgradeVersion,
6163
prerelease: Constants.ExperimentalPhpVersions.contains(version)
6264
)
65+
66+
return formula
6367
}.sorted { $0.displayName > $1.displayName }
6468
}
6569
}

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

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,22 @@ class InstallAndUpgradeCommand: BrewCommand {
4141
description: "PHP Monitor is preparing Homebrew..."
4242
))
4343

44-
// Try to run all upgrade and installation operations
45-
try await self.upgradePackages(onProgress)
46-
try await self.installPackages(onProgress)
44+
let unavailable = upgrading.first(where: { formula in
45+
formula.unavailableAfterUpgrade
46+
})
47+
48+
// Make sure the tap is installed
49+
try await self.checkPhpTap(onProgress)
50+
51+
if unavailable == nil {
52+
// Try to run all upgrade and installation operations
53+
try await self.upgradePackages(onProgress)
54+
try await self.installPackages(onProgress)
55+
} else {
56+
// Simply upgrade `php` to the latest version
57+
try await self.upgradeMainPhpFormula(unavailable!, onProgress)
58+
await PhpEnvironments.shared.determinePhpAlias()
59+
}
4760

4861
// Re-check the installed versions
4962
await PhpEnvironments.detectPhpVersions()
@@ -55,6 +68,39 @@ class InstallAndUpgradeCommand: BrewCommand {
5568
await self.completedOperations(onProgress)
5669
}
5770

71+
private func upgradeMainPhpFormula(
72+
_ unavailable: BrewFormula,
73+
_ onProgress: @escaping (BrewCommandProgress) -> Void
74+
) async throws {
75+
// Determine which version was previously available (that will become unavailable)
76+
guard let short = try? VersionNumber
77+
.parse(unavailable.installedVersion!).short else {
78+
return
79+
}
80+
81+
// Upgrade the main formula
82+
let command = """
83+
export HOMEBREW_NO_INSTALL_CLEANUP=true; \
84+
\(Paths.brew) upgrade php;
85+
\(Paths.brew) install php@\(short);
86+
"""
87+
88+
// Run the upgrade command
89+
try await run(command, onProgress)
90+
}
91+
92+
private func checkPhpTap(_ onProgress: @escaping (BrewCommandProgress) -> Void) async throws {
93+
if !BrewDiagnostics.installedTaps.contains("shivammathur/php") {
94+
let command = "brew tap shivammathur/php"
95+
try await run(command, onProgress)
96+
}
97+
98+
if !BrewDiagnostics.installedTaps.contains("shivammathur/extensions") {
99+
let command = "brew tap shivammathur/extensions"
100+
try await run(command, onProgress)
101+
}
102+
}
103+
58104
private func upgradePackages(_ onProgress: @escaping (BrewCommandProgress) -> Void) async throws {
59105
// If no upgrades are needed, early exit
60106
if self.upgrading.isEmpty {

0 commit comments

Comments
 (0)