From 89642de12e4fd618767b58c1e7db6d9c55e9f240 Mon Sep 17 00:00:00 2001 From: Nico Verbruggen Date: Tue, 17 Jan 2023 19:16:36 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Add=20testable=20configuration=20fo?= =?UTF-8?q?r=20Valet-free=20env?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xcschemes/PHP Monitor DEV.xcscheme | 4 + phpmon/Common/PHP/PHP Version/PhpEnv.swift | 4 +- .../Testables/TestableConfiguration.swift | 15 +- phpmon/Domain/App/EnvironmentManager.swift | 18 +-- phpmon/Domain/App/Startup.swift | 2 +- phpmon/Domain/Integrations/Valet/Valet.swift | 19 ++- tests/Shared/TestableConfigurations.swift | 136 ++++++++++++++++++ .../Testables/TestableConfigurationTest.swift | 11 ++ 8 files changed, 181 insertions(+), 28 deletions(-) diff --git a/PHP Monitor.xcodeproj/xcshareddata/xcschemes/PHP Monitor DEV.xcscheme b/PHP Monitor.xcodeproj/xcshareddata/xcschemes/PHP Monitor DEV.xcscheme index 8642ae0..33c1688 100644 --- a/PHP Monitor.xcodeproj/xcshareddata/xcschemes/PHP Monitor DEV.xcscheme +++ b/PHP Monitor.xcodeproj/xcshareddata/xcschemes/PHP Monitor DEV.xcscheme @@ -93,6 +93,10 @@ argument = "--configuration:~/.phpmon_fconf_working.json" isEnabled = "NO"> + + diff --git a/phpmon/Common/PHP/PHP Version/PhpEnv.swift b/phpmon/Common/PHP/PHP Version/PhpEnv.swift index c34c89d..286119d 100644 --- a/phpmon/Common/PHP/PHP Version/PhpEnv.swift +++ b/phpmon/Common/PHP/PHP Version/PhpEnv.swift @@ -97,13 +97,13 @@ class PhpEnv { let supportedByValet: Set = { guard let version = Valet.shared.version else { - return [] + return Constants.DetectedPhpVersions } return Constants.ValetSupportedPhpVersionMatrix[version.major] ?? [] }() - var supportedVersions = versions.intersection(supportedByValet) + var supportedVersions = Valet.installed ? versions.intersection(supportedByValet) : versions // Make sure the aliased version is detected // The user may have `php` installed, but not e.g. `php@8.0` diff --git a/phpmon/Common/Testables/TestableConfiguration.swift b/phpmon/Common/Testables/TestableConfiguration.swift index f7b2a75..af7bc43 100644 --- a/phpmon/Common/Testables/TestableConfiguration.swift +++ b/phpmon/Common/Testables/TestableConfiguration.swift @@ -24,12 +24,15 @@ public struct TestableConfiguration: Codable { ActiveFileSystem.useTestable(filesystem) Log.info("Applying fake commands...") ActiveCommand.useTestable(commandOutput) - Log.info("Applying fake scanner...") - ValetScanner.useFake() - Log.info("Applying fake services manager...") - ServicesManager.useFake() - Log.info("Applying fake Valet domain interactor...") - ValetInteractor.useFake() + + if Valet.shared.installed { + Log.info("Applying fake scanner...") + ValetScanner.useFake() + Log.info("Applying fake services manager...") + ServicesManager.useFake() + Log.info("Applying fake Valet domain interactor...") + ValetInteractor.useFake() + } } func toJson(pretty: Bool = false) -> String { diff --git a/phpmon/Domain/App/EnvironmentManager.swift b/phpmon/Domain/App/EnvironmentManager.swift index 52f3ca7..5eef699 100644 --- a/phpmon/Domain/App/EnvironmentManager.swift +++ b/phpmon/Domain/App/EnvironmentManager.swift @@ -9,24 +9,10 @@ import Foundation public class EnvironmentManager { - var values: [EnvironmentProperty: Bool] = [:] + static var values: [EnvironmentProperty: Bool] = [:] public func process() async { - self.values[.hasValetInstalled] = await !{ - let output = await Shell.pipe("valet --version").out - - // Failure condition #1: does not contain Laravel Valet - if !output.contains("Laravel Valet") { - return true - } - - // Extract the version number - Valet.shared.version = try! VersionNumber.parse(VersionExtractor.from(output)!) - - // Get the actual version - return Valet.shared.version == nil - - }() // returns true if none of the failure conditions are met + Self.values[.hasValetInstalled] = Valet.shared.installed } } diff --git a/phpmon/Domain/App/Startup.swift b/phpmon/Domain/App/Startup.swift index bc87e4c..681aa8c 100644 --- a/phpmon/Domain/App/Startup.swift +++ b/phpmon/Domain/App/Startup.swift @@ -136,7 +136,7 @@ class Startup { descriptionText: "startup.errors.php_opt.desc".localized ), ]), - EnvironmentCheckGroup(name: "valet", condition: { return Valet.installed() }, checks: [ + EnvironmentCheckGroup(name: "valet", condition: { return Valet.shared.installed }, checks: [ // ================================================================================= // The Valet binary must exist. // ================================================================================= diff --git a/phpmon/Domain/Integrations/Valet/Valet.swift b/phpmon/Domain/Integrations/Valet/Valet.swift index 788d088..9c89fe6 100644 --- a/phpmon/Domain/Integrations/Valet/Valet.swift +++ b/phpmon/Domain/Integrations/Valet/Valet.swift @@ -57,10 +57,17 @@ class Valet { } } - public static func installed() -> Bool { - return FileSystem.fileExists(Paths.binPath.appending("/valet")) + static var installed: Bool { + return self.shared.installed } + lazy var installed: Bool = { + return false + + // TODO: Make this lazy + // return FileSystem.fileExists(Paths.binPath.appending("/valet")) + }() + /** Check if a particular feature is enabled. */ @@ -79,6 +86,10 @@ class Valet { Notify the user about a non-default TLD being set. */ public static func notifyAboutUnsupportedTLD() { + if !Valet.shared.installed { + return + } + if Valet.shared.config.tld != "test" && Preferences.isEnabled(.warnAboutNonStandardTLD) { Task { @MainActor in BetterAlert().withInformation( @@ -121,7 +132,9 @@ class Valet { handle all PHP versions including isolation, it needs to know about all sites. */ public func startPreloadingSites() async { - await self.reloadSites() + if Valet.shared.installed { + await self.reloadSites() + } } /** diff --git a/tests/Shared/TestableConfigurations.swift b/tests/Shared/TestableConfigurations.swift index 6bdfd63..0b9fe81 100644 --- a/tests/Shared/TestableConfigurations.swift +++ b/tests/Shared/TestableConfigurations.swift @@ -173,6 +173,142 @@ class TestableConfigurations { ] ) } + + /** A functional, working system setup (but without Valet). */ + static var workingWithoutValet: TestableConfiguration { + return TestableConfiguration( + architecture: "arm64", + filesystem: [ + "/usr/local/bin/" + : .fake(.directory, readOnly: true), + "/usr/local/bin/composer" + : .fake(.binary), + "/opt/homebrew/bin/brew" + : .fake(.binary), + "/opt/homebrew/bin/php" + : .fake(.binary), + "/opt/homebrew/opt/php" + : .fake(.symlink, "/opt/homebrew/Cellar/php/8.2.0"), + "/opt/homebrew/opt/php@8.2/bin/php" + : .fake(.symlink, "/opt/homebrew/Cellar/php/8.2.0/bin/php"), + "/opt/homebrew/Cellar/php/8.2.0/bin/php" + : .fake(.binary), + "/opt/homebrew/Cellar/php/8.2.0/bin/php-config" + : .fake(.binary), + "/opt/homebrew/etc/php/8.2/php-fpm.d/www.conf" + : .fake(.text), + "/opt/homebrew/etc/php/8.2/php.ini" + : .fake(.text), + "/opt/homebrew/etc/php/8.2/conf.d/php-memory-limits.ini" + : .fake(.text) + ], + shellOutput: [ + "sysctl -n sysctl.proc_translated" + : .instant("0"), + "id -un" + : .instant("user"), + "which node" + : .instant("/opt/homebrew/bin/node"), + "php -v" + : .instant(""" + PHP 8.2.0 (cli) (built: Dec XX 20XX XX:XX:XX) (NTS) + Copyright (c) The PHP Group + Zend Engine vX.X, Copyright (c) Zend Technologies + with Zend OPcache vX.X, Copyright (c), by Zend Technologies + """), + "ls /opt/homebrew/opt | grep php" + : .instant("php"), + "ls /opt/homebrew/opt | grep php@" + : .instant("php@8.2"), + "sudo /opt/homebrew/bin/brew services info dnsmasq --json" + : .delayed(0.2, """ + [ + { + "name": "nginx", + "service_name": "homebrew.mxcl.nginx", + "running": true, + "loaded": true, + "schedulable": false, + "pid": 133, + "exit_code": 0, + "user": "root", + "status": "started", + "file": "/Library/LaunchDaemons/homebrew.mxcl.nginx.plist", + "command": "/opt/homebrew/opt/nginx/bin/nginx -g daemon off;", + "working_dir": "/opt/homebrew", + "root_dir": null, + "log_path": null, + "error_log_path": null, + "interval": null, + "cron": null + } + ] + """), + "/opt/homebrew/bin/brew tap" + : .instant(""" + homebrew/cask + homebrew/core + homebrew/services + nicoverbruggen/cask + shivammathur/php + """), + "chmod +x /Users/nicoverbruggen/.config/phpmon/bin/pm82" + : .instant(""), + "mkdir -p ~/.config/phpmon" + : .instant(""), + "mkdir -p ~/.config/phpmon/bin" + : .instant(""), + "brew info shivammathur/php/php --json" + : .instant("Error: No available formula with the name \"shivammathur/php/php\"."), + "/usr/bin/open -Ra \"PhpStorm\"" + : .instant("Unable to find application named 'PhpStorm'", .stdErr), + "/usr/bin/open -Ra \"Visual Studio Code\"" + : .instant("Unable to find application named 'Visual Studio Code'", .stdErr), + "/usr/bin/open -Ra \"Sublime Text\"" + : .instant("Unable to find application named 'Sublime Text'", .stdErr), + "/usr/bin/open -Ra \"Sublime Merge\"" + : .instant("Unable to find application named 'Sublime Merge'", .stdErr), + "/usr/bin/open -Ra \"iTerm\"" + : .instant("Unable to find application named 'iTerm'", .stdErr), + "/opt/homebrew/bin/brew info php --json" + : .instant(ShellStrings.shared.brewJson), + "sudo /opt/homebrew/bin/brew services info --all --json" + : .instant(ShellStrings.shared.brewServicesAsRoot), + "/opt/homebrew/bin/brew services info --all --json" + : .instant(ShellStrings.shared.brewServicesAsUser), + "curl -s --max-time 5 '\(Constants.Urls.StableBuildCaskFile.absoluteString)' | grep version" + : .instant("version '5.6.2_976'"), + "/opt/homebrew/bin/brew unlink php" + : .delayed(0.2, "OK"), + "/opt/homebrew/bin/brew unlink php@8.2" + : .delayed(0.2, "OK"), + "/opt/homebrew/bin/brew link php --overwrite --force" + : .delayed(0.2, "OK"), + "sudo /opt/homebrew/bin/brew services stop php" + : .delayed(0.2, "OK"), + "sudo /opt/homebrew/bin/brew services start php" + : .delayed(0.2, "OK"), + "sudo /opt/homebrew/bin/brew services stop nginx" + : .delayed(0.2, "OK"), + "sudo /opt/homebrew/bin/brew services start nginx" + : .delayed(0.2, "OK"), + "sudo /opt/homebrew/bin/brew services stop dnsmasq" + : .delayed(0.2, "OK"), + "sudo /opt/homebrew/bin/brew services start dnsmasq" + : .delayed(0.2, "OK"), + ], + commandOutput: [ + "/opt/homebrew/bin/php-config --version": "8.2.0", + "/opt/homebrew/bin/php -r echo ini_get('memory_limit');": "512M", + "/opt/homebrew/bin/php -r echo ini_get('upload_max_filesize');": "512M", + "/opt/homebrew/bin/php -r echo ini_get('post_max_size');": "512M", + "/opt/homebrew/bin/php -r echo php_ini_scanned_files();" + : """ + /opt/homebrew/etc/php/8.2/conf.d/php-memory-limits.ini, + """ + ] + ) + } } class ShellStrings { diff --git a/tests/unit/Testables/TestableConfigurationTest.swift b/tests/unit/Testables/TestableConfigurationTest.swift index 97ec216..4e6bbb6 100644 --- a/tests/unit/Testables/TestableConfigurationTest.swift +++ b/tests/unit/Testables/TestableConfigurationTest.swift @@ -10,6 +10,7 @@ import XCTest class TestableConfigurationTest: XCTestCase { func test_configuration_can_be_saved_as_json() async { + // WORKING var configuration = TestableConfigurations.working try! configuration.toJson().write( @@ -18,6 +19,16 @@ class TestableConfigurationTest: XCTestCase { encoding: .utf8 ) + // WORKING (WITHOUT VALET) + let valetFreeConfiguration = TestableConfigurations.workingWithoutValet + + try! valetFreeConfiguration.toJson().write( + toFile: NSHomeDirectory() + "/.phpmon_fconf_working_no_valet.json", + atomically: true, + encoding: .utf8 + ) + + // NOT WORKING configuration.filesystem["/opt/homebrew/bin/php"] = nil try! configuration.toJson().write(