1
0
mirror of https://github.com/nicoverbruggen/phpmon.git synced 2025-08-07 03:50:08 +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 */; };
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 */; };
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 */; };
C4D5CFCB27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D5CFC927E0F9CD00035329 /* NginxConfigurationFile.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>"; };
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>"; };
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>"; };
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>"; };
@ -1355,6 +1360,7 @@
children = (
C43931C429C4BD610069165B /* PhpFormulaeManager.swift */,
C48DDD0C29C75C9E00D032D9 /* BlockingOverlayView.swift */,
C4D5576329C77CC5001A44CD /* PhpVersionManagerWindowController.swift */,
);
path = PhpManager;
sourceTree = "<group>";
@ -2240,6 +2246,7 @@
C4F2E43A2752F7D00020E974 /* PhpInstallation.swift in Sources */,
C4D9F24B280B69E100DCD39A /* AddProxyVC.swift in Sources */,
C45B914E295608E300F4EC78 /* ValetServicesManager.swift in Sources */,
C4D5576429C77CC5001A44CD /* PhpVersionManagerWindowController.swift in Sources */,
C4E49DED28F764A00026AC4E /* TestableCommand.swift in Sources */,
C4A6957628D23EE300A14CF8 /* EnvironmentManager.swift in Sources */,
C41E871A2763D42300161EE0 /* DomainListVC+ContextMenu.swift in Sources */,
@ -2438,6 +2445,7 @@
C4E2E86628FC2F1B003B070C /* XCPMApplication.swift in Sources */,
C471E85F28F9BB650021E251 /* DomainListVC+Actions.swift in Sources */,
C490E3B429BC9FEA006D2DE6 /* ProgressWindowView.swift in Sources */,
C4D5576629C77CC5001A44CD /* PhpVersionManagerWindowController.swift in Sources */,
C471E86028F9BB650021E251 /* SelectionVC.swift in Sources */,
C471E86128F9BB650021E251 /* AddSiteVC.swift in Sources */,
C471E86228F9BB650021E251 /* AddProxyVC.swift in Sources */,
@ -2613,6 +2621,7 @@
C4E2E86A28FC3002003B070C /* Utility.swift in Sources */,
C471E8BF28F9BB8F0021E251 /* DomainListWindowController.swift in Sources */,
C471E8C028F9BB8F0021E251 /* DomainListVC.swift in Sources */,
C4D5576729C77CC5001A44CD /* PhpVersionManagerWindowController.swift in Sources */,
C471E8C128F9BB8F0021E251 /* DomainListVC+ContextMenu.swift in Sources */,
C4BF56AE2949381100379603 /* FakeValetInteractor.swift in Sources */,
C471E8C228F9BB8F0021E251 /* DomainListVC+Actions.swift in Sources */,
@ -2805,6 +2814,7 @@
C4B5635F276AB09000F12CCB /* VersionExtractor.swift in Sources */,
C463E381284930EE00422731 /* PresetHelper.swift in Sources */,
C46FA98C2822F08F00D78807 /* PhpConfigurationTest.swift in Sources */,
C4D5576529C77CC5001A44CD /* PhpVersionManagerWindowController.swift in Sources */,
C4BF90C127C57C220054E78C /* MainMenu+FixMyValet.swift in Sources */,
C4E49DEB28F7643D0026AC4E /* CommandProtocol.swift in Sources */,
C4F2E4382752F08D0020E974 /* BrewDiagnostics.swift in Sources */,

View File

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

View File

