1
0
mirror of https://github.com/nicoverbruggen/phpmon.git synced 2025-08-07 20:10:08 +02:00

♻️ Preliminary refactor for Valet 3.0 (#148)

This commit is contained in:
2022-03-15 22:39:46 +01:00
parent a8bad8447a
commit 1a1a53b472
6 changed files with 77 additions and 43 deletions

View File

@ -10,7 +10,7 @@ import Foundation
class PhpInstallation {
var longVersion: PhpVersionNumber
var versionNumber: PhpVersionNumber
/**
In order to determine details about a PHP installation, well simply run `php-config --version`
@ -19,7 +19,7 @@ class PhpInstallation {
init(_ version: String) {
let phpConfigExecutablePath = "\(Paths.optPath)/php@\(version)/bin/php-config"
self.longVersion = PhpVersionNumber.make(from: version)!
self.versionNumber = PhpVersionNumber.make(from: version)!
if Filesystem.fileExists(phpConfigExecutablePath) {
let longVersionString = Command.execute(
@ -29,7 +29,7 @@ class PhpInstallation {
// The parser should always work, or the string has to be very unusual.
// If so, the app SHOULD crash, so that the users report what's up.
self.longVersion = try! PhpVersionNumber.parse(longVersionString)
self.versionNumber = try! PhpVersionNumber.parse(longVersionString)
}
}

View File

@ -24,22 +24,23 @@ class InternalSwitcher: PhpSwitcher {
{
Log.info("Switching to \(version), unlinking all versions...")
let isolated = Valet.shared.sites.filter { site in
site.isolatedPhpVersion != nil
}.map { site in
return site.isolatedPhpVersion!.versionNumber.homebrewVersion
}
var versions: Set<String> = []
versions = versions.union(isolated)
versions = versions.union([version])
let group = DispatchGroup()
PhpEnv.shared.availablePhpVersions.forEach { (available) in
group.enter()
DispatchQueue.global(qos: .userInitiated).async {
let formula = (available == PhpEnv.brewPhpVersion)
? "php" : "php@\(available)"
brew("unlink \(formula)")
// TODO: (ISOLATION) Only stop formulae that are not used for isolation
brew("services stop \(formula)", sudo: true)
Log.perf("Unlinked and stopped services for \(formula)")
self.stopPhpVersion(available)
group.leave()
}
}
@ -48,16 +49,39 @@ class InternalSwitcher: PhpSwitcher {
Log.info("All versions have been unlinked!")
Log.info("Linking the new version!")
let formula = (version == PhpEnv.brewPhpVersion) ? "php" : "php@\(version)"
brew("link \(formula) --overwrite --force")
brew("services start \(formula)", sudo: true)
for formula in versions {
self.startPhpVersion(formula, primary: (version == formula))
}
Log.info("Restarting nginx, just to be sure!")
brew("services restart nginx", sudo: true)
Log.info("The new version has been linked!")
Log.info("The new version(s) has been linked!")
completion()
}
}
private func stopPhpVersion(_ version: String) {
let formula = (version == PhpEnv.brewPhpVersion) ? "php" : "php@\(version)"
brew("unlink \(formula)")
brew("services stop \(formula)", sudo: true)
Log.perf("Unlinked and stopped services for \(formula)")
}
private func startPhpVersion(_ version: String, primary: Bool) {
let formula = (version == PhpEnv.brewPhpVersion) ? "php" : "php@\(version)"
if (primary) {
Log.perf("PHP \(formula) is the primary formula, linking and starting services...")
brew("link \(formula) --overwrite --force")
} else {
Log.perf("PHP \(formula) is an isolated PHP version, starting services only...")
}
brew("services start \(formula)", sudo: true)
let socketVersion = version.replacingOccurrences(of: ".", with: "")
Shell.run("ln -sF ~/.config/valet/valet\(socketVersion).sock ~/.config/valet/valet.sock")
Log.perf("Symlinked new socket version.")
}
}

View File

@ -13,12 +13,15 @@ class NginxConfigParser {
var contents: String!
init(filePath: String) {
self.contents = try! String(contentsOfFile: filePath)
self.contents = try! String(contentsOfFile: filePath
.replacingOccurrences(of: "~", with: "/Users/\(Paths.whoami)")
)
}
lazy var isolatedVersion: String? = {
let regex = try! NSRegularExpression(
pattern: #"(ISOLATED_PHP_VERSION=(php@)?)((?<major>\d)(.)?(?<minor>\d))"#,
// PHP versions have (so far) never needed multiple digits for version numbers
pattern: #"(ISOLATED_PHP_VERSION=(php)?(@)?)((?<major>\d)(.)?(?<minor>\d))"#,
options: []
)
@ -27,12 +30,9 @@ class NginxConfigParser {
if match == nil {
return nil
}
let majorRange = Range(match!.range(withName: "major"), in: contents)!
let minorRange = Range(match!.range(withName: "minor"), in: contents)!
let major: String = contents[majorRange]
let minor: String = contents[minorRange]
let major: String = contents[Range(match!.range(withName: "major"), in: contents)!]
let minor: String = contents[Range(match!.range(withName: "minor"), in: contents)!]
return "\(major).\(minor)"
}()

View File

@ -60,27 +60,27 @@ class ValetSite {
case valetphprc = "valetphprc"
}
init(absolutePath: String, tld: String) {
self.absolutePath = absolutePath
init(name: String, tld: String, absolutePath: String, aliasPath: String? = nil) {
self.name = name
self.tld = tld
self.name = URL(fileURLWithPath: absolutePath).lastPathComponent
self.aliasPath = nil
determineSecured()
determineComposerPhpVersion()
determineDriver()
}
convenience init(aliasPath: String, tld: String) {
let absolutePath = try! FileManager.default.destinationOfSymbolicLink(atPath: aliasPath)
self.init(absolutePath: absolutePath, tld: tld)
self.name = URL(fileURLWithPath: aliasPath).lastPathComponent
self.absolutePath = absolutePath
self.aliasPath = aliasPath
determineSecured()
determineComposerPhpVersion()
determineDriver()
determineIsolated()
}
convenience init(absolutePath: String, tld: String) {
let name = URL(fileURLWithPath: absolutePath).lastPathComponent
self.init(name: name, tld: tld, absolutePath: absolutePath)
}
convenience init(aliasPath: String, tld: String) {
let name = URL(fileURLWithPath: aliasPath).lastPathComponent
let absolutePath = try! FileManager.default.destinationOfSymbolicLink(atPath: aliasPath)
self.init(name: name, tld: tld, absolutePath: absolutePath, aliasPath: aliasPath)
}
/**
@ -88,6 +88,10 @@ class ValetSite {
*/
public func determineIsolated() {
if let version = ValetSite.isolatedVersion("~/.config/valet/Nginx/\(self.name).\(self.tld)") {
if (!PhpEnv.shared.cachedPhpInstallations.keys.contains(version)) {
Log.err("The PHP version \(version) is isolated for the site \(self.name) but that PHP version is unavailable.")
return
}
self.isolatedPhpVersion = PhpEnv.shared.cachedPhpInstallations[version]
}
}

View File

@ -139,7 +139,7 @@ class StatusMenu : NSMenu {
// Get the short and long version
let shortVersion = PhpEnv.shared.availablePhpVersions[index]
let longVersion = PhpEnv.shared.cachedPhpInstallations[shortVersion]!.longVersion
let longVersion = PhpEnv.shared.cachedPhpInstallations[shortVersion]!.versionNumber
let long = Preferences.preferences[.fullPhpVersionDynamicIcon] as! Bool
let versionString = long ? longVersion.toString() : shortVersion

View File

@ -33,7 +33,13 @@ class SiteListCell: NSTableCellView
self.site = site
// Make sure to show the TLD
labelSiteName.stringValue = "\(site.name).\(Valet.shared.config.tld)"
var siteName = "\(site.name).\(Valet.shared.config.tld)"
if (site.isolatedPhpVersion != nil) {
siteName += " [isolated \(site.isolatedPhpVersion!.versionNumber.homebrewVersion)]"
}
labelSiteName.stringValue = siteName
// Show the absolute path, except make sure to replace the /Users/username segment with ~ for readability
labelPathName.stringValue = site.absolutePathRelative