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

Check if running the app with Rosetta

This commit is contained in:
2022-08-10 21:04:23 +02:00
parent c1c7561361
commit 78e750d764
11 changed files with 148 additions and 60 deletions

View File

@ -166,6 +166,8 @@
C4927F0C27B2DFC200C55AFD /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4927F0A27B2DFC200C55AFD /* Errors.swift */; };
C493084A279F331F009C240B /* AddSiteVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4930849279F331F009C240B /* AddSiteVC.swift */; };
C493084B279F331F009C240B /* AddSiteVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4930849279F331F009C240B /* AddSiteVC.swift */; };
C495F5AF28A42E080087F70A /* EnvironmentCheck.swift in Sources */ = {isa = PBXBuildFile; fileRef = C495F5AE28A42E080087F70A /* EnvironmentCheck.swift */; };
C495F5B028A42E080087F70A /* EnvironmentCheck.swift in Sources */ = {isa = PBXBuildFile; fileRef = C495F5AE28A42E080087F70A /* EnvironmentCheck.swift */; };
C4998F0A2617633900B2526E /* PreferencesWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4998F092617633900B2526E /* PreferencesWindowController.swift */; };
C4998F0B2617633900B2526E /* PreferencesWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4998F092617633900B2526E /* PreferencesWindowController.swift */; };
C4AC51FC27E27F47008528CA /* DomainListKindCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AC51FB27E27F47008528CA /* DomainListKindCell.swift */; };
@ -398,6 +400,7 @@
C48D6C73279CD3E400F26D7E /* PhpVersionNumberTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhpVersionNumberTest.swift; sourceTree = "<group>"; };
C4927F0A27B2DFC200C55AFD /* Errors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Errors.swift; sourceTree = "<group>"; };
C4930849279F331F009C240B /* AddSiteVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddSiteVC.swift; sourceTree = "<group>"; };
C495F5AE28A42E080087F70A /* EnvironmentCheck.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnvironmentCheck.swift; sourceTree = "<group>"; };
C4998F092617633900B2526E /* PreferencesWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesWindowController.swift; sourceTree = "<group>"; };
C4AC51FB27E27F47008528CA /* DomainListKindCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DomainListKindCell.swift; sourceTree = "<group>"; };
C4ACA38E25C754C100060C66 /* PhpExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpExtension.swift; sourceTree = "<group>"; };
@ -890,6 +893,7 @@
C4B97B7A275CF20A003F3378 /* App+GlobalHotkey.swift */,
C4EED88827A48778006D7272 /* InterAppHandler.swift */,
C4D8016522B1584700C6DA1B /* Startup.swift */,
C495F5AE28A42E080087F70A /* EnvironmentCheck.swift */,
C46E206C28299B3800D909D6 /* AppUpdateChecker.swift */,
C40FE736282ABA4F00A302C2 /* AppVersion.swift */,
C45E76132854A65300B4FE0C /* ServicesManager.swift */,
@ -1322,6 +1326,7 @@
C422DDAD28A2DAC600CEAC97 /* WarningsWindowController.swift in Sources */,
C415937F27A1B54F00D2E1B7 /* PhpFrameworks.swift in Sources */,
C4811D2422D70A4700B5F6B3 /* App.swift in Sources */,
C495F5AF28A42E080087F70A /* EnvironmentCheck.swift in Sources */,
C41C1B4922B00A9800E7CF16 /* MenuBarImageGenerator.swift in Sources */,
C4F30B03278E16BA00755FCE /* HomebrewService.swift in Sources */,
54D9E0B427E4F51E003B9AD9 /* Key.swift in Sources */,
@ -1453,6 +1458,7 @@
C4B97B76275CF08C003F3378 /* AppDelegate+MenuOutlets.swift in Sources */,
C4F780CD25D80B75000DBC97 /* Alert.swift in Sources */,
C481F79726164A78004FBCFF /* PrefsVC.swift in Sources */,
C495F5B028A42E080087F70A /* EnvironmentCheck.swift in Sources */,
C41E871B2763D42300161EE0 /* DomainListVC+ContextMenu.swift in Sources */,
C40C7F3127722E8D00DDDCDC /* Logger.swift in Sources */,
C4068CAB27B0890D00544CD5 /* MenuBarIcons.swift in Sources */,

