mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-11-08 05:30:05 +01:00
♻️ Preliminary refactor for Valet 3.0 (#148)
This commit is contained in:
@@ -10,7 +10,7 @@ import Foundation
|
|||||||
|
|
||||||
class PhpInstallation {
|
class PhpInstallation {
|
||||||
|
|
||||||
var longVersion: PhpVersionNumber
|
var versionNumber: PhpVersionNumber
|
||||||
|
|
||||||
/**
|
/**
|
||||||
In order to determine details about a PHP installation, we’ll simply run `php-config --version`
|
In order to determine details about a PHP installation, we’ll simply run `php-config --version`
|
||||||
@@ -19,7 +19,7 @@ class PhpInstallation {
|
|||||||
init(_ version: String) {
|
init(_ version: String) {
|
||||||
|
|
||||||
let phpConfigExecutablePath = "\(Paths.optPath)/php@\(version)/bin/php-config"
|
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) {
|
if Filesystem.fileExists(phpConfigExecutablePath) {
|
||||||
let longVersionString = Command.execute(
|
let longVersionString = Command.execute(
|
||||||
@@ -29,7 +29,7 @@ class PhpInstallation {
|
|||||||
|
|
||||||
// The parser should always work, or the string has to be very unusual.
|
// 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.
|
// 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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,22 +24,23 @@ class InternalSwitcher: PhpSwitcher {
|
|||||||
{
|
{
|
||||||
Log.info("Switching to \(version), unlinking all versions...")
|
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()
|
let group = DispatchGroup()
|
||||||
|
|
||||||
PhpEnv.shared.availablePhpVersions.forEach { (available) in
|
PhpEnv.shared.availablePhpVersions.forEach { (available) in
|
||||||
group.enter()
|
group.enter()
|
||||||
|
|
||||||
DispatchQueue.global(qos: .userInitiated).async {
|
DispatchQueue.global(qos: .userInitiated).async {
|
||||||
let formula = (available == PhpEnv.brewPhpVersion)
|
self.stopPhpVersion(available)
|
||||||
? "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)")
|
|
||||||
|
|
||||||
group.leave()
|
group.leave()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -48,16 +49,39 @@ class InternalSwitcher: PhpSwitcher {
|
|||||||
Log.info("All versions have been unlinked!")
|
Log.info("All versions have been unlinked!")
|
||||||
Log.info("Linking the new version!")
|
Log.info("Linking the new version!")
|
||||||
|
|
||||||
let formula = (version == PhpEnv.brewPhpVersion) ? "php" : "php@\(version)"
|
for formula in versions {
|
||||||
brew("link \(formula) --overwrite --force")
|
self.startPhpVersion(formula, primary: (version == formula))
|
||||||
brew("services start \(formula)", sudo: true)
|
}
|
||||||
|
|
||||||
Log.info("Restarting nginx, just to be sure!")
|
Log.info("Restarting nginx, just to be sure!")
|
||||||
brew("services restart nginx", sudo: true)
|
brew("services restart nginx", sudo: true)
|
||||||
|
|
||||||
Log.info("The new version has been linked!")
|
Log.info("The new version(s) has been linked!")
|
||||||
completion()
|
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.")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,12 +13,15 @@ class NginxConfigParser {
|
|||||||
var contents: String!
|
var contents: String!
|
||||||
|
|
||||||
init(filePath: 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? = {
|
lazy var isolatedVersion: String? = {
|
||||||
let regex = try! NSRegularExpression(
|
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: []
|
options: []
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -27,12 +30,9 @@ class NginxConfigParser {
|
|||||||
if match == nil {
|
if match == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
let majorRange = Range(match!.range(withName: "major"), in: contents)!
|
let major: String = contents[Range(match!.range(withName: "major"), in: contents)!]
|
||||||
let minorRange = Range(match!.range(withName: "minor"), in: contents)!
|
let minor: String = contents[Range(match!.range(withName: "minor"), in: contents)!]
|
||||||
|
|
||||||
let major: String = contents[majorRange]
|
|
||||||
let minor: String = contents[minorRange]
|
|
||||||
|
|
||||||
return "\(major).\(minor)"
|
return "\(major).\(minor)"
|
||||||
}()
|
}()
|
||||||
|
|||||||
@@ -60,27 +60,27 @@ class ValetSite {
|
|||||||
case valetphprc = "valetphprc"
|
case valetphprc = "valetphprc"
|
||||||
}
|
}
|
||||||
|
|
||||||
init(absolutePath: String, tld: String) {
|
init(name: String, tld: String, absolutePath: String, aliasPath: String? = nil) {
|
||||||
self.absolutePath = absolutePath
|
self.name = name
|
||||||
self.tld = tld
|
self.tld = tld
|
||||||
self.name = URL(fileURLWithPath: absolutePath).lastPathComponent
|
self.absolutePath = absolutePath
|
||||||
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.aliasPath = aliasPath
|
self.aliasPath = aliasPath
|
||||||
|
|
||||||
determineSecured()
|
determineSecured()
|
||||||
determineComposerPhpVersion()
|
determineComposerPhpVersion()
|
||||||
determineDriver()
|
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() {
|
public func determineIsolated() {
|
||||||
if let version = ValetSite.isolatedVersion("~/.config/valet/Nginx/\(self.name).\(self.tld)") {
|
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]
|
self.isolatedPhpVersion = PhpEnv.shared.cachedPhpInstallations[version]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ class StatusMenu : NSMenu {
|
|||||||
|
|
||||||
// Get the short and long version
|
// Get the short and long version
|
||||||
let shortVersion = PhpEnv.shared.availablePhpVersions[index]
|
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 long = Preferences.preferences[.fullPhpVersionDynamicIcon] as! Bool
|
||||||
let versionString = long ? longVersion.toString() : shortVersion
|
let versionString = long ? longVersion.toString() : shortVersion
|
||||||
|
|||||||
@@ -33,7 +33,13 @@ class SiteListCell: NSTableCellView
|
|||||||
self.site = site
|
self.site = site
|
||||||
|
|
||||||
// Make sure to show the TLD
|
// 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
|
// Show the absolute path, except make sure to replace the /Users/username segment with ~ for readability
|
||||||
labelPathName.stringValue = site.absolutePathRelative
|
labelPathName.stringValue = site.absolutePathRelative
|
||||||
|
|||||||
Reference in New Issue
Block a user