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

Display window, load info for all PHP versions

This commit is contained in:
2023-03-19 19:02:34 +01:00
parent 2939a2ab28
commit e1eb61859e
9 changed files with 162 additions and 84 deletions

View File

@ -672,6 +672,10 @@
C4D4CB3829C109CF00DB9F93 /* InternalSwitcher+Valet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D4CB3629C109CF00DB9F93 /* InternalSwitcher+Valet.swift */; }; C4D4CB3829C109CF00DB9F93 /* InternalSwitcher+Valet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D4CB3629C109CF00DB9F93 /* InternalSwitcher+Valet.swift */; };
C4D4CB3929C109CF00DB9F93 /* InternalSwitcher+Valet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D4CB3629C109CF00DB9F93 /* InternalSwitcher+Valet.swift */; }; C4D4CB3929C109CF00DB9F93 /* InternalSwitcher+Valet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D4CB3629C109CF00DB9F93 /* InternalSwitcher+Valet.swift */; };
C4D4CB3A29C109CF00DB9F93 /* InternalSwitcher+Valet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D4CB3629C109CF00DB9F93 /* InternalSwitcher+Valet.swift */; }; C4D4CB3A29C109CF00DB9F93 /* InternalSwitcher+Valet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D4CB3629C109CF00DB9F93 /* InternalSwitcher+Valet.swift */; };
C4D5576429C77CC5001A44CD /* PhpVersionManagerWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D5576329C77CC5001A44CD /* PhpVersionManagerWindowController.swift */; };
C4D5576529C77CC5001A44CD /* PhpVersionManagerWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D5576329C77CC5001A44CD /* PhpVersionManagerWindowController.swift */; };
C4D5576629C77CC5001A44CD /* PhpVersionManagerWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D5576329C77CC5001A44CD /* PhpVersionManagerWindowController.swift */; };
C4D5576729C77CC5001A44CD /* PhpVersionManagerWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D5576329C77CC5001A44CD /* PhpVersionManagerWindowController.swift */; };
C4D5CFCA27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D5CFC927E0F9CD00035329 /* NginxConfigurationFile.swift */; }; C4D5CFCA27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D5CFC927E0F9CD00035329 /* NginxConfigurationFile.swift */; };
C4D5CFCB27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D5CFC927E0F9CD00035329 /* NginxConfigurationFile.swift */; }; C4D5CFCB27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D5CFC927E0F9CD00035329 /* NginxConfigurationFile.swift */; };
C4D8016622B1584700C6DA1B /* Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D8016522B1584700C6DA1B /* Startup.swift */; }; C4D8016622B1584700C6DA1B /* Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D8016522B1584700C6DA1B /* Startup.swift */; };
@ -1001,6 +1005,7 @@
C4D36614291160A1006BD146 /* WIP.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WIP.swift; sourceTree = "<group>"; }; C4D36614291160A1006BD146 /* WIP.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WIP.swift; sourceTree = "<group>"; };
C4D36619291173EA006BD146 /* DictionaryExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DictionaryExtension.swift; sourceTree = "<group>"; }; C4D36619291173EA006BD146 /* DictionaryExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DictionaryExtension.swift; sourceTree = "<group>"; };
C4D4CB3629C109CF00DB9F93 /* InternalSwitcher+Valet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "InternalSwitcher+Valet.swift"; sourceTree = "<group>"; }; C4D4CB3629C109CF00DB9F93 /* InternalSwitcher+Valet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "InternalSwitcher+Valet.swift"; sourceTree = "<group>"; };
C4D5576329C77CC5001A44CD /* PhpVersionManagerWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpVersionManagerWindowController.swift; sourceTree = "<group>"; };
C4D5CFC927E0F9CD00035329 /* NginxConfigurationFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NginxConfigurationFile.swift; sourceTree = "<group>"; }; C4D5CFC927E0F9CD00035329 /* NginxConfigurationFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NginxConfigurationFile.swift; sourceTree = "<group>"; };
C4D8016522B1584700C6DA1B /* Startup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Startup.swift; sourceTree = "<group>"; }; C4D8016522B1584700C6DA1B /* Startup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Startup.swift; sourceTree = "<group>"; };
C4D89BC52783C99400A02B68 /* ComposerJson.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerJson.swift; sourceTree = "<group>"; }; C4D89BC52783C99400A02B68 /* ComposerJson.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerJson.swift; sourceTree = "<group>"; };
@ -1355,6 +1360,7 @@
children = ( children = (
C43931C429C4BD610069165B /* PhpFormulaeManager.swift */, C43931C429C4BD610069165B /* PhpFormulaeManager.swift */,
C48DDD0C29C75C9E00D032D9 /* BlockingOverlayView.swift */, C48DDD0C29C75C9E00D032D9 /* BlockingOverlayView.swift */,
C4D5576329C77CC5001A44CD /* PhpVersionManagerWindowController.swift */,
); );
path = PhpManager; path = PhpManager;
sourceTree = "<group>"; sourceTree = "<group>";
@ -2240,6 +2246,7 @@
C4F2E43A2752F7D00020E974 /* PhpInstallation.swift in Sources */, C4F2E43A2752F7D00020E974 /* PhpInstallation.swift in Sources */,
C4D9F24B280B69E100DCD39A /* AddProxyVC.swift in Sources */, C4D9F24B280B69E100DCD39A /* AddProxyVC.swift in Sources */,
C45B914E295608E300F4EC78 /* ValetServicesManager.swift in Sources */, C45B914E295608E300F4EC78 /* ValetServicesManager.swift in Sources */,
C4D5576429C77CC5001A44CD /* PhpVersionManagerWindowController.swift in Sources */,
C4E49DED28F764A00026AC4E /* TestableCommand.swift in Sources */, C4E49DED28F764A00026AC4E /* TestableCommand.swift in Sources */,
C4A6957628D23EE300A14CF8 /* EnvironmentManager.swift in Sources */, C4A6957628D23EE300A14CF8 /* EnvironmentManager.swift in Sources */,
C41E871A2763D42300161EE0 /* DomainListVC+ContextMenu.swift in Sources */, C41E871A2763D42300161EE0 /* DomainListVC+ContextMenu.swift in Sources */,
@ -2438,6 +2445,7 @@
C4E2E86628FC2F1B003B070C /* XCPMApplication.swift in Sources */, C4E2E86628FC2F1B003B070C /* XCPMApplication.swift in Sources */,
C471E85F28F9BB650021E251 /* DomainListVC+Actions.swift in Sources */, C471E85F28F9BB650021E251 /* DomainListVC+Actions.swift in Sources */,
C490E3B429BC9FEA006D2DE6 /* ProgressWindowView.swift in Sources */, C490E3B429BC9FEA006D2DE6 /* ProgressWindowView.swift in Sources */,
C4D5576629C77CC5001A44CD /* PhpVersionManagerWindowController.swift in Sources */,
C471E86028F9BB650021E251 /* SelectionVC.swift in Sources */, C471E86028F9BB650021E251 /* SelectionVC.swift in Sources */,
C471E86128F9BB650021E251 /* AddSiteVC.swift in Sources */, C471E86128F9BB650021E251 /* AddSiteVC.swift in Sources */,
C471E86228F9BB650021E251 /* AddProxyVC.swift in Sources */, C471E86228F9BB650021E251 /* AddProxyVC.swift in Sources */,
@ -2613,6 +2621,7 @@
C4E2E86A28FC3002003B070C /* Utility.swift in Sources */, C4E2E86A28FC3002003B070C /* Utility.swift in Sources */,
C471E8BF28F9BB8F0021E251 /* DomainListWindowController.swift in Sources */, C471E8BF28F9BB8F0021E251 /* DomainListWindowController.swift in Sources */,
C471E8C028F9BB8F0021E251 /* DomainListVC.swift in Sources */, C471E8C028F9BB8F0021E251 /* DomainListVC.swift in Sources */,
C4D5576729C77CC5001A44CD /* PhpVersionManagerWindowController.swift in Sources */,
C471E8C128F9BB8F0021E251 /* DomainListVC+ContextMenu.swift in Sources */, C471E8C128F9BB8F0021E251 /* DomainListVC+ContextMenu.swift in Sources */,
C4BF56AE2949381100379603 /* FakeValetInteractor.swift in Sources */, C4BF56AE2949381100379603 /* FakeValetInteractor.swift in Sources */,
C471E8C228F9BB8F0021E251 /* DomainListVC+Actions.swift in Sources */, C471E8C228F9BB8F0021E251 /* DomainListVC+Actions.swift in Sources */,
@ -2805,6 +2814,7 @@
C4B5635F276AB09000F12CCB /* VersionExtractor.swift in Sources */, C4B5635F276AB09000F12CCB /* VersionExtractor.swift in Sources */,
C463E381284930EE00422731 /* PresetHelper.swift in Sources */, C463E381284930EE00422731 /* PresetHelper.swift in Sources */,
C46FA98C2822F08F00D78807 /* PhpConfigurationTest.swift in Sources */, C46FA98C2822F08F00D78807 /* PhpConfigurationTest.swift in Sources */,
C4D5576529C77CC5001A44CD /* PhpVersionManagerWindowController.swift in Sources */,
C4BF90C127C57C220054E78C /* MainMenu+FixMyValet.swift in Sources */, C4BF90C127C57C220054E78C /* MainMenu+FixMyValet.swift in Sources */,
C4E49DEB28F7643D0026AC4E /* CommandProtocol.swift in Sources */, C4E49DEB28F7643D0026AC4E /* CommandProtocol.swift in Sources */,
C4F2E4382752F08D0020E974 /* BrewDiagnostics.swift in Sources */, C4F2E4382752F08D0020E974 /* BrewDiagnostics.swift in Sources */,

