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

♻️ Big Cleanup

This commit is contained in:
2022-02-08 23:07:23 +01:00
parent 7cd50aed7b
commit 9fabda545f
10 changed files with 297 additions and 218 deletions

View File

@ -136,6 +136,8 @@
C4C8E81C276F54E5003AC782 /* PhpConfigWatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E81A276F54E5003AC782 /* PhpConfigWatcher.swift */; }; C4C8E81C276F54E5003AC782 /* PhpConfigWatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E81A276F54E5003AC782 /* PhpConfigWatcher.swift */; };
C4CCBA6C275C567B008C7055 /* PMWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CCBA6B275C567B008C7055 /* PMWindowController.swift */; }; C4CCBA6C275C567B008C7055 /* PMWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CCBA6B275C567B008C7055 /* PMWindowController.swift */; };
C4CCBA6D275C567B008C7055 /* PMWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CCBA6B275C567B008C7055 /* PMWindowController.swift */; }; C4CCBA6D275C567B008C7055 /* PMWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CCBA6B275C567B008C7055 /* PMWindowController.swift */; };
C4CE3BB827B31F2E0086CA49 /* MainMenu+Switcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CE3BB727B31F2E0086CA49 /* MainMenu+Switcher.swift */; };
C4CE3BBA27B31F670086CA49 /* MainMenu+Composer.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CE3BB927B31F670086CA49 /* MainMenu+Composer.swift */; };
C4D8016622B1584700C6DA1B /* Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D8016522B1584700C6DA1B /* Startup.swift */; }; C4D8016622B1584700C6DA1B /* Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D8016522B1584700C6DA1B /* Startup.swift */; };
C4D89BC62783C99400A02B68 /* ComposerJson.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D89BC52783C99400A02B68 /* ComposerJson.swift */; }; C4D89BC62783C99400A02B68 /* ComposerJson.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D89BC52783C99400A02B68 /* ComposerJson.swift */; };
C4D9ADBF277610E1007277F4 /* PhpSwitcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D9ADBE277610E1007277F4 /* PhpSwitcher.swift */; }; C4D9ADBF277610E1007277F4 /* PhpSwitcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D9ADBE277610E1007277F4 /* PhpSwitcher.swift */; };
@ -283,6 +285,8 @@
C4C8E817276F54D8003AC782 /* App+ConfigWatch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "App+ConfigWatch.swift"; sourceTree = "<group>"; }; C4C8E817276F54D8003AC782 /* App+ConfigWatch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "App+ConfigWatch.swift"; sourceTree = "<group>"; };
C4C8E81A276F54E5003AC782 /* PhpConfigWatcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhpConfigWatcher.swift; sourceTree = "<group>"; }; C4C8E81A276F54E5003AC782 /* PhpConfigWatcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhpConfigWatcher.swift; sourceTree = "<group>"; };
C4CCBA6B275C567B008C7055 /* PMWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PMWindowController.swift; sourceTree = "<group>"; }; C4CCBA6B275C567B008C7055 /* PMWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PMWindowController.swift; sourceTree = "<group>"; };
C4CE3BB727B31F2E0086CA49 /* MainMenu+Switcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MainMenu+Switcher.swift"; sourceTree = "<group>"; };
C4CE3BB927B31F670086CA49 /* MainMenu+Composer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MainMenu+Composer.swift"; sourceTree = "<group>"; };
C4D8016522B1584700C6DA1B /* Startup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Startup.swift; sourceTree = "<group>"; }; C4D8016522B1584700C6DA1B /* Startup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Startup.swift; sourceTree = "<group>"; };
C4D89BC52783C99400A02B68 /* ComposerJson.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerJson.swift; sourceTree = "<group>"; }; C4D89BC52783C99400A02B68 /* ComposerJson.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerJson.swift; sourceTree = "<group>"; };
C4D9ADBE277610E1007277F4 /* PhpSwitcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpSwitcher.swift; sourceTree = "<group>"; }; C4D9ADBE277610E1007277F4 /* PhpSwitcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpSwitcher.swift; sourceTree = "<group>"; };
@ -509,6 +513,8 @@
C4811D2922D70F9A00B5F6B3 /* MainMenu.swift */, C4811D2922D70F9A00B5F6B3 /* MainMenu.swift */,
C44CCD4827AFF3B700CE40E5 /* MainMenu+Async.swift */, C44CCD4827AFF3B700CE40E5 /* MainMenu+Async.swift */,
C4C3ED402783497000AB15D8 /* MainMenu+Startup.swift */, C4C3ED402783497000AB15D8 /* MainMenu+Startup.swift */,
C4CE3BB727B31F2E0086CA49 /* MainMenu+Switcher.swift */,
C4CE3BB927B31F670086CA49 /* MainMenu+Composer.swift */,
C47331A1247093B7009A0597 /* StatusMenu.swift */, C47331A1247093B7009A0597 /* StatusMenu.swift */,
C48D0C9525CC80B100CC7490 /* HeaderView.swift */, C48D0C9525CC80B100CC7490 /* HeaderView.swift */,
C48D0C9925CC888B00CC7490 /* HeaderView.xib */, C48D0C9925CC888B00CC7490 /* HeaderView.xib */,
@ -847,6 +853,7 @@
C4C3ED4327834C5200AB15D8 /* CustomPrefs.swift in Sources */, C4C3ED4327834C5200AB15D8 /* CustomPrefs.swift in Sources */,
54B48B5F275F66AE006D90C5 /* Application.swift in Sources */, 54B48B5F275F66AE006D90C5 /* Application.swift in Sources */,
C4B97B78275CF1B5003F3378 /* App+ActivationPolicy.swift in Sources */, C4B97B78275CF1B5003F3378 /* App+ActivationPolicy.swift in Sources */,
C4CE3BB827B31F2E0086CA49 /* MainMenu+Switcher.swift in Sources */,
C415937F27A1B54F00D2E1B7 /* PhpFrameworks.swift in Sources */, C415937F27A1B54F00D2E1B7 /* PhpFrameworks.swift in Sources */,
C4811D2422D70A4700B5F6B3 /* App.swift in Sources */, C4811D2422D70A4700B5F6B3 /* App.swift in Sources */,
C41C1B4922B00A9800E7CF16 /* MenuBarImageGenerator.swift in Sources */, C41C1B4922B00A9800E7CF16 /* MenuBarImageGenerator.swift in Sources */,
@ -880,6 +887,7 @@
C476FF9822B0DD830098105B /* Alert.swift in Sources */, C476FF9822B0DD830098105B /* Alert.swift in Sources */,
C474B00624C0E98C00066A22 /* LocalNotification.swift in Sources */, C474B00624C0E98C00066A22 /* LocalNotification.swift in Sources */,
C48D0C9625CC80B100CC7490 /* HeaderView.swift in Sources */, C48D0C9625CC80B100CC7490 /* HeaderView.swift in Sources */,
C4CE3BBA27B31F670086CA49 /* MainMenu+Composer.swift in Sources */,
C4D9ADC8277611A0007277F4 /* InternalSwitcher.swift in Sources */, C4D9ADC8277611A0007277F4 /* InternalSwitcher.swift in Sources */,
C4B5635E276AB09000F12CCB /* VersionExtractor.swift in Sources */, C4B5635E276AB09000F12CCB /* VersionExtractor.swift in Sources */,
C47331A2247093B7009A0597 /* StatusMenu.swift in Sources */, C47331A2247093B7009A0597 /* StatusMenu.swift in Sources */,

