mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2026-03-29 16:10:08 +02:00
♻️ Reworked command history
This commit is contained in:
@@ -189,6 +189,8 @@
|
|||||||
03CC1FF52E3D23130050FC18 /* ZshRunCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03CC1FF32E3D230B0050FC18 /* ZshRunCommand.swift */; };
|
03CC1FF52E3D23130050FC18 /* ZshRunCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03CC1FF32E3D230B0050FC18 /* ZshRunCommand.swift */; };
|
||||||
03CC1FF62E3D23130050FC18 /* ZshRunCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03CC1FF32E3D230B0050FC18 /* ZshRunCommand.swift */; };
|
03CC1FF62E3D23130050FC18 /* ZshRunCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03CC1FF32E3D230B0050FC18 /* ZshRunCommand.swift */; };
|
||||||
03CC1FF72E3D23130050FC18 /* ZshRunCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03CC1FF32E3D230B0050FC18 /* ZshRunCommand.swift */; };
|
03CC1FF72E3D23130050FC18 /* ZshRunCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03CC1FF32E3D230B0050FC18 /* ZshRunCommand.swift */; };
|
||||||
|
03D0F9752F4DE6FE00613D1E /* TestableCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E49DEC28F764A00026AC4E /* TestableCommand.swift */; };
|
||||||
|
03D0F9762F4DE6FE00613D1E /* TestableShell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4928DB966A007ACC74 /* TestableShell.swift */; };
|
||||||
03D846252EB6344E006EFE3C /* DomainListVC+Window.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03D846242EB6344A006EFE3C /* DomainListVC+Window.swift */; };
|
03D846252EB6344E006EFE3C /* DomainListVC+Window.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03D846242EB6344A006EFE3C /* DomainListVC+Window.swift */; };
|
||||||
03D846262EB6344E006EFE3C /* DomainListVC+Window.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03D846242EB6344A006EFE3C /* DomainListVC+Window.swift */; };
|
03D846262EB6344E006EFE3C /* DomainListVC+Window.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03D846242EB6344A006EFE3C /* DomainListVC+Window.swift */; };
|
||||||
03D846272EB6344E006EFE3C /* DomainListVC+Window.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03D846242EB6344A006EFE3C /* DomainListVC+Window.swift */; };
|
03D846272EB6344E006EFE3C /* DomainListVC+Window.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03D846242EB6344A006EFE3C /* DomainListVC+Window.swift */; };
|
||||||
@@ -487,8 +489,8 @@
|
|||||||
C46EBC4528DB95F0007ACC74 /* ShellProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4328DB95F0007ACC74 /* ShellProtocol.swift */; };
|
C46EBC4528DB95F0007ACC74 /* ShellProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4328DB95F0007ACC74 /* ShellProtocol.swift */; };
|
||||||
C46EBC4728DB9644007ACC74 /* RealShell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4628DB9644007ACC74 /* RealShell.swift */; };
|
C46EBC4728DB9644007ACC74 /* RealShell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4628DB9644007ACC74 /* RealShell.swift */; };
|
||||||
C46EBC4828DB9644007ACC74 /* RealShell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4628DB9644007ACC74 /* RealShell.swift */; };
|
C46EBC4828DB9644007ACC74 /* RealShell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4628DB9644007ACC74 /* RealShell.swift */; };
|
||||||
C46EBC4A28DB966A007ACC74 /* TestableShell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4928DB966A007ACC74 /* TestableShell.swift */; };
|
|
||||||
C46EBC4B28DB966A007ACC74 /* TestableShell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4928DB966A007ACC74 /* TestableShell.swift */; };
|
C46EBC4B28DB966A007ACC74 /* TestableShell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4928DB966A007ACC74 /* TestableShell.swift */; };
|
||||||
|
C46EBC4C28DB95F0007ACC74 /* TrackedShell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4A28DB966A007ACC74 /* TrackedShell.swift */; };
|
||||||
C46FA23F246C358E00944F05 /* StringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46FA23E246C358E00944F05 /* StringExtension.swift */; };
|
C46FA23F246C358E00944F05 /* StringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46FA23E246C358E00944F05 /* StringExtension.swift */; };
|
||||||
C46FA9882822EFDC00D78807 /* PhpConfigurationFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46FA9872822EFDC00D78807 /* PhpConfigurationFile.swift */; };
|
C46FA9882822EFDC00D78807 /* PhpConfigurationFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46FA9872822EFDC00D78807 /* PhpConfigurationFile.swift */; };
|
||||||
C46FA9892822EFDC00D78807 /* PhpConfigurationFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46FA9872822EFDC00D78807 /* PhpConfigurationFile.swift */; };
|
C46FA9892822EFDC00D78807 /* PhpConfigurationFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46FA9872822EFDC00D78807 /* PhpConfigurationFile.swift */; };
|
||||||
@@ -547,9 +549,13 @@
|
|||||||
C471E7F628F9BAC80021E251 /* PhpHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D936C827E3EB6100BD69FE /* PhpHelper.swift */; };
|
C471E7F628F9BAC80021E251 /* PhpHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D936C827E3EB6100BD69FE /* PhpHelper.swift */; };
|
||||||
C471E7F728F9BACB0021E251 /* PhpSwitcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D9ADBE277610E1007277F4 /* PhpSwitcher.swift */; };
|
C471E7F728F9BACB0021E251 /* PhpSwitcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D9ADBE277610E1007277F4 /* PhpSwitcher.swift */; };
|
||||||
C471E7F828F9BACB0021E251 /* InternalSwitcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D9ADC7277611A0007277F4 /* InternalSwitcher.swift */; };
|
C471E7F828F9BACB0021E251 /* InternalSwitcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D9ADC7277611A0007277F4 /* InternalSwitcher.swift */; };
|
||||||
|
C471E7F928F9BA600021E251 /* TrackedShell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4A28DB966A007ACC74 /* TrackedShell.swift */; };
|
||||||
C471E7F928F9BACB0021E251 /* PhpSwitcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D9ADBE277610E1007277F4 /* PhpSwitcher.swift */; };
|
C471E7F928F9BACB0021E251 /* PhpSwitcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D9ADBE277610E1007277F4 /* PhpSwitcher.swift */; };
|
||||||
|
C471E7FA28F9BA8F0021E251 /* TrackedShell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4A28DB966A007ACC74 /* TrackedShell.swift */; };
|
||||||
C471E7FA28F9BACB0021E251 /* InternalSwitcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D9ADC7277611A0007277F4 /* InternalSwitcher.swift */; };
|
C471E7FA28F9BACB0021E251 /* InternalSwitcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D9ADC7277611A0007277F4 /* InternalSwitcher.swift */; };
|
||||||
|
C471E7FB28F9BAA30021E251 /* TrackedCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E49DED28F764A00026AC4E /* TrackedCommand.swift */; };
|
||||||
C471E7FB28F9BACE0021E251 /* HomebrewService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4F30B02278E16BA00755FCE /* HomebrewService.swift */; };
|
C471E7FB28F9BACE0021E251 /* HomebrewService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4F30B02278E16BA00755FCE /* HomebrewService.swift */; };
|
||||||
|
C471E7FC28F9BAA30021E251 /* TrackedCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E49DED28F764A00026AC4E /* TrackedCommand.swift */; };
|
||||||
C471E7FC28F9BACE0021E251 /* HomebrewDecodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C412E5FB25700D5300A1FB67 /* HomebrewDecodable.swift */; };
|
C471E7FC28F9BACE0021E251 /* HomebrewDecodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C412E5FB25700D5300A1FB67 /* HomebrewDecodable.swift */; };
|
||||||
C471E7FD28F9BACE0021E251 /* HomebrewService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4F30B02278E16BA00755FCE /* HomebrewService.swift */; };
|
C471E7FD28F9BACE0021E251 /* HomebrewService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4F30B02278E16BA00755FCE /* HomebrewService.swift */; };
|
||||||
C471E7FE28F9BACE0021E251 /* HomebrewDecodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C412E5FB25700D5300A1FB67 /* HomebrewDecodable.swift */; };
|
C471E7FE28F9BACE0021E251 /* HomebrewDecodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C412E5FB25700D5300A1FB67 /* HomebrewDecodable.swift */; };
|
||||||
@@ -968,8 +974,9 @@
|
|||||||
C4E4404727C56F4700D225E1 /* ValetSite.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E4404527C56F4700D225E1 /* ValetSite.swift */; };
|
C4E4404727C56F4700D225E1 /* ValetSite.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E4404527C56F4700D225E1 /* ValetSite.swift */; };
|
||||||
C4E49DEA28F7643D0026AC4E /* CommandProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E49DE928F7643D0026AC4E /* CommandProtocol.swift */; };
|
C4E49DEA28F7643D0026AC4E /* CommandProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E49DE928F7643D0026AC4E /* CommandProtocol.swift */; };
|
||||||
C4E49DEB28F7643D0026AC4E /* CommandProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E49DE928F7643D0026AC4E /* CommandProtocol.swift */; };
|
C4E49DEB28F7643D0026AC4E /* CommandProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E49DE928F7643D0026AC4E /* CommandProtocol.swift */; };
|
||||||
C4E49DED28F764A00026AC4E /* TestableCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E49DEC28F764A00026AC4E /* TestableCommand.swift */; };
|
|
||||||
C4E49DEE28F764A00026AC4E /* TestableCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E49DEC28F764A00026AC4E /* TestableCommand.swift */; };
|
C4E49DEE28F764A00026AC4E /* TestableCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E49DEC28F764A00026AC4E /* TestableCommand.swift */; };
|
||||||
|
C4E49DF028F764A00026AC4E /* TrackedCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E49DED28F764A00026AC4E /* TrackedCommand.swift */; };
|
||||||
|
C4E49DF128F764A00026AC4E /* TrackedCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E49DED28F764A00026AC4E /* TrackedCommand.swift */; };
|
||||||
C4E684092AF26B830023ED25 /* BrewTapFormulae.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E684082AF26B830023ED25 /* BrewTapFormulae.swift */; };
|
C4E684092AF26B830023ED25 /* BrewTapFormulae.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E684082AF26B830023ED25 /* BrewTapFormulae.swift */; };
|
||||||
C4E6840A2AF26B830023ED25 /* BrewTapFormulae.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E684082AF26B830023ED25 /* BrewTapFormulae.swift */; };
|
C4E6840A2AF26B830023ED25 /* BrewTapFormulae.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E684082AF26B830023ED25 /* BrewTapFormulae.swift */; };
|
||||||
C4E6840B2AF26B830023ED25 /* BrewTapFormulae.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E684082AF26B830023ED25 /* BrewTapFormulae.swift */; };
|
C4E6840B2AF26B830023ED25 /* BrewTapFormulae.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E684082AF26B830023ED25 /* BrewTapFormulae.swift */; };
|
||||||
@@ -1267,6 +1274,7 @@
|
|||||||
C46EBC4328DB95F0007ACC74 /* ShellProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShellProtocol.swift; sourceTree = "<group>"; };
|
C46EBC4328DB95F0007ACC74 /* ShellProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShellProtocol.swift; sourceTree = "<group>"; };
|
||||||
C46EBC4628DB9644007ACC74 /* RealShell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealShell.swift; sourceTree = "<group>"; };
|
C46EBC4628DB9644007ACC74 /* RealShell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealShell.swift; sourceTree = "<group>"; };
|
||||||
C46EBC4928DB966A007ACC74 /* TestableShell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestableShell.swift; sourceTree = "<group>"; };
|
C46EBC4928DB966A007ACC74 /* TestableShell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestableShell.swift; sourceTree = "<group>"; };
|
||||||
|
C46EBC4A28DB966A007ACC74 /* TrackedShell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackedShell.swift; sourceTree = "<group>"; };
|
||||||
C46FA23E246C358E00944F05 /* StringExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringExtension.swift; sourceTree = "<group>"; };
|
C46FA23E246C358E00944F05 /* StringExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringExtension.swift; sourceTree = "<group>"; };
|
||||||
C46FA9872822EFDC00D78807 /* PhpConfigurationFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpConfigurationFile.swift; sourceTree = "<group>"; };
|
C46FA9872822EFDC00D78807 /* PhpConfigurationFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpConfigurationFile.swift; sourceTree = "<group>"; };
|
||||||
C46FA98A2822F08F00D78807 /* PhpConfigurationFileTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpConfigurationFileTest.swift; sourceTree = "<group>"; };
|
C46FA98A2822F08F00D78807 /* PhpConfigurationFileTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpConfigurationFileTest.swift; sourceTree = "<group>"; };
|
||||||
@@ -1363,6 +1371,7 @@
|
|||||||
C4E4404527C56F4700D225E1 /* ValetSite.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValetSite.swift; sourceTree = "<group>"; };
|
C4E4404527C56F4700D225E1 /* ValetSite.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValetSite.swift; sourceTree = "<group>"; };
|
||||||
C4E49DE928F7643D0026AC4E /* CommandProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommandProtocol.swift; sourceTree = "<group>"; };
|
C4E49DE928F7643D0026AC4E /* CommandProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommandProtocol.swift; sourceTree = "<group>"; };
|
||||||
C4E49DEC28F764A00026AC4E /* TestableCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestableCommand.swift; sourceTree = "<group>"; };
|
C4E49DEC28F764A00026AC4E /* TestableCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestableCommand.swift; sourceTree = "<group>"; };
|
||||||
|
C4E49DED28F764A00026AC4E /* TrackedCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackedCommand.swift; sourceTree = "<group>"; };
|
||||||
C4E684082AF26B830023ED25 /* BrewTapFormulae.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrewTapFormulae.swift; sourceTree = "<group>"; };
|
C4E684082AF26B830023ED25 /* BrewTapFormulae.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrewTapFormulae.swift; sourceTree = "<group>"; };
|
||||||
C4E713562570150F00007428 /* SECURITY.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = SECURITY.md; sourceTree = "<group>"; };
|
C4E713562570150F00007428 /* SECURITY.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = SECURITY.md; sourceTree = "<group>"; };
|
||||||
C4E713572570151400007428 /* docs */ = {isa = PBXFileReference; lastKnownFileType = folder; path = docs; sourceTree = "<group>"; };
|
C4E713572570151400007428 /* docs */ = {isa = PBXFileReference; lastKnownFileType = folder; path = docs; sourceTree = "<group>"; };
|
||||||
@@ -1573,6 +1582,16 @@
|
|||||||
path = Container;
|
path = Container;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
03D0F9772F4DE7E800613D1E /* Monitoring */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
031A80DB2F4CF1690016F7DD /* CommandTracker.swift */,
|
||||||
|
C46EBC4A28DB966A007ACC74 /* TrackedShell.swift */,
|
||||||
|
C4E49DED28F764A00026AC4E /* TrackedCommand.swift */,
|
||||||
|
);
|
||||||
|
path = Monitoring;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
03D53E902E8AE089001B1671 /* Testables */ = {
|
03D53E902E8AE089001B1671 /* Testables */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -2285,6 +2304,7 @@
|
|||||||
C4F787A628EF811000790735 /* Shell */,
|
C4F787A628EF811000790735 /* Shell */,
|
||||||
C4C8900128F0E27900CE5E97 /* Filesystem */,
|
C4C8900128F0E27900CE5E97 /* Filesystem */,
|
||||||
C4E49DE528F763E20026AC4E /* Command */,
|
C4E49DE528F763E20026AC4E /* Command */,
|
||||||
|
03D0F9772F4DE7E800613D1E /* Monitoring */,
|
||||||
C40C7F2127721F7300DDDCDC /* Core */,
|
C40C7F2127721F7300DDDCDC /* Core */,
|
||||||
54B20EDF263AA22C00D3250E /* PHP */,
|
54B20EDF263AA22C00D3250E /* PHP */,
|
||||||
C44CCD4327AFE93300CE40E5 /* Errors */,
|
C44CCD4327AFE93300CE40E5 /* Errors */,
|
||||||
@@ -2452,7 +2472,6 @@
|
|||||||
C4B5853D2770FE3900DA4FBE /* RealCommand.swift */,
|
C4B5853D2770FE3900DA4FBE /* RealCommand.swift */,
|
||||||
C4E49DEC28F764A00026AC4E /* TestableCommand.swift */,
|
C4E49DEC28F764A00026AC4E /* TestableCommand.swift */,
|
||||||
C4E49DE928F7643D0026AC4E /* CommandProtocol.swift */,
|
C4E49DE928F7643D0026AC4E /* CommandProtocol.swift */,
|
||||||
031A80DB2F4CF1690016F7DD /* CommandTracker.swift */,
|
|
||||||
);
|
);
|
||||||
path = Command;
|
path = Command;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -2921,7 +2940,7 @@
|
|||||||
C4F2E43A2752F7D00020E974 /* PhpInstallation.swift in Sources */,
|
C4F2E43A2752F7D00020E974 /* PhpInstallation.swift in Sources */,
|
||||||
C45B914E295608E300F4EC78 /* ValetServicesManager.swift in Sources */,
|
C45B914E295608E300F4EC78 /* ValetServicesManager.swift in Sources */,
|
||||||
C4D5576429C77CC5001A44CD /* PhpVersionManagerWindowController.swift in Sources */,
|
C4D5576429C77CC5001A44CD /* PhpVersionManagerWindowController.swift in Sources */,
|
||||||
C4E49DED28F764A00026AC4E /* TestableCommand.swift in Sources */,
|
C4E49DEE28F764A00026AC4E /* TestableCommand.swift in Sources */,
|
||||||
C41E871A2763D42300161EE0 /* DomainListVC+ContextMenu.swift in Sources */,
|
C41E871A2763D42300161EE0 /* DomainListVC+ContextMenu.swift in Sources */,
|
||||||
037F44222EDB92EC002EBF75 /* HomebrewWatchManager.swift in Sources */,
|
037F44222EDB92EC002EBF75 /* HomebrewWatchManager.swift in Sources */,
|
||||||
C40C7F2827721FF600DDDCDC /* Valet+Alerts.swift in Sources */,
|
C40C7F2827721FF600DDDCDC /* Valet+Alerts.swift in Sources */,
|
||||||
@@ -2969,7 +2988,7 @@
|
|||||||
C40175B82903108900763A68 /* ValetInteractor.swift in Sources */,
|
C40175B82903108900763A68 /* ValetInteractor.swift in Sources */,
|
||||||
C4ACE9E129F84EDD00110766 /* PhpGuard.swift in Sources */,
|
C4ACE9E129F84EDD00110766 /* PhpGuard.swift in Sources */,
|
||||||
C4F361612836BFD9003598CC /* MainMenu+Actions.swift in Sources */,
|
C4F361612836BFD9003598CC /* MainMenu+Actions.swift in Sources */,
|
||||||
C46EBC4A28DB966A007ACC74 /* TestableShell.swift in Sources */,
|
C46EBC4B28DB966A007ACC74 /* TestableShell.swift in Sources */,
|
||||||
C44C198D276E3A1C0072762D /* TerminalProgressWindowController.swift in Sources */,
|
C44C198D276E3A1C0072762D /* TerminalProgressWindowController.swift in Sources */,
|
||||||
0379C49F2ED71D050035D7EA /* Startup+Launch.swift in Sources */,
|
0379C49F2ED71D050035D7EA /* Startup+Launch.swift in Sources */,
|
||||||
54D9E0B827E4F51E003B9AD9 /* KeyCombo.swift in Sources */,
|
54D9E0B827E4F51E003B9AD9 /* KeyCombo.swift in Sources */,
|
||||||
@@ -2986,6 +3005,7 @@
|
|||||||
C40934A2298EEB2C00D25014 /* CaskFile.swift in Sources */,
|
C40934A2298EEB2C00D25014 /* CaskFile.swift in Sources */,
|
||||||
C495F5AF28A42E080087F70A /* EnvironmentCheck.swift in Sources */,
|
C495F5AF28A42E080087F70A /* EnvironmentCheck.swift in Sources */,
|
||||||
C46EBC4428DB95F0007ACC74 /* ShellProtocol.swift in Sources */,
|
C46EBC4428DB95F0007ACC74 /* ShellProtocol.swift in Sources */,
|
||||||
|
C46EBC4C28DB95F0007ACC74 /* TrackedShell.swift in Sources */,
|
||||||
C41C1B4922B00A9800E7CF16 /* MenuBarImageGenerator.swift in Sources */,
|
C41C1B4922B00A9800E7CF16 /* MenuBarImageGenerator.swift in Sources */,
|
||||||
C4F30B03278E16BA00755FCE /* HomebrewService.swift in Sources */,
|
C4F30B03278E16BA00755FCE /* HomebrewService.swift in Sources */,
|
||||||
54D9E0B427E4F51E003B9AD9 /* Key.swift in Sources */,
|
54D9E0B427E4F51E003B9AD9 /* Key.swift in Sources */,
|
||||||
@@ -3104,6 +3124,7 @@
|
|||||||
039C29182E8AA314007F5FAB /* TestableWebApi.swift in Sources */,
|
039C29182E8AA314007F5FAB /* TestableWebApi.swift in Sources */,
|
||||||
C47015022C46D6910069AAE7 /* NVAlertExtension.swift in Sources */,
|
C47015022C46D6910069AAE7 /* NVAlertExtension.swift in Sources */,
|
||||||
C4E49DEA28F7643D0026AC4E /* CommandProtocol.swift in Sources */,
|
C4E49DEA28F7643D0026AC4E /* CommandProtocol.swift in Sources */,
|
||||||
|
C4E49DF028F764A00026AC4E /* TrackedCommand.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -3295,6 +3316,7 @@
|
|||||||
031E2B6B2B1525A7007C29E1 /* BrewPhpExtension.swift in Sources */,
|
031E2B6B2B1525A7007C29E1 /* BrewPhpExtension.swift in Sources */,
|
||||||
C471E82728F9BB310021E251 /* BrewDiagnostics.swift in Sources */,
|
C471E82728F9BB310021E251 /* BrewDiagnostics.swift in Sources */,
|
||||||
C471E7DB28F9BA8F0021E251 /* RealShell.swift in Sources */,
|
C471E7DB28F9BA8F0021E251 /* RealShell.swift in Sources */,
|
||||||
|
C471E7FA28F9BA8F0021E251 /* TrackedShell.swift in Sources */,
|
||||||
C471E7FF28F9BAD10021E251 /* Xdebug.swift in Sources */,
|
C471E7FF28F9BAD10021E251 /* Xdebug.swift in Sources */,
|
||||||
037F441D2EDB9195002EBF75 /* ConfigWatchManager.swift in Sources */,
|
037F441D2EDB9195002EBF75 /* ConfigWatchManager.swift in Sources */,
|
||||||
C409349F298EE8E900D25014 /* AppUpdater.swift in Sources */,
|
C409349F298EE8E900D25014 /* AppUpdater.swift in Sources */,
|
||||||
@@ -3310,6 +3332,7 @@
|
|||||||
C42106682AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift in Sources */,
|
C42106682AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift in Sources */,
|
||||||
C4B79EC829CA474200A483EE /* FakeCommand.swift in Sources */,
|
C4B79EC829CA474200A483EE /* FakeCommand.swift in Sources */,
|
||||||
C471E7DE28F9BAA30021E251 /* CommandProtocol.swift in Sources */,
|
C471E7DE28F9BAA30021E251 /* CommandProtocol.swift in Sources */,
|
||||||
|
C471E7FB28F9BAA30021E251 /* TrackedCommand.swift in Sources */,
|
||||||
C471E82928F9BB330021E251 /* Valet.swift in Sources */,
|
C471E82928F9BB330021E251 /* Valet.swift in Sources */,
|
||||||
C471E80728F9BAD40021E251 /* PhpConfigurationFile.swift in Sources */,
|
C471E80728F9BAD40021E251 /* PhpConfigurationFile.swift in Sources */,
|
||||||
0329A9A32E92A69000A62A12 /* WarningManager+Evaluations.swift in Sources */,
|
0329A9A32E92A69000A62A12 /* WarningManager+Evaluations.swift in Sources */,
|
||||||
@@ -3554,10 +3577,12 @@
|
|||||||
C471E7ED28F9BAC30021E251 /* Process.swift in Sources */,
|
C471E7ED28F9BAC30021E251 /* Process.swift in Sources */,
|
||||||
C471E81128F9BAE80021E251 /* NSMenuItemExtension.swift in Sources */,
|
C471E81128F9BAE80021E251 /* NSMenuItemExtension.swift in Sources */,
|
||||||
C471E7CC28F9BA5B0021E251 /* TestableShell.swift in Sources */,
|
C471E7CC28F9BA5B0021E251 /* TestableShell.swift in Sources */,
|
||||||
|
C471E7F928F9BA600021E251 /* TrackedShell.swift in Sources */,
|
||||||
C4E6840C2AF26B830023ED25 /* BrewTapFormulae.swift in Sources */,
|
C4E6840C2AF26B830023ED25 /* BrewTapFormulae.swift in Sources */,
|
||||||
C471E80C28F9BAE80021E251 /* NSWindowExtension.swift in Sources */,
|
C471E80C28F9BAE80021E251 /* NSWindowExtension.swift in Sources */,
|
||||||
C471E7CA28F9BA480021E251 /* TestableFileSystem.swift in Sources */,
|
C471E7CA28F9BA480021E251 /* TestableFileSystem.swift in Sources */,
|
||||||
C471E7DD28F9BAA30021E251 /* CommandProtocol.swift in Sources */,
|
C471E7DD28F9BAA30021E251 /* CommandProtocol.swift in Sources */,
|
||||||
|
C471E7FC28F9BAA30021E251 /* TrackedCommand.swift in Sources */,
|
||||||
C471E7D128F9BA630021E251 /* RealFileSystem.swift in Sources */,
|
C471E7D128F9BA630021E251 /* RealFileSystem.swift in Sources */,
|
||||||
033D459B2B0D4EC600070080 /* InstallPhpExtensionCommand.swift in Sources */,
|
033D459B2B0D4EC600070080 /* InstallPhpExtensionCommand.swift in Sources */,
|
||||||
C471E82B28F9BB340021E251 /* Valet.swift in Sources */,
|
C471E82B28F9BB340021E251 /* Valet.swift in Sources */,
|
||||||
@@ -3674,6 +3699,7 @@
|
|||||||
C4D5576529C77CC5001A44CD /* PhpVersionManagerWindowController.swift in Sources */,
|
C4D5576529C77CC5001A44CD /* PhpVersionManagerWindowController.swift in Sources */,
|
||||||
C4BF90C127C57C220054E78C /* MainMenu+FixMyValet.swift in Sources */,
|
C4BF90C127C57C220054E78C /* MainMenu+FixMyValet.swift in Sources */,
|
||||||
C4E49DEB28F7643D0026AC4E /* CommandProtocol.swift in Sources */,
|
C4E49DEB28F7643D0026AC4E /* CommandProtocol.swift in Sources */,
|
||||||
|
C4E49DF128F764A00026AC4E /* TrackedCommand.swift in Sources */,
|
||||||
C4F2E4382752F08D0020E974 /* BrewDiagnostics.swift in Sources */,
|
C4F2E4382752F08D0020E974 /* BrewDiagnostics.swift in Sources */,
|
||||||
C485707428BF454E00539B36 /* ServicesView.swift in Sources */,
|
C485707428BF454E00539B36 /* ServicesView.swift in Sources */,
|
||||||
03B947DE2F43692500B6F899 /* TestURL.swift in Sources */,
|
03B947DE2F43692500B6F899 /* TestURL.swift in Sources */,
|
||||||
@@ -3731,7 +3757,7 @@
|
|||||||
C40FE738282ABA4F00A302C2 /* AppVersion.swift in Sources */,
|
C40FE738282ABA4F00A302C2 /* AppVersion.swift in Sources */,
|
||||||
03B675EC2EBA30D800EE04A9 /* NSImageExtension.swift in Sources */,
|
03B675EC2EBA30D800EE04A9 /* NSImageExtension.swift in Sources */,
|
||||||
C415D3E92770F692005EF286 /* AppDelegate+InterApp.swift in Sources */,
|
C415D3E92770F692005EF286 /* AppDelegate+InterApp.swift in Sources */,
|
||||||
C4E49DEE28F764A00026AC4E /* TestableCommand.swift in Sources */,
|
03D0F9752F4DE6FE00613D1E /* TestableCommand.swift in Sources */,
|
||||||
C4611E612AEAD3110010BE24 /* ByteLimitView.swift in Sources */,
|
C4611E612AEAD3110010BE24 /* ByteLimitView.swift in Sources */,
|
||||||
C40175B92903108900763A68 /* ValetInteractor.swift in Sources */,
|
C40175B92903108900763A68 /* ValetInteractor.swift in Sources */,
|
||||||
03ACC6452ECCAB190070D4CD /* RealWebApiTest.swift in Sources */,
|
03ACC6452ECCAB190070D4CD /* RealWebApiTest.swift in Sources */,
|
||||||
@@ -3851,7 +3877,7 @@
|
|||||||
C40C7F1F2772136000DDDCDC /* PhpEnvironments.swift in Sources */,
|
C40C7F1F2772136000DDDCDC /* PhpEnvironments.swift in Sources */,
|
||||||
C464ADB0275A7A6A003FCD53 /* DomainListVC.swift in Sources */,
|
C464ADB0275A7A6A003FCD53 /* DomainListVC.swift in Sources */,
|
||||||
C43A8A1A25D9CD1000591B77 /* Utility.swift in Sources */,
|
C43A8A1A25D9CD1000591B77 /* Utility.swift in Sources */,
|
||||||
C46EBC4B28DB966A007ACC74 /* TestableShell.swift in Sources */,
|
03D0F9762F4DE6FE00613D1E /* TestableShell.swift in Sources */,
|
||||||
C40FE73B282ABB2E00A302C2 /* AppVersionTest.swift in Sources */,
|
C40FE73B282ABB2E00A302C2 /* AppVersionTest.swift in Sources */,
|
||||||
C490E3BD29BCA375006D2DE6 /* Measurements.swift in Sources */,
|
C490E3BD29BCA375006D2DE6 /* Measurements.swift in Sources */,
|
||||||
C4F780C625D80B75000DBC97 /* XibLoadable.swift in Sources */,
|
C4F780C625D80B75000DBC97 /* XibLoadable.swift in Sources */,
|
||||||
|
|||||||
@@ -9,21 +9,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
protocol CommandProtocol {
|
protocol CommandProtocol {
|
||||||
/**
|
|
||||||
Immediately executes a command, without tracking.
|
|
||||||
|
|
||||||
- Parameter path: The path of the command or program to invoke.
|
|
||||||
- Parameter arguments: A list of arguments that are passed on.
|
|
||||||
- Parameter trimNewlines: Removes empty new line output.
|
|
||||||
- Parameter withStandardError: Outputs standard error output to the same string output as well.
|
|
||||||
*/
|
|
||||||
func executeRaw(
|
|
||||||
path: String,
|
|
||||||
arguments: [String],
|
|
||||||
trimNewlines: Bool,
|
|
||||||
withStandardError: Bool
|
|
||||||
) -> String
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Immediately executes a command.
|
Immediately executes a command.
|
||||||
|
|
||||||
@@ -55,20 +40,6 @@ protocol CommandProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension CommandProtocol {
|
extension CommandProtocol {
|
||||||
func execute(
|
|
||||||
path: String,
|
|
||||||
arguments: [String],
|
|
||||||
trimNewlines: Bool,
|
|
||||||
withStandardError: Bool
|
|
||||||
) -> String {
|
|
||||||
executeRaw(
|
|
||||||
path: path,
|
|
||||||
arguments: arguments,
|
|
||||||
trimNewlines: trimNewlines,
|
|
||||||
withStandardError: withStandardError
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func execute(
|
func execute(
|
||||||
path: String,
|
path: String,
|
||||||
arguments: [String],
|
arguments: [String],
|
||||||
@@ -83,24 +54,3 @@ extension CommandProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protocol TrackedCommandProtocol: CommandProtocol, CommandTrackingProvider {}
|
|
||||||
|
|
||||||
extension TrackedCommandProtocol {
|
|
||||||
func execute(
|
|
||||||
path: String,
|
|
||||||
arguments: [String],
|
|
||||||
trimNewlines: Bool,
|
|
||||||
withStandardError: Bool
|
|
||||||
) -> String {
|
|
||||||
let commandDescription = "\(path) \(arguments.joined(separator: " "))"
|
|
||||||
return trackedCommand(description: commandDescription) {
|
|
||||||
executeRaw(
|
|
||||||
path: path,
|
|
||||||
arguments: arguments,
|
|
||||||
trimNewlines: trimNewlines,
|
|
||||||
withStandardError: withStandardError
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -7,14 +7,10 @@
|
|||||||
|
|
||||||
import Cocoa
|
import Cocoa
|
||||||
|
|
||||||
public class RealCommand: TrackedCommandProtocol {
|
public class RealCommand: CommandProtocol {
|
||||||
let commandTracker: CommandTracker
|
init() {}
|
||||||
|
|
||||||
init(commandTracker: CommandTracker) {
|
public func execute(
|
||||||
self.commandTracker = commandTracker
|
|
||||||
}
|
|
||||||
|
|
||||||
public func executeRaw(
|
|
||||||
path: String,
|
path: String,
|
||||||
arguments: [String],
|
arguments: [String],
|
||||||
trimNewlines: Bool,
|
trimNewlines: Bool,
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ class TestableCommand: CommandProtocol {
|
|||||||
|
|
||||||
var commands: [String: String]
|
var commands: [String: String]
|
||||||
|
|
||||||
public func executeRaw(
|
public func execute(
|
||||||
path: String,
|
path: String,
|
||||||
arguments: [String],
|
arguments: [String],
|
||||||
trimNewlines: Bool,
|
trimNewlines: Bool,
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ class CommandTracker: ObservableObject {
|
|||||||
nonisolated init() {}
|
nonisolated init() {}
|
||||||
|
|
||||||
private let maxStoredCommands = 200
|
private let maxStoredCommands = 200
|
||||||
@Published private(set) var commands: [TrackedCommand] = []
|
@Published private(set) var commands: [LoggedCommand] = []
|
||||||
|
|
||||||
var activeCommands: [TrackedCommand] {
|
var activeCommands: [LoggedCommand] {
|
||||||
commands.filter { !$0.isCompleted }
|
commands.filter { !$0.isCompleted }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ class CommandTracker: ObservableObject {
|
|||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
func track(_ command: String, id: UUID = UUID()) -> UUID {
|
func track(_ command: String, id: UUID = UUID()) -> UUID {
|
||||||
let tracked = TrackedCommand(id: id, command: command, startedAt: Date())
|
let tracked = LoggedCommand(id: id, command: command, startedAt: Date())
|
||||||
commands.append(tracked)
|
commands.append(tracked)
|
||||||
if commands.count > maxStoredCommands {
|
if commands.count > maxStoredCommands {
|
||||||
commands.removeFirst(commands.count - maxStoredCommands)
|
commands.removeFirst(commands.count - maxStoredCommands)
|
||||||
@@ -54,9 +54,9 @@ class CommandTracker: ObservableObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Tracked Command
|
// MARK: - Logged Command
|
||||||
|
|
||||||
struct TrackedCommand: Identifiable {
|
struct LoggedCommand: Identifiable {
|
||||||
let id: UUID
|
let id: UUID
|
||||||
let command: String
|
let command: String
|
||||||
let startedAt: Date
|
let startedAt: Date
|
||||||
@@ -72,7 +72,7 @@ struct TrackedCommand: Identifiable {
|
|||||||
|
|
||||||
if duration < 0.001 {
|
if duration < 0.001 {
|
||||||
let micros = max(1, Int(duration * 1_000_000))
|
let micros = max(1, Int(duration * 1_000_000))
|
||||||
return "Completed in \(micros) μs"
|
return "Completed in \(micros) us"
|
||||||
}
|
}
|
||||||
|
|
||||||
let ms = max(1, Int(duration * 1000))
|
let ms = max(1, Int(duration * 1000))
|
||||||
@@ -83,30 +83,3 @@ struct TrackedCommand: Identifiable {
|
|||||||
return "Running for \(ms) ms"
|
return "Running for \(ms) ms"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Command Tracking
|
|
||||||
|
|
||||||
protocol CommandTrackingProvider {
|
|
||||||
var commandTracker: CommandTracker { get }
|
|
||||||
}
|
|
||||||
|
|
||||||
extension CommandTrackingProvider {
|
|
||||||
func trackedCommand<T>(description: String, _ work: () -> T) -> T {
|
|
||||||
let trackingId = commandTracker.trackFromAnyThread(description)
|
|
||||||
defer {
|
|
||||||
commandTracker.completeFromAnyThread(trackingId)
|
|
||||||
}
|
|
||||||
return work()
|
|
||||||
}
|
|
||||||
|
|
||||||
func trackedCommandAsync<T>(
|
|
||||||
description: String,
|
|
||||||
_ work: () async throws -> T
|
|
||||||
) async rethrows -> T {
|
|
||||||
let trackingId = commandTracker.trackFromAnyThread(description)
|
|
||||||
defer {
|
|
||||||
commandTracker.completeFromAnyThread(trackingId)
|
|
||||||
}
|
|
||||||
return try await work()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
38
phpmon/Common/Monitoring/TrackedCommand.swift
Normal file
38
phpmon/Common/Monitoring/TrackedCommand.swift
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
//
|
||||||
|
// TrackedCommand.swift
|
||||||
|
// PHP Monitor
|
||||||
|
//
|
||||||
|
// Copyright © 2025 Nico Verbruggen. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
final class TrackedCommand: CommandProtocol {
|
||||||
|
private let command: CommandProtocol
|
||||||
|
private let commandTracker: CommandTracker
|
||||||
|
|
||||||
|
init(command: CommandProtocol, commandTracker: CommandTracker) {
|
||||||
|
self.command = command
|
||||||
|
self.commandTracker = commandTracker
|
||||||
|
}
|
||||||
|
|
||||||
|
func execute(
|
||||||
|
path: String,
|
||||||
|
arguments: [String],
|
||||||
|
trimNewlines: Bool,
|
||||||
|
withStandardError: Bool
|
||||||
|
) -> String {
|
||||||
|
let commandDescription = "\(path) \(arguments.joined(separator: " "))"
|
||||||
|
let trackingId = commandTracker.trackFromAnyThread(commandDescription)
|
||||||
|
defer {
|
||||||
|
commandTracker.completeFromAnyThread(trackingId)
|
||||||
|
}
|
||||||
|
|
||||||
|
return command.execute(
|
||||||
|
path: path,
|
||||||
|
arguments: arguments,
|
||||||
|
trimNewlines: trimNewlines,
|
||||||
|
withStandardError: withStandardError
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
65
phpmon/Common/Monitoring/TrackedShell.swift
Normal file
65
phpmon/Common/Monitoring/TrackedShell.swift
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
//
|
||||||
|
// TrackedShell.swift
|
||||||
|
// PHP Monitor
|
||||||
|
//
|
||||||
|
// Copyright © 2025 Nico Verbruggen. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
final class TrackedShell: ShellProtocol {
|
||||||
|
private let shell: ShellProtocol
|
||||||
|
private let commandTracker: CommandTracker
|
||||||
|
|
||||||
|
init(shell: ShellProtocol, commandTracker: CommandTracker) {
|
||||||
|
self.shell = shell
|
||||||
|
self.commandTracker = commandTracker
|
||||||
|
}
|
||||||
|
|
||||||
|
var PATH: String {
|
||||||
|
shell.PATH
|
||||||
|
}
|
||||||
|
|
||||||
|
func sync(_ command: String) -> ShellOutput {
|
||||||
|
let trackingId = commandTracker.trackFromAnyThread(command)
|
||||||
|
defer {
|
||||||
|
commandTracker.completeFromAnyThread(trackingId)
|
||||||
|
}
|
||||||
|
return shell.sync(command)
|
||||||
|
}
|
||||||
|
|
||||||
|
@discardableResult
|
||||||
|
func pipe(_ command: String) async -> ShellOutput {
|
||||||
|
let trackingId = commandTracker.trackFromAnyThread(command)
|
||||||
|
defer {
|
||||||
|
commandTracker.completeFromAnyThread(trackingId)
|
||||||
|
}
|
||||||
|
return await shell.pipe(command)
|
||||||
|
}
|
||||||
|
|
||||||
|
@discardableResult
|
||||||
|
func pipe(_ command: String, timeout: TimeInterval) async -> ShellOutput {
|
||||||
|
let trackingId = commandTracker.trackFromAnyThread(command)
|
||||||
|
defer {
|
||||||
|
commandTracker.completeFromAnyThread(trackingId)
|
||||||
|
}
|
||||||
|
return await shell.pipe(command, timeout: timeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
@discardableResult
|
||||||
|
func attach(
|
||||||
|
_ command: String,
|
||||||
|
didReceiveOutput: @escaping (String, ShellStream) -> Void,
|
||||||
|
withTimeout timeout: TimeInterval
|
||||||
|
) async throws -> (Process, ShellOutput) {
|
||||||
|
let trackingId = commandTracker.trackFromAnyThread(command)
|
||||||
|
defer {
|
||||||
|
commandTracker.completeFromAnyThread(trackingId)
|
||||||
|
}
|
||||||
|
return try await shell.attach(command, didReceiveOutput: didReceiveOutput, withTimeout: timeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
func reloadEnvPath() {
|
||||||
|
shell.reloadEnvPath()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,15 +9,12 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
@preconcurrency import Dispatch
|
@preconcurrency import Dispatch
|
||||||
|
|
||||||
class RealShell: TrackedShellProtocol, @unchecked Sendable {
|
class RealShell: ShellProtocol, @unchecked Sendable {
|
||||||
init(binPath: String, commandTracker: CommandTracker) {
|
init(binPath: String) {
|
||||||
self.binPath = binPath
|
self.binPath = binPath
|
||||||
self.commandTracker = commandTracker
|
|
||||||
self._PATH = RealShell.getPath()
|
self._PATH = RealShell.getPath()
|
||||||
self._exports = [:]
|
self._exports = [:]
|
||||||
}
|
}
|
||||||
|
|
||||||
let commandTracker: CommandTracker
|
|
||||||
private(set) var binPath: String
|
private(set) var binPath: String
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -157,7 +154,8 @@ class RealShell: TrackedShellProtocol, @unchecked Sendable {
|
|||||||
|
|
||||||
// MARK: - Shellable Protocol
|
// MARK: - Shellable Protocol
|
||||||
|
|
||||||
func syncRaw(_ command: String) -> ShellOutput {
|
@discardableResult
|
||||||
|
func sync(_ command: String) -> ShellOutput {
|
||||||
let process = getShellProcess(for: command)
|
let process = getShellProcess(for: command)
|
||||||
|
|
||||||
let outputPipe = Pipe()
|
let outputPipe = Pipe()
|
||||||
@@ -188,7 +186,7 @@ class RealShell: TrackedShellProtocol, @unchecked Sendable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
func pipeRaw(_ command: String) async -> ShellOutput {
|
func pipe(_ command: String) async -> ShellOutput {
|
||||||
let process = getShellProcess(for: command)
|
let process = getShellProcess(for: command)
|
||||||
|
|
||||||
let outputPipe = Pipe()
|
let outputPipe = Pipe()
|
||||||
@@ -224,7 +222,7 @@ class RealShell: TrackedShellProtocol, @unchecked Sendable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
func pipeRaw(_ command: String, timeout: TimeInterval) async -> ShellOutput {
|
func pipe(_ command: String, timeout: TimeInterval) async -> ShellOutput {
|
||||||
let process = getShellProcess(for: command)
|
let process = getShellProcess(for: command)
|
||||||
|
|
||||||
let outputPipe = Pipe()
|
let outputPipe = Pipe()
|
||||||
@@ -290,7 +288,7 @@ class RealShell: TrackedShellProtocol, @unchecked Sendable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
func attachRaw(
|
func attach(
|
||||||
_ command: String,
|
_ command: String,
|
||||||
didReceiveOutput: @escaping (String, ShellStream) -> Void,
|
didReceiveOutput: @escaping (String, ShellStream) -> Void,
|
||||||
withTimeout timeout: TimeInterval = 5.0
|
withTimeout timeout: TimeInterval = 5.0
|
||||||
@@ -382,6 +380,7 @@ class RealShell: TrackedShellProtocol, @unchecked Sendable {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func reloadEnvPath() {
|
func reloadEnvPath() {
|
||||||
// Instead of replacing the entire shell instance, we simply re-fetch the PATH
|
// Instead of replacing the entire shell instance, we simply re-fetch the PATH
|
||||||
self.PATH = RealShell.getPath()
|
self.PATH = RealShell.getPath()
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ protocol ShellProtocol {
|
|||||||
var PATH: String { get }
|
var PATH: String { get }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Run a command synchronously without tracking. Use with caution!
|
Run a command synchronously. Use with caution!
|
||||||
|
|
||||||
Common usage:
|
Common usage:
|
||||||
```
|
```
|
||||||
@@ -24,9 +24,6 @@ protocol ShellProtocol {
|
|||||||
|
|
||||||
@return The shell output. If the command times out, returns empty output.
|
@return The shell output. If the command times out, returns empty output.
|
||||||
*/
|
*/
|
||||||
@discardableResult
|
|
||||||
func syncRaw(_ command: String) -> ShellOutput
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Run a command synchronously. Use with caution!
|
Run a command synchronously. Use with caution!
|
||||||
|
|
||||||
@@ -50,9 +47,6 @@ protocol ShellProtocol {
|
|||||||
|
|
||||||
@return The shell output. If the command times out, returns empty output.
|
@return The shell output. If the command times out, returns empty output.
|
||||||
*/
|
*/
|
||||||
@discardableResult
|
|
||||||
func pipeRaw(_ command: String) async -> ShellOutput
|
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
func pipe(_ command: String) async -> ShellOutput
|
func pipe(_ command: String) async -> ShellOutput
|
||||||
|
|
||||||
@@ -65,9 +59,6 @@ protocol ShellProtocol {
|
|||||||
|
|
||||||
@return The shell output. If the command times out, returns empty output.
|
@return The shell output. If the command times out, returns empty output.
|
||||||
*/
|
*/
|
||||||
@discardableResult
|
|
||||||
func pipeRaw(_ command: String, timeout: TimeInterval) async -> ShellOutput
|
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
func pipe(_ command: String, timeout: TimeInterval) async -> ShellOutput
|
func pipe(_ command: String, timeout: TimeInterval) async -> ShellOutput
|
||||||
|
|
||||||
@@ -82,13 +73,6 @@ protocol ShellProtocol {
|
|||||||
|
|
||||||
@return A tuple, containing the `Process` and `ShellOutput` objects.
|
@return A tuple, containing the `Process` and `ShellOutput` objects.
|
||||||
*/
|
*/
|
||||||
@discardableResult
|
|
||||||
func attachRaw(
|
|
||||||
_ command: String,
|
|
||||||
didReceiveOutput: @escaping (String, ShellStream) -> Void,
|
|
||||||
withTimeout timeout: TimeInterval
|
|
||||||
) async throws -> (Process, ShellOutput)
|
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
func attach(
|
func attach(
|
||||||
_ command: String,
|
_ command: String,
|
||||||
@@ -102,42 +86,6 @@ protocol ShellProtocol {
|
|||||||
func reloadEnvPath()
|
func reloadEnvPath()
|
||||||
}
|
}
|
||||||
|
|
||||||
protocol TrackedShellProtocol: ShellProtocol, CommandTrackingProvider {}
|
|
||||||
|
|
||||||
extension TrackedShellProtocol {
|
|
||||||
@discardableResult
|
|
||||||
func sync(_ command: String) -> ShellOutput {
|
|
||||||
trackedCommand(description: command) {
|
|
||||||
syncRaw(command)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@discardableResult
|
|
||||||
func pipe(_ command: String) async -> ShellOutput {
|
|
||||||
await trackedCommandAsync(description: command) {
|
|
||||||
await pipeRaw(command)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@discardableResult
|
|
||||||
func pipe(_ command: String, timeout: TimeInterval) async -> ShellOutput {
|
|
||||||
await trackedCommandAsync(description: command) {
|
|
||||||
await pipeRaw(command, timeout: timeout)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@discardableResult
|
|
||||||
func attach(
|
|
||||||
_ command: String,
|
|
||||||
didReceiveOutput: @escaping (String, ShellStream) -> Void,
|
|
||||||
withTimeout timeout: TimeInterval
|
|
||||||
) async throws -> (Process, ShellOutput) {
|
|
||||||
try await trackedCommandAsync(description: command) {
|
|
||||||
try await attachRaw(command, didReceiveOutput: didReceiveOutput, withTimeout: timeout)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ShellStream: Codable {
|
enum ShellStream: Codable {
|
||||||
case stdOut, stdErr, stdIn
|
case stdOut, stdErr, stdIn
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public class TestableShell: ShellProtocol {
|
|||||||
var expectations: [String: BatchFakeShellOutput] = [:]
|
var expectations: [String: BatchFakeShellOutput] = [:]
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
func syncRaw(_ command: String) -> ShellOutput {
|
func sync(_ command: String) -> ShellOutput {
|
||||||
// This assertion will only fire during test builds
|
// This assertion will only fire during test builds
|
||||||
assert(expectations.keys.contains(command), "No response declared for command: \(command)")
|
assert(expectations.keys.contains(command), "No response declared for command: \(command)")
|
||||||
|
|
||||||
@@ -32,18 +32,18 @@ public class TestableShell: ShellProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
func pipeRaw(_ command: String) async -> ShellOutput {
|
func pipe(_ command: String) async -> ShellOutput {
|
||||||
await pipeRaw(command, timeout: 60)
|
await pipe(command, timeout: 60)
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
func pipeRaw(_ command: String, timeout: TimeInterval) async -> ShellOutput {
|
func pipe(_ command: String, timeout: TimeInterval) async -> ShellOutput {
|
||||||
let (_, output) = try! await self.attachRaw(command, didReceiveOutput: { _, _ in }, withTimeout: timeout)
|
let (_, output) = try! await self.attach(command, didReceiveOutput: { _, _ in }, withTimeout: timeout)
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
func attachRaw(
|
func attach(
|
||||||
_ command: String,
|
_ command: String,
|
||||||
didReceiveOutput: @escaping (String, ShellStream) -> Void,
|
didReceiveOutput: @escaping (String, ShellStream) -> Void,
|
||||||
withTimeout timeout: TimeInterval
|
withTimeout timeout: TimeInterval
|
||||||
@@ -73,29 +73,6 @@ public class TestableShell: ShellProtocol {
|
|||||||
// does nothing
|
// does nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
|
||||||
func sync(_ command: String) -> ShellOutput {
|
|
||||||
syncRaw(command)
|
|
||||||
}
|
|
||||||
|
|
||||||
@discardableResult
|
|
||||||
func pipe(_ command: String) async -> ShellOutput {
|
|
||||||
await pipeRaw(command)
|
|
||||||
}
|
|
||||||
|
|
||||||
@discardableResult
|
|
||||||
func pipe(_ command: String, timeout: TimeInterval) async -> ShellOutput {
|
|
||||||
await pipeRaw(command, timeout: timeout)
|
|
||||||
}
|
|
||||||
|
|
||||||
@discardableResult
|
|
||||||
func attach(
|
|
||||||
_ command: String,
|
|
||||||
didReceiveOutput: @escaping (String, ShellStream) -> Void,
|
|
||||||
withTimeout timeout: TimeInterval
|
|
||||||
) async throws -> (Process, ShellOutput) {
|
|
||||||
try await attachRaw(command, didReceiveOutput: didReceiveOutput, withTimeout: timeout)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FakeShellOutput: Codable {
|
struct FakeShellOutput: Codable {
|
||||||
|
|||||||
@@ -69,8 +69,10 @@ class Container: @unchecked Sendable {
|
|||||||
self.filesystem = RealFileSystem(container: self)
|
self.filesystem = RealFileSystem(container: self)
|
||||||
self.paths = Paths(container: self)
|
self.paths = Paths(container: self)
|
||||||
self.commandTracker = CommandTracker()
|
self.commandTracker = CommandTracker()
|
||||||
self.shell = RealShell(binPath: paths.binPath, commandTracker: commandTracker)
|
let realShell = RealShell(binPath: paths.binPath)
|
||||||
self.command = RealCommand(commandTracker: commandTracker)
|
self.shell = TrackedShell(shell: realShell, commandTracker: commandTracker)
|
||||||
|
let realCommand = RealCommand()
|
||||||
|
self.command = TrackedCommand(command: realCommand, commandTracker: commandTracker)
|
||||||
self.webApi = RealWebApi(container: self)
|
self.webApi = RealWebApi(container: self)
|
||||||
|
|
||||||
if coreOnly {
|
if coreOnly {
|
||||||
|
|||||||
Reference in New Issue
Block a user