View File

@ -17,6 +17,7 @@ public enum PhpInstallAction {
} }
public class PhpVersionInstaller { public class PhpVersionInstaller {
// TODO: Remove
public static var installables = [ public static var installables = [
// "8.2": "php", // "8.2": "php",
"8.1": "php@8.1", "8.1": "php@8.1",

View File

@ -80,6 +80,9 @@ class App {
/** The window controller of the warnings window. */ /** The window controller of the warnings window. */
var warningsWindowController: WarningsWindowController? var warningsWindowController: WarningsWindowController?
/** The window controller of the warnings window. */
var versionManagerWindowController: PhpVersionManagerWindowController?
/** List of detected (installed) applications that PHP Monitor can work with. */ /** List of detected (installed) applications that PHP Monitor can work with. */
var detectedApplications: [Application] = [] var detectedApplications: [Application] = []

View File

@ -29,6 +29,18 @@ class Brew {
} }
} }
public static var phpVersionFormulae = [
"8.2": "php@8.2",
"8.1": "php@8.1",
"8.0": "php@8.0",
"7.4": "shivammathur/php/php@7.4",
"7.3": "shivammathur/php/php@7.3",
"7.2": "shivammathur/php/php@7.2",
"7.1": "shivammathur/php/php@7.1",
"7.0": "shivammathur/php/php@7.0",
"5.6": "shivammathur/php/php@5.6",
]
public func getPhpVersions() async -> [BrewFormula] { public func getPhpVersions() async -> [BrewFormula] {
let command = """ let command = """
\(Paths.brew) update >/dev/null && \ \(Paths.brew) update >/dev/null && \
@ -38,12 +50,6 @@ class Brew {
let rawJsonText = await Shell.pipe(command).out let rawJsonText = await Shell.pipe(command).out
.data(using: .utf8)! .data(using: .utf8)!
let installed = PhpEnv.shared.cachedPhpInstallations.map { key, value in
return (key, value.versionNumber.text)
}
let phpAlias = PhpEnv.brewPhpAlias
let outdated = try? JSONDecoder().decode( let outdated = try? JSONDecoder().decode(
OutdatedFormulae.self, OutdatedFormulae.self,
from: rawJsonText from: rawJsonText
@ -51,15 +57,24 @@ class Brew {
formula.name.starts(with: "php") formula.name.starts(with: "php")
}) })
return installed.map { (version, fullVersion) in return Self.phpVersionFormulae.map { (version, formula) in
return BrewFormula( let fullVersion = PhpEnv.shared.cachedPhpInstallations[version]?.versionNumber.text
name: version != phpAlias ? "php@\(version)" : "php", var upgradeVersion: String? = nil
displayName: version,
installedVersion: fullVersion, if let version = fullVersion {
upgradeVersion: outdated?.first(where: { formula in upgradeVersion = outdated?.first(where: { formula in
return formula.installed_versions.contains(fullVersion) return formula.installed_versions.contains(version)
})?.current_version })?.current_version
}
return BrewFormula(
name: formula,
displayName: "PHP \(version)",
installedVersion: fullVersion,
upgradeVersion: upgradeVersion
) )
}.sorted { a, b in
a.displayName > b.displayName
} }
} }
} }

