1
0
mirror of https://github.com/nicoverbruggen/phpmon.git synced 2025-11-07 05:10:06 +01:00

Add testable configuration for Valet-free env

This commit is contained in:
2023-01-17 19:16:36 +01:00
parent c6f2167c92
commit 89642de12e
8 changed files with 181 additions and 28 deletions

View File

@@ -93,6 +93,10 @@
argument = "--configuration:~/.phpmon_fconf_working.json" argument = "--configuration:~/.phpmon_fconf_working.json"
isEnabled = "NO"> isEnabled = "NO">
</CommandLineArgument> </CommandLineArgument>
<CommandLineArgument
argument = "--configuration:~/.phpmon_fconf_working_no_valet.json"
isEnabled = "YES">
</CommandLineArgument>
<CommandLineArgument <CommandLineArgument
argument = "--configuration:~/.phpmon_fconf_broken.json" argument = "--configuration:~/.phpmon_fconf_broken.json"
isEnabled = "NO"> isEnabled = "NO">

View File

@@ -97,13 +97,13 @@ class PhpEnv {
let supportedByValet: Set<String> = { let supportedByValet: Set<String> = {
guard let version = Valet.shared.version else { guard let version = Valet.shared.version else {
return [] return Constants.DetectedPhpVersions
} }
return Constants.ValetSupportedPhpVersionMatrix[version.major] ?? [] 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 // Make sure the aliased version is detected
// The user may have `php` installed, but not e.g. `php@8.0` // The user may have `php` installed, but not e.g. `php@8.0`

View File

@@ -24,6 +24,8 @@ public struct TestableConfiguration: Codable {
ActiveFileSystem.useTestable(filesystem) ActiveFileSystem.useTestable(filesystem)
Log.info("Applying fake commands...") Log.info("Applying fake commands...")
ActiveCommand.useTestable(commandOutput) ActiveCommand.useTestable(commandOutput)
if Valet.shared.installed {
Log.info("Applying fake scanner...") Log.info("Applying fake scanner...")
ValetScanner.useFake() ValetScanner.useFake()
Log.info("Applying fake services manager...") Log.info("Applying fake services manager...")
@@ -31,6 +33,7 @@ public struct TestableConfiguration: Codable {
Log.info("Applying fake Valet domain interactor...") Log.info("Applying fake Valet domain interactor...")
ValetInteractor.useFake() ValetInteractor.useFake()
} }
}
func toJson(pretty: Bool = false) -> String { func toJson(pretty: Bool = false) -> String {
let data = try! JSONEncoder().encode(self) let data = try! JSONEncoder().encode(self)

View File

@@ -9,24 +9,10 @@
import Foundation import Foundation
public class EnvironmentManager { public class EnvironmentManager {
var values: [EnvironmentProperty: Bool] = [:] static var values: [EnvironmentProperty: Bool] = [:]
public func process() async { public func process() async {
self.values[.hasValetInstalled] = await !{ Self.values[.hasValetInstalled] = Valet.shared.installed
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
} }
} }

View File

@@ -136,7 +136,7 @@ class Startup {
descriptionText: "startup.errors.php_opt.desc".localized 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. // The Valet binary must exist.
// ================================================================================= // =================================================================================

View File

@@ -57,10 +57,17 @@ class Valet {
} }
} }
public static func installed() -> Bool { static var installed: Bool {
return FileSystem.fileExists(Paths.binPath.appending("/valet")) 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. Check if a particular feature is enabled.
*/ */
@@ -79,6 +86,10 @@ class Valet {
Notify the user about a non-default TLD being set. Notify the user about a non-default TLD being set.
*/ */
public static func notifyAboutUnsupportedTLD() { public static func notifyAboutUnsupportedTLD() {
if !Valet.shared.installed {
return
}
if Valet.shared.config.tld != "test" && Preferences.isEnabled(.warnAboutNonStandardTLD) { if Valet.shared.config.tld != "test" && Preferences.isEnabled(.warnAboutNonStandardTLD) {
Task { @MainActor in Task { @MainActor in
BetterAlert().withInformation( BetterAlert().withInformation(
@@ -121,8 +132,10 @@ class Valet {
handle all PHP versions including isolation, it needs to know about all sites. handle all PHP versions including isolation, it needs to know about all sites.
*/ */
public func startPreloadingSites() async { public func startPreloadingSites() async {
if Valet.shared.installed {
await self.reloadSites() await self.reloadSites()
} }
}
/** /**
Reloads the list of sites, assuming that the list isn't being reloaded at the time. Reloads the list of sites, assuming that the list isn't being reloaded at the time.

View File

@@ -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 { class ShellStrings {

View File

@@ -10,6 +10,7 @@ import XCTest
class TestableConfigurationTest: XCTestCase { class TestableConfigurationTest: XCTestCase {
func test_configuration_can_be_saved_as_json() async { func test_configuration_can_be_saved_as_json() async {
// WORKING
var configuration = TestableConfigurations.working var configuration = TestableConfigurations.working
try! configuration.toJson().write( try! configuration.toJson().write(
@@ -18,6 +19,16 @@ class TestableConfigurationTest: XCTestCase {
encoding: .utf8 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 configuration.filesystem["/opt/homebrew/bin/php"] = nil
try! configuration.toJson().write( try! configuration.toJson().write(