View File

@ -8,11 +8,6 @@
import Foundation import Foundation
protocol PhpSwitcherDelegate: AnyObject {
func switcherDidStartSwitching()
func switcherDidCompleteSwitch()
}
class PhpEnv { class PhpEnv {
// MARK: - Initializer // MARK: - Initializer

View File

@ -8,6 +8,14 @@
import Foundation import Foundation
protocol PhpSwitcherDelegate: AnyObject {
func switcherDidStartSwitching(to: String)
func switcherDidCompleteSwitch(to: String)
}
protocol PhpSwitcher { protocol PhpSwitcher {
func performSwitch(to version: String, completion: @escaping () -> Void) func performSwitch(to version: String, completion: @escaping () -> Void)

View File

@ -8,7 +8,7 @@
import Cocoa import Cocoa
import HotKey import HotKey
class App: PhpSwitcherDelegate { class App {
// MARK: Static Vars // MARK: Static Vars
@ -73,20 +73,4 @@ class App: PhpSwitcherDelegate {
The `PhpConfigWatcher` is responsible for watching the `.ini` files and the `.conf.d` folder. The `PhpConfigWatcher` is responsible for watching the `.ini` files and the `.conf.d` folder.
*/ */
var watcher: PhpConfigWatcher! var watcher: PhpConfigWatcher!
// MARK: - PhpSwitcherDelegate
func switcherDidStartSwitching() {
}
func switcherDidCompleteSwitch() {
PhpEnv.shared.currentInstall = ActivePhpInstallation()
handlePhpConfigWatcher()
if let window = siteListWindowController {
DispatchQueue.main.async {
window.contentVC.reloadSites()
}
}
}
} }

View File

@ -45,12 +45,16 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
let valet: Valet let valet: Valet
/** /**
The PhpSwitcher singleton that handles PHP version The PhpEnv singleton that handles PHP version
detection, as well as switching. It is initialized detection, as well as switching. It is initialized
when the app is ready and passed all checks. when the app is ready and passed all checks.
*/ */
var switcher: PhpEnv! = nil var phpEnvironment: PhpEnv! = nil
/**
The logger is responsible for different levels of logging.
You can tweak the verbosity in the `init` method here.
*/
var logger = Log.shared var logger = Log.shared
// MARK: - Initializer // MARK: - Initializer
@ -59,7 +63,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
When the application initializes, create all singletons. When the application initializes, create all singletons.
*/ */
override init() { override init() {
logger.verbosity = .performance logger.verbosity = .info
Log.info("==================================") Log.info("==================================")
Log.info("PHP MONITOR by Nico Verbruggen") Log.info("PHP MONITOR by Nico Verbruggen")
Log.info("Version \(App.version)") Log.info("Version \(App.version)")
@ -73,8 +77,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
} }
func initializeSwitcher() { func initializeSwitcher() {
self.switcher = PhpEnv.shared self.phpEnvironment = PhpEnv.shared
self.switcher.delegate = self.state
} }
// MARK: - Lifecycle // MARK: - Lifecycle

View File

@ -0,0 +1,98 @@
//
// MainMenu+Composer.swift
// PHP Monitor
//
// Created by Nico Verbruggen on 08/02/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
//
import Foundation
extension MainMenu {
/**
Updates the global dependencies and runs the completion callback when done.
This method should probably be broken up into several smaller methods at some point.
*/
func updateGlobalDependencies(notify: Bool, completion: @escaping (Bool) -> Void) {
if !Shell.fileExists("/usr/local/bin/composer") {
Alert.notify(
message: "alert.composer_missing.title".localized,
info: "alert.composer_missing.info".localized
)
return
}
PhpEnv.shared.isBusy = true
setBusyImage()
self.rebuild()
let noLongerBusy = {
PhpEnv.shared.isBusy = false
DispatchQueue.main.async { [self] in
self.updatePhpVersionInStatusBar()
self.rebuild()
}
}
var window: ProgressWindowController? = ProgressWindowController.display(
title: "alert.composer_progress.title".localized,
description: "alert.composer_progress.info".localized
)
window?.setType(info: true)
DispatchQueue.global(qos: .userInitiated).async {
let task = Shell.user.createTask(
for: "/usr/local/bin/composer global update", requiresPath: true
)
DispatchQueue.main.async {
window?.addToConsole("/usr/local/bin/composer global update\n")
}
Shell.captureOutput(
task,
didReceiveStdOutData: { string in
DispatchQueue.main.async {
window?.addToConsole(string)
}
Log.perf("\(string.trimmingCharacters(in: .newlines))")
},
didReceiveStdErrData: { string in
DispatchQueue.main.async {
window?.addToConsole(string)
}
Log.perf("\(string.trimmingCharacters(in: .newlines))")
}
)
task.launch()
task.waitUntilExit()
Shell.haltCapturingOutput(task)
DispatchQueue.main.async {
if task.terminationStatus <= 0 {
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
window?.close()
if (notify) {
LocalNotification.send(
title: "alert.composer_success.title".localized,
subtitle: "alert.composer_success.info".localized
)
}
window = nil
noLongerBusy()
completion(true)
}
} else {
window?.setType(info: false)
window?.progressView?.labelTitle.stringValue = "alert.composer_failure.title".localized
window?.progressView?.labelDescription.stringValue = "alert.composer_failure.info".localized
window = nil
noLongerBusy()
completion(false)
}
}
}
}
}

View File

@ -0,0 +1,84 @@
//
// MainMenu+PhpSwitcherDelegate.swift
// PHP Monitor
//
// Created by Nico Verbruggen on 08/02/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
//
import Foundation
extension MainMenu {
// MARK: - PhpSwitcherDelegate
func switcherDidStartSwitching(to version: String) {}
func switcherDidCompleteSwitch(to version: String) {
// Update the PHP version
PhpEnv.shared.currentInstall = ActivePhpInstallation()
// Ensure the config watcher gets reloaded
App.shared.handlePhpConfigWatcher()
// Mark as no longer busy
PhpEnv.shared.isBusy = false
// Reload the site list
self.reloadSiteListData()
// Perform UI updates on main thread
DispatchQueue.main.async { [self] in
updatePhpVersionInStatusBar()
rebuild()
if !PhpEnv.shared.validate(version) {
self.suggestFixMyValet(failed: version)
return
}
// Run composer updates
if Preferences.isEnabled(.autoComposerGlobalUpdateAfterSwitch) {
self.updateGlobalDependencies(notify: false, completion: { _ in
self.notifyAboutVersionChange(to: version)
})
} else {
self.notifyAboutVersionChange(to: version)
}
// Update stats
Stats.incrementSuccessfulSwitchCount()
Stats.evaluateSponsorMessageShouldBeDisplayed()
}
}
private func suggestFixMyValet(failed version: String) {
let outcome = Alert.present(
messageText: "alert.php_switch_failed.title".localized(version),
informativeText: "alert.php_switch_failed.info".localized(version),
buttonTitle: "alert.php_switch_failed.confirm".localized,
secondButtonTitle: "alert.php_switch_failed.cancel".localized, style: .informational)
if outcome {
MainMenu.shared.fixMyValet()
}
}
private func reloadSiteListData() {
if let window = App.shared.siteListWindowController {
DispatchQueue.main.async {
window.contentVC.reloadSites()
}
} else {
Valet.shared.reloadSites()
}
}
private func notifyAboutVersionChange(to version: String) {
LocalNotification.send(
title: String(format: "notification.version_changed_title".localized, version),
subtitle: String(format: "notification.version_changed_desc".localized, version)
)
PhpEnv.phpInstall.notifyAboutBrokenPhpFpm()
}
}

View File

@ -7,7 +7,7 @@
import Cocoa import Cocoa
class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate { class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate {
static let shared = MainMenu() static let shared = MainMenu()
@ -23,12 +23,28 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate {
// MARK: - UI related // MARK: - UI related
/** /**
Update the menu's contents, based on what's going on. Rebuilds the menu (either asynchronously or synchronously).
This will rebuild the entire menu, so this can take a few moments. Defaults to rebuilding the menu asynchronously.
*/ */
func rebuild() { func rebuild(async: Bool = true) {
if !async {
self.rebuildMenu()
return
}
// Update the menu item on the main thread // Update the menu item on the main thread
DispatchQueue.main.async { [self] in DispatchQueue.main.async { [self] in
self.rebuildMenu()
}
}
/**
Update the menu's contents, based on what's going on.
This will rebuild the entire menu, so this can take a few moments.
Use `rebuild(async:)` to ensure the rebuilding happens in the background.
*/
private func rebuildMenu() {
// Create a new menu // Create a new menu
let menu = StatusMenu() let menu = StatusMenu()
@ -61,7 +77,6 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate {
statusItem.menu = menu statusItem.menu = menu
statusItem.menu?.delegate = self statusItem.menu?.delegate = self
} }
}
/** /**
Sets the status bar image based on a version string. Sets the status bar image based on a version string.
@ -87,6 +102,7 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate {
// MARK: - User Interface // MARK: - User Interface
/** Reloads which PHP versions is currently active. */
@objc func refreshActiveInstallation() { @objc func refreshActiveInstallation() {
if !PhpEnv.shared.isBusy { if !PhpEnv.shared.isBusy {
PhpEnv.shared.currentInstall = ActivePhpInstallation() PhpEnv.shared.currentInstall = ActivePhpInstallation()
@ -96,12 +112,38 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate {
} }
} }
/** Updates the icon (refresh icon) and rebuilds the menu. */
@objc func updatePhpVersionInStatusBar() { @objc func updatePhpVersionInStatusBar() {
refreshIcon() refreshIcon()
rebuild() rebuild()
} }
func refreshIcon() { /**
Reloads the menu in the foreground.
This mimics the exact behaviours of `asyncExecution` as set in the method below.
*/
@objc func reloadPhpMonitorMenuInForeground() {
refreshActiveInstallation()
refreshIcon()
rebuild(async: false)
NotificationCenter.default.post(name: Events.ServicesUpdated, object: nil)
}
/** Reloads the menu in the background, using `asyncExecution`. */
@objc func reloadPhpMonitorMenuInBackground() {
asyncExecution({
// This automatically reloads the menu
Log.info("Reloading information about the PHP installation (in the background)...")
}, behaviours: [
.setsBusyUI,
.reloadsPhpInstallation,
.broadcastServicesUpdate,
.updatesMenuBarContents
])
}
/** Refreshes the icon with the PHP version. */
@objc func refreshIcon() {
DispatchQueue.main.async { [self] in DispatchQueue.main.async { [self] in
if (App.busy) { if (App.busy) {
setStatusBar(image: NSImage(named: NSImage.Name("StatusBarIcon"))!) setStatusBar(image: NSImage(named: NSImage.Name("StatusBarIcon"))!)
@ -118,20 +160,7 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate {
} }
} }
@objc func reloadPhpMonitorMenuInBackground() { /** Updates the icon to be displayed as busy. */
asyncExecution {
// This automatically reloads the menu
Log.info("Reloading information about the PHP installation (in the background)...")
}
}
@objc func reloadPhpMonitorMenu() {
asyncExecution {
// This automatically reloads the menu
Log.info("Reloading information about the PHP installation...")
}
}
@objc func setBusyImage() { @objc func setBusyImage() {
DispatchQueue.main.async { [self] in DispatchQueue.main.async { [self] in
setStatusBar(image: NSImage(named: NSImage.Name("StatusBarIcon"))!) setStatusBar(image: NSImage(named: NSImage.Name("StatusBarIcon"))!)
@ -282,66 +311,23 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate {
@objc func switchToPhpVersion(_ version: String) { @objc func switchToPhpVersion(_ version: String) {
setBusyImage() setBusyImage()
PhpEnv.shared.isBusy = true PhpEnv.shared.isBusy = true
PhpEnv.shared.delegate = self
PhpEnv.shared.delegate?.switcherDidStartSwitching(to: version)
DispatchQueue.global(qos: .userInitiated).async { [unowned self] in DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
// Update the PHP version in the status bar
updatePhpVersionInStatusBar()
// Update the menu
rebuild()
let sendLocalNotification = {
LocalNotification.send(
title: String(format: "notification.version_changed_title".localized, version),
subtitle: String(format: "notification.version_changed_desc".localized, version)
)
PhpEnv.phpInstall.notifyAboutBrokenPhpFpm()
}
let completion = {
// Fire off the delegate method
PhpEnv.shared.delegate?.switcherDidCompleteSwitch()
// Mark as no longer busy
PhpEnv.shared.isBusy = false
// Perform UI updates on main thread
DispatchQueue.main.async { [self] in
updatePhpVersionInStatusBar() updatePhpVersionInStatusBar()
rebuild() rebuild()
if !PhpEnv.shared.validate(version) {
let outcome = Alert.present(
messageText: "alert.php_switch_failed.title".localized(version),
informativeText: "alert.php_switch_failed.info".localized(version),
buttonTitle: "alert.php_switch_failed.confirm".localized,
secondButtonTitle: "alert.php_switch_failed.cancel".localized, style: .informational)
if outcome {
MainMenu.shared.fixMyValet()
}
return
}
// Run composer updates
if Preferences.isEnabled(.autoComposerGlobalUpdateAfterSwitch) {
self.updateGlobalDependencies(notify: false, completion: { _ in sendLocalNotification() })
} else {
sendLocalNotification()
}
// Update stats
Stats.incrementSuccessfulSwitchCount()
Stats.evaluateSponsorMessageShouldBeDisplayed()
}
}
PhpEnv.switcher.performSwitch( PhpEnv.switcher.performSwitch(
to: version, to: version,
completion: completion completion: {
PhpEnv.shared.delegate?.switcherDidCompleteSwitch(to: version)
}
) )
} }
} }
// MARK: - Menu Item Functionality
@objc func openAbout() { @objc func openAbout() {
NSApplication.shared.activate(ignoringOtherApps: true) NSApplication.shared.activate(ignoringOtherApps: true)
NSApplication.shared.orderFrontStandardAboutPanel() NSApplication.shared.orderFrontStandardAboutPanel()
@ -374,91 +360,4 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate {
// When the menu is closed, allow the shortcut to work again // When the menu is closed, allow the shortcut to work again
App.shared.shortcutHotkey?.isPaused = false App.shared.shortcutHotkey?.isPaused = false
} }
// MARK: - Private Methods
/**
Updates the global dependencies and runs the completion callback when done.
*/
private func updateGlobalDependencies(notify: Bool, completion: @escaping (Bool) -> Void) {
if !Shell.fileExists("/usr/local/bin/composer") {
Alert.notify(
message: "alert.composer_missing.title".localized,
info: "alert.composer_missing.info".localized
)
return
}
PhpEnv.shared.isBusy = true
setBusyImage()
self.rebuild()
let noLongerBusy = {
PhpEnv.shared.isBusy = false
DispatchQueue.main.async { [self] in
self.updatePhpVersionInStatusBar()
self.rebuild()
}
}
var window: ProgressWindowController? = ProgressWindowController.display(
title: "alert.composer_progress.title".localized,
description: "alert.composer_progress.info".localized
)
window?.setType(info: true)
DispatchQueue.global(qos: .userInitiated).async {
let task = Shell.user.createTask(
for: "/usr/local/bin/composer global update", requiresPath: true
)
DispatchQueue.main.async {
window?.addToConsole("/usr/local/bin/composer global update\n")
}
Shell.captureOutput(
task,
didReceiveStdOutData: { string in
DispatchQueue.main.async {
window?.addToConsole(string)
}
Log.perf("\(string.trimmingCharacters(in: .newlines))")
},
didReceiveStdErrData: { string in
DispatchQueue.main.async {
window?.addToConsole(string)
}
Log.perf("\(string.trimmingCharacters(in: .newlines))")
}
)
task.launch()
task.waitUntilExit()
Shell.haltCapturingOutput(task)
DispatchQueue.main.async {
if task.terminationStatus <= 0 {
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
window?.close()
if (notify) {
LocalNotification.send(
title: "alert.composer_success.title".localized,
subtitle: "alert.composer_success.info".localized
)
}
window = nil
noLongerBusy()
completion(true)
}
} else {
window?.setType(info: false)
window?.progressView?.labelTitle.stringValue = "alert.composer_failure.title".localized
window?.progressView?.labelDescription.stringValue = "alert.composer_failure.info".localized
window = nil
noLongerBusy()
completion(false)
}
}
}
}
} }

View File

@ -132,7 +132,7 @@ class StatusMenu : NSMenu {
servicesMenu.addItem(NSMenuItem.separator()) servicesMenu.addItem(NSMenuItem.separator())
servicesMenu.addItem(HeaderView.asMenuItem(text: "mi_manual_actions".localized)) servicesMenu.addItem(HeaderView.asMenuItem(text: "mi_manual_actions".localized))
servicesMenu.addItem(NSMenuItem(title: "mi_php_refresh".localized, action: #selector(MainMenu.reloadPhpMonitorMenu), keyEquivalent: "r")) servicesMenu.addItem(NSMenuItem(title: "mi_php_refresh".localized, action: #selector(MainMenu.reloadPhpMonitorMenuInForeground), keyEquivalent: "r"))
for item in servicesMenu.items { for item in servicesMenu.items {
item.target = MainMenu.shared item.target = MainMenu.shared

View File

@ -40,8 +40,8 @@ class PhpConfigWatcher {
self.addWatcher(for: self.url.appendingPathComponent("conf.d/\(file)"), eventMask: .write) self.addWatcher(for: self.url.appendingPathComponent("conf.d/\(file)"), eventMask: .write)
} }
Log.info("A watcher exists for the following config paths:") Log.perf("A watcher exists for the following config paths:")
Log.info(self.watchers.map({ watcher in Log.perf(self.watchers.map({ watcher in
return watcher.url.relativePath return watcher.url.relativePath
})) }))
} }
@ -57,7 +57,7 @@ class PhpConfigWatcher {
} }
func disable() { func disable() {
Log.info("Turning off existing watchers...") Log.perf("Turning off all individual existing watchers...")
self.watchers.forEach { (watcher) in self.watchers.forEach { (watcher) in
watcher.stopMonitoring() watcher.stopMonitoring()
} }