mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-08-07 20:10:08 +02:00
👌 Async / await support for loading services
This commit is contained in:
@ -31,7 +31,6 @@
|
|||||||
C40B24F127A3106D0018C7D2 /* ServicesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EC1E67279DE0540010F296 /* ServicesView.swift */; };
|
C40B24F127A3106D0018C7D2 /* ServicesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EC1E67279DE0540010F296 /* ServicesView.swift */; };
|
||||||
C40B24F227A310770018C7D2 /* Events.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EC1E72279DFCF40010F296 /* Events.swift */; };
|
C40B24F227A310770018C7D2 /* Events.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EC1E72279DFCF40010F296 /* Events.swift */; };
|
||||||
C40B24F427A310830018C7D2 /* StatusMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47331A1247093B7009A0597 /* StatusMenu.swift */; };
|
C40B24F427A310830018C7D2 /* StatusMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47331A1247093B7009A0597 /* StatusMenu.swift */; };
|
||||||
C40B24F527A3108B0018C7D2 /* Async.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EC1E6C279DF87A0010F296 /* Async.swift */; };
|
|
||||||
C40C7F1E2772136000DDDCDC /* PhpEnv.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40C7F1D2772136000DDDCDC /* PhpEnv.swift */; };
|
C40C7F1E2772136000DDDCDC /* PhpEnv.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40C7F1D2772136000DDDCDC /* PhpEnv.swift */; };
|
||||||
C40C7F1F2772136000DDDCDC /* PhpEnv.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40C7F1D2772136000DDDCDC /* PhpEnv.swift */; };
|
C40C7F1F2772136000DDDCDC /* PhpEnv.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40C7F1D2772136000DDDCDC /* PhpEnv.swift */; };
|
||||||
C40C7F2827721FF600DDDCDC /* ActivePhpInstallation+Checks.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40C7F2727721FF600DDDCDC /* ActivePhpInstallation+Checks.swift */; };
|
C40C7F2827721FF600DDDCDC /* ActivePhpInstallation+Checks.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40C7F2727721FF600DDDCDC /* ActivePhpInstallation+Checks.swift */; };
|
||||||
@ -149,7 +148,6 @@
|
|||||||
C4DEB7D427A5D60B00834718 /* Stats.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4DEB7D327A5D60B00834718 /* Stats.swift */; };
|
C4DEB7D427A5D60B00834718 /* Stats.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4DEB7D327A5D60B00834718 /* Stats.swift */; };
|
||||||
C4EC1E66279DE0380010F296 /* ServicesView.xib in Resources */ = {isa = PBXBuildFile; fileRef = C4EC1E65279DE0380010F296 /* ServicesView.xib */; };
|
C4EC1E66279DE0380010F296 /* ServicesView.xib in Resources */ = {isa = PBXBuildFile; fileRef = C4EC1E65279DE0380010F296 /* ServicesView.xib */; };
|
||||||
C4EC1E68279DE0540010F296 /* ServicesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EC1E67279DE0540010F296 /* ServicesView.swift */; };
|
C4EC1E68279DE0540010F296 /* ServicesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EC1E67279DE0540010F296 /* ServicesView.swift */; };
|
||||||
C4EC1E6D279DF87A0010F296 /* Async.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EC1E6C279DF87A0010F296 /* Async.swift */; };
|
|
||||||
C4EC1E73279DFCF40010F296 /* Events.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EC1E72279DFCF40010F296 /* Events.swift */; };
|
C4EC1E73279DFCF40010F296 /* Events.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EC1E72279DFCF40010F296 /* Events.swift */; };
|
||||||
C4EE188422D3386B00E126E5 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EE188322D3386B00E126E5 /* Constants.swift */; };
|
C4EE188422D3386B00E126E5 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EE188322D3386B00E126E5 /* Constants.swift */; };
|
||||||
C4EE55A927708B9E001DF387 /* PMHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EE55A627708B9E001DF387 /* PMHeaderView.swift */; };
|
C4EE55A927708B9E001DF387 /* PMHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EE55A627708B9E001DF387 /* PMHeaderView.swift */; };
|
||||||
@ -298,7 +296,6 @@
|
|||||||
C4E713572570151400007428 /* docs */ = {isa = PBXFileReference; lastKnownFileType = folder; path = docs; sourceTree = "<group>"; };
|
C4E713572570151400007428 /* docs */ = {isa = PBXFileReference; lastKnownFileType = folder; path = docs; sourceTree = "<group>"; };
|
||||||
C4EC1E65279DE0380010F296 /* ServicesView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ServicesView.xib; sourceTree = "<group>"; };
|
C4EC1E65279DE0380010F296 /* ServicesView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ServicesView.xib; sourceTree = "<group>"; };
|
||||||
C4EC1E67279DE0540010F296 /* ServicesView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ServicesView.swift; sourceTree = "<group>"; };
|
C4EC1E67279DE0540010F296 /* ServicesView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ServicesView.swift; sourceTree = "<group>"; };
|
||||||
C4EC1E6C279DF87A0010F296 /* Async.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Async.swift; sourceTree = "<group>"; };
|
|
||||||
C4EC1E72279DFCF40010F296 /* Events.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Events.swift; sourceTree = "<group>"; };
|
C4EC1E72279DFCF40010F296 /* Events.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Events.swift; sourceTree = "<group>"; };
|
||||||
C4EE188322D3386B00E126E5 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
|
C4EE188322D3386B00E126E5 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
|
||||||
C4EE55A627708B9E001DF387 /* PMHeaderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PMHeaderView.swift; sourceTree = "<group>"; };
|
C4EE55A627708B9E001DF387 /* PMHeaderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PMHeaderView.swift; sourceTree = "<group>"; };
|
||||||
@ -536,7 +533,6 @@
|
|||||||
C41C1B4822B00A9800E7CF16 /* MenuBarImageGenerator.swift */,
|
C41C1B4822B00A9800E7CF16 /* MenuBarImageGenerator.swift */,
|
||||||
C4CCBA6B275C567B008C7055 /* PMWindowController.swift */,
|
C4CCBA6B275C567B008C7055 /* PMWindowController.swift */,
|
||||||
C4B5635D276AB09000F12CCB /* VersionExtractor.swift */,
|
C4B5635D276AB09000F12CCB /* VersionExtractor.swift */,
|
||||||
C4EC1E6C279DF87A0010F296 /* Async.swift */,
|
|
||||||
);
|
);
|
||||||
path = Helpers;
|
path = Helpers;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -873,7 +869,6 @@
|
|||||||
C41C1B3722B0097F00E7CF16 /* AppDelegate.swift in Sources */,
|
C41C1B3722B0097F00E7CF16 /* AppDelegate.swift in Sources */,
|
||||||
C42759672627662800093CAE /* NSMenuExtension.swift in Sources */,
|
C42759672627662800093CAE /* NSMenuExtension.swift in Sources */,
|
||||||
C464ADAF275A7A69003FCD53 /* SiteListVC.swift in Sources */,
|
C464ADAF275A7A69003FCD53 /* SiteListVC.swift in Sources */,
|
||||||
C4EC1E6D279DF87A0010F296 /* Async.swift in Sources */,
|
|
||||||
C44CCD4927AFF3B700CE40E5 /* MainMenu+Async.swift in Sources */,
|
C44CCD4927AFF3B700CE40E5 /* MainMenu+Async.swift in Sources */,
|
||||||
C4EC1E73279DFCF40010F296 /* Events.swift in Sources */,
|
C4EC1E73279DFCF40010F296 /* Events.swift in Sources */,
|
||||||
C4927F0B27B2DFC200C55AFD /* Errors.swift in Sources */,
|
C4927F0B27B2DFC200C55AFD /* Errors.swift in Sources */,
|
||||||
@ -931,7 +926,6 @@
|
|||||||
C4AF9F7B2754499000D44ED0 /* Valet.swift in Sources */,
|
C4AF9F7B2754499000D44ED0 /* Valet.swift in Sources */,
|
||||||
C4F780C025D80B6E000DBC97 /* Startup.swift in Sources */,
|
C4F780C025D80B6E000DBC97 /* Startup.swift in Sources */,
|
||||||
C4CCBA6D275C567B008C7055 /* PMWindowController.swift in Sources */,
|
C4CCBA6D275C567B008C7055 /* PMWindowController.swift in Sources */,
|
||||||
C40B24F527A3108B0018C7D2 /* Async.swift in Sources */,
|
|
||||||
C4B5635F276AB09000F12CCB /* VersionExtractor.swift in Sources */,
|
C4B5635F276AB09000F12CCB /* VersionExtractor.swift in Sources */,
|
||||||
C4F2E4382752F08D0020E974 /* HomebrewDiagnostics.swift in Sources */,
|
C4F2E4382752F08D0020E974 /* HomebrewDiagnostics.swift in Sources */,
|
||||||
C4F780AE25D80B37000DBC97 /* ExtensionParserTest.swift in Sources */,
|
C4F780AE25D80B37000DBC97 /* ExtensionParserTest.swift in Sources */,
|
||||||
|
@ -35,7 +35,7 @@ func sed(file: String, original: String, replacement: String)
|
|||||||
|
|
||||||
// Check if gsed exists; it is able to follow symlinks,
|
// Check if gsed exists; it is able to follow symlinks,
|
||||||
// which we want to do to toggle the extension
|
// which we want to do to toggle the extension
|
||||||
if Shell.fileExists("\(Paths.binPath)/gsed") {
|
if Filesystem.fileExists("\(Paths.binPath)/gsed") {
|
||||||
Shell.run("\(Paths.binPath)/gsed -i --follow-symlinks 's/\(e_original)/\(e_replacement)/g' \(file)")
|
Shell.run("\(Paths.binPath)/gsed -i --follow-symlinks 's/\(e_original)/\(e_replacement)/g' \(file)")
|
||||||
} else {
|
} else {
|
||||||
Shell.run("sed -i '' 's/\(e_original)/\(e_replacement)/g' \(file)")
|
Shell.run("sed -i '' 's/\(e_original)/\(e_replacement)/g' \(file)")
|
||||||
|
@ -104,16 +104,6 @@ public class Shell {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Checks if a file exists at a certain path.
|
|
||||||
Used to be done with a shell command, now uses the native FileManager class instead.
|
|
||||||
*/
|
|
||||||
// TODO: To be moved
|
|
||||||
public static func fileExists(_ path: String) -> Bool {
|
|
||||||
let fullPath = path.replacingOccurrences(of: "~", with: "/Users/\(Paths.whoami)")
|
|
||||||
return FileManager.default.fileExists(atPath: fullPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Creates a new process with the correct PATH and shell.
|
Creates a new process with the correct PATH and shell.
|
||||||
*/
|
*/
|
||||||
|
@ -16,6 +16,10 @@ class Alert {
|
|||||||
secondButtonTitle: String = "",
|
secondButtonTitle: String = "",
|
||||||
style: NSAlert.Style = .informational
|
style: NSAlert.Style = .informational
|
||||||
) -> Bool {
|
) -> Bool {
|
||||||
|
if !Thread.isMainThread {
|
||||||
|
fatalError("You should always present alerts on the main thread!")
|
||||||
|
}
|
||||||
|
|
||||||
let alert = NSAlert.init()
|
let alert = NSAlert.init()
|
||||||
alert.alertStyle = style
|
alert.alertStyle = style
|
||||||
alert.messageText = messageText
|
alert.messageText = messageText
|
||||||
@ -36,6 +40,10 @@ class Alert {
|
|||||||
style: NSAlert.Style = .warning,
|
style: NSAlert.Style = .warning,
|
||||||
onFirstButtonPressed: @escaping (() -> Void)
|
onFirstButtonPressed: @escaping (() -> Void)
|
||||||
) {
|
) {
|
||||||
|
if !Thread.isMainThread {
|
||||||
|
fatalError("You should always present alerts on the main thread!")
|
||||||
|
}
|
||||||
|
|
||||||
let alert = NSAlert.init()
|
let alert = NSAlert.init()
|
||||||
alert.alertStyle = style
|
alert.alertStyle = style
|
||||||
alert.messageText = messageText
|
alert.messageText = messageText
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
//
|
|
||||||
// Async.swift
|
|
||||||
// PHP Monitor
|
|
||||||
//
|
|
||||||
// Created by Nico Verbruggen on 23/01/2022.
|
|
||||||
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
/**
|
|
||||||
This generic async helper is something I'd like to use in more places.
|
|
||||||
|
|
||||||
The `DispatchQueue.global` into `DispatchQueue.main.async` logic is common in the app.
|
|
||||||
|
|
||||||
I could also use try `async` support which was introduced in Swift but that would
|
|
||||||
require too much refactoring at this time to consider. I also need to read up on async
|
|
||||||
in order to properly grasp all the gotchas. Looking into that later at some point.
|
|
||||||
*/
|
|
||||||
public func runAsync(_ execute: @escaping () -> Void, completion: @escaping () -> Void = {})
|
|
||||||
{
|
|
||||||
DispatchQueue.global(qos: .userInitiated).async {
|
|
||||||
execute()
|
|
||||||
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
completion()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -137,7 +137,7 @@ class ActivePhpInstallation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Make sure to check if valet-fpm.conf exists. If it does, we should be fine :)
|
// Make sure to check if valet-fpm.conf exists. If it does, we should be fine :)
|
||||||
return Shell.fileExists("\(Paths.etcPath)/php/\(self.version.short)/php-fpm.d/valet-fpm.conf")
|
return Filesystem.fileExists("\(Paths.etcPath)/php/\(self.version.short)/php-fpm.d/valet-fpm.conf")
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Structs
|
// MARK: - Structs
|
||||||
|
@ -18,4 +18,18 @@ struct HomebrewService: Decodable, Equatable {
|
|||||||
let status: String?
|
let status: String?
|
||||||
let log_path: String?
|
let log_path: String?
|
||||||
let error_log_path: String?
|
let error_log_path: String?
|
||||||
|
|
||||||
|
public static func loadAll(
|
||||||
|
filter: [String] = [PhpEnv.phpInstall.formula, "nginx", "dnsmasq"]
|
||||||
|
) async -> [HomebrewService] {
|
||||||
|
return try! JSONDecoder().decode(
|
||||||
|
[HomebrewService].self,
|
||||||
|
from: Shell.pipe(
|
||||||
|
"sudo \(Paths.brew) services info --all --json",
|
||||||
|
requiresPath: true
|
||||||
|
).data(using: .utf8)!
|
||||||
|
).filter({ service in
|
||||||
|
return filter.contains(service.name)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ class PhpEnv {
|
|||||||
let phpAlias = homebrewPackage.version
|
let phpAlias = homebrewPackage.version
|
||||||
|
|
||||||
// Avoid inserting a duplicate
|
// Avoid inserting a duplicate
|
||||||
if (!versionsOnly.contains(phpAlias) && Shell.fileExists("\(Paths.optPath)/php/bin/php")) {
|
if (!versionsOnly.contains(phpAlias) && Filesystem.fileExists("\(Paths.optPath)/php/bin/php")) {
|
||||||
versionsOnly.append(phpAlias)
|
versionsOnly.append(phpAlias)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,7 +134,7 @@ class PhpEnv {
|
|||||||
// is supported and where the binary exists (avoids broken installs)
|
// is supported and where the binary exists (avoids broken installs)
|
||||||
if !output.contains(version)
|
if !output.contains(version)
|
||||||
&& Constants.SupportedPhpVersions.contains(version)
|
&& Constants.SupportedPhpVersions.contains(version)
|
||||||
&& (checkBinaries ? Shell.fileExists("\(Paths.optPath)/php@\(version)/bin/php") : true)
|
&& (checkBinaries ? Filesystem.fileExists("\(Paths.optPath)/php@\(version)/bin/php") : true)
|
||||||
{
|
{
|
||||||
output.append(version)
|
output.append(version)
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ public struct PhpVersionNumber: Equatable {
|
|||||||
case greaterThanOrEqual = #"^>=(?<major>\d+).(?<minor>\d+).?(?<patch>\d+)?\z"#
|
case greaterThanOrEqual = #"^>=(?<major>\d+).(?<minor>\d+).?(?<patch>\d+)?\z"#
|
||||||
case greaterThan = #"^>(?<major>\d+).(?<minor>\d+).?(?<patch>\d+)?\z"#
|
case greaterThan = #"^>(?<major>\d+).(?<minor>\d+).?(?<patch>\d+)?\z"#
|
||||||
|
|
||||||
// TODO: (5.1) Handle these cases (even though I suspect these are uncommon)
|
// TODO: (6.0) Handle these cases (even though I suspect these are uncommon)
|
||||||
/*
|
/*
|
||||||
case smallerThanOrEqual = #"^<=(?<major>\d+).(?<minor>\d+).?(?<patch>\d+)?\z"#
|
case smallerThanOrEqual = #"^<=(?<major>\d+).(?<minor>\d+).?(?<patch>\d+)?\z"#
|
||||||
case smallerThan = #"^<(?<major>\d+).(?<minor>\d+).?(?<patch>\d+)?\z"#
|
case smallerThan = #"^<(?<major>\d+).(?<minor>\d+).?(?<patch>\d+)?\z"#
|
||||||
|
@ -21,7 +21,7 @@ class PhpInstallation {
|
|||||||
let phpConfigExecutablePath = "\(Paths.optPath)/php@\(version)/bin/php-config"
|
let phpConfigExecutablePath = "\(Paths.optPath)/php@\(version)/bin/php-config"
|
||||||
self.longVersion = PhpVersionNumber.make(from: version)!
|
self.longVersion = PhpVersionNumber.make(from: version)!
|
||||||
|
|
||||||
if Shell.fileExists(phpConfigExecutablePath) {
|
if Filesystem.fileExists(phpConfigExecutablePath) {
|
||||||
let longVersionString = Command.execute(
|
let longVersionString = Command.execute(
|
||||||
path: phpConfigExecutablePath,
|
path: phpConfigExecutablePath,
|
||||||
arguments: ["--version"]
|
arguments: ["--version"]
|
||||||
@ -29,7 +29,6 @@ class PhpInstallation {
|
|||||||
|
|
||||||
// The parser should always work, or the string has to be very unusual.
|
// The parser should always work, or the string has to be very unusual.
|
||||||
// If so, the app SHOULD crash, so that the users report what's up.
|
// If so, the app SHOULD crash, so that the users report what's up.
|
||||||
// TODO: Alert the user that the version number could not be parsed.
|
|
||||||
self.longVersion = try! PhpVersionNumber.parse(longVersionString)
|
self.longVersion = try! PhpVersionNumber.parse(longVersionString)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,8 @@ class Startup {
|
|||||||
Checks the user's environment and checks if PHP Monitor can be used properly.
|
Checks the user's environment and checks if PHP Monitor can be used properly.
|
||||||
This checks if PHP is installed, Valet is running, the appropriate permissions are set, and more.
|
This checks if PHP is installed, Valet is running, the appropriate permissions are set, and more.
|
||||||
|
|
||||||
- Parameter success: Callback that is fired if the application can proceed with launch
|
If this method returns false, there was a failed check and an alert was displayed.
|
||||||
- Parameter failure: Callback that is fired if the application must retry launch
|
If this method returns true, then all checks succeeded and the app can continue.
|
||||||
*/
|
*/
|
||||||
func checkEnvironment() async -> Bool
|
func checkEnvironment() async -> Bool
|
||||||
{
|
{
|
||||||
@ -41,6 +41,11 @@ class Startup {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Displays an alert for a particular check. There are two types of alerts:
|
||||||
|
- ones that require an app restart, which prompt the user to exit the app
|
||||||
|
- ones that allow the app to continue, which allow the user to retry
|
||||||
|
*/
|
||||||
private func showAlert(for check: EnvironmentCheck) {
|
private func showAlert(for check: EnvironmentCheck) {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
if check.requiresAppRestart {
|
if check.requiresAppRestart {
|
||||||
@ -63,7 +68,7 @@ class Startup {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
Because the Switcher requires various environment guarantees, the switcher is only
|
Because the Switcher requires various environment guarantees, the switcher is only
|
||||||
initialized when it is done working.
|
initialized when it is done working. The switcher must be initialized on the main thread.
|
||||||
*/
|
*/
|
||||||
private func initializeSwitcher() {
|
private func initializeSwitcher() {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
@ -89,7 +94,7 @@ class Startup {
|
|||||||
requiresAppRestart: true
|
requiresAppRestart: true
|
||||||
),
|
),
|
||||||
EnvironmentCheck(
|
EnvironmentCheck(
|
||||||
command: { return !Shell.fileExists(Paths.php) },
|
command: { return !Filesystem.fileExists(Paths.php) },
|
||||||
name: "`\(Paths.php)` exists",
|
name: "`\(Paths.php)` exists",
|
||||||
titleText: "startup.errors.php_binary.title".localized,
|
titleText: "startup.errors.php_binary.title".localized,
|
||||||
descriptionText: "startup.errors.php_binary.desc".localized(
|
descriptionText: "startup.errors.php_binary.desc".localized(
|
||||||
@ -106,8 +111,8 @@ class Startup {
|
|||||||
),
|
),
|
||||||
EnvironmentCheck(
|
EnvironmentCheck(
|
||||||
command: {
|
command: {
|
||||||
return !(Shell.fileExists(Paths.valet)
|
return !(Filesystem.fileExists(Paths.valet)
|
||||||
|| Shell.fileExists("~/.composer/vendor/bin/valet"))
|
|| Filesystem.fileExists("~/.composer/vendor/bin/valet"))
|
||||||
},
|
},
|
||||||
name: "`valet` binary exists",
|
name: "`valet` binary exists",
|
||||||
titleText: "startup.errors.valet_executable.title".localized,
|
titleText: "startup.errors.valet_executable.title".localized,
|
||||||
|
@ -241,7 +241,7 @@ class Valet {
|
|||||||
- Note: The file is not validated, only its presence is checked.
|
- Note: The file is not validated, only its presence is checked.
|
||||||
*/
|
*/
|
||||||
public func determineSecured(_ tld: String) {
|
public func determineSecured(_ tld: String) {
|
||||||
secured = Shell.fileExists("~/.config/valet/Certificates/\(self.name!).\(tld).key")
|
secured = Filesystem.fileExists("~/.config/valet/Certificates/\(self.name!).\(tld).key")
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,7 +15,7 @@ extension MainMenu {
|
|||||||
This method should probably be broken up into several smaller methods at some point.
|
This method should probably be broken up into several smaller methods at some point.
|
||||||
*/
|
*/
|
||||||
func updateGlobalDependencies(notify: Bool, completion: @escaping (Bool) -> Void) {
|
func updateGlobalDependencies(notify: Bool, completion: @escaping (Bool) -> Void) {
|
||||||
if !Shell.fileExists("/usr/local/bin/composer") {
|
if !Filesystem.fileExists("/usr/local/bin/composer") {
|
||||||
Alert.notify(
|
Alert.notify(
|
||||||
message: "alert.composer_missing.title".localized,
|
message: "alert.composer_missing.title".localized,
|
||||||
info: "alert.composer_missing.info".localized
|
info: "alert.composer_missing.info".localized
|
||||||
|
@ -52,7 +52,7 @@ extension MainMenu {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func suggestFixMyValet(failed version: String) {
|
@MainActor private func suggestFixMyValet(failed version: String) {
|
||||||
let outcome = Alert.present(
|
let outcome = Alert.present(
|
||||||
messageText: "alert.php_switch_failed.title".localized(version),
|
messageText: "alert.php_switch_failed.title".localized(version),
|
||||||
informativeText: "alert.php_switch_failed.info".localized(version),
|
informativeText: "alert.php_switch_failed.info".localized(version),
|
||||||
|
@ -180,6 +180,7 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
asyncExecution {
|
asyncExecution {
|
||||||
try Actions.fixHomebrewPermissions()
|
try Actions.fixHomebrewPermissions()
|
||||||
} success: {
|
} success: {
|
||||||
@ -189,8 +190,9 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate
|
|||||||
style: .warning
|
style: .warning
|
||||||
)
|
)
|
||||||
} failure: { error in
|
} failure: { error in
|
||||||
Alert.notify(about: error as! HomebrewPermissionError)
|
await Alert.notify(about: error as! HomebrewPermissionError)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func restartPhpFpm() {
|
@objc func restartPhpFpm() {
|
||||||
|
@ -54,26 +54,12 @@ class ServicesView: NSView, XibLoadable {
|
|||||||
self.loadData()
|
self.loadData()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: (5.1) Move data fetching, caching & retrieval somewhere else
|
|
||||||
func loadData() {
|
func loadData() {
|
||||||
// Use stale data
|
|
||||||
self.applyAllInfoFieldsFromCachedValue()
|
self.applyAllInfoFieldsFromCachedValue()
|
||||||
|
|
||||||
// Re-fetch services
|
Task {
|
||||||
runAsync {
|
let services = await HomebrewService.loadAll()
|
||||||
let servicesList = try! JSONDecoder().decode(
|
ServicesView.services = Dictionary(uniqueKeysWithValues: services.map{ ($0.name, $0) })
|
||||||
[HomebrewService].self,
|
|
||||||
from: Shell.pipe(
|
|
||||||
"sudo \(Paths.brew) services info --all --json",
|
|
||||||
requiresPath: true
|
|
||||||
).data(using: .utf8)!
|
|
||||||
).filter({ service in
|
|
||||||
return [PhpEnv.phpInstall.formula, "nginx", "dnsmasq"].contains(service.name)
|
|
||||||
})
|
|
||||||
|
|
||||||
ServicesView.services = Dictionary(uniqueKeysWithValues: servicesList.map{ ($0.name, $0) })
|
|
||||||
} completion: {
|
|
||||||
// Use fresh data
|
|
||||||
self.applyAllInfoFieldsFromCachedValue()
|
self.applyAllInfoFieldsFromCachedValue()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user