mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-08-07 20:10:08 +02:00
♻️ Refactor Composer window logic
This commit is contained in:
@ -116,7 +116,7 @@
|
||||
C4AF9F78275447F100D44ED0 /* ValetConfigParserTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AF9F76275447F100D44ED0 /* ValetConfigParserTest.swift */; };
|
||||
C4AF9F7A2754499000D44ED0 /* Valet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AF9F792754499000D44ED0 /* Valet.swift */; };
|
||||
C4AF9F7B2754499000D44ED0 /* Valet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AF9F792754499000D44ED0 /* Valet.swift */; };
|
||||
C4AF9F7D275454A900D44ED0 /* ValetTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AF9F7C275454A900D44ED0 /* ValetTest.swift */; };
|
||||
C4AF9F7D275454A900D44ED0 /* ValetVersionExtractorTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AF9F7C275454A900D44ED0 /* ValetVersionExtractorTest.swift */; };
|
||||
C4B5635E276AB09000F12CCB /* VersionExtractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B5635D276AB09000F12CCB /* VersionExtractor.swift */; };
|
||||
C4B5635F276AB09000F12CCB /* VersionExtractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B5635D276AB09000F12CCB /* VersionExtractor.swift */; };
|
||||
C4B56362276AB0A500F12CCB /* VersionExtractorTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B56360276AB0A500F12CCB /* VersionExtractorTest.swift */; };
|
||||
@ -134,6 +134,8 @@
|
||||
C4B97B7C275CF20A003F3378 /* App+GlobalHotkey.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B97B7A275CF20A003F3378 /* App+GlobalHotkey.swift */; };
|
||||
C4BF90C127C57C220054E78C /* MainMenu+FixMyValet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42C49DA27C2806F0074ABAC /* MainMenu+FixMyValet.swift */; };
|
||||
C4C1019627C659B7001FACC2 /* HotKey in Frameworks */ = {isa = PBXBuildFile; productRef = C4C1019527C659B7001FACC2 /* HotKey */; };
|
||||
C4C1019B27C65C6F001FACC2 /* Process.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C1019A27C65C6F001FACC2 /* Process.swift */; };
|
||||
C4C1019C27C65C6F001FACC2 /* Process.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C1019A27C65C6F001FACC2 /* Process.swift */; };
|
||||
C4C3ED412783497000AB15D8 /* MainMenu+Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C3ED402783497000AB15D8 /* MainMenu+Startup.swift */; };
|
||||
C4C3ED4327834C5200AB15D8 /* CustomPrefs.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C3ED4227834C5200AB15D8 /* CustomPrefs.swift */; };
|
||||
C4C8E818276F54D8003AC782 /* App+ConfigWatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E817276F54D8003AC782 /* App+ConfigWatch.swift */; };
|
||||
@ -143,9 +145,9 @@
|
||||
C4CCBA6C275C567B008C7055 /* PMWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CCBA6B275C567B008C7055 /* PMWindowController.swift */; };
|
||||
C4CCBA6D275C567B008C7055 /* PMWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CCBA6B275C567B008C7055 /* PMWindowController.swift */; };
|
||||
C4CE3BB827B31F2E0086CA49 /* MainMenu+Switcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CE3BB727B31F2E0086CA49 /* MainMenu+Switcher.swift */; };
|
||||
C4CE3BBA27B31F670086CA49 /* MainMenu+Composer.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CE3BB927B31F670086CA49 /* MainMenu+Composer.swift */; };
|
||||
C4CE3BBA27B31F670086CA49 /* ComposerWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CE3BB927B31F670086CA49 /* ComposerWindow.swift */; };
|
||||
C4CE3BBB27B324230086CA49 /* MainMenu+Switcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CE3BB727B31F2E0086CA49 /* MainMenu+Switcher.swift */; };
|
||||
C4CE3BBC27B324250086CA49 /* MainMenu+Composer.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CE3BB927B31F670086CA49 /* MainMenu+Composer.swift */; };
|
||||
C4CE3BBC27B324250086CA49 /* ComposerWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CE3BB927B31F670086CA49 /* ComposerWindow.swift */; };
|
||||
C4D8016622B1584700C6DA1B /* Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D8016522B1584700C6DA1B /* Startup.swift */; };
|
||||
C4D89BC62783C99400A02B68 /* ComposerJson.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D89BC52783C99400A02B68 /* ComposerJson.swift */; };
|
||||
C4D9ADBF277610E1007277F4 /* PhpSwitcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D9ADBE277610E1007277F4 /* PhpSwitcher.swift */; };
|
||||
@ -285,7 +287,7 @@
|
||||
C4AF9F70275445FF00D44ED0 /* valet-config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "valet-config.json"; sourceTree = "<group>"; };
|
||||
C4AF9F76275447F100D44ED0 /* ValetConfigParserTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValetConfigParserTest.swift; sourceTree = "<group>"; };
|
||||
C4AF9F792754499000D44ED0 /* Valet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Valet.swift; sourceTree = "<group>"; };
|
||||
C4AF9F7C275454A900D44ED0 /* ValetTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValetTest.swift; sourceTree = "<group>"; };
|
||||
C4AF9F7C275454A900D44ED0 /* ValetVersionExtractorTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValetVersionExtractorTest.swift; sourceTree = "<group>"; };
|
||||
C4B5635D276AB09000F12CCB /* VersionExtractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionExtractor.swift; sourceTree = "<group>"; };
|
||||
C4B56360276AB0A500F12CCB /* VersionExtractorTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VersionExtractorTest.swift; sourceTree = "<group>"; };
|
||||
C4B5853B2770FE3900DA4FBE /* Paths.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Paths.swift; sourceTree = "<group>"; };
|
||||
@ -294,13 +296,14 @@
|
||||
C4B97B74275CF08C003F3378 /* AppDelegate+MenuOutlets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+MenuOutlets.swift"; sourceTree = "<group>"; };
|
||||
C4B97B77275CF1B5003F3378 /* App+ActivationPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "App+ActivationPolicy.swift"; sourceTree = "<group>"; };
|
||||
C4B97B7A275CF20A003F3378 /* App+GlobalHotkey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "App+GlobalHotkey.swift"; sourceTree = "<group>"; };
|
||||
C4C1019A27C65C6F001FACC2 /* Process.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Process.swift; sourceTree = "<group>"; };
|
||||
C4C3ED402783497000AB15D8 /* MainMenu+Startup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MainMenu+Startup.swift"; sourceTree = "<group>"; };
|
||||
C4C3ED4227834C5200AB15D8 /* CustomPrefs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomPrefs.swift; sourceTree = "<group>"; };
|
||||
C4C8E817276F54D8003AC782 /* App+ConfigWatch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "App+ConfigWatch.swift"; sourceTree = "<group>"; };
|
||||
C4C8E81A276F54E5003AC782 /* PhpConfigWatcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhpConfigWatcher.swift; sourceTree = "<group>"; };
|
||||
C4CCBA6B275C567B008C7055 /* PMWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PMWindowController.swift; sourceTree = "<group>"; };
|
||||
C4CE3BB727B31F2E0086CA49 /* MainMenu+Switcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MainMenu+Switcher.swift"; sourceTree = "<group>"; };
|
||||
C4CE3BB927B31F670086CA49 /* MainMenu+Composer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MainMenu+Composer.swift"; sourceTree = "<group>"; };
|
||||
C4CE3BB927B31F670086CA49 /* ComposerWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerWindow.swift; sourceTree = "<group>"; };
|
||||
C4D8016522B1584700C6DA1B /* Startup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Startup.swift; sourceTree = "<group>"; };
|
||||
C4D89BC52783C99400A02B68 /* ComposerJson.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerJson.swift; sourceTree = "<group>"; };
|
||||
C4D9ADBE277610E1007277F4 /* PhpSwitcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpSwitcher.swift; sourceTree = "<group>"; };
|
||||
@ -431,6 +434,7 @@
|
||||
C4B5853D2770FE3900DA4FBE /* Command.swift */,
|
||||
C4B5853B2770FE3900DA4FBE /* Paths.swift */,
|
||||
C4B5853C2770FE3900DA4FBE /* Shell.swift */,
|
||||
C4C1019A27C65C6F001FACC2 /* Process.swift */,
|
||||
C40C7F2F27722E8D00DDDCDC /* Logger.swift */,
|
||||
C417DC73277614690015E6EE /* Helpers.swift */,
|
||||
);
|
||||
@ -538,7 +542,6 @@
|
||||
C4C3ED402783497000AB15D8 /* MainMenu+Startup.swift */,
|
||||
C44CCD4827AFF3B700CE40E5 /* MainMenu+Async.swift */,
|
||||
C4CE3BB727B31F2E0086CA49 /* MainMenu+Switcher.swift */,
|
||||
C4CE3BB927B31F670086CA49 /* MainMenu+Composer.swift */,
|
||||
C42C49DA27C2806F0074ABAC /* MainMenu+FixMyValet.swift */,
|
||||
C47331A1247093B7009A0597 /* StatusMenu.swift */,
|
||||
C48D0C9525CC80B100CC7490 /* HeaderView.swift */,
|
||||
@ -630,6 +633,35 @@
|
||||
path = Common;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C4C1019727C65A11001FACC2 /* Parsers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C4AF9F76275447F100D44ED0 /* ValetConfigParserTest.swift */,
|
||||
C4F780AD25D80B37000DBC97 /* ExtensionParserTest.swift */,
|
||||
C43A8A2325D9D20D00591B77 /* BrewJsonParserTest.swift */,
|
||||
);
|
||||
path = Parsers;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C4C1019827C65A1A001FACC2 /* Versions */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C4FBFC512616485F00CDB8E1 /* PhpVersionDetectionTest.swift */,
|
||||
C48D6C73279CD3E400F26D7E /* PhpVersionNumberTest.swift */,
|
||||
C4B56360276AB0A500F12CCB /* VersionExtractorTest.swift */,
|
||||
C4AF9F7C275454A900D44ED0 /* ValetVersionExtractorTest.swift */,
|
||||
);
|
||||
path = Versions;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C4C1019927C65A4D001FACC2 /* Commands */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C4F7809B25D80344000DBC97 /* CommandTest.swift */,
|
||||
);
|
||||
path = Commands;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C4C8E81D276F5686003AC782 /* Watcher */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -649,6 +681,7 @@
|
||||
C4D89BC42783C98800A02B68 /* Composer */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C4CE3BB927B31F670086CA49 /* ComposerWindow.swift */,
|
||||
C4D89BC52783C99400A02B68 /* ComposerJson.swift */,
|
||||
C415937E27A1B54F00D2E1B7 /* PhpFrameworks.swift */,
|
||||
);
|
||||
@ -696,16 +729,11 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C4F7807D25D7F84B000DBC97 /* Info.plist */,
|
||||
C40C7F1C27720E1400DDDCDC /* Test Files */,
|
||||
C4F7809B25D80344000DBC97 /* CommandTest.swift */,
|
||||
C4F780AD25D80B37000DBC97 /* ExtensionParserTest.swift */,
|
||||
C43A8A2325D9D20D00591B77 /* BrewJsonParserTest.swift */,
|
||||
C4FBFC512616485F00CDB8E1 /* PhpVersionDetectionTest.swift */,
|
||||
C48D6C73279CD3E400F26D7E /* PhpVersionNumberTest.swift */,
|
||||
C43A8A1925D9CD1000591B77 /* Utility.swift */,
|
||||
C4AF9F76275447F100D44ED0 /* ValetConfigParserTest.swift */,
|
||||
C4AF9F7C275454A900D44ED0 /* ValetTest.swift */,
|
||||
C4B56360276AB0A500F12CCB /* VersionExtractorTest.swift */,
|
||||
C40C7F1C27720E1400DDDCDC /* Test Files */,
|
||||
C4C1019927C65A4D001FACC2 /* Commands */,
|
||||
C4C1019827C65A1A001FACC2 /* Versions */,
|
||||
C4C1019727C65A11001FACC2 /* Parsers */,
|
||||
);
|
||||
path = "phpmon-tests";
|
||||
sourceTree = "<group>";
|
||||
@ -906,6 +934,7 @@
|
||||
C42759672627662800093CAE /* NSMenuExtension.swift in Sources */,
|
||||
C464ADAF275A7A69003FCD53 /* SiteListVC.swift in Sources */,
|
||||
C44CCD4927AFF3B700CE40E5 /* MainMenu+Async.swift in Sources */,
|
||||
C4C1019B27C65C6F001FACC2 /* Process.swift in Sources */,
|
||||
C4EC1E73279DFCF40010F296 /* Events.swift in Sources */,
|
||||
C4927F0B27B2DFC200C55AFD /* Errors.swift in Sources */,
|
||||
C4B5853E2770FE3900DA4FBE /* Paths.swift in Sources */,
|
||||
@ -918,7 +947,7 @@
|
||||
C476FF9822B0DD830098105B /* Alert.swift in Sources */,
|
||||
C474B00624C0E98C00066A22 /* LocalNotification.swift in Sources */,
|
||||
C48D0C9625CC80B100CC7490 /* HeaderView.swift in Sources */,
|
||||
C4CE3BBA27B31F670086CA49 /* MainMenu+Composer.swift in Sources */,
|
||||
C4CE3BBA27B31F670086CA49 /* ComposerWindow.swift in Sources */,
|
||||
C4D9ADC8277611A0007277F4 /* InternalSwitcher.swift in Sources */,
|
||||
C4080FFA27BD956700BF2C6B /* BetterAlertVC.swift in Sources */,
|
||||
C4B5635E276AB09000F12CCB /* VersionExtractor.swift in Sources */,
|
||||
@ -962,6 +991,7 @@
|
||||
C4F319C927B034A500AFF46F /* Stats.swift in Sources */,
|
||||
C4F30B04278E16BA00755FCE /* HomebrewService.swift in Sources */,
|
||||
C4AF9F7B2754499000D44ED0 /* Valet.swift in Sources */,
|
||||
C4C1019C27C65C6F001FACC2 /* Process.swift in Sources */,
|
||||
C4F780C025D80B6E000DBC97 /* Startup.swift in Sources */,
|
||||
C4CCBA6D275C567B008C7055 /* PMWindowController.swift in Sources */,
|
||||
C4B5635F276AB09000F12CCB /* VersionExtractor.swift in Sources */,
|
||||
@ -983,7 +1013,7 @@
|
||||
C464ADB3275A87CA003FCD53 /* SiteListCell.swift in Sources */,
|
||||
C415D3E92770F692005EF286 /* AppDelegate+InterApp.swift in Sources */,
|
||||
C4AF9F78275447F100D44ED0 /* ValetConfigParserTest.swift in Sources */,
|
||||
C4CE3BBC27B324250086CA49 /* MainMenu+Composer.swift in Sources */,
|
||||
C4CE3BBC27B324250086CA49 /* ComposerWindow.swift in Sources */,
|
||||
C40B24F427A310830018C7D2 /* StatusMenu.swift in Sources */,
|
||||
C417DC75277614690015E6EE /* Helpers.swift in Sources */,
|
||||
C4080FF727BD8C6400BF2C6B /* BetterAlert.swift in Sources */,
|
||||
@ -1004,7 +1034,7 @@
|
||||
C4F30B0B278E203C00755FCE /* MainMenu+Startup.swift in Sources */,
|
||||
C40B24F227A310770018C7D2 /* Events.swift in Sources */,
|
||||
C4F30B0A278E1A1A00755FCE /* ComposerJson.swift in Sources */,
|
||||
C4AF9F7D275454A900D44ED0 /* ValetTest.swift in Sources */,
|
||||
C4AF9F7D275454A900D44ED0 /* ValetVersionExtractorTest.swift in Sources */,
|
||||
C4B56362276AB0A500F12CCB /* VersionExtractorTest.swift in Sources */,
|
||||
C4B585452770FE3900DA4FBE /* Command.swift in Sources */,
|
||||
C40B24F127A3106D0018C7D2 /* ServicesView.swift in Sources */,
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
import XCTest
|
||||
|
||||
class ValetTest: XCTestCase {
|
||||
class ValetVersionExtractorTest: XCTestCase {
|
||||
|
||||
func testDetermineValetVersion() {
|
||||
let version = valet("--version", sudo: false)
|
59
phpmon/Common/Core/Process.swift
Normal file
59
phpmon/Common/Core/Process.swift
Normal file
@ -0,0 +1,59 @@
|
||||
//
|
||||
// Process.swift
|
||||
// PHP Monitor
|
||||
//
|
||||
// Created by Nico Verbruggen on 23/02/2022.
|
||||
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension Process {
|
||||
|
||||
/**
|
||||
When a process is running in the background, it can send content to standard
|
||||
output or standard error, just like it would in a terminal. Using `listen`
|
||||
allows us to react whenever data is received by running a particular closure,
|
||||
depending on which type of data is received.
|
||||
*/
|
||||
public func listen(
|
||||
didReceiveStandardOutputData: @escaping (String) -> Void,
|
||||
didReceiveStandardErrorData: @escaping (String) -> Void
|
||||
) {
|
||||
let outputPipe = Pipe()
|
||||
let errorPipe = Pipe()
|
||||
|
||||
self.standardOutput = outputPipe
|
||||
self.standardError = errorPipe
|
||||
|
||||
[
|
||||
(outputPipe, didReceiveStandardOutputData),
|
||||
(errorPipe, didReceiveStandardErrorData)
|
||||
].forEach { (pipe: Pipe, callback: @escaping (String) -> Void) in
|
||||
pipe.fileHandleForReading.waitForDataInBackgroundAndNotify()
|
||||
NotificationCenter.default.addObserver(
|
||||
forName: NSNotification.Name.NSFileHandleDataAvailable,
|
||||
object: pipe.fileHandleForReading,
|
||||
queue: nil
|
||||
) { notification in
|
||||
if let outputString = String(data: pipe.fileHandleForReading.availableData, encoding: String.Encoding.utf8) {
|
||||
callback(outputString)
|
||||
}
|
||||
pipe.fileHandleForReading.waitForDataInBackgroundAndNotify()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
After the process is done running, you'll want to stop listening.
|
||||
*/
|
||||
public func haltListening() {
|
||||
if let pipe = self.standardOutput as? Pipe {
|
||||
NotificationCenter.default.removeObserver(pipe.fileHandleForReading)
|
||||
}
|
||||
if let pipe = self.standardError as? Pipe {
|
||||
NotificationCenter.default.removeObserver(pipe.fileHandleForReading)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -119,42 +119,6 @@ public class Shell {
|
||||
return task
|
||||
}
|
||||
|
||||
public static func captureOutput(
|
||||
_ task: Process,
|
||||
didReceiveStdOutData: @escaping (String) -> Void,
|
||||
didReceiveStdErrData: @escaping (String) -> Void
|
||||
) {
|
||||
let outputPipe = Pipe()
|
||||
let errorPipe = Pipe()
|
||||
|
||||
task.standardOutput = outputPipe
|
||||
task.standardError = errorPipe
|
||||
|
||||
[(outputPipe, didReceiveStdOutData), (errorPipe, didReceiveStdErrData)].forEach {
|
||||
(pipe: Pipe, callback: @escaping (String) -> Void) in
|
||||
pipe.fileHandleForReading.waitForDataInBackgroundAndNotify()
|
||||
NotificationCenter.default.addObserver(
|
||||
forName: NSNotification.Name.NSFileHandleDataAvailable,
|
||||
object: pipe.fileHandleForReading,
|
||||
queue: nil
|
||||
) { notification in
|
||||
if let outputString = String(data: pipe.fileHandleForReading.availableData, encoding: String.Encoding.utf8) {
|
||||
callback(outputString)
|
||||
}
|
||||
pipe.fileHandleForReading.waitForDataInBackgroundAndNotify()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static func haltCapturingOutput(_ task: Process) {
|
||||
if let pipe = task.standardOutput as? Pipe {
|
||||
NotificationCenter.default.removeObserver(pipe.fileHandleForReading)
|
||||
}
|
||||
if let pipe = task.standardError as? Pipe {
|
||||
NotificationCenter.default.removeObserver(pipe.fileHandleForReading)
|
||||
}
|
||||
}
|
||||
|
||||
public class Output {
|
||||
public let standardOutput: String
|
||||
public let errorOutput: String
|
||||
|
@ -29,6 +29,7 @@ struct ComposerJson: Decodable {
|
||||
struct Config: Decodable {
|
||||
let platform: Platform?
|
||||
}
|
||||
|
||||
struct Platform: Decodable {
|
||||
let php: String?
|
||||
}
|
||||
|
126
phpmon/Domain/Integrations/Composer/ComposerWindow.swift
Normal file
126
phpmon/Domain/Integrations/Composer/ComposerWindow.swift
Normal file
@ -0,0 +1,126 @@
|
||||
//
|
||||
// MainMenu+Composer.swift
|
||||
// PHP Monitor
|
||||
//
|
||||
// Created by Nico Verbruggen on 08/02/2022.
|
||||
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class ComposerWindow {
|
||||
|
||||
private var menu: MainMenu? = nil
|
||||
private var shouldNotify: Bool! = nil
|
||||
private var completion: ((Bool) -> Void)! = nil
|
||||
private var window: ProgressWindowController? = nil
|
||||
|
||||
/**
|
||||
Updates the global dependencies and runs the completion callback when done.
|
||||
*/
|
||||
func updateGlobalDependencies(notify: Bool, completion: @escaping (Bool) -> Void) {
|
||||
self.menu = MainMenu.shared
|
||||
self.shouldNotify = notify
|
||||
self.completion = completion
|
||||
|
||||
if !Filesystem.fileExists("/usr/local/bin/composer") {
|
||||
presentMissingSymlinkAlert()
|
||||
return
|
||||
}
|
||||
|
||||
PhpEnv.shared.isBusy = true
|
||||
menu?.setBusyImage()
|
||||
menu?.rebuild()
|
||||
|
||||
window = ProgressWindowController.display(
|
||||
title: "alert.composer_progress.title".localized,
|
||||
description: "alert.composer_progress.info".localized
|
||||
)
|
||||
|
||||
window?.setType(info: true)
|
||||
|
||||
DispatchQueue.global(qos: .userInitiated).async { [self] in
|
||||
let task = Shell.user.createTask(
|
||||
for: "/usr/local/bin/composer global update", requiresPath: true
|
||||
)
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.window?.addToConsole("/usr/local/bin/composer global update\n")
|
||||
}
|
||||
|
||||
task.listen(
|
||||
didReceiveStandardOutputData: { string in
|
||||
DispatchQueue.main.async {
|
||||
self.window?.addToConsole(string)
|
||||
}
|
||||
// Log.perf("\(string.trimmingCharacters(in: .newlines))")
|
||||
},
|
||||
didReceiveStandardErrorData: { string in
|
||||
DispatchQueue.main.async {
|
||||
self.window?.addToConsole(string)
|
||||
}
|
||||
// Log.perf("\(string.trimmingCharacters(in: .newlines))")
|
||||
}
|
||||
)
|
||||
|
||||
task.launch()
|
||||
task.waitUntilExit()
|
||||
task.haltListening()
|
||||
|
||||
if task.terminationStatus <= 0 {
|
||||
composerUpdateSucceeded()
|
||||
} else {
|
||||
composerUpdateFailed()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func composerUpdateSucceeded() {
|
||||
// Closing the window should happen after a slight delay
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { [self] in
|
||||
window?.close()
|
||||
if (shouldNotify) {
|
||||
LocalNotification.send(
|
||||
title: "alert.composer_success.title".localized,
|
||||
subtitle: "alert.composer_success.info".localized
|
||||
)
|
||||
}
|
||||
window = nil
|
||||
removeBusyStatus()
|
||||
completion(true)
|
||||
}
|
||||
}
|
||||
|
||||
private func composerUpdateFailed() {
|
||||
// Showing that something failed should be shown immediately
|
||||
DispatchQueue.main.async { [self] in
|
||||
window?.setType(info: false)
|
||||
window?.progressView?.labelTitle.stringValue = "alert.composer_failure.title".localized
|
||||
window?.progressView?.labelDescription.stringValue = "alert.composer_failure.info".localized
|
||||
window = nil
|
||||
removeBusyStatus()
|
||||
completion(false)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Main Menu Update
|
||||
|
||||
private func removeBusyStatus() {
|
||||
PhpEnv.shared.isBusy = false
|
||||
DispatchQueue.main.async { [self] in
|
||||
menu?.updatePhpVersionInStatusBar()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Alert
|
||||
|
||||
private func presentMissingSymlinkAlert() {
|
||||
BetterAlert()
|
||||
.withInformation(
|
||||
title: "alert.composer_missing.title".localized,
|
||||
subtitle: "alert.composer_missing.info".localized
|
||||
)
|
||||
.withPrimary(text: "OK")
|
||||
.show()
|
||||
}
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
//
|
||||
// MainMenu+Composer.swift
|
||||
// PHP Monitor
|
||||
//
|
||||
// Created by Nico Verbruggen on 08/02/2022.
|
||||
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension MainMenu {
|
||||
|
||||
/**
|
||||
Updates the global dependencies and runs the completion callback when done.
|
||||
This method should probably be broken up into several smaller methods at some point.
|
||||
*/
|
||||
func updateGlobalDependencies(notify: Bool, completion: @escaping (Bool) -> Void) {
|
||||
if !Filesystem.fileExists("/usr/local/bin/composer") {
|
||||
BetterAlert()
|
||||
.withInformation(
|
||||
title: "alert.composer_missing.title".localized,
|
||||
subtitle: "alert.composer_missing.info".localized
|
||||
)
|
||||
.withPrimary(text: "OK")
|
||||
.show()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
PhpEnv.shared.isBusy = true
|
||||
setBusyImage()
|
||||
self.rebuild()
|
||||
|
||||
let noLongerBusy = {
|
||||
PhpEnv.shared.isBusy = false
|
||||
DispatchQueue.main.async { [self] in
|
||||
self.updatePhpVersionInStatusBar()
|
||||
self.rebuild()
|
||||
}
|
||||
}
|
||||
|
||||
var window: ProgressWindowController? = ProgressWindowController.display(
|
||||
title: "alert.composer_progress.title".localized,
|
||||
description: "alert.composer_progress.info".localized
|
||||
)
|
||||
window?.setType(info: true)
|
||||
|
||||
DispatchQueue.global(qos: .userInitiated).async {
|
||||
let task = Shell.user.createTask(
|
||||
for: "/usr/local/bin/composer global update", requiresPath: true
|
||||
)
|
||||
|
||||
DispatchQueue.main.async {
|
||||
window?.addToConsole("/usr/local/bin/composer global update\n")
|
||||
}
|
||||
|
||||
Shell.captureOutput(
|
||||
task,
|
||||
didReceiveStdOutData: { string in
|
||||
DispatchQueue.main.async {
|
||||
window?.addToConsole(string)
|
||||
}
|
||||
Log.perf("\(string.trimmingCharacters(in: .newlines))")
|
||||
},
|
||||
didReceiveStdErrData: { string in
|
||||
DispatchQueue.main.async {
|
||||
window?.addToConsole(string)
|
||||
}
|
||||
Log.perf("\(string.trimmingCharacters(in: .newlines))")
|
||||
}
|
||||
)
|
||||
|
||||
task.launch()
|
||||
task.waitUntilExit()
|
||||
Shell.haltCapturingOutput(task)
|
||||
|
||||
DispatchQueue.main.async {
|
||||
if task.terminationStatus <= 0 {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
|
||||
window?.close()
|
||||
if (notify) {
|
||||
LocalNotification.send(
|
||||
title: "alert.composer_success.title".localized,
|
||||
subtitle: "alert.composer_success.info".localized
|
||||
)
|
||||
}
|
||||
window = nil
|
||||
noLongerBusy()
|
||||
completion(true)
|
||||
}
|
||||
} else {
|
||||
window?.setType(info: false)
|
||||
window?.progressView?.labelTitle.stringValue = "alert.composer_failure.title".localized
|
||||
window?.progressView?.labelDescription.stringValue = "alert.composer_failure.info".localized
|
||||
window = nil
|
||||
noLongerBusy()
|
||||
completion(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -39,9 +39,13 @@ extension MainMenu {
|
||||
|
||||
// Run composer updates
|
||||
if Preferences.isEnabled(.autoComposerGlobalUpdateAfterSwitch) {
|
||||
self.updateGlobalDependencies(notify: false, completion: { _ in
|
||||
self.notifyAboutVersionChange(to: version)
|
||||
})
|
||||
ComposerWindow().updateGlobalDependencies(
|
||||
notify: false,
|
||||
completion: { _ in
|
||||
self.notifyAboutVersionChange(to: version)
|
||||
}
|
||||
)
|
||||
|
||||
} else {
|
||||
self.notifyAboutVersionChange(to: version)
|
||||
}
|
||||
|
@ -265,7 +265,10 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate
|
||||
}
|
||||
|
||||
@objc func updateGlobalComposerDependencies() {
|
||||
self.updateGlobalDependencies(notify: true, completion: { _ in })
|
||||
ComposerWindow().updateGlobalDependencies(
|
||||
notify: true,
|
||||
completion: { _ in }
|
||||
)
|
||||
}
|
||||
|
||||
@objc func openActiveConfigFolder() {
|
||||
|
Reference in New Issue
Block a user