mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-08-07 03:50:08 +02:00
👌 Shell tweaks, fix ComposerWindow async issue
This commit is contained in:
@ -125,6 +125,8 @@
|
||||
C449B4F427EE7FC800C47E8A /* DomainListKindCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AC51FB27E27F47008528CA /* DomainListKindCell.swift */; };
|
||||
C44A874828905BB000498BC4 /* ProgressVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44A874728905BB000498BC4 /* ProgressVC.swift */; };
|
||||
C44A874928905BB000498BC4 /* ProgressVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44A874728905BB000498BC4 /* ProgressVC.swift */; };
|
||||
C44B3A4628E5C70100718CB1 /* TimeIntervalExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44B3A4528E5C70100718CB1 /* TimeIntervalExtension.swift */; };
|
||||
C44B3A4728E5C70100718CB1 /* TimeIntervalExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44B3A4528E5C70100718CB1 /* TimeIntervalExtension.swift */; };
|
||||
C44C198D276E3A1C0072762D /* TerminalProgressWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44C198C276E3A1C0072762D /* TerminalProgressWindowController.swift */; };
|
||||
C44C198E276E3A1C0072762D /* TerminalProgressWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44C198C276E3A1C0072762D /* TerminalProgressWindowController.swift */; };
|
||||
C44C1991276E44CB0072762D /* ProgressWindow.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C44C1990276E44CB0072762D /* ProgressWindow.storyboard */; };
|
||||
@ -412,6 +414,7 @@
|
||||
C44264BD2850B86C007400F1 /* SwiftUIHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIHelper.swift; sourceTree = "<group>"; };
|
||||
C44264BF2850BD2A007400F1 /* VersionPopoverView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionPopoverView.swift; sourceTree = "<group>"; };
|
||||
C44A874728905BB000498BC4 /* ProgressVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressVC.swift; sourceTree = "<group>"; };
|
||||
C44B3A4528E5C70100718CB1 /* TimeIntervalExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeIntervalExtension.swift; sourceTree = "<group>"; };
|
||||
C44C198C276E3A1C0072762D /* TerminalProgressWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TerminalProgressWindowController.swift; sourceTree = "<group>"; };
|
||||
C44C1990276E44CB0072762D /* ProgressWindow.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = ProgressWindow.storyboard; sourceTree = "<group>"; };
|
||||
C44CCD3F27AFE2FC00CE40E5 /* AlertableError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertableError.swift; sourceTree = "<group>"; };
|
||||
@ -1202,6 +1205,7 @@
|
||||
C40508B028ADAB44008FAC1F /* NSMenuItemExtension.swift */,
|
||||
C4E0F7EC27BEBDA9007475F2 /* NSWindowExtension.swift */,
|
||||
C4EB53E628553117006F9937 /* ArrayExtension.swift */,
|
||||
C44B3A4528E5C70100718CB1 /* TimeIntervalExtension.swift */,
|
||||
);
|
||||
path = Extensions;
|
||||
sourceTree = "<group>";
|
||||
@ -1388,6 +1392,7 @@
|
||||
C463E380284930EE00422731 /* PresetHelper.swift in Sources */,
|
||||
C41C02A927E61A65009F26CB /* ValetSite+Fake.swift in Sources */,
|
||||
C4C0E8DF27F88AEB002D32A9 /* FakeSiteScanner.swift in Sources */,
|
||||
C44B3A4628E5C70100718CB1 /* TimeIntervalExtension.swift in Sources */,
|
||||
C44264BE2850B86C007400F1 /* SwiftUIHelper.swift in Sources */,
|
||||
C4E9D2C02878B336008FFDAD /* OnboardingView.swift in Sources */,
|
||||
C4F2E4372752F0870020E974 /* HomebrewDiagnostics.swift in Sources */,
|
||||
@ -1510,6 +1515,7 @@
|
||||
C4205A7F27F4D21800191A39 /* ValetProxy.swift in Sources */,
|
||||
C42F26742805B4B400938AC7 /* DomainListable.swift in Sources */,
|
||||
C46EBC4528DB95F0007ACC74 /* Shellable.swift in Sources */,
|
||||
C44B3A4728E5C70100718CB1 /* TimeIntervalExtension.swift in Sources */,
|
||||
C4F780C425D80B75000DBC97 /* MainMenu.swift in Sources */,
|
||||
54FCFD2B276C8AA4004CE748 /* CheckboxPreferenceView.swift in Sources */,
|
||||
C415D3B82770F294005EF286 /* Actions.swift in Sources */,
|
||||
|
@ -31,7 +31,7 @@ class SystemShellTest: XCTestCase {
|
||||
func test_system_shell_can_buffer_output() async {
|
||||
var bits: [String] = []
|
||||
|
||||
let shellOutput = try! await Shell.attach(
|
||||
let (_, shellOutput) = try! await Shell.attach(
|
||||
"php -r \"echo 'Hello world' . PHP_EOL; usleep(200); echo 'Goodbye world';\"",
|
||||
didReceiveOutput: { incoming in
|
||||
bits.append(incoming.out)
|
||||
|
15
phpmon/Common/Extensions/TimeIntervalExtension.swift
Normal file
15
phpmon/Common/Extensions/TimeIntervalExtension.swift
Normal file
@ -0,0 +1,15 @@
|
||||
//
|
||||
// TimeExtension.swift
|
||||
// PHP Monitor
|
||||
//
|
||||
// Created by Nico Verbruggen on 29/09/2022.
|
||||
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension TimeInterval {
|
||||
public static func minutes(_ amount: Int) -> TimeInterval {
|
||||
return Double(amount * 60)
|
||||
}
|
||||
}
|
@ -8,8 +8,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
class ComposerWindow {
|
||||
|
||||
@MainActor class ComposerWindow {
|
||||
private var menu: MainMenu?
|
||||
private var shouldNotify: Bool! = nil
|
||||
private var completion: ((Bool) -> Void)! = nil
|
||||
@ -42,39 +41,37 @@ class ComposerWindow {
|
||||
|
||||
window?.setType(info: true)
|
||||
|
||||
DispatchQueue.global(qos: .userInitiated).async { [self] in
|
||||
let task = LegacyShell.user.createTask(
|
||||
for: "\(Paths.composer!) global update", requiresPath: true
|
||||
)
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.window?.addToConsole("\(Paths.composer!) global update\n")
|
||||
Task { await performComposerUpdate() }
|
||||
}
|
||||
|
||||
task.listen(
|
||||
didReceiveStandardOutputData: { [weak self] string in
|
||||
private func performComposerUpdate() async {
|
||||
do {
|
||||
let command = "\(Paths.composer!) global update"
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self?.window?.addToConsole(string)
|
||||
self.window?.addToConsole("\(command)\n")
|
||||
}
|
||||
|
||||
let (process, _) = try await Shell.attach(
|
||||
command,
|
||||
didReceiveOutput: { [weak self] output in
|
||||
if output.hasError {
|
||||
DispatchQueue.main.async { self?.window?.addToConsole(output.err) }
|
||||
}
|
||||
if !output.out.isEmpty {
|
||||
DispatchQueue.main.async { self?.window?.addToConsole(output.out) }
|
||||
}
|
||||
// Log.perf("\(string.trimmingCharacters(in: .newlines))")
|
||||
},
|
||||
didReceiveStandardErrorData: { [weak self] string in
|
||||
DispatchQueue.main.async {
|
||||
self?.window?.addToConsole(string)
|
||||
}
|
||||
// Log.perf("\(string.trimmingCharacters(in: .newlines))")
|
||||
}
|
||||
withTimeout: .minutes(5)
|
||||
)
|
||||
|
||||
task.launch()
|
||||
task.waitUntilExit()
|
||||
task.haltListening()
|
||||
|
||||
if task.terminationStatus <= 0 {
|
||||
if process.terminationStatus <= 0 {
|
||||
composerUpdateSucceeded()
|
||||
} else {
|
||||
composerUpdateFailed()
|
||||
}
|
||||
} catch {
|
||||
composerUpdateFailed()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -200,7 +200,7 @@ extension MainMenu {
|
||||
}
|
||||
}
|
||||
|
||||
@objc func updateGlobalComposerDependencies() {
|
||||
@MainActor @objc func updateGlobalComposerDependencies() {
|
||||
ComposerWindow().updateGlobalDependencies(
|
||||
notify: true,
|
||||
completion: { _ in }
|
||||
|
@ -58,7 +58,7 @@ protocol Shellable {
|
||||
_ command: String,
|
||||
didReceiveOutput: @escaping (ShellOutput) -> Void,
|
||||
withTimeout timeout: TimeInterval
|
||||
) async throws -> ShellOutput
|
||||
) async throws -> (Process, ShellOutput)
|
||||
}
|
||||
|
||||
enum ShellError: Error {
|
||||
|
@ -118,7 +118,7 @@ class SystemShell: Shellable {
|
||||
_ command: String,
|
||||
didReceiveOutput: @escaping (ShellOutput) -> Void,
|
||||
withTimeout timeout: TimeInterval = 5.0
|
||||
) async throws -> ShellOutput {
|
||||
) async throws -> (Process, ShellOutput) {
|
||||
let task = getShellProcess(for: command)
|
||||
|
||||
var allOut: String = ""
|
||||
@ -139,10 +139,10 @@ class SystemShell: Shellable {
|
||||
timer?.invalidate()
|
||||
|
||||
if !allErr.isEmpty {
|
||||
return continuation.resume(returning: .err(allErr))
|
||||
return continuation.resume(returning: (process, .err(allErr)))
|
||||
}
|
||||
|
||||
return continuation.resume(returning: .out(allOut))
|
||||
return continuation.resume(returning: (process, .out(allOut)))
|
||||
}
|
||||
|
||||
timer = Timer.scheduledTimer(withTimeInterval: timeout, repeats: false) { _ in
|
||||
|
@ -29,8 +29,8 @@ public class TestableShell: Shellable {
|
||||
_ command: String,
|
||||
didReceiveOutput: @escaping (ShellOutput) -> Void,
|
||||
withTimeout timeout: TimeInterval
|
||||
) async throws -> ShellOutput {
|
||||
self.sync(command)
|
||||
) async throws -> (Process, ShellOutput) {
|
||||
return (Process(), self.sync(command))
|
||||
}
|
||||
|
||||
func sync(_ command: String) -> ShellOutput {
|
||||
|
Reference in New Issue
Block a user