mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-08-07 03:50:08 +02:00
✨ Add FakeValetInteractor
This commit is contained in:
@ -91,7 +91,7 @@
|
|||||||
</CommandLineArgument>
|
</CommandLineArgument>
|
||||||
<CommandLineArgument
|
<CommandLineArgument
|
||||||
argument = "--configuration:~/.phpmon_fconf_working.json"
|
argument = "--configuration:~/.phpmon_fconf_working.json"
|
||||||
isEnabled = "NO">
|
isEnabled = "YES">
|
||||||
</CommandLineArgument>
|
</CommandLineArgument>
|
||||||
<CommandLineArgument
|
<CommandLineArgument
|
||||||
argument = "--configuration:~/.phpmon_fconf_broken.json"
|
argument = "--configuration:~/.phpmon_fconf_broken.json"
|
||||||
|
@ -26,6 +26,8 @@ public struct TestableConfiguration: Codable {
|
|||||||
ActiveCommand.useTestable(commandOutput)
|
ActiveCommand.useTestable(commandOutput)
|
||||||
Log.info("Applying fake scanner...")
|
Log.info("Applying fake scanner...")
|
||||||
ValetScanners.useFake()
|
ValetScanners.useFake()
|
||||||
|
Log.info("Applying fake Valet domain interactor...")
|
||||||
|
ValetInteractor.useFake()
|
||||||
}
|
}
|
||||||
|
|
||||||
func toJson(pretty: Bool = false) -> String {
|
func toJson(pretty: Bool = false) -> String {
|
||||||
|
@ -72,6 +72,7 @@ class AddProxyVC: NSViewController, NSTextFieldDelegate {
|
|||||||
App.shared.domainListWindowController?.contentVC.setUIBusy()
|
App.shared.domainListWindowController?.contentVC.setUIBusy()
|
||||||
|
|
||||||
Task { // Ensure we proxy the site asynchronously and reload UI on main thread again
|
Task { // Ensure we proxy the site asynchronously and reload UI on main thread again
|
||||||
|
#warning("Creating a proxy should happen via the ValetInteractor")
|
||||||
await Shell.quiet("\(Paths.valet) proxy \(domain) \(proxyName)\(secure)")
|
await Shell.quiet("\(Paths.valet) proxy \(domain) \(proxyName)\(secure)")
|
||||||
await Actions.restartNginx()
|
await Actions.restartNginx()
|
||||||
|
|
||||||
|
@ -71,6 +71,7 @@ class AddSiteVC: NSViewController, NSTextFieldDelegate {
|
|||||||
|
|
||||||
// Adding `valet links` is a workaround for Valet malforming the config.json file
|
// Adding `valet links` is a workaround for Valet malforming the config.json file
|
||||||
// TODO: I will have to investigate and report this behaviour if possible
|
// TODO: I will have to investigate and report this behaviour if possible
|
||||||
|
#warning("Linking a site should happen via the ValetInteractor")
|
||||||
Task { await Shell.quiet("cd '\(path)' && \(Paths.valet) link '\(name)' && valet links") }
|
Task { await Shell.quiet("cd '\(path)' && \(Paths.valet) link '\(name)' && valet links") }
|
||||||
|
|
||||||
dismissView(outcome: .OK)
|
dismissView(outcome: .OK)
|
||||||
|
@ -68,7 +68,7 @@ extension DomainListVC {
|
|||||||
|
|
||||||
@objc func toggleSecure() {
|
@objc func toggleSecure() {
|
||||||
if selected is ValetSite {
|
if selected is ValetSite {
|
||||||
Task { toggleSecureForSite() }
|
Task { await toggleSecureForSite() }
|
||||||
} else {
|
} else {
|
||||||
Task { await toggleSecureForProxy() }
|
Task { await toggleSecureForProxy() }
|
||||||
}
|
}
|
||||||
@ -78,74 +78,33 @@ extension DomainListVC {
|
|||||||
guard let proxy = selectedProxy else { return }
|
guard let proxy = selectedProxy else { return }
|
||||||
|
|
||||||
do {
|
do {
|
||||||
// Toggle secure
|
// Recreate proxy as secure or unsecured proxy
|
||||||
try await proxy.toggleSecure()
|
try await proxy.toggleSecure()
|
||||||
|
|
||||||
// Send a notification about the new status (if applicable)
|
// Send a notification about the new status (if applicable)
|
||||||
LocalNotification.send(
|
self.notifyAboutModifiedSecureStatus(domain: proxy.domain, secured: proxy.secured)
|
||||||
title: "domain_list.alerts_status_changed.title".localized,
|
|
||||||
subtitle: "domain_list.alerts_status_changed.desc"
|
|
||||||
.localized(
|
|
||||||
// 1. The domain that was secured is listed
|
|
||||||
"\(proxy.domain).\(Valet.shared.config.tld)",
|
|
||||||
// 2. What the domain is is listed (secure / unsecure)
|
|
||||||
proxy.secured
|
|
||||||
? "domain_list.alerts_status_secure".localized
|
|
||||||
: "domain_list.alerts_status_secure".localized
|
|
||||||
),
|
|
||||||
preference: .notifyAboutSecureToggle
|
|
||||||
)
|
|
||||||
|
|
||||||
// Reload the UI (do this last so we don't invalidate the proxy)
|
// Reload the UI (do this last so we don't invalidate the proxy)
|
||||||
self.reloadSelectedRow()
|
self.reloadSelectedRow()
|
||||||
} catch {
|
} catch {
|
||||||
|
// Notify the user about a failed command
|
||||||
let error = error as! ValetInteractionError
|
let error = error as! ValetInteractionError
|
||||||
|
self.notifyAboutFailedSecureStatus(command: error.command)
|
||||||
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()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func toggleSecureForSite() {
|
func toggleSecureForSite() async {
|
||||||
let rowToReload = tableView.selectedRow
|
guard let site = selectedSite else { return }
|
||||||
let originalSecureStatus = selectedSite!.secured
|
|
||||||
let action = selectedSite!.secured ? "unsecure" : "secure"
|
|
||||||
let selectedSite = selectedSite!
|
|
||||||
let command = "cd '\(selectedSite.absolutePath)' && sudo \(Paths.valet) \(action) && exit;"
|
|
||||||
|
|
||||||
waitAndExecute {
|
do {
|
||||||
await Shell.quiet(command)
|
// Instruct Valet to secure or unsecure a site
|
||||||
} completion: { [self] in
|
try await site.toggleSecure()
|
||||||
selectedSite.determineSecured()
|
// Send a notification about the new status (if applicable)
|
||||||
if selectedSite.secured == originalSecureStatus {
|
self.notifyAboutModifiedSecureStatus(domain: site.name, secured: site.secured)
|
||||||
BetterAlert()
|
// Reload the UI (do this last so we don't invalidate the proxy)
|
||||||
.withInformation(
|
self.reloadSelectedRow()
|
||||||
title: "domain_list.alerts_status_not_changed.title".localized,
|
} catch {
|
||||||
subtitle: "domain_list.alerts_status_not_changed.desc".localized(command)
|
// Notify the user about a failed command
|
||||||
)
|
let error = error as! ValetInteractionError
|
||||||
.withPrimary(text: "OK")
|
self.notifyAboutFailedSecureStatus(command: error.command)
|
||||||
.show()
|
|
||||||
} else {
|
|
||||||
let newState = selectedSite.secured ? "secured" : "unsecured"
|
|
||||||
LocalNotification.send(
|
|
||||||
title: "domain_list.alerts_status_changed.title".localized,
|
|
||||||
subtitle: "domain_list.alerts_status_changed.desc"
|
|
||||||
.localized(
|
|
||||||
"\(selectedSite.name).\(Valet.shared.config.tld)",
|
|
||||||
newState
|
|
||||||
),
|
|
||||||
preference: .notifyAboutSecureToggle
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
tableView.reloadData(forRowIndexes: [rowToReload], columnIndexes: [0, 1, 2, 3, 4])
|
|
||||||
tableView.deselectRow(rowToReload)
|
|
||||||
tableView.selectRowIndexes([rowToReload], byExtendingSelection: true)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,4 +182,32 @@ extension DomainListVC {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Alerts & Modals
|
||||||
|
|
||||||
|
private func notifyAboutModifiedSecureStatus(domain: String, secured: Bool) {
|
||||||
|
LocalNotification.send(
|
||||||
|
title: "domain_list.alerts_status_changed.title".localized,
|
||||||
|
subtitle: "domain_list.alerts_status_changed.desc"
|
||||||
|
.localized(
|
||||||
|
// 1. The domain that was secured is listed
|
||||||
|
"\(domain).\(Valet.shared.config.tld)",
|
||||||
|
// 2. What the domain is is listed (secure / unsecure)
|
||||||
|
secured
|
||||||
|
? "domain_list.alerts_status_secure".localized
|
||||||
|
: "domain_list.alerts_status_unsecure".localized
|
||||||
|
),
|
||||||
|
preference: .notifyAboutSecureToggle
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func notifyAboutFailedSecureStatus(command: String) {
|
||||||
|
BetterAlert()
|
||||||
|
.withInformation(
|
||||||
|
title: "domain_list.alerts_status_not_changed.title".localized,
|
||||||
|
subtitle: "domain_list.alerts_status_not_changed.desc".localized(command)
|
||||||
|
)
|
||||||
|
.withPrimary(text: "OK")
|
||||||
|
.show()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,11 +15,31 @@ struct ValetInteractionError: Error {
|
|||||||
|
|
||||||
#warning("ValetInteractor needs to be implemented and used")
|
#warning("ValetInteractor needs to be implemented and used")
|
||||||
class ValetInteractor {
|
class ValetInteractor {
|
||||||
public static func toggleSecure(site: ValetSite) async throws {
|
static var shared = ValetInteractor()
|
||||||
// TODO
|
|
||||||
|
public static func useFake() {
|
||||||
|
ValetInteractor.shared = FakeValetInteractor()
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func toggleSecure(proxy: ValetProxy) async throws {
|
public func toggleSecure(site: ValetSite) async throws {
|
||||||
|
// Keep track of the original status (secure or not?)
|
||||||
|
let originalSecureStatus = site.secured
|
||||||
|
|
||||||
|
// Keep track of the command we wish to run
|
||||||
|
let action = site.secured ? "unsecure" : "secure"
|
||||||
|
let command = "cd '\(site.absolutePath)' && sudo \(Paths.valet) \(action) && exit;"
|
||||||
|
|
||||||
|
// Run the command
|
||||||
|
await Shell.quiet(command)
|
||||||
|
|
||||||
|
// Check if the secured status has actually changed
|
||||||
|
site.determineSecured()
|
||||||
|
if site.secured == originalSecureStatus {
|
||||||
|
throw ValetInteractionError(command: command)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func toggleSecure(proxy: ValetProxy) async throws {
|
||||||
// Keep track of the original status (secure or not?)
|
// Keep track of the original status (secure or not?)
|
||||||
let originalSecureStatus = proxy.secured
|
let originalSecureStatus = proxy.secured
|
||||||
|
|
||||||
@ -33,6 +53,7 @@ class ValetInteractor {
|
|||||||
: "\(Paths.valet) proxy \(proxy.domain) \(proxy.target) --secure"
|
: "\(Paths.valet) proxy \(proxy.domain) \(proxy.target) --secure"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
// Run the commands
|
||||||
for command in commands {
|
for command in commands {
|
||||||
await Shell.quiet(command)
|
await Shell.quiet(command)
|
||||||
}
|
}
|
||||||
@ -49,15 +70,29 @@ class ValetInteractor {
|
|||||||
await Actions.restartNginx()
|
await Actions.restartNginx()
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func isolate(site: ValetSite, version: PhpVersionNumber) async throws {
|
public func isolate(site: ValetSite, version: PhpVersionNumber) async throws {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func unlink(site: ValetSite) async throws {
|
public func unlink(site: ValetSite) async throws {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func remove(proxy: ValetProxy) async throws {
|
public func remove(proxy: ValetProxy) async throws {
|
||||||
await Shell.quiet("valet unproxy '\(proxy.domain)'")
|
await Shell.quiet("valet unproxy '\(proxy.domain)'")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class FakeValetInteractor: ValetInteractor {
|
||||||
|
override func toggleSecure(proxy: ValetProxy) async throws {
|
||||||
|
proxy.secured = !proxy.secured
|
||||||
|
}
|
||||||
|
|
||||||
|
override func toggleSecure(site: ValetSite) async throws {
|
||||||
|
site.secured = !site.secured
|
||||||
|
}
|
||||||
|
|
||||||
|
override func remove(proxy: ValetProxy) async throws {
|
||||||
|
fatalError("This should remove the proxy")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -58,10 +58,10 @@ class ValetProxy: ValetListable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func toggleSecure() async throws {
|
func toggleSecure() async throws {
|
||||||
try await ValetInteractor.toggleSecure(proxy: self)
|
try await ValetInteractor.shared.toggleSecure(proxy: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
func remove() async {
|
func remove() async {
|
||||||
try! await ValetInteractor.remove(proxy: self)
|
try! await ValetInteractor.shared.remove(proxy: self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -266,14 +266,14 @@ class ValetSite: ValetListable {
|
|||||||
// MARK: - Interactions
|
// MARK: - Interactions
|
||||||
|
|
||||||
func toggleSecure() async throws {
|
func toggleSecure() async throws {
|
||||||
try await ValetInteractor.toggleSecure(site: self)
|
try await ValetInteractor.shared.toggleSecure(site: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
func isolate(version: PhpVersionNumber) async throws {
|
func isolate(version: PhpVersionNumber) async throws {
|
||||||
try await ValetInteractor.isolate(site: self, version: version)
|
try await ValetInteractor.shared.isolate(site: self, version: version)
|
||||||
}
|
}
|
||||||
|
|
||||||
func unlink() async throws {
|
func unlink() async throws {
|
||||||
try await ValetInteractor.unlink(site: self)
|
try await ValetInteractor.shared.unlink(site: self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user