mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-08-07 03:50:08 +02:00
👌 Cleanup filesystem watcher code
This commit is contained in:
@ -162,6 +162,10 @@
|
|||||||
C44067F727E258410045BD4E /* DomainListPhpCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067F627E258410045BD4E /* DomainListPhpCell.swift */; };
|
C44067F727E258410045BD4E /* DomainListPhpCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067F627E258410045BD4E /* DomainListPhpCell.swift */; };
|
||||||
C44067F927E2585E0045BD4E /* DomainListTypeCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067F827E2585E0045BD4E /* DomainListTypeCell.swift */; };
|
C44067F927E2585E0045BD4E /* DomainListTypeCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067F827E2585E0045BD4E /* DomainListTypeCell.swift */; };
|
||||||
C44067FB27E25FD70045BD4E /* DomainListTLSCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067FA27E25FD70045BD4E /* DomainListTLSCell.swift */; };
|
C44067FB27E25FD70045BD4E /* DomainListTLSCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067FA27E25FD70045BD4E /* DomainListTLSCell.swift */; };
|
||||||
|
C441CC562AE8249400DDFACD /* ConfigFSNotifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = C441CC552AE8249400DDFACD /* ConfigFSNotifier.swift */; };
|
||||||
|
C441CC572AE8249400DDFACD /* ConfigFSNotifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = C441CC552AE8249400DDFACD /* ConfigFSNotifier.swift */; };
|
||||||
|
C441CC582AE8249400DDFACD /* ConfigFSNotifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = C441CC552AE8249400DDFACD /* ConfigFSNotifier.swift */; };
|
||||||
|
C441CC592AE8249400DDFACD /* ConfigFSNotifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = C441CC552AE8249400DDFACD /* ConfigFSNotifier.swift */; };
|
||||||
C44264BE2850B86C007400F1 /* SwiftUIHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44264BD2850B86C007400F1 /* SwiftUIHelper.swift */; };
|
C44264BE2850B86C007400F1 /* SwiftUIHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44264BD2850B86C007400F1 /* SwiftUIHelper.swift */; };
|
||||||
C44264C02850BD2A007400F1 /* VersionPopoverView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44264BF2850BD2A007400F1 /* VersionPopoverView.swift */; };
|
C44264C02850BD2A007400F1 /* VersionPopoverView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44264BF2850BD2A007400F1 /* VersionPopoverView.swift */; };
|
||||||
C4463FCC29804BCB007B93D5 /* RCFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4463FCB29804BCB007B93D5 /* RCFile.swift */; };
|
C4463FCC29804BCB007B93D5 /* RCFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4463FCB29804BCB007B93D5 /* RCFile.swift */; };
|
||||||
@ -424,7 +428,7 @@
|
|||||||
C471E87828F9BB650021E251 /* TerminalProgressWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44C198C276E3A1C0072762D /* TerminalProgressWindowController.swift */; };
|
C471E87828F9BB650021E251 /* TerminalProgressWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44C198C276E3A1C0072762D /* TerminalProgressWindowController.swift */; };
|
||||||
C471E87928F9BB650021E251 /* ProgressVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44A874728905BB000498BC4 /* ProgressVC.swift */; };
|
C471E87928F9BB650021E251 /* ProgressVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44A874728905BB000498BC4 /* ProgressVC.swift */; };
|
||||||
C471E87B28F9BB650021E251 /* App+ConfigWatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E817276F54D8003AC782 /* App+ConfigWatch.swift */; };
|
C471E87B28F9BB650021E251 /* App+ConfigWatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E817276F54D8003AC782 /* App+ConfigWatch.swift */; };
|
||||||
C471E87C28F9BB650021E251 /* PhpConfigWatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E81A276F54E5003AC782 /* PhpConfigWatcher.swift */; };
|
C471E87C28F9BB650021E251 /* ConfigWatchManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E81A276F54E5003AC782 /* ConfigWatchManager.swift */; };
|
||||||
C471E87D28F9BB650021E251 /* Preset.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40C5C9B2846A40600E28255 /* Preset.swift */; };
|
C471E87D28F9BB650021E251 /* Preset.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40C5C9B2846A40600E28255 /* Preset.swift */; };
|
||||||
C471E87E28F9BB650021E251 /* PresetHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C463E37F284930EE00422731 /* PresetHelper.swift */; };
|
C471E87E28F9BB650021E251 /* PresetHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C463E37F284930EE00422731 /* PresetHelper.swift */; };
|
||||||
C471E87F28F9BB650021E251 /* WarningView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4297F7928970D59004C4630 /* WarningView.swift */; };
|
C471E87F28F9BB650021E251 /* WarningView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4297F7928970D59004C4630 /* WarningView.swift */; };
|
||||||
@ -512,7 +516,7 @@
|
|||||||
C471E8DB28F9BB8F0021E251 /* TerminalProgressWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44C198C276E3A1C0072762D /* TerminalProgressWindowController.swift */; };
|
C471E8DB28F9BB8F0021E251 /* TerminalProgressWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44C198C276E3A1C0072762D /* TerminalProgressWindowController.swift */; };
|
||||||
C471E8DC28F9BB8F0021E251 /* ProgressVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44A874728905BB000498BC4 /* ProgressVC.swift */; };
|
C471E8DC28F9BB8F0021E251 /* ProgressVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44A874728905BB000498BC4 /* ProgressVC.swift */; };
|
||||||
C471E8DE28F9BB8F0021E251 /* App+ConfigWatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E817276F54D8003AC782 /* App+ConfigWatch.swift */; };
|
C471E8DE28F9BB8F0021E251 /* App+ConfigWatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E817276F54D8003AC782 /* App+ConfigWatch.swift */; };
|
||||||
C471E8DF28F9BB8F0021E251 /* PhpConfigWatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E81A276F54E5003AC782 /* PhpConfigWatcher.swift */; };
|
C471E8DF28F9BB8F0021E251 /* ConfigWatchManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E81A276F54E5003AC782 /* ConfigWatchManager.swift */; };
|
||||||
C471E8E028F9BB8F0021E251 /* Preset.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40C5C9B2846A40600E28255 /* Preset.swift */; };
|
C471E8E028F9BB8F0021E251 /* Preset.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40C5C9B2846A40600E28255 /* Preset.swift */; };
|
||||||
C471E8E128F9BB8F0021E251 /* PresetHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C463E37F284930EE00422731 /* PresetHelper.swift */; };
|
C471E8E128F9BB8F0021E251 /* PresetHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C463E37F284930EE00422731 /* PresetHelper.swift */; };
|
||||||
C471E8E228F9BB8F0021E251 /* WarningView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4297F7928970D59004C4630 /* WarningView.swift */; };
|
C471E8E228F9BB8F0021E251 /* WarningView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4297F7928970D59004C4630 /* WarningView.swift */; };
|
||||||
@ -678,8 +682,8 @@
|
|||||||
C4C8900728F0E3EF00CE5E97 /* ActiveFileSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8900628F0E3EF00CE5E97 /* ActiveFileSystem.swift */; };
|
C4C8900728F0E3EF00CE5E97 /* ActiveFileSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8900628F0E3EF00CE5E97 /* ActiveFileSystem.swift */; };
|
||||||
C4C8E818276F54D8003AC782 /* App+ConfigWatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E817276F54D8003AC782 /* App+ConfigWatch.swift */; };
|
C4C8E818276F54D8003AC782 /* App+ConfigWatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E817276F54D8003AC782 /* App+ConfigWatch.swift */; };
|
||||||
C4C8E819276F54D8003AC782 /* App+ConfigWatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E817276F54D8003AC782 /* App+ConfigWatch.swift */; };
|
C4C8E819276F54D8003AC782 /* App+ConfigWatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E817276F54D8003AC782 /* App+ConfigWatch.swift */; };
|
||||||
C4C8E81B276F54E5003AC782 /* PhpConfigWatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E81A276F54E5003AC782 /* PhpConfigWatcher.swift */; };
|
C4C8E81B276F54E5003AC782 /* ConfigWatchManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E81A276F54E5003AC782 /* ConfigWatchManager.swift */; };
|
||||||
C4C8E81C276F54E5003AC782 /* PhpConfigWatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E81A276F54E5003AC782 /* PhpConfigWatcher.swift */; };
|
C4C8E81C276F54E5003AC782 /* ConfigWatchManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E81A276F54E5003AC782 /* ConfigWatchManager.swift */; };
|
||||||
C4CB250529B28BB800CA4492 /* MainMenuTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CB250429B28BB800CA4492 /* MainMenuTest.swift */; };
|
C4CB250529B28BB800CA4492 /* MainMenuTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CB250429B28BB800CA4492 /* MainMenuTest.swift */; };
|
||||||
C4CB6E65292C362C002E9027 /* Homebrew.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CB6E64292C362C002E9027 /* Homebrew.swift */; };
|
C4CB6E65292C362C002E9027 /* Homebrew.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CB6E64292C362C002E9027 /* Homebrew.swift */; };
|
||||||
C4CB6E66292C362C002E9027 /* Homebrew.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CB6E64292C362C002E9027 /* Homebrew.swift */; };
|
C4CB6E66292C362C002E9027 /* Homebrew.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CB6E64292C362C002E9027 /* Homebrew.swift */; };
|
||||||
@ -946,6 +950,7 @@
|
|||||||
C44067F627E258410045BD4E /* DomainListPhpCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomainListPhpCell.swift; sourceTree = "<group>"; };
|
C44067F627E258410045BD4E /* DomainListPhpCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomainListPhpCell.swift; sourceTree = "<group>"; };
|
||||||
C44067F827E2585E0045BD4E /* DomainListTypeCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DomainListTypeCell.swift; sourceTree = "<group>"; };
|
C44067F827E2585E0045BD4E /* DomainListTypeCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DomainListTypeCell.swift; sourceTree = "<group>"; };
|
||||||
C44067FA27E25FD70045BD4E /* DomainListTLSCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DomainListTLSCell.swift; sourceTree = "<group>"; };
|
C44067FA27E25FD70045BD4E /* DomainListTLSCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DomainListTLSCell.swift; sourceTree = "<group>"; };
|
||||||
|
C441CC552AE8249400DDFACD /* ConfigFSNotifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigFSNotifier.swift; sourceTree = "<group>"; };
|
||||||
C44264BD2850B86C007400F1 /* SwiftUIHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIHelper.swift; sourceTree = "<group>"; };
|
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>"; };
|
C44264BF2850BD2A007400F1 /* VersionPopoverView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionPopoverView.swift; sourceTree = "<group>"; };
|
||||||
C4463FCB29804BCB007B93D5 /* RCFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RCFile.swift; sourceTree = "<group>"; };
|
C4463FCB29804BCB007B93D5 /* RCFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RCFile.swift; sourceTree = "<group>"; };
|
||||||
@ -1054,7 +1059,7 @@
|
|||||||
C4C8900428F0E3D100CE5E97 /* RealFileSystem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealFileSystem.swift; sourceTree = "<group>"; };
|
C4C8900428F0E3D100CE5E97 /* RealFileSystem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealFileSystem.swift; sourceTree = "<group>"; };
|
||||||
C4C8900628F0E3EF00CE5E97 /* ActiveFileSystem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveFileSystem.swift; sourceTree = "<group>"; };
|
C4C8900628F0E3EF00CE5E97 /* ActiveFileSystem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveFileSystem.swift; sourceTree = "<group>"; };
|
||||||
C4C8E817276F54D8003AC782 /* App+ConfigWatch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "App+ConfigWatch.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>"; };
|
C4C8E81A276F54E5003AC782 /* ConfigWatchManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfigWatchManager.swift; sourceTree = "<group>"; };
|
||||||
C4CB250429B28BB800CA4492 /* MainMenuTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainMenuTest.swift; sourceTree = "<group>"; };
|
C4CB250429B28BB800CA4492 /* MainMenuTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainMenuTest.swift; sourceTree = "<group>"; };
|
||||||
C4CB6E64292C362C002E9027 /* Homebrew.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Homebrew.swift; sourceTree = "<group>"; };
|
C4CB6E64292C362C002E9027 /* Homebrew.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Homebrew.swift; sourceTree = "<group>"; };
|
||||||
C4CCBA6B275C567B008C7055 /* PMWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PMWindowController.swift; sourceTree = "<group>"; };
|
C4CCBA6B275C567B008C7055 /* PMWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PMWindowController.swift; sourceTree = "<group>"; };
|
||||||
@ -1745,7 +1750,6 @@
|
|||||||
C4B5635D276AB09000F12CCB /* VersionExtractor.swift */,
|
C4B5635D276AB09000F12CCB /* VersionExtractor.swift */,
|
||||||
C4D3660A29113F20006BD146 /* System.swift */,
|
C4D3660A29113F20006BD146 /* System.swift */,
|
||||||
C4D36614291160A1006BD146 /* WIP.swift */,
|
C4D36614291160A1006BD146 /* WIP.swift */,
|
||||||
C41ADCE72970CCC700120423 /* FSNotifier.swift */,
|
|
||||||
C47DF1AE299D5A3B0007055D /* LoginItemManager.swift */,
|
C47DF1AE299D5A3B0007055D /* LoginItemManager.swift */,
|
||||||
C49EAA5129B12A5A00AB28FC /* Measurements.swift */,
|
C49EAA5129B12A5A00AB28FC /* Measurements.swift */,
|
||||||
);
|
);
|
||||||
@ -1964,9 +1968,11 @@
|
|||||||
C4C8E81D276F5686003AC782 /* Watcher */ = {
|
C4C8E81D276F5686003AC782 /* Watcher */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
C4C8E81A276F54E5003AC782 /* ConfigWatchManager.swift */,
|
||||||
|
C441CC552AE8249400DDFACD /* ConfigFSNotifier.swift */,
|
||||||
|
C41ADCE72970CCC700120423 /* FSNotifier.swift */,
|
||||||
C49EAA5629B1689200AB28FC /* App+BrewWatch.swift */,
|
C49EAA5629B1689200AB28FC /* App+BrewWatch.swift */,
|
||||||
C4C8E817276F54D8003AC782 /* App+ConfigWatch.swift */,
|
C4C8E817276F54D8003AC782 /* App+ConfigWatch.swift */,
|
||||||
C4C8E81A276F54E5003AC782 /* PhpConfigWatcher.swift */,
|
|
||||||
);
|
);
|
||||||
path = Watcher;
|
path = Watcher;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -2506,8 +2512,9 @@
|
|||||||
C4D4CB3729C109CF00DB9F93 /* InternalSwitcher+Valet.swift in Sources */,
|
C4D4CB3729C109CF00DB9F93 /* InternalSwitcher+Valet.swift in Sources */,
|
||||||
C46EBC4728DB9644007ACC74 /* RealShell.swift in Sources */,
|
C46EBC4728DB9644007ACC74 /* RealShell.swift in Sources */,
|
||||||
C4068CAA27B0890D00544CD5 /* MenuBarIcons.swift in Sources */,
|
C4068CAA27B0890D00544CD5 /* MenuBarIcons.swift in Sources */,
|
||||||
|
C441CC562AE8249400DDFACD /* ConfigFSNotifier.swift in Sources */,
|
||||||
C44264C02850BD2A007400F1 /* VersionPopoverView.swift in Sources */,
|
C44264C02850BD2A007400F1 /* VersionPopoverView.swift in Sources */,
|
||||||
C4C8E81B276F54E5003AC782 /* PhpConfigWatcher.swift in Sources */,
|
C4C8E81B276F54E5003AC782 /* ConfigWatchManager.swift in Sources */,
|
||||||
C417DC74277614690015E6EE /* Helpers.swift in Sources */,
|
C417DC74277614690015E6EE /* Helpers.swift in Sources */,
|
||||||
C415D3E82770F692005EF286 /* AppDelegate+InterApp.swift in Sources */,
|
C415D3E82770F692005EF286 /* AppDelegate+InterApp.swift in Sources */,
|
||||||
C41C1B3722B0097F00E7CF16 /* AppDelegate.swift in Sources */,
|
C41C1B3722B0097F00E7CF16 /* AppDelegate.swift in Sources */,
|
||||||
@ -2683,7 +2690,7 @@
|
|||||||
C471E87828F9BB650021E251 /* TerminalProgressWindowController.swift in Sources */,
|
C471E87828F9BB650021E251 /* TerminalProgressWindowController.swift in Sources */,
|
||||||
C471E87928F9BB650021E251 /* ProgressVC.swift in Sources */,
|
C471E87928F9BB650021E251 /* ProgressVC.swift in Sources */,
|
||||||
C471E87B28F9BB650021E251 /* App+ConfigWatch.swift in Sources */,
|
C471E87B28F9BB650021E251 /* App+ConfigWatch.swift in Sources */,
|
||||||
C471E87C28F9BB650021E251 /* PhpConfigWatcher.swift in Sources */,
|
C471E87C28F9BB650021E251 /* ConfigWatchManager.swift in Sources */,
|
||||||
C471E87D28F9BB650021E251 /* Preset.swift in Sources */,
|
C471E87D28F9BB650021E251 /* Preset.swift in Sources */,
|
||||||
C471E87E28F9BB650021E251 /* PresetHelper.swift in Sources */,
|
C471E87E28F9BB650021E251 /* PresetHelper.swift in Sources */,
|
||||||
C471E87F28F9BB650021E251 /* WarningView.swift in Sources */,
|
C471E87F28F9BB650021E251 /* WarningView.swift in Sources */,
|
||||||
@ -2728,6 +2735,7 @@
|
|||||||
C471E7E828F9BAC20021E251 /* Actions.swift in Sources */,
|
C471E7E828F9BAC20021E251 /* Actions.swift in Sources */,
|
||||||
C40D72612A018AE30054A067 /* BrewFormula+UI.swift in Sources */,
|
C40D72612A018AE30054A067 /* BrewFormula+UI.swift in Sources */,
|
||||||
C471E82528F9BB2E0021E251 /* ComposerWindow.swift in Sources */,
|
C471E82528F9BB2E0021E251 /* ComposerWindow.swift in Sources */,
|
||||||
|
C441CC582AE8249400DDFACD /* ConfigFSNotifier.swift in Sources */,
|
||||||
C471E80828F9BAD40021E251 /* PhpExtension.swift in Sources */,
|
C471E80828F9BAD40021E251 /* PhpExtension.swift in Sources */,
|
||||||
C471E7F928F9BACB0021E251 /* PhpSwitcher.swift in Sources */,
|
C471E7F928F9BACB0021E251 /* PhpSwitcher.swift in Sources */,
|
||||||
C471E82A28F9BB330021E251 /* ValetListable.swift in Sources */,
|
C471E82A28F9BB330021E251 /* ValetListable.swift in Sources */,
|
||||||
@ -2785,6 +2793,7 @@
|
|||||||
C471E89228F9BB8F0021E251 /* Alert.swift in Sources */,
|
C471E89228F9BB8F0021E251 /* Alert.swift in Sources */,
|
||||||
C471E89328F9BB8F0021E251 /* Application.swift in Sources */,
|
C471E89328F9BB8F0021E251 /* Application.swift in Sources */,
|
||||||
C471E89428F9BB8F0021E251 /* LocalNotification.swift in Sources */,
|
C471E89428F9BB8F0021E251 /* LocalNotification.swift in Sources */,
|
||||||
|
C441CC592AE8249400DDFACD /* ConfigFSNotifier.swift in Sources */,
|
||||||
C40934A5298EEB2C00D25014 /* CaskFile.swift in Sources */,
|
C40934A5298EEB2C00D25014 /* CaskFile.swift in Sources */,
|
||||||
C471E89528F9BB8F0021E251 /* MenuBarImageGenerator.swift in Sources */,
|
C471E89528F9BB8F0021E251 /* MenuBarImageGenerator.swift in Sources */,
|
||||||
C40D725D2A018ACC0054A067 /* PhpFormulaeStatus.swift in Sources */,
|
C40D725D2A018ACC0054A067 /* PhpFormulaeStatus.swift in Sources */,
|
||||||
@ -2871,7 +2880,7 @@
|
|||||||
C471E8DC28F9BB8F0021E251 /* ProgressVC.swift in Sources */,
|
C471E8DC28F9BB8F0021E251 /* ProgressVC.swift in Sources */,
|
||||||
C490E3BF29BCA376006D2DE6 /* Measurements.swift in Sources */,
|
C490E3BF29BCA376006D2DE6 /* Measurements.swift in Sources */,
|
||||||
C471E8DE28F9BB8F0021E251 /* App+ConfigWatch.swift in Sources */,
|
C471E8DE28F9BB8F0021E251 /* App+ConfigWatch.swift in Sources */,
|
||||||
C471E8DF28F9BB8F0021E251 /* PhpConfigWatcher.swift in Sources */,
|
C471E8DF28F9BB8F0021E251 /* ConfigWatchManager.swift in Sources */,
|
||||||
C4CB250529B28BB800CA4492 /* MainMenuTest.swift in Sources */,
|
C4CB250529B28BB800CA4492 /* MainMenuTest.swift in Sources */,
|
||||||
C40D72622A018AE30054A067 /* BrewFormula+UI.swift in Sources */,
|
C40D72622A018AE30054A067 /* BrewFormula+UI.swift in Sources */,
|
||||||
C4B79ECE29CA475900A483EE /* RemovePhpVersionCommand.swift in Sources */,
|
C4B79ECE29CA475900A483EE /* RemovePhpVersionCommand.swift in Sources */,
|
||||||
@ -3018,7 +3027,7 @@
|
|||||||
C43A8A2425D9D20D00591B77 /* HomebrewPackageTest.swift in Sources */,
|
C43A8A2425D9D20D00591B77 /* HomebrewPackageTest.swift in Sources */,
|
||||||
C485707928BF456C00539B36 /* ArrayExtension.swift in Sources */,
|
C485707928BF456C00539B36 /* ArrayExtension.swift in Sources */,
|
||||||
C4F780CA25D80B75000DBC97 /* HomebrewDecodable.swift in Sources */,
|
C4F780CA25D80B75000DBC97 /* HomebrewDecodable.swift in Sources */,
|
||||||
C4C8E81C276F54E5003AC782 /* PhpConfigWatcher.swift in Sources */,
|
C4C8E81C276F54E5003AC782 /* ConfigWatchManager.swift in Sources */,
|
||||||
C4F319C927B034A500AFF46F /* Stats.swift in Sources */,
|
C4F319C927B034A500AFF46F /* Stats.swift in Sources */,
|
||||||
C4F30B04278E16BA00755FCE /* HomebrewService.swift in Sources */,
|
C4F30B04278E16BA00755FCE /* HomebrewService.swift in Sources */,
|
||||||
54D9E0B527E4F51E003B9AD9 /* Key.swift in Sources */,
|
54D9E0B527E4F51E003B9AD9 /* Key.swift in Sources */,
|
||||||
@ -3034,6 +3043,7 @@
|
|||||||
C4CCBA6D275C567B008C7055 /* PMWindowController.swift in Sources */,
|
C4CCBA6D275C567B008C7055 /* PMWindowController.swift in Sources */,
|
||||||
C4B5635F276AB09000F12CCB /* VersionExtractor.swift in Sources */,
|
C4B5635F276AB09000F12CCB /* VersionExtractor.swift in Sources */,
|
||||||
C463E381284930EE00422731 /* PresetHelper.swift in Sources */,
|
C463E381284930EE00422731 /* PresetHelper.swift in Sources */,
|
||||||
|
C441CC572AE8249400DDFACD /* ConfigFSNotifier.swift in Sources */,
|
||||||
C46FA98C2822F08F00D78807 /* PhpConfigurationFileTest.swift in Sources */,
|
C46FA98C2822F08F00D78807 /* PhpConfigurationFileTest.swift in Sources */,
|
||||||
C4D5576529C77CC5001A44CD /* PhpVersionManagerWindowController.swift in Sources */,
|
C4D5576529C77CC5001A44CD /* PhpVersionManagerWindowController.swift in Sources */,
|
||||||
C4BF90C127C57C220054E78C /* MainMenu+FixMyValet.swift in Sources */,
|
C4BF90C127C57C220054E78C /* MainMenu+FixMyValet.swift in Sources */,
|
||||||
@ -3492,7 +3502,7 @@
|
|||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 1335;
|
CURRENT_PROJECT_VERSION = 1336;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEBUG = YES;
|
DEBUG = YES;
|
||||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||||
@ -3523,7 +3533,7 @@
|
|||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 1335;
|
CURRENT_PROJECT_VERSION = 1336;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEBUG = NO;
|
DEBUG = NO;
|
||||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||||
@ -3763,7 +3773,7 @@
|
|||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 1335;
|
CURRENT_PROJECT_VERSION = 1336;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEBUG = NO;
|
DEBUG = NO;
|
||||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||||
@ -3879,7 +3889,7 @@
|
|||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 1335;
|
CURRENT_PROJECT_VERSION = 1336;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEBUG = YES;
|
DEBUG = YES;
|
||||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||||
@ -3995,7 +4005,7 @@
|
|||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 1335;
|
CURRENT_PROJECT_VERSION = 1336;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEBUG = YES;
|
DEBUG = YES;
|
||||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||||
@ -4176,7 +4186,7 @@
|
|||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 1335;
|
CURRENT_PROJECT_VERSION = 1336;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEBUG = NO;
|
DEBUG = NO;
|
||||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||||
|
@ -97,14 +97,14 @@ class PhpConfigurationFile: CreatedFromFile {
|
|||||||
self.lines[item.lineIndex] = components.joined(separator: "=")
|
self.lines[item.lineIndex] = components.joined(separator: "=")
|
||||||
|
|
||||||
// Ensure the watchers aren't tripped up by config changes
|
// Ensure the watchers aren't tripped up by config changes
|
||||||
PhpConfigWatcher.ignoresModificationsToConfigValues = true
|
ConfigWatchManager.ignoresModificationsToConfigValues = true
|
||||||
|
|
||||||
// Finally, join the string and save the file atomatically again
|
// Finally, join the string and save the file atomatically again
|
||||||
try self.lines.joined(separator: "\n")
|
try self.lines.joined(separator: "\n")
|
||||||
.write(toFile: self.filePath, atomically: true, encoding: .utf8)
|
.write(toFile: self.filePath, atomically: true, encoding: .utf8)
|
||||||
|
|
||||||
// Ensure watcher behaviour is reverted
|
// Ensure watcher behaviour is reverted
|
||||||
PhpConfigWatcher.ignoresModificationsToConfigValues = false
|
ConfigWatchManager.ignoresModificationsToConfigValues = false
|
||||||
|
|
||||||
// Reload the original file
|
// Reload the original file
|
||||||
self.reload()
|
self.reload()
|
||||||
|
@ -89,9 +89,6 @@ class App {
|
|||||||
/** The warning manager, responsible for keeping track of warnings. */
|
/** The warning manager, responsible for keeping track of warnings. */
|
||||||
var warnings = WarningManager.shared
|
var warnings = WarningManager.shared
|
||||||
|
|
||||||
/** The filesystem watchers, responsible for keeping track of changes to the PHP installation. */
|
|
||||||
var watchers: [FSNotifier.Kind: FSNotifier] = [:]
|
|
||||||
|
|
||||||
/** Timer that will periodically reload info about the user's PHP installation. */
|
/** Timer that will periodically reload info about the user's PHP installation. */
|
||||||
var timer: Timer?
|
var timer: Timer?
|
||||||
|
|
||||||
@ -120,8 +117,12 @@ class App {
|
|||||||
|
|
||||||
// MARK: - App Watchers
|
// MARK: - App Watchers
|
||||||
|
|
||||||
/**
|
/** Individual filesystem watchers, which are, i.e. responsible for watching the Homebrew folders. */
|
||||||
The `PhpConfigWatcher` is responsible for watching the `.ini` files and the `.conf.d` folder.
|
var watchers: [String: FSNotifier] = [:]
|
||||||
|
|
||||||
|
/**
|
||||||
|
The `ConfigWatchManager` is responsible for watching the `.ini` files and the `.conf.d` folder.
|
||||||
|
This manager object can immediately start or stop all watchers (or pause them) all at once.
|
||||||
*/
|
*/
|
||||||
var watcher: PhpConfigWatcher!
|
var watchManager: ConfigWatchManager!
|
||||||
}
|
}
|
||||||
|
@ -17,13 +17,13 @@ extension App {
|
|||||||
onChange: { Task { await self.onHomebrewPhpModification() } }
|
onChange: { Task { await self.onHomebrewPhpModification() } }
|
||||||
)
|
)
|
||||||
|
|
||||||
App.shared.watchers[.homebrewBinaries] = notifier
|
App.shared.watchers["homebrewBinaries"] = notifier
|
||||||
}
|
}
|
||||||
|
|
||||||
public func destroyHomebrewWatchers() {
|
public func destroyHomebrewWatchers() {
|
||||||
// Removing requires termination and then removing reference
|
// Removing requires termination and then removing reference
|
||||||
self.watchers[.homebrewBinaries]?.terminate()
|
self.watchers["homebrewBinaries"]?.terminate()
|
||||||
self.watchers[.homebrewBinaries] = nil
|
self.watchers["homebrewBinaries"] = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
public func onHomebrewPhpModification() async {
|
public func onHomebrewPhpModification() async {
|
||||||
@ -31,10 +31,13 @@ extension App {
|
|||||||
Log.info("Something changed in the Homebrew binary directory...")
|
Log.info("Something changed in the Homebrew binary directory...")
|
||||||
await PhpEnvironments.detectPhpVersions()
|
await PhpEnvironments.detectPhpVersions()
|
||||||
await MainMenu.shared.refreshActiveInstallation()
|
await MainMenu.shared.refreshActiveInstallation()
|
||||||
// let new = PhpEnvironments.shared.currentInstall?.version.text
|
|
||||||
|
|
||||||
// TODO:
|
//
|
||||||
// Check if the new and previous version are different
|
// TODO: PHP Guard 2.0
|
||||||
// if so, we can show a notification if needed
|
// Check if the new and previous version of PHP are different
|
||||||
|
// if so, we can show a notification if needed or alert the user
|
||||||
|
//
|
||||||
|
// let new = PhpEnvironments.shared.currentInstall?.version.text
|
||||||
|
//
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,52 +10,52 @@ import Foundation
|
|||||||
|
|
||||||
extension App {
|
extension App {
|
||||||
|
|
||||||
func startWatcher(_ url: URL) {
|
func startWatchManager(_ url: URL) {
|
||||||
Log.perf("No watcher currently active...")
|
Log.perf("Starting config watch manager...")
|
||||||
self.watcher = PhpConfigWatcher(for: url)
|
self.watchManager = ConfigWatchManager(for: url)
|
||||||
|
|
||||||
self.watcher.didChange = { url in
|
self.watchManager.didChange = { url in
|
||||||
Log.perf("Something has changed in: \(url)")
|
Log.perf("Something has changed in: \(url)")
|
||||||
|
|
||||||
// Check if the watcher has last updated the menu less than 0.75s ago
|
// Check if the watcher has last updated the menu less than 0.75s ago
|
||||||
let distance = self.watcher.lastUpdate?.distance(to: Date().timeIntervalSince1970)
|
let distance = self.watchManager.lastUpdate?.distance(to: Date().timeIntervalSince1970)
|
||||||
if distance == nil || distance != nil && distance! > 0.75 {
|
if distance == nil || distance != nil && distance! > 0.75 {
|
||||||
Log.perf("Refreshing menu...")
|
Log.perf("Refreshing menu...")
|
||||||
Task { @MainActor in MainMenu.shared.reloadPhpMonitorMenuInBackground() }
|
Task { @MainActor in MainMenu.shared.reloadPhpMonitorMenuInBackground() }
|
||||||
self.watcher.lastUpdate = Date().timeIntervalSince1970
|
self.watchManager.lastUpdate = Date().timeIntervalSince1970
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func handlePhpConfigWatcher(forceReload: Bool = false) {
|
func handlePhpConfigWatcher(forceReload: Bool = false) {
|
||||||
if ActiveFileSystem.shared is TestableFileSystem {
|
if ActiveFileSystem.shared is TestableFileSystem {
|
||||||
Log.warn("FS watcher is disabled when using testable filesystem.")
|
Log.warn("Config watch manager is disabled when using testable filesystem.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let install = PhpEnvironments.phpInstall else {
|
guard let install = PhpEnvironments.phpInstall else {
|
||||||
Log.info("It appears as if no PHP installation is currently active.")
|
Log.info("It appears as if no PHP installation is currently active.")
|
||||||
Log.info("The FS watcher will be disabled until a PHP install is active.")
|
Log.info("The config watch manager be disabled until a PHP install is active.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let url = URL(fileURLWithPath: "\(Paths.etcPath)/php/\(install.version.short)")
|
let url = URL(fileURLWithPath: "\(Paths.etcPath)/php/\(install.version.short)")
|
||||||
|
|
||||||
// Check whether the watcher exists and schedule on the main thread
|
// Check whether the manager exists and schedule on the main thread
|
||||||
// if we don't consistently do this, the app will create duplicate watchers
|
// if we don't consistently do this, the app will create duplicate watchers
|
||||||
// due to timing issues, which creates retain cycles.
|
// due to timing issues, which creates retain cycles
|
||||||
Task { @MainActor in
|
Task { @MainActor in
|
||||||
// Watcher needs to be created
|
// Watcher needs to be created
|
||||||
if self.watcher == nil {
|
if self.watchManager == nil {
|
||||||
self.startWatcher(url)
|
self.startWatchManager(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Watcher needs to be updated
|
// Watcher needs to be updated
|
||||||
if self.watcher.url != url || forceReload {
|
if self.watchManager.url != url || forceReload {
|
||||||
self.watcher.disable()
|
self.watchManager.disable()
|
||||||
self.watcher = nil
|
self.watchManager = nil
|
||||||
Log.perf("Watcher has stopped watching files. Starting new one...")
|
Log.perf("Watcher has stopped watching files. Starting new one...")
|
||||||
self.startWatcher(url)
|
self.startWatchManager(url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
77
phpmon/Domain/Watcher/ConfigFSNotifier.swift
Normal file
77
phpmon/Domain/Watcher/ConfigFSNotifier.swift
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
//
|
||||||
|
// ConfigFSNotifier.swift
|
||||||
|
// PHP Monitor
|
||||||
|
//
|
||||||
|
// Created by Nico Verbruggen on 24/10/2023.
|
||||||
|
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
class ConfigFSNotifier {
|
||||||
|
|
||||||
|
enum Behaviour {
|
||||||
|
case reloadsMenu
|
||||||
|
case reloadsWatchers
|
||||||
|
}
|
||||||
|
|
||||||
|
private var parent: ConfigWatchManager!
|
||||||
|
|
||||||
|
private var monitoredFolderFileDescriptor: CInt = -1
|
||||||
|
|
||||||
|
private var folderMonitorSource: DispatchSourceFileSystemObject?
|
||||||
|
|
||||||
|
let url: URL
|
||||||
|
|
||||||
|
init(
|
||||||
|
for url: URL,
|
||||||
|
eventMask: DispatchSource.FileSystemEvent,
|
||||||
|
parent: ConfigWatchManager,
|
||||||
|
behaviour: ConfigFSNotifier.Behaviour = .reloadsMenu
|
||||||
|
) {
|
||||||
|
self.url = url
|
||||||
|
self.parent = parent
|
||||||
|
self.startMonitoring(eventMask, behaviour: behaviour)
|
||||||
|
}
|
||||||
|
|
||||||
|
func startMonitoring(
|
||||||
|
_ eventMask: DispatchSource.FileSystemEvent,
|
||||||
|
behaviour: ConfigFSNotifier.Behaviour
|
||||||
|
) {
|
||||||
|
guard folderMonitorSource == nil && monitoredFolderFileDescriptor == -1 else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
monitoredFolderFileDescriptor = open(url.path, O_EVTONLY)
|
||||||
|
folderMonitorSource = DispatchSource.makeFileSystemObjectSource(
|
||||||
|
fileDescriptor: monitoredFolderFileDescriptor,
|
||||||
|
eventMask: eventMask,
|
||||||
|
queue: parent.folderMonitorQueue
|
||||||
|
)
|
||||||
|
|
||||||
|
folderMonitorSource?.setEventHandler { [weak self] in
|
||||||
|
if behaviour == .reloadsWatchers
|
||||||
|
&& !ConfigWatchManager.ignoresModificationsToConfigValues {
|
||||||
|
// Reload all configuration watchers
|
||||||
|
return App.shared.handlePhpConfigWatcher(forceReload: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
self?.parent.didChange?(self!.url)
|
||||||
|
}
|
||||||
|
|
||||||
|
folderMonitorSource?.setCancelHandler { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
|
close(self.monitoredFolderFileDescriptor)
|
||||||
|
self.monitoredFolderFileDescriptor = -1
|
||||||
|
self.folderMonitorSource = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
folderMonitorSource?.resume()
|
||||||
|
}
|
||||||
|
|
||||||
|
func stopMonitoring() {
|
||||||
|
folderMonitorSource?.cancel()
|
||||||
|
self.parent = nil
|
||||||
|
}
|
||||||
|
}
|
82
phpmon/Domain/Watcher/ConfigWatchManager.swift
Normal file
82
phpmon/Domain/Watcher/ConfigWatchManager.swift
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
//
|
||||||
|
// ConfigWatchManager.swift
|
||||||
|
// PHP Monitor
|
||||||
|
//
|
||||||
|
// Created by Nico Verbruggen on 30/03/2021.
|
||||||
|
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
class ConfigWatchManager {
|
||||||
|
|
||||||
|
static var ignoresModificationsToConfigValues: Bool = false
|
||||||
|
|
||||||
|
let folderMonitorQueue = DispatchQueue(label: "FolderMonitorQueue", attributes: .concurrent)
|
||||||
|
|
||||||
|
let url: URL
|
||||||
|
var didChange: ((URL) -> Void)?
|
||||||
|
var lastUpdate: TimeInterval?
|
||||||
|
|
||||||
|
var watchers: [ConfigFSNotifier] = []
|
||||||
|
|
||||||
|
init(for url: URL) {
|
||||||
|
if FileSystem is TestableFileSystem {
|
||||||
|
fatalError("""
|
||||||
|
PhpConfigWatcher is not compatible with testable FS!"
|
||||||
|
You are not allowed to instantiate these while using a testable FS.
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
|
||||||
|
self.url = url
|
||||||
|
|
||||||
|
// Add a watcher for php.ini
|
||||||
|
self.addWatcher(for: self.url.appendingPathComponent("php.ini"), eventMask: .write)
|
||||||
|
|
||||||
|
// Add a watcher for conf.d (in case a new file is added or a file is deleted)
|
||||||
|
// This watcher, when triggered, will restart all watchers
|
||||||
|
self.addWatcher(for: self.url.appendingPathComponent("conf.d"), eventMask: .all, behaviour: .reloadsWatchers)
|
||||||
|
|
||||||
|
// Scan the conf.d folder for .ini files, and add a watcher for each file
|
||||||
|
let filePaths = FileManager.default.enumerator(
|
||||||
|
atPath: self.url.appendingPathComponent("conf.d").path
|
||||||
|
)?.allObjects as! [String]
|
||||||
|
|
||||||
|
// Loop over the .ini files that we discovered
|
||||||
|
filePaths.filter { $0.contains(".ini") }.forEach { (file) in
|
||||||
|
// Add a watcher for each file we have discovered
|
||||||
|
self.addWatcher(for: self.url.appendingPathComponent("conf.d/\(file)"), eventMask: .write)
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.perf("A watcher exists for the following config paths:")
|
||||||
|
Log.perf(self.watchers.map({ watcher in
|
||||||
|
return watcher.url.relativePath
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
func addWatcher(
|
||||||
|
for url: URL,
|
||||||
|
eventMask: DispatchSource.FileSystemEvent,
|
||||||
|
behaviour: ConfigFSNotifier.Behaviour = .reloadsMenu
|
||||||
|
) {
|
||||||
|
if !FileSystem.anyExists(url.path) {
|
||||||
|
Log.warn("No watcher was created for \(url.path) because the requested file does not exist.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let watcher = ConfigFSNotifier(for: url, eventMask: eventMask, parent: self, behaviour: behaviour)
|
||||||
|
self.watchers.append(watcher)
|
||||||
|
}
|
||||||
|
|
||||||
|
func disable() {
|
||||||
|
Log.perf("Turning off all individual existing watchers...")
|
||||||
|
self.watchers.forEach { (watcher) in
|
||||||
|
watcher.stopMonitoring()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
Log.perf("deinit: \(String(describing: self)).\(#function)")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -6,12 +6,9 @@
|
|||||||
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Cocoa
|
import Foundation
|
||||||
|
|
||||||
class FSNotifier {
|
class FSNotifier {
|
||||||
enum Kind {
|
|
||||||
case homebrewLocks, homebrewBinaries
|
|
||||||
}
|
|
||||||
|
|
||||||
public static var shared: FSNotifier! = nil
|
public static var shared: FSNotifier! = nil
|
||||||
|
|
||||||
@ -66,4 +63,5 @@ class FSNotifier {
|
|||||||
deinit {
|
deinit {
|
||||||
Log.perf("FSNotifier for \(self.url) will be deinitialized.")
|
Log.perf("FSNotifier for \(self.url) will be deinitialized.")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,155 +0,0 @@
|
|||||||
//
|
|
||||||
// FolderWatcher.swift
|
|
||||||
// PHP Monitor
|
|
||||||
//
|
|
||||||
// Created by Nico Verbruggen on 30/03/2021.
|
|
||||||
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
class PhpConfigWatcher {
|
|
||||||
|
|
||||||
static var ignoresModificationsToConfigValues: Bool = false
|
|
||||||
|
|
||||||
let folderMonitorQueue = DispatchQueue(label: "FolderMonitorQueue", attributes: .concurrent)
|
|
||||||
|
|
||||||
let url: URL
|
|
||||||
|
|
||||||
var didChange: ((URL) -> Void)?
|
|
||||||
|
|
||||||
var lastUpdate: TimeInterval?
|
|
||||||
|
|
||||||
var watchers: [FSWatcher] = []
|
|
||||||
|
|
||||||
init(for url: URL) {
|
|
||||||
if FileSystem is TestableFileSystem {
|
|
||||||
fatalError("""
|
|
||||||
PhpConfigWatcher is not compatible with testable FS!"
|
|
||||||
You are not allowed to instantiate these while using a testable FS.
|
|
||||||
""")
|
|
||||||
}
|
|
||||||
|
|
||||||
self.url = url
|
|
||||||
|
|
||||||
// Add a watcher for php.ini
|
|
||||||
self.addWatcher(for: self.url.appendingPathComponent("php.ini"), eventMask: .write)
|
|
||||||
|
|
||||||
// Add a watcher for conf.d (in case a new file is added or a file is deleted)
|
|
||||||
// This watcher, when triggered, will restart all watchers
|
|
||||||
self.addWatcher(for: self.url.appendingPathComponent("conf.d"), eventMask: .all, behaviour: .reloadsWatchers)
|
|
||||||
|
|
||||||
// Scan the conf.d folder for .ini files, and add a watcher for each file
|
|
||||||
let enumerator = FileManager.default.enumerator(atPath: self.url.appendingPathComponent("conf.d").path)
|
|
||||||
let filePaths = enumerator?.allObjects as! [String]
|
|
||||||
|
|
||||||
// Loop over the .ini files that we discovered
|
|
||||||
filePaths.filter { $0.contains(".ini") }.forEach { (file) in
|
|
||||||
// Add a watcher for each file we have discovered
|
|
||||||
self.addWatcher(for: self.url.appendingPathComponent("conf.d/\(file)"), eventMask: .write)
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.perf("A watcher exists for the following config paths:")
|
|
||||||
Log.perf(self.watchers.map({ watcher in
|
|
||||||
return watcher.url.relativePath
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
func addWatcher(
|
|
||||||
for url: URL,
|
|
||||||
eventMask: DispatchSource.FileSystemEvent,
|
|
||||||
behaviour: FSWatcherBehaviour = .reloadsMenu
|
|
||||||
) {
|
|
||||||
if !FileSystem.anyExists(url.path) {
|
|
||||||
Log.warn("No watcher was created for \(url.path) because the requested file does not exist.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let watcher = FSWatcher(for: url, eventMask: eventMask, parent: self, behaviour: behaviour)
|
|
||||||
self.watchers.append(watcher)
|
|
||||||
}
|
|
||||||
|
|
||||||
func disable() {
|
|
||||||
Log.perf("Turning off all individual existing watchers...")
|
|
||||||
self.watchers.forEach { (watcher) in
|
|
||||||
watcher.stopMonitoring()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
deinit {
|
|
||||||
Log.perf("deinit: \(String(describing: self)).\(#function)")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
enum FSWatcherBehaviour {
|
|
||||||
case reloadsMenu
|
|
||||||
case reloadsWatchers
|
|
||||||
}
|
|
||||||
|
|
||||||
class FSWatcher {
|
|
||||||
|
|
||||||
private var parent: PhpConfigWatcher!
|
|
||||||
|
|
||||||
private var monitoredFolderFileDescriptor: CInt = -1
|
|
||||||
|
|
||||||
private var folderMonitorSource: DispatchSourceFileSystemObject?
|
|
||||||
|
|
||||||
let url: URL
|
|
||||||
|
|
||||||
init(
|
|
||||||
for url: URL,
|
|
||||||
eventMask: DispatchSource.FileSystemEvent,
|
|
||||||
parent: PhpConfigWatcher,
|
|
||||||
behaviour: FSWatcherBehaviour = .reloadsMenu
|
|
||||||
) {
|
|
||||||
self.url = url
|
|
||||||
self.parent = parent
|
|
||||||
self.startMonitoring(eventMask, behaviour: behaviour)
|
|
||||||
}
|
|
||||||
|
|
||||||
func startMonitoring(
|
|
||||||
_ eventMask: DispatchSource.FileSystemEvent,
|
|
||||||
behaviour: FSWatcherBehaviour
|
|
||||||
) {
|
|
||||||
guard folderMonitorSource == nil && monitoredFolderFileDescriptor == -1 else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open the file or folder referenced by URL for monitoring only.
|
|
||||||
monitoredFolderFileDescriptor = open(url.path, O_EVTONLY)
|
|
||||||
folderMonitorSource = DispatchSource.makeFileSystemObjectSource(
|
|
||||||
fileDescriptor: monitoredFolderFileDescriptor,
|
|
||||||
eventMask: eventMask,
|
|
||||||
queue: parent.folderMonitorQueue
|
|
||||||
)
|
|
||||||
|
|
||||||
// Define the block to call when a file change is detected.
|
|
||||||
folderMonitorSource?.setEventHandler { [weak self] in
|
|
||||||
if behaviour == .reloadsWatchers
|
|
||||||
&& !PhpConfigWatcher.ignoresModificationsToConfigValues {
|
|
||||||
// Reload all configuration watchers
|
|
||||||
return App.shared.handlePhpConfigWatcher(forceReload: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The default behaviour is to reload the menu
|
|
||||||
self?.parent.didChange?(self!.url)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Define a cancel handler to ensure the directory is closed when the source is cancelled.
|
|
||||||
folderMonitorSource?.setCancelHandler { [weak self] in
|
|
||||||
guard let self = self else { return }
|
|
||||||
close(self.monitoredFolderFileDescriptor)
|
|
||||||
self.monitoredFolderFileDescriptor = -1
|
|
||||||
self.folderMonitorSource = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start monitoring the directory via the source.
|
|
||||||
folderMonitorSource?.resume()
|
|
||||||
}
|
|
||||||
|
|
||||||
func stopMonitoring() {
|
|
||||||
folderMonitorSource?.cancel()
|
|
||||||
self.parent = nil
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue
Block a user