@ -80,6 +80,9 @@ class App {
/** The window controller of the warnings window. */
var warningsWindowController: WarningsWindowController?
/** The window controller of the warnings window. */
var versionManagerWindowController: PhpVersionManagerWindowController?
/** List of detected (installed) applications that PHP Monitor can work with. */
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] {
let command = """
\(Paths.brew) update >/dev/null && \
@ -38,12 +50,6 @@ class Brew {
let rawJsonText = await Shell.pipe(command).out
.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(
OutdatedFormulae.self,
from: rawJsonText
@ -51,15 +57,24 @@ class Brew {
formula.name.starts(with: "php")
})
return installed.map { (version, fullVersion) in
return BrewFormula(
name: version != phpAlias ? "php@\(version)" : "php",
displayName: version,
installedVersion: fullVersion,
upgradeVersion: outdated?.first(where: { formula in
return formula.installed_versions.contains(fullVersion)
return Self.phpVersionFormulae.map { (version, formula) in
let fullVersion = PhpEnv.shared.cachedPhpInstallations[version]?.versionNumber.text
var upgradeVersion: String? = nil
if let version = fullVersion {
upgradeVersion = outdated?.first(where: { formula in
return formula.installed_versions.contains(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()
}
@objc func openPhpVersionManager() {
PhpVersionManagerWindowController.show()
}
@objc func openDonate() {
NSWorkspace.shared.open(Constants.Urls.DonationPage)
}

View File

@ -91,33 +91,6 @@ extension StatusMenu {
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 {
addItem(NSMenuItem.separator())
addItem(NSMenuItem(
@ -164,6 +137,9 @@ extension StatusMenu {
func addConfigurationMenuItems() {
addItems([
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,
action: #selector(MainMenu.openActiveConfigFolder),
keyEquivalent: "c"),

View File

@ -1,5 +1,5 @@
//
// PhpFormulaeManager.swift
// PhpFormulaeView.swift
// PHP Monitor
//
// Created by Nico Verbruggen on 17/03/2023.
@ -9,67 +9,81 @@
import Foundation
import SwiftUI
struct PhpFormulaeManager: View {
struct PhpFormulaeView: View {
@State var formulae: [BrewFormula]
@State var busy: Bool = true
@State var title: String = "Doing a thing"
@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 {
BlockingOverlayView(busy: busy, title: title, text: description) {
List(Array(formulae.enumerated()), id: \.1.name) { (index, formula) in
HStack {
Image(systemName: formula.icon)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 16, height: 16)
.foregroundColor(formula.iconColor)
.padding(.horizontal, 5)
VStack(alignment: .leading) {
Text(formula.displayName).bold()
VStack {
List(Array(formulae.enumerated()), id: \.1.name) { (index, formula) in
HStack {
Image(systemName: formula.icon)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 16, height: 16)
.foregroundColor(formula.iconColor)
.padding(.horizontal, 5)
VStack(alignment: .leading) {
Text(formula.displayName).bold()
if formula.isInstalled && formula.hasUpgrade {
Text("\(formula.installedVersion!) installed, \(formula.upgradeVersion!) available.")
.font(.system(size: 11))
.foregroundColor(.gray)
} else if formula.isInstalled && formula.installedVersion != nil {
Text("Latest version is currently installed.").font(.system(size: 11))
.foregroundColor(.gray)
if formula.isInstalled && formula.hasUpgrade {
Text("\(formula.installedVersion!) installed, \(formula.upgradeVersion!) available.")
.font(.system(size: 11))
.foregroundColor(.gray)
} else if formula.isInstalled && formula.installedVersion != nil {
Text("Latest version is currently installed.").font(.system(size: 11))
.foregroundColor(.gray)
} else {
Text("This version can be installed.")
.font(.system(size: 11))
.foregroundColor(.gray)
}
}
.frame(maxWidth: .infinity, alignment: .leading)
if formula.isInstalled {
Button("Uninstall") {
// handle uninstall action here
}
} else {
Text("This version can be installed.")
.font(.system(size: 11))
.foregroundColor(.gray)
}
}
.frame(maxWidth: .infinity, alignment: .leading)
if formula.isInstalled {
Button("Uninstall") {
// handle uninstall action here
}
} else {
Button("Install") {
// handle install action here
}
}
if formula.hasUpgrade {
Button("Update") {
// handle uninstall action here
Button("Install") {
// handle install action here
}
}
if formula.hasUpgrade {
Button("Update") {
// handle uninstall action here
}
}
}
.listRowBackground(index % 2 == 0
? Color.gray.opacity(0)
: Color.gray.opacity(0.08)
)
.padding(.vertical, 10)
}
.listRowBackground(index % 2 == 0
? Color.gray.opacity(0)
: Color.gray.opacity(0.08)
)
.padding(.vertical, 10)
}
}.frame(width: 500, height: 500)
}
}
struct PhpFormulaeManager_Previews: PreviewProvider {
struct PhpFormulaeView_Previews: PreviewProvider {
static var previews: some View {
PhpFormulaeManager(formulae: [
PhpFormulaeView(formulae: [
BrewFormula(
name: "php",
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_fix_php_link" = "Fix Automatically...";
"mi_no_php_linked_explain" = "What's This?";
"mi_php_version_manager" = "Install & Upgrade PHP Versions...";
"mi_diagnostics" = "Diagnostics";
"mi_active_services" = "Active Services";