mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-08-07 12:00:09 +02:00
👌 Path based on architecture (#134)
This commit is contained in:
@ -231,8 +231,15 @@ Since v3.4 all of the loaded .ini files are sourced to determine which extension
|
||||
<details>
|
||||
<summary><strong>I've got two Homebrew installations on my Apple Silicon Mac, can I choose which installation to use with PHP Monitor?</strong></summary>
|
||||
|
||||
Not at this time, no. PHP Monitor will prefer the `/opt/homebrew` installation over the classic installation directory.
|
||||
If you are using PHP Monitor on an Intel machine or on an Apple Silicon machine with Rosetta enabled, PHP Monitor expects the main Homebrew binary in `/usr/local/bin/brew`.
|
||||
|
||||
If you are using PHP Monitor on Apple Silicon without Rosetta, PHP Monitor expects the main Homebrew binary in `/opt/homebrew/bin/brew`.
|
||||
|
||||
If there's an issue here, you'll get an alert at launch.
|
||||
|
||||
Make sure that the version of Homebrew that you are running normally is the same as the one that PHP Monitor expects. If you are on M1 hardware for example, but still using Rosetta for Homebrew, you'll need to run PHP Monitor under Rosetta as well.
|
||||
|
||||
PHP Monitor is a universal app and supports both architectures, so [find out here](https://support.apple.com/en-us/HT211861) how to enable Rosetta with PHP Monitor.
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
@ -15,15 +15,15 @@ public class Paths {
|
||||
|
||||
public static let shared = Paths()
|
||||
|
||||
private var baseDir : Paths.HomebrewDir
|
||||
internal var baseDir : Paths.HomebrewDir
|
||||
|
||||
private var userName : String
|
||||
|
||||
init() {
|
||||
baseDir = FileManager.default.fileExists(atPath: "\(HomebrewDir.opt.rawValue)/bin/brew") ? .opt : .usr
|
||||
baseDir = App.architecture != "x86_64" ? .opt : .usr
|
||||
userName = String(Shell.pipe("whoami").split(separator: "\n")[0])
|
||||
}
|
||||
|
||||
|
||||
// - MARK: Binaries
|
||||
|
||||
public static var valet: String {
|
||||
|
@ -22,6 +22,20 @@ class App {
|
||||
return "\(version) (\(build))"
|
||||
}
|
||||
|
||||
static var architecture: String {
|
||||
var systeminfo = utsname()
|
||||
uname(&systeminfo)
|
||||
let machine = withUnsafeBytes(of: &systeminfo.machine) {bufPtr->String in
|
||||
let data = Data(bufPtr)
|
||||
if let lastIndex = data.lastIndex(where: {$0 != 0}) {
|
||||
return String(data: data[0...lastIndex], encoding: .isoLatin1)!
|
||||
} else {
|
||||
return String(data: data, encoding: .isoLatin1)!
|
||||
}
|
||||
}
|
||||
return machine
|
||||
}
|
||||
|
||||
/** Whether the app is busy doing something. Used to determine what UI to display. */
|
||||
// TODO: Remove this, and always use PhpEnv.shared.isBusy
|
||||
static var busy: Bool {
|
||||
|
@ -10,7 +10,7 @@ import AppKit
|
||||
|
||||
class Startup {
|
||||
|
||||
public var failed : Bool = false
|
||||
public var failed: Bool = false
|
||||
public var failureCallback = {}
|
||||
|
||||
/**
|
||||
@ -27,40 +27,34 @@ class Startup {
|
||||
performEnvironmentCheck(
|
||||
!Shell.fileExists("\(Paths.binPath)/php"),
|
||||
messageText: "startup.errors.php_binary.title".localized,
|
||||
informativeText: "startup.errors.php_binary.desc".localized,
|
||||
breaking: true
|
||||
informativeText: "startup.errors.php_binary.desc".localized
|
||||
)
|
||||
|
||||
performEnvironmentCheck(
|
||||
!Shell.pipe("ls \(Paths.optPath) | grep php").contains("php"),
|
||||
messageText: "startup.errors.php_opt.title".localized,
|
||||
informativeText: "startup.errors.php_opt.desc".localized,
|
||||
breaking: true
|
||||
informativeText: "startup.errors.php_opt.desc".localized
|
||||
)
|
||||
|
||||
performEnvironmentCheck(
|
||||
// Check for Valet; it can be symlinked or in .composer/vendor/bin
|
||||
!(Shell.fileExists("/usr/local/bin/valet")
|
||||
|| Shell.fileExists("/opt/homebrew/bin/valet")
|
||||
!(Shell.fileExists("\(Paths.binPath))/valet")
|
||||
|| Shell.fileExists("~/.composer/vendor/bin/valet")
|
||||
),
|
||||
messageText: "startup.errors.valet_executable.title".localized,
|
||||
informativeText: "startup.errors.valet_executable.desc".localized,
|
||||
breaking: true
|
||||
informativeText: "startup.errors.valet_executable.desc".localized
|
||||
)
|
||||
|
||||
performEnvironmentCheck(
|
||||
HomebrewDiagnostics.cannotLoadService(),
|
||||
messageText: "startup.errors.services_json_error.title".localized,
|
||||
informativeText: "startup.errors.services_json_error.desc".localized,
|
||||
breaking: true
|
||||
informativeText: "startup.errors.services_json_error.desc".localized
|
||||
)
|
||||
|
||||
performEnvironmentCheck(
|
||||
!Shell.pipe("cat /private/etc/sudoers.d/brew").contains("\(Paths.binPath)/brew"),
|
||||
messageText: "startup.errors.sudoers_brew.title".localized,
|
||||
informativeText: "startup.errors.sudoers_brew.desc".localized,
|
||||
breaking: true
|
||||
informativeText: "startup.errors.sudoers_brew.desc".localized
|
||||
)
|
||||
|
||||
performEnvironmentCheck(
|
||||
@ -69,8 +63,7 @@ class Startup {
|
||||
|| Shell.pipe("cat /private/etc/sudoers.d/valet").contains("/opt/homebrew/bin/valet")
|
||||
),
|
||||
messageText: "startup.errors.sudoers_valet.title".localized,
|
||||
informativeText: "startup.errors.sudoers_valet.desc".localized,
|
||||
breaking: true
|
||||
informativeText: "startup.errors.sudoers_valet.desc".localized
|
||||
)
|
||||
|
||||
// Determine the Valet version only AFTER confirming the correct permission is in place
|
||||
@ -78,8 +71,7 @@ class Startup {
|
||||
performEnvironmentCheck(
|
||||
Valet.shared.version == nil,
|
||||
messageText: "startup.errors.valet_version_unknown.title".localized,
|
||||
informativeText: "startup.errors.valet_version_unknown.desc".localized,
|
||||
breaking: true
|
||||
informativeText: "startup.errors.valet_version_unknown.desc".localized
|
||||
)
|
||||
|
||||
if (!failed) {
|
||||
@ -101,32 +93,28 @@ class Startup {
|
||||
}
|
||||
|
||||
/**
|
||||
Perform an environment check. Will cause the application to terminate, if `breaking` is set to true.
|
||||
Perform an environment check.
|
||||
|
||||
- Parameter condition: Fail condition to check for; if this returns `true`, the alert will be shown
|
||||
- Parameter messageText: Short description of what is wrong
|
||||
- Parameter informativeText: Expanded description of the environment check that failed
|
||||
- Parameter breaking: If the application should terminate afterwards
|
||||
*/
|
||||
private func performEnvironmentCheck(
|
||||
_ condition: Bool,
|
||||
messageText: String,
|
||||
informativeText: String,
|
||||
breaking: Bool
|
||||
informativeText: String
|
||||
) {
|
||||
if (!condition) { return }
|
||||
|
||||
failed = breaking
|
||||
|
||||
DispatchQueue.main.async { [self] in
|
||||
// Present the information to the user
|
||||
Alert.notify(
|
||||
message: messageText,
|
||||
info: informativeText,
|
||||
style: breaking ? .critical : .warning
|
||||
style: .critical
|
||||
)
|
||||
// Only breaking issues will throw the extra retry modal
|
||||
breaking ? failureCallback() : ()
|
||||
failureCallback()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,25 @@ extension MainMenu {
|
||||
// Start with the icon
|
||||
setStatusBar(image: NSImage(named: NSImage.Name("StatusBarIcon"))!)
|
||||
|
||||
// Do the important system setup checks
|
||||
Log.info("The user is running PHP Monitor with the architecture: \(App.architecture)")
|
||||
|
||||
// Make sure Homebrew is installed
|
||||
if !FileManager.default.fileExists(atPath: Paths.brew) {
|
||||
_ = Alert.present(
|
||||
messageText: "alert.homebrew_missing.title".localized,
|
||||
informativeText: "alert.homebrew_missing.info".localized(
|
||||
App.architecture
|
||||
.replacingOccurrences(of: "x86_64", with: "Intel")
|
||||
.replacingOccurrences(of: "arm64", with: "Apple Silicon"),
|
||||
Paths.brew
|
||||
),
|
||||
buttonTitle: "alert.homebrew_missing.quit".localized,
|
||||
style: .critical
|
||||
)
|
||||
exit(1)
|
||||
}
|
||||
|
||||
// Perform environment boot checks
|
||||
DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
|
||||
Startup().checkEnvironment(success: { onEnvironmentPass() },
|
||||
|
@ -183,6 +183,10 @@
|
||||
|
||||
// ALERTS
|
||||
|
||||
"alert.homebrew_missing.title" = "PHP Monitor cannot start";
|
||||
"alert.homebrew_missing.info" = "You are running PHP Monitor with the following architecture: %@.\n\nA working Homebrew binary is expected in `%@`, but was not found, so PHP Monitor cannot work.\n\nIf you have not installed Homebrew yet, please do so. (If you are on Apple Silicon, make sure your Homebrew and PHP Monitor use the same architecture, by enabling or disabling Rosetta where needed.)\n\nPHP Monitor will now quit, please restart the app after fixing this issue.";
|
||||
"alert.homebrew_missing.quit" = "Quit";
|
||||
|
||||
// Composer Update
|
||||
"alert.composer_missing.title" = "Composer not found!";
|
||||
"alert.composer_missing.info" = "Make sure you have Composer available in `/usr/local/bin/composer`. If Composer is located somewhere else, please create a symlink, like so (make sure to use the correct path):\n\n`ln -s /path/to/composer /usr/local/bin`.";
|
||||
|
Reference in New Issue
Block a user