View File

@ -190,6 +190,10 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate
DomainListVC.show() DomainListVC.show()
} }
@objc func openPhpVersionManager() {
PhpVersionManagerWindowController.show()
}
@objc func openDonate() { @objc func openDonate() {
NSWorkspace.shared.open(Constants.Urls.DonationPage) NSWorkspace.shared.open(Constants.Urls.DonationPage)
} }

View File

@ -91,33 +91,6 @@ extension StatusMenu {
addItem(menuItem) addItem(menuItem)
} }
// TODO: This is a fixed list...
addItem(NSMenuItem.separator())
addItem(HeaderView.asMenuItem(text: "Experimental"))
for result in PhpVersionInstaller.availableActions {
let title = result.action == .install
? "Install PHP \(result.version)..."
: "Remove PHP \(result.version)..."
let action: Selector? = result.action == .install
? #selector(MainMenu.installPhpVersion(sender:))
: #selector(MainMenu.removePhpVersion(sender:))
if result.version == PhpEnv.brewPhpAlias {
continue
}
let menuItem = PhpMenuItem(
title: title,
action: action,
keyEquivalent: ""
)
menuItem.version = result.version
addItem(menuItem)
}
if !PhpEnv.shared.incompatiblePhpVersions.isEmpty { if !PhpEnv.shared.incompatiblePhpVersions.isEmpty {
addItem(NSMenuItem.separator()) addItem(NSMenuItem.separator())
addItem(NSMenuItem( addItem(NSMenuItem(
@ -164,6 +137,9 @@ extension StatusMenu {
func addConfigurationMenuItems() { func addConfigurationMenuItems() {
addItems([ addItems([
HeaderView.asMenuItem(text: "mi_configuration".localized), HeaderView.asMenuItem(text: "mi_configuration".localized),
NSMenuItem(title: "mi_php_version_manager".localized,
action: #selector(MainMenu.openPhpVersionManager),
keyEquivalent: "m"),
NSMenuItem(title: "mi_php_config".localized, NSMenuItem(title: "mi_php_config".localized,
action: #selector(MainMenu.openActiveConfigFolder), action: #selector(MainMenu.openActiveConfigFolder),
keyEquivalent: "c"), keyEquivalent: "c"),

View File

@ -1,5 +1,5 @@
// //
// PhpFormulaeManager.swift // PhpFormulaeView.swift
// PHP Monitor // PHP Monitor
// //
// Created by Nico Verbruggen on 17/03/2023. // Created by Nico Verbruggen on 17/03/2023.
@ -9,14 +9,27 @@
import Foundation import Foundation
import SwiftUI import SwiftUI
struct PhpFormulaeManager: View { struct PhpFormulaeView: View {
@State var formulae: [BrewFormula] @State var formulae: [BrewFormula]
@State var busy: Bool = true @State var busy: Bool = true
@State var title: String = "Doing a thing" @State var title: String = "Doing a thing"
@State var description: String = "Preparing..." @State var description: String = "Preparing..."
init(formulae: [BrewFormula], busy: Bool = true, title: String = "", description: String = "") {
self.formulae = formulae
self.busy = busy
self.title = title
self.description = description
Task { @MainActor in
let items = await Brew.shared.getPhpVersions()
print(items)
}
}
var body: some View { var body: some View {
BlockingOverlayView(busy: busy, title: title, text: description) { BlockingOverlayView(busy: busy, title: title, text: description) {
VStack {
List(Array(formulae.enumerated()), id: \.1.name) { (index, formula) in List(Array(formulae.enumerated()), id: \.1.name) { (index, formula) in
HStack { HStack {
Image(systemName: formula.icon) Image(systemName: formula.icon)
@ -63,13 +76,14 @@ struct PhpFormulaeManager: View {
) )
.padding(.vertical, 10) .padding(.vertical, 10)
} }
}
}.frame(width: 500, height: 500) }.frame(width: 500, height: 500)
} }
} }
struct PhpFormulaeManager_Previews: PreviewProvider { struct PhpFormulaeView_Previews: PreviewProvider {
static var previews: some View { static var previews: some View {
PhpFormulaeManager(formulae: [ PhpFormulaeView(formulae: [
BrewFormula( BrewFormula(
name: "php", name: "php",
displayName: "PHP 8.2", displayName: "PHP 8.2",

View File

@ -0,0 +1,54 @@
//
// PhpVersionManagerWindowController.swift
// PHP Monitor
//
// Created by Nico Verbruggen on 19/03/2023.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation
import Cocoa
import SwiftUI
class PhpVersionManagerWindowController: PMWindowController {
// MARK: - Window Identifier
var view: PhpFormulaeView!
override var windowName: String {
return "PhpFormulaeView"
}
public static func create(delegate: NSWindowDelegate?) {
let windowController = Self()
windowController.window = NSWindow()
windowController.view = PhpFormulaeView(
formulae: [],
busy: true,
title: "Loading PHP versions",
description: "Loading available PHP versions..."
)
guard let window = windowController.window else { return }
window.title = ""
window.styleMask = [.titled, .closable, .miniaturizable]
window.titlebarAppearsTransparent = true
window.delegate = delegate ?? windowController
window.contentView = NSHostingView(rootView: windowController.view)
window.setContentSize(NSSize(width: 600, height: 480))
App.shared.versionManagerWindowController = windowController
}
public static func show(delegate: NSWindowDelegate? = nil) {
if App.shared.versionManagerWindowController == nil {
Self.create(delegate: delegate)
}
App.shared.versionManagerWindowController?.showWindow(self)
App.shared.versionManagerWindowController?.window?.setCenterPosition(offsetY: 70)
NSApp.activate(ignoringOtherApps: true)
}
}

View File

@ -20,6 +20,7 @@
"mi_no_php_linked" = "No PHP version linked!"; "mi_no_php_linked" = "No PHP version linked!";
"mi_fix_php_link" = "Fix Automatically..."; "mi_fix_php_link" = "Fix Automatically...";
"mi_no_php_linked_explain" = "What's This?"; "mi_no_php_linked_explain" = "What's This?";
"mi_php_version_manager" = "Install & Upgrade PHP Versions...";
"mi_diagnostics" = "Diagnostics"; "mi_diagnostics" = "Diagnostics";
"mi_active_services" = "Active Services"; "mi_active_services" = "Active Services";