1
0
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:
2022-12-13 22:56:36 +01:00
parent 04c78eba35
commit 1f165058b2
4 changed files with 133 additions and 70 deletions

View File

@ -91,7 +91,7 @@
</CommandLineArgument>
<CommandLineArgument
argument = "--configuration:~/.phpmon_fconf_working.json"
isEnabled = "YES">
isEnabled = "NO">
</CommandLineArgument>
<CommandLineArgument
argument = "--configuration:~/.phpmon_fconf_broken.json"

View File

@ -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)
}
}
}

View File

@ -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)'")
}
}

View File

@ -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)
}
}