mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-08-07 03:50:08 +02:00
👌 FileSystem changes, rework and testing
This commit is contained in:
@ -72,7 +72,7 @@
|
|||||||
C40FE738282ABA4F00A302C2 /* AppVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40FE736282ABA4F00A302C2 /* AppVersion.swift */; };
|
C40FE738282ABA4F00A302C2 /* AppVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40FE736282ABA4F00A302C2 /* AppVersion.swift */; };
|
||||||
C40FE73B282ABB2E00A302C2 /* AppVersionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40FE739282ABB2E00A302C2 /* AppVersionTest.swift */; };
|
C40FE73B282ABB2E00A302C2 /* AppVersionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40FE739282ABB2E00A302C2 /* AppVersionTest.swift */; };
|
||||||
C412E5FC25700D5300A1FB67 /* HomebrewPackage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C412E5FB25700D5300A1FB67 /* HomebrewPackage.swift */; };
|
C412E5FC25700D5300A1FB67 /* HomebrewPackage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C412E5FB25700D5300A1FB67 /* HomebrewPackage.swift */; };
|
||||||
C413E43528DA3EB100AE33C7 /* FakeShellTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C413E43428DA3EB100AE33C7 /* FakeShellTest.swift */; };
|
C413E43528DA3EB100AE33C7 /* TestableShellTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C413E43428DA3EB100AE33C7 /* TestableShellTest.swift */; };
|
||||||
C415937F27A1B54F00D2E1B7 /* PhpFrameworks.swift in Sources */ = {isa = PBXBuildFile; fileRef = C415937E27A1B54F00D2E1B7 /* PhpFrameworks.swift */; };
|
C415937F27A1B54F00D2E1B7 /* PhpFrameworks.swift in Sources */ = {isa = PBXBuildFile; fileRef = C415937E27A1B54F00D2E1B7 /* PhpFrameworks.swift */; };
|
||||||
C415938027A1B54F00D2E1B7 /* PhpFrameworks.swift in Sources */ = {isa = PBXBuildFile; fileRef = C415937E27A1B54F00D2E1B7 /* PhpFrameworks.swift */; };
|
C415938027A1B54F00D2E1B7 /* PhpFrameworks.swift in Sources */ = {isa = PBXBuildFile; fileRef = C415937E27A1B54F00D2E1B7 /* PhpFrameworks.swift */; };
|
||||||
C4159AF728E4D40400545349 /* SystemShellTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4159AF628E4D40400545349 /* SystemShellTest.swift */; };
|
C4159AF728E4D40400545349 /* SystemShellTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4159AF628E4D40400545349 /* SystemShellTest.swift */; };
|
||||||
@ -569,6 +569,11 @@
|
|||||||
C4D366072911331E006BD146 /* EmptyProxyScanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D366052911331E006BD146 /* EmptyProxyScanner.swift */; };
|
C4D366072911331E006BD146 /* EmptyProxyScanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D366052911331E006BD146 /* EmptyProxyScanner.swift */; };
|
||||||
C4D366082911331E006BD146 /* EmptyProxyScanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D366052911331E006BD146 /* EmptyProxyScanner.swift */; };
|
C4D366082911331E006BD146 /* EmptyProxyScanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D366052911331E006BD146 /* EmptyProxyScanner.swift */; };
|
||||||
C4D366092911331E006BD146 /* EmptyProxyScanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D366052911331E006BD146 /* EmptyProxyScanner.swift */; };
|
C4D366092911331E006BD146 /* EmptyProxyScanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D366052911331E006BD146 /* EmptyProxyScanner.swift */; };
|
||||||
|
C4D3660B29113F20006BD146 /* System.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D3660A29113F20006BD146 /* System.swift */; };
|
||||||
|
C4D3660C29113F20006BD146 /* System.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D3660A29113F20006BD146 /* System.swift */; };
|
||||||
|
C4D3660D29113F20006BD146 /* System.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D3660A29113F20006BD146 /* System.swift */; };
|
||||||
|
C4D3660E29113F20006BD146 /* System.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D3660A29113F20006BD146 /* System.swift */; };
|
||||||
|
C4D36611291140BE006BD146 /* TestableFileSystemTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D3660F291140BE006BD146 /* TestableFileSystemTest.swift */; };
|
||||||
C4D5CFCA27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D5CFC927E0F9CD00035329 /* NginxConfigurationFile.swift */; };
|
C4D5CFCA27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D5CFC927E0F9CD00035329 /* NginxConfigurationFile.swift */; };
|
||||||
C4D5CFCB27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D5CFC927E0F9CD00035329 /* NginxConfigurationFile.swift */; };
|
C4D5CFCB27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D5CFC927E0F9CD00035329 /* NginxConfigurationFile.swift */; };
|
||||||
C4D8016622B1584700C6DA1B /* Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D8016522B1584700C6DA1B /* Startup.swift */; };
|
C4D8016622B1584700C6DA1B /* Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D8016522B1584700C6DA1B /* Startup.swift */; };
|
||||||
@ -725,7 +730,7 @@
|
|||||||
C40FE736282ABA4F00A302C2 /* AppVersion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppVersion.swift; sourceTree = "<group>"; };
|
C40FE736282ABA4F00A302C2 /* AppVersion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppVersion.swift; sourceTree = "<group>"; };
|
||||||
C40FE739282ABB2E00A302C2 /* AppVersionTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppVersionTest.swift; sourceTree = "<group>"; };
|
C40FE739282ABB2E00A302C2 /* AppVersionTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppVersionTest.swift; sourceTree = "<group>"; };
|
||||||
C412E5FB25700D5300A1FB67 /* HomebrewPackage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomebrewPackage.swift; sourceTree = "<group>"; };
|
C412E5FB25700D5300A1FB67 /* HomebrewPackage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomebrewPackage.swift; sourceTree = "<group>"; };
|
||||||
C413E43428DA3EB100AE33C7 /* FakeShellTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeShellTest.swift; sourceTree = "<group>"; };
|
C413E43428DA3EB100AE33C7 /* TestableShellTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestableShellTest.swift; sourceTree = "<group>"; };
|
||||||
C415937E27A1B54F00D2E1B7 /* PhpFrameworks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpFrameworks.swift; sourceTree = "<group>"; };
|
C415937E27A1B54F00D2E1B7 /* PhpFrameworks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpFrameworks.swift; sourceTree = "<group>"; };
|
||||||
C4159AF628E4D40400545349 /* SystemShellTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemShellTest.swift; sourceTree = "<group>"; };
|
C4159AF628E4D40400545349 /* SystemShellTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemShellTest.swift; sourceTree = "<group>"; };
|
||||||
C415D3B62770F294005EF286 /* Actions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Actions.swift; sourceTree = "<group>"; };
|
C415D3B62770F294005EF286 /* Actions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Actions.swift; sourceTree = "<group>"; };
|
||||||
@ -851,6 +856,8 @@
|
|||||||
C4CE3BB927B31F670086CA49 /* ComposerWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerWindow.swift; sourceTree = "<group>"; };
|
C4CE3BB927B31F670086CA49 /* ComposerWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerWindow.swift; sourceTree = "<group>"; };
|
||||||
C4D36600291132B7006BD146 /* ValetScanners.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValetScanners.swift; sourceTree = "<group>"; };
|
C4D36600291132B7006BD146 /* ValetScanners.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValetScanners.swift; sourceTree = "<group>"; };
|
||||||
C4D366052911331E006BD146 /* EmptyProxyScanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyProxyScanner.swift; sourceTree = "<group>"; };
|
C4D366052911331E006BD146 /* EmptyProxyScanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyProxyScanner.swift; sourceTree = "<group>"; };
|
||||||
|
C4D3660A29113F20006BD146 /* System.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = System.swift; sourceTree = "<group>"; };
|
||||||
|
C4D3660F291140BE006BD146 /* TestableFileSystemTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestableFileSystemTest.swift; sourceTree = "<group>"; };
|
||||||
C4D5CFC927E0F9CD00035329 /* NginxConfigurationFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NginxConfigurationFile.swift; sourceTree = "<group>"; };
|
C4D5CFC927E0F9CD00035329 /* NginxConfigurationFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NginxConfigurationFile.swift; sourceTree = "<group>"; };
|
||||||
C4D8016522B1584700C6DA1B /* Startup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Startup.swift; sourceTree = "<group>"; };
|
C4D8016522B1584700C6DA1B /* Startup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Startup.swift; sourceTree = "<group>"; };
|
||||||
C4D89BC52783C99400A02B68 /* ComposerJson.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerJson.swift; sourceTree = "<group>"; };
|
C4D89BC52783C99400A02B68 /* ComposerJson.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerJson.swift; sourceTree = "<group>"; };
|
||||||
@ -1069,7 +1076,7 @@
|
|||||||
C413E43328DA3E8F00AE33C7 /* Shell */ = {
|
C413E43328DA3E8F00AE33C7 /* Shell */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
C413E43428DA3EB100AE33C7 /* FakeShellTest.swift */,
|
C413E43428DA3EB100AE33C7 /* TestableShellTest.swift */,
|
||||||
C4159AF628E4D40400545349 /* SystemShellTest.swift */,
|
C4159AF628E4D40400545349 /* SystemShellTest.swift */,
|
||||||
);
|
);
|
||||||
path = Shell;
|
path = Shell;
|
||||||
@ -1291,6 +1298,7 @@
|
|||||||
C471E6DA28F9AFCB0021E251 /* Filesystem */ = {
|
C471E6DA28F9AFCB0021E251 /* Filesystem */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
C4D3660F291140BE006BD146 /* TestableFileSystemTest.swift */,
|
||||||
);
|
);
|
||||||
path = Filesystem;
|
path = Filesystem;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1355,6 +1363,7 @@
|
|||||||
C41C1B4822B00A9800E7CF16 /* MenuBarImageGenerator.swift */,
|
C41C1B4822B00A9800E7CF16 /* MenuBarImageGenerator.swift */,
|
||||||
C4CCBA6B275C567B008C7055 /* PMWindowController.swift */,
|
C4CCBA6B275C567B008C7055 /* PMWindowController.swift */,
|
||||||
C4B5635D276AB09000F12CCB /* VersionExtractor.swift */,
|
C4B5635D276AB09000F12CCB /* VersionExtractor.swift */,
|
||||||
|
C4D3660A29113F20006BD146 /* System.swift */,
|
||||||
);
|
);
|
||||||
path = Helpers;
|
path = Helpers;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -2038,6 +2047,7 @@
|
|||||||
C4B6091D2853AB9700C95265 /* ServicesView.swift in Sources */,
|
C4B6091D2853AB9700C95265 /* ServicesView.swift in Sources */,
|
||||||
C40508B128ADAB44008FAC1F /* NSMenuItemExtension.swift in Sources */,
|
C40508B128ADAB44008FAC1F /* NSMenuItemExtension.swift in Sources */,
|
||||||
C4B97B7B275CF20A003F3378 /* App+GlobalHotkey.swift in Sources */,
|
C4B97B7B275CF20A003F3378 /* App+GlobalHotkey.swift in Sources */,
|
||||||
|
C4D3660B29113F20006BD146 /* System.swift in Sources */,
|
||||||
C4D36601291132B7006BD146 /* ValetScanners.swift in Sources */,
|
C4D36601291132B7006BD146 /* ValetScanners.swift in Sources */,
|
||||||
C4EED88927A48778006D7272 /* InterAppHandler.swift in Sources */,
|
C4EED88927A48778006D7272 /* InterAppHandler.swift in Sources */,
|
||||||
C40C7F1E2772136000DDDCDC /* PhpEnv.swift in Sources */,
|
C40C7F1E2772136000DDDCDC /* PhpEnv.swift in Sources */,
|
||||||
@ -2146,6 +2156,7 @@
|
|||||||
C471E86A28F9BB650021E251 /* PrefsVC.swift in Sources */,
|
C471E86A28F9BB650021E251 /* PrefsVC.swift in Sources */,
|
||||||
C471E86B28F9BB650021E251 /* PreferenceName.swift in Sources */,
|
C471E86B28F9BB650021E251 /* PreferenceName.swift in Sources */,
|
||||||
C471E86C28F9BB650021E251 /* Preferences.swift in Sources */,
|
C471E86C28F9BB650021E251 /* Preferences.swift in Sources */,
|
||||||
|
C4D3660D29113F20006BD146 /* System.swift in Sources */,
|
||||||
C471E86D28F9BB650021E251 /* CustomPrefs.swift in Sources */,
|
C471E86D28F9BB650021E251 /* CustomPrefs.swift in Sources */,
|
||||||
C4E2E84C28FC1E70003B070C /* DataExtension.swift in Sources */,
|
C4E2E84C28FC1E70003B070C /* DataExtension.swift in Sources */,
|
||||||
C471E86E28F9BB650021E251 /* MenuBarIcons.swift in Sources */,
|
C471E86E28F9BB650021E251 /* MenuBarIcons.swift in Sources */,
|
||||||
@ -2355,6 +2366,7 @@
|
|||||||
C471E82128F9BB2E0021E251 /* PhpFrameworks.swift in Sources */,
|
C471E82128F9BB2E0021E251 /* PhpFrameworks.swift in Sources */,
|
||||||
C471E7EF28F9BAC30021E251 /* Actions.swift in Sources */,
|
C471E7EF28F9BAC30021E251 /* Actions.swift in Sources */,
|
||||||
C471E82228F9BB2E0021E251 /* ComposerWindow.swift in Sources */,
|
C471E82228F9BB2E0021E251 /* ComposerWindow.swift in Sources */,
|
||||||
|
C4D3660E29113F20006BD146 /* System.swift in Sources */,
|
||||||
C471E80428F9BAD40021E251 /* PhpExtension.swift in Sources */,
|
C471E80428F9BAD40021E251 /* PhpExtension.swift in Sources */,
|
||||||
C471E7F728F9BACB0021E251 /* PhpSwitcher.swift in Sources */,
|
C471E7F728F9BACB0021E251 /* PhpSwitcher.swift in Sources */,
|
||||||
C471E82C28F9BB340021E251 /* DomainListable.swift in Sources */,
|
C471E82C28F9BB340021E251 /* DomainListable.swift in Sources */,
|
||||||
@ -2401,7 +2413,7 @@
|
|||||||
C41CA5EE2774F8EE00A2C80E /* DomainListVC+Actions.swift in Sources */,
|
C41CA5EE2774F8EE00A2C80E /* DomainListVC+Actions.swift in Sources */,
|
||||||
C4FACE81288F1C0D00FC478F /* PreferencesWindowController+Hotkey.swift in Sources */,
|
C4FACE81288F1C0D00FC478F /* PreferencesWindowController+Hotkey.swift in Sources */,
|
||||||
54D9E0B727E4F51E003B9AD9 /* HotKey.swift in Sources */,
|
54D9E0B727E4F51E003B9AD9 /* HotKey.swift in Sources */,
|
||||||
C413E43528DA3EB100AE33C7 /* FakeShellTest.swift in Sources */,
|
C413E43528DA3EB100AE33C7 /* TestableShellTest.swift in Sources */,
|
||||||
C4205A7F27F4D21800191A39 /* ValetProxy.swift in Sources */,
|
C4205A7F27F4D21800191A39 /* ValetProxy.swift in Sources */,
|
||||||
C42F26742805B4B400938AC7 /* DomainListable.swift in Sources */,
|
C42F26742805B4B400938AC7 /* DomainListable.swift in Sources */,
|
||||||
C46EBC4528DB95F0007ACC74 /* ShellProtocol.swift in Sources */,
|
C46EBC4528DB95F0007ACC74 /* ShellProtocol.swift in Sources */,
|
||||||
@ -2505,7 +2517,9 @@
|
|||||||
C4F7809C25D80344000DBC97 /* CommandTest.swift in Sources */,
|
C4F7809C25D80344000DBC97 /* CommandTest.swift in Sources */,
|
||||||
C44CCD4127AFE2FC00CE40E5 /* AlertableError.swift in Sources */,
|
C44CCD4127AFE2FC00CE40E5 /* AlertableError.swift in Sources */,
|
||||||
C4CDA894288F1A71007CE25F /* Keys.swift in Sources */,
|
C4CDA894288F1A71007CE25F /* Keys.swift in Sources */,
|
||||||
|
C4D3660C29113F20006BD146 /* System.swift in Sources */,
|
||||||
C4D936CA27E3EB6100BD69FE /* PhpHelper.swift in Sources */,
|
C4D936CA27E3EB6100BD69FE /* PhpHelper.swift in Sources */,
|
||||||
|
C4D36611291140BE006BD146 /* TestableFileSystemTest.swift in Sources */,
|
||||||
C4E2E84B28FC1E70003B070C /* DataExtension.swift in Sources */,
|
C4E2E84B28FC1E70003B070C /* DataExtension.swift in Sources */,
|
||||||
C449B4F127EE7FC200C47E8A /* DomainListNameCell.swift in Sources */,
|
C449B4F127EE7FC200C47E8A /* DomainListNameCell.swift in Sources */,
|
||||||
C4F780BA25D80B62000DBC97 /* AppDelegate.swift in Sources */,
|
C4F780BA25D80B62000DBC97 /* AppDelegate.swift in Sources */,
|
||||||
|
@ -80,7 +80,7 @@
|
|||||||
</CommandLineArgument>
|
</CommandLineArgument>
|
||||||
<CommandLineArgument
|
<CommandLineArgument
|
||||||
argument = "--configuration:~/.phpmon_fconf_working.json"
|
argument = "--configuration:~/.phpmon_fconf_working.json"
|
||||||
isEnabled = "YES">
|
isEnabled = "NO">
|
||||||
</CommandLineArgument>
|
</CommandLineArgument>
|
||||||
<CommandLineArgument
|
<CommandLineArgument
|
||||||
argument = "--configuration:~/.phpmon_fconf_broken.json"
|
argument = "--configuration:~/.phpmon_fconf_broken.json"
|
||||||
|
@ -9,28 +9,36 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
protocol FileSystemProtocol {
|
protocol FileSystemProtocol {
|
||||||
/**
|
|
||||||
Checks if a given path is a file *and* executable.
|
// MARK: - Basics
|
||||||
*/
|
|
||||||
|
func createDirectory(_ path: String, withIntermediateDirectories: Bool) throws
|
||||||
|
|
||||||
|
func writeAtomicallyToFile(_ path: String, content: String) throws
|
||||||
|
|
||||||
|
func readStringFromFile(_ path: String) throws -> String
|
||||||
|
|
||||||
|
// MARK: - Move & Delete Files
|
||||||
|
|
||||||
|
func move(from path: String, to newPath: String) throws
|
||||||
|
|
||||||
|
func remove(_ path: String) throws
|
||||||
|
|
||||||
|
// MARK: — Attributes
|
||||||
|
|
||||||
|
func makeExecutable(_ path: String) throws
|
||||||
|
|
||||||
|
// MARK: - Checks
|
||||||
|
|
||||||
func isExecutableFile(_ path: String) -> Bool
|
func isExecutableFile(_ path: String) -> Bool
|
||||||
|
|
||||||
/**
|
func isWriteableFile(_ path: String) -> Bool
|
||||||
Checks if a file or directory exists at the provided path.
|
|
||||||
*/
|
func anyExists(_ path: String) -> Bool
|
||||||
func exists(_ path: String) -> Bool
|
|
||||||
|
|
||||||
/**
|
|
||||||
Checks if a file exists at the provided path.
|
|
||||||
*/
|
|
||||||
func fileExists(_ path: String) -> Bool
|
func fileExists(_ path: String) -> Bool
|
||||||
|
|
||||||
/**
|
|
||||||
Checks if a directory exists at the provided path.
|
|
||||||
*/
|
|
||||||
func directoryExists(_ path: String) -> Bool
|
func directoryExists(_ path: String) -> Bool
|
||||||
|
|
||||||
/**
|
|
||||||
Checks if a given file is a symbolic link.
|
|
||||||
*/
|
|
||||||
func fileIsSymlink(_ path: String) -> Bool
|
func fileIsSymlink(_ path: String) -> Bool
|
||||||
}
|
}
|
||||||
|
@ -15,27 +15,67 @@ extension String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class RealFileSystem: FileSystemProtocol {
|
class RealFileSystem: FileSystemProtocol {
|
||||||
/**
|
|
||||||
Checks if a given path is a file *and* executable.
|
// MARK: - Basics
|
||||||
*/
|
|
||||||
|
func createDirectory(_ path: String, withIntermediateDirectories: Bool) {
|
||||||
|
try! FileManager.default.createDirectory(
|
||||||
|
atPath: path.replacingTildeWithHomeDirectory,
|
||||||
|
withIntermediateDirectories: withIntermediateDirectories
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeAtomicallyToFile(_ path: String, content: String) throws {
|
||||||
|
try content.write(
|
||||||
|
to: URL(fileURLWithPath: path.replacingTildeWithHomeDirectory),
|
||||||
|
atomically: true,
|
||||||
|
encoding: String.Encoding.utf8
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func readStringFromFile(_ path: String) throws -> String {
|
||||||
|
return try String(
|
||||||
|
contentsOf: URL(fileURLWithPath: path.replacingTildeWithHomeDirectory),
|
||||||
|
encoding: .utf8
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Move & Delete Files
|
||||||
|
|
||||||
|
func move(from path: String, to newPath: String) throws {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
func remove(_ path: String) throws {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: — FS Attributes
|
||||||
|
|
||||||
|
func makeExecutable(_ path: String) throws {
|
||||||
|
system("chmod +x \(path.replacingTildeWithHomeDirectory)")
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Checks
|
||||||
|
|
||||||
func isExecutableFile(_ path: String) -> Bool {
|
func isExecutableFile(_ path: String) -> Bool {
|
||||||
return FileManager.default.isExecutableFile(
|
return FileManager.default.isExecutableFile(
|
||||||
atPath: path.replacingTildeWithHomeDirectory
|
atPath: path.replacingTildeWithHomeDirectory
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
func isWriteableFile(_ path: String) -> Bool {
|
||||||
Checks if a file or directory exists at the provided path.
|
return FileManager.default.isWritableFile(
|
||||||
*/
|
atPath: path.replacingTildeWithHomeDirectory
|
||||||
func exists(_ path: String) -> Bool {
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func anyExists(_ path: String) -> Bool {
|
||||||
return FileManager.default.fileExists(
|
return FileManager.default.fileExists(
|
||||||
atPath: path.replacingTildeWithHomeDirectory
|
atPath: path.replacingTildeWithHomeDirectory
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Checks if a file exists at the provided path.
|
|
||||||
*/
|
|
||||||
func fileExists(_ path: String) -> Bool {
|
func fileExists(_ path: String) -> Bool {
|
||||||
var isDirectory: ObjCBool = true
|
var isDirectory: ObjCBool = true
|
||||||
let exists = FileManager.default.fileExists(
|
let exists = FileManager.default.fileExists(
|
||||||
@ -46,9 +86,6 @@ class RealFileSystem: FileSystemProtocol {
|
|||||||
return exists && !isDirectory.boolValue
|
return exists && !isDirectory.boolValue
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Checks if a directory exists at the provided path.
|
|
||||||
*/
|
|
||||||
func directoryExists(_ path: String) -> Bool {
|
func directoryExists(_ path: String) -> Bool {
|
||||||
var isDirectory: ObjCBool = true
|
var isDirectory: ObjCBool = true
|
||||||
let exists = FileManager.default.fileExists(
|
let exists = FileManager.default.fileExists(
|
||||||
@ -59,9 +96,6 @@ class RealFileSystem: FileSystemProtocol {
|
|||||||
return exists && isDirectory.boolValue
|
return exists && isDirectory.boolValue
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Checks if a given file is a symbolic link.
|
|
||||||
*/
|
|
||||||
func fileIsSymlink(_ path: String) -> Bool {
|
func fileIsSymlink(_ path: String) -> Bool {
|
||||||
do {
|
do {
|
||||||
let attribs = try FileManager.default.attributesOfItem(atPath: path)
|
let attribs = try FileManager.default.attributesOfItem(atPath: path)
|
||||||
|
18
phpmon/Common/Helpers/System.swift
Normal file
18
phpmon/Common/Helpers/System.swift
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// System.swift
|
||||||
|
// PHP Monitor
|
||||||
|
//
|
||||||
|
// Created by Nico Verbruggen on 01/11/2022.
|
||||||
|
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public func system(_ command: String) {
|
||||||
|
let argsArray = command.split(separator: " ").map { String($0) }
|
||||||
|
guard argsArray.isEmpty else { return }
|
||||||
|
let command = strdup(argsArray.first!)
|
||||||
|
let args = argsArray.map { strdup($0) } + [nil]
|
||||||
|
posix_spawn(nil, command, nil, nil, args, nil)
|
||||||
|
return
|
||||||
|
}
|
@ -23,12 +23,15 @@ class PhpHelper {
|
|||||||
let inPath = Shell.PATH.contains("\(Paths.homePath)/.config/phpmon/bin")
|
let inPath = Shell.PATH.contains("\(Paths.homePath)/.config/phpmon/bin")
|
||||||
|
|
||||||
// Check if we can create symlinks (`/usr/local/bin` must be writable)
|
// Check if we can create symlinks (`/usr/local/bin` must be writable)
|
||||||
let canWriteSymlinks = FileManager.default.isWritableFile(atPath: "/usr/local/bin/")
|
let canWriteSymlinks = FileSystem.isWriteableFile("/usr/local/bin/")
|
||||||
|
|
||||||
Task { // Create the appropriate folders and check if the files exist
|
Task { // Create the appropriate folders and check if the files exist
|
||||||
do {
|
do {
|
||||||
if !FileSystem.directoryExists("~/.config/phpmon/bin") {
|
if !FileSystem.directoryExists("~/.config/phpmon/bin") {
|
||||||
await Shell.quiet("mkdir -p ~/.config/phpmon/bin")
|
try FileSystem.createDirectory(
|
||||||
|
"~/.config/phpmon/bin",
|
||||||
|
withIntermediateDirectories: true
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if FileSystem.fileExists(destination) {
|
if FileSystem.fileExists(destination) {
|
||||||
@ -56,17 +59,10 @@ class PhpHelper {
|
|||||||
export PATH=\(path):$PATH
|
export PATH=\(path):$PATH
|
||||||
"""
|
"""
|
||||||
|
|
||||||
// Write to the destination
|
try FileSystem.writeAtomicallyToFile(destination, content: script)
|
||||||
// TODO: Use FileSystem abstraction
|
|
||||||
try script.write(
|
|
||||||
to: URL(fileURLWithPath: destination),
|
|
||||||
atomically: true,
|
|
||||||
encoding: String.Encoding.utf8
|
|
||||||
)
|
|
||||||
|
|
||||||
// Make sure the file is executable
|
|
||||||
if !FileSystem.isExecutableFile(destination) {
|
if !FileSystem.isExecutableFile(destination) {
|
||||||
await Shell.quiet("chmod +x \(destination)")
|
try FileSystem.makeExecutable(destination)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a symlink if the folder is not in the PATH
|
// Create a symlink if the folder is not in the PATH
|
||||||
|
@ -74,22 +74,22 @@ class InternalSwitcher: PhpSwitcher {
|
|||||||
|
|
||||||
func requiresDisablingOfDefaultPhpFpmPool(_ version: String) -> Bool {
|
func requiresDisablingOfDefaultPhpFpmPool(_ version: String) -> Bool {
|
||||||
let pool = "\(Paths.etcPath)/php/\(version)/php-fpm.d/www.conf"
|
let pool = "\(Paths.etcPath)/php/\(version)/php-fpm.d/www.conf"
|
||||||
return FileManager.default.fileExists(atPath: pool)
|
return FileSystem.fileExists(pool)
|
||||||
}
|
}
|
||||||
|
|
||||||
func disableDefaultPhpFpmPool(_ version: String) async {
|
func disableDefaultPhpFpmPool(_ version: String) async {
|
||||||
let pool = "\(Paths.etcPath)/php/\(version)/php-fpm.d/www.conf"
|
let pool = "\(Paths.etcPath)/php/\(version)/php-fpm.d/www.conf"
|
||||||
if FileManager.default.fileExists(atPath: pool) {
|
if FileSystem.fileExists(pool) {
|
||||||
Log.info("A default `www.conf` file was found in the php-fpm.d directory for PHP \(version).")
|
Log.info("A default `www.conf` file was found in the php-fpm.d directory for PHP \(version).")
|
||||||
let existing = URL(string: "file://\(Paths.etcPath)/php/\(version)/php-fpm.d/www.conf")!
|
let existing = "\(Paths.etcPath)/php/\(version)/php-fpm.d/www.conf"
|
||||||
let new = URL(string: "file://\(Paths.etcPath)/php/\(version)/php-fpm.d/www.conf.disabled-by-phpmon")!
|
let new = "\(Paths.etcPath)/php/\(version)/php-fpm.d/www.conf.disabled-by-phpmon"
|
||||||
do {
|
do {
|
||||||
if FileManager.default.fileExists(atPath: new.path) {
|
if FileSystem.fileExists(new) {
|
||||||
Log.info("A moved `www.conf.disabled-by-phpmon` file was found for PHP \(version), "
|
Log.info("A moved `www.conf.disabled-by-phpmon` file was found for PHP \(version), "
|
||||||
+ "cleaning up so the newer `www.conf` can be moved again.")
|
+ "cleaning up so the newer `www.conf` can be moved again.")
|
||||||
try FileManager.default.removeItem(at: new)
|
try FileSystem.remove(new)
|
||||||
}
|
}
|
||||||
try FileManager.default.moveItem(at: existing, to: new)
|
try FileSystem.move(from: existing, to: new)
|
||||||
Log.info("Success: A default `www.conf` file was disabled for PHP \(version).")
|
Log.info("Success: A default `www.conf` file was disabled for PHP \(version).")
|
||||||
} catch {
|
} catch {
|
||||||
Log.err(error)
|
Log.err(error)
|
||||||
|
@ -15,6 +15,54 @@ class TestableFileSystem: FileSystemProtocol {
|
|||||||
|
|
||||||
var files: [String: FakeFile]
|
var files: [String: FakeFile]
|
||||||
|
|
||||||
|
// MARK: - Basics
|
||||||
|
|
||||||
|
func createDirectory(_ path: String, withIntermediateDirectories: Bool) throws {
|
||||||
|
if files[path] != nil {
|
||||||
|
throw TestableFileSystemError.alreadyExists
|
||||||
|
}
|
||||||
|
|
||||||
|
self.files[path] = .fake(.directory)
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeAtomicallyToFile(_ path: String, content: String) throws {
|
||||||
|
if files[path] != nil {
|
||||||
|
throw TestableFileSystemError.alreadyExists
|
||||||
|
}
|
||||||
|
|
||||||
|
self.files[path] = .fake(.text, content)
|
||||||
|
}
|
||||||
|
|
||||||
|
func readStringFromFile(_ path: String) throws -> String {
|
||||||
|
guard let file = files[path] else {
|
||||||
|
throw TestableFileSystemError.fileMissing
|
||||||
|
}
|
||||||
|
|
||||||
|
return file.content ?? ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Move & Delete Files
|
||||||
|
|
||||||
|
func move(from path: String, to newPath: String) throws {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
func remove(_ path: String) throws {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: — Attributes
|
||||||
|
|
||||||
|
func makeExecutable(_ path: String) throws {
|
||||||
|
guard let file = files[path] else {
|
||||||
|
throw TestableFileSystemError.fileMissing
|
||||||
|
}
|
||||||
|
|
||||||
|
file.type = .binary
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Checks
|
||||||
|
|
||||||
func isExecutableFile(_ path: String) -> Bool {
|
func isExecutableFile(_ path: String) -> Bool {
|
||||||
guard let file = files[path] else {
|
guard let file = files[path] else {
|
||||||
return false
|
return false
|
||||||
@ -23,7 +71,15 @@ class TestableFileSystem: FileSystemProtocol {
|
|||||||
return file.type == .binary
|
return file.type == .binary
|
||||||
}
|
}
|
||||||
|
|
||||||
func exists(_ path: String) -> Bool {
|
func isWriteableFile(_ path: String) -> Bool {
|
||||||
|
guard let file = files[path] else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return !file.readOnly
|
||||||
|
}
|
||||||
|
|
||||||
|
func anyExists(_ path: String) -> Bool {
|
||||||
return files.keys.contains(path)
|
return files.keys.contains(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,11 +112,31 @@ enum FakeFileType: Codable {
|
|||||||
case binary, text, directory, symlink
|
case binary, text, directory, symlink
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FakeFile: Codable {
|
class FakeFile: Codable {
|
||||||
var type: FakeFileType
|
var type: FakeFileType
|
||||||
var content: String?
|
var content: String?
|
||||||
|
var readOnly: Bool = false
|
||||||
|
|
||||||
public static func fake(_ type: FakeFileType, _ content: String? = nil) -> FakeFile {
|
init(type: FakeFileType, content: String?, readOnly: Bool = false) {
|
||||||
return FakeFile(type: type, content: content)
|
self.type = type
|
||||||
|
self.content = content
|
||||||
|
self.readOnly = readOnly
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func fake(
|
||||||
|
_ type: FakeFileType,
|
||||||
|
_ content: String? = nil,
|
||||||
|
readOnly: Bool = false
|
||||||
|
) -> FakeFile {
|
||||||
|
return FakeFile(
|
||||||
|
type: type,
|
||||||
|
content: content,
|
||||||
|
readOnly: readOnly
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum TestableFileSystemError: Error {
|
||||||
|
case fileMissing
|
||||||
|
case alreadyExists
|
||||||
|
}
|
||||||
|
@ -55,7 +55,7 @@ class AddSiteVC: NSViewController, NSTextFieldDelegate {
|
|||||||
let path = pathControl.url!.path
|
let path = pathControl.url!.path
|
||||||
let name = inputDomainName.stringValue
|
let name = inputDomainName.stringValue
|
||||||
|
|
||||||
if !FileSystem.exists(path) {
|
if !FileSystem.anyExists(path) {
|
||||||
Alert.confirm(
|
Alert.confirm(
|
||||||
onWindow: view.window!,
|
onWindow: view.window!,
|
||||||
messageText: "domain_list.alert.folder_missing.title".localized,
|
messageText: "domain_list.alert.folder_missing.title".localized,
|
||||||
|
@ -71,7 +71,7 @@ struct PhpFrameworks {
|
|||||||
public static func detectFallbackDependency(_ basePath: String) -> String? {
|
public static func detectFallbackDependency(_ basePath: String) -> String? {
|
||||||
for entry in Self.FileMapping {
|
for entry in Self.FileMapping {
|
||||||
let found = entry.value
|
let found = entry.value
|
||||||
.map { path in return FileSystem.exists(basePath + path) }
|
.map { path in return FileSystem.anyExists(basePath + path) }
|
||||||
.contains(true)
|
.contains(true)
|
||||||
|
|
||||||
if found {
|
if found {
|
||||||
|
@ -98,13 +98,10 @@ class Valet {
|
|||||||
If the JSON is invalid when the app launches, an alert will be presented, however.
|
If the JSON is invalid when the app launches, an alert will be presented, however.
|
||||||
*/
|
*/
|
||||||
public func loadConfiguration() {
|
public func loadConfiguration() {
|
||||||
let file = FileManager.default.homeDirectoryForCurrentUser
|
|
||||||
.appendingPathComponent(".config/valet/config.json")
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
config = try JSONDecoder().decode(
|
config = try JSONDecoder().decode(
|
||||||
Valet.Configuration.self,
|
Valet.Configuration.self,
|
||||||
from: try String(contentsOf: file, encoding: .utf8).data(using: .utf8)!
|
from: FileSystem.readStringFromFile("~/.config/valet/config.json").data(using: .utf8)!
|
||||||
)
|
)
|
||||||
} catch {
|
} catch {
|
||||||
Log.err(error)
|
Log.err(error)
|
||||||
|
@ -51,7 +51,7 @@ class PhpConfigWatcher {
|
|||||||
eventMask: DispatchSource.FileSystemEvent,
|
eventMask: DispatchSource.FileSystemEvent,
|
||||||
behaviour: FSWatcherBehaviour = .reloadsMenu
|
behaviour: FSWatcherBehaviour = .reloadsMenu
|
||||||
) {
|
) {
|
||||||
if !FileSystem.exists(url.path) {
|
if !FileSystem.anyExists(url.path) {
|
||||||
Log.warn("No watcher was created for \(url.path) because the requested file does not exist.")
|
Log.warn("No watcher was created for \(url.path) because the requested file does not exist.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,8 @@ class TestableConfigurations {
|
|||||||
return TestableConfiguration(
|
return TestableConfiguration(
|
||||||
architecture: "arm64",
|
architecture: "arm64",
|
||||||
filesystem: [
|
filesystem: [
|
||||||
|
"/usr/local/bin/"
|
||||||
|
: .fake(.directory, readOnly: true),
|
||||||
"/opt/homebrew/bin/brew"
|
"/opt/homebrew/bin/brew"
|
||||||
: .fake(.binary),
|
: .fake(.binary),
|
||||||
"/opt/homebrew/bin/php"
|
"/opt/homebrew/bin/php"
|
||||||
@ -30,10 +32,21 @@ class TestableConfigurations {
|
|||||||
: .fake(.binary),
|
: .fake(.binary),
|
||||||
"/opt/homebrew/Cellar/php/8.1.10_1/bin/php-config"
|
"/opt/homebrew/Cellar/php/8.1.10_1/bin/php-config"
|
||||||
: .fake(.binary),
|
: .fake(.binary),
|
||||||
"~/.config/valet"
|
"/Users/user/.config/valet"
|
||||||
: .fake(.directory),
|
: .fake(.directory),
|
||||||
|
"/Users/user/.config/valet/config.json"
|
||||||
|
: .fake(.text, """
|
||||||
|
{
|
||||||
|
"tld": "test",
|
||||||
|
"paths": [
|
||||||
|
"/Users/user/.config/valet/Sites",
|
||||||
|
"/Users/user/Sites"
|
||||||
|
],
|
||||||
|
"loopback": "127.0.0.1"
|
||||||
|
}
|
||||||
|
"""),
|
||||||
"/opt/homebrew/etc/php/8.1/php-fpm.d/valet-fpm.conf"
|
"/opt/homebrew/etc/php/8.1/php-fpm.d/valet-fpm.conf"
|
||||||
: .fake(.text)
|
: .fake(.text),
|
||||||
],
|
],
|
||||||
shellOutput: [
|
shellOutput: [
|
||||||
"sysctl -n sysctl.proc_translated"
|
"sysctl -n sysctl.proc_translated"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// Utility.swift
|
// Utility.swift
|
||||||
// phpmon-tests
|
// PHP Monitor
|
||||||
//
|
//
|
||||||
// Created by Nico Verbruggen on 14/02/2021.
|
// Created by Nico Verbruggen on 14/02/2021.
|
||||||
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// CommandTest.swift
|
// CommandTest.swift
|
||||||
// phpmon-tests
|
// PHP Monitor
|
||||||
//
|
//
|
||||||
// Created by Nico Verbruggen on 13/02/2021.
|
// Created by Nico Verbruggen on 13/02/2021.
|
||||||
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// BrewJsonParserTest.swift
|
// BrewJsonParserTest.swift
|
||||||
// phpmon-tests
|
// PHP Monitor
|
||||||
//
|
//
|
||||||
// Created by Nico Verbruggen on 14/02/2021.
|
// Created by Nico Verbruggen on 14/02/2021.
|
||||||
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// NginxConfigurationTest.swift
|
// NginxConfigurationTest.swift
|
||||||
// phpmon-tests
|
// PHP Monitor
|
||||||
//
|
//
|
||||||
// Created by Nico Verbruggen on 29/11/2021.
|
// Created by Nico Verbruggen on 29/11/2021.
|
||||||
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// ExtensionParserTest.swift
|
// ExtensionParserTest.swift
|
||||||
// phpmon-tests
|
// PHP Monitor
|
||||||
//
|
//
|
||||||
// Created by Nico Verbruggen on 13/02/2021.
|
// Created by Nico Verbruggen on 13/02/2021.
|
||||||
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// ValetConfigParserTest.swift
|
// ValetConfigParserTest.swift
|
||||||
// phpmon-tests
|
// PHP Monitor
|
||||||
//
|
//
|
||||||
// Created by Nico Verbruggen on 29/11/2021.
|
// Created by Nico Verbruggen on 29/11/2021.
|
||||||
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
||||||
|
61
tests/unit/Testables/Filesystem/TestableFileSystemTest.swift
Normal file
61
tests/unit/Testables/Filesystem/TestableFileSystemTest.swift
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
//
|
||||||
|
// TestableFileSystemTest.swift
|
||||||
|
// PHP Monitor
|
||||||
|
//
|
||||||
|
// Created by Nico Verbruggen on 01/11/2022.
|
||||||
|
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
class TestableFileSystemTest: XCTestCase {
|
||||||
|
|
||||||
|
override class func setUp() {
|
||||||
|
ActiveFileSystem.useTestable([
|
||||||
|
"/home/user/bin": .fake(.directory),
|
||||||
|
"/home/user/bin/foo": .fake(.binary),
|
||||||
|
"/home/user/documents": .fake(.directory),
|
||||||
|
"/home/user/docs": .fake(.symlink, "/home/user/documents"),
|
||||||
|
"/home/user/documents/nice.txt": .fake(.text, "69"),
|
||||||
|
"/home/user/documents/script.sh": .fake(.text, "echo 'cool';")
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_testable_fs_is_in_use() {
|
||||||
|
XCTAssertTrue(FileSystem is TestableFileSystem)
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_binary_directory_exists() {
|
||||||
|
XCTAssertTrue(FileSystem.directoryExists("/home/user/bin"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_binary_directory_is_writable() {
|
||||||
|
XCTAssertTrue(FileSystem.isWriteableFile("/home/user/bin"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_binary_exists() {
|
||||||
|
XCTAssertTrue(FileSystem.isExecutableFile("/home/user/bin/foo"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_can_write_text_to_executable() throws {
|
||||||
|
try! FileSystem.writeAtomicallyToFile("/home/user/bin/bar", content: "bar bar bar!")
|
||||||
|
|
||||||
|
XCTAssertFalse(FileSystem.isExecutableFile("/home/user/bin/bar"))
|
||||||
|
|
||||||
|
try! FileSystem.makeExecutable("/home/user/bin/bar")
|
||||||
|
|
||||||
|
XCTAssertTrue(FileSystem.isExecutableFile("/home/user/bin/bar"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_can_create_directory() throws {
|
||||||
|
try! FileSystem.createDirectory(
|
||||||
|
"/home/nico/phpmon/config",
|
||||||
|
withIntermediateDirectories: true
|
||||||
|
)
|
||||||
|
|
||||||
|
XCTAssertTrue(FileSystem.anyExists("/home/nico/phpmon/config"))
|
||||||
|
XCTAssertTrue(FileSystem.directoryExists("/home/nico/phpmon/config"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Implement and test the remove() and move() methods and reorganize method order
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SystemShellTest.swift
|
// SystemShellTest.swift
|
||||||
// phpmon-tests
|
// PHP Monitor
|
||||||
//
|
//
|
||||||
// Created by Nico Verbruggen on 28/09/2022.
|
// Created by Nico Verbruggen on 28/09/2022.
|
||||||
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// ShellTest.swift
|
// TestableShellTest.swift
|
||||||
// phpmon-tests
|
// PHP Monitor
|
||||||
//
|
//
|
||||||
// Created by Nico Verbruggen on 20/09/2022.
|
// Created by Nico Verbruggen on 20/09/2022.
|
||||||
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
||||||
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
import XCTest
|
import XCTest
|
||||||
|
|
||||||
class FakeShellTest: XCTestCase {
|
class TestableShellTest: XCTestCase {
|
||||||
func test_fake_shell_output_can_be_declared() async {
|
func test_fake_shell_output_can_be_declared() async {
|
||||||
let greeting = BatchFakeShellOutput(items: [
|
let greeting = BatchFakeShellOutput(items: [
|
||||||
.instant("Hello world\n"),
|
.instant("Hello world\n"),
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// AppUpdaterCheckTest.swift
|
// AppUpdaterCheckTest.swift
|
||||||
// phpmon-tests
|
// PHP Monitor
|
||||||
//
|
//
|
||||||
// Created by Nico Verbruggen on 10/05/2022.
|
// Created by Nico Verbruggen on 10/05/2022.
|
||||||
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// PhpVersionDetectionTest.swift
|
// PhpVersionDetectionTest.swift
|
||||||
// phpmon-tests
|
// PHP Monitor
|
||||||
//
|
//
|
||||||
// Created by Nico Verbruggen on 01/04/2021.
|
// Created by Nico Verbruggen on 01/04/2021.
|
||||||
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// ValetTest.swift
|
// ValetTest.swift
|
||||||
// phpmon-tests
|
// PHP Monitor
|
||||||
//
|
//
|
||||||
// Created by Nico Verbruggen on 29/11/2021.
|
// Created by Nico Verbruggen on 29/11/2021.
|
||||||
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VersionExtractorTest.swift
|
// VersionExtractorTest.swift
|
||||||
// phpmon-tests
|
// PHP Monitor
|
||||||
//
|
//
|
||||||
// Created by Nico Verbruggen on 16/12/2021.
|
// Created by Nico Verbruggen on 16/12/2021.
|
||||||
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
||||||
|
Reference in New Issue
Block a user