mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-08-08 04:20:07 +02:00
Compare commits
14 Commits
Author | SHA1 | Date | |
---|---|---|---|
b0de0c04c6 | |||
f27e07fc78 | |||
9fceab3e2e | |||
03fdf23f0a | |||
412b7bad5c | |||
147407666d | |||
4568f03a65 | |||
2eda8d6382 | |||
dd330fecce | |||
aaa7c636db | |||
ff75fb7be3 | |||
4d7b01831b | |||
0fceb852bb | |||
9fb5f33770 |
5
.github/ISSUE_TEMPLATE/bug_report.md
vendored
5
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -29,5 +29,10 @@ If applicable, add screenshots to help explain your problem.
|
||||
- OS: [e.g. macOS Monterey]
|
||||
- PHP Monitor version [e.g. v5.0.1]
|
||||
|
||||
**Additional log**
|
||||
You can help me figure out even more information by sending me your verbose log for your latest session of PHP Monitor. Logging is disabled by default.
|
||||
|
||||
You can start extra verbose logging by running: `touch ~/.config/phpmon/verbose` and restarting PHP Monitor. You can find the latest log in: `~/.config/phpmon/last_session.log`. Please attach it here!
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
|
@ -2831,7 +2831,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1031;
|
||||
CURRENT_PROJECT_VERSION = 1040;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEBUG = YES;
|
||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||
@ -2843,7 +2843,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||
MARKETING_VERSION = 5.7.1;
|
||||
MARKETING_VERSION = 5.7.4;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
@ -2860,7 +2860,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1031;
|
||||
CURRENT_PROJECT_VERSION = 1040;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEBUG = NO;
|
||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||
@ -2872,7 +2872,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||
MARKETING_VERSION = 5.7.1;
|
||||
MARKETING_VERSION = 5.7.4;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
@ -3088,7 +3088,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1031;
|
||||
CURRENT_PROJECT_VERSION = 1040;
|
||||
DEBUG = NO;
|
||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
@ -3099,7 +3099,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||
MARKETING_VERSION = 5.7.1;
|
||||
MARKETING_VERSION = 5.7.4;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.dev;
|
||||
PRODUCT_NAME = "$(TARGET_NAME) DEV";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
@ -3198,7 +3198,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1031;
|
||||
CURRENT_PROJECT_VERSION = 1040;
|
||||
DEBUG = YES;
|
||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
@ -3209,7 +3209,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||
MARKETING_VERSION = 5.7.1;
|
||||
MARKETING_VERSION = 5.7.4;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.dev;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
|
@ -89,6 +89,10 @@
|
||||
argument = "--v"
|
||||
isEnabled = "NO">
|
||||
</CommandLineArgument>
|
||||
<CommandLineArgument
|
||||
argument = "--cli"
|
||||
isEnabled = "YES">
|
||||
</CommandLineArgument>
|
||||
<CommandLineArgument
|
||||
argument = "--configuration:~/.phpmon_fconf_working.json"
|
||||
isEnabled = "NO">
|
||||
|
@ -553,6 +553,10 @@ If you would like to report a crash, please include the associated **log files**
|
||||
|
||||
To find the logs, take a look in `~/Library/Logs/DiagnosticReports` (in Finder) and see if there's any (log) files that start with "PHP Monitor".
|
||||
|
||||
Additionally, you can help me figure out even more information by sending me your verbose log for your latest session of PHP Monitor. Logging is disabled by default.
|
||||
|
||||
You can start extra verbose logging by running: `touch ~/.config/phpmon/verbose` and restarting PHP Monitor. You can find the latest log in: `~/.config/phpmon/last_session.log`. Please attach it to the relevant bug report.
|
||||
|
||||
</details>
|
||||
|
||||
## 📝 Having another issue?
|
||||
|
@ -13,21 +13,21 @@ class Actions {
|
||||
// MARK: - Services
|
||||
|
||||
public static func restartPhpFpm() async {
|
||||
await brew("services restart \(Homebrew.Formulae.php.name)", sudo: Homebrew.Formulae.php.elevated)
|
||||
await brew("services restart \(Homebrew.Formulae.php)", sudo: Homebrew.Formulae.php.elevated)
|
||||
}
|
||||
|
||||
public static func restartNginx() async {
|
||||
await brew("services restart \(Homebrew.Formulae.nginx.name)", sudo: Homebrew.Formulae.nginx.elevated)
|
||||
await brew("services restart \(Homebrew.Formulae.nginx)", sudo: Homebrew.Formulae.nginx.elevated)
|
||||
}
|
||||
|
||||
public static func restartDnsMasq() async {
|
||||
await brew("services restart \(Homebrew.Formulae.dnsmasq.name)", sudo: Homebrew.Formulae.dnsmasq.elevated)
|
||||
await brew("services restart \(Homebrew.Formulae.dnsmasq)", sudo: Homebrew.Formulae.dnsmasq.elevated)
|
||||
}
|
||||
|
||||
public static func stopValetServices() async {
|
||||
await brew("services stop \(Homebrew.Formulae.php.name)", sudo: Homebrew.Formulae.php.elevated)
|
||||
await brew("services stop \(Homebrew.Formulae.nginx.name)", sudo: Homebrew.Formulae.nginx.elevated)
|
||||
await brew("services stop \(Homebrew.Formulae.dnsmasq.name)", sudo: Homebrew.Formulae.dnsmasq.elevated)
|
||||
await brew("services stop \(Homebrew.Formulae.php)", sudo: Homebrew.Formulae.php.elevated)
|
||||
await brew("services stop \(Homebrew.Formulae.nginx)", sudo: Homebrew.Formulae.nginx.elevated)
|
||||
await brew("services stop \(Homebrew.Formulae.dnsmasq)", sudo: Homebrew.Formulae.dnsmasq.elevated)
|
||||
}
|
||||
|
||||
public static func fixHomebrewPermissions() throws {
|
||||
@ -54,9 +54,10 @@ class Actions {
|
||||
+ " && "
|
||||
+ cellarCommands.joined(separator: " && ")
|
||||
|
||||
let appleScript = NSAppleScript(
|
||||
source: "do shell script \"\(script)\" with administrator privileges"
|
||||
)
|
||||
let source = "do shell script \"\(script)\" with administrator privileges"
|
||||
|
||||
Log.perf(source)
|
||||
let appleScript = NSAppleScript(source: source)
|
||||
|
||||
let eventResult: NSAppleEventDescriptor? = appleScript?.executeAndReturnError(nil)
|
||||
|
||||
|
@ -36,10 +36,14 @@ class Homebrew {
|
||||
}
|
||||
}
|
||||
|
||||
class HomebrewFormula: Equatable, Hashable {
|
||||
class HomebrewFormula: Equatable, Hashable, CustomStringConvertible {
|
||||
let name: String
|
||||
let elevated: Bool
|
||||
|
||||
var description: String {
|
||||
return name
|
||||
}
|
||||
|
||||
init(_ name: String, elevated: Bool = true) {
|
||||
self.name = name
|
||||
self.elevated = elevated
|
||||
|
@ -12,47 +12,76 @@ class Log {
|
||||
|
||||
static var shared = Log()
|
||||
|
||||
var logFilePath = "~/.config/phpmon/last_session.log"
|
||||
var logExists = false
|
||||
|
||||
enum Verbosity: Int {
|
||||
case error = 1,
|
||||
warning = 2,
|
||||
info = 3,
|
||||
performance = 4
|
||||
performance = 4,
|
||||
cli = 5
|
||||
|
||||
public func isApplicable() -> Bool {
|
||||
return Log.shared.verbosity.rawValue >= self.rawValue
|
||||
}
|
||||
}
|
||||
|
||||
var verbosity: Verbosity = .warning
|
||||
public func prepareLogFile() {
|
||||
if !isRunningTests && Verbosity.cli.isApplicable() {
|
||||
_ = system("mkdir -p ~/.config/phpmon 2> /dev/null")
|
||||
_ = system("rm ~/.config/phpmon/last_session.log 2> /dev/null")
|
||||
_ = system("touch ~/.config/phpmon/last_session.log 2> /dev/null")
|
||||
self.logExists = FileSystem.fileExists(self.logFilePath)
|
||||
}
|
||||
}
|
||||
|
||||
var verbosity: Verbosity = .warning {
|
||||
didSet {
|
||||
self.prepareLogFile()
|
||||
}
|
||||
}
|
||||
|
||||
static func err(_ item: Any) {
|
||||
if Verbosity.error.isApplicable() {
|
||||
print("[E] \(item)")
|
||||
Log.shared.log("[E] \(item)")
|
||||
}
|
||||
}
|
||||
|
||||
static func warn(_ item: Any) {
|
||||
if Verbosity.warning.isApplicable() {
|
||||
print("[W] \(item)")
|
||||
Log.shared.log("[W] \(item)")
|
||||
}
|
||||
}
|
||||
|
||||
static func info(_ item: Any) {
|
||||
if Verbosity.info.isApplicable() {
|
||||
print("\(item)")
|
||||
Log.shared.log("\(item)")
|
||||
}
|
||||
}
|
||||
|
||||
static func perf(_ item: Any) {
|
||||
if Verbosity.performance.isApplicable() {
|
||||
print("[P] \(item)")
|
||||
Log.shared.log("[P] \(item)")
|
||||
}
|
||||
}
|
||||
|
||||
static func separator(as verbosity: Verbosity = .info) {
|
||||
if verbosity.isApplicable() {
|
||||
print("==================================")
|
||||
Log.shared.log("==================================")
|
||||
}
|
||||
}
|
||||
|
||||
private func log(_ text: String) {
|
||||
print(text)
|
||||
|
||||
if logExists && Verbosity.cli.isApplicable() {
|
||||
let logFile = URL(string: self.logFilePath.replacingTildeWithHomeDirectory)!
|
||||
if let fileHandle = try? FileHandle(forWritingTo: logFile) {
|
||||
fileHandle.seekToEndOfFile()
|
||||
fileHandle.write(text.appending("\n").data(using: .utf8).unsafelyUnwrapped)
|
||||
fileHandle.closeFile()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,5 +40,4 @@ class VersionExtractor {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,8 +8,6 @@
|
||||
import Foundation
|
||||
|
||||
struct HomebrewPackage: Decodable {
|
||||
|
||||
let name: String
|
||||
let full_name: String
|
||||
let aliases: [String]
|
||||
let installed: [HomebrewInstalled]
|
||||
|
@ -68,6 +68,7 @@ class RealShell: ShellProtocol {
|
||||
let task = Process()
|
||||
task.launchPath = self.launchPath
|
||||
task.arguments = ["--noprofile", "-norc", "--login", "-c", completeCommand]
|
||||
|
||||
return task
|
||||
}
|
||||
|
||||
@ -113,6 +114,35 @@ class RealShell: ShellProtocol {
|
||||
encoding: .utf8
|
||||
)!
|
||||
|
||||
if Log.shared.verbosity == .cli {
|
||||
var args = task.arguments
|
||||
let last: String = "\"" + (args?.popLast() ?? "") + "\""
|
||||
let concat = [self.launchPath] + task.arguments! + [last]
|
||||
let command = concat.joined(separator: " ")
|
||||
var log = """
|
||||
|
||||
<~~~~~~~~~~~~~~~~~~~~~~~
|
||||
$ \(command)
|
||||
|
||||
[OUT]:
|
||||
\(stdOut)
|
||||
"""
|
||||
|
||||
if !stdErr.isEmpty {
|
||||
log.append("""
|
||||
[ERR]:
|
||||
\(stdErr)
|
||||
""")
|
||||
}
|
||||
|
||||
log.append("""
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~>
|
||||
|
||||
""")
|
||||
|
||||
Log.info(log)
|
||||
}
|
||||
|
||||
return .out(stdOut, stdErr)
|
||||
}
|
||||
|
||||
|
@ -56,10 +56,9 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
|
||||
When the application initializes, create all singletons.
|
||||
*/
|
||||
override init() {
|
||||
logger.verbosity = .info
|
||||
|
||||
#if DEBUG
|
||||
logger.verbosity = .performance
|
||||
|
||||
if let profile = CommandLine.arguments.first(where: { $0.matches(pattern: "--configuration:*") }) {
|
||||
Self.initializeTestingProfile(profile.replacingOccurrences(of: "--configuration:", with: ""))
|
||||
}
|
||||
@ -70,6 +69,16 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
|
||||
Log.info("Extra verbose mode has been activated.")
|
||||
}
|
||||
|
||||
if CommandLine.arguments.contains("--cli") {
|
||||
logger.verbosity = .cli
|
||||
Log.info("Extra CLI mode has been activated via --cli flag.")
|
||||
}
|
||||
|
||||
if FileSystem.fileExists("~/.config/phpmon/verbose") {
|
||||
logger.verbosity = .cli
|
||||
Log.info("Extra CLI mode is on (`~/.config/phpmon/verbose` exists).")
|
||||
}
|
||||
|
||||
Log.separator(as: .info)
|
||||
Log.info("PHP MONITOR by Nico Verbruggen")
|
||||
Log.info("Version \(App.version)")
|
||||
|
@ -17,7 +17,7 @@ public class EnvironmentManager {
|
||||
|
||||
// Failure condition #1: does not contain Laravel Valet
|
||||
if !output.contains("Laravel Valet") {
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
// Extract the version number
|
||||
@ -25,7 +25,6 @@ public class EnvironmentManager {
|
||||
|
||||
// Get the actual version
|
||||
return Valet.shared.version == nil
|
||||
|
||||
}() // returns true if none of the failure conditions are met
|
||||
}
|
||||
}
|
||||
|
@ -1,78 +0,0 @@
|
||||
//
|
||||
// ServicesManager.swift
|
||||
// PHP Monitor
|
||||
//
|
||||
// Created by Nico Verbruggen on 11/06/2022.
|
||||
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
class ServicesManager: ObservableObject {
|
||||
|
||||
static var shared = ServicesManager()
|
||||
|
||||
@Published var rootServices: [String: HomebrewService] = [:]
|
||||
@Published var userServices: [String: HomebrewService] = [:]
|
||||
|
||||
public static func loadHomebrewServices(completed: (() -> Void)? = nil) {
|
||||
let rootServiceNames = [
|
||||
Homebrew.Formulae.php,
|
||||
Homebrew.Formulae.nginx,
|
||||
Homebrew.Formulae.dnsmasq
|
||||
]
|
||||
|
||||
DispatchQueue.global(qos: .background).async {
|
||||
let data = Shell
|
||||
.pipe("sudo \(Paths.brew) services info --all --json", requiresPath: true)
|
||||
.data(using: .utf8)!
|
||||
|
||||
let services = try! JSONDecoder()
|
||||
.decode([HomebrewService].self, from: data)
|
||||
.filter({ return rootServiceNames.contains($0.name) })
|
||||
|
||||
DispatchQueue.main.async {
|
||||
ServicesManager.shared.rootServices = Dictionary(
|
||||
uniqueKeysWithValues: services.map { ($0.name, $0) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
let userServiceNames = Preferences.custom.services ?? []
|
||||
|
||||
DispatchQueue.global(qos: .background).async {
|
||||
let data = Shell
|
||||
.pipe("\(Paths.brew) services info --all --json", requiresPath: true)
|
||||
.data(using: .utf8)!
|
||||
|
||||
let services = try! JSONDecoder()
|
||||
.decode([HomebrewService].self, from: data)
|
||||
.filter({ return userServiceNames.contains($0.name) })
|
||||
|
||||
DispatchQueue.main.async {
|
||||
ServicesManager.shared.userServices = Dictionary(
|
||||
uniqueKeysWithValues: services.map { ($0.name, $0) }
|
||||
)
|
||||
completed?()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func loadData() {
|
||||
Self.loadHomebrewServices()
|
||||
}
|
||||
|
||||
/**
|
||||
Dummy data for preview purposes.
|
||||
*/
|
||||
func withDummyServices(_ services: [String: Bool]) -> Self {
|
||||
for (service, enabled) in services {
|
||||
let item = HomebrewService.dummy(named: service, enabled: enabled)
|
||||
self.rootServices[service] = item
|
||||
}
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
}
|
@ -242,7 +242,7 @@ class Startup {
|
||||
.components(separatedBy: "Laravel Valet")[1]
|
||||
.trimmingCharacters(in: .whitespaces)
|
||||
// Extract the version number
|
||||
Valet.shared.version = try! VersionNumber.parse(VersionExtractor.from(output)!)
|
||||
Valet.shared.version = try! VersionNumber.parse(VersionExtractor.from(versionString)!)
|
||||
// Get the actual version
|
||||
return Valet.shared.version == nil
|
||||
},
|
||||
|
@ -37,7 +37,8 @@ class DomainListPhpCell: NSTableCellView, DomainListCellProtocol {
|
||||
imageViewPhpVersionOK.image = NSImage(named: "Isolated")
|
||||
imageViewPhpVersionOK.toolTip = "domain_list.tooltips.isolated".localized(site.servingPhpVersion)
|
||||
} else {
|
||||
imageViewPhpVersionOK.isHidden = (site.preferredPhpVersion == "???" || !site.isCompatibleWithPreferredPhpVersion)
|
||||
imageViewPhpVersionOK.isHidden = (site.preferredPhpVersion == "???"
|
||||
|| !site.isCompatibleWithPreferredPhpVersion)
|
||||
imageViewPhpVersionOK.image = NSImage(named: "Checkmark")
|
||||
imageViewPhpVersionOK.toolTip = "domain_list.tooltips.checkmark".localized(site.preferredPhpVersion)
|
||||
|
||||
|
@ -23,11 +23,10 @@ class HomebrewPackageTest: XCTestCase {
|
||||
[HomebrewPackage].self, from: json.data(using: .utf8)!
|
||||
).first!
|
||||
|
||||
XCTAssertEqual(package.name, "php")
|
||||
XCTAssertEqual(package.full_name, "php")
|
||||
XCTAssertEqual(package.aliases.first!, "php@8.1")
|
||||
XCTAssertEqual(package.aliases.first!, "php@8.2")
|
||||
XCTAssertEqual(package.installed.contains(where: { installed in
|
||||
installed.version.starts(with: "8.1")
|
||||
installed.version.starts(with: "8.2")
|
||||
}), true)
|
||||
}
|
||||
|
||||
|
@ -1,69 +1,77 @@
|
||||
[
|
||||
{
|
||||
"name": "php",
|
||||
"full_name": "php",
|
||||
"tap": "homebrew/core",
|
||||
"oldname": null,
|
||||
"aliases": [
|
||||
"php@8.1"
|
||||
"php@8.2"
|
||||
],
|
||||
"versioned_formulae": [
|
||||
"php@8.1",
|
||||
"php@8.0",
|
||||
"php@7.4",
|
||||
"php@7.3",
|
||||
"php@7.2"
|
||||
"php@7.4"
|
||||
],
|
||||
"desc": "General-purpose scripting language",
|
||||
"license": "PHP-3.01",
|
||||
"homepage": "https://www.php.net/",
|
||||
"versions": {
|
||||
"stable": "8.1.10",
|
||||
"stable": "8.2.2",
|
||||
"head": "HEAD",
|
||||
"bottle": true
|
||||
},
|
||||
"urls": {
|
||||
"stable": {
|
||||
"url": "https://www.php.net/distributions/php-8.1.10.tar.xz",
|
||||
"url": "https://www.php.net/distributions/php-8.2.2.tar.xz",
|
||||
"tag": null,
|
||||
"revision": null
|
||||
"revision": null,
|
||||
"checksum": "bdc4aa38e652bac86039601840bae01c0c3653972eaa6f9f93d5f71953a7ee33"
|
||||
},
|
||||
"head": {
|
||||
"url": "https://github.com/php/php-src.git",
|
||||
"branch": "master"
|
||||
}
|
||||
},
|
||||
"revision": 1,
|
||||
"revision": 0,
|
||||
"version_scheme": 0,
|
||||
"bottle": {
|
||||
"stable": {
|
||||
"rebuild": 0,
|
||||
"root_url": "https://ghcr.io/v2/homebrew/core",
|
||||
"files": {
|
||||
"arm64_ventura": {
|
||||
"cellar": "/opt/homebrew/Cellar",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/php/blobs/sha256:ad2e6a6f1cdc65c22b39bd607cbb7305958951cf58ee87d5060717be5a8b5a45",
|
||||
"sha256": "ad2e6a6f1cdc65c22b39bd607cbb7305958951cf58ee87d5060717be5a8b5a45"
|
||||
},
|
||||
"arm64_monterey": {
|
||||
"cellar": "/opt/homebrew/Cellar",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/php/blobs/sha256:dcee33c9f445db3026a7e867805eb8f6d82e9e5599599b8c6cd8645475f7961c",
|
||||
"sha256": "dcee33c9f445db3026a7e867805eb8f6d82e9e5599599b8c6cd8645475f7961c"
|
||||
"url": "https://ghcr.io/v2/homebrew/core/php/blobs/sha256:27069c973e63f38a3cb4fad1c7a2e17853bcffe318c8a957ff96a1026dff0cac",
|
||||
"sha256": "27069c973e63f38a3cb4fad1c7a2e17853bcffe318c8a957ff96a1026dff0cac"
|
||||
},
|
||||
"arm64_big_sur": {
|
||||
"cellar": "/opt/homebrew/Cellar",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/php/blobs/sha256:e0590064cd32f2baa4102fa49c80056f3886a0a89aec0589d0134ecbf0e7923e",
|
||||
"sha256": "e0590064cd32f2baa4102fa49c80056f3886a0a89aec0589d0134ecbf0e7923e"
|
||||
"url": "https://ghcr.io/v2/homebrew/core/php/blobs/sha256:ceef280bcd57e5f794ae59cc75e83d407c9704aa3d238b282bda52cbc644d0dd",
|
||||
"sha256": "ceef280bcd57e5f794ae59cc75e83d407c9704aa3d238b282bda52cbc644d0dd"
|
||||
},
|
||||
"ventura": {
|
||||
"cellar": "/usr/local/Cellar",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/php/blobs/sha256:22f733b7b0b0ed95cd6b0a1534b9eca4cf63fe54647394c3f7e7ac019eb019ff",
|
||||
"sha256": "22f733b7b0b0ed95cd6b0a1534b9eca4cf63fe54647394c3f7e7ac019eb019ff"
|
||||
},
|
||||
"monterey": {
|
||||
"cellar": "/usr/local/Cellar",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/php/blobs/sha256:62481320613b19c6ff310bf6ed50c7d2a2253cdbf403af12ec97bccd8a97a84c",
|
||||
"sha256": "62481320613b19c6ff310bf6ed50c7d2a2253cdbf403af12ec97bccd8a97a84c"
|
||||
"url": "https://ghcr.io/v2/homebrew/core/php/blobs/sha256:9ff8f5e1df5e849567cdb2ddea6d3c2a2b9cae024842c9ac65b35a01657bfc37",
|
||||
"sha256": "9ff8f5e1df5e849567cdb2ddea6d3c2a2b9cae024842c9ac65b35a01657bfc37"
|
||||
},
|
||||
"big_sur": {
|
||||
"cellar": "/usr/local/Cellar",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/php/blobs/sha256:b34d96f7aad3c580a7cbdaadb8054fb9b6872111a5eec8e1bcb4a529970c8e03",
|
||||
"sha256": "b34d96f7aad3c580a7cbdaadb8054fb9b6872111a5eec8e1bcb4a529970c8e03"
|
||||
},
|
||||
"catalina": {
|
||||
"cellar": "/usr/local/Cellar",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/php/blobs/sha256:cc0b85dcfdd60e1d8d7fa74c9f53be5d249d068835dbc7a81edacb7a076b6c76",
|
||||
"sha256": "cc0b85dcfdd60e1d8d7fa74c9f53be5d249d068835dbc7a81edacb7a076b6c76"
|
||||
"url": "https://ghcr.io/v2/homebrew/core/php/blobs/sha256:11fd1ea6da8ef728b7cacd4da8a51ed125069595abf4e37ae1552d418560c5fb",
|
||||
"sha256": "11fd1ea6da8ef728b7cacd4da8a51ed125069595abf4e37ae1552d418560c5fb"
|
||||
},
|
||||
"x86_64_linux": {
|
||||
"cellar": "/home/linuxbrew/.linuxbrew/Cellar",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/php/blobs/sha256:b934a5a4ad2d29b629f83962b57f638a654801d1ba21ba659a42da2e5afe3fae",
|
||||
"sha256": "b934a5a4ad2d29b629f83962b57f638a654801d1ba21ba659a42da2e5afe3fae"
|
||||
"url": "https://ghcr.io/v2/homebrew/core/php/blobs/sha256:baaa41e60f9e8125fe8f549d4813a8476a8947a1f10d7817a2ee36d8baa625f3",
|
||||
"sha256": "baaa41e60f9e8125fe8f549d4813a8476a8947a1f10d7817a2ee36d8baa625f3"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -127,34 +135,35 @@
|
||||
"conflicts_with": [
|
||||
|
||||
],
|
||||
"caveats": "To enable PHP in Apache add the following to httpd.conf and restart Apache:\n LoadModule php_module $(brew --prefix)/opt/php/lib/httpd/modules/libphp.so\n\n <FilesMatch \\.php$>\n SetHandler application/x-httpd-php\n </FilesMatch>\n\nFinally, check DirectoryIndex includes index.php\n DirectoryIndex index.php index.html\n\nThe php.ini and php-fpm.ini file can be found in:\n $(brew --prefix)/etc/php/8.1/\n",
|
||||
"caveats": "To enable PHP in Apache add the following to httpd.conf and restart Apache:\n LoadModule php_module $(brew --prefix)/opt/php/lib/httpd/modules/libphp.so\n\n <FilesMatch \\.php$>\n SetHandler application/x-httpd-php\n </FilesMatch>\n\nFinally, check DirectoryIndex includes index.php\n DirectoryIndex index.php index.html\n\nThe php.ini and php-fpm.ini file can be found in:\n $(brew --prefix)/etc/php/8.2/\n",
|
||||
"installed": [
|
||||
{
|
||||
"version": "8.1.10_1",
|
||||
"version": "8.2.2",
|
||||
"used_options": [
|
||||
|
||||
],
|
||||
"built_as_bottle": true,
|
||||
"poured_from_bottle": true,
|
||||
"time": 1675654665,
|
||||
"runtime_dependencies": [
|
||||
{
|
||||
"full_name": "apr",
|
||||
"version": "1.7.0",
|
||||
"version": "1.7.2",
|
||||
"declared_directly": true
|
||||
},
|
||||
{
|
||||
"full_name": "ca-certificates",
|
||||
"version": "2022-07-19",
|
||||
"version": "2023-01-10",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "openssl@1.1",
|
||||
"version": "1.1.1q",
|
||||
"version": "1.1.1s",
|
||||
"declared_directly": true
|
||||
},
|
||||
{
|
||||
"full_name": "apr-util",
|
||||
"version": "1.6.1",
|
||||
"version": "1.6.3",
|
||||
"declared_directly": true
|
||||
},
|
||||
{
|
||||
@ -182,24 +191,24 @@
|
||||
"version": "1.0.9",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "gettext",
|
||||
"version": "0.21",
|
||||
"declared_directly": true
|
||||
},
|
||||
{
|
||||
"full_name": "libunistring",
|
||||
"version": "1.0",
|
||||
"version": "1.1",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "gettext",
|
||||
"version": "0.21.1",
|
||||
"declared_directly": true
|
||||
},
|
||||
{
|
||||
"full_name": "libidn2",
|
||||
"version": "2.3.3",
|
||||
"version": "2.3.4",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "libnghttp2",
|
||||
"version": "1.49.0",
|
||||
"version": "1.51.0",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
@ -224,7 +233,7 @@
|
||||
},
|
||||
{
|
||||
"full_name": "xz",
|
||||
"version": "5.2.6",
|
||||
"version": "5.4.1",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
@ -234,7 +243,7 @@
|
||||
},
|
||||
{
|
||||
"full_name": "curl",
|
||||
"version": "7.85.0",
|
||||
"version": "7.87.0",
|
||||
"declared_directly": true
|
||||
},
|
||||
{
|
||||
@ -249,12 +258,12 @@
|
||||
},
|
||||
{
|
||||
"full_name": "freetds",
|
||||
"version": "1.3.13",
|
||||
"version": "1.3.17",
|
||||
"declared_directly": true
|
||||
},
|
||||
{
|
||||
"full_name": "libpng",
|
||||
"version": "1.6.37",
|
||||
"version": "1.6.39",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
@ -264,12 +273,12 @@
|
||||
},
|
||||
{
|
||||
"full_name": "fontconfig",
|
||||
"version": "2.14.0",
|
||||
"version": "2.14.2",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "jpeg-turbo",
|
||||
"version": "2.1.4",
|
||||
"version": "2.1.5",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
@ -278,13 +287,13 @@
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "imath",
|
||||
"version": "3.1.5",
|
||||
"full_name": "highway",
|
||||
"version": "1.0.3",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "openexr",
|
||||
"version": "3.1.5",
|
||||
"full_name": "imath",
|
||||
"version": "3.1.6",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
@ -292,14 +301,24 @@
|
||||
"version": "4.4.0",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "little-cms2",
|
||||
"version": "2.14",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "openexr",
|
||||
"version": "3.1.5",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "webp",
|
||||
"version": "1.2.4",
|
||||
"version": "1.3.0",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "jpeg-xl",
|
||||
"version": "0.6.1",
|
||||
"version": "0.8.1",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
@ -309,12 +328,12 @@
|
||||
},
|
||||
{
|
||||
"full_name": "aom",
|
||||
"version": "3.4.0",
|
||||
"version": "3.5.0",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "libavif",
|
||||
"version": "0.10.1",
|
||||
"version": "0.11.1",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
@ -329,17 +348,17 @@
|
||||
},
|
||||
{
|
||||
"full_name": "icu4c",
|
||||
"version": "71.1",
|
||||
"version": "72.1",
|
||||
"declared_directly": true
|
||||
},
|
||||
{
|
||||
"full_name": "krb5",
|
||||
"version": "1.20",
|
||||
"version": "1.20.1",
|
||||
"declared_directly": true
|
||||
},
|
||||
{
|
||||
"full_name": "libpq",
|
||||
"version": "14.5",
|
||||
"version": "15.1",
|
||||
"declared_directly": true
|
||||
},
|
||||
{
|
||||
@ -359,17 +378,17 @@
|
||||
},
|
||||
{
|
||||
"full_name": "pcre2",
|
||||
"version": "10.40",
|
||||
"version": "10.42",
|
||||
"declared_directly": true
|
||||
},
|
||||
{
|
||||
"full_name": "readline",
|
||||
"version": "8.1.2",
|
||||
"version": "8.2.1",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "sqlite",
|
||||
"version": "3.39.2",
|
||||
"version": "3.40.1",
|
||||
"declared_directly": true
|
||||
},
|
||||
{
|
||||
@ -382,7 +401,7 @@
|
||||
"installed_on_request": true
|
||||
}
|
||||
],
|
||||
"linked_keg": "8.1.10_1",
|
||||
"linked_keg": "8.2.2",
|
||||
"pinned": false,
|
||||
"outdated": false,
|
||||
"deprecated": false,
|
||||
@ -390,6 +409,8 @@
|
||||
"deprecation_reason": null,
|
||||
"disabled": false,
|
||||
"disable_date": null,
|
||||
"disable_reason": null
|
||||
"disable_reason": null,
|
||||
"tap_git_head": "0bbb89420e74756a5a5c145ed7efa4a32f7e7e7c"
|
||||
}
|
||||
]
|
||||
|
||||
]
|
||||
|
@ -10,6 +10,34 @@ import XCTest
|
||||
|
||||
class ValetVersionExtractorTest: XCTestCase {
|
||||
|
||||
func test_can_determine_valet_version_regardless_of_deprecations() async {
|
||||
let output = """
|
||||
Deprecated: Return type of Tightenco\\Collect\\Support\\Collection::offsetExists($key) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /Users/dummy/.composer/vendor/tightenco/collect/src/Collect/Support/Collection.php on line 1789
|
||||
|
||||
Deprecated: Return type of Tightenco\\Collect\\Support\\Collection::offsetGet($key) should either be compatible with ArrayAccess::offsetGet(mixed $offset): mixed, or the #[\\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /Users/dummy/.composer/vendor/tightenco/collect/src/Collect/Support/Collection.php on line 1800
|
||||
|
||||
Deprecated: Return type of Tightenco\\Collect\\Support\\Collection::offsetSet($key, $value) should either be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value): void, or the #[\\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /Users/dummy/.composer/vendor/tightenco/collect/src/Collect/Support/Collection.php on line 1812
|
||||
|
||||
Deprecated: Return type of Tightenco\\Collect\\Support\\Collection::offsetUnset($key) should either be compatible with ArrayAccess::offsetUnset(mixed $offset): void, or the #[\\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /Users/dummy/.composer/vendor/tightenco/collect/src/Collect/Support/Collection.php on line 1827
|
||||
|
||||
Deprecated: Return type of Tightenco\\Collect\\Support\\Collection::count() should either be compatible with Countable::count(): int, or the #[\\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /Users/dummy/.composer/vendor/tightenco/collect/src/Collect/Support/Collection.php on line 1768
|
||||
|
||||
Deprecated: Return type of Tightenco\\Collect\\Support\\Collection::getIterator() should either be compatible with IteratorAggregate::getIterator(): Traversable, or the #[\\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /Users/dummy/.composer/vendor/tightenco/collect/src/Collect/Support/Collection.php on line 1747
|
||||
|
||||
Deprecated: Return type of Tightenco\\Collect\\Support\\Collection::jsonSerialize() should either be compatible with JsonSerializable::jsonSerialize(): mixed, or the #[\\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /Users/dummy/.composer/vendor/tightenco/collect/src/Collect/Support/Collection.php on line 1716
|
||||
Laravel Valet 3.3.0
|
||||
"""
|
||||
|
||||
let versionString = output
|
||||
.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
.components(separatedBy: "Laravel Valet")[1]
|
||||
.trimmingCharacters(in: .whitespaces)
|
||||
|
||||
let version = try! VersionNumber.parse(VersionExtractor.from(versionString)!)
|
||||
|
||||
XCTAssertEqual(version.major, 3)
|
||||
}
|
||||
|
||||
func test_can_determine_valet_version() async {
|
||||
let version = await valet("--version", sudo: false)
|
||||
XCTAssert(version.contains("Laravel Valet 2") || version.contains("Laravel Valet 3"))
|
||||
|
Reference in New Issue
Block a user