1
0
mirror of https://github.com/nicoverbruggen/phpmon.git synced 2025-08-08 04:20:07 +02:00

Compare commits

...

6 Commits

Author SHA1 Message Date
21a1d6576e 🔧 Bump build 2023-02-10 19:36:42 +01:00
b08912ce11 Add support for wildcard constraints (#224) 2023-02-10 19:31:07 +01:00
7285d24ef3 👌 Improve first launch onboarding experience 2023-02-07 22:02:34 +01:00
ac60c66bb9 🐛 Add missing strings for update 2023-02-06 19:33:41 +01:00
9a7575790a 🔧 Bump build 2023-02-06 19:12:34 +01:00
cd5cbccb04 🐛 Fix generated script (#231) 2023-02-06 19:10:10 +01:00
10 changed files with 120 additions and 30 deletions

View File

@ -2857,7 +2857,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1060;
CURRENT_PROJECT_VERSION = 1064;
DEAD_CODE_STRIPPING = YES;
DEBUG = YES;
DEVELOPMENT_TEAM = 8M54J5J787;
@ -2886,7 +2886,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1060;
CURRENT_PROJECT_VERSION = 1064;
DEAD_CODE_STRIPPING = YES;
DEBUG = NO;
DEVELOPMENT_TEAM = 8M54J5J787;
@ -3114,7 +3114,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1060;
CURRENT_PROJECT_VERSION = 1064;
DEBUG = NO;
DEVELOPMENT_TEAM = 8M54J5J787;
ENABLE_HARDENED_RUNTIME = YES;
@ -3224,7 +3224,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1060;
CURRENT_PROJECT_VERSION = 1064;
DEBUG = YES;
DEVELOPMENT_TEAM = 8M54J5J787;
ENABLE_HARDENED_RUNTIME = YES;

View File

@ -13,21 +13,21 @@ class Actions {
// MARK: - Services
public static func restartPhpFpm() async {
await brew("services restart \(Homebrew.Formulae.php.name)", sudo: Homebrew.Formulae.php.elevated)
await brew("services restart \(Homebrew.Formulae.php)", sudo: Homebrew.Formulae.php.elevated)
}
public static func restartNginx() async {
await brew("services restart \(Homebrew.Formulae.nginx.name)", sudo: Homebrew.Formulae.nginx.elevated)
await brew("services restart \(Homebrew.Formulae.nginx)", sudo: Homebrew.Formulae.nginx.elevated)
}
public static func restartDnsMasq() async {
await brew("services restart \(Homebrew.Formulae.dnsmasq.name)", sudo: Homebrew.Formulae.dnsmasq.elevated)
await brew("services restart \(Homebrew.Formulae.dnsmasq)", sudo: Homebrew.Formulae.dnsmasq.elevated)
}
public static func stopValetServices() async {
await brew("services stop \(Homebrew.Formulae.php.name)", sudo: Homebrew.Formulae.php.elevated)
await brew("services stop \(Homebrew.Formulae.nginx.name)", sudo: Homebrew.Formulae.nginx.elevated)
await brew("services stop \(Homebrew.Formulae.dnsmasq.name)", sudo: Homebrew.Formulae.dnsmasq.elevated)
await brew("services stop \(Homebrew.Formulae.php)", sudo: Homebrew.Formulae.php.elevated)
await brew("services stop \(Homebrew.Formulae.nginx)", sudo: Homebrew.Formulae.nginx.elevated)
await brew("services stop \(Homebrew.Formulae.dnsmasq)", sudo: Homebrew.Formulae.dnsmasq.elevated)
}
public static func fixHomebrewPermissions() throws {
@ -54,9 +54,10 @@ class Actions {
+ " && "
+ cellarCommands.joined(separator: " && ")
let appleScript = NSAppleScript(
source: "do shell script \"\(script)\" with administrator privileges"
)
let source = "do shell script \"\(script)\" with administrator privileges"
Log.perf(source)
let appleScript = NSAppleScript(source: source)
let eventResult: NSAppleEventDescriptor? = appleScript?.executeAndReturnError(nil)

View File

@ -36,10 +36,14 @@ class Homebrew {
}
}
class HomebrewFormula: Equatable, Hashable {
class HomebrewFormula: Equatable, Hashable, CustomStringConvertible {
let name: String
let elevated: Bool
var description: String {
return name
}
init(_ name: String, elevated: Bool = true) {
self.name = name
self.elevated = elevated

View File

@ -35,6 +35,7 @@ public struct PhpVersionNumberCollection: Equatable {
- Parameter strict: Whether the patch version check is strict. See more below.
The strict mode does not matter if a patch version is provided for all versions in the collection.
It also does not matter for certain comparisons (e.g. when dealing with wildcards).
Strict mode assumes that any PHP version lacking precise patch information, e.g. inferred
from Homebrew corresponds to the .0 patch version of that version. The default, which is imprecise,
@ -45,6 +46,7 @@ public struct PhpVersionNumberCollection: Equatable {
Given versions 8.0.? and 8.1.?, but the requirement is ^8.0.1, in strict mode only 8.1.? will
be considered valid (8.0 translates to 8.0.0 and as such is older than 8.0.1, 8.1.0 is OK).
When checking against actual PHP versions installed by the user (with patch precision), use
strict mode.
@ -52,11 +54,26 @@ public struct PhpVersionNumberCollection: Equatable {
Given versions 8.0.? and 8.1.?, but the requirement is ^8.0.1, in non-strict mode version 8.0
is assumed to be equal to version 8.0.999, which is actually fine if 8.0.1 is the required version.
In non-strict mode, the patch version is ignored for regular version checks (no caret / tilde).
If checking compatibility with general Homebrew versions of PHP, do NOT use strict mode, since
the patch version there is not used. (The formula php@8.0 suffices for ^8.0.1.)
*/
public func matching(constraint: String, strict: Bool = false) -> [VersionNumber] {
if constraint == "*" {
return self.versions
}
if let version = VersionNumber.make(from: constraint, type: .wildCardPatch) {
// Wildcard for patch (e.g. "7.4.*") must match major and minor (any patch)
return self.versions.filter { $0.hasSameMajorAndMinor(version) }
}
if let version = VersionNumber.make(from: constraint, type: .wildCardMinor) {
// Strict constraint (e.g. "7.*") -> must only match major (any patch, minor)
return self.versions.filter { $0.isSameMajorVersionAs(version) }
}
if let version = VersionNumber.make(from: constraint, type: .versionOnly) {
// Strict constraint (e.g. "7.0") -> returns specific version
return self.versions.filter { $0.isSameAs(version, strict) }

View File

@ -39,6 +39,8 @@ public struct VersionNumber: Equatable, Hashable {
public enum MatchType: String {
case versionOnly = #"^(?<major>\d+).(?<minor>\d+).?(?<patch>\d+)?\z"#
case wildCardPatch = #"^(?<major>\d+).(?<minor>\d+).?(?<patch>\*)?\z"#
case wildCardMinor = #"^(?<major>\d+).(?<minor>\*)?\z"#
case caretVersionRange = #"^\^(?<major>\d+).(?<minor>\d+).?(?<patch>\d+)?\z"#
case tildeVersionRange = #"^~(?<major>\d+).(?<minor>\d+).?(?<patch>\d+)?\z"#
case greaterThanOrEqual = #"^>=(?<major>\d+).(?<minor>\d+).?(?<patch>\d+)?\z"#
@ -64,21 +66,25 @@ public struct VersionNumber: Equatable, Hashable {
range: NSRange(location: 0, length: versionString.count)
).first
if match != nil {
let major = Int(
versionString[Range(match!.range(withName: "major"), in: versionString)!]
)!
let minor = Int(
versionString[Range(match!.range(withName: "minor"), in: versionString)!]
)!
var patch: Int?
if let minorRange = Range(match!.range(withName: "patch"), in: versionString) {
patch = Int(versionString[minorRange])
}
return Self(major: major, minor: minor, patch: patch)
guard let match else { return nil }
let major = Int(versionString[Range(match.range(withName: "major"), in: versionString)!])!
var minor: Int = 0
var patch: Int?
if let minorRange = Range(match.range(withName: "minor"), in: versionString) {
let value = versionString[minorRange] as String
// Zero is the fallback if a wildcard was used
minor = Int(value) ?? 0
}
return nil
if let patchRange = Range(match.range(withName: "patch"), in: versionString) {
let value = versionString[patchRange] as String
// nil is the fallback if a wildcard was used
patch = Int(value) ?? nil
}
return Self(major: major, minor: minor, patch: patch)
}
// MARK: Comparison Logic
@ -93,6 +99,10 @@ public struct VersionNumber: Equatable, Hashable {
&& (strict ? self.patch(strict, version) == version.patch(strict) : true)
}
internal func hasSameMajorAndMinor(_ version: VersionNumber) -> Bool {
return self.major == version.major && self.minor == version.minor
}
internal func isNewerThan(_ version: VersionNumber, _ strict: Bool) -> Bool {
return (
self.major > version.major ||

View File

@ -22,7 +22,6 @@ class InternalSwitcher: PhpSwitcher {
*/
func performSwitch(to version: String) async {
Log.info("Switching to \(version), unlinking all versions...")
let versions = getVersionsToBeHandled(version)
await withTaskGroup(of: String.self, body: { group in

View File

@ -110,9 +110,9 @@ extension MainMenu {
Task { @MainActor in
OnboardingWindowController.show()
}
} else {
await AppUpdater().checkForUpdates(interactive: false)
}
await AppUpdater().checkForUpdates(interactive: false)
}
// Check if the linked version has changed between launches of phpmon

View File

@ -42,4 +42,13 @@ class OnboardingWindowController: PMWindowController {
NSApp.activate(ignoringOtherApps: true)
}
override func close() {
super.close()
// Search for updates after closing the window
if Stats.successfulLaunchCount == 1 {
Task { await AppUpdater().checkForUpdates(interactive: false) }
}
}
}

View File

@ -355,6 +355,9 @@ This has no effect on other terminals, only for the particular terminal session
"notification.preset_reverted_title" = "Preset reverted";
"notification.preset_reverted_desc" = "The last preset you applied has been undone. Your previous configuration is now active.";
"notification.phpmon_updated.title" = "PHP Monitor has been updated!";
"notification.phpmon_updated.desc" = "You are now running PHP Monitor v%@.";
// Composer Update
"alert.composer_missing.title" = "Composer not found!";
"alert.composer_missing.subtitle" = "PHP Monitor could not find Composer. Make sure that Composer is installed and try again.";

View File

@ -44,6 +44,53 @@ class PhpVersionNumberTest: XCTestCase {
}
}
func test_can_parse_wildcard() throws {
let version = VersionNumber.make(from: "7.*", type: .wildCardMinor)
XCTAssertNotNil(version)
XCTAssertEqual(version!.major, 7)
XCTAssertEqual(version!.minor, 0)
}
func test_can_check_wildcard_version_constraint() throws {
// Wildcard for patch only
XCTAssertEqual(
PhpVersionNumberCollection
.make(from: ["7.4.10", "7.3.10", "7.3.9"])
.matching(constraint: "7.3.*", strict: false),
PhpVersionNumberCollection
.make(from: ["7.3.10", "7.3.9"]).all
)
// Wildcard for minor
XCTAssertEqual(
PhpVersionNumberCollection
.make(from: ["8.0.0", "7.4.10", "7.3.10", "7.3.9"])
.matching(constraint: "7.*", strict: false),
PhpVersionNumberCollection
.make(from: ["7.4.10", "7.3.10", "7.3.9"]).all
)
// Full wildcard
XCTAssertEqual(
PhpVersionNumberCollection
.make(from: ["7.4.10", "7.3.10", "7.2.10", "7.1.10", "7.0.10"])
.matching(constraint: "*", strict: false),
PhpVersionNumberCollection
.make(from: ["7.4.10", "7.3.10", "7.2.10", "7.1.10", "7.0.10"]).all
)
}
func test_can_check_any_version_constraint() throws {
XCTAssertEqual(
PhpVersionNumberCollection
.make(from: ["7.4.10", "7.3.10", "7.2.10", "7.1.10", "7.0.10"])
.matching(constraint: "*", strict: false),
PhpVersionNumberCollection
.make(from: ["7.4.10", "7.3.10", "7.2.10", "7.1.10", "7.0.10"]).all
)
}
func test_can_check_fixed_constraints() throws {
XCTAssertEqual(
PhpVersionNumberCollection