From 08dcfb36f4d3accd80b495a8c1889d33acac6742 Mon Sep 17 00:00:00 2001 From: Nico Verbruggen Date: Sun, 19 Mar 2023 14:00:15 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=8F=97=20WIP:=20Formulae=20manager=20UI?= =?UTF-8?q?=20changes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PHP Monitor.xcodeproj/project.pbxproj | 20 +-- .../PhpManager/PhpFormulaeManager.swift | 110 +++++++++++++++++ .../SwiftUI/PhpManager/PhpManager.swift | 115 ------------------ .../unit/Parsers/HomebrewUpgradableTest.swift | 3 +- 4 files changed, 122 insertions(+), 126 deletions(-) create mode 100644 phpmon/Domain/SwiftUI/PhpManager/PhpFormulaeManager.swift delete mode 100644 phpmon/Domain/SwiftUI/PhpManager/PhpManager.swift diff --git a/PHP Monitor.xcodeproj/project.pbxproj b/PHP Monitor.xcodeproj/project.pbxproj index 02dc9f2..877fb5e 100644 --- a/PHP Monitor.xcodeproj/project.pbxproj +++ b/PHP Monitor.xcodeproj/project.pbxproj @@ -129,10 +129,10 @@ C42F26762805FEE200938AC7 /* nginx-secure-proxy.test in Resources */ = {isa = PBXBuildFile; fileRef = C42F26752805FEE200938AC7 /* nginx-secure-proxy.test */; }; C43603A0275E67610028EFC6 /* AppDelegate+Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = C436039F275E67610028EFC6 /* AppDelegate+Notifications.swift */; }; C43603A1275E67610028EFC6 /* AppDelegate+Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = C436039F275E67610028EFC6 /* AppDelegate+Notifications.swift */; }; - C43931C529C4BD610069165B /* PhpManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43931C429C4BD610069165B /* PhpManager.swift */; }; - C43931C629C4BD610069165B /* PhpManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43931C429C4BD610069165B /* PhpManager.swift */; }; - C43931C729C4BD610069165B /* PhpManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43931C429C4BD610069165B /* PhpManager.swift */; }; - C43931C829C4BD610069165B /* PhpManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43931C429C4BD610069165B /* PhpManager.swift */; }; + C43931C529C4BD610069165B /* PhpFormulaeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43931C429C4BD610069165B /* PhpFormulaeManager.swift */; }; + C43931C629C4BD610069165B /* PhpFormulaeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43931C429C4BD610069165B /* PhpFormulaeManager.swift */; }; + C43931C729C4BD610069165B /* PhpFormulaeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43931C429C4BD610069165B /* PhpFormulaeManager.swift */; }; + C43931C829C4BD610069165B /* PhpFormulaeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43931C429C4BD610069165B /* PhpFormulaeManager.swift */; }; C43931CA29C4C03F0069165B /* Brew.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43931C929C4C03F0069165B /* Brew.swift */; }; C43931CB29C4C03F0069165B /* Brew.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43931C929C4C03F0069165B /* Brew.swift */; }; C43931CC29C4C03F0069165B /* Brew.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43931C929C4C03F0069165B /* Brew.swift */; }; @@ -875,7 +875,7 @@ C42F26722805B4B400938AC7 /* ValetListable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValetListable.swift; sourceTree = ""; }; C42F26752805FEE200938AC7 /* nginx-secure-proxy.test */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "nginx-secure-proxy.test"; sourceTree = ""; }; C436039F275E67610028EFC6 /* AppDelegate+Notifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+Notifications.swift"; sourceTree = ""; }; - C43931C429C4BD610069165B /* PhpManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpManager.swift; sourceTree = ""; }; + C43931C429C4BD610069165B /* PhpFormulaeManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpFormulaeManager.swift; sourceTree = ""; }; C43931C929C4C03F0069165B /* Brew.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Brew.swift; sourceTree = ""; }; C43A8A1925D9CD1000591B77 /* Utility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utility.swift; sourceTree = ""; }; C43A8A1F25D9D1D700591B77 /* brew-formula.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "brew-formula.json"; sourceTree = ""; }; @@ -1348,7 +1348,7 @@ C43931C329C4BD510069165B /* PhpManager */ = { isa = PBXGroup; children = ( - C43931C429C4BD610069165B /* PhpManager.swift */, + C43931C429C4BD610069165B /* PhpFormulaeManager.swift */, ); path = PhpManager; sourceTree = ""; @@ -2263,7 +2263,7 @@ C4C3643928AE4FCE00C0770E /* StatusMenu+Items.swift in Sources */, C4AC51FC27E27F47008528CA /* DomainListKindCell.swift in Sources */, C4CDA893288F1A71007CE25F /* Keys.swift in Sources */, - C43931C529C4BD610069165B /* PhpManager.swift in Sources */, + C43931C529C4BD610069165B /* PhpFormulaeManager.swift in Sources */, C40175B82903108900763A68 /* ValetInteractor.swift in Sources */, C4F361612836BFD9003598CC /* MainMenu+Actions.swift in Sources */, C46EBC4A28DB966A007ACC74 /* TestableShell.swift in Sources */, @@ -2437,7 +2437,7 @@ C471E86328F9BB650021E251 /* PMTableView.swift in Sources */, C471E86428F9BB650021E251 /* Warning.swift in Sources */, C40175BA2903108900763A68 /* ValetInteractor.swift in Sources */, - C43931C729C4BD610069165B /* PhpManager.swift in Sources */, + C43931C729C4BD610069165B /* PhpFormulaeManager.swift in Sources */, C4463FCE29804BCB007B93D5 /* RCFile.swift in Sources */, C45B9150295608E300F4EC78 /* ValetServicesManager.swift in Sources */, C471E86528F9BB650021E251 /* WarningManager.swift in Sources */, @@ -2689,7 +2689,7 @@ C471E82228F9BB2E0021E251 /* ComposerWindow.swift in Sources */, C4D3660E29113F20006BD146 /* System.swift in Sources */, C471E80428F9BAD40021E251 /* PhpExtension.swift in Sources */, - C43931C829C4BD610069165B /* PhpManager.swift in Sources */, + C43931C829C4BD610069165B /* PhpFormulaeManager.swift in Sources */, C471E7F728F9BACB0021E251 /* PhpSwitcher.swift in Sources */, C4463FCF29804BCB007B93D5 /* RCFile.swift in Sources */, C471E82C28F9BB340021E251 /* ValetListable.swift in Sources */, @@ -2790,7 +2790,7 @@ C47DF1B0299D5A3B0007055D /* LoginItemManager.swift in Sources */, C4F780C025D80B6E000DBC97 /* Startup.swift in Sources */, C45B914A295607F400F4EC78 /* Service.swift in Sources */, - C43931C629C4BD610069165B /* PhpManager.swift in Sources */, + C43931C629C4BD610069165B /* PhpFormulaeManager.swift in Sources */, C4C0E8E327F88B13002D32A9 /* ValetDomainScanner.swift in Sources */, C4CCBA6D275C567B008C7055 /* PMWindowController.swift in Sources */, C4B5635F276AB09000F12CCB /* VersionExtractor.swift in Sources */, diff --git a/phpmon/Domain/SwiftUI/PhpManager/PhpFormulaeManager.swift b/phpmon/Domain/SwiftUI/PhpManager/PhpFormulaeManager.swift new file mode 100644 index 0000000..faca9cd --- /dev/null +++ b/phpmon/Domain/SwiftUI/PhpManager/PhpFormulaeManager.swift @@ -0,0 +1,110 @@ +// +// PhpFormulaeManager.swift +// PHP Monitor +// +// Created by Nico Verbruggen on 17/03/2023. +// Copyright © 2023 Nico Verbruggen. All rights reserved. +// + +import Foundation +import SwiftUI + +struct PhpFormulaeManager: View { + @State var formulae: [BrewFormula] + @State var busy: Bool = false + + var body: some View { + 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) + } 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 + } + } + } + .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 { + static var previews: some View { + PhpFormulaeManager(formulae: [ + BrewFormula( + name: "php", + displayName: "PHP 8.2", + installedVersion: "8.2.3", + upgradeVersion: "8.2.4" + ), + BrewFormula( + name: "php@8.1", + displayName: "PHP 8.1", + installedVersion: "8.1.17", + upgradeVersion: nil + ), + BrewFormula( + name: "php@8.0", + displayName: "PHP 8.0", + installedVersion: nil, + upgradeVersion: nil + ) + ]).frame(width: 600, height: 500) + } +} + +extension BrewFormula { + var icon: String { + if self.hasUpgrade { + return "arrow.up.square.fill" + } else if self.isInstalled { + return "checkmark.square.fill" + } + return "square.dashed" + } + + var iconColor: Color { + if self.hasUpgrade { + return .blue + } else if self.isInstalled { + return .green + } + return Color.gray.opacity(0.3) + } +} diff --git a/phpmon/Domain/SwiftUI/PhpManager/PhpManager.swift b/phpmon/Domain/SwiftUI/PhpManager/PhpManager.swift deleted file mode 100644 index f9f28a7..0000000 --- a/phpmon/Domain/SwiftUI/PhpManager/PhpManager.swift +++ /dev/null @@ -1,115 +0,0 @@ -// -// PhpManager.swift -// PHP Monitor -// -// Created by Nico Verbruggen on 17/03/2023. -// Copyright © 2023 Nico Verbruggen. All rights reserved. -// - -import Foundation -import SwiftUI - -struct PhpInstallable { - var name: String - var installed: String? - var latest: String - var actions: [PhpInstallAction] - - var icon: String { - if actions.contains(.upgrade) { - return "arrow.up.square.fill" - } - if actions.contains(.remove) || installed != nil { - return "checkmark.square.fill" - } - return "square.dashed" - } - - var iconColor: Color { - if actions.contains(.upgrade) { - return .blue - } else if actions.contains(.remove) || installed != nil { - return .green - } - return Color.gray.opacity(0.3) - } -} - -struct PhpInstallationList: View { - @State var phpVersions: [PhpInstallable] - - var body: some View { - List(Array(phpVersions.enumerated()), id: \.1.name) { (index, version) in - HStack { - Image(systemName: version.icon) - .resizable() - .aspectRatio(contentMode: .fit) - .frame(width: 16, height: 16) - .foregroundColor(version.iconColor) - .padding(.horizontal, 5) - VStack(alignment: .leading) { - Text(version.name).bold() - - if version.actions.contains(.upgrade) { - Text("\(version.installed!) installed, \(version.latest) available.") - .font(.system(size: 11)) - .foregroundColor(.gray) - } else if version.installed != nil { - Text("Latest version is currently installed.").font(.system(size: 11)) - .foregroundColor(.gray) - } - - if version.actions.contains(.install) { - Text("This version can be installed.") - .font(.system(size: 11)) - .foregroundColor(.gray) - } - } - .frame(maxWidth: .infinity, alignment: .leading) - if version.actions.contains(.install) { - Button("Install") { - // handle install action here - } - } - if version.actions.contains(.upgrade) { - Button("Upgrade") { - // handle uninstall action here - } - } - if version.actions.contains(.remove) { - Button("Uninstall") { - // handle uninstall action here - } - } - if version.actions.isEmpty { - Button("Unavailable") { - // handle uninstall action here - }.disabled(true) - } - - } - .listRowBackground(index % 2 == 0 - ? Color.gray.opacity(0) - : Color.gray.opacity(0.08) - ) - .padding(.vertical, 10) - } - .frame(width: 500, height: 500) - } -} - -struct PhpInstallationList_Previews: PreviewProvider { - static var previews: some View { - PhpInstallationList(phpVersions: [ - PhpInstallable(name: "PHP 8.2", installed: "8.2.3", latest: "8.2.4", actions: [.upgrade]), - PhpInstallable(name: "PHP 8.1", installed: "8.1.15", latest: "8.1.16", actions: [.upgrade, .remove]), - PhpInstallable(name: "PHP 8.0", installed: "8.0.14", latest: "8.0.14", actions: [.remove]), - PhpInstallable(name: "PHP 7.4", installed: nil, latest: "", actions: [.install]), - PhpInstallable(name: "PHP 7.3", installed: nil, latest: "", actions: [.install]), - PhpInstallable(name: "PHP 7.2", installed: nil, latest: "", actions: [.install]), - PhpInstallable(name: "PHP 7.1", installed: nil, latest: "", actions: [.install]), - PhpInstallable(name: "PHP 7.0", installed: nil, latest: "", actions: [.install]), - PhpInstallable(name: "PHP 5.6", installed: nil, latest: "", actions: [.install]) - ]).frame(width: 600, height: 500) - } -} diff --git a/tests/unit/Parsers/HomebrewUpgradableTest.swift b/tests/unit/Parsers/HomebrewUpgradableTest.swift index 28f0420..aa46be0 100644 --- a/tests/unit/Parsers/HomebrewUpgradableTest.swift +++ b/tests/unit/Parsers/HomebrewUpgradableTest.swift @@ -16,7 +16,8 @@ class HomebrewUpgradableTest: XCTestCase { func test_upgradable_php_versions_can_be_parsed() async throws { ActiveShell.useTestable([ - "/opt/homebrew/bin/brew update >/dev/null && /opt/homebrew/bin/brew outdated --json --formulae": .instant(try! String(contentsOf: Self.outdatedFileUrl)) + "/opt/homebrew/bin/brew update >/dev/null && /opt/homebrew/bin/brew outdated --json --formulae" + : .instant(try! String(contentsOf: Self.outdatedFileUrl)) ]) let env = PhpEnv.shared