mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-11-05 04:20:06 +01:00
✨ Add GUI to upgrade Valet
This commit is contained in:
@@ -36,6 +36,10 @@
|
||||
036C39122E5C8D42008DAEDF /* PackagistError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 036C390E2E5C8D3B008DAEDF /* PackagistError.swift */; };
|
||||
036C39142E5CB822008DAEDF /* TestBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 036C39132E5CB820008DAEDF /* TestBundle.swift */; };
|
||||
036C3A212E5CBBAA008DAEDF /* ValetConfigurationTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AF9F76275447F100D44ED0 /* ValetConfigurationTest.swift */; };
|
||||
039E1D792E5F0F300072D13D /* ValetUpgrader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 039E1D782E5F0F2C0072D13D /* ValetUpgrader.swift */; };
|
||||
039E1D7A2E5F0F300072D13D /* ValetUpgrader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 039E1D782E5F0F2C0072D13D /* ValetUpgrader.swift */; };
|
||||
039E1D7B2E5F0F300072D13D /* ValetUpgrader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 039E1D782E5F0F2C0072D13D /* ValetUpgrader.swift */; };
|
||||
039E1D7C2E5F0F300072D13D /* ValetUpgrader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 039E1D782E5F0F2C0072D13D /* ValetUpgrader.swift */; };
|
||||
03BFF5272E312C3D007F96FA /* Startup+Timers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03BFF5262E312C39007F96FA /* Startup+Timers.swift */; };
|
||||
03BFF5282E312C3D007F96FA /* Startup+Timers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03BFF5262E312C39007F96FA /* Startup+Timers.swift */; };
|
||||
03BFF5292E312C3D007F96FA /* Startup+Timers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03BFF5262E312C39007F96FA /* Startup+Timers.swift */; };
|
||||
@@ -955,6 +959,7 @@
|
||||
036C39092E5C8CBD008DAEDF /* PackagistP2Response.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PackagistP2Response.swift; sourceTree = "<group>"; };
|
||||
036C390E2E5C8D3B008DAEDF /* PackagistError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PackagistError.swift; sourceTree = "<group>"; };
|
||||
036C39132E5CB820008DAEDF /* TestBundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestBundle.swift; sourceTree = "<group>"; };
|
||||
039E1D782E5F0F2C0072D13D /* ValetUpgrader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValetUpgrader.swift; sourceTree = "<group>"; };
|
||||
03BFF5262E312C39007F96FA /* Startup+Timers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Startup+Timers.swift"; sourceTree = "<group>"; };
|
||||
03BFF52B2E313240007F96FA /* StatusMenu+Driver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "StatusMenu+Driver.swift"; sourceTree = "<group>"; };
|
||||
03CC1FE42E3D220F0050FC18 /* InstallHomebrew.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstallHomebrew.swift; sourceTree = "<group>"; };
|
||||
@@ -1297,6 +1302,7 @@
|
||||
036C38FB2E5C8827008DAEDF /* Packagist */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
039E1D782E5F0F2C0072D13D /* ValetUpgrader.swift */,
|
||||
036C39012E5C883A008DAEDF /* Packagist.swift */,
|
||||
036C390E2E5C8D3B008DAEDF /* PackagistError.swift */,
|
||||
036C39092E5C8CBD008DAEDF /* PackagistP2Response.swift */,
|
||||
@@ -2777,6 +2783,7 @@
|
||||
C4B79EB629CA387F00A483EE /* BrewPhpFormulaeHandler.swift in Sources */,
|
||||
C476FF9822B0DD830098105B /* Alert.swift in Sources */,
|
||||
033D45A32B0D531D00070080 /* PhpExtensionManagerView+Actions.swift in Sources */,
|
||||
039E1D7C2E5F0F300072D13D /* ValetUpgrader.swift in Sources */,
|
||||
C474B00624C0E98C00066A22 /* LocalNotification.swift in Sources */,
|
||||
036C390D2E5C8CC5008DAEDF /* PackagistP2Response.swift in Sources */,
|
||||
C4D5CFCA27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */,
|
||||
@@ -2829,6 +2836,7 @@
|
||||
C471E82D28F9BB650021E251 /* AlertableError.swift in Sources */,
|
||||
C471E82E28F9BB650021E251 /* Errors.swift in Sources */,
|
||||
C471E82F28F9BB650021E251 /* Alert.swift in Sources */,
|
||||
039E1D7A2E5F0F300072D13D /* ValetUpgrader.swift in Sources */,
|
||||
C4FD87A929AB9ABD0002D701 /* PhpConfigChecker.swift in Sources */,
|
||||
C471E83028F9BB650021E251 /* Application.swift in Sources */,
|
||||
C471E83128F9BB650021E251 /* LocalNotification.swift in Sources */,
|
||||
@@ -3179,6 +3187,7 @@
|
||||
C471E7CF28F9BA600021E251 /* ActiveShell.swift in Sources */,
|
||||
C4BB393C2981AFC700F8E797 /* PhpVersionSource.swift in Sources */,
|
||||
C471E7F628F9BAC80021E251 /* PhpHelper.swift in Sources */,
|
||||
039E1D7B2E5F0F300072D13D /* ValetUpgrader.swift in Sources */,
|
||||
C471E7EE28F9BAC30021E251 /* Constants.swift in Sources */,
|
||||
C40934A0298EE8E900D25014 /* AppUpdater.swift in Sources */,
|
||||
C4611E5A2AEAD2E20010BE24 /* ConfigManagerWindowController.swift in Sources */,
|
||||
@@ -3373,6 +3382,7 @@
|
||||
C4E49DEE28F764A00026AC4E /* TestableCommand.swift in Sources */,
|
||||
C4611E612AEAD3110010BE24 /* ByteLimitView.swift in Sources */,
|
||||
C40175B92903108900763A68 /* ValetInteractor.swift in Sources */,
|
||||
039E1D792E5F0F300072D13D /* ValetUpgrader.swift in Sources */,
|
||||
C4CE3BBC27B324250086CA49 /* ComposerWindow.swift in Sources */,
|
||||
C40B24F427A310830018C7D2 /* StatusMenu.swift in Sources */,
|
||||
C417DC75277614690015E6EE /* Helpers.swift in Sources */,
|
||||
|
||||
86
phpmon/Domain/Integrations/Packagist/ValetUpgrader.swift
Normal file
86
phpmon/Domain/Integrations/Packagist/ValetUpgrader.swift
Normal file
@@ -0,0 +1,86 @@
|
||||
//
|
||||
// ValetUpgrader.swift
|
||||
// PHP Monitor
|
||||
//
|
||||
// Created by Nico Verbruggen on 27/08/2025.
|
||||
// Copyright © 2025 Nico Verbruggen. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import NVAlert
|
||||
|
||||
class ValetUpgrader {
|
||||
private static func getGlobalComposerJson() -> ComposerJson? {
|
||||
let path = "~/.composer/composer.json".replacingTildeWithHomeDirectory
|
||||
|
||||
do {
|
||||
if FileSystem.fileExists(path) {
|
||||
return try JSONDecoder().decode(
|
||||
ComposerJson.self,
|
||||
from: String(
|
||||
contentsOf: URL(fileURLWithPath: path),
|
||||
encoding: .utf8
|
||||
).data(using: .utf8)!
|
||||
)
|
||||
} else {
|
||||
Log.err("The global Composer file is missing. This should, uh, not happen!")
|
||||
return nil
|
||||
}
|
||||
} catch {
|
||||
Log.err("Something went wrong reading the Composer JSON file.")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
public static func showUpgradeAlert() {
|
||||
var valetConstraint: String = "unknown"
|
||||
var constraintCheckPassed: Bool?
|
||||
|
||||
if let json = getGlobalComposerJson(), let dependencies = json.dependencies {
|
||||
if dependencies.keys.contains("laravel/valet") {
|
||||
valetConstraint = dependencies["laravel/valet"]!
|
||||
}
|
||||
}
|
||||
|
||||
guard let latest = Valet.shared.latestVersion else {
|
||||
return Log.err("The latest version is unknown. This should, uh, not happen!")
|
||||
}
|
||||
|
||||
if valetConstraint != "unknown" {
|
||||
// Do a constraint check
|
||||
constraintCheckPassed = !PhpVersionNumberCollection(versions: [latest])
|
||||
.matching(constraint: valetConstraint).isEmpty
|
||||
}
|
||||
|
||||
notifyAboutUpgrade(
|
||||
latest: latest.text,
|
||||
constraint: valetConstraint,
|
||||
passing: constraintCheckPassed ?? false
|
||||
)
|
||||
}
|
||||
|
||||
private static func notifyAboutUpgrade(latest: String, constraint: String, passing: Bool) {
|
||||
Task { @MainActor in
|
||||
let alert = NVAlert().withInformation(
|
||||
title: "valet_upgrade_available.title".localized,
|
||||
subtitle: "valet_upgrade_available.subtitle".localized(latest),
|
||||
description: passing
|
||||
? "valet_upgrade_available.description_constraint_ok".localized(latest)
|
||||
: "valet_upgrade_available.description_constraint_fail".localized(constraint, latest)
|
||||
)
|
||||
.withPrimary(text: "valet_upgrade_available.upgrade".localized, action: { vc in
|
||||
vc.close(with: .OK)
|
||||
MainMenu.shared.updateGlobalComposerDependencies()
|
||||
})
|
||||
.withSecondary(text: "valet_upgrade_available.cancel".localized)
|
||||
|
||||
if !passing {
|
||||
_ = alert.withTertiary(text: "valet_upgrade_available.open_composer".localized, action: { _ in
|
||||
MainMenu.shared.openGlobalComposerFolder()
|
||||
})
|
||||
}
|
||||
|
||||
alert.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -219,7 +219,7 @@ class Valet {
|
||||
let latestVersion = try? await Packagist.getLatestStableVersion(packageName: "laravel/valet") {
|
||||
self.latestVersion = latestVersion
|
||||
|
||||
if latestVersion.isNewerThan(currentVersion, false) {
|
||||
if latestVersion.isNewerThan(currentVersion) {
|
||||
Log.info("The latest version of Valet is \(latestVersion.text); current is \(currentVersion.text).")
|
||||
|
||||
// Update the menu so this update is visible.
|
||||
|
||||
@@ -137,6 +137,10 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate
|
||||
}
|
||||
}
|
||||
|
||||
@objc func showValetUpgradeAvailableAlert() {
|
||||
ValetUpgrader.showUpgradeAlert()
|
||||
}
|
||||
|
||||
/** Reloads the menu in the background, using `asyncExecution`. */
|
||||
@objc func reloadPhpMonitorMenuInBackground() {
|
||||
asyncExecution({
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
import NVAlert
|
||||
|
||||
extension StatusMenu {
|
||||
@MainActor func addLiteModeMenuItem() {
|
||||
@@ -18,11 +19,23 @@ extension StatusMenu {
|
||||
|
||||
@MainActor func addValetVersionItem() {
|
||||
if let version = Valet.shared.version {
|
||||
addItems([
|
||||
var items = [
|
||||
NSMenuItem.separator(),
|
||||
NSMenuItem(title: "mi_driver".localized("Valet \(version.text)"),
|
||||
action: nil, customImage: "ValetDriverIcon")
|
||||
])
|
||||
]
|
||||
|
||||
if let latest = Valet.shared.latestVersion {
|
||||
if latest.isNewerThan(version) {
|
||||
items.append(
|
||||
NSMenuItem(title: "mi_valet_upgrade_action".localized(latest.text),
|
||||
action: #selector(MainMenu.showValetUpgradeAvailableAlert),
|
||||
systemImage: "arrow.up.square.fill")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
addItems(items)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,6 +72,9 @@
|
||||
"mi_quit" = "Quit PHP Monitor";
|
||||
"mi_about" = "About PHP Monitor";
|
||||
|
||||
"mi_valet_upgrade_available" = "An updated version of Valet is available.";
|
||||
"mi_valet_upgrade_action" = "Upgrade to Valet %@...";
|
||||
|
||||
"mi_presets_title" = "Configuration Presets";
|
||||
"mi_apply_presets_title" = "Apply Configuration Presets";
|
||||
"mi_revert_to_prev_config" = "Revert to Previous Configuration...";
|
||||
@@ -467,8 +470,8 @@ This has no effect on other terminals, only for the particular terminal session
|
||||
"prefs.warn_about_non_standard_tld_desc" = "If you use a non-standard TLD, you may not wish to get repeated notifications about this.";
|
||||
"prefs.warn_about_non_standard_tld" = "Warn about non-standard TLD";
|
||||
|
||||
"prefs.display_driver_desc" = "If disabled, you will not be able to see which driver is in use. If Valet is active, the version number will also no longer be visible.";
|
||||
"prefs.display_driver" = "App Driver";
|
||||
"prefs.display_driver_desc" = "If disabled, you will not be able to see which driver is in use. If Valet is active, the version number will also no longer be visible, and you will not be notified about updates to Valet in the menu.";
|
||||
"prefs.display_driver" = "Driver & Updates";
|
||||
|
||||
"prefs.display_global_version_switcher_desc" = "If disabled, you will not be able to change the globally linked PHP version via the main menu.";
|
||||
"prefs.display_global_version_switcher" = "PHP Switcher";
|
||||
@@ -891,3 +894,17 @@ Please note that some features (greyed out below) are currently unavailable beca
|
||||
It is recommended to restart PHP Monitor afterwards. Learn more about this issue at: https://github.com/nicoverbruggen/phpmon/issues/294.
|
||||
|
||||
If PHP Monitor has finished initializing anyway or you want to wait a bit longer, feel free to click 'Ignore' and use PHP Monitor as usual. Either way, you may want to investigate, because this isn't supposed to take this long.";
|
||||
|
||||
// VALET UPGRADES
|
||||
|
||||
"valet_upgrade_available.title" = "Do you want to upgrade Valet to the latest compatible version?";
|
||||
"valet_upgrade_available.subtitle" = "Laravel Valet %@ is available. PHP Monitor can update your global Composer dependencies for you.";
|
||||
"valet_upgrade_available.description_constraint_ok" = "Given your global Composer setup, the latest version that will be installed should be the very latest, Laravel Valet %@.";
|
||||
"valet_upgrade_available.description_constraint_fail" = "Please note that given your global Composer setup, the latest version that can be automatically installed WILL NOT be latest version available. This is due to constraints in your global `composer.json` file.
|
||||
|
||||
Your version constraint for Valet is: `%@`, which prohibits the installation of Valet %@.
|
||||
|
||||
If you want to make edits to this file, please do so before upgrading. When you see this message, you should probably check Valet's release notes, as Valet's requirements may have changed.";
|
||||
"valet_upgrade_available.upgrade" = "Upgrade";
|
||||
"valet_upgrade_available.cancel" = "Cancel";
|
||||
"valet_upgrade_available.open_composer" = "Locate `composer.json`";
|
||||
|
||||
Reference in New Issue
Block a user