mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-08-07 03:50:08 +02:00
♻️ Rework interaction with Valet commands
This commit is contained in:
@ -91,7 +91,7 @@
|
||||
</CommandLineArgument>
|
||||
<CommandLineArgument
|
||||
argument = "--configuration:~/.phpmon_fconf_working.json"
|
||||
isEnabled = "YES">
|
||||
isEnabled = "NO">
|
||||
</CommandLineArgument>
|
||||
<CommandLineArgument
|
||||
argument = "--configuration:~/.phpmon_fconf_broken.json"
|
||||
|
@ -11,33 +11,99 @@ import Cocoa
|
||||
|
||||
extension DomainListVC {
|
||||
|
||||
@objc func toggleSecure() {
|
||||
if selected is ValetSite {
|
||||
toggleSecureForSite()
|
||||
} else {
|
||||
toggleSecureForProxy()
|
||||
@objc func openInBrowser() {
|
||||
guard let selected = self.selected else {
|
||||
return
|
||||
}
|
||||
|
||||
guard let url = selected.getListableUrl() else {
|
||||
BetterAlert()
|
||||
.withInformation(
|
||||
title: "domain_list.alert.invalid_folder_name".localized,
|
||||
subtitle: "domain_list.alert.invalid_folder_name_desc".localized
|
||||
)
|
||||
.withPrimary(text: "OK")
|
||||
.show()
|
||||
return
|
||||
}
|
||||
|
||||
NSWorkspace.shared.open(url)
|
||||
}
|
||||
|
||||
@objc func openInFinder() async {
|
||||
await Shell.quiet("open '\(selectedSite!.absolutePath)'")
|
||||
}
|
||||
|
||||
@objc func openInTerminal() async {
|
||||
await Shell.quiet("open -b com.apple.terminal '\(selectedSite!.absolutePath)'")
|
||||
}
|
||||
|
||||
@objc func openWithEditor(sender: EditorMenuItem) async {
|
||||
guard let editor = sender.editor else { return }
|
||||
await editor.openDirectory(file: selectedSite!.absolutePath)
|
||||
}
|
||||
|
||||
// MARK: - UI interaction
|
||||
|
||||
private func performAction(command: String, beforeCellReload: @escaping () -> Void) {
|
||||
let rowToReload = tableView.selectedRow
|
||||
|
||||
waitAndExecute {
|
||||
await Shell.quiet(command)
|
||||
} completion: { [self] in
|
||||
beforeCellReload()
|
||||
tableView.reloadData(forRowIndexes: [rowToReload], columnIndexes: [0, 1, 2, 3, 4])
|
||||
tableView.deselectRow(rowToReload)
|
||||
tableView.selectRowIndexes([rowToReload], byExtendingSelection: true)
|
||||
}
|
||||
}
|
||||
|
||||
func toggleSecureForProxy() {
|
||||
let originalSecureStatus = selectedProxy!.secured
|
||||
let selectedProxy = selectedProxy!
|
||||
private func reloadSelectedRow() {
|
||||
tableView.reloadData(forRowIndexes: [tableView.selectedRow], columnIndexes: [0, 1, 2, 3, 4])
|
||||
tableView.deselectRow(tableView.selectedRow)
|
||||
tableView.selectRowIndexes([tableView.selectedRow], byExtendingSelection: true)
|
||||
}
|
||||
|
||||
self.waitAndExecute {
|
||||
// 1. Remove the original proxy
|
||||
await Shell.quiet("\(Paths.valet) unproxy \(selectedProxy.domain)")
|
||||
// MARK: - Interactions with `valet` or terminal
|
||||
|
||||
// 2. Add a new proxy, which is either secured/unsecured
|
||||
let secure = originalSecureStatus ? "" : " --secure"
|
||||
await Shell.quiet("\(Paths.valet) proxy \(selectedProxy.domain) \(selectedProxy.target)\(secure)")
|
||||
@objc func toggleSecure() {
|
||||
if selected is ValetSite {
|
||||
Task { toggleSecureForSite() }
|
||||
} else {
|
||||
Task { await toggleSecureForProxy() }
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Restart nginx
|
||||
await Actions.restartNginx()
|
||||
func toggleSecureForProxy() async {
|
||||
guard let proxy = selectedProxy else { return }
|
||||
|
||||
// 4. Reload site list
|
||||
Task { @MainActor in
|
||||
App.shared.domainListWindowController?.pressedReload(nil)
|
||||
}
|
||||
do {
|
||||
// Toggle secure
|
||||
try await proxy.toggleSecure()
|
||||
|
||||
// Reload the UI
|
||||
self.reloadSelectedRow()
|
||||
|
||||
// Send a notification about the new status (if applicable)
|
||||
LocalNotification.send(
|
||||
title: "domain_list.alerts_status_changed.title".localized,
|
||||
subtitle: "domain_list.alerts_status_changed.desc"
|
||||
.localized(
|
||||
"\(proxy.domain).\(Valet.shared.config.tld)",
|
||||
proxy.secured
|
||||
),
|
||||
preference: .notifyAboutSecureToggle
|
||||
)
|
||||
} catch {
|
||||
let error = error as! ValetInteractionError
|
||||
|
||||
BetterAlert()
|
||||
.withInformation(
|
||||
title: "domain_list.alerts_status_not_changed.title".localized,
|
||||
subtitle: "domain_list.alerts_status_not_changed.desc".localized(error.command)
|
||||
)
|
||||
.withPrimary(text: "OK")
|
||||
.show()
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,38 +145,6 @@ extension DomainListVC {
|
||||
}
|
||||
}
|
||||
|
||||
@objc func openInBrowser() {
|
||||
guard let selected = self.selected else {
|
||||
return
|
||||
}
|
||||
|
||||
guard let url = selected.getListableUrl() else {
|
||||
BetterAlert()
|
||||
.withInformation(
|
||||
title: "domain_list.alert.invalid_folder_name".localized,
|
||||
subtitle: "domain_list.alert.invalid_folder_name_desc".localized
|
||||
)
|
||||
.withPrimary(text: "OK")
|
||||
.show()
|
||||
return
|
||||
}
|
||||
|
||||
NSWorkspace.shared.open(url)
|
||||
}
|
||||
|
||||
@objc func openInFinder() async {
|
||||
await Shell.quiet("open '\(selectedSite!.absolutePath)'")
|
||||
}
|
||||
|
||||
@objc func openInTerminal() async {
|
||||
await Shell.quiet("open -b com.apple.terminal '\(selectedSite!.absolutePath)'")
|
||||
}
|
||||
|
||||
@objc func openWithEditor(sender: EditorMenuItem) async {
|
||||
guard let editor = sender.editor else { return }
|
||||
await editor.openDirectory(file: selectedSite!.absolutePath)
|
||||
}
|
||||
|
||||
@objc func isolateSite(sender: PhpMenuItem) {
|
||||
let command = "sudo \(Paths.valet) isolate php@\(sender.version) --site '\(self.selectedSite!.name)' && exit;"
|
||||
|
||||
@ -178,25 +212,11 @@ extension DomainListVC {
|
||||
style: .critical,
|
||||
onFirstButtonPressed: {
|
||||
self.waitAndExecute {
|
||||
Task { await Shell.quiet("valet unproxy '\(proxy.domain)'") }
|
||||
Task { await proxy.remove() }
|
||||
} completion: {
|
||||
Task { await self.reloadDomains() }
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private func performAction(command: String, beforeCellReload: @escaping () -> Void) {
|
||||
let rowToReload = tableView.selectedRow
|
||||
|
||||
waitAndExecute {
|
||||
await Shell.quiet(command)
|
||||
} completion: { [self] in
|
||||
beforeCellReload()
|
||||
tableView.reloadData(forRowIndexes: [rowToReload], columnIndexes: [0, 1, 2, 3, 4])
|
||||
tableView.deselectRow(rowToReload)
|
||||
tableView.selectRowIndexes([rowToReload], byExtendingSelection: true)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,6 +8,11 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
struct ValetInteractionError: Error {
|
||||
/// The command the user should try (and failed).
|
||||
var command: String
|
||||
}
|
||||
|
||||
#warning("ValetInteractor needs to be implemented and used")
|
||||
class ValetInteractor {
|
||||
public static func toggleSecure(site: ValetSite) async throws {
|
||||
@ -15,7 +20,33 @@ class ValetInteractor {
|
||||
}
|
||||
|
||||
public static func toggleSecure(proxy: ValetProxy) async throws {
|
||||
// TODO
|
||||
// Keep track of the original status (secure or not?)
|
||||
let originalSecureStatus = proxy.secured
|
||||
|
||||
// Build the list of commands we will need to run
|
||||
let commands: [String] = [
|
||||
// Unproxy the given domain
|
||||
"\(Paths.valet) unproxy \(proxy.domain)",
|
||||
// Re-create the proxy (with the inverse secured status)
|
||||
originalSecureStatus
|
||||
? "\(Paths.valet) proxy \(proxy.domain) \(proxy.target)"
|
||||
: "\(Paths.valet) proxy \(proxy.domain) \(proxy.target) --secure"
|
||||
]
|
||||
|
||||
for command in commands {
|
||||
await Shell.quiet(command)
|
||||
}
|
||||
|
||||
// Check if the secured status has actually changed
|
||||
proxy.determineSecured()
|
||||
if proxy.secured == originalSecureStatus {
|
||||
throw ValetInteractionError(
|
||||
command: commands.joined(separator: " && ")
|
||||
)
|
||||
}
|
||||
|
||||
// Restart nginx to load the new configuration
|
||||
await Actions.restartNginx()
|
||||
}
|
||||
|
||||
public static func isolate(site: ValetSite, version: PhpVersionNumber) async throws {
|
||||
@ -25,4 +56,8 @@ class ValetInteractor {
|
||||
public static func unlink(site: ValetSite) async throws {
|
||||
// TODO
|
||||
}
|
||||
|
||||
public static func remove(proxy: ValetProxy) async throws {
|
||||
await Shell.quiet("valet unproxy '\(proxy.domain)'")
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ class ValetProxy: ValetListable {
|
||||
self.domain = configuration.domain
|
||||
self.tld = configuration.tld
|
||||
self.target = configuration.proxy!
|
||||
self.secured = FileSystem.fileExists("~/.config/valet/Certificates/\(self.domain).\(self.tld).key")
|
||||
self.determineSecured()
|
||||
}
|
||||
|
||||
// MARK: - ValetListable Protocol
|
||||
@ -53,7 +53,15 @@ class ValetProxy: ValetListable {
|
||||
|
||||
// MARK: - Interactions
|
||||
|
||||
func determineSecured() {
|
||||
self.secured = FileSystem.fileExists("~/.config/valet/Certificates/\(self.domain).\(self.tld).key")
|
||||
}
|
||||
|
||||
func toggleSecure() async throws {
|
||||
try await ValetInteractor.toggleSecure(proxy: self)
|
||||
}
|
||||
|
||||
func remove() async {
|
||||
try! await ValetInteractor.remove(proxy: self)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user