mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-08-08 04:20:07 +02:00
♻️ Change app detection
This commit is contained in:
@ -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 */,
|
||||
|
@ -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>
|
||||
|
@ -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() }
|
||||
}
|
@ -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
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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"
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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 PhpStorm’s 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 domain’s folder in PhpStorm.";
|
||||
|
||||
// - PHPSTORM (standalone)
|
||||
"editors.pstorm_binary_not_linked.desc" =
|
||||
"PHP Monitor makes use of PhpStorm’s 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 domain’s 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 domain’s folder in PhpStorm.";
|
||||
|
||||
// - VS CODE
|
||||
"editors.code_binary_not_linked.desc" =
|
||||
"PHP Monitor makes use of Visual Studio Code‘s 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 Code’s command palette.
|
||||
(Type `>code` to find it.)
|
||||
|
||||
After this is done, PHP Monitor should be able to open the domain’s folder in PhpStorm.";
|
||||
|
||||
// PREFERENCES
|
||||
|
||||
"prefs.title" = "PHP Monitor";
|
||||
|
Reference in New Issue
Block a user