View File

@ -68,6 +68,9 @@ class App {
/** The services manager, responsible for figuring out what services are active/inactive. */
var services = ServicesManager.shared
/** The warning manager, responsible for keeping track of warnings. */
var warnings = WarningManager.shared
/** Timer that will periodically reload info about the user's PHP installation. */
var timer: Timer?

View File

@ -0,0 +1,45 @@
//
// EnvironmentCheck.swift
// PHP Monitor
//
// Created by Nico Verbruggen on 10/08/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
//
import Foundation
/**
The `EnvironmentCheck` is used to defer the execution of all of these commands until necessary.
Checks that require an app restart will always lead to an alert and app termination shortly after.
*/
struct EnvironmentCheck {
let command: () async -> Bool
let name: String
let titleText: String
let subtitleText: String
let descriptionText: String
let buttonText: String
let requiresAppRestart: Bool
init(
command: @escaping () async -> Bool,
name: String,
titleText: String,
subtitleText: String,
descriptionText: String = "",
buttonText: String = "OK",
requiresAppRestart: Bool = false
) {
self.command = command
self.name = name
self.titleText = titleText
self.subtitleText = subtitleText
self.descriptionText = descriptionText
self.buttonText = buttonText
self.requiresAppRestart = requiresAppRestart
}
public func succeeds() async -> Bool {
return await !self.command()
}
}

View File

@ -238,42 +238,4 @@ class Startup {
descriptionText: "startup.errors.valet_version_unknown.desc".localized
)
]
// MARK: - EnvironmentCheck struct
/**
The `EnvironmentCheck` is used to defer the execution of all of these commands until necessary.
Checks that require an app restart will always lead to an alert and app termination shortly after.
*/
struct EnvironmentCheck {
let command: () async -> Bool
let name: String
let titleText: String
let subtitleText: String
let descriptionText: String
let buttonText: String
let requiresAppRestart: Bool
init(
command: @escaping () async -> Bool,
name: String,
titleText: String,
subtitleText: String,
descriptionText: String = "",
buttonText: String = "OK",
requiresAppRestart: Bool = false
) {
self.command = command
self.name = name
self.titleText = titleText
self.subtitleText = subtitleText
self.descriptionText = descriptionText
self.buttonText = buttonText
self.requiresAppRestart = requiresAppRestart
}
public func succeeds() async -> Bool {
return await !self.command()
}
}
}

View File

