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

♻️ Change app detection

This commit is contained in:
2021-12-10 12:42:06 +01:00
parent c05f0fe5cb
commit b6b5a94bbd
7 changed files with 93 additions and 42 deletions

View File

@ -9,8 +9,8 @@
/* Begin PBXBuildFile section */
5420395926135DC100FB00FA /* PrefsVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5420395826135DC100FB00FA /* PrefsVC.swift */; };
5420395F2613607600FB00FA /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5420395E2613607600FB00FA /* Preferences.swift */; };
54B48B5F275F66AE006D90C5 /* Editor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54B48B5E275F66AE006D90C5 /* Editor.swift */; };
54B48B60275F66AE006D90C5 /* Editor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54B48B5E275F66AE006D90C5 /* Editor.swift */; };
54B48B5F275F66AE006D90C5 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54B48B5E275F66AE006D90C5 /* Application.swift */; };
54B48B60275F66AE006D90C5 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54B48B5E275F66AE006D90C5 /* Application.swift */; };
54EAC806262F212B0092D14E /* GlobalKeybindPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41CD0282628D8EE0065BBED /* GlobalKeybindPreference.swift */; };
C405A4D024B9B9140062FAFA /* InternetAccessPolicy.strings in Resources */ = {isa = PBXBuildFile; fileRef = C405A4CE24B9B9130062FAFA /* InternetAccessPolicy.strings */; };
C405A4D124B9B9140062FAFA /* InternetAccessPolicy.plist in Resources */ = {isa = PBXBuildFile; fileRef = C405A4CF24B9B9140062FAFA /* InternetAccessPolicy.plist */; };
@ -120,7 +120,7 @@
/* Begin PBXFileReference section */
5420395826135DC100FB00FA /* PrefsVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrefsVC.swift; sourceTree = "<group>"; };
5420395E2613607600FB00FA /* Preferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = "<group>"; };
54B48B5E275F66AE006D90C5 /* Editor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Editor.swift; sourceTree = "<group>"; };
54B48B5E275F66AE006D90C5 /* Application.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Application.swift; sourceTree = "<group>"; };
C405A4CE24B9B9130062FAFA /* InternetAccessPolicy.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; path = InternetAccessPolicy.strings; sourceTree = "<group>"; };
C405A4CF24B9B9140062FAFA /* InternetAccessPolicy.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = InternetAccessPolicy.plist; sourceTree = "<group>"; };
C412E5FB25700D5300A1FB67 /* HomebrewPackage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomebrewPackage.swift; sourceTree = "<group>"; };
@ -323,7 +323,7 @@
isa = PBXGroup;
children = (
C476FF9722B0DD830098105B /* Alert.swift */,
54B48B5E275F66AE006D90C5 /* Editor.swift */,
54B48B5E275F66AE006D90C5 /* Application.swift */,
C4188988275FE8CB001EF227 /* Filesystem.swift */,
C474B00524C0E98C00066A22 /* LocalNotification.swift */,
C41C1B4822B00A9800E7CF16 /* MenuBarImageGenerator.swift */,
@ -544,7 +544,7 @@
C4CCBA6C275C567B008C7055 /* PMWindowController.swift in Sources */,
C41CD0292628D8EE0065BBED /* GlobalKeybindPreference.swift in Sources */,
C42295DD2358D02000E263B2 /* Command.swift in Sources */,
54B48B5F275F66AE006D90C5 /* Editor.swift in Sources */,
54B48B5F275F66AE006D90C5 /* Application.swift in Sources */,
C4B97B78275CF1B5003F3378 /* App+ActivationPolicy.swift in Sources */,
C4811D2422D70A4700B5F6B3 /* App.swift in Sources */,
C41C1B4922B00A9800E7CF16 /* MenuBarImageGenerator.swift in Sources */,
@ -577,7 +577,7 @@
files = (
54EAC806262F212B0092D14E /* GlobalKeybindPreference.swift in Sources */,
C4F780C425D80B75000DBC97 /* MainMenu.swift in Sources */,
54B48B60275F66AE006D90C5 /* Editor.swift in Sources */,
54B48B60275F66AE006D90C5 /* Application.swift in Sources */,
C4F780C825D80B75000DBC97 /* DateExtension.swift in Sources */,
C4F780CC25D80B75000DBC97 /* ActivePhpInstallation.swift in Sources */,
C4F780B125D80B4D000DBC97 /* PhpExtension.swift in Sources */,

View File

@ -235,7 +235,7 @@ PHP Monitor itself doesn't do any network requests. Feel free to check the sourc
When you select and right-click on a domain, you can open these directories with various applications. This can help speed up your workflow. However, for these apps to show up, they must be detected first.
The supported apps are: <i>PhpStorm, Visual Studio Code, Sublime Text, Sublime Merge</i>.
The supported apps are: <i>PhpStorm, Visual Studio Code, Sublime Text, Sublime Merge, iTerm</i>.
For <strong>Visual Studio Code</strong>, you need to have `code` available in your PATH (`/usr/bin/local/code` is checked).
[More info](https://code.visualstudio.com/docs/editor/command-line) here.
@ -243,7 +243,7 @@ For <strong>Visual Studio Code</strong>, you need to have `code` available in yo
For <strong>PhpStorm</strong>, you need to have `pstorm` available in your PATH (`/usr/bin/local/pstorm` is checked).
[More info](https://www.jetbrains.com/help/phpstorm/working-with-the-ide-features-from-command-line.html) here.
For <strong>Sublime Text (and Sublime Merge)</strong>, the apps need to be in your `/Applications` directory.
For <strong>Sublime Text, Sublime Merge and iTerm</strong>, the apps need to be in your `/Applications` directory.
To see which files are checked to determine availability, see [this file](./phpmon/Domain/Helpers/Editor.swift).
</details>

View File

@ -10,10 +10,10 @@ import Foundation
/// An application that is capable of opening a particular directory (usually of a PHP project).
/// In most cases this is going to be a code editor, but it could also be another application
/// that supports opening those directories, like a visual Git client.
class Editor {
/// that supports opening those directories, like a visual Git client or a terminal app.
class Application {
/// Name of the editor. Used for display purposes.
/// Name of the app. Used for display purposes.
let name: String
/// Paths to check whether the application is actually installed.
@ -31,7 +31,7 @@ class Editor {
@objc let openCallback: (String) -> Void
/**
- Parameter name: Name of the editor.
- Parameter name: Name of the application.
- Parameter installPath: Files to verify, if any file exists here the app is considered present on the system.
- Parameter binaryPath: Additional file that is used to open a specific path.
- Parameter open: Callback used to open a specific directory in the editor in question.
@ -57,6 +57,9 @@ class Editor {
/** Checks if the app is installed. */
func isInstalled() -> Bool {
// TODO: Alternative way to detect if an app is installed:
// mdfind "kMDItemKind == 'Application'" | grep AppName.app
// This will return the path to the application. Worth a refactor?
self.pathsToVerifyInstalled.map({ path in
Shell.fileExists(path)
}).contains(true)
@ -68,14 +71,13 @@ class Editor {
}
/**
Detect which "editors" are available to open a specific directory.
Detect which apps are available to open a specific directory.
*/
static public func detectPresetEditors() -> [Editor] {
static public func detectPresetApplications() -> [Application] {
return [
Editor(
Application(
name: "PhpStorm",
installPaths: [
"~/Applications/JetBrains Toolbox/PhpStorm.app/Contents/Info.plist",
"/Applications/PhpStorm.app/Contents/Info.plist",
"/usr/local/bin/pstorm"
],
@ -85,7 +87,19 @@ class Editor {
},
instruction: "editors.pstorm_binary_not_linked.desc".localized
),
Editor(
Application(
name: "PhpStorm (via Toolbox)",
installPaths: [
"~/Applications/JetBrains Toolbox/PhpStorm.app/Contents/Info.plist",
"/usr/local/bin/phpstorm"
],
binaryPath: "/usr/local/bin/phpstorm",
open: { path in
Shell.run("/usr/local/bin/phpstorm \(path)")
},
instruction: "editors.phpstorm_binary_not_linked.desc".localized
),
Application(
name: "Visual Studio Code",
installPaths: [
"/Applications/Visual Studio Code.app/Contents/Info.plist",
@ -97,7 +111,7 @@ class Editor {
},
instruction: "editors.code_binary_not_linked.desc".localized
),
Editor(
Application(
name: "Sublime Text",
installPaths: ["/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl"],
binaryPath: "/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl",
@ -105,13 +119,21 @@ class Editor {
Shell.run("/Applications/Sublime\\ Text.app/Contents/SharedSupport/bin/subl \(path)")
}
),
Editor(
Application(
name: "Sublime Merge",
installPaths: ["/Applications/Sublime Merge.app/Contents/SharedSupport/bin/smerge"],
binaryPath: "/Applications/Sublime Merge.app/Contents/SharedSupport/bin/smerge",
open: { path in
Shell.run("/Applications/Sublime\\ Merge.app/Contents/SharedSupport/bin/smerge \(path)")
}
),
Application(
name: "iTerm",
installPaths: ["/Applications/iTerm.app/Contents/Info.plist"],
binaryPath: "/Applications/iTerm.app/Contents/Info.plist",
open: { path in
Shell.run("open -a iTerm \(path)")
}
)
].filter { return $0.isInstalled() }
}

View File

@ -90,17 +90,14 @@ class StatusMenu : NSMenu {
func addForceLoadLatestVersion() {
if !App.shared.availablePhpVersions.contains(App.shared.brewPhpVersion) {
self.addItem(NSMenuItem(
title: "mi_force_load_latest_unavailable".localized
.replacingOccurrences(of: "%@", with: App.shared.brewPhpVersion),
title: "mi_force_load_latest_unavailable".localized(App.shared.brewPhpVersion),
action: nil, keyEquivalent: "f"
))
} else {
self.addItem(NSMenuItem(
title: "mi_force_load_latest".localized
.replacingOccurrences(of: "%@", with: App.shared.brewPhpVersion),
title: "mi_force_load_latest".localized(App.shared.brewPhpVersion),
action: #selector(MainMenu.forceRestartLatestPhp), keyEquivalent: "f"))
}
}
func addValetMenuItems() {
@ -185,5 +182,5 @@ class ExtensionMenuItem: NSMenuItem {
}
class EditorMenuItem: NSMenuItem {
var editor: Editor? = nil
var editor: Application? = nil
}

View File

@ -22,8 +22,8 @@ class SiteListVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
/// List of sites that will be displayed in this view. Originates from the `Valet` object.
var sites: [Valet.Site] = []
/// Array that contains various editors that might open a particular site directory.
var editors: [Editor] = Editor.detectPresetEditors()
/// Array that contains various apps that might open a particular site directory.
var editors: [Application] = Application.detectPresetApplications()
/// String that was last searched for. Empty by default.
var lastSearchedFor = ""
@ -176,16 +176,18 @@ class SiteListVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
selectedSite.determineSecured(Valet.shared.config.tld)
if selectedSite.secured == originalSecureStatus {
Alert.notify(
message: "site_list.alerts_status_changed.title".localized,
info: "\("site_list.alerts_status_changed.desc".localized) `\(command)`")
message: "site_list.alerts_status_not_changed.title".localized,
info: "site_list.alerts_status_not_changed.desc".localized(command)
)
} else {
let newState = selectedSite.secured ? "secured" : "unsecured"
LocalNotification.send(
title: "site_list.alerts_status_changed.title".localized,
subtitle: "site_list.alerts_status_changed.desc"
.localized
.replacingOccurrences(of: "{@1}", with: "\(selectedSite.name!).\(Valet.shared.config.tld)")
.replacingOccurrences(of: "{@2}", with: newState)
.localized(
"\(selectedSite.name!).\(Valet.shared.config.tld)",
newState
)
)
}
@ -207,6 +209,10 @@ class SiteListVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
Shell.run("open \(selectedSite!.absolutePath!)")
}
@objc public func openInTerminal() {
Shell.run("open -b com.apple.terminal \(selectedSite!.absolutePath!)")
}
@objc public func unlinkSite() {
guard let site = selectedSite else {
return
@ -218,8 +224,7 @@ class SiteListVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
Alert.confirm(
onWindow: view.window!,
messageText: "site_list.confirm_unlink".localized
.replacingOccurrences(of: "%@", with: site.name),
messageText: "site_list.confirm_unlink".localized(site.name),
informativeText: "site_link.confirm_link".localized,
buttonTitle: "site_list.unlink".localized,
secondButtonTitle: "Cancel",
@ -280,6 +285,7 @@ class SiteListVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
if (editors.count > 0) {
menu.addItem(NSMenuItem.separator())
menu.addItem(withTitle: "site_list.detected_apps".localized, action: nil, keyEquivalent: "")
for (index, editor) in editors.enumerated() {
let editorMenuItem = EditorMenuItem(
@ -294,11 +300,17 @@ class SiteListVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
menu.addItem(NSMenuItem.separator())
}
menu.addItem(withTitle: "site_list.system_apps".localized, action: nil, keyEquivalent: "")
menu.addItem(
withTitle: "site_list.open_in_finder".localized,
action: #selector(self.openInFinder),
keyEquivalent: "F"
)
menu.addItem(
withTitle: "site_list.open_in_terminal".localized,
action: #selector(self.openInTerminal),
keyEquivalent: "T"
)
menu.addItem(
withTitle: "site_list.open_in_browser".localized,
action: #selector(self.openInBrowser),
@ -318,7 +330,7 @@ class SiteListVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
}
}
private func presentAlertForMissingEditorBinary(_ editor: Editor, _ sender: EditorMenuItem) {
private func presentAlertForMissingEditorBinary(_ editor: Application, _ sender: EditorMenuItem) {
Alert.confirm(
onWindow: self.view.window!,
messageText: "editors.binary_missing.title".localized(editor.pathToBinary),

View File

@ -93,5 +93,4 @@ class Shell {
public static func fileExists(_ path: String) -> Bool {
return Shell.pipe("if [ -f \(path) ]; then /bin/echo -n \"0\"; fi") == "0"
}
}

View File

@ -54,11 +54,11 @@
"site_list.title" = "Domains";
"site_list.subtitle" = "Linked & Parked";
"site_list.alerts_status_changed.title" = "SSL Status Not Changed";
"site_list.alerts_status_changed.desc" = "Something went wrong. Try running the command in your terminal manually:";
"site_list.alerts_status_not_changed.title" = "SSL Status Not Changed";
"site_list.alerts_status_not_changed.desc" = "Something went wrong. Try running the command in your terminal manually: %@";
"site_list.alerts_status_changed.title" = "SSL Status Changed";
"site_list.alerts_status_changed.desc" = "The domain '{@1}' is now {@2}.";
"site_list.alerts_status_changed.desc" = "The domain '%@' is now %@.";
"site_list.confirm_unlink" = "Are you sure you want to unlink '%@'?";
"site_link.confirm_link" = "No files will be removed. If needed, the site will need to be relinked via the command line.";
@ -70,8 +70,9 @@
"site_list.unsecure" = "Unsecure";
"site_list.open_in_finder" = "Open in Finder";
"site_list.open_in_browser" = "Open in Browser";
"site_list.open_with_vs_code" = "Open with Visual Studio Code";
"site_list.open_with_pstorm" = "Open with PhpStorm";
"site_list.open_in_terminal" = "Open in Terminal";
"site_list.detected_apps" = "Detected Applications";
"site_list.system_apps" = "System Applications";
// EDITORS
"editors.binary_missing.title" = "`%@` missing";
@ -79,10 +80,21 @@
"editors.alert.try_again" = "Try Again";
"editors.alert.cancel" = "Cancel";
// - PHPSTORM + TOOLBOX
"editors.phpstorm_binary_not_linked.desc" =
"PHP Monitor makes use of PhpStorms launcher to open a specific directory.
The required launcher does not seem to be found in the usual location. In JetBrains Toolbox go to Settings, and select 'Generate shell scripts'.
As the directory, enter `/usr/local/bin`.
After this is done, PHP Monitor should be able to open the domains folder in PhpStorm.";
// - PHPSTORM (standalone)
"editors.pstorm_binary_not_linked.desc" =
"PHP Monitor makes use of PhpStorms launcher to open a specific directory.
The desired launcher does not seem to be found in the usual location. Please set up the launcher by going to 'Tools > Create command-line launcher' in PhpStorm.
The required launcher does not seem to be found in the usual location. Please set up the launcher by going to 'Tools > Create command-line launcher' in PhpStorm.
After this is done, PHP Monitor should be able to open the domains folder in PhpStorm.";
"editors.code_binary_not_linked.desc" =
@ -93,6 +105,15 @@ You can fix this by selecting 'Install `code` command in PATH' in Visual Studio
After this is done, PHP Monitor should be able to open the domains folder in PhpStorm.";
// - VS CODE
"editors.code_binary_not_linked.desc" =
"PHP Monitor makes use of Visual Studio Codes helper binary, `code`, but it seems not to exist on your system.
You can fix this by selecting 'Install `code` command in PATH' in Visual Studio Codes command palette.
(Type `>code` to find it.)
After this is done, PHP Monitor should be able to open the domains folder in PhpStorm.";
// PREFERENCES
"prefs.title" = "PHP Monitor";