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(