@ -79,21 +79,25 @@ extension MainMenu {
// A non-default TLD is not officially supported since Valet 3.2.x
Valet.notifyAboutUnsupportedTLD()
// Find out which services are active
ServicesManager.shared.loadData()
// Start the background refresh timer
startSharedTimer()
// Check warnings
WarningManager.shared.evaluateWarnings()
// Update the stats
Stats.incrementSuccessfulLaunchCount()
Stats.evaluateSponsorMessageShouldBeDisplayed()
// Present first launch screen if needed
#warning("The launch screen will be presented every time you launch the app.")
if Stats.successfulLaunchCount >= 1 && !isRunningSwiftUIPreview {
#warning("You should definitely tweak this view again")
if Stats.successfulLaunchCount == 0 && !isRunningSwiftUIPreview {
Log.info("Should present the first launch screen!")
DispatchQueue.main.async {
// OnboardingWindowController.show()
OnboardingWindowController.show()
}
}

View File

@ -64,6 +64,7 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate
menu.addRemainingMenuItems()
menu.addItem(NSMenuItem.separator())
menu.addWarningsMenuItem()
menu.addCoreMenuItems()
menu.items.forEach({ (item) in

View File

@ -74,12 +74,21 @@ class StatusMenu: NSMenu {
self.addFirstAidAndServicesMenuItems()
}
func addWarningsMenuItem() {
if !WarningManager.shared.hasWarnings() {
return
}
self.addItem(NSMenuItem.separator())
let count = WarningManager.shared.warnings.count
self.addItem(NSMenuItem(title: (count == 1 ? "mi_warning" : "mi_warnings").localized(count),
action: #selector(MainMenu.openWarnings), keyEquivalent: ""))
}
func addCoreMenuItems() {
self.addItem(NSMenuItem.separator())
if (WarningManager.hasWarnings()) {
self.addItem(NSMenuItem(title: "mi_warnings".localized(2),
action: #selector(MainMenu.openWarnings), keyEquivalent: ""))
}
self.addItem(NSMenuItem(title: "mi_preferences".localized,
action: #selector(MainMenu.openPrefs), keyEquivalent: ","))
self.addItem(NSMenuItem(title: "mi_check_for_updates".localized,

View File

@ -12,17 +12,14 @@ struct WarningListView: View {
var body: some View {
List {
VStack(alignment: .leading) {
WarningView(
title: "warnings.arm_compatibility_title",
description: "warnings.arm_compatibility.description",
documentationUrl: "https://phpmon.app/documentation/apple-silicon-transition"
)
Divider()
WarningView(
title: "warnings.helper_permissions_title",
description: "warnings.helper_permissions.description"
)
Divider()
ForEach(WarningManager.shared.warnings) { warning in
WarningView(
title: warning.titleText,
description: warning.descriptionText,
documentationUrl: warning.url
)
Divider()
}
}
}

View File

@ -8,6 +8,29 @@
import Foundation
struct Warning {
struct Warning: Identifiable {
var id = UUID()
let command: () async -> Bool
let name: String
let titleText: String
let descriptionText: String
let url: String?
init(
command: @escaping () async -> Bool,
name: String,
titleText: String,
descriptionText: String,
url: String?
) {
self.command = command
self.name = name
self.titleText = titleText
self.descriptionText = descriptionText
self.url = url
}
public func applies() async -> Bool {
return await self.command()
}
}

View File

@ -10,6 +10,43 @@ import Foundation
class WarningManager {
// TODO: Singleton initialization at launch
static var shared = WarningManager()
public let evaluations: [Warning] = [
Warning(
command: {
return Shell.pipe("sysctl -n sysctl.proc_translated")
.trimmingCharacters(in: .whitespacesAndNewlines) == "1"
},
name: "Running PHP Monitor with Rosetta on M1",
titleText: "warnings.arm_compatibility.title",
descriptionText: "warnings.arm_compatibility.description",
url: nil
)
]
@Published public var warnings: [Warning] = []
public func hasWarnings() -> Bool {
return !warnings.isEmpty
}
func evaluateWarnings() {
Task { await WarningManager.shared.checkEnvironment() }
}
/**
Checks the user's environment and checks if any special warnings apply.
*/
func checkEnvironment() async {
self.warnings = []
for check in self.evaluations {
if await check.applies() {
Log.info("[WARNING] \(check.name)")
self.warnings.append(check)
continue
}
}
}
}

View File

@ -55,6 +55,7 @@
"mi_detected_extensions" = "Detected Extensions";
"mi_no_extensions_detected" = "No additional extensions detected.";
"mi_warning" = "⚠️ %i Warning";
"mi_warnings" = "⚠️ %i Warnings...";
"mi_valet" = "Laravel Valet";
@ -510,10 +511,10 @@ If you are seeing this message but are confused why this folder has gone missing
"warnings.title" = "Warnings";
"warnings.helper_permissions_title" = "Helpers could not be written!";
"warnings.helper_permissions.title" = "Helpers could not be written!";
"warnings.helper_permissions.description" = "The helper files in `/usr/local/bin` could not be written because PHP Monitor does not have permission to write there.";
"warnings.arm_compatibility_title" = "You are running PHP Monitor using Rosetta";
"warnings.arm_compatibility.title" = "You are running PHP Monitor using Rosetta";
"warnings.arm_compatibility.description" = "You appear to be running an ARM-compatible version of macOS, but you are currently running PHP Monitor using Rosetta. While this will work correctly, it is recommended that you use the native version of Homebrew.";
// ONBOARDING