From 8f1304308de9bb6d82337db90d76b523aa047203 Mon Sep 17 00:00:00 2001 From: Nico Verbruggen Date: Fri, 17 Mar 2023 20:38:21 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=8F=97=20WIP:=20Parsing=20version=20updat?= =?UTF-8?q?es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PHP Monitor.xcodeproj/project.pbxproj | 18 ++ .../Domain/Integrations/Homebrew/Brew.swift | 18 ++ .../Integrations/Homebrew/BrewFormula.swift | 23 +++ tests/feature/InternalSwitcherTest.swift | 15 +- tests/unit/Parsers/HomebrewTest.swift | 33 ++++ tests/unit/Test Files/brew/brew-outdated.json | 169 ++++++++++++++++++ 6 files changed, 265 insertions(+), 11 deletions(-) create mode 100644 phpmon/Domain/Integrations/Homebrew/BrewFormula.swift create mode 100644 tests/unit/Parsers/HomebrewTest.swift create mode 100644 tests/unit/Test Files/brew/brew-outdated.json diff --git a/PHP Monitor.xcodeproj/project.pbxproj b/PHP Monitor.xcodeproj/project.pbxproj index b8f1bf5..802028d 100644 --- a/PHP Monitor.xcodeproj/project.pbxproj +++ b/PHP Monitor.xcodeproj/project.pbxproj @@ -579,6 +579,12 @@ C4AF9F7A2754499000D44ED0 /* Valet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AF9F792754499000D44ED0 /* Valet.swift */; }; C4AF9F7B2754499000D44ED0 /* Valet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AF9F792754499000D44ED0 /* Valet.swift */; }; C4AF9F7D275454A900D44ED0 /* ValetVersionExtractorTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AF9F7C275454A900D44ED0 /* ValetVersionExtractorTest.swift */; }; + C4AFC4AE29C4F32F00BF4E0D /* BrewFormula.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AFC4AD29C4F32F00BF4E0D /* BrewFormula.swift */; }; + C4AFC4AF29C4F32F00BF4E0D /* BrewFormula.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AFC4AD29C4F32F00BF4E0D /* BrewFormula.swift */; }; + C4AFC4B029C4F32F00BF4E0D /* BrewFormula.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AFC4AD29C4F32F00BF4E0D /* BrewFormula.swift */; }; + C4AFC4B129C4F32F00BF4E0D /* BrewFormula.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AFC4AD29C4F32F00BF4E0D /* BrewFormula.swift */; }; + C4AFC4B429C4F43300BF4E0D /* HomebrewTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AFC4B229C4F43300BF4E0D /* HomebrewTest.swift */; }; + C4AFC4B829C4F6DC00BF4E0D /* brew-outdated.json in Resources */ = {isa = PBXBuildFile; fileRef = C4AFC4B729C4F57B00BF4E0D /* brew-outdated.json */; }; C4B5635E276AB09000F12CCB /* VersionExtractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B5635D276AB09000F12CCB /* VersionExtractor.swift */; }; C4B5635F276AB09000F12CCB /* VersionExtractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B5635D276AB09000F12CCB /* VersionExtractor.swift */; }; C4B56362276AB0A500F12CCB /* VersionExtractorTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B56360276AB0A500F12CCB /* VersionExtractorTest.swift */; }; @@ -949,6 +955,9 @@ C4AF9F76275447F100D44ED0 /* ValetConfigurationTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValetConfigurationTest.swift; sourceTree = ""; }; C4AF9F792754499000D44ED0 /* Valet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Valet.swift; sourceTree = ""; }; C4AF9F7C275454A900D44ED0 /* ValetVersionExtractorTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValetVersionExtractorTest.swift; sourceTree = ""; }; + C4AFC4AD29C4F32F00BF4E0D /* BrewFormula.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrewFormula.swift; sourceTree = ""; }; + C4AFC4B229C4F43300BF4E0D /* HomebrewTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomebrewTest.swift; sourceTree = ""; }; + C4AFC4B729C4F57B00BF4E0D /* brew-outdated.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "brew-outdated.json"; sourceTree = ""; }; C4B5635D276AB09000F12CCB /* VersionExtractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionExtractor.swift; sourceTree = ""; }; C4B56360276AB0A500F12CCB /* VersionExtractorTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VersionExtractorTest.swift; sourceTree = ""; }; C4B5853B2770FE3900DA4FBE /* Paths.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Paths.swift; sourceTree = ""; }; @@ -1424,6 +1433,7 @@ isa = PBXGroup; children = ( C40934A6298EEB8700D25014 /* phpmon-dev.rb */, + C4AFC4B729C4F57B00BF4E0D /* brew-outdated.json */, C4E2E85228FC256B003B070C /* brew-services-normal.json */, C4E2E85128FC256B003B070C /* brew-services-sudo.json */, C43A8A1F25D9D1D700591B77 /* brew-formula.json */, @@ -1610,6 +1620,7 @@ isa = PBXGroup; children = ( C43931C929C4C03F0069165B /* Brew.swift */, + C4AFC4AD29C4F32F00BF4E0D /* BrewFormula.swift */, C4F2E4362752F0870020E974 /* BrewDiagnostics.swift */, C40934A1298EEB2C00D25014 /* CaskFile.swift */, ); @@ -1721,6 +1732,7 @@ C42CFB1927DFE8BD00862737 /* NginxConfigurationTest.swift */, C4551656297AED18009B8466 /* ValetRcTest.swift */, C40934AA298EEDA900D25014 /* CaskFileParserTest.swift */, + C4AFC4B229C4F43300BF4E0D /* HomebrewTest.swift */, ); path = Parsers; sourceTree = ""; @@ -2129,6 +2141,7 @@ C4E2E85828FC256B003B070C /* brew-services-normal.json in Resources */, C44C1992276E44CB0072762D /* ProgressWindow.storyboard in Resources */, C42F26762805FEE200938AC7 /* nginx-secure-proxy.test in Resources */, + C4AFC4B829C4F6DC00BF4E0D /* brew-outdated.json in Resources */, C4F30B08278E195800755FCE /* brew-services.json in Resources */, C455165B297AEDB5009B8466 /* valetrc.broken in Resources */, 54A18D40282A566E000A0D81 /* nginx-secure-proxy-custom-tld.test in Resources */, @@ -2332,6 +2345,7 @@ C4B5635E276AB09000F12CCB /* VersionExtractor.swift in Sources */, C451AFF62969E40F0078E617 /* HelpButton.swift in Sources */, 54D9E0B627E4F51E003B9AD9 /* HotKey.swift in Sources */, + C4AFC4AE29C4F32F00BF4E0D /* BrewFormula.swift in Sources */, C4D936C927E3EB6100BD69FE /* PhpHelper.swift in Sources */, C47331A2247093B7009A0597 /* StatusMenu.swift in Sources */, C44067F927E2585E0045BD4E /* DomainListTypeCell.swift in Sources */, @@ -2431,6 +2445,7 @@ C471E86728F9BB650021E251 /* OnboardingWindowController.swift in Sources */, C471E86828F9BB650021E251 /* PreferencesWindowController.swift in Sources */, C471E86928F9BB650021E251 /* PreferencesWindowController+Hotkey.swift in Sources */, + C4AFC4B029C4F32F00BF4E0D /* BrewFormula.swift in Sources */, C471E86A28F9BB650021E251 /* PrefsVC.swift in Sources */, C471E86B28F9BB650021E251 /* PreferenceName.swift in Sources */, C471E86C28F9BB650021E251 /* Preferences.swift in Sources */, @@ -2701,6 +2716,7 @@ C471E7EB28F9BAC30021E251 /* Helpers.swift in Sources */, C4CB6E68292C362C002E9027 /* Homebrew.swift in Sources */, C4181F1128FAF9330042EA28 /* UITestCase.swift in Sources */, + C4AFC4B129C4F32F00BF4E0D /* BrewFormula.swift in Sources */, C471E81F28F9BB290021E251 /* NginxConfigurationFile.swift in Sources */, C471E7BF28F9B90F0021E251 /* StartupTest.swift in Sources */, C4D3661D291173EA006BD146 /* DictionaryExtension.swift in Sources */, @@ -2800,9 +2816,11 @@ C43603A1275E67610028EFC6 /* AppDelegate+Notifications.swift in Sources */, C4C3643A28AE4FCE00C0770E /* StatusMenu+Items.swift in Sources */, C42759682627662800093CAE /* NSMenuExtension.swift in Sources */, + C4AFC4B429C4F43300BF4E0D /* HomebrewTest.swift in Sources */, C4E2E84828FC1D93003B070C /* TestableConfigurationTest.swift in Sources */, C4D936CB27E3EE4A00BD69FE /* DomainListCellProtocol.swift in Sources */, C4B97B76275CF08C003F3378 /* AppDelegate+MenuOutlets.swift in Sources */, + C4AFC4AF29C4F32F00BF4E0D /* BrewFormula.swift in Sources */, C4F780CD25D80B75000DBC97 /* Alert.swift in Sources */, C485706D28BF450900539B36 /* NSMenuItemExtension.swift in Sources */, C481F79726164A78004FBCFF /* PrefsVC.swift in Sources */, diff --git a/phpmon/Domain/Integrations/Homebrew/Brew.swift b/phpmon/Domain/Integrations/Homebrew/Brew.swift index 0b46c3c..889f3c8 100644 --- a/phpmon/Domain/Integrations/Homebrew/Brew.swift +++ b/phpmon/Domain/Integrations/Homebrew/Brew.swift @@ -28,4 +28,22 @@ class Brew { Log.warn("The Homebrew version could not be determined.") } } + + public func getPhpVersions() async -> [BrewFormula] { + let command = """ + \(Paths.brew) update >/dev/null && \ + \(Paths.brew) outdated --json --formulae + """ + + let raw = await Shell.pipe(command).out + print(raw) + + // We can now figure out what updates there are + + // We also know what's installed + let items = PhpEnv.shared.cachedPhpInstallations.keys + print(items) + + return [] + } } diff --git a/phpmon/Domain/Integrations/Homebrew/BrewFormula.swift b/phpmon/Domain/Integrations/Homebrew/BrewFormula.swift new file mode 100644 index 0000000..a92abf7 --- /dev/null +++ b/phpmon/Domain/Integrations/Homebrew/BrewFormula.swift @@ -0,0 +1,23 @@ +// +// BrewFormula.swift +// PHP Monitor +// +// Created by Nico Verbruggen on 17/03/2023. +// Copyright © 2023 Nico Verbruggen. All rights reserved. +// + +import Foundation + +struct BrewFormula { + let name: String + let installedVersion: String? + let upgradeVersion: String? + + var isInstalled: Bool { + return installedVersion != nil + } + + var hasUpgrade: Bool { + return upgradeVersion != nil + } +} diff --git a/tests/feature/InternalSwitcherTest.swift b/tests/feature/InternalSwitcherTest.swift index 9b89eff..ba7fb19 100644 --- a/tests/feature/InternalSwitcherTest.swift +++ b/tests/feature/InternalSwitcherTest.swift @@ -10,21 +10,13 @@ import XCTest final class InternalSwitcherTest: FeatureTestCase { - public func testDefaultPhpFpmPoolRequiresDisabling() async { - ActiveFileSystem.useTestable([ - "/opt/homebrew/etc/php/8.1/php-fpm.d/www.conf": .fake(.text) - ]) - - assertFileSystemHas("/opt/homebrew/etc/php/8.1/php-fpm.d/www.conf") - XCTAssertTrue(InternalSwitcher().requiresDisablingOfDefaultPhpFpmPool("8.1")) - } - public func testDefaultPhpFpmPoolIsMoved() async { ActiveFileSystem.useTestable([ "/opt/homebrew/etc/php/8.1/php-fpm.d/www.conf": .fake(.text) ]) - await InternalSwitcher().disableDefaultPhpFpmPool("8.1") + let outcome = await InternalSwitcher().disableDefaultPhpFpmPool("8.1") + XCTAssertTrue(outcome) assertFileSystemHas("/opt/homebrew/etc/php/8.1/php-fpm.d/www.conf.disabled-by-phpmon") assertFileSystemDoesNotHave("/opt/homebrew/etc/php/8.1/php-fpm.d/www.conf") @@ -41,7 +33,8 @@ final class InternalSwitcherTest: FeatureTestCase { contents: "phpmon generated" ) - await InternalSwitcher().disableDefaultPhpFpmPool("8.1") + let outcome = await InternalSwitcher().disableDefaultPhpFpmPool("8.1") + XCTAssertTrue(outcome) assertFileSystemHas("/opt/homebrew/etc/php/8.1/php-fpm.d/www.conf.disabled-by-phpmon") assertFileSystemDoesNotHave("/opt/homebrew/etc/php/8.1/php-fpm.d/www.conf") diff --git a/tests/unit/Parsers/HomebrewTest.swift b/tests/unit/Parsers/HomebrewTest.swift new file mode 100644 index 0000000..2046f65 --- /dev/null +++ b/tests/unit/Parsers/HomebrewTest.swift @@ -0,0 +1,33 @@ +// +// HomebrewTest.swift +// PHP Monitor +// +// Created by Nico Verbruggen on 17/03/2023. +// Copyright © 2023 Nico Verbruggen. All rights reserved. +// + +import XCTest + +class HomebrewTest: XCTestCase { + static var outdatedFileUrl: URL { + return Bundle(for: Self.self) + .url(forResource: "brew-outdated", withExtension: "json")! + } + + 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)) + ]) + + let env = PhpEnv.shared + env.cachedPhpInstallations = [ + "8.1": PhpInstallation("8.1.3"), + "8.2": PhpInstallation("8.2.4"), + "7.4": PhpInstallation("7.4.11") + ] + + let brew = Brew.shared + let data = await brew.getPhpVersions() + print(data) + } +} diff --git a/tests/unit/Test Files/brew/brew-outdated.json b/tests/unit/Test Files/brew/brew-outdated.json new file mode 100644 index 0000000..79126ca --- /dev/null +++ b/tests/unit/Test Files/brew/brew-outdated.json @@ -0,0 +1,169 @@ +{ + "formulae": [ + { + "name": "cmake", + "installed_versions": [ + "3.25.2" + ], + "current_version": "3.26.0", + "pinned": false, + "pinned_version": null + }, + { + "name": "cmocka", + "installed_versions": [ + "1.1.5" + ], + "current_version": "1.1.7", + "pinned": false, + "pinned_version": null + }, + { + "name": "glib", + "installed_versions": [ + "2.74.6" + ], + "current_version": "2.76.0", + "pinned": false, + "pinned_version": null + }, + { + "name": "harfbuzz", + "installed_versions": [ + "7.0.1" + ], + "current_version": "7.1.0", + "pinned": false, + "pinned_version": null + }, + { + "name": "httpd", + "installed_versions": [ + "2.4.55" + ], + "current_version": "2.4.56", + "pinned": false, + "pinned_version": null + }, + { + "name": "imagemagick", + "installed_versions": [ + "7.1.1-2" + ], + "current_version": "7.1.1-3", + "pinned": false, + "pinned_version": null + }, + { + "name": "libarchive", + "installed_versions": [ + "3.6.2" + ], + "current_version": "3.6.2_1", + "pinned": false, + "pinned_version": null + }, + { + "name": "libsndfile", + "installed_versions": [ + "1.2.0" + ], + "current_version": "1.2.0_1", + "pinned": false, + "pinned_version": null + }, + { + "name": "libvidstab", + "installed_versions": [ + "1.1.0" + ], + "current_version": "1.1.1", + "pinned": false, + "pinned_version": null + }, + { + "name": "libvpx", + "installed_versions": [ + "1.12.0" + ], + "current_version": "1.13.0", + "pinned": false, + "pinned_version": null + }, + { + "name": "node", + "installed_versions": [ + "19.6.0" + ], + "current_version": "19.8.1", + "pinned": false, + "pinned_version": null + }, + { + "name": "pango", + "installed_versions": [ + "1.50.13" + ], + "current_version": "1.50.14", + "pinned": false, + "pinned_version": null + }, + { + "name": "php", + "installed_versions": [ + "8.2.3" + ], + "current_version": "8.2.4", + "pinned": false, + "pinned_version": null + }, + { + "name": "php@8.1", + "installed_versions": [ + "8.1.16" + ], + "current_version": "8.1.17", + "pinned": false, + "pinned_version": null + }, + { + "name": "rclone", + "installed_versions": [ + "1.61.1" + ], + "current_version": "1.62.2", + "pinned": false, + "pinned_version": null + }, + { + "name": "sdl2", + "installed_versions": [ + "2.26.3" + ], + "current_version": "2.26.4", + "pinned": false, + "pinned_version": null + }, + { + "name": "snappy", + "installed_versions": [ + "1.1.9" + ], + "current_version": "1.1.10", + "pinned": false, + "pinned_version": null + }, + { + "name": "tcl-tk", + "installed_versions": [ + "8.6.13" + ], + "current_version": "8.6.13_1", + "pinned": false, + "pinned_version": null + } + ], + "casks": [ + + ] +}