From e20db1b399e68de6b193c848ab933e1f98d8d8ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 12 Mar 2026 11:58:44 -0400 Subject: [PATCH] Establish repository formatting baseline and enforcement - normalize repository whitespace and formatting to the current .editorconfig baseline - add a pre-commit hook, hook installer, CI verification, and contributor guidance for formatting - tune .editorconfig and project files to avoid WinUI/XAML false positives and keep Visual Studio design-time loading working - fix WindowsPackageManager interop workspace loading for dotnet format --- .gitattributes | 3 +- .githooks/pre-commit | 38 + .github/workflows/dotnet-test.yml | 13 + CONTRIBUTING.md | 8 + scripts/install-git-hooks.ps1 | 8 + src/.editorconfig | 11 +- src/Directory.Build.props | 18 +- .../ExternalLibraries.Clipboard.csproj | 12 +- .../Classes/FileOpenDialogRCW.cs | 16 +- .../Classes/FileSaveDialogRCW.cs | 16 +- .../Classes/Helper.cs | 19 +- .../Enums/FDAP.cs | 2 +- .../Enums/FDE_OVERWRITE_RESPONSE.cs | 4 +- .../Enums/FDE_SHAREVIOLATION_RESPONSE.cs | 4 +- .../Enums/FOS.cs | 4 +- .../Enums/HRESULT.cs | 4 +- .../Enums/SIGDN.cs | 20 +- .../ExternalLibraries.FilePickers.csproj | 12 +- .../FileOpenPicker.cs | 2 +- .../FileSavePicker.cs | 2 +- .../FolderPicker.cs | 2 +- .../Guids/CLSIDGuid.cs | 2 +- .../Guids/IIDGuid.cs | 2 +- .../Guids/KFIDGuid.cs | 2 +- .../Interfaces/FileOpenDialog.cs | 14 +- .../Interfaces/FileSaveDialog.cs | 14 +- .../Interfaces/IFileDialog.cs | 22 +- .../Interfaces/IFileDialogEvents.cs | 39 +- .../Interfaces/IFileOpenDialog.cs | 6 +- .../Interfaces/IModalWindow.cs | 13 +- .../Interfaces/IShellItem.cs | 24 +- .../Interfaces/IShellItemArray.cs | 25 +- .../Structures/COMDLG_FILTERSPEC.cs | 3 +- .../Structures/PROPERTYKEY.cs | 2 +- src/SharedAssemblyInfo.cs | 2 +- .../PersonTests.cs | 17 +- .../SortableObservableCollectionTests.cs | 16 +- .../TaskRecyclerTests.cs | 16 +- .../UniGetUI.Core.Classes.Tests.csproj | 65 +- .../IIndexableListItem.cs | 2 +- src/UniGetUI.Core.Classes/ObservableQueue.cs | 2 +- src/UniGetUI.Core.Classes/Person.cs | 9 +- .../SortableObservableCollection.cs | 22 +- src/UniGetUI.Core.Classes/TaskRecycler.cs | 75 +- .../UniGetUI.Core.Classes.csproj | 15 +- .../ContributorsTests.cs | 3 +- src/UniGetUI.Core.Data.Tests/CoreTests.cs | 29 +- src/UniGetUI.Core.Data.Tests/LicensesTest.cs | 13 +- .../UniGetUI.Core.Data.Tests.csproj | 79 +- src/UniGetUI.Core.Data/Contributors.cs | 13 +- src/UniGetUI.Core.Data/CoreCredentialStore.cs | 29 +- src/UniGetUI.Core.Data/CoreData.cs | 168 +- src/UniGetUI.Core.Data/Licenses.cs | 203 +- .../UniGetUI.Core.Data.csproj | 31 +- .../IconCacheEngineTests.cs | 107 +- .../IconDatabaseTests.cs | 12 +- .../UniGetUI.Core.IconEngine.Tests.csproj | 67 +- .../IconCacheEngine.cs | 188 +- src/UniGetUI.Core.IconStore/IconDatabase.cs | 30 +- src/UniGetUI.Core.IconStore/Serializable.cs | 3 +- .../UniGetUI.Core.IconEngine.csproj | 26 +- .../LanguageDataTests.cs | 24 +- .../LanguageEngineTests.cs | 16 +- .../UniGetUI.Core.LanguageEngine.Tests.csproj | 65 +- .../LanguageData.cs | 65 +- .../LanguageEngine.cs | 82 +- .../UniGetUI.Core.LanguageEngine.csproj | 153 +- src/UniGetUI.Core.Logger/LogEntry.cs | 1 - src/UniGetUI.Core.Logger/Logger.cs | 50 +- .../UniGetUI.Core.Logging.csproj | 9 +- .../LogEntryTests.cs | 2 +- .../UniGetUI.Core.Logging.Tests.csproj | 65 +- .../SecureGHTokenManager.cs | 8 +- .../SecureSettings.cs | 18 +- .../UniGetUI.Core.SecureSettings.csproj | 4 + .../SettingsTest.cs | 418 ++- .../UniGetUI.Core.Settings.Tests.csproj | 71 +- src/UniGetUI.Core.Settings/SettingsEngine.cs | 33 +- .../SettingsEngine_Dictionaries.cs | 76 +- .../SettingsEngine_Extras.cs | 30 +- .../SettingsEngine_ImportExport.cs | 43 +- .../SettingsEngine_Lists.cs | 39 +- .../SettingsEngine_Names.cs | 4 +- .../UniGetUI.Core.Settings.csproj | 17 +- src/UniGetUI.Core.Tools.Tests/MetaTests.cs | 58 +- src/UniGetUI.Core.Tools.Tests/ToolsTests.cs | 38 +- .../UniGetUI.Core.Tools.Tests.csproj | 71 +- src/UniGetUI.Core.Tools/DWMThreadHelper.cs | 115 +- src/UniGetUI.Core.Tools/IntegrityTester.cs | 33 +- .../SerializationHelpers.cs | 17 +- src/UniGetUI.Core.Tools/Tools.cs | 283 +- .../UniGetUI.Core.Tools.csproj | 21 +- .../BackgroundApi.cs | 127 +- .../UniGetUI.Interface.BackgroundApi.csproj | 47 +- src/UniGetUI.Interface.Enums/Enums.cs | 8 +- .../UniGetUI.Interface.Enums.csproj | 9 +- .../TelemetryHandler.cs | 108 +- .../UniGetUI.Interface.Telemetry.csproj | 4 +- .../IManagerLogger.cs | 1 + .../IPackageManager.cs | 1 - .../ManagerDependency.cs | 3 +- .../ManagerHelpers/IMultiSourceHelper.cs | 12 +- .../ManagerHelpers/IPackageOperationHelper.cs | 6 +- .../ManagerProperties.cs | 8 +- .../UniGetUI.PackageEngine.Interfaces.csproj | 52 +- src/UniGetUI.PackageEngine.Enums/Enums.cs | 17 +- .../ManagerCapabilities.cs | 5 +- .../OverridenInstallationOptions.cs | 1 + .../UniGetUI.PackageEngine.Structs.csproj | 9 +- .../Cargo.cs | 54 +- .../CratesIOClient.cs | 5 +- .../Helpers/CargoPkgDetailsHelper.cs | 32 +- .../Helpers/CargoPkgOperationHelper.cs | 40 +- ...iGetUI.PackageEngine.Managers.Cargo.csproj | 5 +- .../Chocolatey.cs | 238 +- .../Helpers/ChocolateyDetailsHelper.cs | 52 +- .../Helpers/ChocolateyPkgOperationHelper.cs | 65 +- .../Helpers/ChocolateySourceHelper.cs | 61 +- ...I.PackageEngine.Managers.Chocolatey.csproj | 61 +- .../Chocolatey.PowerShell.dll-help.xml | 2703 ++++++++++------- .../choco-cli/tools/checksum.exe.config | 4 +- .../DotNet.cs | 91 +- .../Helpers/DotNetDetailsHelper.cs | 10 +- .../Helpers/DotNetPkgOperationHelper.cs | 58 +- ...GetUI.PackageEngine.Managers.Dotnet.csproj | 43 +- .../BaseNuGet.cs | 177 +- .../BaseNuGetDetailsHelper.cs | 169 +- .../Internal/NuGetManifestLoader.cs | 31 +- ...ackageEngine.Managers.Generic.NuGet.csproj | 23 +- .../Helpers/NpmPkgDetailsHelper.cs | 145 +- .../Helpers/NpmPkgOperationHelper.cs | 54 +- .../Npm.cs | 124 +- ...UniGetUI.PackageEngine.Managers.Npm.csproj | 41 +- .../Helpers/PipPkgDetailsHelper.cs | 78 +- .../Helpers/PipPkgOperationHelper.cs | 57 +- .../Pip.cs | 145 +- ...UniGetUI.PackageEngine.Managers.Pip.csproj | 41 +- .../Helpers/PowerShellDetailsHelper.cs | 26 +- .../Helpers/PowerShellPkgOperationHelper.cs | 68 +- .../Helpers/PowerShellSourceHelper.cs | 41 +- .../PowerShell.cs | 60 +- ...I.PackageEngine.Managers.PowerShell.csproj | 51 +- .../Helpers/PowerShell7DetailsHelper.cs | 27 +- .../Helpers/PowerShell7PkgOperationHelper.cs | 64 +- .../Helpers/PowerShell7SourceHelper.cs | 49 +- .../PowerShell7.cs | 68 +- ....PackageEngine.Managers.PowerShell7.csproj | 42 +- .../Helpers/ScoopPkgDetailsHelper.cs | 134 +- .../Helpers/ScoopPkgOperationHelper.cs | 86 +- .../Helpers/ScoopSourceHelper.cs | 66 +- .../Scoop.cs | 278 +- ...iGetUI.PackageEngine.Managers.Scoop.csproj | 49 +- .../Helpers/VcpkgPkgDetailsHelper.cs | 49 +- .../Helpers/VcpkgPkgOperationHelper.cs | 33 +- .../Helpers/VcpkgSourceHelper.cs | 33 +- ...iGetUI.PackageEngine.Managers.Vcpkg.csproj | 35 +- .../Vcpkg.cs | 166 +- .../ClientHelpers/BundledWinGetHelper.cs | 295 +- .../ClientHelpers/NativePackageHandler.cs | 94 +- .../ClientHelpers/NativeWinGetHelper.cs | 209 +- .../ClientHelpers/WinGetIconsHelper.cs | 68 +- .../Helpers/WinGetPkgDetailsHelper.cs | 72 +- .../Helpers/WinGetPkgOperationHelper.cs | 226 +- .../Helpers/WinGetSourceHelper.cs | 28 +- ...GetUI.PackageEngine.Managers.WinGet.csproj | 107 +- .../WinGet.cs | 216 +- .../AbstractOperation.cs | 172 +- .../AbstractOperation_Auxiliaries.cs | 5 +- .../AbstractProcessOperation.cs | 66 +- .../DownloadOperation.cs | 78 +- .../KillProcessOperation.cs | 39 +- .../PackageOperations.cs | 240 +- .../PrePostOperation.cs | 23 +- .../SourceOperations.cs | 199 +- .../UniGetUI.PackageEngine.Operations.csproj | 3 + .../PEInterface.cs | 39 +- .../UniGetUI.PackageEngine.PEInterface.csproj | 65 +- .../AbstractPackageLoader.cs | 27 +- .../DiscoverablePackagesLoader.cs | 44 +- .../InstalledPackagesLoader.cs | 23 +- .../PackageBundlesLoader.cs | 19 +- ...iGetUI.PackageEngine.PackageLoaders.csproj | 28 +- .../UpgradablePackagesLoader.cs | 30 +- .../Manager/Classes/ManagerLogger.cs | 59 +- .../Manager/Classes/ManagerSource.cs | 23 +- .../Manager/Classes/NullPackageManager.cs | 91 +- .../Manager/Helpers/BasePkgDetailsHelper.cs | 74 +- .../Manager/Helpers/BasePkgOperationHelper.cs | 39 +- .../Manager/Helpers/BaseSourceHelper.cs | 54 +- .../Manager/PackageManager.cs | 179 +- .../Classes/DesktopShortcutsDatabase.cs | 57 +- .../Classes/IgnoredUpdatesDatabase.cs | 79 +- .../Packages/Classes/InstallOptionsFactory.cs | 167 +- .../Packages/ImportedPackage.cs | 33 +- .../Packages/InvalidImportedPackage.cs | 56 +- .../Packages/Package.cs | 180 +- .../UniGetUI.PackageEngine.Classes.csproj | 43 +- .../TestDuplicateUpdateDetection.cs | 5 +- .../TestInstallOptions.cs | 176 +- .../TestSerializableBundle.cs | 57 +- .../TestSerializableIncompatiblePackage.cs | 53 +- .../TestSerializablePackage.cs | 88 +- .../TestSerializableUpdatesOptions.cs | 37 +- ...UI.PackageEngine.Serializable.Tests.csproj | 24 +- .../InstallOptions.cs | 213 +- .../SerializableBundle.cs | 48 +- .../SerializableComponent.cs | 7 +- .../SerializableIncompatiblePackage.cs | 20 +- .../SerializablePackage.cs | 12 +- .../SerializableUpdatesOptions.cs | 24 +- ...UniGetUI.PackageEngine.Serializable.csproj | 17 +- src/UniGetUI.sln | 4 +- src/UniGetUI/App.xaml | 1697 ++++++----- src/UniGetUI/App.xaml.cs | 177 +- src/UniGetUI/AppOperationHelper.cs | 265 +- src/UniGetUI/AutoUpdater.cs | 388 ++- src/UniGetUI/CLIHandler.cs | 56 +- src/UniGetUI/Controls/CustomNavViewItem.cs | 16 +- src/UniGetUI/Controls/DialogCloseButton.xaml | 60 +- .../Controls/DialogCloseButton.xaml.cs | 1 + src/UniGetUI/Controls/LocalIcon.cs | 6 +- src/UniGetUI/Controls/MenuForPackage.cs | 56 +- .../Controls/ObservablePackageCollection.cs | 1 + .../OperationWidgets/OperationBadge.cs | 8 +- .../OperationWidgets/OperationControl.cs | 364 ++- src/UniGetUI/Controls/PackageItemContainer.cs | 2 +- src/UniGetUI/Controls/PackageWrapper.cs | 106 +- .../Controls/SettingsWidgets/ButtonCard.cs | 5 +- .../SettingsWidgets/CheckboxButtonCard.cs | 19 +- .../Controls/SettingsWidgets/CheckboxCard.cs | 46 +- .../Controls/SettingsWidgets/ComboboxCard.cs | 19 +- .../SettingsWidgets/SecureCheckboxCard.cs | 19 +- .../Controls/SettingsWidgets/TextboxCard.cs | 21 +- src/UniGetUI/Controls/SourceManager.xaml | 261 +- src/UniGetUI/Controls/SourceManager.xaml.cs | 89 +- .../Controls/TranslatedTextBlock.xaml | 35 +- .../Controls/TranslatedTextBlock.xaml.cs | 15 +- src/UniGetUI/CrashHandler.cs | 109 +- src/UniGetUI/EntryPoint.cs | 35 +- src/UniGetUI/MainWindow.xaml | 383 ++- src/UniGetUI/MainWindow.xaml.cs | 235 +- .../Pages/AboutPages/AboutUniGetUI.xaml | 119 +- .../Pages/AboutPages/AboutUniGetUI.xaml.cs | 10 +- .../Pages/AboutPages/Contributors.xaml | 136 +- .../Pages/AboutPages/Contributors.xaml.cs | 1 + .../Pages/AboutPages/ThirdPartyLicenses.xaml | 135 +- .../AboutPages/ThirdPartyLicenses.xaml.cs | 21 +- .../Pages/AboutPages/Translators.xaml | 160 +- .../Pages/AboutPages/Translators.xaml.cs | 1 + .../Pages/DialogPages/AboutUniGetUI.xaml | 118 +- .../Pages/DialogPages/AboutUniGetUI.xaml.cs | 20 +- .../Pages/DialogPages/DesktopShortcuts.xaml | 354 ++- .../DialogPages/DesktopShortcuts.xaml.cs | 27 +- .../Pages/DialogPages/DialogHelper_Generic.cs | 365 ++- .../DialogHelper_Infrastructure.cs | 108 +- .../DialogPages/DialogHelper_Operations.cs | 5 +- .../DialogPages/DialogHelper_Packages.cs | 253 +- .../Pages/DialogPages/IgnoredUpdates.xaml | 324 +- .../Pages/DialogPages/IgnoredUpdates.xaml.cs | 57 +- .../DialogPages/InstallOptions_Manager.xaml | 444 ++- .../InstallOptions_Manager.xaml.cs | 53 +- .../DialogPages/InstallOptions_Package.xaml | 1378 ++++----- .../InstallOptions_Package.xaml.cs | 238 +- .../DialogPages/OperationFailedDialog.xaml | 92 +- .../DialogPages/OperationFailedDialog.xaml.cs | 14 +- .../DialogPages/OperationLiveLogPage.xaml | 76 +- .../DialogPages/OperationLiveLogPage.xaml.cs | 56 +- .../Pages/DialogPages/PackageDetailsPage.xaml | 665 ++-- .../DialogPages/PackageDetailsPage.xaml.cs | 315 +- .../Pages/DialogPages/ReleaseNotes.xaml | 73 +- .../Pages/DialogPages/ReleaseNotes.xaml.cs | 16 +- src/UniGetUI/Pages/HelpPage.xaml | 207 +- src/UniGetUI/Pages/HelpPage.xaml.cs | 23 +- src/UniGetUI/Pages/LogPages/LogPage.xaml | 154 +- src/UniGetUI/Pages/LogPages/LogPage.xaml.cs | 32 +- .../Pages/LogPages/ManagerLogsPage.cs | 34 +- .../Pages/LogPages/OperationHistoryPage.cs | 9 +- .../Pages/LogPages/UniGetUILogPage.cs | 75 +- src/UniGetUI/Pages/MainView.xaml | 849 +++--- src/UniGetUI/Pages/MainView.xaml.cs | 194 +- .../IKeyboardShortcutListener.cs | 2 +- .../Pages/PageInterfaces/ISearchBoxPage.cs | 6 +- .../GeneralPages/Administrator.xaml | 261 +- .../GeneralPages/Administrator.xaml.cs | 39 +- .../SettingsPages/GeneralPages/Backup.xaml | 433 +-- .../SettingsPages/GeneralPages/Backup.xaml.cs | 105 +- .../GeneralPages/Experimental.xaml | 218 +- .../GeneralPages/Experimental.xaml.cs | 13 +- .../SettingsPages/GeneralPages/General.xaml | 228 +- .../GeneralPages/General.xaml.cs | 58 +- .../GeneralPages/Interface_P.xaml | 163 +- .../GeneralPages/Interface_P.xaml.cs | 55 +- .../SettingsPages/GeneralPages/Internet.xaml | 345 +-- .../GeneralPages/Internet.xaml.cs | 111 +- .../GeneralPages/Notifications.xaml | 145 +- .../GeneralPages/Notifications.xaml.cs | 14 +- .../GeneralPages/Operations.xaml | 194 +- .../GeneralPages/Operations.xaml.cs | 11 +- .../GeneralPages/SettingsHomepage.xaml | 256 +- .../GeneralPages/SettingsHomepage.xaml.cs | 46 +- .../SettingsPages/GeneralPages/Updates.xaml | 210 +- .../GeneralPages/Updates.xaml.cs | 32 +- .../ManagersPages/ManagersHomepage.xaml | 41 +- .../ManagersPages/ManagersHomepage.xaml.cs | 108 +- .../ManagersPages/PackageManager.xaml | 398 ++- .../ManagersPages/PackageManager.xaml.cs | 279 +- .../Pages/SettingsPages/SettingsBasePage.xaml | 159 +- .../SettingsPages/SettingsBasePage.xaml.cs | 99 +- .../SoftwarePages/AbstractPackagesPage.xaml | 2416 ++++++++------- .../AbstractPackagesPage.xaml.cs | 576 +++- .../SoftwarePages/DiscoverSoftwarePage.cs | 242 +- .../SoftwarePages/InstalledPackagesPage.cs | 231 +- .../Pages/SoftwarePages/PackageBundlesPage.cs | 664 ++-- .../SoftwarePages/SoftwareUpdatesPage.cs | 399 ++- src/UniGetUI/Services/BackgroundLoginApi.cs | 6 +- src/UniGetUI/Services/GitHubAuthService.cs | 20 +- src/UniGetUI/Services/GitHubBackupService.cs | 60 +- src/UniGetUI/Services/Secrets.cs | 1 + src/UniGetUI/Services/UserAvatar.cs | 72 +- src/UniGetUI/Themes/Generic.xaml | 36 +- src/UniGetUI/UniGetUI.csproj | 699 +++-- .../WinGetConfigurationException.cs | 2 +- ...aries.WindowsPackageManager.Interop.csproj | 103 +- .../WindowsPackageManager/ClassModel.cs | 6 +- .../ClassesDefinition.cs | 105 +- .../WindowsPackageManager/ClsidContext.cs | 2 +- .../WindowsPackageManagerFactory.cs | 8 +- .../WindowsPackageManagerStandardFactory.cs | 17 +- 328 files changed, 21846 insertions(+), 13894 deletions(-) create mode 100644 .githooks/pre-commit create mode 100644 scripts/install-git-hooks.ps1 diff --git a/.gitattributes b/.gitattributes index fb2ccc79f0..1b8a169a6c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,2 @@ -src/UniGetUI.PackageEngine.Managers.Chocolatey/choco-cli/** linguist-vendored \ No newline at end of file +src/UniGetUI.PackageEngine.Managers.Chocolatey/choco-cli/** linguist-vendored +.githooks/* text eol=lf \ No newline at end of file diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 100644 index 0000000000..45f6cfe32c --- /dev/null +++ b/.githooks/pre-commit @@ -0,0 +1,38 @@ +#!/usr/bin/env sh + +set -eu + +repo_root=$(git rev-parse --show-toplevel) +cd "$repo_root" + +staged_files=$(git diff --cached --name-only --diff-filter=ACMR -- src | grep -E '\.(cs|csproj|props|targets|editorconfig|json|sln|slnx)$' || true) + +if [ -z "$staged_files" ]; then + exit 0 +fi + +unstaged_files=$(git diff --name-only -- $staged_files || true) +if [ -n "$unstaged_files" ]; then + echo "pre-commit: relevant files have unstaged changes." + echo "Stage or stash them before committing so dotnet format does not rewrite mixed content." + printf '%s\n' "$unstaged_files" + exit 1 +fi + +if ! command -v dotnet >/dev/null 2>&1; then + echo "pre-commit: dotnet CLI not found; skipping whitespace formatting." + exit 0 +fi + +echo "pre-commit: running dotnet format whitespace on staged src files" + +# shellcheck disable=SC2086 +dotnet format whitespace src --folder --verbosity minimal --include $staged_files + +if ! git diff --quiet -- $staged_files; then + git add -- $staged_files + echo "pre-commit: formatting updates were staged. Review them and run git commit again." + exit 1 +fi + +exit 0 \ No newline at end of file diff --git a/.github/workflows/dotnet-test.yml b/.github/workflows/dotnet-test.yml index 1a63e7928f..e2c0e3a610 100644 --- a/.github/workflows/dotnet-test.yml +++ b/.github/workflows/dotnet-test.yml @@ -5,7 +5,10 @@ on: paths: - '**.cs' - '**.csproj' + - '**.props' + - '**.targets' - '**.sln' + - 'src/.editorconfig' - '.github/workflows/dotnet-test.yml' pull_request: @@ -13,7 +16,10 @@ on: paths: - '**.cs' - '**.csproj' + - '**.props' + - '**.targets' - '**.sln' + - 'src/.editorconfig' - '.github/workflows/dotnet-test.yml' workflow_dispatch: @@ -47,6 +53,13 @@ jobs: working-directory: src run: dotnet restore UniGetUI.sln + - name: Check whitespace formatting + run: dotnet format whitespace src --folder --verify-no-changes --verbosity minimal + + - name: Check code style formatting + working-directory: src + run: dotnet format style UniGetUI.sln --no-restore --verify-no-changes --verbosity minimal + - name: Run Tests working-directory: src run: dotnet test UniGetUI.sln --no-restore --verbosity q --nologo diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4b907cc984..e7e59745a4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -38,6 +38,14 @@ Before reading: All of the rules below are guidelines, which means that they sho - Draft pull requests should be properly identified as [draft pull requests](https://github.blog/2019-02-14-introducing-draft-pull-requests/) to avoid confusion. - When modifying/coding, please follow the guidelines below: +## Formatting: + - Run `pwsh ./scripts/install-git-hooks.ps1` once after cloning to enable the repository pre-commit hook. +- The pre-commit hook runs `dotnet format whitespace src --folder` on staged files under `src` when the `dotnet` CLI is available, and stops the commit if it had to rewrite files so you can review the changes and commit again. + - CI enforces whitespace formatting with `dotnet format whitespace src --folder --verify-no-changes` and code-style verification with `dotnet format style src/UniGetUI.sln --no-restore --verify-no-changes` in `.github/workflows/dotnet-test.yml`. + - The pre-commit hook intentionally does not run `dotnet format style` because solution loading makes it take roughly the same time for one staged C# file as for the full solution. + - If you want to check the same style rules locally before pushing, run `dotnet format style src/UniGetUI.sln --no-restore --verify-no-changes` from the repository root. + - If you want to prepare a dedicated formatting-only commit, run `dotnet format whitespace src --folder` from the repository root. + ## Coding: - As a repository standard, every function and variable name should use camelCase. - Correct usage: `updatesCount = 0`, `def searchForUpdates(packageManager):` diff --git a/scripts/install-git-hooks.ps1 b/scripts/install-git-hooks.ps1 new file mode 100644 index 0000000000..54cdc94511 --- /dev/null +++ b/scripts/install-git-hooks.ps1 @@ -0,0 +1,8 @@ +$ErrorActionPreference = 'Stop' + +$repoRoot = (Resolve-Path (Join-Path $PSScriptRoot '..')).Path + +git -C $repoRoot config core.hooksPath .githooks + +Write-Host 'Configured git hooks path to .githooks' -ForegroundColor Green +Write-Host 'The pre-commit hook will run dotnet format whitespace on staged files under src.' -ForegroundColor Green \ No newline at end of file diff --git a/src/.editorconfig b/src/.editorconfig index 8c85072a5f..c2a8f3bef2 100644 --- a/src/.editorconfig +++ b/src/.editorconfig @@ -280,7 +280,7 @@ dotnet_diagnostic.CA2246.severity = warning dotnet_diagnostic.CA2249.severity = warning # IDE0005: Remove unnecessary usings -dotnet_diagnostic.IDE0005.severity = warning +dotnet_diagnostic.IDE0005.severity = suggestion # IDE0011: Curly braces to surround blocks of code dotnet_diagnostic.IDE0011.severity = warning @@ -343,6 +343,15 @@ dotnet_diagnostic.IDE0200.severity = warning dotnet_style_allow_multiple_blank_lines_experimental = false dotnet_diagnostic.IDE2000.severity = warning +# WinUI code-behind relies on XAML-wired event handlers that Roslyn cannot +# reliably see as C# references. +[UniGetUI/**.cs] +dotnet_diagnostic.IDE0051.severity = suggestion +dotnet_diagnostic.IDE0060.severity = suggestion + +[UniGetUI/Controls/SourceManager.xaml.cs] +dotnet_diagnostic.IDE0044.severity = suggestion + ###### End of EditorConfig from dotnet/aspnetcore repository ### Our rules diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 2cea04fc32..42c53f52c4 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -17,9 +17,16 @@ - true - $(PortableTargetFramework);$(WindowsTargetFramework) - $(PortableTargetFramework) + true + $(PortableTargetFramework);$(WindowsTargetFramework) + $(PortableTargetFramework) @@ -31,7 +38,10 @@ 10.0.26100.56 true win-x64;win-arm64 - win-$(Platform) + win-$(Platform) diff --git a/src/ExternalLibraries.Clipboard/ExternalLibraries.Clipboard.csproj b/src/ExternalLibraries.Clipboard/ExternalLibraries.Clipboard.csproj index 1c504771f0..317faf91f8 100644 --- a/src/ExternalLibraries.Clipboard/ExternalLibraries.Clipboard.csproj +++ b/src/ExternalLibraries.Clipboard/ExternalLibraries.Clipboard.csproj @@ -1,10 +1,6 @@  - - - $(WindowsTargetFramework) - - - - - + + $(WindowsTargetFramework) + + diff --git a/src/ExternalLibraries.FilePickers/Classes/FileOpenDialogRCW.cs b/src/ExternalLibraries.FilePickers/Classes/FileOpenDialogRCW.cs index b54f8c31b1..83181b7830 100644 --- a/src/ExternalLibraries.FilePickers/Classes/FileOpenDialogRCW.cs +++ b/src/ExternalLibraries.FilePickers/Classes/FileOpenDialogRCW.cs @@ -1,14 +1,14 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; using ExternalLibraries.Pickers.Guids; namespace ExternalLibraries.Pickers.Classes; // --------------------------------------------------- // .NET classes representing runtime callable wrappers -[ComImport, -ClassInterface(ClassInterfaceType.None), -TypeLibType(TypeLibTypeFlags.FCanCreate), -Guid(CLSIDGuid.FileOpenDialog)] -internal class FileOpenDialogRCW -{ -} \ No newline at end of file +[ + ComImport, + ClassInterface(ClassInterfaceType.None), + TypeLibType(TypeLibTypeFlags.FCanCreate), + Guid(CLSIDGuid.FileOpenDialog) +] +internal class FileOpenDialogRCW { } diff --git a/src/ExternalLibraries.FilePickers/Classes/FileSaveDialogRCW.cs b/src/ExternalLibraries.FilePickers/Classes/FileSaveDialogRCW.cs index 96a69092fe..ffd05fda99 100644 --- a/src/ExternalLibraries.FilePickers/Classes/FileSaveDialogRCW.cs +++ b/src/ExternalLibraries.FilePickers/Classes/FileSaveDialogRCW.cs @@ -1,14 +1,14 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; using ExternalLibraries.Pickers.Guids; namespace ExternalLibraries.Pickers.Classes; // --------------------------------------------------- // .NET classes representing runtime callable wrappers -[ComImport, -ClassInterface(ClassInterfaceType.None), -TypeLibType(TypeLibTypeFlags.FCanCreate), -Guid(CLSIDGuid.FileSaveDialog)] -internal class FileSaveDialogRCW -{ -} +[ + ComImport, + ClassInterface(ClassInterfaceType.None), + TypeLibType(TypeLibTypeFlags.FCanCreate), + Guid(CLSIDGuid.FileSaveDialog) +] +internal class FileSaveDialogRCW { } diff --git a/src/ExternalLibraries.FilePickers/Classes/Helper.cs b/src/ExternalLibraries.FilePickers/Classes/Helper.cs index 56a6a379a7..bd040acba1 100644 --- a/src/ExternalLibraries.FilePickers/Classes/Helper.cs +++ b/src/ExternalLibraries.FilePickers/Classes/Helper.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; using ExternalLibraries.Pickers.Enums; using ExternalLibraries.Pickers.Interfaces; using ExternalLibraries.Pickers.Structures; @@ -24,7 +24,9 @@ internal static string ShowOpen(nint windowHandle, FOS fos, List? typeFi if (typeFilters is not null) { typeFilters.Insert(0, string.Join("; ", typeFilters)); - COMDLG_FILTERSPEC[] filterSpecs = typeFilters.Select(f => new COMDLG_FILTERSPEC(f)).ToArray(); + COMDLG_FILTERSPEC[] filterSpecs = typeFilters + .Select(f => new COMDLG_FILTERSPEC(f)) + .ToArray(); dialog.SetFileTypes((uint)filterSpecs.Length, filterSpecs); } @@ -46,7 +48,12 @@ internal static string ShowOpen(nint windowHandle, FOS fos, List? typeFi } } - internal static string ShowSave(nint windowHandle, FOS fos, List? typeFilters = null, string name = "") + internal static string ShowSave( + nint windowHandle, + FOS fos, + List? typeFilters = null, + string name = "" + ) { FileSaveDialog dialog = new(); try @@ -55,7 +62,9 @@ internal static string ShowSave(nint windowHandle, FOS fos, List? typeFi if (typeFilters is not null) { - COMDLG_FILTERSPEC[] filterSpecs = typeFilters.Select(f => new COMDLG_FILTERSPEC(f)).ToArray(); + COMDLG_FILTERSPEC[] filterSpecs = typeFilters + .Select(f => new COMDLG_FILTERSPEC(f)) + .ToArray(); dialog.SetFileTypes((uint)filterSpecs.Length, filterSpecs); } @@ -78,7 +87,7 @@ internal static string ShowSave(nint windowHandle, FOS fos, List? typeFi if (fileExtension.Length > 0 && fileExtension[0] == '*') fileExtension = fileExtension.TrimStart('*'); - return path.Contains(fileExtension)? path: path + fileExtension; + return path.Contains(fileExtension) ? path : path + fileExtension; } finally { diff --git a/src/ExternalLibraries.FilePickers/Enums/FDAP.cs b/src/ExternalLibraries.FilePickers/Enums/FDAP.cs index c6347e9328..ff698114e1 100644 --- a/src/ExternalLibraries.FilePickers/Enums/FDAP.cs +++ b/src/ExternalLibraries.FilePickers/Enums/FDAP.cs @@ -1,4 +1,4 @@ -namespace ExternalLibraries.Pickers.Enums; +namespace ExternalLibraries.Pickers.Enums; // https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/ne-shobjidl_core-fdap internal enum FDAP diff --git a/src/ExternalLibraries.FilePickers/Enums/FDE_OVERWRITE_RESPONSE.cs b/src/ExternalLibraries.FilePickers/Enums/FDE_OVERWRITE_RESPONSE.cs index 011f2bdaa0..4056b0558e 100644 --- a/src/ExternalLibraries.FilePickers/Enums/FDE_OVERWRITE_RESPONSE.cs +++ b/src/ExternalLibraries.FilePickers/Enums/FDE_OVERWRITE_RESPONSE.cs @@ -1,9 +1,9 @@ -namespace ExternalLibraries.Pickers.Enums; +namespace ExternalLibraries.Pickers.Enums; // https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/ne-shobjidl_core-fde_overwrite_response internal enum FDE_OVERWRITE_RESPONSE { FDEOR_DEFAULT = 0x00000000, FDEOR_ACCEPT = 0x00000001, - FDEOR_REFUSE = 0x00000002 + FDEOR_REFUSE = 0x00000002, } diff --git a/src/ExternalLibraries.FilePickers/Enums/FDE_SHAREVIOLATION_RESPONSE.cs b/src/ExternalLibraries.FilePickers/Enums/FDE_SHAREVIOLATION_RESPONSE.cs index 71fb59290f..0c7cb4dbe7 100644 --- a/src/ExternalLibraries.FilePickers/Enums/FDE_SHAREVIOLATION_RESPONSE.cs +++ b/src/ExternalLibraries.FilePickers/Enums/FDE_SHAREVIOLATION_RESPONSE.cs @@ -1,9 +1,9 @@ -namespace ExternalLibraries.Pickers.Enums; +namespace ExternalLibraries.Pickers.Enums; // https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/ne-shobjidl_core-fde_shareviolation_response internal enum FDE_SHAREVIOLATION_RESPONSE { FDESVR_DEFAULT = 0x00000000, FDESVR_ACCEPT = 0x00000001, - FDESVR_REFUSE = 0x00000002 + FDESVR_REFUSE = 0x00000002, } diff --git a/src/ExternalLibraries.FilePickers/Enums/FOS.cs b/src/ExternalLibraries.FilePickers/Enums/FOS.cs index 5504ea162d..3bfb7aa97e 100644 --- a/src/ExternalLibraries.FilePickers/Enums/FOS.cs +++ b/src/ExternalLibraries.FilePickers/Enums/FOS.cs @@ -1,4 +1,4 @@ -namespace ExternalLibraries.Pickers.Enums; +namespace ExternalLibraries.Pickers.Enums; [Flags] // https://learn.microsoft.com/ru-ru/windows/win32/api/shobjidl_core/ne-shobjidl_core-_fileopendialogoptions @@ -23,5 +23,5 @@ internal enum FOS : uint FOS_NODEREFERENCELINKS = 0x00100000, FOS_DONTADDTORECENT = 0x02000000, FOS_FORCESHOWHIDDEN = 0x10000000, - FOS_DEFAULTNOMINIMODE = 0x20000000 + FOS_DEFAULTNOMINIMODE = 0x20000000, } diff --git a/src/ExternalLibraries.FilePickers/Enums/HRESULT.cs b/src/ExternalLibraries.FilePickers/Enums/HRESULT.cs index 2bbc83dbff..3bec281c97 100644 --- a/src/ExternalLibraries.FilePickers/Enums/HRESULT.cs +++ b/src/ExternalLibraries.FilePickers/Enums/HRESULT.cs @@ -1,4 +1,4 @@ -namespace ExternalLibraries.Pickers.Enums; +namespace ExternalLibraries.Pickers.Enums; internal enum HRESULT : long { @@ -6,5 +6,5 @@ internal enum HRESULT : long S_OK = 0x0000, E_INVALIDARG = 0x80070057, E_OUTOFMEMORY = 0x8007000E, - ERROR_CANCELLED = 0x800704C7 + ERROR_CANCELLED = 0x800704C7, } diff --git a/src/ExternalLibraries.FilePickers/Enums/SIGDN.cs b/src/ExternalLibraries.FilePickers/Enums/SIGDN.cs index 0b2456d0d9..40037cb880 100644 --- a/src/ExternalLibraries.FilePickers/Enums/SIGDN.cs +++ b/src/ExternalLibraries.FilePickers/Enums/SIGDN.cs @@ -1,15 +1,15 @@ -namespace ExternalLibraries.Pickers.Enums; +namespace ExternalLibraries.Pickers.Enums; // https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/ne-shobjidl_core-sigdn internal enum SIGDN : uint { - SIGDN_NORMALDISPLAY = 0x00000000, // SHGDN_NORMAL - SIGDN_PARENTRELATIVEPARSING = 0x80018001, // SHGDN_INFOLDER | SHGDN_FORPARSING - SIGDN_DESKTOPABSOLUTEPARSING = 0x80028000, // SHGDN_FORPARSING - SIGDN_PARENTRELATIVEEDITING = 0x80031001, // SHGDN_INFOLDER | SHGDN_FOREDITING - SIGDN_DESKTOPABSOLUTEEDITING = 0x8004c000, // SHGDN_FORPARSING | SHGDN_FORADDRESSBAR - SIGDN_FILESYSPATH = 0x80058000, // SHGDN_FORPARSING - SIGDN_URL = 0x80068000, // SHGDN_FORPARSING - SIGDN_PARENTRELATIVEFORADDRESSBAR = 0x8007c001, // SHGDN_INFOLDER | SHGDN_FORPARSING | SHGDN_FORADDRESSBAR - SIGDN_PARENTRELATIVE = 0x80080001 // SHGDN_INFOLDER + SIGDN_NORMALDISPLAY = 0x00000000, // SHGDN_NORMAL + SIGDN_PARENTRELATIVEPARSING = 0x80018001, // SHGDN_INFOLDER | SHGDN_FORPARSING + SIGDN_DESKTOPABSOLUTEPARSING = 0x80028000, // SHGDN_FORPARSING + SIGDN_PARENTRELATIVEEDITING = 0x80031001, // SHGDN_INFOLDER | SHGDN_FOREDITING + SIGDN_DESKTOPABSOLUTEEDITING = 0x8004c000, // SHGDN_FORPARSING | SHGDN_FORADDRESSBAR + SIGDN_FILESYSPATH = 0x80058000, // SHGDN_FORPARSING + SIGDN_URL = 0x80068000, // SHGDN_FORPARSING + SIGDN_PARENTRELATIVEFORADDRESSBAR = 0x8007c001, // SHGDN_INFOLDER | SHGDN_FORPARSING | SHGDN_FORADDRESSBAR + SIGDN_PARENTRELATIVE = 0x80080001, // SHGDN_INFOLDER } diff --git a/src/ExternalLibraries.FilePickers/ExternalLibraries.FilePickers.csproj b/src/ExternalLibraries.FilePickers/ExternalLibraries.FilePickers.csproj index 1c504771f0..317faf91f8 100644 --- a/src/ExternalLibraries.FilePickers/ExternalLibraries.FilePickers.csproj +++ b/src/ExternalLibraries.FilePickers/ExternalLibraries.FilePickers.csproj @@ -1,10 +1,6 @@  - - - $(WindowsTargetFramework) - - - - - + + $(WindowsTargetFramework) + + diff --git a/src/ExternalLibraries.FilePickers/FileOpenPicker.cs b/src/ExternalLibraries.FilePickers/FileOpenPicker.cs index 0f86c05da6..365e393a40 100644 --- a/src/ExternalLibraries.FilePickers/FileOpenPicker.cs +++ b/src/ExternalLibraries.FilePickers/FileOpenPicker.cs @@ -1,4 +1,4 @@ -using ExternalLibraries.Pickers.Classes; +using ExternalLibraries.Pickers.Classes; using ExternalLibraries.Pickers.Enums; namespace ExternalLibraries.Pickers; diff --git a/src/ExternalLibraries.FilePickers/FileSavePicker.cs b/src/ExternalLibraries.FilePickers/FileSavePicker.cs index 1059728807..917ad60647 100644 --- a/src/ExternalLibraries.FilePickers/FileSavePicker.cs +++ b/src/ExternalLibraries.FilePickers/FileSavePicker.cs @@ -1,4 +1,4 @@ -using ExternalLibraries.Pickers.Classes; +using ExternalLibraries.Pickers.Classes; using ExternalLibraries.Pickers.Enums; namespace ExternalLibraries.Pickers; diff --git a/src/ExternalLibraries.FilePickers/FolderPicker.cs b/src/ExternalLibraries.FilePickers/FolderPicker.cs index 0642f9e2a4..f241217237 100644 --- a/src/ExternalLibraries.FilePickers/FolderPicker.cs +++ b/src/ExternalLibraries.FilePickers/FolderPicker.cs @@ -1,4 +1,4 @@ -using ExternalLibraries.Pickers.Classes; +using ExternalLibraries.Pickers.Classes; using ExternalLibraries.Pickers.Enums; namespace ExternalLibraries.Pickers; diff --git a/src/ExternalLibraries.FilePickers/Guids/CLSIDGuid.cs b/src/ExternalLibraries.FilePickers/Guids/CLSIDGuid.cs index 228f4ed353..0e42f31158 100644 --- a/src/ExternalLibraries.FilePickers/Guids/CLSIDGuid.cs +++ b/src/ExternalLibraries.FilePickers/Guids/CLSIDGuid.cs @@ -1,4 +1,4 @@ -namespace ExternalLibraries.Pickers.Guids; +namespace ExternalLibraries.Pickers.Guids; internal static class CLSIDGuid { diff --git a/src/ExternalLibraries.FilePickers/Guids/IIDGuid.cs b/src/ExternalLibraries.FilePickers/Guids/IIDGuid.cs index a0f1878073..22e824da89 100644 --- a/src/ExternalLibraries.FilePickers/Guids/IIDGuid.cs +++ b/src/ExternalLibraries.FilePickers/Guids/IIDGuid.cs @@ -1,4 +1,4 @@ -namespace ExternalLibraries.Pickers.Guids; +namespace ExternalLibraries.Pickers.Guids; internal static class IIDGuid { diff --git a/src/ExternalLibraries.FilePickers/Guids/KFIDGuid.cs b/src/ExternalLibraries.FilePickers/Guids/KFIDGuid.cs index b51f3740d8..a959a87c68 100644 --- a/src/ExternalLibraries.FilePickers/Guids/KFIDGuid.cs +++ b/src/ExternalLibraries.FilePickers/Guids/KFIDGuid.cs @@ -1,4 +1,4 @@ -namespace ExternalLibraries.Pickers.Guids; +namespace ExternalLibraries.Pickers.Guids; internal static class KFIDGuid { diff --git a/src/ExternalLibraries.FilePickers/Interfaces/FileOpenDialog.cs b/src/ExternalLibraries.FilePickers/Interfaces/FileOpenDialog.cs index 9cddb1024f..2284c73339 100644 --- a/src/ExternalLibraries.FilePickers/Interfaces/FileOpenDialog.cs +++ b/src/ExternalLibraries.FilePickers/Interfaces/FileOpenDialog.cs @@ -1,17 +1,13 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; using ExternalLibraries.Pickers.Classes; using ExternalLibraries.Pickers.Guids; namespace ExternalLibraries.Pickers.Interfaces; // --------------------------------------------------------- -// Coclass interfaces - designed to "look like" the object -// in the API, so that the 'new' operator can be used in a +// Coclass interfaces - designed to "look like" the object +// in the API, so that the 'new' operator can be used in a // straightforward way. Behind the scenes, the C# compiler // morphs all 'new CoClass()' calls to 'new CoClassWrapper()' -[ComImport, -Guid(IIDGuid.IFileOpenDialog), -CoClass(typeof(FileOpenDialogRCW))] -internal interface FileOpenDialog : IFileOpenDialog -{ -} \ No newline at end of file +[ComImport, Guid(IIDGuid.IFileOpenDialog), CoClass(typeof(FileOpenDialogRCW))] +internal interface FileOpenDialog : IFileOpenDialog { } diff --git a/src/ExternalLibraries.FilePickers/Interfaces/FileSaveDialog.cs b/src/ExternalLibraries.FilePickers/Interfaces/FileSaveDialog.cs index 2f76d7e805..1f8240d100 100644 --- a/src/ExternalLibraries.FilePickers/Interfaces/FileSaveDialog.cs +++ b/src/ExternalLibraries.FilePickers/Interfaces/FileSaveDialog.cs @@ -1,17 +1,13 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; using ExternalLibraries.Pickers.Classes; using ExternalLibraries.Pickers.Guids; namespace ExternalLibraries.Pickers.Interfaces; // --------------------------------------------------------- -// Coclass interfaces - designed to "look like" the object -// in the API, so that the 'new' operator can be used in a +// Coclass interfaces - designed to "look like" the object +// in the API, so that the 'new' operator can be used in a // straightforward way. Behind the scenes, the C# compiler // morphs all 'new CoClass()' calls to 'new CoClassWrapper()' -[ComImport, -Guid(IIDGuid.IFileSaveDialog), -CoClass(typeof(FileSaveDialogRCW))] -internal interface FileSaveDialog : IFileSaveDialog -{ -} +[ComImport, Guid(IIDGuid.IFileSaveDialog), CoClass(typeof(FileSaveDialogRCW))] +internal interface FileSaveDialog : IFileSaveDialog { } diff --git a/src/ExternalLibraries.FilePickers/Interfaces/IFileDialog.cs b/src/ExternalLibraries.FilePickers/Interfaces/IFileDialog.cs index 12f2955bad..23a49dd1de 100644 --- a/src/ExternalLibraries.FilePickers/Interfaces/IFileDialog.cs +++ b/src/ExternalLibraries.FilePickers/Interfaces/IFileDialog.cs @@ -1,4 +1,4 @@ -using System.Runtime.CompilerServices; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using ExternalLibraries.Pickers.Enums; using ExternalLibraries.Pickers.Guids; @@ -6,21 +6,24 @@ namespace ExternalLibraries.Pickers.Interfaces; -[ComImport(), -Guid(IIDGuid.IFileDialog), -InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] +[ComImport(), Guid(IIDGuid.IFileDialog), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IFileDialog : IModalWindow { // Defined on IModalWindow - repeated here due to requirements of COM interop layer // -------------------------------------------------------------------------------- - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), - PreserveSig] + [ + MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), + PreserveSig + ] new int Show([In] IntPtr parent); // IFileDialog-Specific interface members // -------------------------------------------------------------------------------- [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void SetFileTypes([In] uint cFileTypes, [In, MarshalAs(UnmanagedType.LPArray)] COMDLG_FILTERSPEC[] rgFilterSpec); + void SetFileTypes( + [In] uint cFileTypes, + [In, MarshalAs(UnmanagedType.LPArray)] COMDLG_FILTERSPEC[] rgFilterSpec + ); [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] void SetFileTypeIndex([In] uint iFileType); @@ -29,7 +32,10 @@ internal interface IFileDialog : IModalWindow void GetFileTypeIndex(out uint piFileType); [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void Advise([In, MarshalAs(UnmanagedType.Interface)] IFileDialogEvents pfde, out uint pdwCookie); + void Advise( + [In, MarshalAs(UnmanagedType.Interface)] IFileDialogEvents pfde, + out uint pdwCookie + ); [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] void Unadvise([In] uint dwCookie); diff --git a/src/ExternalLibraries.FilePickers/Interfaces/IFileDialogEvents.cs b/src/ExternalLibraries.FilePickers/Interfaces/IFileDialogEvents.cs index 732a52d25c..f1eeddeb99 100644 --- a/src/ExternalLibraries.FilePickers/Interfaces/IFileDialogEvents.cs +++ b/src/ExternalLibraries.FilePickers/Interfaces/IFileDialogEvents.cs @@ -1,26 +1,31 @@ -using System.Runtime.CompilerServices; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using ExternalLibraries.Pickers.Enums; using ExternalLibraries.Pickers.Guids; namespace ExternalLibraries.Pickers.Interfaces; -[ComImport, -Guid(IIDGuid.IFileDialogEvents), -InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] +[ComImport, Guid(IIDGuid.IFileDialogEvents), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IFileDialogEvents { - // NOTE: some of these callbacks are cancelable - returning S_FALSE means that - // the dialog should not proceed (e.g. with closing, changing folder); to + // NOTE: some of these callbacks are cancelable - returning S_FALSE means that + // the dialog should not proceed (e.g. with closing, changing folder); to // support this, we need to use the PreserveSig attribute to enable us to return // the proper HRESULT - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), - PreserveSig] + [ + MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), + PreserveSig + ] HRESULT OnFileOk([In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd); - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), - PreserveSig] - HRESULT OnFolderChanging([In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd, [In, MarshalAs(UnmanagedType.Interface)] IShellItem psiFolder); + [ + MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), + PreserveSig + ] + HRESULT OnFolderChanging( + [In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd, + [In, MarshalAs(UnmanagedType.Interface)] IShellItem psiFolder + ); [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] void OnFolderChange([In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd); @@ -29,11 +34,19 @@ internal interface IFileDialogEvents void OnSelectionChange([In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd); [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void OnShareViolation([In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd, [In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, out FDE_SHAREVIOLATION_RESPONSE pResponse); + void OnShareViolation( + [In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd, + [In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, + out FDE_SHAREVIOLATION_RESPONSE pResponse + ); [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] void OnTypeChange([In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd); [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void OnOverwrite([In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd, [In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, out FDE_OVERWRITE_RESPONSE pResponse); + void OnOverwrite( + [In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd, + [In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, + out FDE_OVERWRITE_RESPONSE pResponse + ); } diff --git a/src/ExternalLibraries.FilePickers/Interfaces/IFileOpenDialog.cs b/src/ExternalLibraries.FilePickers/Interfaces/IFileOpenDialog.cs index 61f666d288..3388db6146 100644 --- a/src/ExternalLibraries.FilePickers/Interfaces/IFileOpenDialog.cs +++ b/src/ExternalLibraries.FilePickers/Interfaces/IFileOpenDialog.cs @@ -1,13 +1,11 @@ -using System.Runtime.CompilerServices; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using ExternalLibraries.Pickers.Guids; using ExternalLibraries.Pickers.Structures; namespace ExternalLibraries.Pickers.Interfaces; -[ComImport(), -Guid(IIDGuid.IFileOpenDialog), -InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] +[ComImport(), Guid(IIDGuid.IFileOpenDialog), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IFileOpenDialog : IFileDialog { // Defined on IFileDialog - repeated here due to requirements of COM interop layer diff --git a/src/ExternalLibraries.FilePickers/Interfaces/IModalWindow.cs b/src/ExternalLibraries.FilePickers/Interfaces/IModalWindow.cs index 59f836abdf..edc345f93b 100644 --- a/src/ExternalLibraries.FilePickers/Interfaces/IModalWindow.cs +++ b/src/ExternalLibraries.FilePickers/Interfaces/IModalWindow.cs @@ -1,16 +1,15 @@ -using System.Runtime.CompilerServices; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using ExternalLibraries.Pickers.Guids; namespace ExternalLibraries.Pickers.Interfaces; -[ComImport(), -Guid(IIDGuid.IModalWindow), -InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] +[ComImport(), Guid(IIDGuid.IModalWindow), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IModalWindow { - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), - PreserveSig] + [ + MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), + PreserveSig + ] int Show([In] IntPtr parent); } diff --git a/src/ExternalLibraries.FilePickers/Interfaces/IShellItem.cs b/src/ExternalLibraries.FilePickers/Interfaces/IShellItem.cs index 8bf3f168ff..cd141e3c2a 100644 --- a/src/ExternalLibraries.FilePickers/Interfaces/IShellItem.cs +++ b/src/ExternalLibraries.FilePickers/Interfaces/IShellItem.cs @@ -1,28 +1,38 @@ -using System.Runtime.CompilerServices; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using ExternalLibraries.Pickers.Enums; using ExternalLibraries.Pickers.Guids; namespace ExternalLibraries.Pickers.Interfaces; -[ComImport, -Guid(IIDGuid.IShellItem), -InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] +[ComImport, Guid(IIDGuid.IShellItem), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IShellItem { // Not supported: IBindCtx [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void BindToHandler([In, MarshalAs(UnmanagedType.Interface)] IntPtr pbc, [In] ref Guid bhid, [In] ref Guid riid, out IntPtr ppv); + void BindToHandler( + [In, MarshalAs(UnmanagedType.Interface)] IntPtr pbc, + [In] ref Guid bhid, + [In] ref Guid riid, + out IntPtr ppv + ); [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] void GetParent([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void GetDisplayName([In] SIGDN sigdnName, [MarshalAs(UnmanagedType.LPWStr)] out string ppszName); + void GetDisplayName( + [In] SIGDN sigdnName, + [MarshalAs(UnmanagedType.LPWStr)] out string ppszName + ); [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] void GetAttributes([In] uint sfgaoMask, out uint psfgaoAttribs); [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void Compare([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, [In] uint hint, out int piOrder); + void Compare( + [In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, + [In] uint hint, + out int piOrder + ); } diff --git a/src/ExternalLibraries.FilePickers/Interfaces/IShellItemArray.cs b/src/ExternalLibraries.FilePickers/Interfaces/IShellItemArray.cs index 990cb92fbf..603ecf5832 100644 --- a/src/ExternalLibraries.FilePickers/Interfaces/IShellItemArray.cs +++ b/src/ExternalLibraries.FilePickers/Interfaces/IShellItemArray.cs @@ -1,4 +1,4 @@ -using System.Runtime.CompilerServices; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using ExternalLibraries.Pickers.Enums; using ExternalLibraries.Pickers.Guids; @@ -6,23 +6,34 @@ namespace ExternalLibraries.Pickers.Interfaces; -[ComImport, -Guid(IIDGuid.IShellItemArray), -InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] +[ComImport, Guid(IIDGuid.IShellItemArray), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IShellItemArray { // Not supported: IBindCtx [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void BindToHandler([In, MarshalAs(UnmanagedType.Interface)] IntPtr pbc, [In] ref Guid rbhid, [In] ref Guid riid, out IntPtr ppvOut); + void BindToHandler( + [In, MarshalAs(UnmanagedType.Interface)] IntPtr pbc, + [In] ref Guid rbhid, + [In] ref Guid riid, + out IntPtr ppvOut + ); [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] void GetPropertyStore([In] int Flags, [In] ref Guid riid, out IntPtr ppv); [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void GetPropertyDescriptionList([In] ref PROPERTYKEY keyType, [In] ref Guid riid, out IntPtr ppv); + void GetPropertyDescriptionList( + [In] ref PROPERTYKEY keyType, + [In] ref Guid riid, + out IntPtr ppv + ); [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void GetAttributes([In] SIATTRIBFLAGS dwAttribFlags, [In] uint sfgaoMask, out uint psfgaoAttribs); + void GetAttributes( + [In] SIATTRIBFLAGS dwAttribFlags, + [In] uint sfgaoMask, + out uint psfgaoAttribs + ); [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] void GetCount(out uint pdwNumItems); diff --git a/src/ExternalLibraries.FilePickers/Structures/COMDLG_FILTERSPEC.cs b/src/ExternalLibraries.FilePickers/Structures/COMDLG_FILTERSPEC.cs index 2fa3b3110e..1807ba6ccd 100644 --- a/src/ExternalLibraries.FilePickers/Structures/COMDLG_FILTERSPEC.cs +++ b/src/ExternalLibraries.FilePickers/Structures/COMDLG_FILTERSPEC.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace ExternalLibraries.Pickers.Structures; @@ -19,6 +19,7 @@ internal COMDLG_FILTERSPEC(string name, string spec) [MarshalAs(UnmanagedType.LPWStr)] public string pszName; + [MarshalAs(UnmanagedType.LPWStr)] public string pszSpec; } diff --git a/src/ExternalLibraries.FilePickers/Structures/PROPERTYKEY.cs b/src/ExternalLibraries.FilePickers/Structures/PROPERTYKEY.cs index dbb1a5ab4d..3729e2841b 100644 --- a/src/ExternalLibraries.FilePickers/Structures/PROPERTYKEY.cs +++ b/src/ExternalLibraries.FilePickers/Structures/PROPERTYKEY.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace ExternalLibraries.Pickers.Structures; diff --git a/src/SharedAssemblyInfo.cs b/src/SharedAssemblyInfo.cs index f7c98c2905..635b385194 100644 --- a/src/SharedAssemblyInfo.cs +++ b/src/SharedAssemblyInfo.cs @@ -1,4 +1,4 @@ -using System.Reflection; +using System.Reflection; #if WINDOWS using System.Runtime.Versioning; #endif diff --git a/src/UniGetUI.Core.Classes.Tests/PersonTests.cs b/src/UniGetUI.Core.Classes.Tests/PersonTests.cs index 607dbeaac0..dd53854fd9 100644 --- a/src/UniGetUI.Core.Classes.Tests/PersonTests.cs +++ b/src/UniGetUI.Core.Classes.Tests/PersonTests.cs @@ -1,19 +1,24 @@ -namespace UniGetUI.Core.Classes.Tests +namespace UniGetUI.Core.Classes.Tests { public class PersonTests { [Theory] - [InlineData("Bernat-Miquel Guimerà", "https://github.com/BernatMiquelG.png", "https://github.com/BernatMiquelG")] + [InlineData( + "Bernat-Miquel Guimerà", + "https://github.com/BernatMiquelG.png", + "https://github.com/BernatMiquelG" + )] [InlineData("Bernat-Miquel Guimerà", "https://github.com/BernatMiquelG.png", null)] [InlineData("Bernat-Miquel Guimerà", null, "https://github.com/BernatMiquelG")] [InlineData("Bernat-Miquel Guimerà", null, null)] public void TestPerson(string name, string? profilePicture, string? gitHubUrl) { - //arrange - Person actual = new(Name: name, - ProfilePicture: profilePicture is null ? null : new Uri(profilePicture), - GitHubUrl: gitHubUrl is null ? null : new Uri(gitHubUrl)); + Person actual = new( + Name: name, + ProfilePicture: profilePicture is null ? null : new Uri(profilePicture), + GitHubUrl: gitHubUrl is null ? null : new Uri(gitHubUrl) + ); //Assert if (string.IsNullOrEmpty(profilePicture)) diff --git a/src/UniGetUI.Core.Classes.Tests/SortableObservableCollectionTests.cs b/src/UniGetUI.Core.Classes.Tests/SortableObservableCollectionTests.cs index c4ec45e6cb..907347190f 100644 --- a/src/UniGetUI.Core.Classes.Tests/SortableObservableCollectionTests.cs +++ b/src/UniGetUI.Core.Classes.Tests/SortableObservableCollectionTests.cs @@ -7,7 +7,11 @@ private class SortableInt : IIndexableListItem { public int Value { get; set; } public int Index { get; set; } - public SortableInt(int value) { Value = value; } + + public SortableInt(int value) + { + Value = value; + } } [Fact] @@ -16,8 +20,14 @@ public void TestSortableCollection() int EventTriggeredCount = 0; SortableObservableCollection SortableCollection = []; - SortableCollection.CollectionChanged += (_, _) => { EventTriggeredCount++; }; - SortableCollection.SortingSelector = (s) => { return s.Value; }; + SortableCollection.CollectionChanged += (_, _) => + { + EventTriggeredCount++; + }; + SortableCollection.SortingSelector = (s) => + { + return s.Value; + }; SortableCollection.Add(new(1)); SortableCollection.Add(new(2)); SortableCollection.Add(new(4)); diff --git a/src/UniGetUI.Core.Classes.Tests/TaskRecyclerTests.cs b/src/UniGetUI.Core.Classes.Tests/TaskRecyclerTests.cs index 85575d8ff1..1d55397162 100644 --- a/src/UniGetUI.Core.Classes.Tests/TaskRecyclerTests.cs +++ b/src/UniGetUI.Core.Classes.Tests/TaskRecyclerTests.cs @@ -12,16 +12,24 @@ private int MySlowMethod1() private sealed class TestClass { - public TestClass() {} + public TestClass() { } - [SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Instance methods are required to validate TaskRecycler instance-bound delegate behavior.")] + [SuppressMessage( + "Performance", + "CA1822:Mark members as static", + Justification = "Instance methods are required to validate TaskRecycler instance-bound delegate behavior." + )] public string SlowMethod2() { Thread.Sleep(1000); return new Random().Next().ToString(); } - [SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Instance methods are required to validate TaskRecycler instance-bound delegate behavior.")] + [SuppressMessage( + "Performance", + "CA1822:Mark members as static", + Justification = "Instance methods are required to validate TaskRecycler instance-bound delegate behavior." + )] public string SlowMethod3() { Thread.Sleep(1000); @@ -42,7 +50,7 @@ public async Task TestTaskRecycler_Static_Int() var task1 = TaskRecycler.RunOrAttachAsync(MySlowMethod1); var task2 = TaskRecycler.RunOrAttachAsync(MySlowMethod1); int result1 = await task1; - int result2 = await task2; + int result2 = await task2; Assert.Equal(result1, result2); // The same static method should be cached, and therefore the return value should be the same, but different from previous runs diff --git a/src/UniGetUI.Core.Classes.Tests/UniGetUI.Core.Classes.Tests.csproj b/src/UniGetUI.Core.Classes.Tests/UniGetUI.Core.Classes.Tests.csproj index 2820a5963b..2627cb85ad 100644 --- a/src/UniGetUI.Core.Classes.Tests/UniGetUI.Core.Classes.Tests.csproj +++ b/src/UniGetUI.Core.Classes.Tests/UniGetUI.Core.Classes.Tests.csproj @@ -1,39 +1,38 @@ + + $(PortableTargetFramework) + + false + true + - - $(PortableTargetFramework) - - false - true - + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - + + + - - - + + + - - - - - - - + + + diff --git a/src/UniGetUI.Core.Classes/IIndexableListItem.cs b/src/UniGetUI.Core.Classes/IIndexableListItem.cs index 76856aab66..5e7b20dee3 100644 --- a/src/UniGetUI.Core.Classes/IIndexableListItem.cs +++ b/src/UniGetUI.Core.Classes/IIndexableListItem.cs @@ -1,4 +1,4 @@ -namespace UniGetUI.Core.Classes +namespace UniGetUI.Core.Classes { public interface IIndexableListItem { diff --git a/src/UniGetUI.Core.Classes/ObservableQueue.cs b/src/UniGetUI.Core.Classes/ObservableQueue.cs index ebc57e53b0..54996e5525 100644 --- a/src/UniGetUI.Core.Classes/ObservableQueue.cs +++ b/src/UniGetUI.Core.Classes/ObservableQueue.cs @@ -18,7 +18,7 @@ public class EventArgs(T item) public new T Dequeue() { - T item = base.Dequeue(); + T item = base.Dequeue(); ItemDequeued?.Invoke(this, new EventArgs(item)); return item; } diff --git a/src/UniGetUI.Core.Classes/Person.cs b/src/UniGetUI.Core.Classes/Person.cs index 6e5996f4d0..be7aa29c02 100644 --- a/src/UniGetUI.Core.Classes/Person.cs +++ b/src/UniGetUI.Core.Classes/Person.cs @@ -1,4 +1,4 @@ -namespace UniGetUI.Core.Classes +namespace UniGetUI.Core.Classes { public readonly struct Person { @@ -9,7 +9,12 @@ public readonly struct Person public readonly bool HasGitHubProfile; public readonly string Language; - public Person(string Name, Uri? ProfilePicture = null, Uri? GitHubUrl = null, string Language = "") + public Person( + string Name, + Uri? ProfilePicture = null, + Uri? GitHubUrl = null, + string Language = "" + ) { this.Name = Name; this.ProfilePicture = ProfilePicture; diff --git a/src/UniGetUI.Core.Classes/SortableObservableCollection.cs b/src/UniGetUI.Core.Classes/SortableObservableCollection.cs index 37d187d362..f6510315db 100644 --- a/src/UniGetUI.Core.Classes/SortableObservableCollection.cs +++ b/src/UniGetUI.Core.Classes/SortableObservableCollection.cs @@ -6,7 +6,8 @@ namespace UniGetUI.Core.Classes /* * An observable sorted collection that keeps IIndexableListItem indexes up to date */ - public class SortableObservableCollection : ObservableCollection where T : IIndexableListItem + public class SortableObservableCollection : ObservableCollection + where T : IIndexableListItem { public Func? SortingSelector { get; set; } public bool Descending { get; set; } @@ -18,7 +19,12 @@ protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e) return; base.OnCollectionChanged(e); - if (SortingSelector is null || e.Action is NotifyCollectionChangedAction.Remove or NotifyCollectionChangedAction.Reset) + if ( + SortingSelector is null + || e.Action + is NotifyCollectionChangedAction.Remove + or NotifyCollectionChangedAction.Reset + ) return; Sort(); @@ -33,10 +39,14 @@ public void Sort() if (SortingSelector is null) { - throw new InvalidOperationException("SortableObservableCollection.SortingSelector must not be null when sorting"); + throw new InvalidOperationException( + "SortableObservableCollection.SortingSelector must not be null when sorting" + ); } - List sorted = Descending ? this.OrderByDescending(SortingSelector).ToList() : this.OrderBy(SortingSelector).ToList(); + List sorted = Descending + ? this.OrderByDescending(SortingSelector).ToList() + : this.OrderBy(SortingSelector).ToList(); foreach (T item in sorted) { Move(IndexOf(item), sorted.IndexOf(item)); @@ -48,7 +58,9 @@ public void Sort() } BlockSorting = false; - base.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); + base.OnCollectionChanged( + new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset) + ); } } } diff --git a/src/UniGetUI.Core.Classes/TaskRecycler.cs b/src/UniGetUI.Core.Classes/TaskRecycler.cs index 94aa9b6d0e..53ae2aaba0 100644 --- a/src/UniGetUI.Core.Classes/TaskRecycler.cs +++ b/src/UniGetUI.Core.Classes/TaskRecycler.cs @@ -37,47 +37,78 @@ public static Task RunOrAttachAsync(Func method, int cacheTime } /// Asynchronous entry point for 1 parameter - public static Task RunOrAttachAsync(Func method, ParamT arg1, int cacheTimeSecs = 0) + public static Task RunOrAttachAsync( + Func method, + ParamT arg1, + int cacheTimeSecs = 0 + ) { int hash = method.GetHashCode() + (arg1?.GetHashCode() ?? 0); return _runTaskAndWait(new Task(() => method(arg1)), hash, cacheTimeSecs); } /// Asynchronous entry point for 2 parameters - public static Task RunOrAttachAsync(Func method, - Param1T arg1, Param2T arg2, int cacheTimeSecs = 0) + public static Task RunOrAttachAsync( + Func method, + Param1T arg1, + Param2T arg2, + int cacheTimeSecs = 0 + ) { int hash = method.GetHashCode() + (arg1?.GetHashCode() ?? 0) + (arg2?.GetHashCode() ?? 0); return _runTaskAndWait(new Task(() => method(arg1, arg2)), hash, cacheTimeSecs); } /// Asynchronous entry point for 3 parameters - public static Task RunOrAttachAsync(Func method, - Param1T arg1, Param2T arg2, Param3T arg3, int cacheTimeSecs = 0) + public static Task RunOrAttachAsync( + Func method, + Param1T arg1, + Param2T arg2, + Param3T arg3, + int cacheTimeSecs = 0 + ) { - int hash = method.GetHashCode() + (arg1?.GetHashCode() ?? 0) + (arg2?.GetHashCode() ?? 0) + (arg3?.GetHashCode() ?? 0); - return _runTaskAndWait(new Task(() => method(arg1, arg2, arg3)), hash, cacheTimeSecs); + int hash = + method.GetHashCode() + + (arg1?.GetHashCode() ?? 0) + + (arg2?.GetHashCode() ?? 0) + + (arg3?.GetHashCode() ?? 0); + return _runTaskAndWait( + new Task(() => method(arg1, arg2, arg3)), + hash, + cacheTimeSecs + ); } // --------------------------------------------------------------------------------------------------------------- /// Synchronous entry point for 0 parameters - public static ReturnT RunOrAttach(Func method, int cacheTimeSecs = 0) - => RunOrAttachAsync(method, cacheTimeSecs).GetAwaiter().GetResult(); + public static ReturnT RunOrAttach(Func method, int cacheTimeSecs = 0) => + RunOrAttachAsync(method, cacheTimeSecs).GetAwaiter().GetResult(); /// Synchronous entry point for 1 parameter1 - public static ReturnT RunOrAttach(Func method, ParamT arg1, int cacheTimeSecs = 0) - => RunOrAttachAsync(method, arg1, cacheTimeSecs).GetAwaiter().GetResult(); + public static ReturnT RunOrAttach( + Func method, + ParamT arg1, + int cacheTimeSecs = 0 + ) => RunOrAttachAsync(method, arg1, cacheTimeSecs).GetAwaiter().GetResult(); /// Synchronous entry point for 2 parameters - public static ReturnT RunOrAttach(Func method, Param1T arg1, - Param2T arg2, int cacheTimeSecs = 0) - => RunOrAttachAsync(method, arg1, arg2, cacheTimeSecs).GetAwaiter().GetResult(); + public static ReturnT RunOrAttach( + Func method, + Param1T arg1, + Param2T arg2, + int cacheTimeSecs = 0 + ) => RunOrAttachAsync(method, arg1, arg2, cacheTimeSecs).GetAwaiter().GetResult(); /// Synchronous entry point for 3 parameters - public static ReturnT RunOrAttach(Func method, Param1T arg1, - Param2T arg2, Param3T arg3, int cacheTimeSecs = 0) - => RunOrAttachAsync(method, arg1, arg2, arg3, cacheTimeSecs).GetAwaiter().GetResult(); + public static ReturnT RunOrAttach( + Func method, + Param1T arg1, + Param2T arg2, + Param3T arg3, + int cacheTimeSecs = 0 + ) => RunOrAttachAsync(method, arg1, arg2, arg3, cacheTimeSecs).GetAwaiter().GetResult(); // --------------------------------------------------------------------------------------------------------------- @@ -88,8 +119,8 @@ public static ReturnT RunOrAttach(Func /// - public static void RemoveFromCache(Func method) - => _removeFromCache(method.GetHashCode(), 0); + public static void RemoveFromCache(Func method) => + _removeFromCache(method.GetHashCode(), 0); // --------------------------------------------------------------------------------------------------------------- @@ -126,7 +157,11 @@ private static async Task _runTaskAndWait_VOID(Task task, int hash, int cacheTim /// /// Handles running the task if no such task was found on cache, and returning the cached task if it was found. /// - private static async Task _runTaskAndWait(Task task, int hash, int cacheTimeSecsSecs) + private static async Task _runTaskAndWait( + Task task, + int hash, + int cacheTimeSecsSecs + ) { if (_tasks.TryGetValue(hash, out Task? _task)) { diff --git a/src/UniGetUI.Core.Classes/UniGetUI.Core.Classes.csproj b/src/UniGetUI.Core.Classes/UniGetUI.Core.Classes.csproj index 37104013bb..b66c05a73b 100644 --- a/src/UniGetUI.Core.Classes/UniGetUI.Core.Classes.csproj +++ b/src/UniGetUI.Core.Classes/UniGetUI.Core.Classes.csproj @@ -1,10 +1,13 @@ + + $(SharedTargetFrameworks) + - - - + + + - - - + + + diff --git a/src/UniGetUI.Core.Data.Tests/ContributorsTests.cs b/src/UniGetUI.Core.Data.Tests/ContributorsTests.cs index 9fd9925494..ab8ab45a13 100644 --- a/src/UniGetUI.Core.Data.Tests/ContributorsTests.cs +++ b/src/UniGetUI.Core.Data.Tests/ContributorsTests.cs @@ -1,8 +1,7 @@ -namespace UniGetUI.Core.Data.Tests +namespace UniGetUI.Core.Data.Tests { public class ContributorsTests { - [Fact] public void CheckIfContributorListIsEmpty() { diff --git a/src/UniGetUI.Core.Data.Tests/CoreTests.cs b/src/UniGetUI.Core.Data.Tests/CoreTests.cs index e38f662e74..0f0ad4ca82 100644 --- a/src/UniGetUI.Core.Data.Tests/CoreTests.cs +++ b/src/UniGetUI.Core.Data.Tests/CoreTests.cs @@ -1,22 +1,25 @@ -namespace UniGetUI.Core.Data.Tests +namespace UniGetUI.Core.Data.Tests { public class CoreTests { public static object[][] Data => [ [CoreData.UniGetUIDataDirectory], - [CoreData.UniGetUIInstallationOptionsDirectory ], - [CoreData.UniGetUICacheDirectory_Data ], - [CoreData.UniGetUICacheDirectory_Icons ], - [CoreData.UniGetUICacheDirectory_Lang ], - [CoreData.UniGetUI_DefaultBackupDirectory ] - ]; + [CoreData.UniGetUIInstallationOptionsDirectory], + [CoreData.UniGetUICacheDirectory_Data], + [CoreData.UniGetUICacheDirectory_Icons], + [CoreData.UniGetUICacheDirectory_Lang], + [CoreData.UniGetUI_DefaultBackupDirectory], + ]; [Theory] [MemberData(nameof(Data))] public void CheckDirectoryAttributes(string directory) { - Assert.True(Directory.Exists(directory), $"Directory ${directory} does not exist, but it should have been created automatically"); + Assert.True( + Directory.Exists(directory), + $"Directory ${directory} does not exist, but it should have been created automatically" + ); } [Fact] @@ -26,8 +29,14 @@ public void CheckOtherAttributes() Assert.NotEqual(0, CoreData.BuildNumber); Assert.NotEqual(0, CoreData.UpdatesAvailableNotificationTag); - Assert.True(Directory.Exists(CoreData.UniGetUIExecutableDirectory), "Directory where the executable is located does not exist"); - Assert.True(File.Exists(CoreData.UniGetUIExecutableFile), "The executable file does not exist"); + Assert.True( + Directory.Exists(CoreData.UniGetUIExecutableDirectory), + "Directory where the executable is located does not exist" + ); + Assert.True( + File.Exists(CoreData.UniGetUIExecutableFile), + "The executable file does not exist" + ); } } } diff --git a/src/UniGetUI.Core.Data.Tests/LicensesTest.cs b/src/UniGetUI.Core.Data.Tests/LicensesTest.cs index ebb8c41e46..debdb89d5c 100644 --- a/src/UniGetUI.Core.Data.Tests/LicensesTest.cs +++ b/src/UniGetUI.Core.Data.Tests/LicensesTest.cs @@ -15,7 +15,10 @@ public void EnsureLicenseUrlsExist() } } - Assert.True(MissingUrls.Count == 0, "The list of missing licenses is not empty: " + MissingUrls.ToArray().ToString()); + Assert.True( + MissingUrls.Count == 0, + "The list of missing licenses is not empty: " + MissingUrls.ToArray().ToString() + ); } [Fact] @@ -31,8 +34,10 @@ public void EnsureHomepageUrlsExist() } } - Assert.True(MissingUrls.Count == 0, "The list of missing licenses is not empty: " + MissingUrls.ToArray().ToString()); + Assert.True( + MissingUrls.Count == 0, + "The list of missing licenses is not empty: " + MissingUrls.ToArray().ToString() + ); } - } -} \ No newline at end of file +} diff --git a/src/UniGetUI.Core.Data.Tests/UniGetUI.Core.Data.Tests.csproj b/src/UniGetUI.Core.Data.Tests/UniGetUI.Core.Data.Tests.csproj index 37eb555bba..556d89135b 100644 --- a/src/UniGetUI.Core.Data.Tests/UniGetUI.Core.Data.Tests.csproj +++ b/src/UniGetUI.Core.Data.Tests/UniGetUI.Core.Data.Tests.csproj @@ -1,43 +1,40 @@ - - - $(PortableTargetFramework) - - - - - - - false - true - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - - - - - - - - - - + + $(PortableTargetFramework) + + + + + false + true + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + + + + + + diff --git a/src/UniGetUI.Core.Data/Contributors.cs b/src/UniGetUI.Core.Data/Contributors.cs index cd274d57be..46a913c71b 100644 --- a/src/UniGetUI.Core.Data/Contributors.cs +++ b/src/UniGetUI.Core.Data/Contributors.cs @@ -1,9 +1,16 @@ -namespace UniGetUI.Core.Data +namespace UniGetUI.Core.Data { public static class ContributorsData { public static string[] Contributors = File.ReadAllLines( - Path.Join(CoreData.UniGetUIExecutableDirectory, "Assets", "Data", "Contributors.list") - ).Where(x => x != "").ToArray(); + Path.Join( + CoreData.UniGetUIExecutableDirectory, + "Assets", + "Data", + "Contributors.list" + ) + ) + .Where(x => x != "") + .ToArray(); } } diff --git a/src/UniGetUI.Core.Data/CoreCredentialStore.cs b/src/UniGetUI.Core.Data/CoreCredentialStore.cs index ca5ce6eecf..7cbed4adf0 100644 --- a/src/UniGetUI.Core.Data/CoreCredentialStore.cs +++ b/src/UniGetUI.Core.Data/CoreCredentialStore.cs @@ -15,15 +15,11 @@ public static class CoreCredentialStore string? secret = GetSecret(resourceName, userName); return secret is null ? null - : new NetworkCredential - { - UserName = userName, - Password = secret, - }; + : new NetworkCredential { UserName = userName, Password = secret }; } - public static void SetCredential(string resourceName, string userName, string password) - => SetSecret(resourceName, userName, password); + public static void SetCredential(string resourceName, string userName, string password) => + SetSecret(resourceName, userName, password); public static string? GetSecret(string resourceName, string userName) { @@ -73,8 +69,13 @@ public static void DeleteSecret(string resourceName, string userName) { #if WINDOWS var vault = new PasswordVault(); - IReadOnlyList credentials = vault.FindAllByResource(resourceName) ?? []; - foreach (PasswordCredential credential in credentials.Where(credential => credential.UserName == userName)) + IReadOnlyList credentials = + vault.FindAllByResource(resourceName) ?? []; + foreach ( + PasswordCredential credential in credentials.Where(credential => + credential.UserName == userName + ) + ) { vault.Remove(credential); } @@ -94,11 +95,11 @@ public static void DeleteSecret(string resourceName, string userName) } #if !WINDOWS - private static string GetStorageDirectory() - => Path.Join(CoreData.UniGetUIDataDirectory, "SecureStorage"); + private static string GetStorageDirectory() => + Path.Join(CoreData.UniGetUIDataDirectory, "SecureStorage"); - private static string GetSecretPath(string resourceName, string userName) - => Path.Join(GetStorageDirectory(), GetStableFileName(resourceName, userName)); + private static string GetSecretPath(string resourceName, string userName) => + Path.Join(GetStorageDirectory(), GetStableFileName(resourceName, userName)); private static string GetStableFileName(string resourceName, string userName) { @@ -106,4 +107,4 @@ private static string GetStableFileName(string resourceName, string userName) return Convert.ToHexString(hash) + ".secret"; } #endif -} \ No newline at end of file +} diff --git a/src/UniGetUI.Core.Data/CoreData.cs b/src/UniGetUI.Core.Data/CoreData.cs index 54ec0e31f0..62153855e2 100644 --- a/src/UniGetUI.Core.Data/CoreData.cs +++ b/src/UniGetUI.Core.Data/CoreData.cs @@ -1,4 +1,4 @@ -using System.Diagnostics; +using System.Diagnostics; using System.Text; using UniGetUI.Core.Logging; @@ -7,18 +7,25 @@ namespace UniGetUI.Core.Data public static class CoreData { private static int? __code_page; - public static int CODE_PAGE { get => __code_page ??= GetCodePage(); } + public static int CODE_PAGE + { + get => __code_page ??= GetCodePage(); + } public const string VersionName = "3.3.7"; // Do not modify this line, use file scripts/set-version.ps1 public const int BuildNumber = 106; // Do not modify this line, use file scripts/set-version.ps1 - public const string UserAgentString = $"UniGetUI/{VersionName} (https://marticliment.com/unigetui/; contact@marticliment.com)"; + public const string UserAgentString = + $"UniGetUI/{VersionName} (https://marticliment.com/unigetui/; contact@marticliment.com)"; public const string AppIdentifier = "MartiCliment.UniGetUI"; public const string MainWindowIdentifier = "MartiCliment.UniGetUI.MainInterface"; private static bool? IS_PORTABLE; private static string? PORTABLE_PATH; - public static bool IsPortable { get => IS_PORTABLE ?? false; } + public static bool IsPortable + { + get => IS_PORTABLE ?? false; + } public static string? TEST_DataDirectoryOverride { private get; set; } @@ -36,16 +43,22 @@ public static string UniGetUIDataDirectory if (IS_PORTABLE is null) { - IS_PORTABLE = File.Exists(Path.Join(UniGetUIExecutableDirectory, "ForceUniGetUIPortable")); + IS_PORTABLE = File.Exists( + Path.Join(UniGetUIExecutableDirectory, "ForceUniGetUIPortable") + ); if (IS_PORTABLE is true) { string path = Path.Join(UniGetUIExecutableDirectory, "Settings"); try { - if (!Directory.Exists(path)) Directory.CreateDirectory(path); + if (!Directory.Exists(path)) + Directory.CreateDirectory(path); var testfilepath = Path.Join(path, "PermissionTestFile"); - File.WriteAllText(testfilepath, "https://www.youtube.com/watch?v=dQw4w9WgXcQ"); + File.WriteAllText( + testfilepath, + "https://www.youtube.com/watch?v=dQw4w9WgXcQ" + ); PORTABLE_PATH = path; return path; } @@ -53,16 +66,22 @@ public static string UniGetUIDataDirectory { IS_PORTABLE = false; Logger.Error( - $"Could not acces/write path {path}. UniGetUI will NOT be run in portable mode, and User settings will be used instead"); + $"Could not acces/write path {path}. UniGetUI will NOT be run in portable mode, and User settings will be used instead" + ); Logger.Error(ex); } } - } else if (IS_PORTABLE is true) + } + else if (IS_PORTABLE is true) { - return PORTABLE_PATH ?? throw new InvalidOperationException("This shouldn't be possible"); + return PORTABLE_PATH + ?? throw new InvalidOperationException("This shouldn't be possible"); } - string old_path = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".wingetui"); + string old_path = Path.Join( + Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), + ".wingetui" + ); string new_path = Path.Join(GetLocalDataRoot(), "UniGetUI"); return GetNewDataDirectoryOrMoveOld(old_path, new_path); } @@ -83,14 +102,24 @@ public static string UniGetUIUserConfigurationDirectory //Migration case try { - Logger.Info($"Moving configuration files from '{oldConfigPath}' to '{newConfigPath}'"); + Logger.Info( + $"Moving configuration files from '{oldConfigPath}' to '{newConfigPath}'" + ); Directory.CreateDirectory(newConfigPath); - foreach (string file in Directory.GetFiles(oldConfigPath, "*.*", SearchOption.TopDirectoryOnly)) + foreach ( + string file in Directory.GetFiles( + oldConfigPath, + "*.*", + SearchOption.TopDirectoryOnly + ) + ) { string fileName = Path.GetFileName(file); string fileExtension = Path.GetExtension(file); - bool isConfigFile = string.IsNullOrEmpty(fileExtension) || fileExtension.ToLowerInvariant() == ".json"; + bool isConfigFile = + string.IsNullOrEmpty(fileExtension) + || fileExtension.ToLowerInvariant() == ".json"; if (isConfigFile) { @@ -99,18 +128,24 @@ public static string UniGetUIUserConfigurationDirectory if (!File.Exists(newFile)) { File.Move(file, newFile); - Logger.Debug($"Moved configuration file '{file}' to '{newFile}'"); + Logger.Debug( + $"Moved configuration file '{file}' to '{newFile}'" + ); } // Clean up old file to avoid duplicates and confusion else { - Logger.Warn($"Configuration file '{newFile}' already exists, skipping move from '{file}'."); + Logger.Warn( + $"Configuration file '{newFile}' already exists, skipping move from '{file}'." + ); File.Delete(file); } } else { - Logger.Debug($"Skipping non-configuration file '{file}' during migration."); + Logger.Debug( + $"Skipping non-configuration file '{file}' during migration." + ); } } Logger.Info($"Configuration files moved successfully to '{newConfigPath}'"); @@ -118,7 +153,9 @@ public static string UniGetUIUserConfigurationDirectory catch (Exception ex) { // Fallback to old path if migration fails to not break functionality - Logger.Error($"Error moving configuration files from '{oldConfigPath}' to '{newConfigPath}'. Using old path for now. Manual migration might be needed."); + Logger.Error( + $"Error moving configuration files from '{oldConfigPath}' to '{newConfigPath}'. Using old path for now. Manual migration might be needed." + ); Logger.Error(ex); return oldConfigPath; } @@ -140,7 +177,8 @@ public static string UniGetUIInstallationOptionsDirectory get { string path = Path.Join(UniGetUIDataDirectory, "InstallationOptions"); - if (!Directory.Exists(path)) Directory.CreateDirectory(path); + if (!Directory.Exists(path)) + Directory.CreateDirectory(path); return path; } } @@ -153,7 +191,8 @@ public static string UniGetUICacheDirectory_Data get { string path = Path.Join(UniGetUIDataDirectory, "CachedMetadata"); - if (!Directory.Exists(path)) Directory.CreateDirectory(path); + if (!Directory.Exists(path)) + Directory.CreateDirectory(path); return path; } } @@ -166,7 +205,8 @@ public static string UniGetUICacheDirectory_Icons get { string path = Path.Join(UniGetUIDataDirectory, "CachedMedia"); - if (!Directory.Exists(path)) Directory.CreateDirectory(path); + if (!Directory.Exists(path)) + Directory.CreateDirectory(path); return path; } } @@ -179,7 +219,8 @@ public static string UniGetUICacheDirectory_Lang get { string path = Path.Join(UniGetUIDataDirectory, "CachedLanguageFiles"); - if (!Directory.Exists(path)) Directory.CreateDirectory(path); + if (!Directory.Exists(path)) + Directory.CreateDirectory(path); return path; } } @@ -205,10 +246,12 @@ public static string UniGetUI_DefaultBackupDirectory /// The ID of the notification that is used to inform the user that updates are available /// public const int UpdatesAvailableNotificationTag = 1234; + /// /// The ID of the notification that is used to inform the user that UniGetUI can be updated /// public const int UniGetUICanBeUpdated = 1235; + /// /// The ID of the notification that is used to inform the user that shortcuts are available for deletion /// @@ -221,15 +264,22 @@ public static string UniGetUIExecutableDirectory { get { - string? dir = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); + string? dir = Path.GetDirectoryName( + System.Reflection.Assembly.GetExecutingAssembly().Location + ); if (dir is not null) { return dir; } - Logger.Error("System.Reflection.Assembly.GetExecutingAssembly().Location returned an empty path"); + Logger.Error( + "System.Reflection.Assembly.GetExecutingAssembly().Location returned an empty path" + ); - return AppContext.BaseDirectory.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); + return AppContext.BaseDirectory.TrimEnd( + Path.DirectorySeparatorChar, + Path.AltDirectorySeparatorChar + ); } } @@ -246,7 +296,9 @@ public static string UniGetUIExecutableFile return NormalizeExecutablePath(filename); } - Logger.Error("System.Reflection.Assembly.GetExecutingAssembly().Location returned an empty path"); + Logger.Error( + "System.Reflection.Assembly.GetExecutingAssembly().Location returned an empty path" + ); return OperatingSystem.IsWindows() ? Path.Join(UniGetUIExecutableDirectory, "UniGetUI.exe") @@ -276,7 +328,13 @@ private static string GetNewDataDirectoryOrMoveOld(string old_path, string new_p { try { - foreach (string old_subdir in Directory.GetDirectories(old_path, "*", SearchOption.AllDirectories)) + foreach ( + string old_subdir in Directory.GetDirectories( + old_path, + "*", + SearchOption.AllDirectories + ) + ) { string new_subdir = old_subdir.Replace(old_path, new_path); if (!Directory.Exists(new_subdir)) @@ -290,7 +348,13 @@ private static string GetNewDataDirectoryOrMoveOld(string old_path, string new_p } } - foreach (string old_file in Directory.GetFiles(old_path, "*", SearchOption.AllDirectories)) + foreach ( + string old_file in Directory.GetFiles( + old_path, + "*", + SearchOption.AllDirectories + ) + ) { string new_file = old_file.Replace(old_path, new_path); if (!File.Exists(new_file)) @@ -305,16 +369,28 @@ private static string GetNewDataDirectoryOrMoveOld(string old_path, string new_p } } - foreach (string old_subdir in Directory.GetDirectories(old_path, "*", SearchOption.AllDirectories)) + foreach ( + string old_subdir in Directory.GetDirectories( + old_path, + "*", + SearchOption.AllDirectories + ) + ) { - if (!Directory.EnumerateFiles(old_subdir).Any() && !Directory.EnumerateDirectories(old_subdir).Any()) + if ( + !Directory.EnumerateFiles(old_subdir).Any() + && !Directory.EnumerateDirectories(old_subdir).Any() + ) { Logger.Debug("Deleting old empty subdirectory " + old_subdir); Directory.Delete(old_subdir); } } - if (!Directory.EnumerateFiles(old_path).Any() && !Directory.EnumerateDirectories(old_path).Any()) + if ( + !Directory.EnumerateFiles(old_path).Any() + && !Directory.EnumerateDirectories(old_path).Any() + ) { Logger.Info("Deleting old Chocolatey directory " + old_path); Directory.Delete(old_path); @@ -329,7 +405,9 @@ private static string GetNewDataDirectoryOrMoveOld(string old_path, string new_p } } - if (/*Directory.Exists(new_path)*/Directory.Exists(old_path)) + if ( /*Directory.Exists(new_path)*/ + Directory.Exists(old_path) + ) { try { @@ -339,7 +417,12 @@ private static string GetNewDataDirectoryOrMoveOld(string old_path, string new_p } catch (Exception e) { - Logger.Error("Cannot move old data directory to new location. Directory to move: " + old_path + ". Destination: " + new_path); + Logger.Error( + "Cannot move old data directory to new location. Directory to move: " + + old_path + + ". Destination: " + + new_path + ); Logger.Error(e); return old_path; } @@ -353,7 +436,9 @@ private static string GetNewDataDirectoryOrMoveOld(string old_path, string new_p } catch (Exception e) { - Logger.Error("Could not create new directory. You may perhaps need to disable Controlled Folder Access from Windows Settings or make an exception for UniGetUI."); + Logger.Error( + "Could not create new directory. You may perhaps need to disable Controlled Folder Access from Windows Settings or make an exception for UniGetUI." + ); Logger.Error(e); return new_path; } @@ -376,7 +461,7 @@ private static int GetCodePage() RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true, - } + }, }; p.Start(); string contents = p.StandardOutput.ReadToEnd(); @@ -405,7 +490,9 @@ private static int GetCodePage() private static string GetLocalDataRoot() { - string localApplicationData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); + string localApplicationData = Environment.GetFolderPath( + Environment.SpecialFolder.LocalApplicationData + ); if (!string.IsNullOrWhiteSpace(localApplicationData)) { return localApplicationData; @@ -422,7 +509,9 @@ private static string GetLocalDataRoot() private static string GetDocumentsRoot() { - string documentsDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); + string documentsDirectory = Environment.GetFolderPath( + Environment.SpecialFolder.MyDocuments + ); if (!string.IsNullOrWhiteSpace(documentsDirectory)) { return documentsDirectory; @@ -444,7 +533,10 @@ private static string GetUserHomeDirectory() private static string NormalizeExecutablePath(string path) { - if (OperatingSystem.IsWindows() && path.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)) + if ( + OperatingSystem.IsWindows() + && path.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) + ) { return Path.ChangeExtension(path, ".exe"); } diff --git a/src/UniGetUI.Core.Data/Licenses.cs b/src/UniGetUI.Core.Data/Licenses.cs index acbd048207..fae4800ba0 100644 --- a/src/UniGetUI.Core.Data/Licenses.cs +++ b/src/UniGetUI.Core.Data/Licenses.cs @@ -2,104 +2,137 @@ namespace UniGetUI.Core.Data { public static class LicenseData { - public static Dictionary LicenseNames = new() { - {"UniGetUI", "MIT" }, - + public static Dictionary LicenseNames = new() + { + { "UniGetUI", "MIT" }, // C# Libraries - {"Pickers", "MIT"}, - {"Community Toolkit", "MIT"}, - {"H.NotifyIcon", "MIT"}, - {"Windows App Sdk", "MIT"}, - {"PhotoSauce.MagicScaler", "MIT"}, - {"YamlDotNet", "MIT"}, - {"InnoDependencyInstaller", "CPOL 1.02" }, - + { "Pickers", "MIT" }, + { "Community Toolkit", "MIT" }, + { "H.NotifyIcon", "MIT" }, + { "Windows App Sdk", "MIT" }, + { "PhotoSauce.MagicScaler", "MIT" }, + { "YamlDotNet", "MIT" }, + { "InnoDependencyInstaller", "CPOL 1.02" }, // Package managers and related - {"WinGet", "MIT"}, - {"Scoop", "MIT"}, - {"scoop-search", "MIT"}, - {"Chocolatey", "Apache v2"}, - {"npm", "Artistic License 2.0"}, - {"Pip", "MIT"}, - {"parse_pip_search", "MIT"}, - {"PowerShell Gallery", "Unknown"}, - {".NET SDK", "MIT"}, - {"Cargo", "MIT"}, - {"cargo-binstall", "GPL-3.0-only"}, - {"cargo-update", "MIT"}, - {"vcpkg", "MIT"}, - + { "WinGet", "MIT" }, + { "Scoop", "MIT" }, + { "scoop-search", "MIT" }, + { "Chocolatey", "Apache v2" }, + { "npm", "Artistic License 2.0" }, + { "Pip", "MIT" }, + { "parse_pip_search", "MIT" }, + { "PowerShell Gallery", "Unknown" }, + { ".NET SDK", "MIT" }, + { "Cargo", "MIT" }, + { "cargo-binstall", "GPL-3.0-only" }, + { "cargo-update", "MIT" }, + { "vcpkg", "MIT" }, // Other - {"GSudo", "MIT"}, - {"UniGetUI Elevator", "MIT"}, - {"Icons", "By Icons8"}, + { "GSudo", "MIT" }, + { "UniGetUI Elevator", "MIT" }, + { "Icons", "By Icons8" }, }; - public static Dictionary LicenseURLs = new(){ - {"UniGetUI", new Uri("https://github.com/Devolutions/UniGetUI/blob/main/LICENSE")}, - + public static Dictionary LicenseURLs = new() + { + { "UniGetUI", new Uri("https://github.com/Devolutions/UniGetUI/blob/main/LICENSE") }, // C# Libraries - {"Pickers", new Uri("https://github.com/PavlikBender/Pickers/blob/master/LICENSE")}, - {"Community Toolkit", new Uri("https://github.com/CommunityToolkit/Windows/blob/main/License.md")}, - {"H.NotifyIcon", new Uri("https://github.com/HavenDV/H.NotifyIcon/blob/master/LICENSE.md")}, - {"Windows App Sdk", new Uri("https://github.com/microsoft/WindowsAppSDK/blob/main/LICENSE")}, - {"PhotoSauce.MagicScaler", new Uri("https://github.com/saucecontrol/PhotoSauce/blob/master/license")}, - {"YamlDotNet", new Uri("https://github.com/aaubry/YamlDotNet/blob/master/LICENSE.txt") }, - {"InnoDependencyInstaller", new Uri("https://github.com/DomGries/InnoDependencyInstaller/blob/master/LICENSE.md") }, - + { "Pickers", new Uri("https://github.com/PavlikBender/Pickers/blob/master/LICENSE") }, + { + "Community Toolkit", + new Uri("https://github.com/CommunityToolkit/Windows/blob/main/License.md") + }, + { + "H.NotifyIcon", + new Uri("https://github.com/HavenDV/H.NotifyIcon/blob/master/LICENSE.md") + }, + { + "Windows App Sdk", + new Uri("https://github.com/microsoft/WindowsAppSDK/blob/main/LICENSE") + }, + { + "PhotoSauce.MagicScaler", + new Uri("https://github.com/saucecontrol/PhotoSauce/blob/master/license") + }, + { + "YamlDotNet", + new Uri("https://github.com/aaubry/YamlDotNet/blob/master/LICENSE.txt") + }, + { + "InnoDependencyInstaller", + new Uri( + "https://github.com/DomGries/InnoDependencyInstaller/blob/master/LICENSE.md" + ) + }, // Package managers and related - {"WinGet", new Uri("https://github.com/microsoft/winget-cli/blob/master/LICENSE")}, - {"Scoop", new Uri("https://github.com/ScoopInstaller/Scoop/blob/master/LICENSE")}, - {"scoop-search", new Uri("https://github.com/shilangyu/scoop-search/blob/master/LICENSE")}, - {"Chocolatey", new Uri("https://github.com/chocolatey/choco/blob/develop/LICENSE")}, - {"npm", new Uri("https://github.com/npm/cli/blob/latest/LICENSE")}, - {"Pip", new Uri("https://github.com/pypa/pip/blob/main/LICENSE.txt")}, - {"parse_pip_search", new Uri("https://github.com/marticliment/parseable_pip_search/blob/master/LICENSE.md")}, - {".NET SDK", new Uri("https://github.com/dotnet/sdk/blob/main/LICENSE.TXT")}, - {"PowerShell Gallery", new Uri("https://www.powershellgallery.com/")}, - {"Cargo", new Uri("https://github.com/rust-lang/cargo/blob/master/LICENSE-MIT")}, - {"cargo-binstall", new Uri("https://spdx.org/licenses/GPL-3.0-only.html")}, - {"cargo-update", new Uri("https://github.com/nabijaczleweli/cargo-update/blob/master/LICENSE")}, - {"vcpkg", new Uri("https://github.com/microsoft/vcpkg/blob/master/LICENSE.txt")}, - + { "WinGet", new Uri("https://github.com/microsoft/winget-cli/blob/master/LICENSE") }, + { "Scoop", new Uri("https://github.com/ScoopInstaller/Scoop/blob/master/LICENSE") }, + { + "scoop-search", + new Uri("https://github.com/shilangyu/scoop-search/blob/master/LICENSE") + }, + { "Chocolatey", new Uri("https://github.com/chocolatey/choco/blob/develop/LICENSE") }, + { "npm", new Uri("https://github.com/npm/cli/blob/latest/LICENSE") }, + { "Pip", new Uri("https://github.com/pypa/pip/blob/main/LICENSE.txt") }, + { + "parse_pip_search", + new Uri( + "https://github.com/marticliment/parseable_pip_search/blob/master/LICENSE.md" + ) + }, + { ".NET SDK", new Uri("https://github.com/dotnet/sdk/blob/main/LICENSE.TXT") }, + { "PowerShell Gallery", new Uri("https://www.powershellgallery.com/") }, + { "Cargo", new Uri("https://github.com/rust-lang/cargo/blob/master/LICENSE-MIT") }, + { "cargo-binstall", new Uri("https://spdx.org/licenses/GPL-3.0-only.html") }, + { + "cargo-update", + new Uri("https://github.com/nabijaczleweli/cargo-update/blob/master/LICENSE") + }, + { "vcpkg", new Uri("https://github.com/microsoft/vcpkg/blob/master/LICENSE.txt") }, // Other - {"GSudo", new Uri("https://github.com/gerardog/gsudo/blob/master/LICENSE.txt")}, - {"UniGetUI Elevator", new Uri("https://github.com/marticliment/GSudo-for-UniGetUI/blob/main/LICENSE.txt")}, - {"Icons", new Uri("https://icons8.com/license")}, + { "GSudo", new Uri("https://github.com/gerardog/gsudo/blob/master/LICENSE.txt") }, + { + "UniGetUI Elevator", + new Uri("https://github.com/marticliment/GSudo-for-UniGetUI/blob/main/LICENSE.txt") + }, + { "Icons", new Uri("https://icons8.com/license") }, }; - public static Dictionary HomepageUrls = new(){ - {"UniGetUI", new Uri("https://marticliment.com/unigetui")}, - + public static Dictionary HomepageUrls = new() + { + { "UniGetUI", new Uri("https://marticliment.com/unigetui") }, // C# Libraries - {"Pickers", new Uri("https://github.com/PavlikBender/Pickers/")}, - {"Community Toolkit", new Uri("https://github.com/CommunityToolkit/Windows/")}, - {"H.NotifyIcon", new Uri("https://github.com/HavenDV/H.NotifyIcon/")}, - {"Windows App Sdk", new Uri("https://github.com/microsoft/WindowsAppSDK/")}, - {"PhotoSauce.MagicScaler", new Uri("https://github.com/saucecontrol/PhotoSauce/")}, - {"YamlDotNet", new Uri("https://github.com/aaubry/YamlDotNet/") }, - {"InnoDependencyInstaller", new Uri("https://github.com/DomGries/InnoDependencyInstaller")}, - + { "Pickers", new Uri("https://github.com/PavlikBender/Pickers/") }, + { "Community Toolkit", new Uri("https://github.com/CommunityToolkit/Windows/") }, + { "H.NotifyIcon", new Uri("https://github.com/HavenDV/H.NotifyIcon/") }, + { "Windows App Sdk", new Uri("https://github.com/microsoft/WindowsAppSDK/") }, + { "PhotoSauce.MagicScaler", new Uri("https://github.com/saucecontrol/PhotoSauce/") }, + { "YamlDotNet", new Uri("https://github.com/aaubry/YamlDotNet/") }, + { + "InnoDependencyInstaller", + new Uri("https://github.com/DomGries/InnoDependencyInstaller") + }, // Package managers and related - {"WinGet", new Uri("https://github.com/microsoft/winget-cli/")}, - {"Scoop", new Uri("https://github.com/ScoopInstaller/Scoop/")}, - {"scoop-search", new Uri("https://github.com/shilangyu/scoop-search/")}, - {"Chocolatey", new Uri("https://github.com/chocolatey/choco/")}, - {"npm", new Uri("https://github.com/npm/cli/")}, - {"Pip", new Uri("https://github.com/pypa/pip/")}, - {"parse_pip_search", new Uri("https://github.com/marticliment/parseable_pip_search/")}, - {".NET SDK", new Uri("https://dotnet.microsoft.com/")}, - {"PowerShell Gallery", new Uri("https://www.powershellgallery.com/")}, - {"Cargo", new Uri("https://github.com/rust-lang/cargo")}, - {"cargo-binstall", new Uri("https://github.com/cargo-bins/cargo-binstall")}, - {"cargo-update", new Uri("https://github.com/nabijaczleweli/cargo-update/")}, - {"vcpkg", new Uri("https://github.com/microsoft/vcpkg")}, - + { "WinGet", new Uri("https://github.com/microsoft/winget-cli/") }, + { "Scoop", new Uri("https://github.com/ScoopInstaller/Scoop/") }, + { "scoop-search", new Uri("https://github.com/shilangyu/scoop-search/") }, + { "Chocolatey", new Uri("https://github.com/chocolatey/choco/") }, + { "npm", new Uri("https://github.com/npm/cli/") }, + { "Pip", new Uri("https://github.com/pypa/pip/") }, + { + "parse_pip_search", + new Uri("https://github.com/marticliment/parseable_pip_search/") + }, + { ".NET SDK", new Uri("https://dotnet.microsoft.com/") }, + { "PowerShell Gallery", new Uri("https://www.powershellgallery.com/") }, + { "Cargo", new Uri("https://github.com/rust-lang/cargo") }, + { "cargo-binstall", new Uri("https://github.com/cargo-bins/cargo-binstall") }, + { "cargo-update", new Uri("https://github.com/nabijaczleweli/cargo-update/") }, + { "vcpkg", new Uri("https://github.com/microsoft/vcpkg") }, // Other - {"GSudo", new Uri("https://github.com/gerardog/gsudo/")}, - {"UniGetUI Elevator", new Uri("https://github.com/marticliment/GSudo-for-UniGetUI/")}, - {"Icons", new Uri("https://icons8.com")}, + { "GSudo", new Uri("https://github.com/gerardog/gsudo/") }, + { "UniGetUI Elevator", new Uri("https://github.com/marticliment/GSudo-for-UniGetUI/") }, + { "Icons", new Uri("https://icons8.com") }, }; - } } diff --git a/src/UniGetUI.Core.Data/UniGetUI.Core.Data.csproj b/src/UniGetUI.Core.Data/UniGetUI.Core.Data.csproj index 2329f02494..a764202b92 100644 --- a/src/UniGetUI.Core.Data/UniGetUI.Core.Data.csproj +++ b/src/UniGetUI.Core.Data/UniGetUI.Core.Data.csproj @@ -1,20 +1,23 @@ + + $(SharedTargetFrameworks) + - - - + + + - - - PreserveNewest - - + + + PreserveNewest + + - - - + + + - - - + + + diff --git a/src/UniGetUI.Core.IconEngine.Tests/IconCacheEngineTests.cs b/src/UniGetUI.Core.IconEngine.Tests/IconCacheEngineTests.cs index 8f22b98d2b..4d7548f30f 100644 --- a/src/UniGetUI.Core.IconEngine.Tests/IconCacheEngineTests.cs +++ b/src/UniGetUI.Core.IconEngine.Tests/IconCacheEngineTests.cs @@ -8,15 +8,88 @@ public static class IconCacheEngineTests public static void TestCacheEngineForSha256() { Uri ICON_1 = new Uri("https://marticliment.com/resources/unigetui.png"); - byte[] HASH_1 = [0xB7, 0x41, 0xC3, 0x18, 0xBF, 0x2B, 0x07, 0xAA, 0x92, 0xB2, 0x7A, 0x1B, 0x4D, 0xC5, 0xEE, 0xC4, 0xD1, 0x9B, 0x22, 0xD4, 0x0A, 0x13, 0x26, 0xA7, 0x45, 0xA4, 0xA7, 0xF5, 0x81, 0x8E, 0xAF, 0xFF]; + byte[] HASH_1 = + [ + 0xB7, + 0x41, + 0xC3, + 0x18, + 0xBF, + 0x2B, + 0x07, + 0xAA, + 0x92, + 0xB2, + 0x7A, + 0x1B, + 0x4D, + 0xC5, + 0xEE, + 0xC4, + 0xD1, + 0x9B, + 0x22, + 0xD4, + 0x0A, + 0x13, + 0x26, + 0xA7, + 0x45, + 0xA4, + 0xA7, + 0xF5, + 0x81, + 0x8E, + 0xAF, + 0xFF, + ]; Uri ICON_2 = new Uri("https://marticliment.com/resources/elevenclock.png"); - byte[] HASH_2 = [0x9E, 0xB8, 0x7A, 0x5A, 0x64, 0xCA, 0x6D, 0x8D, 0x0A, 0x7B, 0x98, 0xC5, 0x4F, 0x6A, 0x58, 0x72, 0xFD, 0x94, 0xC9, 0xA6, 0x82, 0xB3, 0x2B, 0x90, 0x70, 0x66, 0x66, 0x1C, 0xBF, 0x81, 0x97, 0x97]; + byte[] HASH_2 = + [ + 0x9E, + 0xB8, + 0x7A, + 0x5A, + 0x64, + 0xCA, + 0x6D, + 0x8D, + 0x0A, + 0x7B, + 0x98, + 0xC5, + 0x4F, + 0x6A, + 0x58, + 0x72, + 0xFD, + 0x94, + 0xC9, + 0xA6, + 0x82, + 0xB3, + 0x2B, + 0x90, + 0x70, + 0x66, + 0x66, + 0x1C, + 0xBF, + 0x81, + 0x97, + 0x97, + ]; string managerName = "TestManager"; string packageId = "Package55"; string extension = ICON_1.ToString().Split(".")[^1]; - string expectedFile = Path.Join(CoreData.UniGetUICacheDirectory_Icons, managerName, packageId, $"icon.{extension}"); + string expectedFile = Path.Join( + CoreData.UniGetUICacheDirectory_Icons, + managerName, + packageId, + $"icon.{extension}" + ); if (File.Exists(expectedFile)) { File.Delete(expectedFile); @@ -67,7 +140,12 @@ public static void TestCacheEngineForPackageVersion() string PACKAGE_ID = "Package2"; string extension = URI.ToString().Split(".")[^1]; - string expectedFile = Path.Join(CoreData.UniGetUICacheDirectory_Icons, MANAGER_NAME, PACKAGE_ID, $"icon.{extension}"); + string expectedFile = Path.Join( + CoreData.UniGetUICacheDirectory_Icons, + MANAGER_NAME, + PACKAGE_ID, + $"icon.{extension}" + ); if (File.Exists(expectedFile)) { File.Delete(expectedFile); @@ -75,7 +153,12 @@ public static void TestCacheEngineForPackageVersion() // Download an icon through version verification CacheableIcon icon = new(URI, VERSION); - string? path = IconCacheEngine.GetCacheOrDownloadIcon(icon, MANAGER_NAME, PACKAGE_ID, 0); + string? path = IconCacheEngine.GetCacheOrDownloadIcon( + icon, + MANAGER_NAME, + PACKAGE_ID, + 0 + ); Assert.NotNull(path); Assert.Equal(expectedFile, path); Assert.True(File.Exists(path)); @@ -112,7 +195,12 @@ public static void TestCacheEngineForIconUri() string packageId = "Package12"; string extension = URI_1.ToString().Split(".")[^1]; - string expectedFile = Path.Join(CoreData.UniGetUICacheDirectory_Icons, managerName, packageId, $"icon.{extension}"); + string expectedFile = Path.Join( + CoreData.UniGetUICacheDirectory_Icons, + managerName, + packageId, + $"icon.{extension}" + ); if (File.Exists(expectedFile)) { File.Delete(expectedFile); @@ -160,7 +248,12 @@ public static void TestCacheEngineForPackageSize() // Clear any cache for reproducible data string extension = ICON_1.ToString().Split(".")[^1]; - string expectedFile = Path.Join(CoreData.UniGetUICacheDirectory_Icons, managerName, packageId, $"icon.{extension}"); + string expectedFile = Path.Join( + CoreData.UniGetUICacheDirectory_Icons, + managerName, + packageId, + $"icon.{extension}" + ); if (File.Exists(expectedFile)) { File.Delete(expectedFile); diff --git a/src/UniGetUI.Core.IconEngine.Tests/IconDatabaseTests.cs b/src/UniGetUI.Core.IconEngine.Tests/IconDatabaseTests.cs index ea9df05f85..0d1dfc70c3 100644 --- a/src/UniGetUI.Core.IconEngine.Tests/IconDatabaseTests.cs +++ b/src/UniGetUI.Core.IconEngine.Tests/IconDatabaseTests.cs @@ -26,7 +26,9 @@ public async Task TestGetExistingIconAndImagesAsync() string? icon = iconStore.GetIconUrlForId("__test_entry_DO_NOT_EDIT_PLEASE"); Assert.Equal("https://this.is.a.test/url/used_for/automated_unit_testing.png", icon); - string[] screenshots = iconStore.GetScreenshotsUrlForId("__test_entry_DO_NOT_EDIT_PLEASE"); + string[] screenshots = iconStore.GetScreenshotsUrlForId( + "__test_entry_DO_NOT_EDIT_PLEASE" + ); Assert.Equal(3, screenshots.Length); Assert.Equal("https://image_number.com/1.png", screenshots[0]); Assert.Equal("https://image_number.com/2.png", screenshots[1]); @@ -38,10 +40,14 @@ public async Task TestGetNonExistingIconAndImagesAsync() { await iconStore.LoadIconAndScreenshotsDatabaseAsync(); - string? nonexistent_icon = iconStore.GetIconUrlForId("__test_entry_THIS_ICON_DOES_NOT_EXTST"); + string? nonexistent_icon = iconStore.GetIconUrlForId( + "__test_entry_THIS_ICON_DOES_NOT_EXTST" + ); Assert.Null(nonexistent_icon); - string[] nonexistent_screenshots = iconStore.GetScreenshotsUrlForId("__test_entry_THIS_ICON_DOES_NOT_EXTST"); + string[] nonexistent_screenshots = iconStore.GetScreenshotsUrlForId( + "__test_entry_THIS_ICON_DOES_NOT_EXTST" + ); Assert.Empty(nonexistent_screenshots); } } diff --git a/src/UniGetUI.Core.IconEngine.Tests/UniGetUI.Core.IconEngine.Tests.csproj b/src/UniGetUI.Core.IconEngine.Tests/UniGetUI.Core.IconEngine.Tests.csproj index f523803f79..57a4effc4c 100644 --- a/src/UniGetUI.Core.IconEngine.Tests/UniGetUI.Core.IconEngine.Tests.csproj +++ b/src/UniGetUI.Core.IconEngine.Tests/UniGetUI.Core.IconEngine.Tests.csproj @@ -1,41 +1,38 @@ + + $(PortableTargetFramework) + + false + true + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + - - $(PortableTargetFramework) - - false - true - + + + - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - - - - - - - - - - + + + diff --git a/src/UniGetUI.Core.IconStore/IconCacheEngine.cs b/src/UniGetUI.Core.IconStore/IconCacheEngine.cs index 3a0c5140a4..85112ce640 100644 --- a/src/UniGetUI.Core.IconStore/IconCacheEngine.cs +++ b/src/UniGetUI.Core.IconStore/IconCacheEngine.cs @@ -13,7 +13,7 @@ public enum IconValidationMethod SHA256, FileSize, PackageVersion, - UriSource + UriSource, } public readonly struct CacheableIcon @@ -37,7 +37,8 @@ public CacheableIcon(Uri uri, byte[] Sha256) Url = uri; this.SHA256 = Sha256; ValidationMethod = IconValidationMethod.SHA256; - _hashCode = uri.ToString().GetHashCode() + Sha256[0] + Sha256[1] + Sha256[2] + Sha256[3]; + _hashCode = + uri.ToString().GetHashCode() + Sha256[0] + Sha256[1] + Sha256[2] + Sha256[3]; } /// @@ -100,21 +101,41 @@ public static class IconCacheEngine /// the Id of the package /// the Time to store the icons on the TaskRecycler cache /// A path to a local icon file - public static string? GetCacheOrDownloadIcon(CacheableIcon? icon, string ManagerName, string PackageId, int cacheInterval = 30) - => TaskRecycler.RunOrAttach(_getCacheOrDownloadIcon, icon, ManagerName, PackageId, cacheInterval); - - private static string? _getCacheOrDownloadIcon(CacheableIcon? _icon, string ManagerName, string PackageId) + public static string? GetCacheOrDownloadIcon( + CacheableIcon? icon, + string ManagerName, + string PackageId, + int cacheInterval = 30 + ) => + TaskRecycler.RunOrAttach( + _getCacheOrDownloadIcon, + icon, + ManagerName, + PackageId, + cacheInterval + ); + + private static string? _getCacheOrDownloadIcon( + CacheableIcon? _icon, + string ManagerName, + string PackageId + ) { if (_icon is null) return null; var icon = _icon.Value; - if(icon.IsLocalPath) + if (icon.IsLocalPath) return icon.LocalPath; - string iconLocation = Path.Join(CoreData.UniGetUICacheDirectory_Icons, ManagerName, PackageId); - if (!Directory.Exists(iconLocation)) Directory.CreateDirectory(iconLocation); + string iconLocation = Path.Join( + CoreData.UniGetUICacheDirectory_Icons, + ManagerName, + PackageId + ); + if (!Directory.Exists(iconLocation)) + Directory.CreateDirectory(iconLocation); string iconVersionFile = Path.Join(iconLocation, $"icon.version"); string iconUriFile = Path.Join(iconLocation, $"icon.uri"); @@ -122,8 +143,8 @@ public static class IconCacheEngine string? cachedIconFile = GetLocalCachedFile(icon, iconLocation); bool isLocalCacheValid = // Verify if the cached icon exists and is valid - cachedIconFile is not null && - icon.ValidationMethod switch + cachedIconFile is not null + && icon.ValidationMethod switch { IconValidationMethod.FileSize => ValidateByImageSize(icon, cachedIconFile), IconValidationMethod.SHA256 => ValidateBySHA256(icon, cachedIconFile), @@ -135,12 +156,16 @@ cachedIconFile is not null && // If a valid cache was found, return that cache if (isLocalCacheValid) { - Logger.Debug($"Cached icon for id={PackageId} is valid and won't be downloaded again ({icon.ValidationMethod})"); + Logger.Debug( + $"Cached icon for id={PackageId} is valid and won't be downloaded again ({icon.ValidationMethod})" + ); return cachedIconFile; } if (cachedIconFile is not null) - Logger.ImportantInfo($"Cached icon for id={PackageId} is INVALID ({icon.ValidationMethod})"); + Logger.ImportantInfo( + $"Cached icon for id={PackageId} is INVALID ({icon.ValidationMethod})" + ); return SaveIconToCacheAndGetPath(icon, iconLocation); } @@ -163,10 +188,16 @@ cachedIconFile is not null && string iconVersionFile = Path.Join(iconLocation, $"icon.version"); string iconUriFile = Path.Join(iconLocation, $"icon.uri"); - if (icon.ValidationMethod is IconValidationMethod.PackageVersion && !File.Exists(iconVersionFile)) + if ( + icon.ValidationMethod is IconValidationMethod.PackageVersion + && !File.Exists(iconVersionFile) + ) return null; // If version file does not exist and icon is versioned - if (icon.ValidationMethod is IconValidationMethod.UriSource && !File.Exists(iconUriFile)) + if ( + icon.ValidationMethod is IconValidationMethod.UriSource + && !File.Exists(iconUriFile) + ) return null; // If uri file does not exist and icon is versioned return cachedIconFile; @@ -189,14 +220,18 @@ cachedIconFile is not null && HttpResponseMessage response = client.GetAsync(icon.Url).GetAwaiter().GetResult(); if (!response.IsSuccessStatusCode) { - Logger.Warn($"Icon download attempt at {icon.Url} failed with code {response.StatusCode}"); + Logger.Warn( + $"Icon download attempt at {icon.Url} failed with code {response.StatusCode}" + ); return null; } string mimeType = response.Content.Headers.GetValues("Content-Type").First(); if (!MimeToExtension.TryGetValue(mimeType, out string? extension)) { - Logger.Warn($"Unknown mimetype {mimeType} for icon {icon.Url}, aborting download"); + Logger.Warn( + $"Unknown mimetype {mimeType} for icon {icon.Url}, aborting download" + ); return null; } @@ -228,17 +263,25 @@ cachedIconFile is not null && if (isNewCacheValid) { - if (icon.ValidationMethod is IconValidationMethod.PackageVersion or IconValidationMethod.UriSource - && new[] { "png", "webp", "tif", "avif" }.Contains(extension)) + if ( + icon.ValidationMethod + is IconValidationMethod.PackageVersion + or IconValidationMethod.UriSource + && new[] { "png", "webp", "tif", "avif" }.Contains(extension) + ) { DownsizeImage(cachedIconFile); } - Logger.Debug($"Icon for Location={iconLocation} has been downloaded and verified properly (if applicable) ({icon.ValidationMethod})"); + Logger.Debug( + $"Icon for Location={iconLocation} has been downloaded and verified properly (if applicable) ({icon.ValidationMethod})" + ); return cachedIconFile; } - Logger.Warn($"NEWLY DOWNLOADED Icon for Location={iconLocation} Uri={icon.Url} is NOT VALID and will be discarded (verification method is {icon.ValidationMethod})"); + Logger.Warn( + $"NEWLY DOWNLOADED Icon for Location={iconLocation} Uri={icon.Url} is NOT VALID and will be discarded (verification method is {icon.ValidationMethod})" + ); DeteteCachedFiles(iconLocation); return null; } @@ -266,25 +309,32 @@ private static void DownsizeImage(string cachedIconFile) if (width > MAX_SIDE || height > MAX_SIDE) { File.Move(cachedIconFile, $"{cachedIconFile}.copy"); - var image = MagicImageProcessor.BuildPipeline($"{cachedIconFile}.copy", new ProcessImageSettings - { - Width = MAX_SIDE, - Height = MAX_SIDE, - ResizeMode = CropScaleMode.Contain, - }); + var image = MagicImageProcessor.BuildPipeline( + $"{cachedIconFile}.copy", + new ProcessImageSettings + { + Width = MAX_SIDE, + Height = MAX_SIDE, + ResizeMode = CropScaleMode.Contain, + } + ); // Apply changes and save the image to disk using (FileStream fileStream = File.Create(cachedIconFile)) { image.WriteOutput(fileStream); } - Logger.Debug($"File {cachedIconFile} was downsized from {width}x{height} to {image.Settings.Width}x{image.Settings.Height}"); + Logger.Debug( + $"File {cachedIconFile} was downsized from {width}x{height} to {image.Settings.Width}x{image.Settings.Height}" + ); image.Dispose(); File.Delete($"{cachedIconFile}.copy"); } else { - Logger.Debug($"File {cachedIconFile} had an already appropiate size of {width}x{height}"); + Logger.Debug( + $"File {cachedIconFile} had an already appropiate size of {width}x{height}" + ); } } catch (Exception ex) @@ -306,7 +356,9 @@ private static bool ValidateByImageSize(CacheableIcon icon, string cachedIconPat } catch (Exception e) { - Logger.Warn($"Failed to verify icon file size for {icon.Url} via FileSize with error {e.Message}"); + Logger.Warn( + $"Failed to verify icon file size for {icon.Url} via FileSize with error {e.Message}" + ); return false; } } @@ -324,7 +376,9 @@ private static bool ValidateBySHA256(CacheableIcon icon, string cachedIconPath) } catch (Exception e) { - Logger.Warn($"Failed to verify icon file size for {icon.Url} via Sha256 with error {e.Message}"); + Logger.Warn( + $"Failed to verify icon file size for {icon.Url} via Sha256 with error {e.Message}" + ); return false; } } @@ -336,11 +390,15 @@ private static bool ValidateByVersion(CacheableIcon icon, string versionPath) { try { - return File.Exists(versionPath) && CoreTools.VersionStringToStruct(File.ReadAllText(versionPath)) >= CoreTools.VersionStringToStruct(icon.Version); + return File.Exists(versionPath) + && CoreTools.VersionStringToStruct(File.ReadAllText(versionPath)) + >= CoreTools.VersionStringToStruct(icon.Version); } catch (Exception e) { - Logger.Warn($"Failed to verify icon file size for {icon.Url} via PackageVersion with error {e.Message}"); + Logger.Warn( + $"Failed to verify icon file size for {icon.Url} via PackageVersion with error {e.Message}" + ); return false; } } @@ -356,7 +414,9 @@ private static bool ValidateByUri(CacheableIcon icon, string uriPath) } catch (Exception e) { - Logger.Warn($"Failed to verify icon file size for {icon.Url} via UriSource with error {e.Message}"); + Logger.Warn( + $"Failed to verify icon file size for {icon.Url} via UriSource with error {e.Message}" + ); return false; } } @@ -379,32 +439,38 @@ private static void DeteteCachedFiles(string iconLocation) } } - public static readonly ReadOnlyDictionary MimeToExtension = new ReadOnlyDictionary(new Dictionary - { - {"image/avif", "avif"}, - {"image/gif", "gif"}, - // {"image/bmp", "bmp"}, Should non-transparent types be allowed? - // {"image/jpeg", "jpg"}, - {"image/png", "png"}, - {"image/webp", "webp"}, - {"image/svg+xml", "svg"}, - {"image/vnd.microsoft.icon", "ico"}, - {"application/octet-stream", "ico"}, - {"image/image/x-icon", "ico"}, - {"image/tiff", "tif"}, - }); - - public static readonly ReadOnlyDictionary ExtensionToMime = new ReadOnlyDictionary(new Dictionary - { - {"avif", "image/avif"}, - {"gif", "image/gif"}, - // {"bmp", "image/bmp"}, Should non-transparent types be allowed - // {"jpg", "image/jpeg"}, - {"png", "image/png"}, - {"webp", "image/webp"}, - {"svg", "image/svg+xml"}, - {"ico", "image/image/x-icon"}, - {"tif", "image/tiff"}, - }); + public static readonly ReadOnlyDictionary MimeToExtension = + new ReadOnlyDictionary( + new Dictionary + { + { "image/avif", "avif" }, + { "image/gif", "gif" }, + // {"image/bmp", "bmp"}, Should non-transparent types be allowed? + // {"image/jpeg", "jpg"}, + { "image/png", "png" }, + { "image/webp", "webp" }, + { "image/svg+xml", "svg" }, + { "image/vnd.microsoft.icon", "ico" }, + { "application/octet-stream", "ico" }, + { "image/image/x-icon", "ico" }, + { "image/tiff", "tif" }, + } + ); + + public static readonly ReadOnlyDictionary ExtensionToMime = + new ReadOnlyDictionary( + new Dictionary + { + { "avif", "image/avif" }, + { "gif", "image/gif" }, + // {"bmp", "image/bmp"}, Should non-transparent types be allowed + // {"jpg", "image/jpeg"}, + { "png", "image/png" }, + { "webp", "image/webp" }, + { "svg", "image/svg+xml" }, + { "ico", "image/image/x-icon" }, + { "tif", "image/tiff" }, + } + ); } } diff --git a/src/UniGetUI.Core.IconStore/IconDatabase.cs b/src/UniGetUI.Core.IconStore/IconDatabase.cs index e18fb4b6c0..7a28119c0d 100644 --- a/src/UniGetUI.Core.IconStore/IconDatabase.cs +++ b/src/UniGetUI.Core.IconStore/IconDatabase.cs @@ -16,6 +16,7 @@ public struct IconCount public int PackagesWithIconCount = 0; public int TotalScreenshotCount = 0; public int PackagesWithScreenshotCount = 0; + public IconCount() { } } @@ -28,7 +29,10 @@ public static IconDatabase Instance /// /// The icon and screenshot database /// - private Dictionary IconDatabaseData = []; + private Dictionary< + string, + IconScreenshotDatabase_v2.PackageIconAndScreenshots + > IconDatabaseData = []; private IconCount __icon_count = new(); /// @@ -38,10 +42,13 @@ public async Task LoadIconAndScreenshotsDatabaseAsync() { try { - string IconsAndScreenshotsFile = Path.Join(CoreData.UniGetUICacheDirectory_Data, "Icon Database.json"); - Uri DownloadUrl = - new( - "https://github.com/Devolutions/UniGetUI/raw/refs/heads/main/WebBasedData/screenshot-database-v2.json"); + string IconsAndScreenshotsFile = Path.Join( + CoreData.UniGetUICacheDirectory_Data, + "Icon Database.json" + ); + Uri DownloadUrl = new( + "https://github.com/Devolutions/UniGetUI/raw/refs/heads/main/WebBasedData/screenshot-database-v2.json" + ); if (Settings.Get(Settings.K.IconDataBaseURL)) { DownloadUrl = new Uri(Settings.GetValue(Settings.K.IconDataBaseURL)); @@ -76,11 +83,15 @@ public async Task LoadFromCacheAsync() { try { - string IconsAndScreenshotsFile = Path.Join(CoreData.UniGetUICacheDirectory_Data, "Icon Database.json"); - IconScreenshotDatabase_v2 JsonData = JsonSerializer.Deserialize( - await File.ReadAllTextAsync(IconsAndScreenshotsFile), - SerializationHelpers.DefaultOptions + string IconsAndScreenshotsFile = Path.Join( + CoreData.UniGetUICacheDirectory_Data, + "Icon Database.json" ); + IconScreenshotDatabase_v2 JsonData = + JsonSerializer.Deserialize( + await File.ReadAllTextAsync(IconsAndScreenshotsFile), + SerializationHelpers.DefaultOptions + ); if (JsonData.icons_and_screenshots is not null) { IconDatabaseData = JsonData.icons_and_screenshots; @@ -119,6 +130,5 @@ public IconCount GetIconCount() { return __icon_count; } - } } diff --git a/src/UniGetUI.Core.IconStore/Serializable.cs b/src/UniGetUI.Core.IconStore/Serializable.cs index 543fa263ce..a7acac1272 100644 --- a/src/UniGetUI.Core.IconStore/Serializable.cs +++ b/src/UniGetUI.Core.IconStore/Serializable.cs @@ -1,4 +1,4 @@ -namespace UniGetUI.Core.IconEngine +namespace UniGetUI.Core.IconEngine { internal struct IconScreenshotDatabase_v2 { @@ -10,6 +10,7 @@ public struct PackageCount public int packages_with_screenshot { get; set; } public int total_screenshots { get; set; } } + public struct PackageIconAndScreenshots { public string icon { get; set; } diff --git a/src/UniGetUI.Core.IconStore/UniGetUI.Core.IconEngine.csproj b/src/UniGetUI.Core.IconStore/UniGetUI.Core.IconEngine.csproj index e8ce530823..c360acdcb6 100644 --- a/src/UniGetUI.Core.IconStore/UniGetUI.Core.IconEngine.csproj +++ b/src/UniGetUI.Core.IconStore/UniGetUI.Core.IconEngine.csproj @@ -1,18 +1,20 @@ + + $(SharedTargetFrameworks) + - - - - - + + + + + - - - - - - + + + - + + + diff --git a/src/UniGetUI.Core.Language.Tests/LanguageDataTests.cs b/src/UniGetUI.Core.Language.Tests/LanguageDataTests.cs index 11e758dd28..3fefaa371e 100644 --- a/src/UniGetUI.Core.Language.Tests/LanguageDataTests.cs +++ b/src/UniGetUI.Core.Language.Tests/LanguageDataTests.cs @@ -11,13 +11,11 @@ public class LanguageDataTests LanguageData.LanguageReference.Select(x => new object[] { x.Key, x.Value }).ToArray(); [Fact] - public void TranslatorsListNotEmptyTest() - => Assert.NotEmpty(LanguageData.TranslatorsList); + public void TranslatorsListNotEmptyTest() => Assert.NotEmpty(LanguageData.TranslatorsList); [Theory] [MemberData(nameof(Translators))] - public void TranslatorsListTest(Person translator) - => Assert.NotEmpty(translator.Name); + public void TranslatorsListTest(Person translator) => Assert.NotEmpty(translator.Name); [Fact] public void LanguageReferenceNotEmptyTest() @@ -29,17 +27,27 @@ public void LanguageReferenceNotEmptyTest() [MemberData(nameof(LanguageReferences))] public void LanguageReferenceTest(string key, string value) { - Assert.False(value.Contains("NoNameLang_"), $"The language with key {key} has no assigned name"); + Assert.False( + value.Contains("NoNameLang_"), + $"The language with key {key} has no assigned name" + ); } [Fact] public void TranslatedPercentageNotEmptyTests() { - System.Collections.ObjectModel.ReadOnlyDictionary TranslatedPercent = LanguageData.TranslationPercentages; + System.Collections.ObjectModel.ReadOnlyDictionary TranslatedPercent = + LanguageData.TranslationPercentages; foreach (string key in TranslatedPercent.Keys) { - Assert.True(LanguageData.LanguageReference.ContainsKey(key), $"The language key {key} was not found on LanguageReference"); - Assert.False(LanguageData.TranslationPercentages[key].Contains("404%"), $"Somehow the key {key} has no value"); + Assert.True( + LanguageData.LanguageReference.ContainsKey(key), + $"The language key {key} was not found on LanguageReference" + ); + Assert.False( + LanguageData.TranslationPercentages[key].Contains("404%"), + $"Somehow the key {key} has no value" + ); } } } diff --git a/src/UniGetUI.Core.Language.Tests/LanguageEngineTests.cs b/src/UniGetUI.Core.Language.Tests/LanguageEngineTests.cs index 317a3ee171..059cc0b0b5 100644 --- a/src/UniGetUI.Core.Language.Tests/LanguageEngineTests.cs +++ b/src/UniGetUI.Core.Language.Tests/LanguageEngineTests.cs @@ -30,7 +30,11 @@ public void TestLoadingLanguageForNonExistentKey() [Theory] [InlineData("en", "UniGetUI Log", "UniGetUI (formerly WingetUI)")] [InlineData("ca", "Registre de l'UniGetUI", "UniGetUI (abans WingetUI)")] - public void TestUniGetUIRefactoring(string language, string uniGetUILogTranslation, string uniGetUITranslation) + public void TestUniGetUIRefactoring( + string language, + string uniGetUILogTranslation, + string uniGetUITranslation + ) { LanguageEngine engine = new(); @@ -56,8 +60,14 @@ public void TestStaticallyLoadedLanguages() Assert.Equal("Usuari | Local", CommonTranslations.ScopeNames[PackageScope.Local]); Assert.Equal("Màquina | Global", CommonTranslations.ScopeNames[PackageScope.Global]); - Assert.Equal(PackageScope.Global, CommonTranslations.InvertedScopeNames["Màquina | Global"]); - Assert.Equal(PackageScope.Local, CommonTranslations.InvertedScopeNames["Usuari | Local"]); + Assert.Equal( + PackageScope.Global, + CommonTranslations.InvertedScopeNames["Màquina | Global"] + ); + Assert.Equal( + PackageScope.Local, + CommonTranslations.InvertedScopeNames["Usuari | Local"] + ); } /* diff --git a/src/UniGetUI.Core.Language.Tests/UniGetUI.Core.LanguageEngine.Tests.csproj b/src/UniGetUI.Core.Language.Tests/UniGetUI.Core.LanguageEngine.Tests.csproj index 1c2e54bab6..8682af74cf 100644 --- a/src/UniGetUI.Core.Language.Tests/UniGetUI.Core.LanguageEngine.Tests.csproj +++ b/src/UniGetUI.Core.Language.Tests/UniGetUI.Core.LanguageEngine.Tests.csproj @@ -1,40 +1,37 @@ + + $(PortableTargetFramework) + + false + true + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + - - $(PortableTargetFramework) - - false - true - + + + - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - - - - - - - - - - + + + diff --git a/src/UniGetUI.Core.LanguageEngine/LanguageData.cs b/src/UniGetUI.Core.LanguageEngine/LanguageData.cs index 07e6d10cc6..90542c8789 100644 --- a/src/UniGetUI.Core.LanguageEngine/LanguageData.cs +++ b/src/UniGetUI.Core.LanguageEngine/LanguageData.cs @@ -54,10 +54,25 @@ public static ReadOnlyDictionary TranslationPercentages private static ReadOnlyDictionary LoadTranslationPercentages() { - try { - if (JsonNode.Parse(File.ReadAllText(Path.Join(CoreData.UniGetUIExecutableDirectory, "Assets", "Data", "TranslatedPercentages.json"))) is JsonObject val) + try + { + if ( + JsonNode.Parse( + File.ReadAllText( + Path.Join( + CoreData.UniGetUIExecutableDirectory, + "Assets", + "Data", + "TranslatedPercentages.json" + ) + ) + ) + is JsonObject val + ) { - return new(val.ToDictionary(x => x.Key, x => (x.Value ?? ("404%" + x.Key)).ToString())); + return new( + val.ToDictionary(x => x.Key, x => (x.Value ?? ("404%" + x.Key)).ToString()) + ); } return new(new Dictionary()); @@ -74,10 +89,26 @@ private static ReadOnlyDictionary LoadLanguageReference() { try { - if (JsonNode.Parse(File.ReadAllText(Path.Join(CoreData.UniGetUIExecutableDirectory, "Assets", "Data", - "LanguagesReference.json"))) is JsonObject val) + if ( + JsonNode.Parse( + File.ReadAllText( + Path.Join( + CoreData.UniGetUIExecutableDirectory, + "Assets", + "Data", + "LanguagesReference.json" + ) + ) + ) + is JsonObject val + ) { - return new(val.ToDictionary(x => x.Key, x => (x.Value ?? ("NoNameLang_" + x.Key)).ToString())); + return new( + val.ToDictionary( + x => x.Key, + x => (x.Value ?? ("NoNameLang_" + x.Key)).ToString() + ) + ); } return new(new Dictionary()); @@ -94,8 +125,14 @@ private static Person[] LoadLanguageTranslatorList() { try { - string JsonContents = File.ReadAllText(Path.Join(CoreData.UniGetUIExecutableDirectory, "Assets", "Data", - "Translators.json")); + string JsonContents = File.ReadAllText( + Path.Join( + CoreData.UniGetUIExecutableDirectory, + "Assets", + "Data", + "Translators.json" + ) + ); if (JsonNode.Parse(JsonContents) is not JsonObject TranslatorsInfo) { @@ -107,7 +144,9 @@ private static Person[] LoadLanguageTranslatorList() { if (!LanguageReference.ContainsKey(langKey.Key)) { - Logger.Warn($"Language {langKey.Key} not in list, maybe has not been added yet?"); + Logger.Warn( + $"Language {langKey.Key} not in list, maybe has not been added yet?" + ); continue; } @@ -127,8 +166,11 @@ private static Person[] LoadLanguageTranslatorList() } Person person = new( - Name: (url is not null ? "@" : "") + (translator["name"] ?? "").ToString(), - ProfilePicture: url is not null ? new Uri(url.ToString() + ".png") : null, + Name: (url is not null ? "@" : "") + + (translator["name"] ?? "").ToString(), + ProfilePicture: url is not null + ? new Uri(url.ToString() + ".png") + : null, GitHubUrl: url, Language: !LangShown ? LanguageReference[langKey.Key] : "" ); @@ -163,4 +205,3 @@ public static class CommonTranslations }; } } - diff --git a/src/UniGetUI.Core.LanguageEngine/LanguageEngine.cs b/src/UniGetUI.Core.LanguageEngine/LanguageEngine.cs index fba0fa5c36..1459d4f90d 100644 --- a/src/UniGetUI.Core.LanguageEngine/LanguageEngine.cs +++ b/src/UniGetUI.Core.LanguageEngine/LanguageEngine.cs @@ -65,33 +65,52 @@ public Dictionary LoadLanguageFile(string LangKey) { try { - - string BundledLangFileToLoad = Path.Join(CoreData.UniGetUIExecutableDirectory, "Assets", "Languages", "lang_" + LangKey + ".json"); + string BundledLangFileToLoad = Path.Join( + CoreData.UniGetUIExecutableDirectory, + "Assets", + "Languages", + "lang_" + LangKey + ".json" + ); JsonObject BundledContents = []; if (!File.Exists(BundledLangFileToLoad)) { - Logger.Error($"Tried to access a non-existing bundled language file! file={BundledLangFileToLoad}"); + Logger.Error( + $"Tried to access a non-existing bundled language file! file={BundledLangFileToLoad}" + ); } else { try { - if (JsonNode.Parse(File.ReadAllText(BundledLangFileToLoad)) is JsonObject parsedObject) + if ( + JsonNode.Parse(File.ReadAllText(BundledLangFileToLoad)) + is JsonObject parsedObject + ) BundledContents = parsedObject; else - throw new ArgumentException($"parsedObject was null for lang file {BundledLangFileToLoad}"); + throw new ArgumentException( + $"parsedObject was null for lang file {BundledLangFileToLoad}" + ); } catch (Exception ex) { - Logger.Warn($"Something went wrong when parsing language file {BundledLangFileToLoad}"); + Logger.Warn( + $"Something went wrong when parsing language file {BundledLangFileToLoad}" + ); Logger.Warn(ex); } } - Dictionary LangDict = BundledContents.ToDictionary(x => x.Key, x => x.Value?.ToString() ?? ""); + Dictionary LangDict = BundledContents.ToDictionary( + x => x.Key, + x => x.Value?.ToString() ?? "" + ); - string CachedLangFileToLoad = Path.Join(CoreData.UniGetUICacheDirectory_Lang, "lang_" + LangKey + ".json"); + string CachedLangFileToLoad = Path.Join( + CoreData.UniGetUICacheDirectory_Lang, + "lang_" + LangKey + ".json" + ); if (Settings.Get(Settings.K.DisableLangAutoUpdater)) { @@ -99,23 +118,34 @@ public Dictionary LoadLanguageFile(string LangKey) } else if (!File.Exists(CachedLangFileToLoad)) { - Logger.Warn($"Tried to access a non-existing cached language file! file={CachedLangFileToLoad}"); + Logger.Warn( + $"Tried to access a non-existing cached language file! file={CachedLangFileToLoad}" + ); } else { try { - if (JsonNode.Parse(File.ReadAllText(CachedLangFileToLoad)) is JsonObject parsedObject) - foreach (var keyval in parsedObject.ToDictionary(x => x.Key, x => x.Value)) + if ( + JsonNode.Parse(File.ReadAllText(CachedLangFileToLoad)) + is JsonObject parsedObject + ) + foreach ( + var keyval in parsedObject.ToDictionary(x => x.Key, x => x.Value) + ) { LangDict[keyval.Key] = keyval.Value?.ToString() ?? ""; } else - throw new ArgumentException($"parsedObject was null for lang file {CachedLangFileToLoad}"); + throw new ArgumentException( + $"parsedObject was null for lang file {CachedLangFileToLoad}" + ); } catch (Exception ex) { - Logger.Warn($"Something went wrong when parsing language file {BundledLangFileToLoad}"); + Logger.Warn( + $"Something went wrong when parsing language file {BundledLangFileToLoad}" + ); Logger.Warn(ex); } } @@ -141,7 +171,11 @@ public async Task DownloadUpdatedLanguageFile(string LangKey) { try { - Uri NewFile = new("https://raw.githubusercontent.com/Devolutions/UniGetUI/main/src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_" + LangKey + ".json"); + Uri NewFile = new( + "https://raw.githubusercontent.com/Devolutions/UniGetUI/main/src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_" + + LangKey + + ".json" + ); HttpClient client = new(); client.DefaultRequestHeaders.UserAgent.ParseAdd(CoreData.UserAgentString); @@ -152,7 +186,10 @@ public async Task DownloadUpdatedLanguageFile(string LangKey) Directory.CreateDirectory(CoreData.UniGetUICacheDirectory_Lang); } - File.WriteAllText(Path.Join(CoreData.UniGetUICacheDirectory_Lang, "lang_" + LangKey + ".json"), fileContents); + File.WriteAllText( + Path.Join(CoreData.UniGetUICacheDirectory_Lang, "lang_" + LangKey + ".json"), + fileContents + ); Logger.ImportantInfo("Lang files were updated successfully from GitHub"); } @@ -169,15 +206,24 @@ public void LoadStaticTranslation() CommonTranslations.ScopeNames[PackageScope.Global] = Translate("Machine | Global"); CommonTranslations.InvertedScopeNames.Clear(); - CommonTranslations.InvertedScopeNames.Add(Translate("Machine | Global"), PackageScope.Global); - CommonTranslations.InvertedScopeNames.Add(Translate("User | Local"), PackageScope.Local); + CommonTranslations.InvertedScopeNames.Add( + Translate("Machine | Global"), + PackageScope.Global + ); + CommonTranslations.InvertedScopeNames.Add( + Translate("User | Local"), + PackageScope.Local + ); } public string Translate(string key) { if (key == "WingetUI") { - if (MainLangDict.TryGetValue("formerly WingetUI", out var formerly) && formerly != "") + if ( + MainLangDict.TryGetValue("formerly WingetUI", out var formerly) + && formerly != "" + ) { return "UniGetUI (" + formerly + ")"; } diff --git a/src/UniGetUI.Core.LanguageEngine/UniGetUI.Core.LanguageEngine.csproj b/src/UniGetUI.Core.LanguageEngine/UniGetUI.Core.LanguageEngine.csproj index 10d2b3bee6..314633789a 100644 --- a/src/UniGetUI.Core.LanguageEngine/UniGetUI.Core.LanguageEngine.csproj +++ b/src/UniGetUI.Core.LanguageEngine/UniGetUI.Core.LanguageEngine.csproj @@ -1,82 +1,85 @@ + + $(SharedTargetFrameworks) + - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + - - - - - - - + + + + + + + - - - + + + diff --git a/src/UniGetUI.Core.Logger/LogEntry.cs b/src/UniGetUI.Core.Logger/LogEntry.cs index dc7f10704b..0686e6aee5 100644 --- a/src/UniGetUI.Core.Logger/LogEntry.cs +++ b/src/UniGetUI.Core.Logger/LogEntry.cs @@ -21,6 +21,5 @@ public LogEntry(string content, SeverityLevel severity) Content = content; Severity = severity; } - } } diff --git a/src/UniGetUI.Core.Logger/Logger.cs b/src/UniGetUI.Core.Logger/Logger.cs index a6a40a34ea..19a817e82d 100644 --- a/src/UniGetUI.Core.Logger/Logger.cs +++ b/src/UniGetUI.Core.Logger/Logger.cs @@ -7,62 +7,92 @@ public static class Logger private static readonly List LogContents = []; // String parameter log functions - public static void ImportantInfo(string s, [System.Runtime.CompilerServices.CallerMemberName] string caller = "") + public static void ImportantInfo( + string s, + [System.Runtime.CompilerServices.CallerMemberName] string caller = "" + ) { Diagnostics.Debug.WriteLine($"[{caller}] " + s); LogContents.Add(new LogEntry(s, LogEntry.SeverityLevel.Success)); } - public static void Debug(string s, [System.Runtime.CompilerServices.CallerMemberName] string caller = "") + public static void Debug( + string s, + [System.Runtime.CompilerServices.CallerMemberName] string caller = "" + ) { Diagnostics.Debug.WriteLine($"[{caller}] " + s); LogContents.Add(new LogEntry(s, LogEntry.SeverityLevel.Debug)); } - public static void Info(string s, [System.Runtime.CompilerServices.CallerMemberName] string caller = "") + public static void Info( + string s, + [System.Runtime.CompilerServices.CallerMemberName] string caller = "" + ) { Diagnostics.Debug.WriteLine($"[{caller}] " + s); LogContents.Add(new LogEntry(s, LogEntry.SeverityLevel.Info)); } - public static void Warn(string s, [System.Runtime.CompilerServices.CallerMemberName] string caller = "") + public static void Warn( + string s, + [System.Runtime.CompilerServices.CallerMemberName] string caller = "" + ) { Diagnostics.Debug.WriteLine($"[{caller}] " + s); LogContents.Add(new LogEntry(s, LogEntry.SeverityLevel.Warning)); } - public static void Error(string s, [System.Runtime.CompilerServices.CallerMemberName] string caller = "") + public static void Error( + string s, + [System.Runtime.CompilerServices.CallerMemberName] string caller = "" + ) { Diagnostics.Debug.WriteLine($"[{caller}] " + s); LogContents.Add(new LogEntry(s, LogEntry.SeverityLevel.Error)); } // Exception parameter log functions - public static void ImportantInfo(Exception e, [System.Runtime.CompilerServices.CallerMemberName] string caller = "") + public static void ImportantInfo( + Exception e, + [System.Runtime.CompilerServices.CallerMemberName] string caller = "" + ) { Diagnostics.Debug.WriteLine($"[{caller}] " + e.ToString()); LogContents.Add(new LogEntry(e.ToString(), LogEntry.SeverityLevel.Success)); } - public static void Debug(Exception e, [System.Runtime.CompilerServices.CallerMemberName] string caller = "") + public static void Debug( + Exception e, + [System.Runtime.CompilerServices.CallerMemberName] string caller = "" + ) { Diagnostics.Debug.WriteLine($"[{caller}] " + e.ToString()); LogContents.Add(new LogEntry(e.ToString(), LogEntry.SeverityLevel.Debug)); } - public static void Info(Exception e, [System.Runtime.CompilerServices.CallerMemberName] string caller = "") + public static void Info( + Exception e, + [System.Runtime.CompilerServices.CallerMemberName] string caller = "" + ) { Diagnostics.Debug.WriteLine($"[{caller}] " + e.ToString()); LogContents.Add(new LogEntry(e.ToString(), LogEntry.SeverityLevel.Info)); } - public static void Warn(Exception e, [System.Runtime.CompilerServices.CallerMemberName] string caller = "") + public static void Warn( + Exception e, + [System.Runtime.CompilerServices.CallerMemberName] string caller = "" + ) { Diagnostics.Debug.WriteLine($"[{caller}] " + e.ToString()); LogContents.Add(new LogEntry(e.ToString(), LogEntry.SeverityLevel.Warning)); } - public static void Error(Exception e, [System.Runtime.CompilerServices.CallerMemberName] string caller = "") + public static void Error( + Exception e, + [System.Runtime.CompilerServices.CallerMemberName] string caller = "" + ) { Diagnostics.Debug.WriteLine($"[{caller}] " + e.ToString()); LogContents.Add(new LogEntry(e.ToString(), LogEntry.SeverityLevel.Error)); diff --git a/src/UniGetUI.Core.Logger/UniGetUI.Core.Logging.csproj b/src/UniGetUI.Core.Logger/UniGetUI.Core.Logging.csproj index 6c35193aa1..3b1ea6e421 100644 --- a/src/UniGetUI.Core.Logger/UniGetUI.Core.Logging.csproj +++ b/src/UniGetUI.Core.Logger/UniGetUI.Core.Logging.csproj @@ -1,6 +1,9 @@ + + $(SharedTargetFrameworks) + - - - + + + diff --git a/src/UniGetUI.Core.Logging.Tests/LogEntryTests.cs b/src/UniGetUI.Core.Logging.Tests/LogEntryTests.cs index 568f12031d..d04bc0f740 100644 --- a/src/UniGetUI.Core.Logging.Tests/LogEntryTests.cs +++ b/src/UniGetUI.Core.Logging.Tests/LogEntryTests.cs @@ -34,4 +34,4 @@ public async Task TestLogEntry() Assert.True(logEntry2.Time < logEntry3.Time); } } -} \ No newline at end of file +} diff --git a/src/UniGetUI.Core.Logging.Tests/UniGetUI.Core.Logging.Tests.csproj b/src/UniGetUI.Core.Logging.Tests/UniGetUI.Core.Logging.Tests.csproj index 1955578c9a..2a8cccea10 100644 --- a/src/UniGetUI.Core.Logging.Tests/UniGetUI.Core.Logging.Tests.csproj +++ b/src/UniGetUI.Core.Logging.Tests/UniGetUI.Core.Logging.Tests.csproj @@ -1,40 +1,37 @@ + + $(PortableTargetFramework) + + false + true + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + - - $(PortableTargetFramework) - - false - true - + + + - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - - - - - - - - - - + + + diff --git a/src/UniGetUI.Core.SecureSettings/SecureGHTokenManager.cs b/src/UniGetUI.Core.SecureSettings/SecureGHTokenManager.cs index ebb6d1beb7..1970bbbfee 100644 --- a/src/UniGetUI.Core.SecureSettings/SecureGHTokenManager.cs +++ b/src/UniGetUI.Core.SecureSettings/SecureGHTokenManager.cs @@ -26,7 +26,9 @@ public static void StoreToken(string token) } catch (Exception ex) { - Logger.Error("An error occurred while attempting to delete the currently stored GitHub Token"); + Logger.Error( + "An error occurred while attempting to delete the currently stored GitHub Token" + ); Logger.Error(ex); } } @@ -60,7 +62,9 @@ public static void DeleteToken() } catch (Exception ex) { - Logger.Error("An error occurred while attempting to delete the currently stored GitHub Token"); + Logger.Error( + "An error occurred while attempting to delete the currently stored GitHub Token" + ); Logger.Error(ex); } } diff --git a/src/UniGetUI.Core.SecureSettings/SecureSettings.cs b/src/UniGetUI.Core.SecureSettings/SecureSettings.cs index 240211119f..b5063de47c 100644 --- a/src/UniGetUI.Core.SecureSettings/SecureSettings.cs +++ b/src/UniGetUI.Core.SecureSettings/SecureSettings.cs @@ -15,7 +15,7 @@ public enum K AllowImportPrePostOpCommands, ForceUserGSudo, AllowCustomManagerPaths, - Unset + Unset, }; public static string ResolveKey(K key) @@ -30,7 +30,9 @@ public static string ResolveKey(K key) K.AllowCustomManagerPaths => "AllowCustomManagerPaths", K.Unset => throw new InvalidDataException("SecureSettings key was unset!"), - _ => throw new KeyNotFoundException($"The SecureSettings key {key} was not found on the ResolveKey map") + _ => throw new KeyNotFoundException( + $"The SecureSettings key {key} was not found on the ResolveKey map" + ), }; } @@ -87,10 +89,10 @@ public static async Task TrySet(K key, bool enabled) Verb = "runas", ArgumentList = { - enabled? Args.ENABLE_FOR_USER: Args.DISABLE_FOR_USER, + enabled ? Args.ENABLE_FOR_USER : Args.DISABLE_FOR_USER, purifiedUser, - purifiedSetting - } + purifiedSetting, + }, }; p.Start(); @@ -140,7 +142,11 @@ private static string GetSecureSettingsRoot() { if (OperatingSystem.IsWindows()) { - return Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "UniGetUI", "SecureSettings"); + return Path.Join( + Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), + "UniGetUI", + "SecureSettings" + ); } return Path.Join(CoreData.UniGetUIDataDirectory, "SecureSettings"); diff --git a/src/UniGetUI.Core.SecureSettings/UniGetUI.Core.SecureSettings.csproj b/src/UniGetUI.Core.SecureSettings/UniGetUI.Core.SecureSettings.csproj index f5614d0e25..5d077fcf5d 100644 --- a/src/UniGetUI.Core.SecureSettings/UniGetUI.Core.SecureSettings.csproj +++ b/src/UniGetUI.Core.SecureSettings/UniGetUI.Core.SecureSettings.csproj @@ -1,4 +1,8 @@ + + $(SharedTargetFrameworks) + + diff --git a/src/UniGetUI.Core.Settings.Tests/SettingsTest.cs b/src/UniGetUI.Core.Settings.Tests/SettingsTest.cs index f568c5da00..6ca45f8ebe 100644 --- a/src/UniGetUI.Core.Settings.Tests/SettingsTest.cs +++ b/src/UniGetUI.Core.Settings.Tests/SettingsTest.cs @@ -3,16 +3,27 @@ namespace UniGetUI.Core.SettingsEngine.Tests { - public sealed class SerializableTestSub { - public SerializableTestSub(string s, int c) { sub = s; count = c; } + public SerializableTestSub(string s, int c) + { + sub = s; + count = c; + } + public string sub { get; set; } public int count { get; set; } } + public sealed class SerializableTest { - public SerializableTest(string t, int c, SerializableTestSub s) { title = t; count = c; sub = s; } + public SerializableTest(string t, int c, SerializableTestSub s) + { + title = t; + count = c; + sub = s; + } + public string title { get; set; } public int count { get; set; } public SerializableTestSub sub { get; set; } @@ -47,8 +58,11 @@ public void Dispose() Directory.Delete(_testRoot, true); } - private string GetNewSettingPath(string fileName) => Path.Combine(_newConfigurationDirectory, fileName); - private string GetOldSettingsPath(string fileName) => Path.Combine(_oldConfigurationDirectory, fileName); + private string GetNewSettingPath(string fileName) => + Path.Combine(_newConfigurationDirectory, fileName); + + private string GetOldSettingsPath(string fileName) => + Path.Combine(_oldConfigurationDirectory, fileName); [Fact] public void TestSettingsSaveToNewDirectory() @@ -90,63 +104,139 @@ public void TestBooleanSettings(Settings.K key, bool st1, bool st2, bool st3, bo string sName = Settings.ResolveKey(key); Settings.Set(key, st1); Assert.Equal(st1, Settings.Get(key)); - Assert.Equal(st1, File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, sName))); + Assert.Equal( + st1, + File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, sName)) + ); Settings.Set(key, st2); Assert.Equal(st2, Settings.Get(key)); - Assert.Equal(st2, File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, sName))); + Assert.Equal( + st2, + File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, sName)) + ); Settings.Set(key, st3); Assert.Equal(st3, Settings.Get(key)); - Assert.Equal(st3, File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, sName))); + Assert.Equal( + st3, + File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, sName)) + ); Settings.Set(key, st4); Assert.Equal(st4, Settings.Get(key)); - Assert.Equal(st4, File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, sName))); + Assert.Equal( + st4, + File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, sName)) + ); Settings.Set(key, false); // Cleanup Assert.False(Settings.Get(key)); - Assert.False(File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, sName))); + Assert.False( + File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, sName)) + ); } [Theory] - [InlineData(Settings.K.Test1, "RandomFirstValue", "RandomSecondValue", "", "RandomThirdValue")] + [InlineData( + Settings.K.Test1, + "RandomFirstValue", + "RandomSecondValue", + "", + "RandomThirdValue" + )] [InlineData(Settings.K.Test2, "", "", "", "RandomThirdValue")] [InlineData(Settings.K.Test3, "RandomFirstValue", " ", "\t", "RandomThirdValue")] [InlineData(Settings.K.Test4, "RandomFirstValue", "", "", "")] [InlineData(Settings.K.Test5, "\x00\x01\x02\u0003", "", "", "RandomThirdValue")] - public void TestValueSettings(Settings.K key, string st1, string st2, string st3, string st4) + public void TestValueSettings( + Settings.K key, + string st1, + string st2, + string st3, + string st4 + ) { string sName = Settings.ResolveKey(key); Settings.SetValue(key, st1); Assert.Equal(st1, Settings.GetValue(key)); - Assert.Equal(st1 != "", File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, sName))); + Assert.Equal( + st1 != "", + File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, sName)) + ); Settings.SetValue(key, st2); Assert.Equal(st2, Settings.GetValue(key)); - Assert.Equal(st2 != "", File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, sName))); + Assert.Equal( + st2 != "", + File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, sName)) + ); Settings.SetValue(key, st3); Assert.Equal(st3, Settings.GetValue(key)); - Assert.Equal(st3 != "", File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, sName))); + Assert.Equal( + st3 != "", + File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, sName)) + ); Settings.SetValue(key, st4); Assert.Equal(st4, Settings.GetValue(key)); - Assert.Equal(st4 != "", File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, sName))); + Assert.Equal( + st4 != "", + File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, sName)) + ); Settings.Set(key, false); // Cleanup Assert.False(Settings.Get(key)); Assert.Equal("", Settings.GetValue(key)); - Assert.False(File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, sName))); + Assert.False( + File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, sName)) + ); } [Theory] - [InlineData("lsTestSetting1", new[] { "UpdatedFirstValue", "RandomString1", "RandomTestValue", "AnotherRandomValue" }, new[] { 9, 15, 21, 1001, 4567 }, new[] { "itemA", "itemB", "itemC" })] - [InlineData("lsktjgshdfsd", new[] { "newValue1", "updatedString", "emptyString", "randomSymbols@123" }, new[] { 42, 23, 17, 98765, 3482 }, new[] { "itemX", "itemY", "itemZ" })] - [InlineData("lsª", new[] { "UniqueVal1", "NewVal2", "AnotherVal3", "TestVal4" }, new[] { 123, 456, 789, 321, 654 }, new[] { "item1", "item2", "item3" })] - [InlineData("lsTestSettingEntry With A Space", new[] { "ChangedFirstValue", "AlteredSecondVal", "TestedValue", "FinalVal" }, new[] { 23, 98, 456, 753, 951 }, new[] { "testA", "testB", "testC" })] - [InlineData("lsVeryVeryLongTestSettingEntrySoTheClassCanReallyBeStressedOut", new[] { "newCharacterSet\x99\x01\x02", "UpdatedRandomValue", "TestEmptyString", "FinalTestValue" }, new[] { 0b11001100, 1234, 5678, 1000000 }, new[] { "finalTest1", "finalTest2", "finalTest3" })] - public void TestListSettings(string SettingName, string[] ls1Array, int[] ls2Array, string[] ls3Array) + [InlineData( + "lsTestSetting1", + new[] { "UpdatedFirstValue", "RandomString1", "RandomTestValue", "AnotherRandomValue" }, + new[] { 9, 15, 21, 1001, 4567 }, + new[] { "itemA", "itemB", "itemC" } + )] + [InlineData( + "lsktjgshdfsd", + new[] { "newValue1", "updatedString", "emptyString", "randomSymbols@123" }, + new[] { 42, 23, 17, 98765, 3482 }, + new[] { "itemX", "itemY", "itemZ" } + )] + [InlineData( + "lsª", + new[] { "UniqueVal1", "NewVal2", "AnotherVal3", "TestVal4" }, + new[] { 123, 456, 789, 321, 654 }, + new[] { "item1", "item2", "item3" } + )] + [InlineData( + "lsTestSettingEntry With A Space", + new[] { "ChangedFirstValue", "AlteredSecondVal", "TestedValue", "FinalVal" }, + new[] { 23, 98, 456, 753, 951 }, + new[] { "testA", "testB", "testC" } + )] + [InlineData( + "lsVeryVeryLongTestSettingEntrySoTheClassCanReallyBeStressedOut", + new[] + { + "newCharacterSet\x99\x01\x02", + "UpdatedRandomValue", + "TestEmptyString", + "FinalTestValue", + }, + new[] { 0b11001100, 1234, 5678, 1000000 }, + new[] { "finalTest1", "finalTest2", "finalTest3" } + )] + public void TestListSettings( + string SettingName, + string[] ls1Array, + int[] ls2Array, + string[] ls3Array + ) { // Convert arrays to Lists manually List ls1 = ls1Array.ToList(); @@ -154,11 +244,20 @@ public void TestListSettings(string SettingName, string[] ls1Array, int[] ls2Arr List ls3 = []; foreach (var item in ls3Array.ToList()) { - ls3.Add(new SerializableTest(item, new Random().Next(), new SerializableTestSub(item + new Random().Next(), new Random().Next()))); + ls3.Add( + new SerializableTest( + item, + new Random().Next(), + new SerializableTestSub(item + new Random().Next(), new Random().Next()) + ) + ); } Settings.ClearList(SettingName); - Assert.Empty(Settings.GetList(SettingName) ?? ["this shouldn't be null; something's wrong"]); + Assert.Empty( + Settings.GetList(SettingName) + ?? ["this shouldn't be null; something's wrong"] + ); Settings.SetList(SettingName, ls1); Assert.NotEmpty(Settings.GetList(SettingName) ?? []); Assert.Equal(ls1[0], Settings.GetListItem(SettingName, 0)); @@ -174,11 +273,19 @@ public void TestListSettings(string SettingName, string[] ls1Array, int[] ls2Arr Assert.Equal("this is now a test case", Settings.GetListItem(SettingName, 3)); Assert.Null(Settings.GetListItem(SettingName, 4)); - List? persistedList = JsonSerializer.Deserialize>(File.ReadAllText(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, $"{SettingName}.json")), Settings.SerializationOptions); + List? persistedList = JsonSerializer.Deserialize>( + File.ReadAllText( + Path.Join(CoreData.UniGetUIUserConfigurationDirectory, $"{SettingName}.json") + ), + Settings.SerializationOptions + ); Assert.NotNull(persistedList); Assert.Equal(Settings.GetListItem(SettingName, 0), persistedList[0]); Settings.ClearList(SettingName); - Assert.Empty(Settings.GetList(SettingName) ?? ["this shouldn't be null; something's wrong"]); + Assert.Empty( + Settings.GetList(SettingName) + ?? ["this shouldn't be null; something's wrong"] + ); Settings.SetList(SettingName, ls2); Assert.NotEmpty(Settings.GetList(SettingName) ?? []); @@ -192,22 +299,71 @@ public void TestListSettings(string SettingName, string[] ls1Array, int[] ls2Arr Settings.SetList(SettingName, ls3); Assert.Equal(ls3.Count, Settings.GetList(SettingName)?.Count); - Assert.Equal(ls3[1].sub.sub, Settings.GetListItem(SettingName, 1)?.sub.sub); + Assert.Equal( + ls3[1].sub.sub, + Settings.GetListItem(SettingName, 1)?.sub.sub + ); Assert.True(Settings.RemoveFromList(SettingName, ls3[0])); Assert.False(Settings.RemoveFromList(SettingName, ls3[0])); - Assert.Equal(ls3[1].sub.sub, Settings.GetListItem(SettingName, 0)?.sub.sub); + Assert.Equal( + ls3[1].sub.sub, + Settings.GetListItem(SettingName, 0)?.sub.sub + ); Settings.ClearList(SettingName); // Cleanup - Assert.Empty(Settings.GetList(SettingName) ?? ["this shouldn't be null; something's wrong"]); - Assert.False(File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, $"{SettingName}.json"))); + Assert.Empty( + Settings.GetList(SettingName) + ?? ["this shouldn't be null; something's wrong"] + ); + Assert.False( + File.Exists( + Path.Join(CoreData.UniGetUIUserConfigurationDirectory, $"{SettingName}.json") + ) + ); } [Theory] - [InlineData(Settings.K.Test2, new[] { "UpdatedFirstValue", "RandomString1", "RandomTestValue", "AnotherRandomValue" }, new[] { 9, 15, 21, 1001, 4567 }, new[] { "itemA", "itemB", "itemC" })] - [InlineData(Settings.K.Test3, new[] { "newValue1", "updatedString", "emptyString", "randomSymbols@123" }, new[] { 42, 23, 17, 98765, 3482 }, new[] { "itemX", "itemY", "itemZ" })] - [InlineData(Settings.K.Test4, new[] { "UniqueVal1", "NewVal2", "AnotherVal3", "TestVal4" }, new[] { 123, 456, 789, 321, 654 }, new[] { "item1", "item2", "item3" })] - [InlineData(Settings.K.Test5, new[] { "ChangedFirstValue", "AlteredSecondVal", "TestedValue", "FinalVal" }, new[] { 23, 98, 456, 753, 951 }, new[] { "testA", "testB", "testC" })] - [InlineData(Settings.K.Test6, new[] { "newCharacterSet\x99\x01\x02", "UpdatedRandomValue", "TestEmptyString", "FinalTestValue" }, new[] { 0b11001100, 1234, 5678, 1000000 }, new[] { "finalTest1", "finalTest2", "finalTest3" })] - public void TestDictionarySettings(Settings.K SettingName, string[] keyArray, int[] intArray, string[] strArray) + [InlineData( + Settings.K.Test2, + new[] { "UpdatedFirstValue", "RandomString1", "RandomTestValue", "AnotherRandomValue" }, + new[] { 9, 15, 21, 1001, 4567 }, + new[] { "itemA", "itemB", "itemC" } + )] + [InlineData( + Settings.K.Test3, + new[] { "newValue1", "updatedString", "emptyString", "randomSymbols@123" }, + new[] { 42, 23, 17, 98765, 3482 }, + new[] { "itemX", "itemY", "itemZ" } + )] + [InlineData( + Settings.K.Test4, + new[] { "UniqueVal1", "NewVal2", "AnotherVal3", "TestVal4" }, + new[] { 123, 456, 789, 321, 654 }, + new[] { "item1", "item2", "item3" } + )] + [InlineData( + Settings.K.Test5, + new[] { "ChangedFirstValue", "AlteredSecondVal", "TestedValue", "FinalVal" }, + new[] { 23, 98, 456, 753, 951 }, + new[] { "testA", "testB", "testC" } + )] + [InlineData( + Settings.K.Test6, + new[] + { + "newCharacterSet\x99\x01\x02", + "UpdatedRandomValue", + "TestEmptyString", + "FinalTestValue", + }, + new[] { 0b11001100, 1234, 5678, 1000000 }, + new[] { "finalTest1", "finalTest2", "finalTest3" } + )] + public void TestDictionarySettings( + Settings.K SettingName, + string[] keyArray, + int[] intArray, + string[] strArray + ) { Dictionary test = []; Dictionary nonEmptyDictionary = []; @@ -228,44 +384,169 @@ public void TestDictionarySettings(Settings.K SettingName, string[] keyArray, in Settings.SetDictionaryItem(SettingName, "key", 12); Assert.Equal(12, Settings.GetDictionaryItem(SettingName, "key")); Settings.SetDictionary(SettingName, test); - Assert.Equal(JsonSerializer.Serialize(test, Settings.SerializationOptions), File.ReadAllText(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, $"{Settings.ResolveKey(SettingName)}.json"))); - Assert.Equal(test[keyArray[0]]?.sub.count, Settings.GetDictionary(SettingName)?[keyArray[0]]?.sub.count); - Assert.Equal(test[keyArray[1]]?.sub.count, Settings.GetDictionaryItem(SettingName, keyArray[1])?.sub.count); + Assert.Equal( + JsonSerializer.Serialize(test, Settings.SerializationOptions), + File.ReadAllText( + Path.Join( + CoreData.UniGetUIUserConfigurationDirectory, + $"{Settings.ResolveKey(SettingName)}.json" + ) + ) + ); + Assert.Equal( + test[keyArray[0]]?.sub.count, + Settings + .GetDictionary(SettingName) + ?[keyArray[0]]?.sub.count + ); + Assert.Equal( + test[keyArray[1]]?.sub.count, + Settings + .GetDictionaryItem(SettingName, keyArray[1]) + ?.sub.count + ); Settings.SetDictionaryItem(SettingName, keyArray[0], test[keyArray[1]]); - Assert.Equal(test[keyArray[1]]?.sub.count, Settings.GetDictionaryItem(SettingName, keyArray[0])?.sub.count); - Assert.NotEqual(test[keyArray[0]]?.sub.count, Settings.GetDictionaryItem(SettingName, keyArray[0])?.sub.count); - Assert.Equal(test[keyArray[1]]?.sub.count, Settings.GetDictionaryItem(SettingName, keyArray[1])?.sub.count); - Assert.Equal(test[keyArray[1]]?.count, Settings.SetDictionaryItem( + Assert.Equal( + test[keyArray[1]]?.sub.count, + Settings + .GetDictionaryItem(SettingName, keyArray[0]) + ?.sub.count + ); + Assert.NotEqual( + test[keyArray[0]]?.sub.count, + Settings + .GetDictionaryItem(SettingName, keyArray[0]) + ?.sub.count + ); + Assert.Equal( + test[keyArray[1]]?.sub.count, + Settings + .GetDictionaryItem(SettingName, keyArray[1]) + ?.sub.count + ); + Assert.Equal( + test[keyArray[1]]?.count, + Settings + .SetDictionaryItem( + SettingName, + keyArray[0], + new SerializableTest( + "this is not test data", + -12000, + new SerializableTestSub("this sub is not test data", -13000) + ) + ) + ?.count + ); + Assert.Equal( + -12000, + Settings + .GetDictionaryItem(SettingName, keyArray[0]) + ?.count + ); + Assert.Equal( + "this is not test data", + Settings + .GetDictionaryItem(SettingName, keyArray[0]) + ?.title + ); + Assert.Equal( + -13000, + Settings + .GetDictionaryItem(SettingName, keyArray[0]) + ?.sub.count + ); + Settings.SetDictionaryItem( SettingName, - keyArray[0], - new SerializableTest( - "this is not test data", - -12000, - new SerializableTestSub("this sub is not test data", -13000) + "this is not a test data key", + test[keyArray[0]] + ); + Assert.Equal( + test[keyArray[0]]?.title, + Settings + .GetDictionaryItem( + SettingName, + "this is not a test data key" + ) + ?.title + ); + Assert.Equal( + test[keyArray[0]]?.sub.count, + Settings + .GetDictionaryItem( + SettingName, + "this is not a test data key" + ) + ?.sub.count + ); + Assert.True( + Settings.DictionaryContainsKey( + SettingName, + "this is not a test data key" + ) + ); + Assert.True( + Settings.DictionaryContainsValue( + SettingName, + test[keyArray[0]] + ) + ); + Assert.NotNull( + Settings.RemoveDictionaryKey( + SettingName, + "this is not a test data key" + ) + ); + Assert.Null( + Settings.RemoveDictionaryKey( + SettingName, + "this is not a test data key" + ) + ); + Assert.False( + Settings.DictionaryContainsKey( + SettingName, + "this is not a test data key" ) - )?.count); - Assert.Equal(-12000, Settings.GetDictionaryItem(SettingName, keyArray[0])?.count); - Assert.Equal("this is not test data", Settings.GetDictionaryItem(SettingName, keyArray[0])?.title); - Assert.Equal(-13000, Settings.GetDictionaryItem(SettingName, keyArray[0])?.sub.count); - Settings.SetDictionaryItem(SettingName, "this is not a test data key", test[keyArray[0]]); - Assert.Equal(test[keyArray[0]]?.title, Settings.GetDictionaryItem(SettingName, "this is not a test data key")?.title); - Assert.Equal(test[keyArray[0]]?.sub.count, Settings.GetDictionaryItem(SettingName, "this is not a test data key")?.sub.count); - Assert.True(Settings.DictionaryContainsKey(SettingName, "this is not a test data key")); - Assert.True(Settings.DictionaryContainsValue(SettingName, test[keyArray[0]])); - Assert.NotNull(Settings.RemoveDictionaryKey(SettingName, "this is not a test data key")); - Assert.Null(Settings.RemoveDictionaryKey(SettingName, "this is not a test data key")); - Assert.False(Settings.DictionaryContainsKey(SettingName, "this is not a test data key")); - Assert.False(Settings.DictionaryContainsValue(SettingName, test[keyArray[0]])); - Assert.True(Settings.DictionaryContainsValue(SettingName, test[keyArray[2]])); + ); + Assert.False( + Settings.DictionaryContainsValue( + SettingName, + test[keyArray[0]] + ) + ); + Assert.True( + Settings.DictionaryContainsValue( + SettingName, + test[keyArray[2]] + ) + ); Assert.Equal( - JsonSerializer.Serialize(Settings.GetDictionary(SettingName), Settings.SerializationOptions), - File.ReadAllText(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, $"{Settings.ResolveKey(SettingName)}.json")) + JsonSerializer.Serialize( + Settings.GetDictionary(SettingName), + Settings.SerializationOptions + ), + File.ReadAllText( + Path.Join( + CoreData.UniGetUIUserConfigurationDirectory, + $"{Settings.ResolveKey(SettingName)}.json" + ) + ) ); Settings.ClearDictionary(SettingName); // Cleanup - Assert.Empty(Settings.GetDictionary(SettingName) ?? nonEmptyDictionary); - Assert.False(File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, $"{Settings.ResolveKey(SettingName)}.json"))); + Assert.Empty( + Settings.GetDictionary(SettingName) ?? nonEmptyDictionary + ); + Assert.False( + File.Exists( + Path.Join( + CoreData.UniGetUIUserConfigurationDirectory, + $"{Settings.ResolveKey(SettingName)}.json" + ) + ) + ); } [Fact] @@ -273,7 +554,8 @@ public static void EnsureAllKeysResolve() { foreach (Settings.K key in Enum.GetValues(typeof(Settings.K))) { - if(key is Settings.K.Unset) continue; + if (key is Settings.K.Unset) + continue; Assert.NotEmpty(Settings.ResolveKey(key)); } } diff --git a/src/UniGetUI.Core.Settings.Tests/UniGetUI.Core.Settings.Tests.csproj b/src/UniGetUI.Core.Settings.Tests/UniGetUI.Core.Settings.Tests.csproj index f6df2a00d3..70793a2084 100644 --- a/src/UniGetUI.Core.Settings.Tests/UniGetUI.Core.Settings.Tests.csproj +++ b/src/UniGetUI.Core.Settings.Tests/UniGetUI.Core.Settings.Tests.csproj @@ -1,39 +1,36 @@ - - - $(PortableTargetFramework) - - - - - - - false - true - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - - - + + $(PortableTargetFramework) + + + + + false + true + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + diff --git a/src/UniGetUI.Core.Settings/SettingsEngine.cs b/src/UniGetUI.Core.Settings/SettingsEngine.cs index 8cc8aee80b..85e29cc14f 100644 --- a/src/UniGetUI.Core.Settings/SettingsEngine.cs +++ b/src/UniGetUI.Core.Settings/SettingsEngine.cs @@ -13,7 +13,7 @@ public static bool Get(K key, bool invert = false) { string setting = ResolveKey(key); if (booleanSettings.TryGetValue(key, out bool result)) - { // If the setting was cached + { // If the setting was cached return result ^ invert; } @@ -32,20 +32,29 @@ public static void Set(K key, bool value) booleanSettings[key] = value; // Update changes on disk if applicable - if (value && !File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, setting))) + if ( + value + && !File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, setting)) + ) { - File.WriteAllText(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, setting), ""); + File.WriteAllText( + Path.Join(CoreData.UniGetUIUserConfigurationDirectory, setting), + "" + ); } else if (!value) { valueSettings[key] = ""; - if (File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, setting))) + if ( + File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, setting)) + ) { - File.Delete(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, setting)); + File.Delete( + Path.Join(CoreData.UniGetUIUserConfigurationDirectory, setting) + ); } } - } catch (Exception e) { @@ -58,7 +67,7 @@ public static string GetValue(K key) { string setting = ResolveKey(key); if (valueSettings.TryGetValue(key, out string? value)) - { // If the setting was cached + { // If the setting was cached return value; } @@ -66,12 +75,13 @@ public static string GetValue(K key) value = ""; if (File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, setting))) { - value = File.ReadAllText(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, setting)); + value = File.ReadAllText( + Path.Join(CoreData.UniGetUIUserConfigurationDirectory, setting) + ); } valueSettings[key] = value; return value; - } public static void SetValue(K key, string value) @@ -87,7 +97,10 @@ public static void SetValue(K key, string value) } else { - File.WriteAllText(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, setting), value); + File.WriteAllText( + Path.Join(CoreData.UniGetUIUserConfigurationDirectory, setting), + value + ); booleanSettings[key] = true; valueSettings[key] = value; } diff --git a/src/UniGetUI.Core.Settings/SettingsEngine_Dictionaries.cs b/src/UniGetUI.Core.Settings/SettingsEngine_Dictionaries.cs index fc20b728f1..a57da6c1e5 100644 --- a/src/UniGetUI.Core.Settings/SettingsEngine_Dictionaries.cs +++ b/src/UniGetUI.Core.Settings/SettingsEngine_Dictionaries.cs @@ -7,44 +7,57 @@ namespace UniGetUI.Core.SettingsEngine { public static partial class Settings { - private static readonly ConcurrentDictionary> _dictionarySettings = new(); + private static readonly ConcurrentDictionary< + K, + Dictionary + > _dictionarySettings = new(); // Returns an empty dictionary if the setting doesn't exist and null if the types are invalid private static Dictionary? _getDictionary(K key) where KeyT : notnull - { + { string setting = ResolveKey(key); try { try { - if (_dictionarySettings.TryGetValue(key, out Dictionary? result)) + if ( + _dictionarySettings.TryGetValue( + key, + out Dictionary? result + ) + ) { // If the setting was cached - return result.ToDictionary( - kvp => (KeyT)kvp.Key, - kvp => (ValueT?)kvp.Value - ); + return result.ToDictionary(kvp => (KeyT)kvp.Key, kvp => (ValueT?)kvp.Value); } } catch (InvalidCastException) { Logger.Error( - $"Tried to get a dictionary setting with a key of type {typeof(KeyT)} and a value of type {typeof(ValueT)}, which is not the type of the dictionary"); + $"Tried to get a dictionary setting with a key of type {typeof(KeyT)} and a value of type {typeof(ValueT)}, which is not the type of the dictionary" + ); return null; } // Otherwise, load the setting from disk and cache that setting Dictionary value = []; - if (File.Exists(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, $"{setting}.json"))) + if ( + File.Exists( + Path.Join(CoreData.UniGetUIUserConfigurationDirectory, $"{setting}.json") + ) + ) { - string result = File.ReadAllText(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, $"{setting}.json")); + string result = File.ReadAllText( + Path.Join(CoreData.UniGetUIUserConfigurationDirectory, $"{setting}.json") + ); try { if (result != "") { - - Dictionary? item = JsonSerializer.Deserialize>(result, SerializationOptions); + Dictionary? item = JsonSerializer.Deserialize< + Dictionary + >(result, SerializationOptions); if (item is not null) { value = item; @@ -54,7 +67,8 @@ public static partial class Settings catch (InvalidCastException) { Logger.Error( - $"Tried to get a dictionary setting with a key of type {typeof(KeyT)} and a value of type {typeof(ValueT)}, but the setting on disk ({result}) cannot be deserialized to that"); + $"Tried to get a dictionary setting with a key of type {typeof(KeyT)} and a value of type {typeof(ValueT)}, but the setting on disk ({result}) cannot be deserialized to that" + ); } } @@ -79,7 +93,10 @@ public static partial class Settings return _getDictionary(settingsKey); } - public static void SetDictionary(K settingsKey, Dictionary value) + public static void SetDictionary( + K settingsKey, + Dictionary value + ) where KeyT : notnull { string setting = ResolveKey(settingsKey); @@ -91,13 +108,16 @@ public static void SetDictionary(K settingsKey, Dictionary(K settingsKey, Dictionary? dictionary = _getDictionary(settingsKey); - if (dictionary == null || !dictionary.TryGetValue(key, out ValueT? value)) return default; + if (dictionary == null || !dictionary.TryGetValue(key, out ValueT? value)) + return default; return value; } @@ -118,10 +139,7 @@ public static void SetDictionary(K settingsKey, Dictionary? dictionary = _getDictionary(settingsKey); if (dictionary == null) { - dictionary = new() - { - { key, value } - }; + dictionary = new() { { key, value } }; SetDictionary(settingsKey, dictionary); return default; } @@ -142,7 +160,8 @@ public static void SetDictionary(K settingsKey, Dictionary? dictionary = _getDictionary(settingsKey); - if (dictionary == null) return default; + if (dictionary == null) + return default; bool success = false; if (dictionary.TryGetValue(key, out ValueT? value)) @@ -151,7 +170,8 @@ public static void SetDictionary(K settingsKey, Dictionary(K settingsKey, KeyT key) where KeyT : notnull { Dictionary? dictionary = _getDictionary(settingsKey); - if (dictionary == null) return false; + if (dictionary == null) + return false; return dictionary.ContainsKey(key); } @@ -168,7 +189,8 @@ public static bool DictionaryContainsValue(K settingsKey, ValueT v where KeyT : notnull { Dictionary? dictionary = _getDictionary(settingsKey); - if (dictionary == null) return false; + if (dictionary == null) + return false; return dictionary.ContainsValue(value); } diff --git a/src/UniGetUI.Core.Settings/SettingsEngine_Extras.cs b/src/UniGetUI.Core.Settings/SettingsEngine_Extras.cs index 21f9d7c8a7..0e4129fbff 100644 --- a/src/UniGetUI.Core.Settings/SettingsEngine_Extras.cs +++ b/src/UniGetUI.Core.Settings/SettingsEngine_Extras.cs @@ -13,28 +13,30 @@ public partial class Settings * */ - public static bool AreNotificationsDisabled() - => Get(K.DisableSystemTray) || Get(K.DisableNotifications); + public static bool AreNotificationsDisabled() => + Get(K.DisableSystemTray) || Get(K.DisableNotifications); - public static bool AreUpdatesNotificationsDisabled() - => AreNotificationsDisabled() || Get(K.DisableUpdatesNotifications); + public static bool AreUpdatesNotificationsDisabled() => + AreNotificationsDisabled() || Get(K.DisableUpdatesNotifications); - public static bool AreErrorNotificationsDisabled() - => AreNotificationsDisabled() || Get(K.DisableErrorNotifications); + public static bool AreErrorNotificationsDisabled() => + AreNotificationsDisabled() || Get(K.DisableErrorNotifications); - public static bool AreSuccessNotificationsDisabled() - => AreNotificationsDisabled() || Get(K.DisableSuccessNotifications); + public static bool AreSuccessNotificationsDisabled() => + AreNotificationsDisabled() || Get(K.DisableSuccessNotifications); - public static bool AreProgressNotificationsDisabled() - => AreNotificationsDisabled() || Get(K.DisableProgressNotifications); + public static bool AreProgressNotificationsDisabled() => + AreNotificationsDisabled() || Get(K.DisableProgressNotifications); public static Uri? GetProxyUrl() { - if (!Get(K.EnableProxy)) return null; + if (!Get(K.EnableProxy)) + return null; string plainUrl = GetValue(K.ProxyURL); Uri.TryCreate(plainUrl, UriKind.RelativeOrAbsolute, out Uri? var); - if(Get(K.EnableProxy) && var is null) Logger.Warn($"Proxy setting {plainUrl} is not valid"); + if (Get(K.EnableProxy) && var is null) + Logger.Warn($"Proxy setting {plainUrl} is not valid"); return var; } @@ -45,7 +47,9 @@ public static bool AreProgressNotificationsDisabled() try { string username = GetValue(K.ProxyUsername); - return username.Length is 0 ? null : CoreCredentialStore.GetCredential(PROXY_RES_ID, username); + return username.Length is 0 + ? null + : CoreCredentialStore.GetCredential(PROXY_RES_ID, username); } catch (Exception ex) { diff --git a/src/UniGetUI.Core.Settings/SettingsEngine_ImportExport.cs b/src/UniGetUI.Core.Settings/SettingsEngine_ImportExport.cs index 59ab0bda49..877c007c0c 100644 --- a/src/UniGetUI.Core.Settings/SettingsEngine_ImportExport.cs +++ b/src/UniGetUI.Core.Settings/SettingsEngine_ImportExport.cs @@ -15,7 +15,7 @@ public static void ImportFromFile_JSON(string path) { if (Path.GetDirectoryName(path) == CoreData.UniGetUIUserConfigurationDirectory) { - var tempLocation = Directory.CreateTempSubdirectory(); + var tempLocation = Directory.CreateTempSubdirectory(); var newPath = Path.Join(tempLocation.FullName, Path.GetFileName(path)); File.Copy(path, newPath); path = newPath; @@ -26,9 +26,19 @@ public static void ImportFromFile_JSON(string path) public static string ExportToString_JSON() { Dictionary settings = []; - foreach (string entry in Directory.EnumerateFiles(CoreData.UniGetUIUserConfigurationDirectory)) + foreach ( + string entry in Directory.EnumerateFiles(CoreData.UniGetUIUserConfigurationDirectory) + ) { - if (new[] { "OperationHistory", "WinGetAlreadyUpgradedPackages.json", "TelemetryClientToken", "CurrentSessionToken" }.Contains(Path.GetFileName(entry))) + if ( + new[] + { + "OperationHistory", + "WinGetAlreadyUpgradedPackages.json", + "TelemetryClientToken", + "CurrentSessionToken", + }.Contains(Path.GetFileName(entry)) + ) continue; settings.Add(Path.GetFileName(entry), File.ReadAllText(entry)); @@ -39,24 +49,41 @@ public static string ExportToString_JSON() public static void ImportFromString_JSON(string jsonContent) { ResetSettings(); - Dictionary settings = JsonSerializer.Deserialize>(jsonContent, SerializationOptions) ?? []; + Dictionary settings = + JsonSerializer.Deserialize>( + jsonContent, + SerializationOptions + ) ?? []; foreach (KeyValuePair entry in settings) { - if (new[] { "OperationHistory", "WinGetAlreadyUpgradedPackages.json", "TelemetryClientToken", "CurrentSessionToken" }.Contains(entry.Key)) + if ( + new[] + { + "OperationHistory", + "WinGetAlreadyUpgradedPackages.json", + "TelemetryClientToken", + "CurrentSessionToken", + }.Contains(entry.Key) + ) continue; - File.WriteAllText(Path.Join(CoreData.UniGetUIUserConfigurationDirectory, entry.Key), entry.Value); + File.WriteAllText( + Path.Join(CoreData.UniGetUIUserConfigurationDirectory, entry.Key), + entry.Value + ); } Logger.Info("Settings successfully imported from string content."); } public static void ResetSettings() { - foreach (string entry in Directory.EnumerateFiles(CoreData.UniGetUIUserConfigurationDirectory)) + foreach ( + string entry in Directory.EnumerateFiles(CoreData.UniGetUIUserConfigurationDirectory) + ) { try { - if(new[] {"TelemetryClientToken"}.Contains(entry.Split("\\")[^1])) + if (new[] { "TelemetryClientToken" }.Contains(entry.Split("\\")[^1])) continue; File.Delete(entry); diff --git a/src/UniGetUI.Core.Settings/SettingsEngine_Lists.cs b/src/UniGetUI.Core.Settings/SettingsEngine_Lists.cs index 19f0a47fc9..51c7ed33b2 100644 --- a/src/UniGetUI.Core.Settings/SettingsEngine_Lists.cs +++ b/src/UniGetUI.Core.Settings/SettingsEngine_Lists.cs @@ -24,14 +24,19 @@ public static partial class Settings } catch (InvalidCastException) { - Logger.Error($"Tried to get a list setting as type {typeof(T)}, which is not the type of the list"); + Logger.Error( + $"Tried to get a list setting as type {typeof(T)}, which is not the type of the list" + ); return null; } // Otherwise, load the setting from disk and cache that setting List value = []; - var file = Path.Join(CoreData.UniGetUIUserConfigurationDirectory, $"{setting}.json"); + var file = Path.Join( + CoreData.UniGetUIUserConfigurationDirectory, + $"{setting}.json" + ); if (File.Exists(file)) { string result = File.ReadAllText(file); @@ -39,7 +44,10 @@ public static partial class Settings { if (result != "") { - List? item = JsonSerializer.Deserialize>(result, SerializationOptions); + List? item = JsonSerializer.Deserialize>( + result, + SerializationOptions + ); if (item is not null) { value = item; @@ -49,7 +57,8 @@ public static partial class Settings catch (InvalidCastException) { Logger.Error( - $"Tried to get a list setting as type {typeof(T)}, but the setting on disk {result} cannot be deserialized to {typeof(T)}"); + $"Tried to get a list setting as type {typeof(T)}, but the setting on disk {result} cannot be deserialized to {typeof(T)}" + ); } } @@ -76,12 +85,16 @@ public static void SetList(string setting, List value) var file = Path.Join(CoreData.UniGetUIUserConfigurationDirectory, $"{setting}.json"); try { - if (value.Count != 0) File.WriteAllText(file, JsonSerializer.Serialize(value, SerializationOptions)); - else if (File.Exists(file)) File.Delete(file); + if (value.Count != 0) + File.WriteAllText(file, JsonSerializer.Serialize(value, SerializationOptions)); + else if (File.Exists(file)) + File.Delete(file); } catch (Exception e) { - Logger.Error($"CANNOT SET SETTING LIST FOR setting={setting} [{string.Join(", ", value)}]"); + Logger.Error( + $"CANNOT SET SETTING LIST FOR setting={setting} [{string.Join(", ", value)}]" + ); Logger.Error(e); } } @@ -89,7 +102,8 @@ public static void SetList(string setting, List value) public static T? GetListItem(string setting, int index) { List? list = _getList(setting); - if (list == null) return default; + if (list == null) + return default; if (list.Count <= index) { Logger.Error($"Index {index} out of range for list setting {setting}"); @@ -102,7 +116,8 @@ public static void SetList(string setting, List value) public static void AddToList(string setting, T value) { List? list = _getList(setting); - if (list == null) return; + if (list == null) + return; list.Add(value); SetList(setting, list); @@ -111,7 +126,8 @@ public static void AddToList(string setting, T value) public static bool RemoveFromList(string setting, T value) { List? list = _getList(setting); - if (list == null) return false; + if (list == null) + return false; bool result = list.Remove(value); SetList(setting, list); @@ -121,7 +137,8 @@ public static bool RemoveFromList(string setting, T value) public static bool ListContains(string setting, T value) { List? list = _getList(setting); - if (list == null) return false; + if (list == null) + return false; return list.Contains(value); } diff --git a/src/UniGetUI.Core.Settings/SettingsEngine_Names.cs b/src/UniGetUI.Core.Settings/SettingsEngine_Names.cs index 52a8a0501e..dc09e46940 100644 --- a/src/UniGetUI.Core.Settings/SettingsEngine_Names.cs +++ b/src/UniGetUI.Core.Settings/SettingsEngine_Names.cs @@ -190,7 +190,9 @@ public static string ResolveKey(K key) K.Test6 => "VeryVeryLongTestSettingEntrySoTheClassCanReallyBeStressedOut", K.Test7_Legacy => "LegacyBoolSetting", K.Unset => throw new InvalidDataException("Setting key was unset!"), - _ => throw new KeyNotFoundException($"The settings key {key} was not found on the ResolveKey map") + _ => throw new KeyNotFoundException( + $"The settings key {key} was not found on the ResolveKey map" + ), }; } } diff --git a/src/UniGetUI.Core.Settings/UniGetUI.Core.Settings.csproj b/src/UniGetUI.Core.Settings/UniGetUI.Core.Settings.csproj index 526f14e344..4ce0b1cfa9 100644 --- a/src/UniGetUI.Core.Settings/UniGetUI.Core.Settings.csproj +++ b/src/UniGetUI.Core.Settings/UniGetUI.Core.Settings.csproj @@ -1,11 +1,14 @@ + + $(SharedTargetFrameworks) + - - - - + + + + - - - + + + diff --git a/src/UniGetUI.Core.Tools.Tests/MetaTests.cs b/src/UniGetUI.Core.Tools.Tests/MetaTests.cs index 9f88a0bc5f..2f1897e5cc 100644 --- a/src/UniGetUI.Core.Tools.Tests/MetaTests.cs +++ b/src/UniGetUI.Core.Tools.Tests/MetaTests.cs @@ -9,20 +9,33 @@ public void TestJsonSerializationOptions() { // This test ensures that any json operation has the proper serialization options set (required for TRIM support) var solutionDirectory = FindRepositoryRoot(); - var csFiles = Directory.GetFiles(solutionDirectory, "*.cs", SearchOption.AllDirectories) - .Where(file => !file.Contains(@"bin\") && !file.Contains(@"obj\") && !file.EndsWith(".g.cs") && !file.EndsWith("Tests.cs")); + var csFiles = Directory + .GetFiles(solutionDirectory, "*.cs", SearchOption.AllDirectories) + .Where(file => + !file.Contains(@"bin\") + && !file.Contains(@"obj\") + && !file.EndsWith(".g.cs") + && !file.EndsWith("Tests.cs") + ); foreach (var file in csFiles) { var lines = File.ReadAllLines(file); var jsonSerCount = lines.Count(x => x.Contains("JsonSerializer.Serialize")); var jsonDeserCount = lines.Count(x => x.Contains("JsonSerializer.Deserialize")); - var serialOptionsCount1 = lines.Count(x => x.Contains("SerializationHelpers.DefaultOptions")); - var serialOptionsCount2 = lines.Count(x => x.Contains("SerializationHelpers.ImportBundleOptions")); + var serialOptionsCount1 = lines.Count(x => + x.Contains("SerializationHelpers.DefaultOptions") + ); + var serialOptionsCount2 = lines.Count(x => + x.Contains("SerializationHelpers.ImportBundleOptions") + ); var serialOptionsCount3 = lines.Count(x => x.Contains("SerializationOptions")); - Assert.True((jsonSerCount + jsonDeserCount) <= serialOptionsCount1 + serialOptionsCount2 + serialOptionsCount3, - $"Failing on {file}. The specified file does not serialize and/or deserialize JSON with" + - $" the proper SerializationHelpers.DefaultOptions set"); + Assert.True( + (jsonSerCount + jsonDeserCount) + <= serialOptionsCount1 + serialOptionsCount2 + serialOptionsCount3, + $"Failing on {file}. The specified file does not serialize and/or deserialize JSON with" + + $" the proper SerializationHelpers.DefaultOptions set" + ); } } @@ -31,18 +44,26 @@ public void TestHttpClientInstantiation() { // This test ensures that any instantiation of HttpClient contains at least one empty line after it var solutionDirectory = FindRepositoryRoot(); - var csFiles = Directory.GetFiles(solutionDirectory, "*.cs", SearchOption.AllDirectories) - .Where(file => !file.Contains(@"bin\") && !file.Contains(@"obj\") && !file.EndsWith(".g.cs") - && !file.EndsWith("Tests.cs") && !file.EndsWith("LanguageEngine.cs")); + var csFiles = Directory + .GetFiles(solutionDirectory, "*.cs", SearchOption.AllDirectories) + .Where(file => + !file.Contains(@"bin\") + && !file.Contains(@"obj\") + && !file.EndsWith(".g.cs") + && !file.EndsWith("Tests.cs") + && !file.EndsWith("LanguageEngine.cs") + ); foreach (var file in csFiles) { var fileContent = File.ReadAllText(file); var match = Regex.Match(fileContent, "new HttpClient ?\\(\\)"); var match2 = Regex.Match(fileContent, "HttpClient [a-zA-Z0-9_]+ ?= ?new ?\\(\\)"); - Assert.False(match.Success || match2.Success, - $"File {file} has an incorrect instantiation of HttpClient, that does not pass the " + - $"compulsory CoreTools.GenericHttpClientParameters param"); + Assert.False( + match.Success || match2.Success, + $"File {file} has an incorrect instantiation of HttpClient, that does not pass the " + + $"compulsory CoreTools.GenericHttpClientParameters param" + ); } } @@ -52,8 +73,10 @@ private static string FindRepositoryRoot() while (currentDirectory is not null) { - if (File.Exists(Path.Join(currentDirectory.FullName, "AGENTS.md")) - && Directory.Exists(Path.Join(currentDirectory.FullName, "src"))) + if ( + File.Exists(Path.Join(currentDirectory.FullName, "AGENTS.md")) + && Directory.Exists(Path.Join(currentDirectory.FullName, "src")) + ) { return currentDirectory.FullName; } @@ -61,7 +84,8 @@ private static string FindRepositoryRoot() currentDirectory = currentDirectory.Parent; } - throw new DirectoryNotFoundException("Unable to locate the UniGetUI repository root from the test output directory."); + throw new DirectoryNotFoundException( + "Unable to locate the UniGetUI repository root from the test output directory." + ); } - } diff --git a/src/UniGetUI.Core.Tools.Tests/ToolsTests.cs b/src/UniGetUI.Core.Tools.Tests/ToolsTests.cs index 8087a1c60c..b4aa21efed 100644 --- a/src/UniGetUI.Core.Tools.Tests/ToolsTests.cs +++ b/src/UniGetUI.Core.Tools.Tests/ToolsTests.cs @@ -43,7 +43,9 @@ public async Task TestWhichFunctionForExistingFile() [Fact] public async Task TestWhichFunctionForNonExistingFile() { - Tuple result = await CoreTools.WhichAsync("nonexistentfile-does-not-exist"); + Tuple result = await CoreTools.WhichAsync( + "nonexistentfile-does-not-exist" + ); Assert.False(result.Item1); Assert.Equal("", result.Item2); } @@ -106,7 +108,10 @@ public void TestRandomStringGenerator(int length) [Theory] [InlineData("", 0)] - [InlineData("https://invalid.url.com/this/is/an/invalid.php?file=to_test&if=the&code_returns=zero", 0)] + [InlineData( + "https://invalid.url.com/this/is/an/invalid.php?file=to_test&if=the&code_returns=zero", + 0 + )] [InlineData("https://marticliment.com/resources/unigetui.png", 19788)] public async Task TestFileSizeLoader(string uri, long expectedSize) { @@ -118,14 +123,14 @@ public async Task TestFileSizeLoader(string uri, long expectedSize) [InlineData("1000.0", 1000, 0, 0, 0)] [InlineData("2.4", 2, 4, 0, 0)] [InlineData("33a.12-beta5", 33, 12, 5, 0)] - [InlineData("0", 0,0,0,0)] - [InlineData("", 0,0,0,0)] - [InlineData("dfgfdsgdfg", 0,0,0,0)] - [InlineData("-12", 12,0,0,0)] - [InlineData("4.0.0.1.0", 4,0,0,10)] - [InlineData("4.0.0.1.05", 4,0,0,105)] + [InlineData("0", 0, 0, 0, 0)] + [InlineData("", 0, 0, 0, 0)] + [InlineData("dfgfdsgdfg", 0, 0, 0, 0)] + [InlineData("-12", 12, 0, 0, 0)] + [InlineData("4.0.0.1.0", 4, 0, 0, 10)] + [InlineData("4.0.0.1.05", 4, 0, 0, 105)] [InlineData("2024.30.04.1223", 2024, 30, 4, 1223)] - [InlineData("0.0", 0,0,0,0)] + [InlineData("0.0", 0, 0, 0, 0)] public void TestGetVersionStringAsFloat(string version, int i1, int i2, int i3, int i4) { CoreTools.Version v = CoreTools.VersionStringToStruct(version); @@ -188,8 +193,10 @@ public void TestEnvVariableYuxtaposition() { const string ENV = "PATH"; - var oldpath = Environment.GetEnvironmentVariable(ENV, EnvironmentVariableTarget.Machine) + ";" + - Environment.GetEnvironmentVariable(ENV, EnvironmentVariableTarget.User); + var oldpath = + Environment.GetEnvironmentVariable(ENV, EnvironmentVariableTarget.Machine) + + ";" + + Environment.GetEnvironmentVariable(ENV, EnvironmentVariableTarget.User); ProcessStartInfo info = CoreTools.UpdateEnvironmentVariables(); info.Environment.TryGetValue(ENV, out string? result); @@ -201,7 +208,12 @@ public void TestEnvVariableYuxtaposition() [InlineData(20, 37, null, "[#######.............] 37%")] [InlineData(10, 0, "", "[..........] 0% ()")] [InlineData(10, 100, "3/3", "[##########] 100% (3/3)")] - public void TestTextProgressbarGenerator(int length, int progress, string? extra, string? expected) + public void TestTextProgressbarGenerator( + int length, + int progress, + string? extra, + string? expected + ) { Assert.Equal(CoreTools.TextProgressGenerator(length, progress, extra), expected); } @@ -209,7 +221,7 @@ public void TestTextProgressbarGenerator(int length, int progress, string? extra [Theory] [InlineData(0, 1, "0 Bytes")] [InlineData(10, 1, "10 Bytes")] - [InlineData(1024*34, 0, "34 KB")] + [InlineData(1024 * 34, 0, "34 KB")] [InlineData(65322450, 3, "62.296 MB")] [InlineData(65322450000, 3, "60.836 GB")] [InlineData(65322450000000, 3, "59.410 TB")] diff --git a/src/UniGetUI.Core.Tools.Tests/UniGetUI.Core.Tools.Tests.csproj b/src/UniGetUI.Core.Tools.Tests/UniGetUI.Core.Tools.Tests.csproj index 8b9e3710f6..8b8434162e 100644 --- a/src/UniGetUI.Core.Tools.Tests/UniGetUI.Core.Tools.Tests.csproj +++ b/src/UniGetUI.Core.Tools.Tests/UniGetUI.Core.Tools.Tests.csproj @@ -1,39 +1,36 @@ - - - $(PortableTargetFramework) - - - - - - - false - true - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - - - + + $(PortableTargetFramework) + + + + + false + true + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + diff --git a/src/UniGetUI.Core.Tools/DWMThreadHelper.cs b/src/UniGetUI.Core.Tools/DWMThreadHelper.cs index 0621627d3a..cfd8867a0f 100644 --- a/src/UniGetUI.Core.Tools/DWMThreadHelper.cs +++ b/src/UniGetUI.Core.Tools/DWMThreadHelper.cs @@ -8,11 +8,20 @@ namespace UniGetUI; public class DWMThreadHelper { [DllImport("ntdll.dll")] - private static extern int NtQueryInformationThread(IntPtr ThreadHandle, int ThreadInformationClass, - ref IntPtr ThreadInformation, int ThreadInformationLength, out int ReturnLength); + private static extern int NtQueryInformationThread( + IntPtr ThreadHandle, + int ThreadInformationClass, + ref IntPtr ThreadInformation, + int ThreadInformationLength, + out int ReturnLength + ); [DllImport("kernel32.dll")] - private static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle, uint dwThreadId); + private static extern IntPtr OpenThread( + ThreadAccess dwDesiredAccess, + bool bInheritHandle, + uint dwThreadId + ); [DllImport("kernel32.dll")] private static extern uint SuspendThread(IntPtr hThread); @@ -27,7 +36,7 @@ private static extern int NtQueryInformationThread(IntPtr ThreadHandle, int Thre private enum ThreadAccess : uint { QUERY_INFORMATION = 0x0040, - SUSPEND_RESUME = 0x0002 + SUSPEND_RESUME = 0x0002, } private const int ThreadQuerySetWin32StartAddress = 9; @@ -41,21 +50,25 @@ private enum ThreadAccess : uint public static void ChangeState_DWM(bool suspend) { - if (Settings.Get(Settings.K.DisableDMWThreadOptimizations)) return; + if (Settings.Get(Settings.K.DisableDMWThreadOptimizations)) + return; if (DWM_IsSuspended && suspend) { - Logger.Debug("DWM Thread was already suspended"); return; + Logger.Debug("DWM Thread was already suspended"); + return; } else if (!DWM_IsSuspended && !suspend) { - Logger.Debug("DWM Thread was already running"); return; + Logger.Debug("DWM Thread was already running"); + return; } - DWMThreadAdress ??= GetTargetFunctionAddress("dwmcorei.dll", 0x36240);// 0x36170); + DWMThreadAdress ??= GetTargetFunctionAddress("dwmcorei.dll", 0x36240); // 0x36170); if (DWMThreadAdress is null) { - Logger.Error("Failed to resolve DWM thread start adress."); return; + Logger.Error("Failed to resolve DWM thread start adress."); + return; } ChangeState(suspend, (IntPtr)DWMThreadAdress, ref DWM_IsSuspended, ref DWMThreadId, "DWM"); @@ -63,42 +76,72 @@ public static void ChangeState_DWM(bool suspend) public static void ChangeState_XAML(bool suspend) { - if (Settings.Get(Settings.K.DisableDMWThreadOptimizations)) return; + if (Settings.Get(Settings.K.DisableDMWThreadOptimizations)) + return; if (XAML_IsSuspended && suspend) { - Logger.Debug("XAML Thread was already suspended"); return; + Logger.Debug("XAML Thread was already suspended"); + return; } else if (!XAML_IsSuspended && !suspend) { - Logger.Debug("XAML Thread was already running"); return; + Logger.Debug("XAML Thread was already running"); + return; } // The reported offset on ProcessExplorer seems to be missing a part somehow. // To find the real adress, set offset to 0, and then get the offset from the Debugger.Break at ChangeState() - XAMLThreadAdress ??= GetTargetFunctionAddress("Microsoft.UI.Xaml.dll", 0x27C0E0);//0x2771A0); + XAMLThreadAdress ??= GetTargetFunctionAddress("Microsoft.UI.Xaml.dll", 0x27C0E0); //0x2771A0); if (XAMLThreadAdress is null) { - Logger.Error("Failed to resolve XAML thread start adress."); return; + Logger.Error("Failed to resolve XAML thread start adress."); + return; } - ChangeState(suspend, (IntPtr)XAMLThreadAdress, ref XAML_IsSuspended, ref XAMLThreadId, "XAML"); + ChangeState( + suspend, + (IntPtr)XAMLThreadAdress, + ref XAML_IsSuspended, + ref XAMLThreadId, + "XAML" + ); } private static IntPtr GetThreadStartAdress(int threadId) { - IntPtr hThread = OpenThread(ThreadAccess.QUERY_INFORMATION | ThreadAccess.SUSPEND_RESUME, false, (uint)threadId); - if (hThread == IntPtr.Zero) return IntPtr.Zero; + IntPtr hThread = OpenThread( + ThreadAccess.QUERY_INFORMATION | ThreadAccess.SUSPEND_RESUME, + false, + (uint)threadId + ); + if (hThread == IntPtr.Zero) + return IntPtr.Zero; IntPtr adress = 0x00; - int status = NtQueryInformationThread(hThread, ThreadQuerySetWin32StartAddress, ref adress, Marshal.SizeOf(typeof(IntPtr)), out _); - if(status != 0) Logger.Warn($"NtQueryInformationThread returned non-zero status code 0x{(uint)status:X}"); + int status = NtQueryInformationThread( + hThread, + ThreadQuerySetWin32StartAddress, + ref adress, + Marshal.SizeOf(typeof(IntPtr)), + out _ + ); + if (status != 0) + Logger.Warn( + $"NtQueryInformationThread returned non-zero status code 0x{(uint)status:X}" + ); CloseHandle(hThread); return adress; } - private static void ChangeState(bool suspend, IntPtr expectedAdress, ref bool IsSuspended, ref int? threadId, - string loggerName, bool canRetry = true) + private static void ChangeState( + bool suspend, + IntPtr expectedAdress, + ref bool IsSuspended, + ref int? threadId, + string loggerName, + bool canRetry = true + ) { IntPtr minId = -1; uint LastDiff = uint.MaxValue; @@ -124,23 +167,39 @@ private static void ChangeState(bool suspend, IntPtr expectedAdress, ref bool Is if (threadId is null) { - Logger.Error($"No thread matching {loggerName} with start adress {expectedAdress:X} was found. " + - $"Best guess was {minId} with adress offset {LastDiff:X}"); - if(Debugger.IsAttached) Debugger.Break(); + Logger.Error( + $"No thread matching {loggerName} with start adress {expectedAdress:X} was found. " + + $"Best guess was {minId} with adress offset {LastDiff:X}" + ); + if (Debugger.IsAttached) + Debugger.Break(); return; } - IntPtr hThread = OpenThread(ThreadAccess.QUERY_INFORMATION | ThreadAccess.SUSPEND_RESUME, false, (uint)threadId); + IntPtr hThread = OpenThread( + ThreadAccess.QUERY_INFORMATION | ThreadAccess.SUSPEND_RESUME, + false, + (uint)threadId + ); if (hThread == IntPtr.Zero) - { // When the thread cannot be opened + { // When the thread cannot be opened if (canRetry) { threadId = null; // On first try, reset argument threadId so it does get loaded again. - ChangeState(suspend, expectedAdress, ref IsSuspended, ref threadId, loggerName, false); + ChangeState( + suspend, + expectedAdress, + ref IsSuspended, + ref threadId, + loggerName, + false + ); return; } // The threadId was already reloaded - Logger.Warn($"Thread with id={threadId} and assigned as {loggerName} exists but could not be opened!"); + Logger.Warn( + $"Thread with id={threadId} and assigned as {loggerName} exists but could not be opened!" + ); return; } diff --git a/src/UniGetUI.Core.Tools/IntegrityTester.cs b/src/UniGetUI.Core.Tools/IntegrityTester.cs index 2915e710c1..121ad1d779 100644 --- a/src/UniGetUI.Core.Tools/IntegrityTester.cs +++ b/src/UniGetUI.Core.Tools/IntegrityTester.cs @@ -48,10 +48,15 @@ private static string GetSHA256(string fullPath, bool canRetry) public static Result CheckIntegrity(bool allowRetry = true) { - string integrityTreePath = Path.Join(CoreData.UniGetUIExecutableDirectory, "IntegrityTree.json"); + string integrityTreePath = Path.Join( + CoreData.UniGetUIExecutableDirectory, + "IntegrityTree.json" + ); if (!File.Exists(integrityTreePath)) { - Logger.Error("/IntegrityTree.json does not exist, integrity check will not be performed!"); + Logger.Error( + "/IntegrityTree.json does not exist, integrity check will not be performed!" + ); return new() { Passed = false, @@ -65,7 +70,10 @@ public static Result CheckIntegrity(bool allowRetry = true) try { - data = JsonSerializer.Deserialize>(rawData, SerializationHelpers.DefaultOptions); + data = JsonSerializer.Deserialize>( + rawData, + SerializationHelpers.DefaultOptions + ); } catch (Exception ex) { @@ -80,7 +88,12 @@ public static Result CheckIntegrity(bool allowRetry = true) Passed = false, MissingFiles = [], CorruptedFiles = new() - { {"", new MismatchedHash() {Got = rawData, Expected = "A valid JSON"} } }, + { + { + "", + new MismatchedHash() { Got = rawData, Expected = "A valid JSON" } + }, + }, }; } @@ -101,7 +114,9 @@ public static Result CheckIntegrity(bool allowRetry = true) if (currentHash != expectedHash.ToLower()) { mismatches.Add($"/{file}", new() { Expected = expectedHash, Got = currentHash }); - Logger.Error($"File {file} expected to have sha256 {expectedHash}, but had {currentHash} instead"); + Logger.Error( + $"File {file} expected to have sha256 {expectedHash}, but had {currentHash} instead" + ); } } @@ -109,7 +124,7 @@ public static Result CheckIntegrity(bool allowRetry = true) { Passed = !misses.Any() && !mismatches.Any(), MissingFiles = misses, - CorruptedFiles = mismatches + CorruptedFiles = mismatches, }; if (result.Passed) @@ -138,10 +153,12 @@ public static string GetReadableReport(Result result) { Builder.Append("Corrupted files: "); foreach (var (file, hashes) in result.CorruptedFiles) - Builder.Append($"\n - {file} (sha256 mismatch, got {hashes.Got} but expected {hashes.Expected} "); + Builder.Append( + $"\n - {file} (sha256 mismatch, got {hashes.Got} but expected {hashes.Expected} " + ); Builder.Append('\n'); } return Builder.ToString(); } -} \ No newline at end of file +} diff --git a/src/UniGetUI.Core.Tools/SerializationHelpers.cs b/src/UniGetUI.Core.Tools/SerializationHelpers.cs index 25e502d5aa..001ec0d1fb 100644 --- a/src/UniGetUI.Core.Tools/SerializationHelpers.cs +++ b/src/UniGetUI.Core.Tools/SerializationHelpers.cs @@ -9,28 +9,31 @@ namespace UniGetUI.Core.Data; public static class SerializationHelpers { - public static Task YAML_to_JSON(string YAML) - => Task.Run(() => yaml_to_json(YAML)); + public static Task YAML_to_JSON(string YAML) => Task.Run(() => yaml_to_json(YAML)); private static string yaml_to_json(string YAML) { var yamlObject = new YamlDotNet.Serialization.Deserializer().Deserialize(YAML); - if (yamlObject is null) return "{'message': 'deserialized YAML object was null'}"; + if (yamlObject is null) + return "{'message': 'deserialized YAML object was null'}"; return new YamlDotNet.Serialization.SerializerBuilder() .JsonCompatible() .Build() .Serialize(yamlObject); } - public static Task XML_to_JSON(string XML) - => Task.Run(() => xml_to_json(XML)); + public static Task XML_to_JSON(string XML) => Task.Run(() => xml_to_json(XML)); private static string xml_to_json(string XML) { var doc = new XmlDocument(); doc.LoadXml(XML); - if (doc.DocumentElement is null) return "{'message': 'XmlDocument.DocumentElement was null'}"; - return JsonSerializer.Serialize(_convertXmlNode(doc.DocumentElement), SerializationHelpers.DefaultOptions); + if (doc.DocumentElement is null) + return "{'message': 'XmlDocument.DocumentElement was null'}"; + return JsonSerializer.Serialize( + _convertXmlNode(doc.DocumentElement), + SerializationHelpers.DefaultOptions + ); } private static object? _convertXmlNode(XmlNode node) diff --git a/src/UniGetUI.Core.Tools/Tools.cs b/src/UniGetUI.Core.Tools/Tools.cs index 9e6a27dbaa..33734fe0df 100644 --- a/src/UniGetUI.Core.Tools/Tools.cs +++ b/src/UniGetUI.Core.Tools/Tools.cs @@ -5,14 +5,14 @@ using System.Security.Cryptography; using System.Security.Principal; using System.Text; -#if WINDOWS -using Windows.Networking.Connectivity; -#endif using UniGetUI.Core.Classes; using UniGetUI.Core.Data; using UniGetUI.Core.Language; using UniGetUI.Core.Logging; using UniGetUI.Core.SettingsEngine; +#if WINDOWS +using Windows.Networking.Connectivity; +#endif namespace UniGetUI.Core.Tools { @@ -26,13 +26,12 @@ public static HttpClientHandler GenericHttpClientParameters IWebProxy? proxy = null; ICredentials? creds = null; - if (Settings.Get(Settings.K.EnableProxy)) proxyUri = Settings.GetProxyUrl(); - if (Settings.Get(Settings.K.EnableProxyAuth)) creds = Settings.GetProxyCredentials(); - if (proxyUri is not null) proxy = new WebProxy() - { - Address = proxyUri, - Credentials = creds - }; + if (Settings.Get(Settings.K.EnableProxy)) + proxyUri = Settings.GetProxyUrl(); + if (Settings.Get(Settings.K.EnableProxyAuth)) + creds = Settings.GetProxyCredentials(); + if (proxyUri is not null) + proxy = new WebProxy() { Address = proxyUri, Credentials = creds }; return new() { @@ -117,7 +116,9 @@ public static List WhichMultiple(string command, bool updateEnv = true) { StartInfo = new ProcessStartInfo { - FileName = OperatingSystem.IsWindows() ? Path.Join(Environment.SystemDirectory, "where.exe") : "which", + FileName = OperatingSystem.IsWindows() + ? Path.Join(Environment.SystemDirectory, "where.exe") + : "which", Arguments = command, UseShellExecute = false, RedirectStandardOutput = true, @@ -125,7 +126,7 @@ public static List WhichMultiple(string command, bool updateEnv = true) CreateNoWindow = true, StandardOutputEncoding = GetCommandOutputEncoding(), StandardErrorEncoding = GetCommandOutputEncoding(), - } + }, }; if (updateEnv) { @@ -136,13 +137,16 @@ public static List WhichMultiple(string command, bool updateEnv = true) try { process.Start(); - string[] lines = process.StandardOutput.ReadToEnd() + string[] lines = process + .StandardOutput.ReadToEnd() .Split(["\r\n", "\n"], StringSplitOptions.RemoveEmptyEntries); process.WaitForExit(); if (process.ExitCode is not 0) - Logger.Warn($"Call to WhichMultiple with file {command} returned non-zero status {process.ExitCode}"); + Logger.Warn( + $"Call to WhichMultiple with file {command} returned non-zero status {process.ExitCode}" + ); if (lines.Length is 0) { @@ -150,12 +154,15 @@ public static List WhichMultiple(string command, bool updateEnv = true) return []; } - Logger.Debug($"Command {command} was found on {lines[0]} (with {lines.Length-1} more occurrences)"); + Logger.Debug( + $"Command {command} was found on {lines[0]} (with {lines.Length - 1} more occurrences)" + ); return lines.ToList(); } catch { - if (updateEnv) return WhichMultiple(command, false); + if (updateEnv) + return WhichMultiple(command, false); throw; } } @@ -163,7 +170,7 @@ public static List WhichMultiple(string command, bool updateEnv = true) public static Tuple Which(string command, bool updateEnv = true) { var paths = WhichMultiple(command, updateEnv); - return new(paths.Any(), paths.Any() ? paths[0]: ""); + return new(paths.Any(), paths.Any() ? paths[0] : ""); } /// @@ -173,13 +180,20 @@ public static Tuple Which(string command, bool updateEnv = true) /// The formatted string public static string FormatAsName(string name) { - name = - name.Replace(".install", "").Replace(".portable", "").Replace("-", " ").Replace("_", " ").Split("/")[^1] - .Split(":")[0]; + name = name.Replace(".install", "") + .Replace(".portable", "") + .Replace("-", " ") + .Replace("_", " ") + .Split("/")[^1] + .Split(":")[0]; string newName = ""; for (int i = 0; i < name.Length; i++) { - if (i == 0 || name[i - 1] == ' ' || name[i - 1] == '[' /* for vcpkg options */) + if ( + i == 0 + || name[i - 1] == ' ' + || name[i - 1] == '[' /* for vcpkg options */ + ) { newName += name[i].ToString().ToUpper(); } @@ -202,7 +216,8 @@ public static string RandomString(int length) { Random random = new(); const string pool = "abcdefghijklmnopqrstuvwxyz0123456789"; - IEnumerable chars = Enumerable.Range(0, length) + IEnumerable chars = Enumerable + .Range(0, length) .Select(_ => pool[random.Next(0, pool.Length)]); return new string(chars.ToArray()); } @@ -213,7 +228,11 @@ public static string RandomString(int length) /// The path of the batch file /// The title of the window /// Whether the batch file should be launched elevated or not - public static async Task LaunchBatchFile(string path, string WindowTitle = "", bool RunAsAdmin = false) + public static async Task LaunchBatchFile( + string path, + string WindowTitle = "", + bool RunAsAdmin = false + ) { try { @@ -254,8 +273,9 @@ public static bool IsAdministrator() return string.Equals(Environment.UserName, "root", StringComparison.Ordinal); } - return new WindowsPrincipal(WindowsIdentity.GetCurrent()) - .IsInRole(WindowsBuiltInRole.Administrator); + return new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole( + WindowsBuiltInRole.Administrator + ); } catch (Exception e) { @@ -265,17 +285,20 @@ public static bool IsAdministrator() } } - public static Task GetFileSizeAsLongAsync(Uri? url) - => Task.Run(() => GetFileSizeAsLong(url)); + public static Task GetFileSizeAsLongAsync(Uri? url) => + Task.Run(() => GetFileSizeAsLong(url)); public static long GetFileSizeAsLong(Uri? url) { - if (url is null) return 0; + if (url is null) + return 0; try { using HttpClient client = new(CoreTools.GenericHttpClientParameters); - HttpResponseMessage response = client.Send(new HttpRequestMessage(HttpMethod.Head, url)); + HttpResponseMessage response = client.Send( + new HttpRequestMessage(HttpMethod.Head, url) + ); return response.Content.Headers.ContentLength ?? 0; } catch (Exception e) @@ -294,17 +317,29 @@ public static string GetFileName(Uri url) var handler = CoreTools.GenericHttpClientParameters; handler.AllowAutoRedirect = false; using HttpClient client = new(handler); - HttpResponseMessage response = client.Send(new HttpRequestMessage(HttpMethod.Head, url)); - - if (response.StatusCode is HttpStatusCode.Moved or HttpStatusCode.Redirect - or HttpStatusCode.RedirectMethod or HttpStatusCode.TemporaryRedirect - or HttpStatusCode.PermanentRedirect) + HttpResponseMessage response = client.Send( + new HttpRequestMessage(HttpMethod.Head, url) + ); + + if ( + response.StatusCode + is HttpStatusCode.Moved + or HttpStatusCode.Redirect + or HttpStatusCode.RedirectMethod + or HttpStatusCode.TemporaryRedirect + or HttpStatusCode.PermanentRedirect + ) { - return GetFileName(response.Headers.Location ?? - throw new HttpRequestException("A redirect code was returned but no new location was given")); + return GetFileName( + response.Headers.Location + ?? throw new HttpRequestException( + "A redirect code was returned but no new location was given" + ) + ); } - return response.Content.Headers.ContentDisposition?.FileName ?? Path.GetFileName(url.LocalPath); + return response.Content.Headers.ContentDisposition?.FileName + ?? Path.GetFileName(url.LocalPath); } catch (Exception e) { @@ -314,10 +349,9 @@ or HttpStatusCode.RedirectMethod or HttpStatusCode.TemporaryRedirect } } - public static Task GetFileNameAsync(Uri url) - => Task.Run(() => GetFileName(url)); + public static Task GetFileNameAsync(Uri url) => Task.Run(() => GetFileName(url)); - public struct Version: IComparable + public struct Version : IComparable { public static readonly Version Null = new(-1, -1, -1, -1); @@ -336,46 +370,49 @@ public Version(int major, int minor = 0, int patch = 0, int remainder = 0) public int CompareTo(object? other_) { - if (other_ is not Version other) return 0; + if (other_ is not Version other) + return 0; int major = Major.CompareTo(other.Major); - if (major != 0) return major; + if (major != 0) + return major; int minor = Minor.CompareTo(other.Minor); - if (minor != 0) return minor; + if (minor != 0) + return minor; int patch = Patch.CompareTo(other.Patch); - if (patch != 0) return patch; + if (patch != 0) + return patch; return Remainder.CompareTo(other.Remainder); } - public static bool operator ==(Version left, Version right) - => left.CompareTo(right) == 0; + public static bool operator ==(Version left, Version right) => + left.CompareTo(right) == 0; - public static bool operator !=(Version left, Version right) - => left.CompareTo(right) != 0; + public static bool operator !=(Version left, Version right) => + left.CompareTo(right) != 0; - public static bool operator >=(Version left, Version right) - => left.CompareTo(right) >= 0; + public static bool operator >=(Version left, Version right) => + left.CompareTo(right) >= 0; - public static bool operator <=(Version left, Version right) - => left.CompareTo(right) <= 0; + public static bool operator <=(Version left, Version right) => + left.CompareTo(right) <= 0; - public static bool operator >(Version left, Version right) - => left.CompareTo(right) > 0; + public static bool operator >(Version left, Version right) => left.CompareTo(right) > 0; - public static bool operator <(Version left, Version right) - => left.CompareTo(right) < 0; + public static bool operator <(Version left, Version right) => left.CompareTo(right) < 0; - public bool Equals(Version other) - => Major == other.Major && Minor == other.Minor && Patch == other.Patch && Remainder == other.Remainder; + public bool Equals(Version other) => + Major == other.Major + && Minor == other.Minor + && Patch == other.Patch + && Remainder == other.Remainder; - public override bool Equals(object? obj) - => obj is Version other && Equals(other); + public override bool Equals(object? obj) => obj is Version other && Equals(other); - public override int GetHashCode() - => HashCode.Combine(Major, Minor, Patch, Remainder); + public override int GetHashCode() => HashCode.Combine(Major, Minor, Patch, Remainder); } /// @@ -395,8 +432,11 @@ public static Version VersionStringToStruct(string Version) foreach (char c in Version) { - if (char.IsDigit(c)) versionItems[dotCount] += c; - else if (!first && separators.Contains(c)) if (dotCount < 3) dotCount++; + if (char.IsDigit(c)) + versionItems[dotCount] += c; + else if (!first && separators.Contains(c)) + if (dotCount < 3) + dotCount++; first = false; } @@ -424,7 +464,8 @@ public static Version VersionStringToStruct(string Version) /// The safe version of the query public static string EnsureSafeQueryString(string query) { - return query.Replace(";", string.Empty) + return query + .Replace(";", string.Empty) .Replace("&", string.Empty) .Replace("|", string.Empty) .Replace(">", string.Empty) @@ -473,15 +514,19 @@ public static string EnsureSafeQueryString(string query) /// Enables GSudo cache for the current process /// private static bool _isCaching; + public static async Task CacheUACForCurrentProcess() { if (Settings.Get(Settings.K.ProhibitElevation)) { - Logger.Error("Elevation is prohibited, CacheUACForCurrentProcess() call will be ignored"); + Logger.Error( + "Elevation is prohibited, CacheUACForCurrentProcess() call will be ignored" + ); return; } - while (_isCaching) await Task.Delay(100); + while (_isCaching) + await Task.Delay(100); try { @@ -499,7 +544,7 @@ public static async Task CacheUACForCurrentProcess() RedirectStandardInput = true, CreateNoWindow = true, StandardOutputEncoding = Encoding.UTF8, - } + }, }; p.Start(); await p.WaitForExitAsync(); @@ -519,11 +564,15 @@ public static async Task ResetUACForCurrentProcess() { if (Settings.Get(Settings.K.ProhibitElevation)) { - Logger.Error("Elevation is prohibited, ResetUACForCurrentProcess() call will be ignored"); + Logger.Error( + "Elevation is prohibited, ResetUACForCurrentProcess() call will be ignored" + ); return; } - Logger.Info("Resetting administrator rights cache for process id " + Environment.ProcessId); + Logger.Info( + "Resetting administrator rights cache for process id " + Environment.ProcessId + ); using Process p = new() { StartInfo = new ProcessStartInfo @@ -536,7 +585,7 @@ public static async Task ResetUACForCurrentProcess() RedirectStandardInput = true, CreateNoWindow = true, StandardOutputEncoding = Encoding.UTF8, - } + }, }; p.Start(); await p.WaitForExitAsync(); @@ -565,7 +614,9 @@ public static void CreateSymbolicLinkDir(string linkPath, string targetPath) if (!Directory.Exists(linkPath)) { - throw new InvalidOperationException($"The symbolic link '{linkPath}' was not created successfully."); + throw new InvalidOperationException( + $"The symbolic link '{linkPath}' was not created successfully." + ); } } @@ -610,17 +661,29 @@ public static ProcessStartInfo UpdateEnvironmentVariables(ProcessStartInfo info) return info; } - foreach (DictionaryEntry env in Environment.GetEnvironmentVariables(EnvironmentVariableTarget.Machine)) + foreach ( + DictionaryEntry env in Environment.GetEnvironmentVariables( + EnvironmentVariableTarget.Machine + ) + ) { info.Environment[env.Key?.ToString() ?? "UNKNOWN"] = env.Value?.ToString(); } - foreach (DictionaryEntry env in Environment.GetEnvironmentVariables(EnvironmentVariableTarget.User)) + foreach ( + DictionaryEntry env in Environment.GetEnvironmentVariables( + EnvironmentVariableTarget.User + ) + ) { string key = env.Key.ToString() ?? ""; string newValue = env.Value?.ToString() ?? ""; - if (info.Environment.TryGetValue(key, out string? oldValue) && oldValue is not null && - oldValue.Contains(';') && newValue != "") + if ( + info.Environment.TryGetValue(key, out string? oldValue) + && oldValue is not null + && oldValue.Contains(';') + && newValue != "" + ) { info.Environment[key] = oldValue + ";" + newValue; } @@ -636,25 +699,32 @@ public static ProcessStartInfo UpdateEnvironmentVariables(ProcessStartInfo info) /// /// Pings the update server and 3 well-known sites to check for internet availability /// - public static async Task WaitForInternetConnection() - => await TaskRecycler.RunOrAttachAsync_VOID(_waitForInternetConnection); + public static async Task WaitForInternetConnection() => + await TaskRecycler.RunOrAttachAsync_VOID(_waitForInternetConnection); public static void _waitForInternetConnection() { - if (Settings.Get(Settings.K.DisableWaitForInternetConnection)) return; + if (Settings.Get(Settings.K.DisableWaitForInternetConnection)) + return; Logger.Debug("Checking for internet connectivity..."); bool internetLost = false; #if WINDOWS var profile = NetworkInformation.GetInternetConnectionProfile(); - while (profile is null || profile.GetNetworkConnectivityLevel() is not NetworkConnectivityLevel.InternetAccess) + while ( + profile is null + || profile.GetNetworkConnectivityLevel() + is not NetworkConnectivityLevel.InternetAccess + ) { Thread.Sleep(1000); profile = NetworkInformation.GetInternetConnectionProfile(); if (!internetLost) { - Logger.Warn("User is not connected to the internet, waiting for an internet connectio to be available..."); + Logger.Warn( + "User is not connected to the internet, waiting for an internet connectio to be available..." + ); internetLost = true; } } @@ -664,7 +734,9 @@ public static void _waitForInternetConnection() Thread.Sleep(1000); if (!internetLost) { - Logger.Warn("User is not connected to the internet, waiting for an internet connection to be available..."); + Logger.Warn( + "User is not connected to the internet, waiting for an internet connection to be available..." + ); internetLost = true; } } @@ -687,9 +759,7 @@ public static string TextProgressGenerator(int length, int progressPercent, stri if (extra is not null) { - builder.Append(" (") - .Append(extra) - .Append(')'); + builder.Append(" (").Append(extra).Append(')'); } return builder.ToString(); @@ -729,7 +799,8 @@ public static async Task ShowFileOnExplorer(string path) { try { - if (!File.Exists(path)) throw new FileNotFoundException($"The file {path} was not found"); + if (!File.Exists(path)) + throw new FileNotFoundException($"The file {path} was not found"); if (!OperatingSystem.IsWindows()) { @@ -745,7 +816,7 @@ public static async Task ShowFileOnExplorer(string path) Arguments = $"/select, \"{path}\"", UseShellExecute = true, CreateNoWindow = true, - } + }, }; p.Start(); await p.WaitForExitAsync(); @@ -761,7 +832,8 @@ public static void Launch(string? path) { try { - if (path is null) return; + if (path is null) + return; var p = new Process() { @@ -770,7 +842,7 @@ public static void Launch(string? path) FileName = path, UseShellExecute = true, CreateNoWindow = true, - } + }, }; p.Start(); } @@ -785,16 +857,18 @@ public static string GetCurrentLocale() return LanguageEngine?.Locale ?? "Unset/Unknown"; } - private static readonly HashSet _illegalPathChars = Path.GetInvalidFileNameChars().ToHashSet(); - public static string MakeValidFileName(string name) - => string.Concat(name.Where(x => !_illegalPathChars.Contains(x))); + private static readonly HashSet _illegalPathChars = Path.GetInvalidFileNameChars() + .ToHashSet(); + + public static string MakeValidFileName(string name) => + string.Concat(name.Where(x => !_illegalPathChars.Contains(x))); // Safely wait for a task that may throw an exception we don't care about public static async void FinalizeDangerousTask(Task t) { try { - await t.ConfigureAwait(false); + await t.ConfigureAwait(false); } catch (Exception ex) { @@ -803,9 +877,10 @@ public static async void FinalizeDangerousTask(Task t) } } - private static Encoding GetCommandOutputEncoding() - => OperatingSystem.IsWindows() - ? CodePagesEncodingProvider.Instance.GetEncoding(CoreData.CODE_PAGE) ?? Encoding.UTF8 + private static Encoding GetCommandOutputEncoding() => + OperatingSystem.IsWindows() + ? CodePagesEncodingProvider.Instance.GetEncoding(CoreData.CODE_PAGE) + ?? Encoding.UTF8 : Encoding.UTF8; private static string GetSearchPath() @@ -816,9 +891,19 @@ private static string GetSearchPath() } string separator = Path.PathSeparator.ToString(); - string pathValue = (Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.User) ?? string.Empty) + separator; - pathValue += (Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Machine) ?? string.Empty) + separator; - pathValue += Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Process) ?? string.Empty; + string pathValue = + ( + Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.User) + ?? string.Empty + ) + separator; + pathValue += + ( + Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Machine) + ?? string.Empty + ) + separator; + pathValue += + Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Process) + ?? string.Empty; return pathValue.Replace(separator + separator, separator).Trim(Path.PathSeparator); } } diff --git a/src/UniGetUI.Core.Tools/UniGetUI.Core.Tools.csproj b/src/UniGetUI.Core.Tools/UniGetUI.Core.Tools.csproj index a378f23844..bede05c870 100644 --- a/src/UniGetUI.Core.Tools/UniGetUI.Core.Tools.csproj +++ b/src/UniGetUI.Core.Tools/UniGetUI.Core.Tools.csproj @@ -1,13 +1,16 @@ + + $(SharedTargetFrameworks) + - - - - - - + + + + + + - - - + + + diff --git a/src/UniGetUI.Interface.BackgroundApi/BackgroundApi.cs b/src/UniGetUI.Interface.BackgroundApi/BackgroundApi.cs index 8c32acc407..ed0e0e552a 100644 --- a/src/UniGetUI.Interface.BackgroundApi/BackgroundApi.cs +++ b/src/UniGetUI.Interface.BackgroundApi/BackgroundApi.cs @@ -1,9 +1,9 @@ +using System.Text; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.Hosting; -using System.Text; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; using UniGetUI.Core.Data; using UniGetUI.Core.IconEngine; using UniGetUI.Core.Logging; @@ -32,9 +32,7 @@ public class BackgroundApiRunner private IHost? _host; - public BackgroundApiRunner() - { - } + public BackgroundApiRunner() { } public static bool AuthenticateToken(string? token) { @@ -56,32 +54,41 @@ public async Task Start() webBuilder.SuppressStatusMessages(true); #endif webBuilder.Configure(app => + { + app.UseCors(policy => + policy.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader() + ); + + app.UseRouting(); + app.UseEndpoints(endpoints => { - app.UseCors(policy => policy - .AllowAnyOrigin() - .AllowAnyMethod() - .AllowAnyHeader() + // Share endpoints + endpoints.MapGet("/v2/show-package", V2_ShowPackage); + endpoints.MapGet("/is-running", API_IsRunning); + // Widgets v1 API + endpoints.MapGet( + "/widgets/v1/get_wingetui_version", + WIDGETS_V1_GetUniGetUIVersion + ); + endpoints.MapGet("/widgets/v1/get_updates", WIDGETS_V1_GetUpdates); + endpoints.MapGet("/widgets/v1/open_wingetui", WIDGETS_V1_OpenUniGetUI); + endpoints.MapGet("/widgets/v1/view_on_wingetui", WIDGETS_V1_ViewOnUniGetUI); + endpoints.MapGet("/widgets/v1/update_package", WIDGETS_V1_UpdatePackage); + endpoints.MapGet( + "/widgets/v1/update_all_packages", + WIDGETS_V1_UpdateAllPackages + ); + endpoints.MapGet( + "/widgets/v1/update_all_packages_for_source", + WIDGETS_V1_UpdateAllPackagesForSource + ); + // Widgets v2 API + endpoints.MapGet( + "/widgets/v2/get_icon_for_package", + WIDGETS_V2_GetIconForPackage ); - - app.UseRouting(); - app.UseEndpoints(endpoints => - { - // Share endpoints - endpoints.MapGet("/v2/show-package", V2_ShowPackage); - endpoints.MapGet("/is-running", API_IsRunning); - // Widgets v1 API - endpoints.MapGet("/widgets/v1/get_wingetui_version", WIDGETS_V1_GetUniGetUIVersion); - endpoints.MapGet("/widgets/v1/get_updates", WIDGETS_V1_GetUpdates); - endpoints.MapGet("/widgets/v1/open_wingetui", WIDGETS_V1_OpenUniGetUI); - endpoints.MapGet("/widgets/v1/view_on_wingetui", WIDGETS_V1_ViewOnUniGetUI); - endpoints.MapGet("/widgets/v1/update_package", WIDGETS_V1_UpdatePackage); - endpoints.MapGet("/widgets/v1/update_all_packages", WIDGETS_V1_UpdateAllPackages); - endpoints.MapGet("/widgets/v1/update_all_packages_for_source", - WIDGETS_V1_UpdateAllPackagesForSource); - // Widgets v2 API - endpoints.MapGet("/widgets/v2/get_icon_for_package", WIDGETS_V2_GetIconForPackage); - }); }); + }); webBuilder.UseUrls("http://localhost:7058"); }); _host = builder.Build(); @@ -89,7 +96,7 @@ public async Task Start() Logger.Info("Api running on http://localhost:7058"); } - private async Task V2_ShowPackage(HttpContext context) + private async Task V2_ShowPackage(HttpContext context) { var query = context.Request.Query; if (string.IsNullOrEmpty(query["pid"]) || string.IsNullOrEmpty(query["psource"])) @@ -100,7 +107,10 @@ private async Task V2_ShowPackage(HttpContext context) string packageId = query["pid"].ToString(); string packageSource = query["psource"].ToString(); - OnShowSharedPackage?.Invoke(null, new KeyValuePair(packageId, packageSource)); + OnShowSharedPackage?.Invoke( + null, + new KeyValuePair(packageId, packageSource) + ); await context.Response.WriteAsync("{\"status\": \"success\"}"); } @@ -129,7 +139,10 @@ private async Task WIDGETS_V1_GetUpdates(HttpContext context) return; } - if (!UpgradablePackagesLoader.Instance.IsLoaded && !UpgradablePackagesLoader.Instance.IsLoading) + if ( + !UpgradablePackagesLoader.Instance.IsLoaded + && !UpgradablePackagesLoader.Instance.IsLoading + ) { _ = UpgradablePackagesLoader.Instance.ReloadPackages(); } @@ -142,14 +155,25 @@ private async Task WIDGETS_V1_GetUpdates(HttpContext context) StringBuilder packages = new(); foreach (IPackage package in UpgradablePackagesLoader.Instance.Packages) { - if (package.Tag is PackageTag.OnQueue or PackageTag.BeingProcessed) continue; - - string icon = $"http://localhost:7058/widgets/v2/get_icon_for_package?packageId={Uri.EscapeDataString(package.Id)}&packageSource={Uri.EscapeDataString(package.Source.Name)}&token={ApiTokenHolder.Token}"; - packages.Append($"{package.Name.Replace('|', '-')}" + $"|{package.Id}" + $"|{package.VersionString}" + $"|{package.NewVersionString}" + $"|{package.Source.AsString_DisplayName}" + $"|{package.Manager.Name}" + $"|{icon}&&"); + if (package.Tag is PackageTag.OnQueue or PackageTag.BeingProcessed) + continue; + + string icon = + $"http://localhost:7058/widgets/v2/get_icon_for_package?packageId={Uri.EscapeDataString(package.Id)}&packageSource={Uri.EscapeDataString(package.Source.Name)}&token={ApiTokenHolder.Token}"; + packages.Append( + $"{package.Name.Replace('|', '-')}" + + $"|{package.Id}" + + $"|{package.VersionString}" + + $"|{package.NewVersionString}" + + $"|{package.Source.AsString_DisplayName}" + + $"|{package.Manager.Name}" + + $"|{icon}&&" + ); } string result = packages.ToString(); - if (result.Length > 2) result = result[..(result.Length - 2)]; + if (result.Length > 2) + result = result[..(result.Length - 2)]; await context.Response.WriteAsync(result); } @@ -248,17 +272,35 @@ private async Task WIDGETS_V2_GetIconForPackage(HttpContext context) return; } - string iconPath = Path.Join(CoreData.UniGetUIExecutableDirectory, "Assets", "Images", "package_color.png"); + string iconPath = Path.Join( + CoreData.UniGetUIExecutableDirectory, + "Assets", + "Images", + "package_color.png" + ); string resolvedPackageId = packageId.ToString(); - IPackage? package = UpgradablePackagesLoader.Instance.GetPackageForId(resolvedPackageId, packageSource); + IPackage? package = UpgradablePackagesLoader.Instance.GetPackageForId( + resolvedPackageId, + packageSource + ); if (package != null) { var iconUrl = await Task.Run(package.GetIconUrl); if (iconUrl.ToString() != "ms-appx:///Assets/Images/package_color.png") { - string mimePath = Path.Join(CoreData.UniGetUICacheDirectory_Icons, package.Manager.Name, package.Id, "icon.mime"); - iconPath = Path.Join(CoreData.UniGetUICacheDirectory_Icons, package.Manager.Name, package.Id, $"icon.{IconCacheEngine.MimeToExtension[await File.ReadAllTextAsync(mimePath)]}"); + string mimePath = Path.Join( + CoreData.UniGetUICacheDirectory_Icons, + package.Manager.Name, + package.Id, + "icon.mime" + ); + iconPath = Path.Join( + CoreData.UniGetUICacheDirectory_Icons, + package.Manager.Name, + package.Id, + $"icon.{IconCacheEngine.MimeToExtension[await File.ReadAllTextAsync(mimePath)]}" + ); } } else @@ -268,7 +310,10 @@ private async Task WIDGETS_V2_GetIconForPackage(HttpContext context) var bytes = await File.ReadAllBytesAsync(iconPath); var ext = Path.GetExtension(iconPath).TrimStart('.').ToLower(); - context.Response.ContentType = IconCacheEngine.ExtensionToMime.GetValueOrDefault(ext, "image/png"); + context.Response.ContentType = IconCacheEngine.ExtensionToMime.GetValueOrDefault( + ext, + "image/png" + ); await context.Response.Body.WriteAsync(bytes.AsMemory()); } diff --git a/src/UniGetUI.Interface.BackgroundApi/UniGetUI.Interface.BackgroundApi.csproj b/src/UniGetUI.Interface.BackgroundApi/UniGetUI.Interface.BackgroundApi.csproj index 95bc771584..0742cb6ac3 100644 --- a/src/UniGetUI.Interface.BackgroundApi/UniGetUI.Interface.BackgroundApi.csproj +++ b/src/UniGetUI.Interface.BackgroundApi/UniGetUI.Interface.BackgroundApi.csproj @@ -1,27 +1,30 @@ + + $(SharedTargetFrameworks) + - - - - - - - + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + + diff --git a/src/UniGetUI.Interface.Enums/Enums.cs b/src/UniGetUI.Interface.Enums/Enums.cs index a805e5f951..730f02ab61 100644 --- a/src/UniGetUI.Interface.Enums/Enums.cs +++ b/src/UniGetUI.Interface.Enums/Enums.cs @@ -12,7 +12,7 @@ public enum PackageTag OnQueue, BeingProcessed, Failed, - Unavailable + Unavailable, } public enum IconType @@ -83,7 +83,7 @@ public enum IconType Warning_Round = '\uE93F', WinGet = '\uE940', Rust = '\uE941', - Vcpkg = '\uE942' + Vcpkg = '\uE942', } public class NotificationArguments @@ -110,7 +110,7 @@ public struct BundleReport { public bool IsEmpty = false; public Dictionary> Contents = new(); - public BundleReport() - {} + + public BundleReport() { } } } diff --git a/src/UniGetUI.Interface.Enums/UniGetUI.Interface.Enums.csproj b/src/UniGetUI.Interface.Enums/UniGetUI.Interface.Enums.csproj index 6c35193aa1..3b1ea6e421 100644 --- a/src/UniGetUI.Interface.Enums/UniGetUI.Interface.Enums.csproj +++ b/src/UniGetUI.Interface.Enums/UniGetUI.Interface.Enums.csproj @@ -1,6 +1,9 @@ + + $(SharedTargetFrameworks) + - - - + + + diff --git a/src/UniGetUI.Interface.Telemetry/TelemetryHandler.cs b/src/UniGetUI.Interface.Telemetry/TelemetryHandler.cs index 8765a87b3e..cf17d40aa4 100644 --- a/src/UniGetUI.Interface.Telemetry/TelemetryHandler.cs +++ b/src/UniGetUI.Interface.Telemetry/TelemetryHandler.cs @@ -21,7 +21,7 @@ public enum TEL_OP_RESULT { SUCCESS, FAILED, - CANCELED + CANCELED, } public static class TelemetryHandler @@ -45,15 +45,17 @@ public static class TelemetryHandler Settings.K.DoCacheAdminRights, Settings.K.DoCacheAdminRightsForBatches, Settings.K.ForceLegacyBundledWinGet, - Settings.K.UseSystemChocolatey + Settings.K.UseSystemChocolatey, ]; + // ------------------------------------------------------------------------- public static async Task InitializeAsync() { try { - if (Settings.Get(Settings.K.DisableTelemetry)) return; + if (Settings.Get(Settings.K.DisableTelemetry)) + return; await CoreTools.WaitForInternetConnection(); string ID = GetRandomizedId(); @@ -62,9 +64,11 @@ public static async Task InitializeAsync() foreach (var manager in PEInterface.Managers) { - if (manager.IsEnabled()) ManagerMagicValue |= mask; + if (manager.IsEnabled()) + ManagerMagicValue |= mask; mask = mask << 1; - if (manager.IsEnabled() && manager.Status.Found) ManagerMagicValue |= mask; + if (manager.IsEnabled() && manager.Status.Found) + ManagerMagicValue |= mask; mask = mask << 1; if (mask == 0x1) @@ -80,20 +84,25 @@ public static async Task InitializeAsync() invert: Settings.ResolveKey(setting).StartsWith("Disable") ); - if (enabled) SettingsMagicValue |= mask; + if (enabled) + SettingsMagicValue |= mask; mask = mask << 1; if (mask == 0x1) throw new OverflowException(); } - foreach (var setting in new []{"SP1", "SP2"}) + foreach (var setting in new[] { "SP1", "SP2" }) { bool enabled; - if (setting == "SP1") enabled = File.Exists("ForceUniGetUIPortable"); - else if (setting == "SP2") enabled = CoreData.WasDaemon; - else throw new NotImplementedException(); - - if (enabled) SettingsMagicValue |= mask; + if (setting == "SP1") + enabled = File.Exists("ForceUniGetUIPortable"); + else if (setting == "SP2") + enabled = CoreData.WasDaemon; + else + throw new NotImplementedException(); + + if (enabled) + SettingsMagicValue |= mask; mask = mask << 1; if (mask == 0x1) @@ -118,7 +127,9 @@ public static async Task InitializeAsync() } else { - Logger.Warn($"[Telemetry] Call to /activity failed with error code {response.StatusCode}"); + Logger.Warn( + $"[Telemetry] Call to /activity failed with error code {response.StatusCode}" + ); } } catch (Exception ex) @@ -130,30 +141,43 @@ public static async Task InitializeAsync() // ------------------------------------------------------------------------- - public static void InstallPackage(IPackage package, TEL_OP_RESULT status, TEL_InstallReferral source) - => PackageEndpoint(package, "install", status, source.ToString()); + public static void InstallPackage( + IPackage package, + TEL_OP_RESULT status, + TEL_InstallReferral source + ) => PackageEndpoint(package, "install", status, source.ToString()); - public static void UpdatePackage(IPackage package, TEL_OP_RESULT status) - => PackageEndpoint(package, "update", status); + public static void UpdatePackage(IPackage package, TEL_OP_RESULT status) => + PackageEndpoint(package, "update", status); - public static void DownloadPackage(IPackage package, TEL_OP_RESULT status, TEL_InstallReferral source) - => PackageEndpoint(package, "download", status, source.ToString()); + public static void DownloadPackage( + IPackage package, + TEL_OP_RESULT status, + TEL_InstallReferral source + ) => PackageEndpoint(package, "download", status, source.ToString()); - public static void UninstallPackage(IPackage package, TEL_OP_RESULT status) - => PackageEndpoint(package, "uninstall", status); + public static void UninstallPackage(IPackage package, TEL_OP_RESULT status) => + PackageEndpoint(package, "uninstall", status); - public static void PackageDetails(IPackage package, string eventSource) - => PackageEndpoint(package, "details", eventSource: eventSource); + public static void PackageDetails(IPackage package, string eventSource) => + PackageEndpoint(package, "details", eventSource: eventSource); - public static void SharedPackage(IPackage package, string eventSource) - => PackageEndpoint(package, "share", eventSource: eventSource); + public static void SharedPackage(IPackage package, string eventSource) => + PackageEndpoint(package, "share", eventSource: eventSource); - private static async void PackageEndpoint(IPackage package, string endpoint, TEL_OP_RESULT? result = null, string? eventSource = null) + private static async void PackageEndpoint( + IPackage package, + string endpoint, + TEL_OP_RESULT? result = null, + string? eventSource = null + ) { try { - if (result is null && eventSource is null) throw new ArgumentException("result and eventSource cannot both be null"); - if (Settings.Get(Settings.K.DisableTelemetry)) return; + if (result is null && eventSource is null) + throw new ArgumentException("result and eventSource cannot both be null"); + if (Settings.Get(Settings.K.DisableTelemetry)) + return; await CoreTools.WaitForInternetConnection(); string ID = GetRandomizedId(); @@ -164,8 +188,10 @@ private static async void PackageEndpoint(IPackage package, string endpoint, TEL request.Headers.Add("packageId", package.Id); request.Headers.Add("managerName", package.Manager.Name); request.Headers.Add("sourceName", package.Source.Name); - if(result is not null) request.Headers.Add("operationResult", result.ToString()); - if(eventSource is not null) request.Headers.Add("eventSource", eventSource); + if (result is not null) + request.Headers.Add("operationResult", result.ToString()); + if (eventSource is not null) + request.Headers.Add("eventSource", eventSource); HttpClient _httpClient = new(CoreTools.GenericHttpClientParameters); _httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(CoreData.UserAgentString); @@ -177,7 +203,9 @@ private static async void PackageEndpoint(IPackage package, string endpoint, TEL } else { - Logger.Warn($"[Telemetry] Call to /package/{endpoint} failed with error code {response.StatusCode}"); + Logger.Warn( + $"[Telemetry] Call to /package/{endpoint} failed with error code {response.StatusCode}" + ); } } catch (Exception ex) @@ -189,20 +217,20 @@ private static async void PackageEndpoint(IPackage package, string endpoint, TEL // ------------------------------------------------------------------------- - public static void ImportBundle(BundleFormatType type) - => BundlesEndpoint("import", type.ToString()); + public static void ImportBundle(BundleFormatType type) => + BundlesEndpoint("import", type.ToString()); - public static void ExportBundle(BundleFormatType type) - => BundlesEndpoint("export", type.ToString()); + public static void ExportBundle(BundleFormatType type) => + BundlesEndpoint("export", type.ToString()); - public static void ExportBatch() - => BundlesEndpoint("export", "PS1_SCRIPT"); + public static void ExportBatch() => BundlesEndpoint("export", "PS1_SCRIPT"); private static async void BundlesEndpoint(string endpoint, string type) { try { - if (Settings.Get(Settings.K.DisableTelemetry)) return; + if (Settings.Get(Settings.K.DisableTelemetry)) + return; await CoreTools.WaitForInternetConnection(); string ID = GetRandomizedId(); @@ -222,7 +250,9 @@ private static async void BundlesEndpoint(string endpoint, string type) } else { - Logger.Warn($"[Telemetry] Call to /bundles/{endpoint} failed with error code {response.StatusCode}"); + Logger.Warn( + $"[Telemetry] Call to /bundles/{endpoint} failed with error code {response.StatusCode}" + ); } } catch (Exception ex) diff --git a/src/UniGetUI.Interface.Telemetry/UniGetUI.Interface.Telemetry.csproj b/src/UniGetUI.Interface.Telemetry/UniGetUI.Interface.Telemetry.csproj index 7a7abce30e..79676932b2 100644 --- a/src/UniGetUI.Interface.Telemetry/UniGetUI.Interface.Telemetry.csproj +++ b/src/UniGetUI.Interface.Telemetry/UniGetUI.Interface.Telemetry.csproj @@ -1,4 +1,7 @@ + + $(SharedTargetFrameworks) + false @@ -18,5 +21,4 @@ - diff --git a/src/UniGetUI.PAckageEngine.Interfaces/IManagerLogger.cs b/src/UniGetUI.PAckageEngine.Interfaces/IManagerLogger.cs index 09ec058aa9..1dc9f903bf 100644 --- a/src/UniGetUI.PAckageEngine.Interfaces/IManagerLogger.cs +++ b/src/UniGetUI.PAckageEngine.Interfaces/IManagerLogger.cs @@ -2,6 +2,7 @@ using UniGetUI.PackageEngine.Enums; namespace UniGetUI.PackageEngine.ManagerClasses.Classes; + public interface IManagerLogger { public IReadOnlyList Operations { get; } diff --git a/src/UniGetUI.PAckageEngine.Interfaces/IPackageManager.cs b/src/UniGetUI.PAckageEngine.Interfaces/IPackageManager.cs index cb898fc0dd..b7d16a8337 100644 --- a/src/UniGetUI.PAckageEngine.Interfaces/IPackageManager.cs +++ b/src/UniGetUI.PAckageEngine.Interfaces/IPackageManager.cs @@ -74,6 +74,5 @@ public interface IPackageManager /// public IReadOnlyList FindCandidateExecutableFiles(); public Tuple GetExecutableFile(); - } } diff --git a/src/UniGetUI.PAckageEngine.Interfaces/ManagerDependency.cs b/src/UniGetUI.PAckageEngine.Interfaces/ManagerDependency.cs index 6072783b1d..7eafaf21a6 100644 --- a/src/UniGetUI.PAckageEngine.Interfaces/ManagerDependency.cs +++ b/src/UniGetUI.PAckageEngine.Interfaces/ManagerDependency.cs @@ -13,7 +13,8 @@ public ManagerDependency( string installFileName, string installArguments, string fancyInstallCommand, - Func> isInstalled) + Func> isInstalled + ) { Name = name; InstallFileName = installFileName; diff --git a/src/UniGetUI.PAckageEngine.Interfaces/ManagerHelpers/IMultiSourceHelper.cs b/src/UniGetUI.PAckageEngine.Interfaces/ManagerHelpers/IMultiSourceHelper.cs index 5500958a42..37df86811c 100644 --- a/src/UniGetUI.PAckageEngine.Interfaces/ManagerHelpers/IMultiSourceHelper.cs +++ b/src/UniGetUI.PAckageEngine.Interfaces/ManagerHelpers/IMultiSourceHelper.cs @@ -30,7 +30,11 @@ public interface IMultiSourceHelper /// The return code of the operation /// the command-line output of the operation /// An OperationVeredict value - public OperationVeredict GetAddOperationVeredict(IManagerSource source, int ReturnCode, string[] Output); + public OperationVeredict GetAddOperationVeredict( + IManagerSource source, + int ReturnCode, + string[] Output + ); /// /// Checks the result of attempting to remove a source @@ -39,7 +43,11 @@ public interface IMultiSourceHelper /// The return code of the operation /// the command-line output of the operation /// An OperationVeredict value - public OperationVeredict GetRemoveOperationVeredict(IManagerSource source, int ReturnCode, string[] Output); + public OperationVeredict GetRemoveOperationVeredict( + IManagerSource source, + int ReturnCode, + string[] Output + ); /// /// Returns the available sources diff --git a/src/UniGetUI.PAckageEngine.Interfaces/ManagerHelpers/IPackageOperationHelper.cs b/src/UniGetUI.PAckageEngine.Interfaces/ManagerHelpers/IPackageOperationHelper.cs index 9278a7aecb..b070e056f7 100644 --- a/src/UniGetUI.PAckageEngine.Interfaces/ManagerHelpers/IPackageOperationHelper.cs +++ b/src/UniGetUI.PAckageEngine.Interfaces/ManagerHelpers/IPackageOperationHelper.cs @@ -13,9 +13,11 @@ public interface IPackageOperationHelper /// that the requested operation is performed over the given package, with its corresponding /// installation options. /// - public IReadOnlyList GetParameters(IPackage package, + public IReadOnlyList GetParameters( + IPackage package, InstallOptions options, - OperationType operation); + OperationType operation + ); /// /// Returns the veredict of the given package operation, given the package, the operation type, diff --git a/src/UniGetUI.PAckageEngine.Interfaces/ManagerProperties.cs b/src/UniGetUI.PAckageEngine.Interfaces/ManagerProperties.cs index d2e4b0cf86..079af4e68e 100644 --- a/src/UniGetUI.PAckageEngine.Interfaces/ManagerProperties.cs +++ b/src/UniGetUI.PAckageEngine.Interfaces/ManagerProperties.cs @@ -13,6 +13,7 @@ public struct ManagerProperties public string Description { get; set; } = "Unset"; public IconType IconId { get; set; } = DefaultIconId; public string ColorIconId { get; set; } = "Unset"; + // public string ExecutableCallArgs { get; set; } = "Unset"; public string ExecutableFriendlyName { get; set; } = "Unset"; public string InstallVerb { get; set; } = "Unset"; @@ -20,7 +21,12 @@ public struct ManagerProperties public string UninstallVerb { get; set; } = "Unset"; public IManagerSource[] KnownSources { get; set; } = []; public IManagerSource DefaultSource { get; set; } = null!; + public ManagerProperties() { } - public ManagerProperties(bool IsDummy) { this.IsDummy = IsDummy; } + + public ManagerProperties(bool IsDummy) + { + this.IsDummy = IsDummy; + } } } diff --git a/src/UniGetUI.PAckageEngine.Interfaces/UniGetUI.PackageEngine.Interfaces.csproj b/src/UniGetUI.PAckageEngine.Interfaces/UniGetUI.PackageEngine.Interfaces.csproj index 73f1a85ea9..6b9ab5fee9 100644 --- a/src/UniGetUI.PAckageEngine.Interfaces/UniGetUI.PackageEngine.Interfaces.csproj +++ b/src/UniGetUI.PAckageEngine.Interfaces/UniGetUI.PackageEngine.Interfaces.csproj @@ -1,29 +1,33 @@ + + $(SharedTargetFrameworks) + - - 10.0.19041.0 - 3.1.0.0 - 3.1.0-beta0 - UniGetUI - 3.1.0-beta0 - Copyright 2021-2026 Devolutions Inc. - + + 10.0.19041.0 + 3.1.0.0 + 3.1.0-beta0 + UniGetUI + 3.1.0-beta0 + Copyright 2021-2026 Devolutions Inc. + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/src/UniGetUI.PackageEngine.Enums/Enums.cs b/src/UniGetUI.PackageEngine.Enums/Enums.cs index 0ae88860d3..2061d7b832 100644 --- a/src/UniGetUI.PackageEngine.Enums/Enums.cs +++ b/src/UniGetUI.PackageEngine.Enums/Enums.cs @@ -27,7 +27,7 @@ public enum DeserializedPackageStatus ManagerNotEnabled, ManagerNotReady, SourceNotFound, - IsAvailable + IsAvailable, } public enum BundleFormatType @@ -43,6 +43,7 @@ public enum OperationVeredict Success, Failure, Canceled, + // RestartRequired, AutoRetry, } @@ -53,7 +54,7 @@ public enum OperationStatus Running, Succeeded, Failed, - Canceled + Canceled, } public enum OperationType @@ -61,7 +62,7 @@ public enum OperationType Install, Update, Uninstall, - None + None, } public enum LoggableTaskType @@ -70,37 +71,45 @@ public enum LoggableTaskType /// Installs a required dependency for a Package Manager /// InstallManagerDependency, + /// /// Searches for packages with a specific query /// FindPackages, + /// /// Lists all the available updates /// ListUpdates, + /// /// Lists the installed packages /// ListInstalledPackages, + /// /// Refreshes the package indexes /// RefreshIndexes, + /// /// Lists the available sources for the manager /// ListSources, + /// /// Loads the package details for a specific package /// LoadPackageDetails, + /// /// Loads the available versions for a specific package /// LoadPackageVersions, + /// /// Other, specific task /// - OtherTask + OtherTask, } } diff --git a/src/UniGetUI.PackageEngine.Enums/ManagerCapabilities.cs b/src/UniGetUI.PackageEngine.Enums/ManagerCapabilities.cs index 02b5d209d3..c68f1b2bc7 100644 --- a/src/UniGetUI.PackageEngine.Enums/ManagerCapabilities.cs +++ b/src/UniGetUI.PackageEngine.Enums/ManagerCapabilities.cs @@ -12,8 +12,8 @@ public struct SourceCapabilities public bool KnowsUpdateDate { get; set; } = false; public bool KnowsPackageCount { get; set; } = false; public bool MustBeInstalledAsAdmin { get; set; } = false; - public SourceCapabilities() - { } + + public SourceCapabilities() { } } public struct ManagerCapabilities @@ -38,6 +38,7 @@ public struct ManagerCapabilities public ProxySupport SupportsProxy = ProxySupport.No; public bool SupportsProxyAuth = false; public SourceCapabilities Sources { get; set; } + public ManagerCapabilities() { Sources = new SourceCapabilities(); diff --git a/src/UniGetUI.PackageEngine.Enums/OverridenInstallationOptions.cs b/src/UniGetUI.PackageEngine.Enums/OverridenInstallationOptions.cs index 75bdc7df31..90fb8ebd7a 100644 --- a/src/UniGetUI.PackageEngine.Enums/OverridenInstallationOptions.cs +++ b/src/UniGetUI.PackageEngine.Enums/OverridenInstallationOptions.cs @@ -1,4 +1,5 @@ namespace UniGetUI.PackageEngine.Structs; + public struct OverridenInstallationOptions { public string? Scope; diff --git a/src/UniGetUI.PackageEngine.Enums/UniGetUI.PackageEngine.Structs.csproj b/src/UniGetUI.PackageEngine.Enums/UniGetUI.PackageEngine.Structs.csproj index 6c35193aa1..3b1ea6e421 100644 --- a/src/UniGetUI.PackageEngine.Enums/UniGetUI.PackageEngine.Structs.csproj +++ b/src/UniGetUI.PackageEngine.Enums/UniGetUI.PackageEngine.Structs.csproj @@ -1,6 +1,9 @@ + + $(SharedTargetFrameworks) + - - - + + + diff --git a/src/UniGetUI.PackageEngine.Managers.Cargo/Cargo.cs b/src/UniGetUI.PackageEngine.Managers.Cargo/Cargo.cs index bc5db70d04..861e77dead 100644 --- a/src/UniGetUI.PackageEngine.Managers.Cargo/Cargo.cs +++ b/src/UniGetUI.PackageEngine.Managers.Cargo/Cargo.cs @@ -5,14 +5,14 @@ using UniGetUI.Core.Data; using UniGetUI.Core.Logging; using UniGetUI.Core.Tools; -using UniGetUI.PackageEngine.Classes.Manager; using UniGetUI.Interface.Enums; +using UniGetUI.PackageEngine.Classes.Manager; using UniGetUI.PackageEngine.Classes.Manager.Classes; using UniGetUI.PackageEngine.Classes.Manager.ManagerHelpers; using UniGetUI.PackageEngine.Enums; +using UniGetUI.PackageEngine.ManagerClasses.Classes; using UniGetUI.PackageEngine.ManagerClasses.Manager; using UniGetUI.PackageEngine.PackageClasses; -using UniGetUI.PackageEngine.ManagerClasses.Classes; namespace UniGetUI.PackageEngine.Managers.CargoManager; @@ -26,21 +26,24 @@ public partial class Cargo : PackageManager public Cargo() { - Dependencies = [ + Dependencies = + [ // cargo-update is required to check for installed and upgradable packages new ManagerDependency( "cargo-update", CoreData.PowerShell5, "-ExecutionPolicy Bypass -NoLogo -NoProfile -Command \"& {cargo install cargo-update; if ($error.count -ne 0){pause}}\"", "cargo install cargo-update", - async () => (await CoreTools.WhichAsync("cargo-install-update.exe")).Item1), + async () => (await CoreTools.WhichAsync("cargo-install-update.exe")).Item1 + ), // Cargo-binstall is required to install and update cargo binaries new ManagerDependency( "cargo-binstall", CoreData.PowerShell5, "-ExecutionPolicy Bypass -NoLogo -NoProfile -Command \"& {Set-ExecutionPolicy Unrestricted -Scope Process; iex (iwr \\\"https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.ps1\\\").Content; if ($error.count -ne 0){pause}}\"", "Set-ExecutionPolicy Unrestricted -Scope Process; iex (iwr \"https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.ps1\").Content", - async () => (await CoreTools.WhichAsync("cargo-binstall.exe")).Item1) + async () => (await CoreTools.WhichAsync("cargo-binstall.exe")).Item1 + ), ]; Capabilities = new ManagerCapabilities @@ -51,7 +54,7 @@ public Cargo() SupportsCustomLocations = true, CanDownloadInstaller = true, SupportsProxy = ProxySupport.Partially, - SupportsProxyAuth = true + SupportsProxyAuth = true, }; var cratesIo = new ManagerSource(this, "crates.io", new Uri("https://index.crates.io/")); @@ -59,7 +62,9 @@ public Cargo() Properties = new ManagerProperties { Name = "Cargo", - Description = CoreTools.Translate("The Rust package manager.
Contains: Rust libraries and programs written in Rust"), + Description = CoreTools.Translate( + "The Rust package manager.
Contains: Rust libraries and programs written in Rust" + ), IconId = IconType.Rust, ColorIconId = "cargo_color", ExecutableFriendlyName = "cargo.exe", @@ -67,7 +72,7 @@ public Cargo() UninstallVerb = "uninstall", UpdateVerb = "binstall", DefaultSource = cratesIo, - KnownSources = [cratesIo] + KnownSources = [cratesIo], }; DetailsHelper = new CargoPkgDetailsHelper(this); @@ -90,7 +95,9 @@ protected override IReadOnlyList FindPackages_UnSafe(string query) { var id = match.Groups[1].Value; var version = match.Groups[2].Value; - Packages.Add(new Package(CoreTools.FormatAsName(id), id, version, DefaultSource, this)); + Packages.Add( + new Package(CoreTools.FormatAsName(id), id, version, DefaultSource, this) + ); } } @@ -106,7 +113,10 @@ protected override IReadOnlyList FindPackages_UnSafe(string query) var package = Packages[i]; try { - var versionInfo = CratesIOClient.GetManifestVersion(package.Id, package.VersionString); + var versionInfo = CratesIOClient.GetManifestVersion( + package.Id, + package.VersionString + ); if (versionInfo.bin_names?.Length > 0) { BinPackages.Add(package); @@ -117,9 +127,12 @@ protected override IReadOnlyList FindPackages_UnSafe(string query) logger.AddToStdErr($"{ex.Message}"); } - if (i + 1 == Packages.Count) break; + if (i + 1 == Packages.Count) + break; // Crates.io api requests that we send no more than one request per second - Task.Delay(Math.Max(0, 1000 - (int)((DateTime.Now - startTime).TotalMilliseconds))).GetAwaiter().GetResult(); + Task.Delay(Math.Max(0, 1000 - (int)((DateTime.Now - startTime).TotalMilliseconds))) + .GetAwaiter() + .GetResult(); } logger.Close(p.ExitCode); @@ -137,10 +150,14 @@ protected override IReadOnlyList GetInstalledPackages_UnSafe() return GetPackages(LoggableTaskType.ListInstalledPackages); } - public override IReadOnlyList FindCandidateExecutableFiles() - => CoreTools.WhichMultiple("cargo.exe"); + public override IReadOnlyList FindCandidateExecutableFiles() => + CoreTools.WhichMultiple("cargo.exe"); - protected override void _loadManagerExecutableFile(out bool found, out string path, out string callArguments) + protected override void _loadManagerExecutableFile( + out bool found, + out string path, + out string callArguments + ) { var (_found, _executablePath) = GetExecutableFile(); found = _found; @@ -154,13 +171,14 @@ protected override void _loadManagerVersion(out string version) p.Start(); version = p.StandardOutput.ReadToEnd().Trim(); string error = p.StandardError.ReadToEnd(); - if (!string.IsNullOrEmpty(error)) Logger.Error("cargo version error: " + error); + if (!string.IsNullOrEmpty(error)) + Logger.Error("cargo version error: " + error); } private IReadOnlyList GetPackages(LoggableTaskType taskType) { List Packages = []; - foreach(var match in TaskRecycler>.RunOrAttach(GetInstalledCommandOutput, 15)) + foreach (var match in TaskRecycler>.RunOrAttach(GetInstalledCommandOutput, 15)) { var id = match.Groups[1]?.Value?.Trim() ?? ""; var name = CoreTools.FormatAsName(id); @@ -212,7 +230,7 @@ private Process GetProcess(string fileName, string extraArguments) CreateNoWindow = true, StandardOutputEncoding = Encoding.UTF8, StandardErrorEncoding = Encoding.UTF8, - } + }, }; } } diff --git a/src/UniGetUI.PackageEngine.Managers.Cargo/CratesIOClient.cs b/src/UniGetUI.PackageEngine.Managers.Cargo/CratesIOClient.cs index 06cd428f2f..1be6c7e88d 100644 --- a/src/UniGetUI.PackageEngine.Managers.Cargo/CratesIOClient.cs +++ b/src/UniGetUI.PackageEngine.Managers.Cargo/CratesIOClient.cs @@ -93,8 +93,9 @@ private static T Fetch(Uri url) var manifestStr = client.GetStringAsync(url).GetAwaiter().GetResult(); - var manifest = JsonSerializer.Deserialize(manifestStr, options: SerializationHelpers.DefaultOptions) - ?? throw new NullResponseException($"Null response for request to {url}"); + var manifest = + JsonSerializer.Deserialize(manifestStr, options: SerializationHelpers.DefaultOptions) + ?? throw new NullResponseException($"Null response for request to {url}"); return manifest; } } diff --git a/src/UniGetUI.PackageEngine.Managers.Cargo/Helpers/CargoPkgDetailsHelper.cs b/src/UniGetUI.PackageEngine.Managers.Cargo/Helpers/CargoPkgDetailsHelper.cs index 2a7be33bbf..1e87981f88 100644 --- a/src/UniGetUI.PackageEngine.Managers.Cargo/Helpers/CargoPkgDetailsHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Cargo/Helpers/CargoPkgDetailsHelper.cs @@ -4,13 +4,16 @@ using UniGetUI.PackageEngine.ManagerClasses.Classes; namespace UniGetUI.PackageEngine.Managers.CargoManager; + internal sealed class CargoPkgDetailsHelper(Cargo manager) : BasePkgDetailsHelper(manager) { protected override void GetDetails_UnSafe(IPackageDetails details) { details.InstallerType = "Source"; - INativeTaskLogger logger = Manager.TaskLogger.CreateNew(Enums.LoggableTaskType.LoadPackageDetails); + INativeTaskLogger logger = Manager.TaskLogger.CreateNew( + Enums.LoggableTaskType.LoadPackageDetails + ); Uri manifestUrl; CargoManifest manifest; @@ -28,21 +31,28 @@ protected override void GetDetails_UnSafe(IPackageDetails details) details.Description = manifest.crate.description; details.ManifestUrl = manifestUrl; - var homepage = manifest.crate.homepage ?? manifest.crate.repository ?? manifest.crate.documentation; + var homepage = + manifest.crate.homepage ?? manifest.crate.repository ?? manifest.crate.documentation; if (!string.IsNullOrEmpty(homepage)) { details.HomepageUrl = new Uri(homepage); } - var keywords = manifest.crate.keywords is null ? [] : (string[]) manifest.crate.keywords.Clone(); - var categories = manifest.categories?.Select(c => c.category) ?? []; + var keywords = manifest.crate.keywords is null + ? [] + : (string[])manifest.crate.keywords.Clone(); + var categories = manifest.categories?.Select(c => c.category) ?? []; details.Tags = [.. keywords, .. categories]; - var versionData = manifest.versions.Where((v) => v.num == details.Package.VersionString).First(); + var versionData = manifest + .versions.Where((v) => v.num == details.Package.VersionString) + .First(); details.Author = versionData.published_by?.name; details.License = versionData.license; - details.InstallerUrl = new Uri((CratesIOClient.ApiUrl + versionData.dl_path).Replace("/api/v1/api/v1", "/api/v1")); + details.InstallerUrl = new Uri( + (CratesIOClient.ApiUrl + versionData.dl_path).Replace("/api/v1/api/v1", "/api/v1") + ); details.InstallerSize = versionData.crate_size ?? 0; details.InstallerHash = versionData.checksum; details.Publisher = versionData.published_by?.name; @@ -67,12 +77,18 @@ protected override IReadOnlyList GetScreenshots_UnSafe(IPackage package) protected override string? GetInstallLocation_UnSafe(IPackage package) { - return Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".cargo", "bin"); + return Path.Join( + Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), + ".cargo", + "bin" + ); } protected override IReadOnlyList GetInstallableVersions_UnSafe(IPackage package) { - INativeTaskLogger logger = Manager.TaskLogger.CreateNew(Enums.LoggableTaskType.LoadPackageVersions); + INativeTaskLogger logger = Manager.TaskLogger.CreateNew( + Enums.LoggableTaskType.LoadPackageVersions + ); try { var (_, manifest) = CratesIOClient.GetManifest(package.Id); diff --git a/src/UniGetUI.PackageEngine.Managers.Cargo/Helpers/CargoPkgOperationHelper.cs b/src/UniGetUI.PackageEngine.Managers.Cargo/Helpers/CargoPkgOperationHelper.cs index be055da6cd..3b2be34f63 100644 --- a/src/UniGetUI.PackageEngine.Managers.Cargo/Helpers/CargoPkgOperationHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Cargo/Helpers/CargoPkgOperationHelper.cs @@ -7,13 +7,22 @@ namespace UniGetUI.PackageEngine.Managers.CargoManager; internal sealed class CargoPkgOperationHelper(Cargo cargo) : BasePkgOperationHelper(cargo) { - protected override IReadOnlyList _getOperationParameters(IPackage package, - InstallOptions options, OperationType operation) + protected override IReadOnlyList _getOperationParameters( + IPackage package, + InstallOptions options, + OperationType operation + ) { var version = options.Version == string.Empty ? package.VersionString : options.Version; List parameters = operation switch { - OperationType.Install => [Manager.Properties.InstallVerb, "--version", version, package.Id], + OperationType.Install => + [ + Manager.Properties.InstallVerb, + "--version", + version, + package.Id, + ], OperationType.Update => [Manager.Properties.UpdateVerb, package.Id], OperationType.Uninstall => [Manager.Properties.UninstallVerb, package.Id], _ => throw new InvalidDataException("Invalid package operation"), @@ -23,24 +32,31 @@ protected override IReadOnlyList _getOperationParameters(IPackage packag { parameters.Add("--no-confirm"); - if(options.SkipHashCheck) + if (options.SkipHashCheck) parameters.Add("--skip-signatures"); - if(options.CustomInstallLocation != "") + if (options.CustomInstallLocation != "") parameters.AddRange(["--install-path", options.CustomInstallLocation]); } - parameters.AddRange(operation switch - { - OperationType.Update => options.CustomParameters_Update, - OperationType.Uninstall => options.CustomParameters_Uninstall, - _ => options.CustomParameters_Install, - }); + parameters.AddRange( + operation switch + { + OperationType.Update => options.CustomParameters_Update, + OperationType.Uninstall => options.CustomParameters_Uninstall, + _ => options.CustomParameters_Install, + } + ); return parameters; } - protected override OperationVeredict _getOperationResult(IPackage package, OperationType operation, IReadOnlyList processOutput, int returnCode) + protected override OperationVeredict _getOperationResult( + IPackage package, + OperationType operation, + IReadOnlyList processOutput, + int returnCode + ) { return returnCode == 0 ? OperationVeredict.Success : OperationVeredict.Failure; } diff --git a/src/UniGetUI.PackageEngine.Managers.Cargo/UniGetUI.PackageEngine.Managers.Cargo.csproj b/src/UniGetUI.PackageEngine.Managers.Cargo/UniGetUI.PackageEngine.Managers.Cargo.csproj index 3b628742de..5590ef43a4 100644 --- a/src/UniGetUI.PackageEngine.Managers.Cargo/UniGetUI.PackageEngine.Managers.Cargo.csproj +++ b/src/UniGetUI.PackageEngine.Managers.Cargo/UniGetUI.PackageEngine.Managers.Cargo.csproj @@ -1,4 +1,7 @@ + + $(SharedTargetFrameworks) + @@ -19,6 +22,6 @@ - + diff --git a/src/UniGetUI.PackageEngine.Managers.Chocolatey/Chocolatey.cs b/src/UniGetUI.PackageEngine.Managers.Chocolatey/Chocolatey.cs index ea3ee8ae7f..1f0445a0e7 100644 --- a/src/UniGetUI.PackageEngine.Managers.Chocolatey/Chocolatey.cs +++ b/src/UniGetUI.PackageEngine.Managers.Chocolatey/Chocolatey.cs @@ -18,10 +18,57 @@ namespace UniGetUI.PackageEngine.Managers.ChocolateyManager { public class Chocolatey : BaseNuGet { - public static readonly string[] FALSE_PACKAGE_IDS = ["Directory", "Output is Id", "", "Did", "Features?", "Validation", "-", "being", "It", "Error", "L'accs", "Maximum", "This", "Output is package name ", "operable", "Invalid"]; - public static readonly string[] FALSE_PACKAGE_VERSIONS = ["", "Version", "of", "Did", "Features?", "Validation", "-", "being", "It", "Error", "L'accs", "Maximum", "This", "packages", "current version", "installed version", "is", "program", "validations", "argument", "no"]; - private static readonly string OldChocoPath = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Programs\\WingetUI\\choco-cli"); - private static readonly string NewChocoPath = Path.Join(CoreData.UniGetUIDataDirectory, "Chocolatey"); + public static readonly string[] FALSE_PACKAGE_IDS = + [ + "Directory", + "Output is Id", + "", + "Did", + "Features?", + "Validation", + "-", + "being", + "It", + "Error", + "L'accs", + "Maximum", + "This", + "Output is package name ", + "operable", + "Invalid", + ]; + public static readonly string[] FALSE_PACKAGE_VERSIONS = + [ + "", + "Version", + "of", + "Did", + "Features?", + "Validation", + "-", + "being", + "It", + "Error", + "L'accs", + "Maximum", + "This", + "packages", + "current version", + "installed version", + "is", + "program", + "validations", + "argument", + "no", + ]; + private static readonly string OldChocoPath = Path.Join( + Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), + "Programs\\WingetUI\\choco-cli" + ); + private static readonly string NewChocoPath = Path.Join( + CoreData.UniGetUIDataDirectory, + "Chocolatey" + ); public Chocolatey() { @@ -44,22 +91,34 @@ public Chocolatey() KnowsUpdateDate = false, }, SupportsProxy = ProxySupport.Yes, - SupportsProxyAuth = true + SupportsProxyAuth = true, }; Properties = new ManagerProperties { Name = "Chocolatey", - Description = CoreTools.Translate("The classical package manager for windows. You'll find everything there.
Contains: General Software"), + Description = CoreTools.Translate( + "The classical package manager for windows. You'll find everything there.
Contains: General Software" + ), IconId = IconType.Chocolatey, ColorIconId = "choco_color", ExecutableFriendlyName = "choco.exe", InstallVerb = "install", UninstallVerb = "uninstall", UpdateVerb = "upgrade", - KnownSources = [new ManagerSource(this, "community", new Uri("https://community.chocolatey.org/api/v2/"))], - DefaultSource = new ManagerSource(this, "community", new Uri("https://community.chocolatey.org/api/v2/")), - + KnownSources = + [ + new ManagerSource( + this, + "community", + new Uri("https://community.chocolatey.org/api/v2/") + ), + ], + DefaultSource = new ManagerSource( + this, + "community", + new Uri("https://community.chocolatey.org/api/v2/") + ), }; SourcesHelper = new ChocolateySourceHelper(this); @@ -69,9 +128,11 @@ public Chocolatey() public static string GetProxyArgument() { - if (!Settings.Get(Settings.K.EnableProxy)) return ""; + if (!Settings.Get(Settings.K.EnableProxy)) + return ""; var proxyUri = Settings.GetProxyUrl(); - if (proxyUri is null) return ""; + if (proxyUri is null) + return ""; if (Settings.Get(Settings.K.EnableProxyAuth) is false) return $"--proxy {proxyUri.ToString()}"; @@ -80,8 +141,8 @@ public static string GetProxyArgument() if (creds is null) return $"--proxy {proxyUri.ToString()}"; - return $"--proxy={proxyUri.ToString()} --proxy-user={Uri.EscapeDataString(creds.UserName)}" + - $" --proxy-password={Uri.EscapeDataString(creds.Password)}"; + return $"--proxy={proxyUri.ToString()} --proxy-user={Uri.EscapeDataString(creds.UserName)}" + + $" --proxy-password={Uri.EscapeDataString(creds.Password)}"; } protected override IReadOnlyList GetAvailableUpdates_UnSafe() @@ -97,8 +158,8 @@ protected override IReadOnlyList GetAvailableUpdates_UnSafe() RedirectStandardInput = true, UseShellExecute = false, CreateNoWindow = true, - StandardOutputEncoding = System.Text.Encoding.UTF8 - } + StandardOutputEncoding = System.Text.Encoding.UTF8, + }, }; IProcessTaskLogger logger = TaskLogger.CreateNew(LoggableTaskType.ListUpdates, p); @@ -122,12 +183,25 @@ protected override IReadOnlyList GetAvailableUpdates_UnSafe() continue; } - if (FALSE_PACKAGE_IDS.Contains(elements[0]) || FALSE_PACKAGE_VERSIONS.Contains(elements[1]) || elements[1] == elements[2]) + if ( + FALSE_PACKAGE_IDS.Contains(elements[0]) + || FALSE_PACKAGE_VERSIONS.Contains(elements[1]) + || elements[1] == elements[2] + ) { continue; } - Packages.Add(new Package(CoreTools.FormatAsName(elements[0]), elements[0], elements[1], elements[2], DefaultSource, this)); + Packages.Add( + new Package( + CoreTools.FormatAsName(elements[0]), + elements[0], + elements[1], + elements[2], + DefaultSource, + this + ) + ); } } @@ -151,11 +225,14 @@ protected override IReadOnlyList _getInstalledPackages_UnSafe() RedirectStandardInput = true, UseShellExecute = false, CreateNoWindow = true, - StandardOutputEncoding = System.Text.Encoding.UTF8 - } + StandardOutputEncoding = System.Text.Encoding.UTF8, + }, }; - IProcessTaskLogger logger = TaskLogger.CreateNew(LoggableTaskType.ListInstalledPackages, p); + IProcessTaskLogger logger = TaskLogger.CreateNew( + LoggableTaskType.ListInstalledPackages, + p + ); p.Start(); string? line; @@ -176,12 +253,23 @@ protected override IReadOnlyList _getInstalledPackages_UnSafe() continue; } - if (FALSE_PACKAGE_IDS.Contains(elements[0]) || FALSE_PACKAGE_VERSIONS.Contains(elements[1])) + if ( + FALSE_PACKAGE_IDS.Contains(elements[0]) + || FALSE_PACKAGE_VERSIONS.Contains(elements[1]) + ) { continue; } - Packages.Add(new Package(CoreTools.FormatAsName(elements[0]), elements[0], elements[1], DefaultSource, this)); + Packages.Add( + new Package( + CoreTools.FormatAsName(elements[0]), + elements[0], + elements[1], + DefaultSource, + this + ) + ); } } @@ -204,7 +292,11 @@ public override IReadOnlyList FindCandidateExecutableFiles() return candidates; } - protected override void _loadManagerExecutableFile(out bool found, out string path, out string callArguments) + protected override void _loadManagerExecutableFile( + out bool found, + out string path, + out string callArguments + ) { if (!Directory.Exists(OldChocoPath)) { @@ -212,7 +304,9 @@ protected override void _loadManagerExecutableFile(out bool found, out string pa } else if (CoreTools.IsSymbolicLinkDir(OldChocoPath)) { - Logger.ImportantInfo("Old chocolatey path is a symbolic link, not migrating Chocolatey..."); + Logger.ImportantInfo( + "Old chocolatey path is a symbolic link, not migrating Chocolatey..." + ); } else if (Settings.Get(Settings.K.ChocolateySymbolicLinkCreated)) { @@ -225,11 +319,23 @@ protected override void _loadManagerExecutableFile(out bool found, out string pa Logger.Info("Moving Bundled Chocolatey from old path to new path..."); string current_env_var = - Environment.GetEnvironmentVariable("chocolateyinstall", EnvironmentVariableTarget.User) ?? ""; - if (current_env_var != "" && Path.GetRelativePath(current_env_var, OldChocoPath) == ".") + Environment.GetEnvironmentVariable( + "chocolateyinstall", + EnvironmentVariableTarget.User + ) ?? ""; + if ( + current_env_var != "" + && Path.GetRelativePath(current_env_var, OldChocoPath) == "." + ) { - Logger.ImportantInfo("Migrating ChocolateyInstall environment variable to new location"); - Environment.SetEnvironmentVariable("chocolateyinstall", NewChocoPath, EnvironmentVariableTarget.User); + Logger.ImportantInfo( + "Migrating ChocolateyInstall environment variable to new location" + ); + Environment.SetEnvironmentVariable( + "chocolateyinstall", + NewChocoPath, + EnvironmentVariableTarget.User + ); } if (!Directory.Exists(NewChocoPath)) @@ -237,7 +343,13 @@ protected override void _loadManagerExecutableFile(out bool found, out string pa Directory.CreateDirectory(NewChocoPath); } - foreach (string old_subdir in Directory.GetDirectories(OldChocoPath, "*", SearchOption.AllDirectories)) + foreach ( + string old_subdir in Directory.GetDirectories( + OldChocoPath, + "*", + SearchOption.AllDirectories + ) + ) { string new_subdir = old_subdir.Replace(OldChocoPath, NewChocoPath); if (!Directory.Exists(new_subdir)) @@ -251,7 +363,13 @@ protected override void _loadManagerExecutableFile(out bool found, out string pa } } - foreach (string old_file in Directory.GetFiles(OldChocoPath, "*", SearchOption.AllDirectories)) + foreach ( + string old_file in Directory.GetFiles( + OldChocoPath, + "*", + SearchOption.AllDirectories + ) + ) { string new_file = old_file.Replace(OldChocoPath, NewChocoPath); if (!File.Exists(new_file)) @@ -266,16 +384,28 @@ protected override void _loadManagerExecutableFile(out bool found, out string pa } } - foreach (string old_subdir in Directory.GetDirectories(OldChocoPath, "*", SearchOption.AllDirectories)) + foreach ( + string old_subdir in Directory.GetDirectories( + OldChocoPath, + "*", + SearchOption.AllDirectories + ) + ) { - if (!Directory.EnumerateFiles(old_subdir).Any() && !Directory.EnumerateDirectories(old_subdir).Any()) + if ( + !Directory.EnumerateFiles(old_subdir).Any() + && !Directory.EnumerateDirectories(old_subdir).Any() + ) { Logger.Debug("Deleting old empty subdirectory " + old_subdir); Directory.Delete(old_subdir); } } - if (!Directory.EnumerateFiles(OldChocoPath).Any() && !Directory.EnumerateDirectories(OldChocoPath).Any()) + if ( + !Directory.EnumerateFiles(OldChocoPath).Any() + && !Directory.EnumerateDirectories(OldChocoPath).Any() + ) { Logger.Info("Deleting old Chocolatey directory " + OldChocoPath); Directory.Delete(OldChocoPath); @@ -283,8 +413,9 @@ protected override void _loadManagerExecutableFile(out bool found, out string pa CoreTools.CreateSymbolicLinkDir(OldChocoPath, NewChocoPath); Settings.Set(Settings.K.ChocolateySymbolicLinkCreated, true); - Logger.Info($"Symbolic link created successfully from {OldChocoPath} to {NewChocoPath}."); - + Logger.Info( + $"Symbolic link created successfully from {OldChocoPath} to {NewChocoPath}." + ); } catch (Exception e) { @@ -311,8 +442,8 @@ protected override void _loadManagerVersion(out string version) RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true, - StandardOutputEncoding = System.Text.Encoding.UTF8 - } + StandardOutputEncoding = System.Text.Encoding.UTF8, + }, }; process.Start(); version = process.StandardOutput.ReadToEnd().Trim(); @@ -321,15 +452,29 @@ protected override void _loadManagerVersion(out string version) protected override void _performExtraLoadingSteps() { // If the user is running bundled chocolatey and chocolatey is not in path, add chocolatey to path - if (!Settings.Get(Settings.K.UseSystemChocolatey) && !File.Exists("C:\\ProgramData\\Chocolatey\\bin\\choco.exe")) - /* && Settings.Get(Settings.K.ShownWelcomeWizard)) */ + if ( + !Settings.Get(Settings.K.UseSystemChocolatey) + && !File.Exists("C:\\ProgramData\\Chocolatey\\bin\\choco.exe") + ) + /* && Settings.Get(Settings.K.ShownWelcomeWizard)) */ { - string? path = Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.User); + string? path = Environment.GetEnvironmentVariable( + "PATH", + EnvironmentVariableTarget.User + ); if (!path?.Contains(Status.ExecutablePath.Replace("\\choco.exe", "\\bin")) ?? false) { Logger.ImportantInfo("Adding chocolatey to path since it was not on path."); - Environment.SetEnvironmentVariable("PATH", $"{Status.ExecutablePath.Replace("\\choco.exe", "\\bin")};{path}", EnvironmentVariableTarget.User); - Environment.SetEnvironmentVariable("chocolateyinstall", Path.GetDirectoryName(Status.ExecutablePath), EnvironmentVariableTarget.User); + Environment.SetEnvironmentVariable( + "PATH", + $"{Status.ExecutablePath.Replace("\\choco.exe", "\\bin")};{path}", + EnvironmentVariableTarget.User + ); + Environment.SetEnvironmentVariable( + "chocolateyinstall", + Path.GetDirectoryName(Status.ExecutablePath), + EnvironmentVariableTarget.User + ); } else { @@ -338,12 +483,17 @@ protected override void _performExtraLoadingSteps() } // Trick chocolatey into using the wanted installation - var choco_dir = Path.GetDirectoryName(Status.ExecutablePath)?.Replace('/', '\\').Trim('\\') ?? ""; + var choco_dir = + Path.GetDirectoryName(Status.ExecutablePath)?.Replace('/', '\\').Trim('\\') ?? ""; if (choco_dir.EndsWith("bin")) { choco_dir = choco_dir[..^3].Trim('\\'); } - Environment.SetEnvironmentVariable("chocolateyinstall", choco_dir, EnvironmentVariableTarget.Process); + Environment.SetEnvironmentVariable( + "chocolateyinstall", + choco_dir, + EnvironmentVariableTarget.Process + ); } } } diff --git a/src/UniGetUI.PackageEngine.Managers.Chocolatey/Helpers/ChocolateyDetailsHelper.cs b/src/UniGetUI.PackageEngine.Managers.Chocolatey/Helpers/ChocolateyDetailsHelper.cs index a90ec78369..bc0cc244d4 100644 --- a/src/UniGetUI.PackageEngine.Managers.Chocolatey/Helpers/ChocolateyDetailsHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Chocolatey/Helpers/ChocolateyDetailsHelper.cs @@ -9,8 +9,8 @@ namespace UniGetUI.PackageEngine.Managers.Choco { public class ChocolateyDetailsHelper : BaseNuGetDetailsHelper { - public ChocolateyDetailsHelper(BaseNuGet manager) : base(manager) - { } + public ChocolateyDetailsHelper(BaseNuGet manager) + : base(manager) { } protected override IReadOnlyList GetInstallableVersions_UnSafe(IPackage package) { @@ -19,17 +19,23 @@ protected override IReadOnlyList GetInstallableVersions_UnSafe(IPackage StartInfo = new ProcessStartInfo { FileName = Manager.Status.ExecutablePath, - Arguments = Manager.Status.ExecutableCallArgs + $" search {package.Id} --exact --all-versions " + Chocolatey.GetProxyArgument(), + Arguments = + Manager.Status.ExecutableCallArgs + + $" search {package.Id} --exact --all-versions " + + Chocolatey.GetProxyArgument(), UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, RedirectStandardInput = true, CreateNoWindow = true, - StandardOutputEncoding = System.Text.Encoding.UTF8 - } + StandardOutputEncoding = System.Text.Encoding.UTF8, + }, }; - IProcessTaskLogger logger = Manager.TaskLogger.CreateNew(LoggableTaskType.LoadPackageVersions, p); + IProcessTaskLogger logger = Manager.TaskLogger.CreateNew( + LoggableTaskType.LoadPackageVersions, + p + ); p.Start(); @@ -52,24 +58,36 @@ protected override IReadOnlyList GetInstallableVersions_UnSafe(IPackage protected override string? GetInstallLocation_UnSafe(IPackage package) { - string portable_path = Manager.Status.ExecutablePath.Replace("choco.exe", $"bin\\{package.Id}.exe"); + string portable_path = Manager.Status.ExecutablePath.Replace( + "choco.exe", + $"bin\\{package.Id}.exe" + ); if (File.Exists(portable_path)) return Path.GetDirectoryName(portable_path); - foreach (var base_path in new[] - { - Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), - Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), - Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Programs"), - Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), - }) + foreach ( + var base_path in new[] + { + Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), + Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), + Path.Join( + Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), + "Programs" + ), + Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), + } + ) { var path_with_id = Path.Join(base_path, package.Id); - if (Directory.Exists(path_with_id)) return path_with_id; + if (Directory.Exists(path_with_id)) + return path_with_id; } - return Path.Join(Path.GetDirectoryName(Manager.Status.ExecutablePath), "lib", package.Id); - + return Path.Join( + Path.GetDirectoryName(Manager.Status.ExecutablePath), + "lib", + package.Id + ); } } } diff --git a/src/UniGetUI.PackageEngine.Managers.Chocolatey/Helpers/ChocolateyPkgOperationHelper.cs b/src/UniGetUI.PackageEngine.Managers.Chocolatey/Helpers/ChocolateyPkgOperationHelper.cs index 86b962f272..0774da699d 100644 --- a/src/UniGetUI.PackageEngine.Managers.Chocolatey/Helpers/ChocolateyPkgOperationHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Chocolatey/Helpers/ChocolateyPkgOperationHelper.cs @@ -5,20 +5,28 @@ using Architecture = UniGetUI.PackageEngine.Enums.Architecture; namespace UniGetUI.PackageEngine.Managers.ChocolateyManager; + internal sealed class ChocolateyPkgOperationHelper : BasePkgOperationHelper { - public ChocolateyPkgOperationHelper(Chocolatey manager) : base(manager) { } + public ChocolateyPkgOperationHelper(Chocolatey manager) + : base(manager) { } - protected override IReadOnlyList _getOperationParameters(IPackage package, + protected override IReadOnlyList _getOperationParameters( + IPackage package, InstallOptions options, - OperationType operation) + OperationType operation + ) { - List parameters = [operation switch { - OperationType.Install => Manager.Properties.InstallVerb, - OperationType.Update => Manager.Properties.UpdateVerb, - OperationType.Uninstall => Manager.Properties.UninstallVerb, - _ => throw new InvalidDataException("Invalid package operation") - }]; + List parameters = + [ + operation switch + { + OperationType.Install => Manager.Properties.InstallVerb, + OperationType.Update => Manager.Properties.UpdateVerb, + OperationType.Uninstall => Manager.Properties.UninstallVerb, + _ => throw new InvalidDataException("Invalid package operation"), + }, + ]; parameters.AddRange([package.Id, "-y"]); if (options.InteractiveInstallation) @@ -43,12 +51,14 @@ protected override IReadOnlyList _getOperationParameters(IPackage packag parameters.Add(Chocolatey.GetProxyArgument()); - parameters.AddRange(operation switch - { - OperationType.Update => options.CustomParameters_Update, - OperationType.Uninstall => options.CustomParameters_Uninstall, - _ => options.CustomParameters_Install, - }); + parameters.AddRange( + operation switch + { + OperationType.Update => options.CustomParameters_Update, + OperationType.Uninstall => options.CustomParameters_Uninstall, + _ => options.CustomParameters_Install, + } + ); return parameters; } @@ -57,7 +67,8 @@ protected override OperationVeredict _getOperationResult( IPackage package, OperationType operation, IReadOnlyList processOutput, - int returnCode) + int returnCode + ) { if (returnCode is 3010) { @@ -71,14 +82,20 @@ protected override OperationVeredict _getOperationResult( } string output_string = string.Join("\n", processOutput); - if (package.OverridenOptions.RunAsAdministrator != true && - (output_string.Contains("Run as administrator") - || output_string.Contains("The requested operation requires elevation") - || output_string.Contains("Access to the path") - || output_string.Contains("Access denied") - || output_string.Contains("is denied") - || output_string.Contains("WARNING: Unable to create shortcut. Error captured was Unable to save shortcut") - || output_string.Contains("access denied"))) + if ( + package.OverridenOptions.RunAsAdministrator != true + && ( + output_string.Contains("Run as administrator") + || output_string.Contains("The requested operation requires elevation") + || output_string.Contains("Access to the path") + || output_string.Contains("Access denied") + || output_string.Contains("is denied") + || output_string.Contains( + "WARNING: Unable to create shortcut. Error captured was Unable to save shortcut" + ) + || output_string.Contains("access denied") + ) + ) { package.OverridenOptions.RunAsAdministrator = true; return OperationVeredict.AutoRetry; diff --git a/src/UniGetUI.PackageEngine.Managers.Chocolatey/Helpers/ChocolateySourceHelper.cs b/src/UniGetUI.PackageEngine.Managers.Chocolatey/Helpers/ChocolateySourceHelper.cs index a6cb717f1d..e853958236 100644 --- a/src/UniGetUI.PackageEngine.Managers.Chocolatey/Helpers/ChocolateySourceHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Chocolatey/Helpers/ChocolateySourceHelper.cs @@ -9,11 +9,21 @@ namespace UniGetUI.PackageEngine.Managers.ChocolateyManager { internal sealed class ChocolateySourceHelper : BaseSourceHelper { - public ChocolateySourceHelper(Chocolatey manager) : base(manager) { } + public ChocolateySourceHelper(Chocolatey manager) + : base(manager) { } public override string[] GetAddSourceParameters(IManagerSource source) { - return ["source", "add", "--name", source.Name, "--source", source.Url.ToString(), "-y"]; + return + [ + "source", + "add", + "--name", + source.Name, + "--source", + source.Url.ToString(), + "-y", + ]; } public override string[] GetRemoveSourceParameters(IManagerSource source) @@ -21,12 +31,20 @@ public override string[] GetRemoveSourceParameters(IManagerSource source) return ["source", "remove", "--name", source.Name, "-y"]; } - protected override OperationVeredict _getAddSourceOperationVeredict(IManagerSource source, int ReturnCode, string[] Output) + protected override OperationVeredict _getAddSourceOperationVeredict( + IManagerSource source, + int ReturnCode, + string[] Output + ) { return ReturnCode == 0 ? OperationVeredict.Success : OperationVeredict.Failure; } - protected override OperationVeredict _getRemoveSourceOperationVeredict(IManagerSource source, int ReturnCode, string[] Output) + protected override OperationVeredict _getRemoveSourceOperationVeredict( + IManagerSource source, + int ReturnCode, + string[] Output + ) { return ReturnCode == 0 ? OperationVeredict.Success : OperationVeredict.Failure; } @@ -40,17 +58,23 @@ protected override IReadOnlyList GetSources_UnSafe() StartInfo = new() { FileName = Manager.Status.ExecutablePath, - Arguments = Manager.Status.ExecutableCallArgs + " source list " + Chocolatey.GetProxyArgument(), + Arguments = + Manager.Status.ExecutableCallArgs + + " source list " + + Chocolatey.GetProxyArgument(), RedirectStandardOutput = true, RedirectStandardError = true, RedirectStandardInput = true, UseShellExecute = false, CreateNoWindow = true, - StandardOutputEncoding = System.Text.Encoding.UTF8 - } + StandardOutputEncoding = System.Text.Encoding.UTF8, + }, }; - IProcessTaskLogger logger = Manager.TaskLogger.CreateNew(LoggableTaskType.ListSources, p); + IProcessTaskLogger logger = Manager.TaskLogger.CreateNew( + LoggableTaskType.ListSources, + p + ); p.Start(); string? line; @@ -67,13 +91,28 @@ protected override IReadOnlyList GetSources_UnSafe() if (line.Contains(" - ") && line.Contains("| ")) { string[] parts = line.Trim().Split('|')[0].Trim().Split(" - "); - if (parts[1].Trim() == "https://community.chocolatey.org/api/v2/" || parts[1].Trim() == "https://chocolatey.org/api/v2/") + if ( + parts[1].Trim() == "https://community.chocolatey.org/api/v2/" + || parts[1].Trim() == "https://chocolatey.org/api/v2/" + ) { - sources.Add(new ManagerSource(Manager, "community", new Uri("https://community.chocolatey.org/api/v2/"))); + sources.Add( + new ManagerSource( + Manager, + "community", + new Uri("https://community.chocolatey.org/api/v2/") + ) + ); } else { - sources.Add(new ManagerSource(Manager, parts[0].Trim(), new Uri(parts[1].Split(" ")[0].Trim()))); + sources.Add( + new ManagerSource( + Manager, + parts[0].Trim(), + new Uri(parts[1].Split(" ")[0].Trim()) + ) + ); } } } diff --git a/src/UniGetUI.PackageEngine.Managers.Chocolatey/UniGetUI.PackageEngine.Managers.Chocolatey.csproj b/src/UniGetUI.PackageEngine.Managers.Chocolatey/UniGetUI.PackageEngine.Managers.Chocolatey.csproj index 54ea79f720..19223e59a0 100644 --- a/src/UniGetUI.PackageEngine.Managers.Chocolatey/UniGetUI.PackageEngine.Managers.Chocolatey.csproj +++ b/src/UniGetUI.PackageEngine.Managers.Chocolatey/UniGetUI.PackageEngine.Managers.Chocolatey.csproj @@ -1,38 +1,35 @@ + + $(WindowsTargetFramework) + + - - $(WindowsTargetFramework) - - + + + + + + + + + + + + + + + + + Never + + + + + - - - - - - - - - - - - - - - - - - Never - - - - - - - - - - + + + diff --git a/src/UniGetUI.PackageEngine.Managers.Chocolatey/choco-cli/helpers/Chocolatey.PowerShell.dll-help.xml b/src/UniGetUI.PackageEngine.Managers.Chocolatey/choco-cli/helpers/Chocolatey.PowerShell.dll-help.xml index 2bf2b24b0a..88181c255f 100644 --- a/src/UniGetUI.PackageEngine.Managers.Chocolatey/choco-cli/helpers/Chocolatey.PowerShell.dll-help.xml +++ b/src/UniGetUI.PackageEngine.Managers.Chocolatey/choco-cli/helpers/Chocolatey.PowerShell.dll-help.xml @@ -1,1117 +1,1618 @@  - - - Get-EnvironmentVariable - Get - EnvironmentVariable - - Gets an Environment Variable. - - - - This will will get an environment variable based on the variable name and scope while accounting whether to expand the variable or not (e.g.: `%TEMP%`-> `C:\User\Username\AppData\Local\Temp`). - - - - Get-EnvironmentVariable - - Name - - The environment variable you want to get the value from. - - String - - String - - - None - - - Scope - - The environment variable target scope. This is `Process`, `User`, or `Machine`. - - - Process - User - Machine - - EnvironmentVariableTarget - - EnvironmentVariableTarget - - - None - - - IgnoredArguments - - Allows splatting with arguments that do not apply. Do not use directly. - - Object[] - - Object[] - - - None - - - PreserveVariables - - Whether you want to expand embedded environment variable names or not. When not set, variables will be expanded. - - - SwitchParameter - - - False - - - - - - IgnoredArguments + + + Get-EnvironmentVariable + Get + EnvironmentVariable + + Gets an Environment Variable. + + - Allows splatting with arguments that do not apply. Do not use directly. + This will will get an environment variable based on the variable name and scope while accounting whether to expand the variable or not (e.g.: `%TEMP%`-> `C:\User\Username\AppData\Local\Temp`). - Object[] - - Object[] - - - None - - - Name + + + Get-EnvironmentVariable + + Name + + The environment variable you want to get the value from. + + String + + String + + + None + + + Scope + + The environment variable target scope. This is `Process`, `User`, or `Machine`. + + + Process + User + Machine + + EnvironmentVariableTarget + + EnvironmentVariableTarget + + + None + + + IgnoredArguments + + Allows splatting with arguments that do not apply. Do not use directly. + + Object[] + + Object[] + + + None + + + PreserveVariables + + Whether you want to expand embedded environment variable names or not. When not set, variables will be expanded. + + + SwitchParameter + + + False + + + + + + IgnoredArguments + + Allows splatting with arguments that do not apply. Do not use directly. + + Object[] + + Object[] + + + None + + + Name + + The environment variable you want to get the value from. + + String + + String + + + None + + + PreserveVariables + + Whether you want to expand embedded environment variable names or not. When not set, variables will be expanded. + + SwitchParameter + + SwitchParameter + + + False + + + Scope + + The environment variable target scope. This is `Process`, `User`, or `Machine`. + + EnvironmentVariableTarget + + EnvironmentVariableTarget + + + None + + + + + + + System.String + + + Outputs the value of the target environment variable as a string. + + + + + + This helper reduces the number of lines one would have to write to get environment variables, mainly when not expanding the variables is a must. + + + + + -------------------------- Example 1 -------------------------- + PS C:\> Get-EnvironmentVariable -Name 'TEMP' -Scope User -PreserveVariables + + Gets the `TEMP` encironment variable from the user scope, without expanding embedded environment variables. + + + + -------------------------- Example 2 -------------------------- + PS C:\> Get-EnvironmentVariable -Name 'PATH' -Scope Machine + + Gets the `PATH` environment variable from the machine scope, expanding embedded environment variables. + + + + + + Online Version: + https://docs.chocolatey.org/en-us/create/cmdlets/get-environmentvariable + + + Get-EnvironmentVariableNames + xref:get-environmentvariablenames,mb-3 d-block + + + Set-EnvironmentVariable + xref:set-environmentvariable,mb-3 d-block + + + Cmdlet Reference + xref:powershell-cmdlet-reference,mb-3 d-block + + + Function Reference + xref:powershell-reference,d-block + + + + + + Get-EnvironmentVariableNames + Get + EnvironmentVariableNames + + Gets all environment variable names. + + - The environment variable you want to get the value from. + Provides a list of environment variable names based on the scope. This can be used to loop through the list and generate names. - String - - String - - - None - - - PreserveVariables + + + Get-EnvironmentVariableNames + + Scope + + The environment variable target scope. This is `Process`, `User`, or `Machine`. + + + Process + User + Machine + + EnvironmentVariableTarget + + EnvironmentVariableTarget + + + None + + + IgnoredArguments + + Allows splatting with arguments that do not apply. Do not use directly. + + Object[] + + Object[] + + + None + + + + + + IgnoredArguments + + Allows splatting with arguments that do not apply. Do not use directly. + + Object[] + + Object[] + + + None + + + Scope + + The environment variable target scope. This is `Process`, `User`, or `Machine`. + + EnvironmentVariableTarget + + EnvironmentVariableTarget + + + None + + + + + + + System.String + + + Outputs the names of all the environment variables in the target scope as strings. + + + + + + Process dumps the current environment variable names in memory / session. The other scopes refer to the registry values. + + + + + -------------------------- Example 1 -------------------------- + PS C:\> Get-EnvironmentVariableNames -Scope Machine + + Outputs the names of all the environment variables defined in the registry for the Machine scope. + + + + + + Online Version: + https://docs.chocolatey.org/en-us/create/cmdlets/get-environmentvariablenames + + + Get-EnvironmentVariableNames + xref:get-environmentvariablenames,mb-3 d-block + + + Set-EnvironmentVariable + xref:set-environmentvariable,mb-3 d-block + + + Cmdlet Reference + xref:powershell-cmdlet-reference,mb-3 d-block + + + Function Reference + xref:powershell-reference,d-block + + + + + + Install-ChocolateyPath + Install + ChocolateyPath + + > :choco-info: NOTE > > Administrative Access Required when `-PathType 'Machine'.` This puts a directory to the PATH environment variable. + + - Whether you want to expand embedded environment variable names or not. When not set, variables will be expanded. + Looks at both PATH environment variables to ensure a path variable correctly shows up on the right PATH. - SwitchParameter - - SwitchParameter - - - False - - - Scope + + + Install-ChocolateyPath + + Path + + The full path to a location to add / ensure is in the PATH. + + String + + String + + + None + + + PathType + + Which PATH to add it to. If specifying `Machine`, this requires admin privileges to run correctly. + + + Process + User + Machine + + EnvironmentVariableTarget + + EnvironmentVariableTarget + + + None + + + IgnoredArguments + + Allows splatting with arguments that do not apply. Do not use directly. + + Object[] + + Object[] + + + None + + + Confirm + + Prompts you for confirmation before running the cmdlet. + + + SwitchParameter + + + False + + + WhatIf + + Shows what would happen if the cmdlet runs. The cmdlet is not run. + + + SwitchParameter + + + False + + + + + + IgnoredArguments + + Allows splatting with arguments that do not apply. Do not use directly. + + Object[] + + Object[] + + + None + + + Path + + The full path to a location to add / ensure is in the PATH. + + String + + String + + + None + + + PathType + + Which PATH to add it to. If specifying `Machine`, this requires admin privileges to run correctly. + + EnvironmentVariableTarget + + EnvironmentVariableTarget + + + None + + + Confirm + + Prompts you for confirmation before running the cmdlet. + + SwitchParameter + + SwitchParameter + + + False + + + WhatIf + + Shows what would happen if the cmdlet runs. The cmdlet is not run. + + SwitchParameter + + SwitchParameter + + + False + + + + + + + This command will assert UAC/Admin privileges on the machine if `-PathType 'Machine'`. + This is used when the application/tool is not being linked by Chocolatey (not in the lib folder). + + + + + -------------------------- Example 2 -------------------------- + PS C:\> Install-ChocolateyPath -PathToInstall "$($env:SystemDrive)\tools\gittfs" + + Adds the target path to the current user's PATH. + + + + -------------------------- Example 1 -------------------------- + PS C:\> Install-ChocolateyPath "$($env:SystemDrive)\Program Files\MySQL\MySQL Server 5.5\bin" -PathType 'Machine' + + Adds the target path to the system-wide PATH. + + + + + + Online Version: + https://docs.chocolatey.org/en-us/create/cmdlets/install-chocolateypath + + + Uninstall-ChocolateyPath + xref:uninstall-chocolateypath,mb-3 d-block + + + Install-ChocolateyEnvironmentVariable + xref:install-chocolateyenvironmentvariable,mb-3 d-block + + + Get-EnvironmentVariableNames + xref:get-environmentvariablenames,mb-3 d-block + + + Set-EnvironmentVariable + xref:set-environmentvariable,mb-3 d-block + + + Get-ToolsLocation + xref:get-toolslocation,mb-3 d-block + + + Cmdlet Reference + xref:powershell-cmdlet-reference,mb-3 d-block + + + Function Reference + xref:powershell-reference,d-block + + + + + + Set-EnvironmentVariable + Set + EnvironmentVariable + + > :choco-info: NOTE > > Administrative Access Required when `-Scope 'Machine'.` DO NOT USE. Not part of the public API. Use `Install-ChocolateyEnvironmentVariable` instead. + + - The environment variable target scope. This is `Process`, `User`, or `Machine`. + Saves an environment variable. - EnvironmentVariableTarget - - EnvironmentVariableTarget - - - None - - - - - - - System.String - + + + Set-EnvironmentVariable + + Name + + The name of the environment variable to set. + + String + + String + + + None + + + Value + + The value to set the named environment variable to. + + String + + String + + + None + + + Scope + + The scope to set the environment variable at. + + + Process + User + Machine + + EnvironmentVariableTarget + + EnvironmentVariableTarget + + + None + + + IgnoredArguments + + Allows splatting with arguments that do not apply. Do not use directly. + + Object[] + + Object[] + + + None + + + Confirm + + Prompts you for confirmation before running the cmdlet. + + + SwitchParameter + + + False + + + WhatIf + + Shows what would happen if the cmdlet runs. The cmdlet is not run. + + + SwitchParameter + + + False + + + + + + IgnoredArguments + + Allows splatting with arguments that do not apply. Do not use directly. + + Object[] + + Object[] + + + None + + + Name + + The name of the environment variable to set. + + String + + String + + + None + + + Scope + + The scope to set the environment variable at. + + EnvironmentVariableTarget + + EnvironmentVariableTarget + + + None + + + Value + + The value to set the named environment variable to. + + String + + String + + + None + + + Confirm + + Prompts you for confirmation before running the cmdlet. + + SwitchParameter + + SwitchParameter + + + False + + + WhatIf + + Shows what would happen if the cmdlet runs. The cmdlet is not run. + + SwitchParameter + + SwitchParameter + + + False + + + + + + + This command will assert UAC/Admin privileges on the machine if `-Scope 'Machine'`. + + + + + -------------------------- Example 1 -------------------------- + PS C:\> Set-EnvironmentVariable -Name MyApplicationPath -Value C:\test -Scope Machine + + Sets the `MyApplicationPath` environment variable to `C:\test` at the system level. + + + + + + Online Version: + https://docs.chocolatey.org/en-us/create/cmdlets/set-environmentvariable + + + Install-ChocolateyEnvironmentVariable + xref:install-chocolateyenvironmentvariable,mb-3 d-block + + + Uninstall-ChocolateyEnvironmentVariable + xref:uninstall-chocolateyenvironmentvariable,mb-3 d-block + + + Install-ChocolateyPath + xref:install-chocolateypath,mb-3 d-block + + + Get-EnvironmentVariableNames + xref:get-environmentvariablenames,mb-3 d-block + + + Cmdlet Reference + xref:powershell-cmdlet-reference,mb-3 d-block + + + Function Reference + xref:powershell-reference,d-block + + + + + + Test-ProcessAdminRights + Test + ProcessAdminRights + + Tests whether the current process is running with administrative rights. + + - Outputs the value of the target environment variable as a string. + This function checks whether the current process has administrative rights by checking if the current user identity is a member of the Administrators group. It returns `$true` if the current process is running with administrative rights, `$false` otherwise. + On Windows Vista and later, with UAC enabled, the returned value represents the actual rights available to the process, for example if it returns `$true`, the process is running elevated. - - - - - This helper reduces the number of lines one would have to write to get environment variables, mainly when not expanding the variables is a must. - - - - - -------------------------- Example 1 -------------------------- - PS C:\> Get-EnvironmentVariable -Name 'TEMP' -Scope User -PreserveVariables - - Gets the `TEMP` encironment variable from the user scope, without expanding embedded environment variables. - - - - -------------------------- Example 2 -------------------------- - PS C:\> Get-EnvironmentVariable -Name 'PATH' -Scope Machine - - Gets the `PATH` environment variable from the machine scope, expanding embedded environment variables. - - - - - - Online Version: - https://docs.chocolatey.org/en-us/create/cmdlets/get-environmentvariable - - - Get-EnvironmentVariableNames - xref:get-environmentvariablenames,mb-3 d-block - - - Set-EnvironmentVariable - xref:set-environmentvariable,mb-3 d-block - - - Cmdlet Reference - xref:powershell-cmdlet-reference,mb-3 d-block - - - Function Reference - xref:powershell-reference,d-block - - - - - - Get-EnvironmentVariableNames - Get - EnvironmentVariableNames - - Gets all environment variable names. - - - - Provides a list of environment variable names based on the scope. This can be used to loop through the list and generate names. - - - - Get-EnvironmentVariableNames - - Scope - - The environment variable target scope. This is `Process`, `User`, or `Machine`. - - - Process - User - Machine - - EnvironmentVariableTarget - - EnvironmentVariableTarget - - - None - - - IgnoredArguments - - Allows splatting with arguments that do not apply. Do not use directly. - - Object[] - - Object[] - - - None - - - - - - IgnoredArguments + + + Test-ProcessAdminRights + + IgnoredArguments + + Allows splatting with arguments that do not apply. Do not use directly. + + Object[] + + Object[] + + + None + + + + + + IgnoredArguments + + Allows splatting with arguments that do not apply. Do not use directly. + + Object[] + + Object[] + + + None + + + + + + + System.Boolean + + + Outputs `$true` if the current process has admin rights, otherwise `$false`. + + + + + + + + + + + -------------------------- Example 1 -------------------------- + PS C:\> Test-ProcessAdminRights + + Outputs `$true` if the current process is elevated, otherwise `$false`. + + + + + + Online Version: + https://docs.chocolatey.org/en-us/create/cmdlets/test-processadminrights + + + Cmdlet Reference + xref:powershell-cmdlet-reference,mb-3 d-block + + + Function Reference + xref:powershell-reference,d-block + + + + + + Uninstall-ChocolateyPath + Uninstall + ChocolateyPath + + > :choco-info: NOTE > > Administrative Access Required when `-PathType 'Machine'.` This puts a directory to the PATH environment variable. + + - Allows splatting with arguments that do not apply. Do not use directly. + Ensures that the given path is not present in the given type of PATH environment variable as well as in the current session. - Object[] - - Object[] - - - None - - - Scope + + + Uninstall-ChocolateyPath + + Path + + The exact path to remove from the environment PATH. + + String + + String + + + None + + + PathType + + Which PATH to add it to. If specifying `Machine`, this requires admin privileges to run correctly. + + + Process + User + Machine + + EnvironmentVariableTarget + + EnvironmentVariableTarget + + + None + + + IgnoredArguments + + Allows splatting with arguments that do not apply. Do not use directly. + + Object[] + + Object[] + + + None + + + Confirm + + Prompts you for confirmation before running the cmdlet. + + + SwitchParameter + + + False + + + WhatIf + + Shows what would happen if the cmdlet runs. The cmdlet is not run. + + + SwitchParameter + + + False + + + + + + IgnoredArguments + + Allows splatting with arguments that do not apply. Do not use directly. + + Object[] + + Object[] + + + None + + + Path + + The exact path to remove from the environment PATH. + + String + + String + + + None + + + PathType + + Which PATH to add it to. If specifying `Machine`, this requires admin privileges to run correctly. + + EnvironmentVariableTarget + + EnvironmentVariableTarget + + + None + + + Confirm + + Prompts you for confirmation before running the cmdlet. + + SwitchParameter + + SwitchParameter + + + False + + + WhatIf + + Shows what would happen if the cmdlet runs. The cmdlet is not run. + + SwitchParameter + + SwitchParameter + + + False + + + + + + + This command will assert UAC/Admin privileges on the machine if `-PathType 'Machine'`. This is used when the application/tool is not being linked by Chocolatey (not in the lib folder). + + + + + -------------------------- Example 1 -------------------------- + PS C:\> Uninstall-ChocolateyPath -PathToUninstall "$($env:SystemDrive)\tools\gittfs" + + Removes the target path from the current user's PATH environment variable. + + + + -------------------------- Example 2 -------------------------- + PS C:\> Uninstall-ChocolateyPath "$($env:SystemDrive)\Program Files\MySQL\MySQL Server 5.5\bin" -PathType 'Machine' + + Removes the target path from the system-wide PATH environment variable. + + + + + + Online Version: + https://docs.chocolatey.org/en-us/create/cmdlets/uninstall-chocolateypath + + + Install-ChocolateyPath + xref:install-chocolateypath,mb-3 d-block + + + Install-ChocolateyEnvironmentVariable + xref:install-chocolateyenvironmentvariable,mb-3 d-block + + + Get-EnvironmentVariableNames + xref:get-environmentvariablenames,mb-3 d-block + + + Set-EnvironmentVariable + xref:set-environmentvariable,mb-3 d-block + + + Get-ToolsLocation + xref:get-toolslocation,mb-3 d-block + + + Cmdlet Reference + xref:powershell-cmdlet-reference,mb-3 d-block + + + Function Reference + xref:powershell-reference,d-block + + + + + + Update-SessionEnvironment + Update + SessionEnvironment + + Updates the environment variables of the current powershell session with any environment variable changes that may have occurred during a Chocolatey package install. + + - The environment variable target scope. This is `Process`, `User`, or `Machine`. + When Chocolatey installs a package, the package author may add or change certain environment variables that will affect how the application runs or how it is accessed. Often, these changes are not visible to the current PowerShell session. This means the user needs to open a new PowerShell session before these settings take effect which can render the installed application nonfunctional until that time. + Use the Update-SessionEnvironment command to refresh the current PowerShell session with all environment settings possibly performed by Chocolatey package installs. - EnvironmentVariableTarget - - EnvironmentVariableTarget - - - None - - - - - - - System.String - - - Outputs the names of all the environment variables in the target scope as strings. - - - - - - Process dumps the current environment variable names in memory / session. The other scopes refer to the registry values. - - - - - -------------------------- Example 1 -------------------------- - PS C:\> Get-EnvironmentVariableNames -Scope Machine - - Outputs the names of all the environment variables defined in the registry for the Machine scope. - - - - - - Online Version: - https://docs.chocolatey.org/en-us/create/cmdlets/get-environmentvariablenames - - - Get-EnvironmentVariableNames - xref:get-environmentvariablenames,mb-3 d-block - - - Set-EnvironmentVariable - xref:set-environmentvariable,mb-3 d-block - - - Cmdlet Reference - xref:powershell-cmdlet-reference,mb-3 d-block - - - Function Reference - xref:powershell-reference,d-block - - - - - - Install-ChocolateyPath - Install - ChocolateyPath - - > :choco-info: NOTE > > Administrative Access Required when `-PathType 'Machine'.` This puts a directory to the PATH environment variable. - - - - Looks at both PATH environment variables to ensure a path variable correctly shows up on the right PATH. - - - - Install-ChocolateyPath - - Path - - The full path to a location to add / ensure is in the PATH. - - String - - String - - - None - - - PathType - - Which PATH to add it to. If specifying `Machine`, this requires admin privileges to run correctly. - - - Process - User - Machine - - EnvironmentVariableTarget - - EnvironmentVariableTarget - - - None - - - IgnoredArguments - - Allows splatting with arguments that do not apply. Do not use directly. - - Object[] - - Object[] - - - None - - - Confirm - - Prompts you for confirmation before running the cmdlet. - - - SwitchParameter - - - False - - - WhatIf - - Shows what would happen if the cmdlet runs. The cmdlet is not run. - - - SwitchParameter - - - False - - - - - - IgnoredArguments - - Allows splatting with arguments that do not apply. Do not use directly. - - Object[] - - Object[] - - - None - - - Path - - The full path to a location to add / ensure is in the PATH. - - String - - String - - - None - - - PathType - - Which PATH to add it to. If specifying `Machine`, this requires admin privileges to run correctly. - - EnvironmentVariableTarget - - EnvironmentVariableTarget - - - None - - - Confirm - - Prompts you for confirmation before running the cmdlet. - - SwitchParameter - - SwitchParameter - - - False - - - WhatIf - - Shows what would happen if the cmdlet runs. The cmdlet is not run. - - SwitchParameter - - SwitchParameter - - - False - - - - - - - This command will assert UAC/Admin privileges on the machine if `-PathType 'Machine'`. - This is used when the application/tool is not being linked by Chocolatey (not in the lib folder). - - - - - -------------------------- Example 2 -------------------------- - PS C:\> Install-ChocolateyPath -PathToInstall "$($env:SystemDrive)\tools\gittfs" - - Adds the target path to the current user's PATH. - - - - -------------------------- Example 1 -------------------------- - PS C:\> Install-ChocolateyPath "$($env:SystemDrive)\Program Files\MySQL\MySQL Server 5.5\bin" -PathType 'Machine' - - Adds the target path to the system-wide PATH. - - - - - - Online Version: - https://docs.chocolatey.org/en-us/create/cmdlets/install-chocolateypath - - - Uninstall-ChocolateyPath - xref:uninstall-chocolateypath,mb-3 d-block - - - Install-ChocolateyEnvironmentVariable - xref:install-chocolateyenvironmentvariable,mb-3 d-block - - - Get-EnvironmentVariableNames - xref:get-environmentvariablenames,mb-3 d-block - - - Set-EnvironmentVariable - xref:set-environmentvariable,mb-3 d-block - - - Get-ToolsLocation - xref:get-toolslocation,mb-3 d-block - - - Cmdlet Reference - xref:powershell-cmdlet-reference,mb-3 d-block - - - Function Reference - xref:powershell-reference,d-block - - - - - - Set-EnvironmentVariable - Set - EnvironmentVariable - - > :choco-info: NOTE > > Administrative Access Required when `-Scope 'Machine'.` DO NOT USE. Not part of the public API. Use `Install-ChocolateyEnvironmentVariable` instead. - - - - Saves an environment variable. - - - - Set-EnvironmentVariable - - Name - - The name of the environment variable to set. - - String - - String - - - None - - - Value - - The value to set the named environment variable to. - - String - - String - - - None - - - Scope - - The scope to set the environment variable at. - - - Process - User - Machine - - EnvironmentVariableTarget - - EnvironmentVariableTarget - - - None - - - IgnoredArguments - - Allows splatting with arguments that do not apply. Do not use directly. - - Object[] - - Object[] - - - None - - - Confirm - - Prompts you for confirmation before running the cmdlet. - - - SwitchParameter - - - False - - - WhatIf - - Shows what would happen if the cmdlet runs. The cmdlet is not run. - - - SwitchParameter - - - False - - - - - - IgnoredArguments - - Allows splatting with arguments that do not apply. Do not use directly. - - Object[] - - Object[] - - - None - - - Name - - The name of the environment variable to set. - - String - - String - - - None - - - Scope - - The scope to set the environment variable at. - - EnvironmentVariableTarget - - EnvironmentVariableTarget - - - None - - - Value - - The value to set the named environment variable to. - - String - - String - - - None - - - Confirm - - Prompts you for confirmation before running the cmdlet. - - SwitchParameter - - SwitchParameter - - - False - - - WhatIf - - Shows what would happen if the cmdlet runs. The cmdlet is not run. - - SwitchParameter - - SwitchParameter - - - False - - - - - - - This command will assert UAC/Admin privileges on the machine if `-Scope 'Machine'`. - - - - - -------------------------- Example 1 -------------------------- - PS C:\> Set-EnvironmentVariable -Name MyApplicationPath -Value C:\test -Scope Machine - - Sets the `MyApplicationPath` environment variable to `C:\test` at the system level. - - - - - - Online Version: - https://docs.chocolatey.org/en-us/create/cmdlets/set-environmentvariable - - - Install-ChocolateyEnvironmentVariable - xref:install-chocolateyenvironmentvariable,mb-3 d-block - - - Uninstall-ChocolateyEnvironmentVariable - xref:uninstall-chocolateyenvironmentvariable,mb-3 d-block - - - Install-ChocolateyPath - xref:install-chocolateypath,mb-3 d-block - - - Get-EnvironmentVariableNames - xref:get-environmentvariablenames,mb-3 d-block - - - Cmdlet Reference - xref:powershell-cmdlet-reference,mb-3 d-block - - - Function Reference - xref:powershell-reference,d-block - - - - - - Test-ProcessAdminRights - Test - ProcessAdminRights - - Tests whether the current process is running with administrative rights. - - - - This function checks whether the current process has administrative rights by checking if the current user identity is a member of the Administrators group. It returns `$true` if the current process is running with administrative rights, `$false` otherwise. - On Windows Vista and later, with UAC enabled, the returned value represents the actual rights available to the process, for example if it returns `$true`, the process is running elevated. - - - - Test-ProcessAdminRights - - IgnoredArguments - - Allows splatting with arguments that do not apply. Do not use directly. - - Object[] - - Object[] - - - None - - - - - - IgnoredArguments - - Allows splatting with arguments that do not apply. Do not use directly. - - Object[] - - Object[] - - - None - - - - - - - System.Boolean - - - Outputs `$true` if the current process has admin rights, otherwise `$false`. - - - - - - - - - - - -------------------------- Example 1 -------------------------- - PS C:\> Test-ProcessAdminRights - - Outputs `$true` if the current process is elevated, otherwise `$false`. - - - - - - Online Version: - https://docs.chocolatey.org/en-us/create/cmdlets/test-processadminrights - - - Cmdlet Reference - xref:powershell-cmdlet-reference,mb-3 d-block - - - Function Reference - xref:powershell-reference,d-block - - - - - - Uninstall-ChocolateyPath - Uninstall - ChocolateyPath - - > :choco-info: NOTE > > Administrative Access Required when `-PathType 'Machine'.` This puts a directory to the PATH environment variable. - - - - Ensures that the given path is not present in the given type of PATH environment variable as well as in the current session. - - - - Uninstall-ChocolateyPath - - Path - - The exact path to remove from the environment PATH. - - String - - String - - - None - - - PathType - - Which PATH to add it to. If specifying `Machine`, this requires admin privileges to run correctly. - - - Process - User - Machine - - EnvironmentVariableTarget - - EnvironmentVariableTarget - - - None - - - IgnoredArguments - - Allows splatting with arguments that do not apply. Do not use directly. - - Object[] - - Object[] - - - None - - - Confirm - - Prompts you for confirmation before running the cmdlet. - - - SwitchParameter - - - False - - - WhatIf - - Shows what would happen if the cmdlet runs. The cmdlet is not run. - - - SwitchParameter - - - False - - - - - - IgnoredArguments - - Allows splatting with arguments that do not apply. Do not use directly. - - Object[] - - Object[] - - - None - - - Path - - The exact path to remove from the environment PATH. - - String - - String - - - None - - - PathType - - Which PATH to add it to. If specifying `Machine`, this requires admin privileges to run correctly. - - EnvironmentVariableTarget - - EnvironmentVariableTarget - - - None - - - Confirm - - Prompts you for confirmation before running the cmdlet. - - SwitchParameter - - SwitchParameter - - - False - - - WhatIf - - Shows what would happen if the cmdlet runs. The cmdlet is not run. - - SwitchParameter - - SwitchParameter - - - False - - - - - - - This command will assert UAC/Admin privileges on the machine if `-PathType 'Machine'`. This is used when the application/tool is not being linked by Chocolatey (not in the lib folder). - - - - - -------------------------- Example 1 -------------------------- - PS C:\> Uninstall-ChocolateyPath -PathToUninstall "$($env:SystemDrive)\tools\gittfs" - - Removes the target path from the current user's PATH environment variable. - - - - -------------------------- Example 2 -------------------------- - PS C:\> Uninstall-ChocolateyPath "$($env:SystemDrive)\Program Files\MySQL\MySQL Server 5.5\bin" -PathType 'Machine' - - Removes the target path from the system-wide PATH environment variable. - - - - - - Online Version: - https://docs.chocolatey.org/en-us/create/cmdlets/uninstall-chocolateypath - - - Install-ChocolateyPath - xref:install-chocolateypath,mb-3 d-block - - - Install-ChocolateyEnvironmentVariable - xref:install-chocolateyenvironmentvariable,mb-3 d-block - - - Get-EnvironmentVariableNames - xref:get-environmentvariablenames,mb-3 d-block - - - Set-EnvironmentVariable - xref:set-environmentvariable,mb-3 d-block - - - Get-ToolsLocation - xref:get-toolslocation,mb-3 d-block - - - Cmdlet Reference - xref:powershell-cmdlet-reference,mb-3 d-block - - - Function Reference - xref:powershell-reference,d-block - - - - - - Update-SessionEnvironment - Update - SessionEnvironment - - Updates the environment variables of the current powershell session with any environment variable changes that may have occurred during a Chocolatey package install. - - - - When Chocolatey installs a package, the package author may add or change certain environment variables that will affect how the application runs or how it is accessed. Often, these changes are not visible to the current PowerShell session. This means the user needs to open a new PowerShell session before these settings take effect which can render the installed application nonfunctional until that time. - Use the Update-SessionEnvironment command to refresh the current PowerShell session with all environment settings possibly performed by Chocolatey package installs. - - - - Update-SessionEnvironment - - IgnoredArguments - - Allows splatting with arguments that do not apply. Do not use directly. - - Object[] - - Object[] - - - None - - - Confirm - - Prompts you for confirmation before running the cmdlet. - - - SwitchParameter - - - False - - - WhatIf - - Shows what would happen if the cmdlet runs. The cmdlet is not run. - - - SwitchParameter - - - False - - - - - - IgnoredArguments - - Allows splatting with arguments that do not apply. Do not use directly. - - Object[] - - Object[] - - - None - - - Confirm - - Prompts you for confirmation before running the cmdlet. - - SwitchParameter - - SwitchParameter - - - False - - - WhatIf - - Shows what would happen if the cmdlet runs. The cmdlet is not run. - - SwitchParameter - - SwitchParameter - - - False - - - - - - - This method is also added to the user's PowerShell profile as `refreshenv`. When called as `refreshenv`, the method will provide additional output. - Preserves `PSModulePath` as set by the process. - - - - - -------------------------- Example 1 -------------------------- - PS C:\> Update-SessionEnvironment - - Updates the current session environment variables. - - - - - - Online Version: - https://docs.chocolatey.org/en-us/create/cmdlets/update-sessionenvironment - - - Cmdlet Reference - xref:powershell-cmdlet-reference,mb-3 d-block - - - Function Reference - xref:powershell-reference,d-block - - - - \ No newline at end of file + + + Update-SessionEnvironment + + IgnoredArguments + + Allows splatting with arguments that do not apply. Do not use directly. + + Object[] + + Object[] + + + None + + + Confirm + + Prompts you for confirmation before running the cmdlet. + + + SwitchParameter + + + False + + + WhatIf + + Shows what would happen if the cmdlet runs. The cmdlet is not run. + + + SwitchParameter + + + False + + + + + + IgnoredArguments + + Allows splatting with arguments that do not apply. Do not use directly. + + Object[] + + Object[] + + + None + + + Confirm + + Prompts you for confirmation before running the cmdlet. + + SwitchParameter + + SwitchParameter + + + False + + + WhatIf + + Shows what would happen if the cmdlet runs. The cmdlet is not run. + + SwitchParameter + + SwitchParameter + + + False + + + + + + + This method is also added to the user's PowerShell profile as `refreshenv`. When called as `refreshenv`, the method will provide additional output. + Preserves `PSModulePath` as set by the process. + + + + + -------------------------- Example 1 -------------------------- + PS C:\> Update-SessionEnvironment + + Updates the current session environment variables. + + + + + + Online Version: + https://docs.chocolatey.org/en-us/create/cmdlets/update-sessionenvironment + + + Cmdlet Reference + xref:powershell-cmdlet-reference,mb-3 d-block + + + Function Reference + xref:powershell-reference,d-block + + + + diff --git a/src/UniGetUI.PackageEngine.Managers.Chocolatey/choco-cli/tools/checksum.exe.config b/src/UniGetUI.PackageEngine.Managers.Chocolatey/choco-cli/tools/checksum.exe.config index a3a1b65776..3ae3fbb439 100644 --- a/src/UniGetUI.PackageEngine.Managers.Chocolatey/choco-cli/tools/checksum.exe.config +++ b/src/UniGetUI.PackageEngine.Managers.Chocolatey/choco-cli/tools/checksum.exe.config @@ -1,6 +1,6 @@ - + - \ No newline at end of file + diff --git a/src/UniGetUI.PackageEngine.Managers.Dotnet/DotNet.cs b/src/UniGetUI.PackageEngine.Managers.Dotnet/DotNet.cs index 70a421afab..1ddcb92d40 100644 --- a/src/UniGetUI.PackageEngine.Managers.Dotnet/DotNet.cs +++ b/src/UniGetUI.PackageEngine.Managers.Dotnet/DotNet.cs @@ -28,28 +28,43 @@ public DotNet() CanDownloadInstaller = true, SupportsCustomScopes = true, SupportsCustomArchitectures = true, - SupportedCustomArchitectures = [Architecture.x86, Architecture.x64, Architecture.arm64, Architecture.arm32], + SupportedCustomArchitectures = + [ + Architecture.x86, + Architecture.x64, + Architecture.arm64, + Architecture.arm32, + ], SupportsPreRelease = true, CanListDependencies = true, SupportsCustomLocations = true, SupportsCustomPackageIcons = true, SupportsCustomVersions = true, SupportsProxy = ProxySupport.Partially, - SupportsProxyAuth = true + SupportsProxyAuth = true, }; Properties = new ManagerProperties { Name = ".NET Tool", - Description = CoreTools.Translate("A repository full of tools and executables designed with Microsoft's .NET ecosystem in mind.
Contains: .NET related tools and scripts"), + Description = CoreTools.Translate( + "A repository full of tools and executables designed with Microsoft's .NET ecosystem in mind.
Contains: .NET related tools and scripts" + ), IconId = IconType.DotNet, ColorIconId = "dotnet_color", ExecutableFriendlyName = "dotnet tool", InstallVerb = "install", UninstallVerb = "uninstall", UpdateVerb = "update", - DefaultSource = new ManagerSource(this, "nuget.org", new Uri("https://www.nuget.org/api/v2")), - KnownSources = [new ManagerSource(this, "nuget.org", new Uri("https://www.nuget.org/api/v2"))], + DefaultSource = new ManagerSource( + this, + "nuget.org", + new Uri("https://www.nuget.org/api/v2") + ), + KnownSources = + [ + new ManagerSource(this, "nuget.org", new Uri("https://www.nuget.org/api/v2")), + ], }; DetailsHelper = new DotNetDetailsHelper(this); @@ -59,23 +74,35 @@ public DotNet() protected override IReadOnlyList _getInstalledPackages_UnSafe() { List Packages = []; - foreach (var options in new OverridenInstallationOptions[] { new(PackageScope.Local), new(PackageScope.Global) }) + foreach ( + var options in new OverridenInstallationOptions[] + { + new(PackageScope.Local), + new(PackageScope.Global), + } + ) { using Process p = new() { StartInfo = new ProcessStartInfo { FileName = Status.ExecutablePath, - Arguments = Status.ExecutableCallArgs + " list" + (options.Scope == PackageScope.Global ? " --global" : ""), + Arguments = + Status.ExecutableCallArgs + + " list" + + (options.Scope == PackageScope.Global ? " --global" : ""), RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true, - StandardOutputEncoding = System.Text.Encoding.UTF8 - } + StandardOutputEncoding = System.Text.Encoding.UTF8, + }, }; - IProcessTaskLogger logger = TaskLogger.CreateNew(LoggableTaskType.ListInstalledPackages, p); + IProcessTaskLogger logger = TaskLogger.CreateNew( + LoggableTaskType.ListInstalledPackages, + p + ); p.Start(); string? line; @@ -103,19 +130,24 @@ protected override IReadOnlyList _getInstalledPackages_UnSafe() elements[i] = elements[i].Trim(); } - if (FALSE_PACKAGE_IDS.Contains(elements[0]) || FALSE_PACKAGE_VERSIONS.Contains(elements[1])) + if ( + FALSE_PACKAGE_IDS.Contains(elements[0]) + || FALSE_PACKAGE_VERSIONS.Contains(elements[1]) + ) { continue; } - Packages.Add(new Package( - CoreTools.FormatAsName(elements[0]), - elements[0], - elements[1], - DefaultSource, - this, - options - )); + Packages.Add( + new Package( + CoreTools.FormatAsName(elements[0]), + elements[0], + elements[1], + DefaultSource, + this, + options + ) + ); } } logger.AddToStdErr(p.StandardError.ReadToEnd()); @@ -125,10 +157,14 @@ protected override IReadOnlyList _getInstalledPackages_UnSafe() return Packages; } - public override IReadOnlyList FindCandidateExecutableFiles() - => CoreTools.WhichMultiple("dotnet.exe"); + public override IReadOnlyList FindCandidateExecutableFiles() => + CoreTools.WhichMultiple("dotnet.exe"); - protected override void _loadManagerExecutableFile(out bool found, out string path, out string callArguments) + protected override void _loadManagerExecutableFile( + out bool found, + out string path, + out string callArguments + ) { var (_found, _path) = GetExecutableFile(); found = _found; @@ -136,7 +172,8 @@ protected override void _loadManagerExecutableFile(out bool found, out string pa callArguments = "tool "; // Ensure .NET SDK is installed - if (!found) return; + if (!found) + return; var process = new Process() { StartInfo = new ProcessStartInfo @@ -147,8 +184,8 @@ protected override void _loadManagerExecutableFile(out bool found, out string pa RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true, - StandardOutputEncoding = System.Text.Encoding.UTF8 - } + StandardOutputEncoding = System.Text.Encoding.UTF8, + }, }; process.Start(); process.WaitForExit(); @@ -167,8 +204,8 @@ protected override void _loadManagerVersion(out string version) RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true, - StandardOutputEncoding = System.Text.Encoding.UTF8 - } + StandardOutputEncoding = System.Text.Encoding.UTF8, + }, }; process.Start(); diff --git a/src/UniGetUI.PackageEngine.Managers.Dotnet/Helpers/DotNetDetailsHelper.cs b/src/UniGetUI.PackageEngine.Managers.Dotnet/Helpers/DotNetDetailsHelper.cs index 79dd73f356..779bf51527 100644 --- a/src/UniGetUI.PackageEngine.Managers.Dotnet/Helpers/DotNetDetailsHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Dotnet/Helpers/DotNetDetailsHelper.cs @@ -5,12 +5,16 @@ namespace UniGetUI.PackageEngine.Managers.Chocolatey { public class DotNetDetailsHelper : BaseNuGetDetailsHelper { - public DotNetDetailsHelper(BaseNuGet manager) : base(manager) - { } + public DotNetDetailsHelper(BaseNuGet manager) + : base(manager) { } protected override string? GetInstallLocation_UnSafe(IPackage package) { - return Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".dotnet", "tools"); + return Path.Join( + Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), + ".dotnet", + "tools" + ); } } } diff --git a/src/UniGetUI.PackageEngine.Managers.Dotnet/Helpers/DotNetPkgOperationHelper.cs b/src/UniGetUI.PackageEngine.Managers.Dotnet/Helpers/DotNetPkgOperationHelper.cs index 944e03f0b5..9a77610214 100644 --- a/src/UniGetUI.PackageEngine.Managers.Dotnet/Helpers/DotNetPkgOperationHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Dotnet/Helpers/DotNetPkgOperationHelper.cs @@ -5,13 +5,17 @@ using Architecture = UniGetUI.PackageEngine.Enums.Architecture; namespace UniGetUI.PackageEngine.Managers.DotNetManager; + internal sealed class DotNetPkgOperationHelper : BasePkgOperationHelper { - public DotNetPkgOperationHelper(DotNet manager) : base(manager) { } + public DotNetPkgOperationHelper(DotNet manager) + : base(manager) { } - protected override IReadOnlyList _getOperationParameters(IPackage package, + protected override IReadOnlyList _getOperationParameters( + IPackage package, InstallOptions options, - OperationType operation) + OperationType operation + ) { List parameters = [ @@ -20,30 +24,35 @@ protected override IReadOnlyList _getOperationParameters(IPackage packag OperationType.Install => Manager.Properties.InstallVerb, OperationType.Update => Manager.Properties.UpdateVerb, OperationType.Uninstall => Manager.Properties.UninstallVerb, - _ => throw new InvalidDataException("Invalid package operation") + _ => throw new InvalidDataException("Invalid package operation"), }, - package.Id, - ]; if (options.CustomInstallLocation != "") parameters.AddRange(["--tool-path", "\"" + options.CustomInstallLocation + "\""]); - if (package.OverridenOptions.Scope is PackageScope.Global || - (package.OverridenOptions.Scope is null && options.InstallationScope is PackageScope.Global)) + if ( + package.OverridenOptions.Scope is PackageScope.Global + || ( + package.OverridenOptions.Scope is null + && options.InstallationScope is PackageScope.Global + ) + ) parameters.Add("--global"); if (operation is OperationType.Install or OperationType.Update) { - parameters.AddRange(options.Architecture switch - { - Architecture.x86 => ["--arch", "x86"], - Architecture.x64 => ["--arch", "x64"], - Architecture.arm32 => ["--arch", "arm32"], - Architecture.arm64 => ["--arch", "arm64"], - _ => [] - }); + parameters.AddRange( + options.Architecture switch + { + Architecture.x86 => ["--arch", "x86"], + Architecture.x64 => ["--arch", "x64"], + Architecture.arm32 => ["--arch", "arm32"], + Architecture.arm64 => ["--arch", "arm64"], + _ => [], + } + ); } if (operation is OperationType.Install) @@ -54,12 +63,14 @@ protected override IReadOnlyList _getOperationParameters(IPackage packag } } - parameters.AddRange(operation switch - { - OperationType.Update => options.CustomParameters_Update, - OperationType.Uninstall => options.CustomParameters_Uninstall, - _ => options.CustomParameters_Install, - }); + parameters.AddRange( + operation switch + { + OperationType.Update => options.CustomParameters_Update, + OperationType.Uninstall => options.CustomParameters_Uninstall, + _ => options.CustomParameters_Install, + } + ); return parameters; } @@ -68,7 +79,8 @@ protected override OperationVeredict _getOperationResult( IPackage package, OperationType operation, IReadOnlyList processOutput, - int returnCode) + int returnCode + ) { if (returnCode is not 0 && package.OverridenOptions.Scope is not PackageScope.Global) { diff --git a/src/UniGetUI.PackageEngine.Managers.Dotnet/UniGetUI.PackageEngine.Managers.Dotnet.csproj b/src/UniGetUI.PackageEngine.Managers.Dotnet/UniGetUI.PackageEngine.Managers.Dotnet.csproj index aab332b650..3a287c6f00 100644 --- a/src/UniGetUI.PackageEngine.Managers.Dotnet/UniGetUI.PackageEngine.Managers.Dotnet.csproj +++ b/src/UniGetUI.PackageEngine.Managers.Dotnet/UniGetUI.PackageEngine.Managers.Dotnet.csproj @@ -1,25 +1,28 @@ + + $(SharedTargetFrameworks) + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - + + + - - - + + + diff --git a/src/UniGetUI.PackageEngine.Managers.Generic.NuGet/BaseNuGet.cs b/src/UniGetUI.PackageEngine.Managers.Generic.NuGet/BaseNuGet.cs index 1b6cbfcdf1..e17b588037 100644 --- a/src/UniGetUI.PackageEngine.Managers.Generic.NuGet/BaseNuGet.cs +++ b/src/UniGetUI.PackageEngine.Managers.Generic.NuGet/BaseNuGet.cs @@ -20,17 +20,24 @@ public sealed override void Initialize() { static void ThrowIC(string name) { - throw new InvalidOperationException($"NuGet-based package managers must have Capabilities.{name} set to true"); + throw new InvalidOperationException( + $"NuGet-based package managers must have Capabilities.{name} set to true" + ); } if (DetailsHelper is not BaseNuGetDetailsHelper) { - throw new InvalidOperationException("NuGet-based package managers must not reassign the PackageDetailsProvider property"); + throw new InvalidOperationException( + "NuGet-based package managers must not reassign the PackageDetailsProvider property" + ); } - if (!Capabilities.SupportsCustomVersions) ThrowIC(nameof(Capabilities.SupportsCustomVersions)); - if (!Capabilities.SupportsCustomPackageIcons) ThrowIC(nameof(Capabilities.SupportsCustomPackageIcons)); - if (!Capabilities.CanListDependencies) ThrowIC(nameof(Capabilities.CanListDependencies)); + if (!Capabilities.SupportsCustomVersions) + ThrowIC(nameof(Capabilities.SupportsCustomVersions)); + if (!Capabilities.SupportsCustomPackageIcons) + ThrowIC(nameof(Capabilities.SupportsCustomPackageIcons)); + if (!Capabilities.CanListDependencies) + ThrowIC(nameof(Capabilities.CanListDependencies)); base.Initialize(); } @@ -55,23 +62,25 @@ protected sealed override IReadOnlyList FindPackages_UnSafe(string quer } else { - sources = [ Properties.DefaultSource ]; + sources = [Properties.DefaultSource]; } bool canPrerelease = InstallOptionsFactory.LoadForManager(this).PreRelease; - foreach(IManagerSource source in sources) + foreach (IManagerSource source in sources) { try { - Uri? SearchUrl = new($"{source.Url}/Search()" + - $"?$filter=IsLatestVersion" + - $"&$orderby=Id&searchTerm='{HttpUtility.UrlEncode(query)}'" + - $"&targetFramework=''" + - $"&includePrerelease={(canPrerelease ? "true" : "false")}" + - $"&$skip=0" + - $"&$top=50" + - $"&semVerLevel=2.0.0"); + Uri? SearchUrl = new( + $"{source.Url}/Search()" + + $"?$filter=IsLatestVersion" + + $"&$orderby=Id&searchTerm='{HttpUtility.UrlEncode(query)}'" + + $"&targetFramework=''" + + $"&includePrerelease={(canPrerelease ? "true" : "false")}" + + $"&$skip=0" + + $"&$top=50" + + $"&semVerLevel=2.0.0" + ); // Uri SearchUrl = new($"{source.Url}/Search()?$filter=IsLatestVersion&searchTerm=%27{HttpUtility.UrlEncode(query)}%27&targetFramework=%27%27&includePrerelease=false"); logger.Log($"Begin package search with url={SearchUrl} on manager {Name}"); Dictionary AlreadyProcessedPackages = []; @@ -81,17 +90,28 @@ protected sealed override IReadOnlyList FindPackages_UnSafe(string quer while (SearchUrl is not null) { - HttpResponseMessage response = client.GetAsync(SearchUrl).GetAwaiter().GetResult(); + HttpResponseMessage response = client + .GetAsync(SearchUrl) + .GetAwaiter() + .GetResult(); if (!response.IsSuccessStatusCode) { - logger.Error($"Failed to fetch api at Url={SearchUrl} with status code {response.StatusCode}"); + logger.Error( + $"Failed to fetch api at Url={SearchUrl} with status code {response.StatusCode}" + ); SearchUrl = null; continue; } - string SearchResults = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); - MatchCollection matches = Regex.Matches(SearchResults, "([\\s\\S]*?)<\\/entry>"); + string SearchResults = response + .Content.ReadAsStringAsync() + .GetAwaiter() + .GetResult(); + MatchCollection matches = Regex.Matches( + SearchResults, + "([\\s\\S]*?)<\\/entry>" + ); foreach (Match match in matches) { @@ -101,21 +121,35 @@ protected sealed override IReadOnlyList FindPackages_UnSafe(string quer } string id = Regex.Match(match.Value, "Id='([^<>']+)'").Groups[1].Value; - string version = Regex.Match(match.Value, "Version='([^<>']+)'").Groups[1].Value; + string version = Regex + .Match(match.Value, "Version='([^<>']+)'") + .Groups[1] + .Value; var float_version = CoreTools.VersionStringToStruct(version); // Match title = Regex.Match(match.Value, "([^<>]+)<\\/title>"); - if (AlreadyProcessedPackages.TryGetValue(id, out var value) && value.version_float >= float_version) + if ( + AlreadyProcessedPackages.TryGetValue(id, out var value) + && value.version_float >= float_version + ) { continue; } - AlreadyProcessedPackages[id] = - new SearchResult { id = id, version = version, version_float = float_version, manifest = match.Value }; + AlreadyProcessedPackages[id] = new SearchResult + { + id = id, + version = version, + version_float = float_version, + manifest = match.Value, + }; } SearchUrl = null; - Match next = Regex.Match(SearchResults, ""); + Match next = Regex.Match( + SearchResults, + "" + ); if (next.Success) { SearchUrl = new Uri(next.Groups[1].Value.Replace("&", "&")); @@ -125,15 +159,25 @@ protected sealed override IReadOnlyList FindPackages_UnSafe(string quer foreach (SearchResult package in AlreadyProcessedPackages.Values) { - logger.Log($"Found package {package.id} version {package.version} on source {source.Name}"); - var nativePackage = new Package(CoreTools.FormatAsName(package.id), package.id, package.version, source, this); + logger.Log( + $"Found package {package.id} version {package.version} on source {source.Name}" + ); + var nativePackage = new Package( + CoreTools.FormatAsName(package.id), + package.id, + package.version, + source, + this + ); Packages.Add(nativePackage); Manifests[nativePackage.GetHash()] = package.manifest; } } catch (Exception ex) { - logger.Error($"Source {source.Name} on manager {source.Manager.Name} failed to find package data"); + logger.Error( + $"Source {source.Name} on manager {source.Manager.Name} failed to find package data" + ); logger.Error(ex); } } @@ -147,7 +191,9 @@ protected override IReadOnlyList GetAvailableUpdates_UnSafe() int errors = 0; var logger = TaskLogger.CreateNew(LoggableTaskType.ListUpdates); - var installedPackages = TaskRecycler>.RunOrAttach(GetInstalledPackages); + var installedPackages = TaskRecycler>.RunOrAttach( + GetInstalledPackages + ); var Packages = new List(); Dictionary> sourceMapping = new(); @@ -155,7 +201,8 @@ protected override IReadOnlyList GetAvailableUpdates_UnSafe() foreach (var package in installedPackages) { var uri = package.Source; - if (!sourceMapping.ContainsKey(uri)) sourceMapping[uri] = new(); + if (!sourceMapping.ContainsKey(uri)) + sourceMapping[uri] = new(); sourceMapping[uri].Add(package); } bool canPrerelease = InstallOptionsFactory.LoadForManager(this).PreRelease; @@ -174,37 +221,65 @@ protected override IReadOnlyList GetAvailableUpdates_UnSafe() packageIdVersion[package.Id.ToLower()] = package.VersionString; } - var SearchUrl = $"{pair.Key.Url.ToString().Trim('/')}/GetUpdates()" + - $"?packageIds=%27{HttpUtility.UrlEncode(packageIds.ToString().Trim('|'))}%27" + - $"&versions=%27{HttpUtility.UrlEncode(packageVers.ToString().Trim('|'))}%27" + - $"&includePrerelease={(canPrerelease ? "true" : "false")}" + - $"&includeAllVersions=0"; + var SearchUrl = + $"{pair.Key.Url.ToString().Trim('/')}/GetUpdates()" + + $"?packageIds=%27{HttpUtility.UrlEncode(packageIds.ToString().Trim('|'))}%27" + + $"&versions=%27{HttpUtility.UrlEncode(packageVers.ToString().Trim('|'))}%27" + + $"&includePrerelease={(canPrerelease ? "true" : "false")}" + + $"&includeAllVersions=0"; using HttpClient client = new(CoreTools.GenericHttpClientParameters); client.DefaultRequestHeaders.UserAgent.ParseAdd(CoreData.UserAgentString); - HttpResponseMessage response = client.GetAsync(SearchUrl).GetAwaiter().GetResult(); + HttpResponseMessage response = client + .GetAsync(SearchUrl) + .GetAwaiter() + .GetResult(); if (!response.IsSuccessStatusCode) { - logger.Error($"Failed to fetch api at Url={SearchUrl} with status code {response.StatusCode}"); + logger.Error( + $"Failed to fetch api at Url={SearchUrl} with status code {response.StatusCode}" + ); errors++; } else { - string SearchResults = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); - MatchCollection matches = Regex.Matches(SearchResults, "([\\s\\S]*?)<\\/entry>"); + string SearchResults = response + .Content.ReadAsStringAsync() + .GetAwaiter() + .GetResult(); + MatchCollection matches = Regex.Matches( + SearchResults, + "([\\s\\S]*?)<\\/entry>" + ); foreach (Match match in matches) { - if (!match.Success) continue; + if (!match.Success) + continue; - string id = Regex.Match(match.Value, "([^<]+)").Groups[1].Value; - string new_version = Regex.Match(match.Value, "([^<]+)").Groups[1].Value; + string id = Regex + .Match(match.Value, "([^<]+)") + .Groups[1] + .Value; + string new_version = Regex + .Match(match.Value, "([^<]+)") + .Groups[1] + .Value; // Match title = Regex.Match(match.Value, "([^<>]+)<\\/title>"); - logger.Log($"Found package {id} version {new_version} on source {pair.Key.Name}"); - - var nativePackage = new Package(CoreTools.FormatAsName(id), id, packageIdVersion[id.ToLower()], new_version, pair.Key, this); + logger.Log( + $"Found package {id} version {new_version} on source {pair.Key.Name}" + ); + + var nativePackage = new Package( + CoreTools.FormatAsName(id), + id, + packageIdVersion[id.ToLower()], + new_version, + pair.Key, + this + ); Packages.Add(nativePackage); Manifests[nativePackage.GetHash()] = match.Value; } @@ -212,7 +287,9 @@ protected override IReadOnlyList GetAvailableUpdates_UnSafe() } catch (Exception ex) { - logger.Error($"Source {pair.Key.Name} on manager {pair.Key.Manager.Name} failed to load updates info with exception"); + logger.Error( + $"Source {pair.Key.Name} on manager {pair.Key.Manager.Name} failed to load updates info with exception" + ); logger.Error(ex); } } @@ -228,14 +305,14 @@ protected override IReadOnlyList GetAvailableUpdates_UnSafe() } logger.Close(errors); - return Packages.Where(p => maxVersions[p.Id.ToLower()] < p.NormalizedNewVersion).ToArray(); + return Packages + .Where(p => maxVersions[p.Id.ToLower()] < p.NormalizedNewVersion) + .ToArray(); } - protected sealed override IReadOnlyList GetInstalledPackages_UnSafe() - => TaskRecycler>.RunOrAttach(_getInstalledPackages_UnSafe); + protected sealed override IReadOnlyList GetInstalledPackages_UnSafe() => + TaskRecycler>.RunOrAttach(_getInstalledPackages_UnSafe); protected abstract IReadOnlyList _getInstalledPackages_UnSafe(); - } - } diff --git a/src/UniGetUI.PackageEngine.Managers.Generic.NuGet/BaseNuGetDetailsHelper.cs b/src/UniGetUI.PackageEngine.Managers.Generic.NuGet/BaseNuGetDetailsHelper.cs index 677b83c708..c10ebfa529 100644 --- a/src/UniGetUI.PackageEngine.Managers.Generic.NuGet/BaseNuGetDetailsHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Generic.NuGet/BaseNuGetDetailsHelper.cs @@ -12,7 +12,8 @@ namespace UniGetUI.PackageEngine.Managers.PowerShellManager { public abstract class BaseNuGetDetailsHelper : BasePkgDetailsHelper { - public BaseNuGetDetailsHelper(BaseNuGet manager) : base(manager) { } + public BaseNuGetDetailsHelper(BaseNuGet manager) + : base(manager) { } protected override void GetDetails_UnSafe(IPackageDetails details) { @@ -20,19 +21,28 @@ protected override void GetDetails_UnSafe(IPackageDetails details) try { details.ManifestUrl = NuGetManifestLoader.GetManifestUrl(details.Package); - string? PackageManifestContents = NuGetManifestLoader.GetManifestContent(details.Package); + string? PackageManifestContents = NuGetManifestLoader.GetManifestContent( + details.Package + ); logger.Log(PackageManifestContents); if (PackageManifestContents is null) { - logger.Error($"No manifest content could be loaded for package {details.Package.Id} on manager {details.Package.Manager.Name}, returning empty PackageDetails"); + logger.Error( + $"No manifest content could be loaded for package {details.Package.Id} on manager {details.Package.Manager.Name}, returning empty PackageDetails" + ); logger.Close(1); return; } details.InstallerType = CoreTools.Translate("NuPkg (zipped manifest)"); - foreach (Match match in Regex.Matches(PackageManifestContents, @"")) + foreach ( + Match match in Regex.Matches( + PackageManifestContents, + @"" + ) + ) { try { @@ -41,11 +51,19 @@ protected override void GetDetails_UnSafe(IPackageDetails details) } catch (Exception ex) { - Logger.Warn($"Failed to parse NuGet Installer URL on package Id={details.Package.Id} for value={match.Groups[1].Value}: " + ex.Message); + Logger.Warn( + $"Failed to parse NuGet Installer URL on package Id={details.Package.Id} for value={match.Groups[1].Value}: " + + ex.Message + ); } } - foreach (Match match in Regex.Matches(PackageManifestContents, @"<(d\:)?PackageSize (m\:type=""[^""]+"")?>([0-9]+)<\/")) + foreach ( + Match match in Regex.Matches( + PackageManifestContents, + @"<(d\:)?PackageSize (m\:type=""[^""]+"")?>([0-9]+)<\/" + ) + ) { try { @@ -54,74 +72,143 @@ protected override void GetDetails_UnSafe(IPackageDetails details) } catch (Exception ex) { - Logger.Warn($"Failed to parse NuGet Installer Size on package Id={details.Package.Id} for value={match.Groups[1].Value}: " + ex.Message); + Logger.Warn( + $"Failed to parse NuGet Installer Size on package Id={details.Package.Id} for value={match.Groups[1].Value}: " + + ex.Message + ); } } - foreach (Match match in Regex.Matches(PackageManifestContents, @"[^<>]+<\/name>")) + foreach ( + Match match in Regex.Matches(PackageManifestContents, @"[^<>]+<\/name>") + ) { details.Author = match.Value.Replace("", "").Replace("", ""); details.Publisher = match.Value.Replace("", "").Replace("", ""); break; } - foreach (Match match in Regex.Matches(PackageManifestContents, @"[^<>]+<\/d:Description>")) + foreach ( + Match match in Regex.Matches( + PackageManifestContents, + @"[^<>]+<\/d:Description>" + ) + ) { - details.Description = match.Value.Replace("", "").Replace("", ""); + details.Description = match + .Value.Replace("", "") + .Replace("", ""); break; } - foreach (Match match in Regex.Matches(PackageManifestContents, @"[^<>]+<\/updated>")) + foreach ( + Match match in Regex.Matches( + PackageManifestContents, + @"[^<>]+<\/updated>" + ) + ) { - details.UpdateDate = match.Value.Replace("", "").Replace("", ""); + details.UpdateDate = match + .Value.Replace("", "") + .Replace("", ""); break; } - foreach (Match match in Regex.Matches(PackageManifestContents, @"[^<>]+<\/d:ProjectUrl>")) + foreach ( + Match match in Regex.Matches( + PackageManifestContents, + @"[^<>]+<\/d:ProjectUrl>" + ) + ) { - details.HomepageUrl = new Uri(match.Value.Replace("", "").Replace("", "")); + details.HomepageUrl = new Uri( + match.Value.Replace("", "").Replace("", "") + ); break; } - foreach (Match match in Regex.Matches(PackageManifestContents, @"[^<>]+<\/d:LicenseUrl>")) + foreach ( + Match match in Regex.Matches( + PackageManifestContents, + @"[^<>]+<\/d:LicenseUrl>" + ) + ) { - details.LicenseUrl = new Uri(match.Value.Replace("", "").Replace("", "")); + details.LicenseUrl = new Uri( + match.Value.Replace("", "").Replace("", "") + ); break; } - foreach (Match match in Regex.Matches(PackageManifestContents, @"[^<>]+<\/d:PackageHash>")) + foreach ( + Match match in Regex.Matches( + PackageManifestContents, + @"[^<>]+<\/d:PackageHash>" + ) + ) { - details.InstallerHash = match.Value.Replace("", "").Replace("", ""); + details.InstallerHash = match + .Value.Replace("", "") + .Replace("", ""); break; } - foreach (Match match in Regex.Matches(PackageManifestContents, @"[^<>]+<\/d:ReleaseNotes>")) + foreach ( + Match match in Regex.Matches( + PackageManifestContents, + @"[^<>]+<\/d:ReleaseNotes>" + ) + ) { - details.ReleaseNotes = match.Value.Replace("", "").Replace("", ""); + details.ReleaseNotes = match + .Value.Replace("", "") + .Replace("", ""); break; } - foreach (Match match in Regex.Matches(PackageManifestContents, @"[^<>]+<\/d:LicenseNames>")) + foreach ( + Match match in Regex.Matches( + PackageManifestContents, + @"[^<>]+<\/d:LicenseNames>" + ) + ) { - details.License = match.Value.Replace("", "").Replace("", ""); + details.License = match + .Value.Replace("", "") + .Replace("", ""); break; } details.Dependencies.Clear(); - foreach (Match match in Regex.Matches(PackageManifestContents, - @"([^<]+)")) + foreach ( + Match match in Regex.Matches( + PackageManifestContents, + @"([^<]+)" + ) + ) { foreach (var dep in match.Groups[1].ToString().Split('|')) { - if(string.IsNullOrEmpty(dep)) + if (string.IsNullOrEmpty(dep)) continue; else if (dep.StartsWith("::")) - details.Dependencies.Add(new() { Name = dep.TrimStart(':'), Version = "", Mandatory = true }); + details.Dependencies.Add( + new() + { + Name = dep.TrimStart(':'), + Version = "", + Mandatory = true, + } + ); else - details.Dependencies.Add(new() - { - Name = dep.Split(':')[0], Version = dep.Split(':')[1].TrimEnd(':'), Mandatory = true - }); + details.Dependencies.Add( + new() + { + Name = dep.Split(':')[0], + Version = dep.Split(':')[1].TrimEnd(':'), + Mandatory = true, + } + ); } } @@ -141,11 +228,16 @@ protected override void GetDetails_UnSafe(IPackageDetails details) string? ManifestContent = NuGetManifestLoader.GetManifestContent(package); if (ManifestContent is null) { - Logger.Warn($"No manifest content could be loaded for package {package.Id} on manager {package.Manager.Name}"); + Logger.Warn( + $"No manifest content could be loaded for package {package.Id} on manager {package.Manager.Name}" + ); return null; } - Match possibleIconUrl = Regex.Match(ManifestContent, "<(?:d\\:)?IconUrl>(.*)<(?:\\/d:)?IconUrl>"); + Match possibleIconUrl = Regex.Match( + ManifestContent, + "<(?:d\\:)?IconUrl>(.*)<(?:\\/d:)?IconUrl>" + ); if (!possibleIconUrl.Success || possibleIconUrl.Groups[1].Value == "") { @@ -154,7 +246,10 @@ protected override void GetDetails_UnSafe(IPackageDetails details) } // Logger.Debug($"A native icon with Url={possibleIconUrl.Groups[1].Value} was found"); - return new CacheableIcon(new Uri(possibleIconUrl.Groups[1].Value), package.VersionString); + return new CacheableIcon( + new Uri(possibleIconUrl.Groups[1].Value), + package.VersionString + ); } protected override IReadOnlyList GetScreenshots_UnSafe(IPackage package) @@ -165,7 +260,9 @@ protected override IReadOnlyList GetScreenshots_UnSafe(IPackage package) protected override IReadOnlyList GetInstallableVersions_UnSafe(IPackage package) { Uri SearchUrl = new($"{package.Source.Url}/FindPackagesById()?id='{package.Id}'"); - Logger.Debug($"Begin package version search with url={SearchUrl} on manager {Manager.Name}"); + Logger.Debug( + $"Begin package version search with url={SearchUrl} on manager {Manager.Name}" + ); List results = []; @@ -175,7 +272,9 @@ protected override IReadOnlyList GetInstallableVersions_UnSafe(IPackage HttpResponseMessage response = client.GetAsync(SearchUrl).GetAwaiter().GetResult(); if (!response.IsSuccessStatusCode) { - Logger.Warn($"Failed to fetch api at Url={SearchUrl} with status code {response.StatusCode} to load versions"); + Logger.Warn( + $"Failed to fetch api at Url={SearchUrl} with status code {response.StatusCode} to load versions" + ); return []; } diff --git a/src/UniGetUI.PackageEngine.Managers.Generic.NuGet/Internal/NuGetManifestLoader.cs b/src/UniGetUI.PackageEngine.Managers.Generic.NuGet/Internal/NuGetManifestLoader.cs index 8950cf2144..9e3e9e6c32 100644 --- a/src/UniGetUI.PackageEngine.Managers.Generic.NuGet/Internal/NuGetManifestLoader.cs +++ b/src/UniGetUI.PackageEngine.Managers.Generic.NuGet/Internal/NuGetManifestLoader.cs @@ -15,7 +15,9 @@ internal static class NuGetManifestLoader /// A Uri object public static Uri GetManifestUrl(IPackage package) { - return new Uri($"{package.Source.Url}/Packages(Id='{package.Id}',Version='{package.VersionString}')"); + return new Uri( + $"{package.Source.Url}/Packages(Id='{package.Id}',Version='{package.VersionString}')" + ); } /// @@ -37,7 +39,9 @@ public static Uri GetNuPkgUrl(IPackage package) { if (BaseNuGet.Manifests.TryGetValue(package.GetHash(), out string? manifest)) { - Logger.Debug($"Loading cached NuGet manifest for package {package.Id} on manager {package.Manager.Name}"); + Logger.Debug( + $"Loading cached NuGet manifest for package {package.Id} on manager {package.Manager.Name}" + ); return manifest; } @@ -49,26 +53,39 @@ public static Uri GetNuPkgUrl(IPackage package) using (HttpClient client = new(CoreTools.GenericHttpClientParameters)) { client.DefaultRequestHeaders.UserAgent.ParseAdd(CoreData.UserAgentString); - HttpResponseMessage response = client.GetAsync(PackageManifestUrl).GetAwaiter().GetResult(); + HttpResponseMessage response = client + .GetAsync(PackageManifestUrl) + .GetAwaiter() + .GetResult(); if (!response.IsSuccessStatusCode && package.VersionString.EndsWith(".0")) { - response = client.GetAsync(new Uri(PackageManifestUrl.ToString().Replace(".0')", "')"))).GetAwaiter().GetResult(); + response = client + .GetAsync(new Uri(PackageManifestUrl.ToString().Replace(".0')", "')"))) + .GetAwaiter() + .GetResult(); } if (!response.IsSuccessStatusCode) { - Logger.Warn($"Failed to download the {package.Manager.Name} manifest at Url={PackageManifestUrl.ToString()} with status code {response.StatusCode}"); + Logger.Warn( + $"Failed to download the {package.Manager.Name} manifest at Url={PackageManifestUrl.ToString()} with status code {response.StatusCode}" + ); return null; } - PackageManifestContent = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + PackageManifestContent = response + .Content.ReadAsStringAsync() + .GetAwaiter() + .GetResult(); } BaseNuGet.Manifests[package.GetHash()] = PackageManifestContent; return PackageManifestContent; } catch (Exception e) { - Logger.Warn($"Failed to download the {package.Manager.Name} manifest at Url={PackageManifestUrl.ToString()}"); + Logger.Warn( + $"Failed to download the {package.Manager.Name} manifest at Url={PackageManifestUrl.ToString()}" + ); Logger.Warn(e); return null; } diff --git a/src/UniGetUI.PackageEngine.Managers.Generic.NuGet/UniGetUI.PackageEngine.Managers.Generic.NuGet.csproj b/src/UniGetUI.PackageEngine.Managers.Generic.NuGet/UniGetUI.PackageEngine.Managers.Generic.NuGet.csproj index 06896b0964..6236cb7e33 100644 --- a/src/UniGetUI.PackageEngine.Managers.Generic.NuGet/UniGetUI.PackageEngine.Managers.Generic.NuGet.csproj +++ b/src/UniGetUI.PackageEngine.Managers.Generic.NuGet/UniGetUI.PackageEngine.Managers.Generic.NuGet.csproj @@ -1,15 +1,18 @@ + + $(SharedTargetFrameworks) + - - - - + + + + - - - + + + - - - + + + diff --git a/src/UniGetUI.PackageEngine.Managers.Npm/Helpers/NpmPkgDetailsHelper.cs b/src/UniGetUI.PackageEngine.Managers.Npm/Helpers/NpmPkgDetailsHelper.cs index f21adf92e9..ff5aac9130 100644 --- a/src/UniGetUI.PackageEngine.Managers.Npm/Helpers/NpmPkgDetailsHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Npm/Helpers/NpmPkgDetailsHelper.cs @@ -12,31 +12,45 @@ namespace UniGetUI.PackageEngine.Managers.NpmManager { internal sealed class NpmPkgDetailsHelper : BasePkgDetailsHelper { - public NpmPkgDetailsHelper(Npm manager) : base(manager) { } + public NpmPkgDetailsHelper(Npm manager) + : base(manager) { } protected override void GetDetails_UnSafe(IPackageDetails details) { try { details.InstallerType = "Tarball"; - details.ManifestUrl = new Uri($"https://www.npmjs.com/package/{details.Package.Id}"); - details.ReleaseNotesUrl = new Uri($"https://www.npmjs.com/package/{details.Package.Id}?activeTab=versions"); + details.ManifestUrl = new Uri( + $"https://www.npmjs.com/package/{details.Package.Id}" + ); + details.ReleaseNotesUrl = new Uri( + $"https://www.npmjs.com/package/{details.Package.Id}?activeTab=versions" + ); using Process p = new(); p.StartInfo = new ProcessStartInfo { FileName = Manager.Status.ExecutablePath, - Arguments = Manager.Status.ExecutableCallArgs + " show " + details.Package.Id + " --json", + Arguments = + Manager.Status.ExecutableCallArgs + + " show " + + details.Package.Id + + " --json", UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, RedirectStandardInput = true, CreateNoWindow = true, - WorkingDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), - StandardOutputEncoding = System.Text.Encoding.UTF8 + WorkingDirectory = Environment.GetFolderPath( + Environment.SpecialFolder.UserProfile + ), + StandardOutputEncoding = System.Text.Encoding.UTF8, }; - IProcessTaskLogger logger = Manager.TaskLogger.CreateNew(LoggableTaskType.LoadPackageDetails, p); + IProcessTaskLogger logger = Manager.TaskLogger.CreateNew( + LoggableTaskType.LoadPackageDetails, + p + ); p.Start(); string strContents = p.StandardOutput.ReadToEnd(); @@ -46,17 +60,38 @@ protected override void GetDetails_UnSafe(IPackageDetails details) details.License = contents?["license"]?.ToString(); details.Description = contents?["description"]?.ToString(); - if (Uri.TryCreate(contents?["homepage"]?.ToString() ?? "", UriKind.RelativeOrAbsolute, out var homepageUrl)) + if ( + Uri.TryCreate( + contents?["homepage"]?.ToString() ?? "", + UriKind.RelativeOrAbsolute, + out var homepageUrl + ) + ) details.HomepageUrl = homepageUrl; details.Publisher = (contents?["maintainers"] as JsonArray)?[0]?.ToString(); details.Author = contents?["author"]?.ToString(); - details.UpdateDate = contents?["time"]?[contents?["dist-tags"]?["latest"]?.ToString() ?? details.Package.VersionString]?.ToString(); - - if (Uri.TryCreate(contents?["dist"]?["tarball"]?.ToString() ?? "", UriKind.RelativeOrAbsolute, out var installerUrl)) + details.UpdateDate = contents?["time"]?[ + contents?["dist-tags"]?["latest"]?.ToString() ?? details.Package.VersionString + ]?.ToString(); + + if ( + Uri.TryCreate( + contents?["dist"]?["tarball"]?.ToString() ?? "", + UriKind.RelativeOrAbsolute, + out var installerUrl + ) + ) details.InstallerUrl = installerUrl; - if (int.TryParse(contents?["dist"]?["unpackedSize"]?.ToString() ?? "", NumberStyles.Any, CultureInfo.InvariantCulture, out int installerSize)) + if ( + int.TryParse( + contents?["dist"]?["unpackedSize"]?.ToString() ?? "", + NumberStyles.Any, + CultureInfo.InvariantCulture, + out int installerSize + ) + ) details.InstallerSize = installerSize; details.InstallerHash = contents?["dist"]?["integrity"]?.ToString(); @@ -65,41 +100,50 @@ protected override void GetDetails_UnSafe(IPackageDetails details) HashSet addedDeps = new(); foreach (var rawDep in (contents?["dependencies"]?.AsObject() ?? [])) { - if(addedDeps.Contains(rawDep.Key)) continue; + if (addedDeps.Contains(rawDep.Key)) + continue; addedDeps.Add(rawDep.Key); - details.Dependencies.Add(new() - { - Name = rawDep.Key, - Version = rawDep.Value?.GetValue() ?? "", - Mandatory = true, - }); + details.Dependencies.Add( + new() + { + Name = rawDep.Key, + Version = rawDep.Value?.GetValue() ?? "", + Mandatory = true, + } + ); } foreach (var rawDep in (contents?["devDependencies"]?.AsObject() ?? [])) { - if(addedDeps.Contains(rawDep.Key)) continue; + if (addedDeps.Contains(rawDep.Key)) + continue; addedDeps.Add(rawDep.Key); - details.Dependencies.Add(new() - { - Name = rawDep.Key, - Version = rawDep.Value?.GetValue() ?? "", - Mandatory = false, - }); + details.Dependencies.Add( + new() + { + Name = rawDep.Key, + Version = rawDep.Value?.GetValue() ?? "", + Mandatory = false, + } + ); } foreach (var rawDep in (contents?["peerDependencies"]?.AsObject() ?? [])) { - if(addedDeps.Contains(rawDep.Key)) continue; + if (addedDeps.Contains(rawDep.Key)) + continue; addedDeps.Add(rawDep.Key); - details.Dependencies.Add(new() - { - Name = rawDep.Key, - Version = rawDep.Value?.GetValue() ?? "", - Mandatory = false, - }); + details.Dependencies.Add( + new() + { + Name = rawDep.Key, + Version = rawDep.Value?.GetValue() ?? "", + Mandatory = false, + } + ); } logger.AddToStdErr(p.StandardError.ReadToEnd()); @@ -127,9 +171,18 @@ protected override IReadOnlyList GetScreenshots_UnSafe(IPackage package) protected override string? GetInstallLocation_UnSafe(IPackage package) { if (package.OverridenOptions.Scope is PackageScope.Local) - return Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "node_modules", package.Id); - return Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Roaming", "npm", - "node_modules", package.Id); + return Path.Join( + Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), + "node_modules", + package.Id + ); + return Path.Join( + Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), + "Roaming", + "npm", + "node_modules", + package.Id + ); } protected override IReadOnlyList GetInstallableVersions_UnSafe(IPackage package) @@ -140,18 +193,26 @@ protected override IReadOnlyList GetInstallableVersions_UnSafe(IPackage { FileName = Manager.Status.ExecutablePath, Arguments = - Manager.Status.ExecutableCallArgs + " show " + package.Id + " versions --json", + Manager.Status.ExecutableCallArgs + + " show " + + package.Id + + " versions --json", UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, RedirectStandardInput = true, CreateNoWindow = true, - WorkingDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), - StandardOutputEncoding = System.Text.Encoding.UTF8 - } + WorkingDirectory = Environment.GetFolderPath( + Environment.SpecialFolder.UserProfile + ), + StandardOutputEncoding = System.Text.Encoding.UTF8, + }, }; - IProcessTaskLogger logger = Manager.TaskLogger.CreateNew(LoggableTaskType.LoadPackageVersions, p); + IProcessTaskLogger logger = Manager.TaskLogger.CreateNew( + LoggableTaskType.LoadPackageVersions, + p + ); p.Start(); string strContents = p.StandardOutput.ReadToEnd(); @@ -159,7 +220,7 @@ protected override IReadOnlyList GetInstallableVersions_UnSafe(IPackage JsonArray? rawVersions = JsonNode.Parse(strContents) as JsonArray; List versions = []; - foreach(JsonNode? raw_ver in rawVersions ?? []) + foreach (JsonNode? raw_ver in rawVersions ?? []) { if (raw_ver is not null) versions.Add(raw_ver.ToString()); diff --git a/src/UniGetUI.PackageEngine.Managers.Npm/Helpers/NpmPkgOperationHelper.cs b/src/UniGetUI.PackageEngine.Managers.Npm/Helpers/NpmPkgOperationHelper.cs index dbe1d18a29..128df82c49 100644 --- a/src/UniGetUI.PackageEngine.Managers.Npm/Helpers/NpmPkgOperationHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Npm/Helpers/NpmPkgOperationHelper.cs @@ -4,33 +4,54 @@ using UniGetUI.PackageEngine.Serializable; namespace UniGetUI.PackageEngine.Managers.NpmManager; + internal sealed class NpmPkgOperationHelper : BasePkgOperationHelper { - public NpmPkgOperationHelper(Npm manager) : base(manager) { } + public NpmPkgOperationHelper(Npm manager) + : base(manager) { } - protected override IReadOnlyList _getOperationParameters(IPackage package, - InstallOptions options, OperationType operation) + protected override IReadOnlyList _getOperationParameters( + IPackage package, + InstallOptions options, + OperationType operation + ) { - List parameters = operation switch { - OperationType.Install => [Manager.Properties.InstallVerb, $"'{package.Id}@{(options.Version == string.Empty? package.VersionString: options.Version)}'"], - OperationType.Update => [Manager.Properties.UpdateVerb, $"'{package.Id}@{package.NewVersionString}'"], + List parameters = operation switch + { + OperationType.Install => + [ + Manager.Properties.InstallVerb, + $"'{package.Id}@{(options.Version == string.Empty ? package.VersionString : options.Version)}'", + ], + OperationType.Update => + [ + Manager.Properties.UpdateVerb, + $"'{package.Id}@{package.NewVersionString}'", + ], OperationType.Uninstall => [Manager.Properties.UninstallVerb, package.Id], - _ => throw new InvalidDataException("Invalid package operation") + _ => throw new InvalidDataException("Invalid package operation"), }; - if (package.OverridenOptions.Scope == PackageScope.Global || - (package.OverridenOptions.Scope is null && options.InstallationScope == PackageScope.Global)) + if ( + package.OverridenOptions.Scope == PackageScope.Global + || ( + package.OverridenOptions.Scope is null + && options.InstallationScope == PackageScope.Global + ) + ) parameters.Add("--global"); if (options.PreRelease) parameters.AddRange(["--include", "dev"]); - parameters.AddRange(operation switch - { - OperationType.Update => options.CustomParameters_Update, - OperationType.Uninstall => options.CustomParameters_Uninstall, - _ => options.CustomParameters_Install, - }); + parameters.AddRange( + operation switch + { + OperationType.Update => options.CustomParameters_Update, + OperationType.Uninstall => options.CustomParameters_Uninstall, + _ => options.CustomParameters_Install, + } + ); return parameters; } @@ -39,7 +60,8 @@ protected override OperationVeredict _getOperationResult( IPackage package, OperationType operation, IReadOnlyList processOutput, - int returnCode) + int returnCode + ) { return returnCode == 0 ? OperationVeredict.Success : OperationVeredict.Failure; } diff --git a/src/UniGetUI.PackageEngine.Managers.Npm/Npm.cs b/src/UniGetUI.PackageEngine.Managers.Npm/Npm.cs index 2e4906aa12..d7dec004e9 100644 --- a/src/UniGetUI.PackageEngine.Managers.Npm/Npm.cs +++ b/src/UniGetUI.PackageEngine.Managers.Npm/Npm.cs @@ -26,13 +26,15 @@ public Npm() CanListDependencies = true, SupportsPreRelease = true, SupportsProxy = ProxySupport.No, - SupportsProxyAuth = false + SupportsProxyAuth = false, }; Properties = new ManagerProperties { Name = "Npm", - Description = CoreTools.Translate("Node JS's package manager. Full of libraries and other utilities that orbit the javascript world
Contains: Node javascript libraries and other related utilities"), + Description = CoreTools.Translate( + "Node JS's package manager. Full of libraries and other utilities that orbit the javascript world
Contains: Node javascript libraries and other related utilities" + ), IconId = IconType.Node, ColorIconId = "node_color", ExecutableFriendlyName = "npm", @@ -41,7 +43,6 @@ public Npm() UpdateVerb = "install", DefaultSource = new ManagerSource(this, "npm", new Uri("https://www.npmjs.com/")), KnownSources = [new ManagerSource(this, "npm", new Uri("https://www.npmjs.com/"))], - }; DetailsHelper = new NpmPkgDetailsHelper(this); @@ -61,9 +62,11 @@ protected override IReadOnlyList FindPackages_UnSafe(string query) RedirectStandardInput = true, UseShellExecute = false, CreateNoWindow = true, - WorkingDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), - StandardOutputEncoding = System.Text.Encoding.UTF8 - } + WorkingDirectory = Environment.GetFolderPath( + Environment.SpecialFolder.UserProfile + ), + StandardOutputEncoding = System.Text.Encoding.UTF8, + }, }; IProcessTaskLogger logger = TaskLogger.CreateNew(LoggableTaskType.FindPackages, p); @@ -81,7 +84,15 @@ protected override IReadOnlyList FindPackages_UnSafe(string query) string? version = node?["version"]?.ToString(); if (id is not null && version is not null) { - Packages.Add(new Package(CoreTools.FormatAsName(id), id, version, DefaultSource, this)); + Packages.Add( + new Package( + CoreTools.FormatAsName(id), + id, + version, + DefaultSource, + this + ) + ); } else { @@ -100,22 +111,33 @@ protected override IReadOnlyList FindPackages_UnSafe(string query) protected override IReadOnlyList GetAvailableUpdates_UnSafe() { List Packages = []; - foreach (var options in new OverridenInstallationOptions[] { new(PackageScope.Local), new(PackageScope.Global) }) + foreach ( + var options in new OverridenInstallationOptions[] + { + new(PackageScope.Local), + new(PackageScope.Global), + } + ) { using Process p = new() { StartInfo = new ProcessStartInfo { FileName = Status.ExecutablePath, - Arguments = Status.ExecutableCallArgs + " outdated --json" + (options.Scope == PackageScope.Global ? " --global" : ""), + Arguments = + Status.ExecutableCallArgs + + " outdated --json" + + (options.Scope == PackageScope.Global ? " --global" : ""), RedirectStandardOutput = true, RedirectStandardError = true, RedirectStandardInput = true, UseShellExecute = false, CreateNoWindow = true, - WorkingDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), - StandardOutputEncoding = System.Text.Encoding.UTF8 - } + WorkingDirectory = Environment.GetFolderPath( + Environment.SpecialFolder.UserProfile + ), + StandardOutputEncoding = System.Text.Encoding.UTF8, + }, }; IProcessTaskLogger logger = TaskLogger.CreateNew(LoggableTaskType.ListUpdates, p); @@ -124,15 +146,25 @@ protected override IReadOnlyList GetAvailableUpdates_UnSafe() string strContents = p.StandardOutput.ReadToEnd(); logger.AddToStdOut(strContents); JsonObject? contents = null; - if (strContents.Any()) contents = JsonNode.Parse(strContents) as JsonObject; + if (strContents.Any()) + contents = JsonNode.Parse(strContents) as JsonObject; foreach (var (packageId, packageData) in contents?.ToDictionary() ?? []) { string? version = packageData?["current"]?.ToString(); string? newVersion = packageData?["latest"]?.ToString(); if (version is not null && newVersion is not null) { - Packages.Add(new Package(CoreTools.FormatAsName(packageId), packageId, version, newVersion, - DefaultSource, this, options)); + Packages.Add( + new Package( + CoreTools.FormatAsName(packageId), + packageId, + version, + newVersion, + DefaultSource, + this, + options + ) + ); } } @@ -146,37 +178,62 @@ protected override IReadOnlyList GetAvailableUpdates_UnSafe() protected override IReadOnlyList GetInstalledPackages_UnSafe() { List Packages = []; - foreach (var options in new OverridenInstallationOptions[] { new(PackageScope.Local), new(PackageScope.Global) }) + foreach ( + var options in new OverridenInstallationOptions[] + { + new(PackageScope.Local), + new(PackageScope.Global), + } + ) { using Process p = new() { StartInfo = new ProcessStartInfo { FileName = Status.ExecutablePath, - Arguments = Status.ExecutableCallArgs + " list --json" + (options.Scope == PackageScope.Global ? " --global" : ""), + Arguments = + Status.ExecutableCallArgs + + " list --json" + + (options.Scope == PackageScope.Global ? " --global" : ""), RedirectStandardOutput = true, RedirectStandardError = true, RedirectStandardInput = true, UseShellExecute = false, CreateNoWindow = true, - WorkingDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), - StandardOutputEncoding = System.Text.Encoding.UTF8 - } + WorkingDirectory = Environment.GetFolderPath( + Environment.SpecialFolder.UserProfile + ), + StandardOutputEncoding = System.Text.Encoding.UTF8, + }, }; - IProcessTaskLogger logger = TaskLogger.CreateNew(LoggableTaskType.ListInstalledPackages, p); + IProcessTaskLogger logger = TaskLogger.CreateNew( + LoggableTaskType.ListInstalledPackages, + p + ); p.Start(); string strContents = p.StandardOutput.ReadToEnd(); logger.AddToStdOut(strContents); JsonObject? contents = null; - if (strContents.Any()) contents = (JsonNode.Parse(strContents) as JsonObject)?["dependencies"] as JsonObject; + if (strContents.Any()) + contents = + (JsonNode.Parse(strContents) as JsonObject)?["dependencies"] as JsonObject; foreach (var (packageId, packageData) in contents?.ToDictionary() ?? []) { string? version = packageData?["version"]?.ToString(); if (version is not null) { - Packages.Add(new Package(CoreTools.FormatAsName(packageId), packageId, version, DefaultSource, this, options)); + Packages.Add( + new Package( + CoreTools.FormatAsName(packageId), + packageId, + version, + DefaultSource, + this, + options + ) + ); } } @@ -188,16 +245,21 @@ protected override IReadOnlyList GetInstalledPackages_UnSafe() return Packages; } - public override IReadOnlyList FindCandidateExecutableFiles() - => CoreTools.WhichMultiple("npm.cmd"); + public override IReadOnlyList FindCandidateExecutableFiles() => + CoreTools.WhichMultiple("npm.cmd"); - protected override void _loadManagerExecutableFile(out bool found, out string path, out string callArguments) + protected override void _loadManagerExecutableFile( + out bool found, + out string path, + out string callArguments + ) { var (_found, _executable) = GetExecutableFile(); found = _found; path = CoreData.PowerShell5; - callArguments = $"-NoProfile -ExecutionPolicy Bypass -Command \"{_executable.Replace(" ", "` ")}\" "; + callArguments = + $"-NoProfile -ExecutionPolicy Bypass -Command \"{_executable.Replace(" ", "` ")}\" "; } protected override void _loadManagerVersion(out string version) @@ -213,9 +275,11 @@ protected override void _loadManagerVersion(out string version) RedirectStandardError = true, RedirectStandardInput = true, CreateNoWindow = true, - WorkingDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), - StandardOutputEncoding = System.Text.Encoding.UTF8 - } + WorkingDirectory = Environment.GetFolderPath( + Environment.SpecialFolder.UserProfile + ), + StandardOutputEncoding = System.Text.Encoding.UTF8, + }, }; process.Start(); version = process.StandardOutput.ReadToEnd().Trim(); diff --git a/src/UniGetUI.PackageEngine.Managers.Npm/UniGetUI.PackageEngine.Managers.Npm.csproj b/src/UniGetUI.PackageEngine.Managers.Npm/UniGetUI.PackageEngine.Managers.Npm.csproj index 601ac03e65..5590ef43a4 100644 --- a/src/UniGetUI.PackageEngine.Managers.Npm/UniGetUI.PackageEngine.Managers.Npm.csproj +++ b/src/UniGetUI.PackageEngine.Managers.Npm/UniGetUI.PackageEngine.Managers.Npm.csproj @@ -1,24 +1,27 @@ + + $(SharedTargetFrameworks) + - - - - - - - - - - - - - + + + + + + + + + + + + + - - - + + + - - - + + + diff --git a/src/UniGetUI.PackageEngine.Managers.Pip/Helpers/PipPkgDetailsHelper.cs b/src/UniGetUI.PackageEngine.Managers.Pip/Helpers/PipPkgDetailsHelper.cs index 3748500f85..fa8dd9da06 100644 --- a/src/UniGetUI.PackageEngine.Managers.Pip/Helpers/PipPkgDetailsHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Pip/Helpers/PipPkgDetailsHelper.cs @@ -12,16 +12,22 @@ namespace UniGetUI.PackageEngine.Managers.PipManager { internal sealed class PipPkgDetailsHelper : BasePkgDetailsHelper { - public PipPkgDetailsHelper(Pip manager) : base(manager) { } + public PipPkgDetailsHelper(Pip manager) + : base(manager) { } protected override void GetDetails_UnSafe(IPackageDetails details) { - INativeTaskLogger logger = Manager.TaskLogger.CreateNew(LoggableTaskType.LoadPackageDetails); + INativeTaskLogger logger = Manager.TaskLogger.CreateNew( + LoggableTaskType.LoadPackageDetails + ); string JsonString; HttpClient client = new(CoreTools.GenericHttpClientParameters); client.DefaultRequestHeaders.UserAgent.ParseAdd(CoreData.UserAgentString); - JsonString = client.GetStringAsync($"https://pypi.org/pypi/{details.Package.Id}/json").GetAwaiter().GetResult(); + JsonString = client + .GetStringAsync($"https://pypi.org/pypi/{details.Package.Id}/json") + .GetAwaiter() + .GetResult(); JsonObject? contents = JsonNode.Parse(JsonString) as JsonObject; @@ -32,10 +38,22 @@ protected override void GetDetails_UnSafe(IPackageDetails details) details.Publisher = info["maintainer"]?.ToString(); details.License = info["license"]?.ToString(); - if (Uri.TryCreate(info["home_page"]?.ToString(), UriKind.RelativeOrAbsolute, out var homepageUrl)) + if ( + Uri.TryCreate( + info["home_page"]?.ToString(), + UriKind.RelativeOrAbsolute, + out var homepageUrl + ) + ) details.HomepageUrl = homepageUrl; - if (Uri.TryCreate(info["package_url"]?.ToString(), UriKind.RelativeOrAbsolute, out var packageUrl)) + if ( + Uri.TryCreate( + info["package_url"]?.ToString(), + UriKind.RelativeOrAbsolute, + out var packageUrl + ) + ) details.ManifestUrl = packageUrl; if (info["classifiers"] is JsonArray classifiers) @@ -61,12 +79,14 @@ protected override void GetDetails_UnSafe(IPackageDetails details) { string line = rawDep?.GetValue().Split(';')[0] ?? ""; string name = line.Split(['>', '<', '=', '!'])[0]; - details.Dependencies.Add(new() - { - Name = name, - Version = line[name.Length..], - Mandatory = true, - }); + details.Dependencies.Add( + new() + { + Name = name, + Version = line[name.Length..], + Mandatory = true, + } + ); } } @@ -78,9 +98,18 @@ protected override void GetDetails_UnSafe(IPackageDetails details) if (url["digests"] is JsonObject digests) details.InstallerHash = digests["sha256"]?.ToString(); - if (Uri.TryCreate(url["url"]?.ToString(), UriKind.RelativeOrAbsolute, out var installerUrl)) + if ( + Uri.TryCreate( + url["url"]?.ToString(), + UriKind.RelativeOrAbsolute, + out var installerUrl + ) + ) { - details.InstallerType = url["url"]?.ToString().Split('.')[^1].Replace("whl", "Wheel"); + details.InstallerType = url["url"] + ?.ToString() + .Split('.')[^1] + .Replace("whl", "Wheel"); details.InstallerUrl = installerUrl; details.InstallerSize = CoreTools.GetFileSizeAsLong(installerUrl); } @@ -103,7 +132,12 @@ protected override IReadOnlyList GetScreenshots_UnSafe(IPackage package) protected override string? GetInstallLocation_UnSafe(IPackage package) { - var full_path = Path.Join(Path.GetDirectoryName(Manager.Status.ExecutablePath), "Lib", "site-packages", package.Id); + var full_path = Path.Join( + Path.GetDirectoryName(Manager.Status.ExecutablePath), + "Lib", + "site-packages", + package.Id + ); return Directory.Exists(full_path) ? full_path : Path.GetDirectoryName(full_path); } @@ -114,17 +148,25 @@ protected override IReadOnlyList GetInstallableVersions_UnSafe(IPackage StartInfo = new ProcessStartInfo { FileName = Manager.Status.ExecutablePath, - Arguments = Manager.Status.ExecutableCallArgs + " index versions " + package.Id + " " + Pip.GetProxyArgument(), + Arguments = + Manager.Status.ExecutableCallArgs + + " index versions " + + package.Id + + " " + + Pip.GetProxyArgument(), RedirectStandardOutput = true, RedirectStandardInput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true, - StandardOutputEncoding = System.Text.Encoding.UTF8 - } + StandardOutputEncoding = System.Text.Encoding.UTF8, + }, }; - IProcessTaskLogger logger = Manager.TaskLogger.CreateNew(LoggableTaskType.LoadPackageVersions, p); + IProcessTaskLogger logger = Manager.TaskLogger.CreateNew( + LoggableTaskType.LoadPackageVersions, + p + ); p.Start(); string? line; diff --git a/src/UniGetUI.PackageEngine.Managers.Pip/Helpers/PipPkgOperationHelper.cs b/src/UniGetUI.PackageEngine.Managers.Pip/Helpers/PipPkgOperationHelper.cs index 5513e52fac..9aa674177f 100644 --- a/src/UniGetUI.PackageEngine.Managers.Pip/Helpers/PipPkgOperationHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Pip/Helpers/PipPkgOperationHelper.cs @@ -4,25 +4,33 @@ using UniGetUI.PackageEngine.Serializable; namespace UniGetUI.PackageEngine.Managers.PipManager; + internal sealed class PipPkgOperationHelper : BasePkgOperationHelper { - public PipPkgOperationHelper(Pip manager) : base(manager) { } + public PipPkgOperationHelper(Pip manager) + : base(manager) { } - protected override IReadOnlyList _getOperationParameters(IPackage package, + protected override IReadOnlyList _getOperationParameters( + IPackage package, InstallOptions options, - OperationType operation) + OperationType operation + ) { - List parameters = [operation switch { - OperationType.Install => Manager.Properties.InstallVerb, - OperationType.Update => Manager.Properties.UpdateVerb, - OperationType.Uninstall => Manager.Properties.UninstallVerb, - _ => throw new InvalidDataException("Invalid package operation") - }]; + List parameters = + [ + operation switch + { + OperationType.Install => Manager.Properties.InstallVerb, + OperationType.Update => Manager.Properties.UpdateVerb, + OperationType.Uninstall => Manager.Properties.UninstallVerb, + _ => throw new InvalidDataException("Invalid package operation"), + }, + ]; parameters.AddRange([ - options.Version.Any()? $"{package.Id}=={options.Version}" : package.Id, + options.Version.Any() ? $"{package.Id}=={options.Version}" : package.Id, "--no-input", "--no-color", - "--no-cache" + "--no-cache", ]); if (operation is OperationType.Uninstall) @@ -34,19 +42,26 @@ protected override IReadOnlyList _getOperationParameters(IPackage packag if (options.PreRelease) parameters.Add("--pre"); - if (package.OverridenOptions.Scope == PackageScope.User || - (package.OverridenOptions.Scope is null && options.InstallationScope == PackageScope.User)) + if ( + package.OverridenOptions.Scope == PackageScope.User + || ( + package.OverridenOptions.Scope is null + && options.InstallationScope == PackageScope.User + ) + ) parameters.Add("--user"); } parameters.Add(Pip.GetProxyArgument()); - parameters.AddRange(operation switch - { - OperationType.Update => options.CustomParameters_Update, - OperationType.Uninstall => options.CustomParameters_Uninstall, - _ => options.CustomParameters_Install, - }); + parameters.AddRange( + operation switch + { + OperationType.Update => options.CustomParameters_Update, + OperationType.Uninstall => options.CustomParameters_Uninstall, + _ => options.CustomParameters_Install, + } + ); return parameters; } @@ -55,7 +70,8 @@ protected override OperationVeredict _getOperationResult( IPackage package, OperationType operation, IReadOnlyList processOutput, - int returnCode) + int returnCode + ) { if (returnCode == 0) { @@ -70,6 +86,5 @@ protected override OperationVeredict _getOperationResult( return OperationVeredict.AutoRetry; } return OperationVeredict.Failure; - } } diff --git a/src/UniGetUI.PackageEngine.Managers.Pip/Pip.cs b/src/UniGetUI.PackageEngine.Managers.Pip/Pip.cs index b7f5e4a64f..d16dcb3ecd 100644 --- a/src/UniGetUI.PackageEngine.Managers.Pip/Pip.cs +++ b/src/UniGetUI.PackageEngine.Managers.Pip/Pip.cs @@ -14,7 +14,14 @@ namespace UniGetUI.PackageEngine.Managers.PipManager { public class Pip : PackageManager { - public static string[] FALSE_PACKAGE_IDS = ["", "WARNING:", "[notice]", "Package", "DEPRECATION:"]; + public static string[] FALSE_PACKAGE_IDS = + [ + "", + "WARNING:", + "[notice]", + "Package", + "DEPRECATION:", + ]; public static string[] FALSE_PACKAGE_VERSIONS = ["", "Ignoring", "invalid"]; public Pip() @@ -52,15 +59,15 @@ public Pip() SupportsPreRelease = true, CanListDependencies = true, SupportsProxy = ProxySupport.Yes, - SupportsProxyAuth = true + SupportsProxyAuth = true, }; Properties = new ManagerProperties { Name = "Pip", - Description = - CoreTools.Translate( - "Python's library manager. Full of python libraries and other python-related utilities
Contains: Python libraries and related utilities"), + Description = CoreTools.Translate( + "Python's library manager. Full of python libraries and other python-related utilities
Contains: Python libraries and related utilities" + ), IconId = IconType.Python, ColorIconId = "pip_color", ExecutableFriendlyName = "pip", @@ -69,7 +76,6 @@ public Pip() UpdateVerb = "install --upgrade", DefaultSource = new ManagerSource(this, "pip", new Uri("https://pypi.org/")), KnownSources = [new ManagerSource(this, "pip", new Uri("https://pypi.org/"))], - }; DetailsHelper = new PipPkgDetailsHelper(this); @@ -78,9 +84,11 @@ public Pip() public static string GetProxyArgument() { - if (!Settings.Get(Settings.K.EnableProxy)) return ""; + if (!Settings.Get(Settings.K.EnableProxy)) + return ""; var proxyUri = Settings.GetProxyUrl(); - if (proxyUri is null) return ""; + if (proxyUri is null) + return ""; if (Settings.Get(Settings.K.EnableProxyAuth) is false) return $"--proxy {proxyUri.ToString()}"; @@ -89,9 +97,8 @@ public static string GetProxyArgument() if (creds is null) return $"--proxy {proxyUri.ToString()}"; - return - $"--proxy {proxyUri.Scheme}://{Uri.EscapeDataString(creds.UserName)}:{Uri.EscapeDataString(creds.Password)}" + - $"@{proxyUri.AbsoluteUri.Replace($"{proxyUri.Scheme}://", "")}"; + return $"--proxy {proxyUri.Scheme}://{Uri.EscapeDataString(creds.UserName)}:{Uri.EscapeDataString(creds.Password)}" + + $"@{proxyUri.AbsoluteUri.Replace($"{proxyUri.Scheme}://", "")}"; } protected override IReadOnlyList FindPackages_UnSafe(string query) @@ -106,14 +113,20 @@ protected override IReadOnlyList FindPackages_UnSafe(string query) StartInfo = new ProcessStartInfo { FileName = Status.ExecutablePath, - Arguments = Status.ExecutableCallArgs + " install parse_pip_search " + GetProxyArgument(), + Arguments = + Status.ExecutableCallArgs + + " install parse_pip_search " + + GetProxyArgument(), UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true, - } + }, }; - IProcessTaskLogger aux_logger = TaskLogger.CreateNew(LoggableTaskType.InstallManagerDependency, proc); + IProcessTaskLogger aux_logger = TaskLogger.CreateNew( + LoggableTaskType.InstallManagerDependency, + proc + ); proc.Start(); aux_logger.AddToStdOut(proc.StandardOutput.ReadToEnd()); @@ -134,8 +147,8 @@ protected override IReadOnlyList FindPackages_UnSafe(string query) RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true, - StandardOutputEncoding = System.Text.Encoding.UTF8 - } + StandardOutputEncoding = System.Text.Encoding.UTF8, + }, }; p.StartInfo = CoreTools.UpdateEnvironmentVariables(p.StartInfo); @@ -167,13 +180,24 @@ protected override IReadOnlyList FindPackages_UnSafe(string query) elements[i] = elements[i].Trim(); } - if (FALSE_PACKAGE_IDS.Contains(elements[0]) || FALSE_PACKAGE_VERSIONS.Contains(elements[1])) + if ( + FALSE_PACKAGE_IDS.Contains(elements[0]) + || FALSE_PACKAGE_VERSIONS.Contains(elements[1]) + ) { continue; } - Packages.Add(new Package(CoreTools.FormatAsName(elements[0]), elements[0], elements[1], - DefaultSource, this, new(PackageScope.Global))); + Packages.Add( + new Package( + CoreTools.FormatAsName(elements[0]), + elements[0], + elements[1], + DefaultSource, + this, + new(PackageScope.Global) + ) + ); } } @@ -191,13 +215,14 @@ protected override IReadOnlyList GetAvailableUpdates_UnSafe() StartInfo = new ProcessStartInfo { FileName = Status.ExecutablePath, - Arguments = Status.ExecutableCallArgs + " list --outdated " + GetProxyArgument(), + Arguments = + Status.ExecutableCallArgs + " list --outdated " + GetProxyArgument(), RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true, - StandardOutputEncoding = System.Text.Encoding.UTF8 - } + StandardOutputEncoding = System.Text.Encoding.UTF8, + }, }; IProcessTaskLogger logger = TaskLogger.CreateNew(LoggableTaskType.ListUpdates, p); @@ -230,13 +255,25 @@ protected override IReadOnlyList GetAvailableUpdates_UnSafe() elements[i] = elements[i].Trim(); } - if (FALSE_PACKAGE_IDS.Contains(elements[0]) || FALSE_PACKAGE_VERSIONS.Contains(elements[1])) + if ( + FALSE_PACKAGE_IDS.Contains(elements[0]) + || FALSE_PACKAGE_VERSIONS.Contains(elements[1]) + ) { continue; } - Packages.Add(new Package(CoreTools.FormatAsName(elements[0]), elements[0], elements[1], elements[2], - DefaultSource, this, new(PackageScope.Global))); + Packages.Add( + new Package( + CoreTools.FormatAsName(elements[0]), + elements[0], + elements[1], + elements[2], + DefaultSource, + this, + new(PackageScope.Global) + ) + ); } } @@ -249,7 +286,6 @@ protected override IReadOnlyList GetAvailableUpdates_UnSafe() protected override IReadOnlyList GetInstalledPackages_UnSafe() { - using Process p = new() { StartInfo = new ProcessStartInfo @@ -260,11 +296,14 @@ protected override IReadOnlyList GetInstalledPackages_UnSafe() RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true, - StandardOutputEncoding = System.Text.Encoding.UTF8 - } + StandardOutputEncoding = System.Text.Encoding.UTF8, + }, }; - IProcessTaskLogger logger = TaskLogger.CreateNew(LoggableTaskType.ListInstalledPackages, p); + IProcessTaskLogger logger = TaskLogger.CreateNew( + LoggableTaskType.ListInstalledPackages, + p + ); p.Start(); @@ -294,13 +333,24 @@ protected override IReadOnlyList GetInstalledPackages_UnSafe() elements[i] = elements[i].Trim(); } - if (FALSE_PACKAGE_IDS.Contains(elements[0]) || FALSE_PACKAGE_VERSIONS.Contains(elements[1])) + if ( + FALSE_PACKAGE_IDS.Contains(elements[0]) + || FALSE_PACKAGE_VERSIONS.Contains(elements[1]) + ) { continue; } - Packages.Add(new Package(CoreTools.FormatAsName(elements[0]), elements[0], elements[1], - DefaultSource, this, new(PackageScope.Global))); + Packages.Add( + new Package( + CoreTools.FormatAsName(elements[0]), + elements[0], + elements[1], + DefaultSource, + this, + new(PackageScope.Global) + ) + ); } } @@ -330,8 +380,10 @@ public override IReadOnlyList FindCandidateExecutableFiles() if (AppData != null) UserPythonInstallDir = Path.Combine(AppData, "Programs", "Python"); - if (Directory.Exists(ProgramFiles)) DirsToSearch.Add(ProgramFiles); - if (Directory.Exists(UserPythonInstallDir)) DirsToSearch.Add(UserPythonInstallDir); + if (Directory.Exists(ProgramFiles)) + DirsToSearch.Add(ProgramFiles); + if (Directory.Exists(UserPythonInstallDir)) + DirsToSearch.Add(UserPythonInstallDir); foreach (var Dir in DirsToSearch) { @@ -341,14 +393,16 @@ public override IReadOnlyList FindCandidateExecutableFiles() Paths.Add(PythonPath); } } - catch (Exception) - { - } + catch (Exception) { } return Paths; } - protected override void _loadManagerExecutableFile(out bool found, out string path, out string callArguments) + protected override void _loadManagerExecutableFile( + out bool found, + out string path, + out string callArguments + ) { var (_found, _path) = GetExecutableFile(); found = _found; @@ -368,22 +422,27 @@ protected override void _loadManagerVersion(out string version) RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true, - StandardOutputEncoding = System.Text.Encoding.UTF8 - } + StandardOutputEncoding = System.Text.Encoding.UTF8, + }, }; process.Start(); version = process.StandardOutput.ReadToEnd().Trim(); if (process.ExitCode is 9009) { - throw new InvalidOperationException("Microsoft Store python alias is not a valid python install"); + throw new InvalidOperationException( + "Microsoft Store python alias is not a valid python install" + ); } } protected override void _performExtraLoadingSteps() { - Environment.SetEnvironmentVariable("PIP_REQUIRE_VIRTUALENV", "false", EnvironmentVariableTarget.Process); + Environment.SetEnvironmentVariable( + "PIP_REQUIRE_VIRTUALENV", + "false", + EnvironmentVariableTarget.Process + ); } } } - diff --git a/src/UniGetUI.PackageEngine.Managers.Pip/UniGetUI.PackageEngine.Managers.Pip.csproj b/src/UniGetUI.PackageEngine.Managers.Pip/UniGetUI.PackageEngine.Managers.Pip.csproj index 601ac03e65..5590ef43a4 100644 --- a/src/UniGetUI.PackageEngine.Managers.Pip/UniGetUI.PackageEngine.Managers.Pip.csproj +++ b/src/UniGetUI.PackageEngine.Managers.Pip/UniGetUI.PackageEngine.Managers.Pip.csproj @@ -1,24 +1,27 @@ + + $(SharedTargetFrameworks) + - - - - - - - - - - - - - + + + + + + + + + + + + + - - - + + + - - - + + + diff --git a/src/UniGetUI.PackageEngine.Managers.PowerShell/Helpers/PowerShellDetailsHelper.cs b/src/UniGetUI.PackageEngine.Managers.PowerShell/Helpers/PowerShellDetailsHelper.cs index 2543d96d6f..12604356ab 100644 --- a/src/UniGetUI.PackageEngine.Managers.PowerShell/Helpers/PowerShellDetailsHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.PowerShell/Helpers/PowerShellDetailsHelper.cs @@ -5,18 +5,28 @@ namespace UniGetUI.PackageEngine.Managers.Chocolatey { public class PowerShellDetailsHelper : BaseNuGetDetailsHelper { - public PowerShellDetailsHelper(BaseNuGet manager) : base(manager) - { } + public PowerShellDetailsHelper(BaseNuGet manager) + : base(manager) { } protected override string? GetInstallLocation_UnSafe(IPackage package) { - var user_path = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), - "WindowsPowerShell", "Modules", package.Id); - if (Directory.Exists(user_path)) return user_path; + var user_path = Path.Join( + Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), + "WindowsPowerShell", + "Modules", + package.Id + ); + if (Directory.Exists(user_path)) + return user_path; - var system_path = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), - "WindowsPowerShell", "Modules", package.Id); - if (Directory.Exists(system_path)) return system_path; + var system_path = Path.Join( + Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), + "WindowsPowerShell", + "Modules", + package.Id + ); + if (Directory.Exists(system_path)) + return system_path; return null; } diff --git a/src/UniGetUI.PackageEngine.Managers.PowerShell/Helpers/PowerShellPkgOperationHelper.cs b/src/UniGetUI.PackageEngine.Managers.PowerShell/Helpers/PowerShellPkgOperationHelper.cs index 73c5e0feb7..c6708b113a 100644 --- a/src/UniGetUI.PackageEngine.Managers.PowerShell/Helpers/PowerShellPkgOperationHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.PowerShell/Helpers/PowerShellPkgOperationHelper.cs @@ -4,19 +4,28 @@ using UniGetUI.PackageEngine.Serializable; namespace UniGetUI.PackageEngine.Managers.PowerShellManager; + internal sealed class PowerShellPkgOperationHelper : BasePkgOperationHelper { - public PowerShellPkgOperationHelper(PowerShell manager) : base(manager) { } + public PowerShellPkgOperationHelper(PowerShell manager) + : base(manager) { } - protected override IReadOnlyList _getOperationParameters(IPackage package, - InstallOptions options, OperationType operation) + protected override IReadOnlyList _getOperationParameters( + IPackage package, + InstallOptions options, + OperationType operation + ) { - List parameters = [operation switch { - OperationType.Install => Manager.Properties.InstallVerb, - OperationType.Update => Manager.Properties.UpdateVerb, - OperationType.Uninstall => Manager.Properties.UninstallVerb, - _ => throw new InvalidDataException("Invalid package operation") - }]; + List parameters = + [ + operation switch + { + OperationType.Install => Manager.Properties.InstallVerb, + OperationType.Update => Manager.Properties.UpdateVerb, + OperationType.Uninstall => Manager.Properties.UninstallVerb, + _ => throw new InvalidDataException("Invalid package operation"), + }, + ]; parameters.AddRange(["-Name", package.Id, "-Confirm:$false", "-Force"]); if (operation is not OperationType.Uninstall) @@ -26,8 +35,13 @@ protected override IReadOnlyList _getOperationParameters(IPackage packag if (!package.OverridenOptions.PowerShell_DoNotSetScopeParameter) { - if (package.OverridenOptions.Scope == PackageScope.Global || - (package.OverridenOptions.Scope is null && options.InstallationScope == PackageScope.Global)) + if ( + package.OverridenOptions.Scope == PackageScope.Global + || ( + package.OverridenOptions.Scope is null + && options.InstallationScope == PackageScope.Global + ) + ) parameters.AddRange(["-Scope", "AllUsers"]); else parameters.AddRange(["-Scope", "CurrentUser"]); @@ -43,12 +57,14 @@ protected override IReadOnlyList _getOperationParameters(IPackage packag parameters.AddRange(["-RequiredVersion", options.Version]); } - parameters.AddRange(operation switch - { - OperationType.Update => options.CustomParameters_Update, - OperationType.Uninstall => options.CustomParameters_Uninstall, - _ => options.CustomParameters_Install, - }); + parameters.AddRange( + operation switch + { + OperationType.Update => options.CustomParameters_Update, + OperationType.Uninstall => options.CustomParameters_Uninstall, + _ => options.CustomParameters_Install, + } + ); return parameters; } @@ -57,18 +73,28 @@ protected override OperationVeredict _getOperationResult( IPackage package, OperationType operation, IReadOnlyList processOutput, - int returnCode) + int returnCode + ) { string output_string = string.Join("\n", processOutput); - if (package.OverridenOptions.RunAsAdministrator is not true && - (output_string.Contains("AdminPrivilegesAreRequired") || output_string.Contains("AdminPrivilegeRequired"))) + if ( + package.OverridenOptions.RunAsAdministrator is not true + && ( + output_string.Contains("AdminPrivilegesAreRequired") + || output_string.Contains("AdminPrivilegeRequired") + ) + ) { package.OverridenOptions.RunAsAdministrator = true; return OperationVeredict.AutoRetry; } - if (output_string.Contains("-Scope") && output_string.Contains("NamedParameterNotFound") && !package.OverridenOptions.PowerShell_DoNotSetScopeParameter) + if ( + output_string.Contains("-Scope") + && output_string.Contains("NamedParameterNotFound") + && !package.OverridenOptions.PowerShell_DoNotSetScopeParameter + ) { package.OverridenOptions.PowerShell_DoNotSetScopeParameter = true; return OperationVeredict.AutoRetry; diff --git a/src/UniGetUI.PackageEngine.Managers.PowerShell/Helpers/PowerShellSourceHelper.cs b/src/UniGetUI.PackageEngine.Managers.PowerShell/Helpers/PowerShellSourceHelper.cs index 9c3d8ae15a..9a4af9d0a5 100644 --- a/src/UniGetUI.PackageEngine.Managers.PowerShell/Helpers/PowerShellSourceHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.PowerShell/Helpers/PowerShellSourceHelper.cs @@ -11,7 +11,8 @@ namespace UniGetUI.PackageEngine.Managers.PowerShellManager { internal sealed class PowerShellSourceHelper : BaseSourceHelper { - public PowerShellSourceHelper(PowerShell manager) : base(manager) { } + public PowerShellSourceHelper(PowerShell manager) + : base(manager) { } public override string[] GetAddSourceParameters(IManagerSource source) { @@ -20,7 +21,14 @@ public override string[] GetAddSourceParameters(IManagerSource source) return ["Register-PSRepository", "-Default"]; } - return ["Register-PSRepository", "-Name", source.Name, "-SourceLocation", source.Url.ToString()]; + return + [ + "Register-PSRepository", + "-Name", + source.Name, + "-SourceLocation", + source.Url.ToString(), + ]; } public override string[] GetRemoveSourceParameters(IManagerSource source) @@ -28,12 +36,20 @@ public override string[] GetRemoveSourceParameters(IManagerSource source) return ["Unregister-PSRepository", "-Name", source.Name]; } - protected override OperationVeredict _getAddSourceOperationVeredict(IManagerSource source, int ReturnCode, string[] Output) + protected override OperationVeredict _getAddSourceOperationVeredict( + IManagerSource source, + int ReturnCode, + string[] Output + ) { return ReturnCode == 0 ? OperationVeredict.Success : OperationVeredict.Failure; } - protected override OperationVeredict _getRemoveSourceOperationVeredict(IManagerSource source, int ReturnCode, string[] Output) + protected override OperationVeredict _getRemoveSourceOperationVeredict( + IManagerSource source, + int ReturnCode, + string[] Output + ) { return ReturnCode == 0 ? OperationVeredict.Success : OperationVeredict.Failure; } @@ -53,11 +69,14 @@ protected override IReadOnlyList GetSources_UnSafe() RedirectStandardInput = true, UseShellExecute = false, CreateNoWindow = true, - StandardOutputEncoding = System.Text.Encoding.UTF8 - } + StandardOutputEncoding = System.Text.Encoding.UTF8, + }, }; - IProcessTaskLogger logger = Manager.TaskLogger.CreateNew(LoggableTaskType.ListSources, p); + IProcessTaskLogger logger = Manager.TaskLogger.CreateNew( + LoggableTaskType.ListSources, + p + ); p.Start(); @@ -85,7 +104,13 @@ protected override IReadOnlyList GetSources_UnSafe() string[] parts = Regex.Replace(line.Trim(), " {2,}", " ").Split(' '); if (parts.Length >= 3) { - sources.Add(new ManagerSource(Manager, parts[0].Trim(), new Uri(parts[2].Trim()))); + sources.Add( + new ManagerSource( + Manager, + parts[0].Trim(), + new Uri(parts[2].Trim()) + ) + ); } } } diff --git a/src/UniGetUI.PackageEngine.Managers.PowerShell/PowerShell.cs b/src/UniGetUI.PackageEngine.Managers.PowerShell/PowerShell.cs index f6d910280f..c1d3ca7f28 100644 --- a/src/UniGetUI.PackageEngine.Managers.PowerShell/PowerShell.cs +++ b/src/UniGetUI.PackageEngine.Managers.PowerShell/PowerShell.cs @@ -35,23 +35,40 @@ public PowerShell() KnowsUpdateDate = false, }, SupportsProxy = ProxySupport.Partially, - SupportsProxyAuth = true + SupportsProxyAuth = true, }; Properties = new ManagerProperties { Name = "PowerShell", DisplayName = "PowerShell 5.x", - Description = CoreTools.Translate("PowerShell's package manager. Find libraries and scripts to expand PowerShell capabilities
Contains: Modules, Scripts, Cmdlets"), + Description = CoreTools.Translate( + "PowerShell's package manager. Find libraries and scripts to expand PowerShell capabilities
Contains: Modules, Scripts, Cmdlets" + ), IconId = IconType.PowerShell, ColorIconId = "powershell_color", ExecutableFriendlyName = "powershell.exe", InstallVerb = "Install-Module", UninstallVerb = "Uninstall-Module", UpdateVerb = "Update-Module", - KnownSources = [new ManagerSource(this, "PSGallery", new Uri("https://www.powershellgallery.com/api/v2")), - new ManagerSource(this, "PoshTestGallery", new Uri("https://www.poshtestgallery.com/api/v2"))], - DefaultSource = new ManagerSource(this, "PSGallery", new Uri("https://www.powershellgallery.com/api/v2")), + KnownSources = + [ + new ManagerSource( + this, + "PSGallery", + new Uri("https://www.powershellgallery.com/api/v2") + ), + new ManagerSource( + this, + "PoshTestGallery", + new Uri("https://www.poshtestgallery.com/api/v2") + ), + ], + DefaultSource = new ManagerSource( + this, + "PSGallery", + new Uri("https://www.powershellgallery.com/api/v2") + ), }; DetailsHelper = new PowerShellDetailsHelper(this); @@ -72,11 +89,14 @@ protected override IReadOnlyList _getInstalledPackages_UnSafe() RedirectStandardInput = true, UseShellExecute = false, CreateNoWindow = true, - StandardOutputEncoding = Encoding.UTF8 - } + StandardOutputEncoding = Encoding.UTF8, + }, }; - IProcessTaskLogger logger = TaskLogger.CreateNew(LoggableTaskType.ListInstalledPackages, p); + IProcessTaskLogger logger = TaskLogger.CreateNew( + LoggableTaskType.ListInstalledPackages, + p + ); p.Start(); string? line; @@ -105,8 +125,15 @@ protected override IReadOnlyList _getInstalledPackages_UnSafe() elements[i] = elements[i].Trim(); } - Packages.Add(new Package(CoreTools.FormatAsName(elements[1]), elements[1], elements[0], - SourcesHelper.Factory.GetSourceOrDefault(elements[2]), this)); + Packages.Add( + new Package( + CoreTools.FormatAsName(elements[1]), + elements[1], + elements[0], + SourcesHelper.Factory.GetSourceOrDefault(elements[2]), + this + ) + ); } } @@ -120,11 +147,16 @@ protected override IReadOnlyList _getInstalledPackages_UnSafe() public override List FindCandidateExecutableFiles() { var candidates = CoreTools.WhichMultiple("powershell.exe"); - if(candidates.Count is 0) candidates.Add(CoreData.PowerShell5); + if (candidates.Count is 0) + candidates.Add(CoreData.PowerShell5); return candidates; } - protected override void _loadManagerExecutableFile(out bool found, out string path, out string callArguments) + protected override void _loadManagerExecutableFile( + out bool found, + out string path, + out string callArguments + ) { var (_found, _path) = GetExecutableFile(); found = _found; @@ -144,8 +176,8 @@ protected override void _loadManagerVersion(out string version) RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true, - StandardOutputEncoding = Encoding.UTF8 - } + StandardOutputEncoding = Encoding.UTF8, + }, }; process.Start(); version = process.StandardOutput.ReadToEnd().Trim(); diff --git a/src/UniGetUI.PackageEngine.Managers.PowerShell/UniGetUI.PackageEngine.Managers.PowerShell.csproj b/src/UniGetUI.PackageEngine.Managers.PowerShell/UniGetUI.PackageEngine.Managers.PowerShell.csproj index b0cd3742ef..fac3e738a0 100644 --- a/src/UniGetUI.PackageEngine.Managers.PowerShell/UniGetUI.PackageEngine.Managers.PowerShell.csproj +++ b/src/UniGetUI.PackageEngine.Managers.PowerShell/UniGetUI.PackageEngine.Managers.PowerShell.csproj @@ -1,32 +1,29 @@ + + $(WindowsTargetFramework) + + - - $(WindowsTargetFramework) - - + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - + + + diff --git a/src/UniGetUI.PackageEngine.Managers.PowerShell7/Helpers/PowerShell7DetailsHelper.cs b/src/UniGetUI.PackageEngine.Managers.PowerShell7/Helpers/PowerShell7DetailsHelper.cs index 6178683a01..5631b3b123 100644 --- a/src/UniGetUI.PackageEngine.Managers.PowerShell7/Helpers/PowerShell7DetailsHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.PowerShell7/Helpers/PowerShell7DetailsHelper.cs @@ -5,19 +5,28 @@ namespace UniGetUI.PackageEngine.Managers.Chocolatey { public class PowerShell7DetailsHelper : BaseNuGetDetailsHelper { - public PowerShell7DetailsHelper(BaseNuGet manager) : base(manager) - { - } + public PowerShell7DetailsHelper(BaseNuGet manager) + : base(manager) { } protected override string? GetInstallLocation_UnSafe(IPackage package) { - var user_path = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), - "PowerShell", "Modules", package.Id); - if (Directory.Exists(user_path)) return user_path; + var user_path = Path.Join( + Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), + "PowerShell", + "Modules", + package.Id + ); + if (Directory.Exists(user_path)) + return user_path; - var system_path = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), - "PowerShell", "Modules", package.Id); - if (Directory.Exists(system_path)) return system_path; + var system_path = Path.Join( + Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), + "PowerShell", + "Modules", + package.Id + ); + if (Directory.Exists(system_path)) + return system_path; return null; } diff --git a/src/UniGetUI.PackageEngine.Managers.PowerShell7/Helpers/PowerShell7PkgOperationHelper.cs b/src/UniGetUI.PackageEngine.Managers.PowerShell7/Helpers/PowerShell7PkgOperationHelper.cs index 1f1b834ce8..3609fe7d9a 100644 --- a/src/UniGetUI.PackageEngine.Managers.PowerShell7/Helpers/PowerShell7PkgOperationHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.PowerShell7/Helpers/PowerShell7PkgOperationHelper.cs @@ -4,24 +4,33 @@ using UniGetUI.PackageEngine.Serializable; namespace UniGetUI.PackageEngine.Managers.PowerShell7Manager; + internal sealed class PowerShell7PkgOperationHelper : BasePkgOperationHelper { - public PowerShell7PkgOperationHelper(PowerShell7 manager) : base(manager) { } + public PowerShell7PkgOperationHelper(PowerShell7 manager) + : base(manager) { } - protected override IReadOnlyList _getOperationParameters(IPackage package, - InstallOptions options, OperationType operation) + protected override IReadOnlyList _getOperationParameters( + IPackage package, + InstallOptions options, + OperationType operation + ) { - List parameters = [operation switch { - OperationType.Install => Manager.Properties.InstallVerb, - OperationType.Update => Manager.Properties.UpdateVerb, - OperationType.Uninstall => Manager.Properties.UninstallVerb, - _ => throw new InvalidDataException("Invalid package operation") - }]; + List parameters = + [ + operation switch + { + OperationType.Install => Manager.Properties.InstallVerb, + OperationType.Update => Manager.Properties.UpdateVerb, + OperationType.Uninstall => Manager.Properties.UninstallVerb, + _ => throw new InvalidDataException("Invalid package operation"), + }, + ]; parameters.AddRange(["-Name", package.Id, "-Confirm:$false"]); if (operation is OperationType.Install) { - if(options.Version != "") + if (options.Version != "") parameters.AddRange(["-Version", options.Version]); } else if (operation is OperationType.Update) @@ -40,19 +49,26 @@ protected override IReadOnlyList _getOperationParameters(IPackage packag if (options.PreRelease) parameters.Add("-Prerelease"); - if (package.OverridenOptions.Scope is PackageScope.Global || - (package.OverridenOptions.Scope is null && options.InstallationScope is PackageScope.Global)) + if ( + package.OverridenOptions.Scope is PackageScope.Global + || ( + package.OverridenOptions.Scope is null + && options.InstallationScope is PackageScope.Global + ) + ) parameters.AddRange(["-Scope", "AllUsers"]); else parameters.AddRange(["-Scope", "CurrentUser"]); } - parameters.AddRange(operation switch - { - OperationType.Update => options.CustomParameters_Update, - OperationType.Uninstall => options.CustomParameters_Uninstall, - _ => options.CustomParameters_Install, - }); + parameters.AddRange( + operation switch + { + OperationType.Update => options.CustomParameters_Update, + OperationType.Uninstall => options.CustomParameters_Uninstall, + _ => options.CustomParameters_Install, + } + ); return parameters; } @@ -61,12 +77,18 @@ protected override OperationVeredict _getOperationResult( IPackage package, OperationType operation, IReadOnlyList processOutput, - int returnCode) + int returnCode + ) { string output_string = string.Join("\n", processOutput); - if (package.OverridenOptions.RunAsAdministrator is not true && - (output_string.Contains("AdminPrivilegesAreRequired") || output_string.Contains("AdminPrivilegeRequired"))) + if ( + package.OverridenOptions.RunAsAdministrator is not true + && ( + output_string.Contains("AdminPrivilegesAreRequired") + || output_string.Contains("AdminPrivilegeRequired") + ) + ) { package.OverridenOptions.RunAsAdministrator = true; return OperationVeredict.AutoRetry; diff --git a/src/UniGetUI.PackageEngine.Managers.PowerShell7/Helpers/PowerShell7SourceHelper.cs b/src/UniGetUI.PackageEngine.Managers.PowerShell7/Helpers/PowerShell7SourceHelper.cs index 96b767cd2c..af36cab2f4 100644 --- a/src/UniGetUI.PackageEngine.Managers.PowerShell7/Helpers/PowerShell7SourceHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.PowerShell7/Helpers/PowerShell7SourceHelper.cs @@ -11,7 +11,8 @@ namespace UniGetUI.PackageEngine.Managers.PowerShell7Manager { internal sealed class PowerShell7SourceHelper : BaseSourceHelper { - public PowerShell7SourceHelper(PowerShell7 manager) : base(manager) { } + public PowerShell7SourceHelper(PowerShell7 manager) + : base(manager) { } public override string[] GetAddSourceParameters(IManagerSource source) { @@ -20,7 +21,14 @@ public override string[] GetAddSourceParameters(IManagerSource source) return ["Register-PSRepository", "-Default"]; } - return ["Register-PSRepository", "-Name", source.Name, "-SourceLocation", source.Url.ToString()]; + return + [ + "Register-PSRepository", + "-Name", + source.Name, + "-SourceLocation", + source.Url.ToString(), + ]; } public override string[] GetRemoveSourceParameters(IManagerSource source) @@ -28,12 +36,20 @@ public override string[] GetRemoveSourceParameters(IManagerSource source) return ["Unregister-PSRepository", "-Name", source.Name]; } - protected override OperationVeredict _getAddSourceOperationVeredict(IManagerSource source, int ReturnCode, string[] Output) + protected override OperationVeredict _getAddSourceOperationVeredict( + IManagerSource source, + int ReturnCode, + string[] Output + ) { return ReturnCode == 0 ? OperationVeredict.Success : OperationVeredict.Failure; } - protected override OperationVeredict _getRemoveSourceOperationVeredict(IManagerSource source, int ReturnCode, string[] Output) + protected override OperationVeredict _getRemoveSourceOperationVeredict( + IManagerSource source, + int ReturnCode, + string[] Output + ) { return ReturnCode == 0 ? OperationVeredict.Success : OperationVeredict.Failure; } @@ -47,18 +63,23 @@ protected override IReadOnlyList GetSources_UnSafe() StartInfo = new() { FileName = Manager.Status.ExecutablePath, - Arguments = Manager.Status.ExecutableCallArgs + " \"Get-PSRepository | Format-Table -Property " + - "Name,@{N='SourceLocation';E={If ($_.Uri) {$_.Uri.AbsoluteUri} Else {$_.SourceLocation}}}\"", + Arguments = + Manager.Status.ExecutableCallArgs + + " \"Get-PSRepository | Format-Table -Property " + + "Name,@{N='SourceLocation';E={If ($_.Uri) {$_.Uri.AbsoluteUri} Else {$_.SourceLocation}}}\"", RedirectStandardOutput = true, RedirectStandardError = true, RedirectStandardInput = true, UseShellExecute = false, CreateNoWindow = true, - StandardOutputEncoding = System.Text.Encoding.UTF8 - } + StandardOutputEncoding = System.Text.Encoding.UTF8, + }, }; - IProcessTaskLogger logger = Manager.TaskLogger.CreateNew(LoggableTaskType.ListSources, p); + IProcessTaskLogger logger = Manager.TaskLogger.CreateNew( + LoggableTaskType.ListSources, + p + ); p.Start(); @@ -86,8 +107,14 @@ protected override IReadOnlyList GetSources_UnSafe() string[] parts = Regex.Replace(line.Trim(), " {2,}", " ").Split(' '); if (parts.Length >= 2) { - string uri = Regex.Match(line, "https?:\\/\\/([\\w%-]+\\.)+[\\w%-]+(\\/[\\w%-]+)+\\/?").Value; - if (uri == "") continue; + string uri = Regex + .Match( + line, + "https?:\\/\\/([\\w%-]+\\.)+[\\w%-]+(\\/[\\w%-]+)+\\/?" + ) + .Value; + if (uri == "") + continue; sources.Add(new ManagerSource(Manager, parts[0].Trim(), new Uri(uri))); } } diff --git a/src/UniGetUI.PackageEngine.Managers.PowerShell7/PowerShell7.cs b/src/UniGetUI.PackageEngine.Managers.PowerShell7/PowerShell7.cs index 64e194007b..b66450a4b0 100644 --- a/src/UniGetUI.PackageEngine.Managers.PowerShell7/PowerShell7.cs +++ b/src/UniGetUI.PackageEngine.Managers.PowerShell7/PowerShell7.cs @@ -36,23 +36,40 @@ public PowerShell7() KnowsUpdateDate = false, }, SupportsProxy = ProxySupport.Partially, - SupportsProxyAuth = true + SupportsProxyAuth = true, }; Properties = new ManagerProperties { Name = "PowerShell7", DisplayName = "PowerShell 7.x", - Description = CoreTools.Translate("PowerShell's package manager. Find libraries and scripts to expand PowerShell capabilities
Contains: Modules, Scripts, Cmdlets"), + Description = CoreTools.Translate( + "PowerShell's package manager. Find libraries and scripts to expand PowerShell capabilities
Contains: Modules, Scripts, Cmdlets" + ), IconId = IconType.PowerShell, ColorIconId = "powershell_color", ExecutableFriendlyName = OperatingSystem.IsWindows() ? "pwsh.exe" : "pwsh", InstallVerb = "Install-PSResource", UninstallVerb = "Uninstall-PSResource", UpdateVerb = "Update-PSResource", - KnownSources = [new ManagerSource(this, "PSGallery", new Uri("https://www.powershellgallery.com/api/v2")), - new ManagerSource(this, "PoshTestGallery", new Uri("https://www.poshtestgallery.com/api/v2"))], - DefaultSource = new ManagerSource(this, "PSGallery", new Uri("https://www.powershellgallery.com/api/v2")), + KnownSources = + [ + new ManagerSource( + this, + "PSGallery", + new Uri("https://www.powershellgallery.com/api/v2") + ), + new ManagerSource( + this, + "PoshTestGallery", + new Uri("https://www.poshtestgallery.com/api/v2") + ), + ], + DefaultSource = new ManagerSource( + this, + "PSGallery", + new Uri("https://www.powershellgallery.com/api/v2") + ), }; DetailsHelper = new PowerShell7DetailsHelper(this); @@ -70,18 +87,22 @@ protected override IReadOnlyList _getInstalledPackages_UnSafe() StartInfo = new ProcessStartInfo { FileName = Status.ExecutablePath, - Arguments = Status.ExecutableCallArgs + - $" \"Get-InstalledPSResource -Scope {env} | Format-Table -Property Name,Version,Repository\"", + Arguments = + Status.ExecutableCallArgs + + $" \"Get-InstalledPSResource -Scope {env} | Format-Table -Property Name,Version,Repository\"", RedirectStandardOutput = true, RedirectStandardError = true, RedirectStandardInput = true, UseShellExecute = false, CreateNoWindow = true, - StandardOutputEncoding = Encoding.UTF8 - } + StandardOutputEncoding = Encoding.UTF8, + }, }; - IProcessTaskLogger logger = TaskLogger.CreateNew(LoggableTaskType.ListInstalledPackages, p); + IProcessTaskLogger logger = TaskLogger.CreateNew( + LoggableTaskType.ListInstalledPackages, + p + ); p.Start(); string? line; @@ -109,9 +130,16 @@ protected override IReadOnlyList _getInstalledPackages_UnSafe() elements[i] = elements[i].Trim(); } - Packages.Add(new Package(CoreTools.FormatAsName(elements[0]), elements[0], elements[1], - SourcesHelper.Factory.GetSourceOrDefault(elements[2]), this, - new(env == "CurrentUser"? PackageScope.User : PackageScope.Machine))); + Packages.Add( + new Package( + CoreTools.FormatAsName(elements[0]), + elements[0], + elements[1], + SourcesHelper.Factory.GetSourceOrDefault(elements[2]), + this, + new(env == "CurrentUser" ? PackageScope.User : PackageScope.Machine) + ) + ); } } @@ -123,10 +151,14 @@ protected override IReadOnlyList _getInstalledPackages_UnSafe() return Packages; } - public override IReadOnlyList FindCandidateExecutableFiles() - => CoreTools.WhichMultiple(OperatingSystem.IsWindows() ? "pwsh.exe" : "pwsh"); + public override IReadOnlyList FindCandidateExecutableFiles() => + CoreTools.WhichMultiple(OperatingSystem.IsWindows() ? "pwsh.exe" : "pwsh"); - protected override void _loadManagerExecutableFile(out bool found, out string path, out string callArguments) + protected override void _loadManagerExecutableFile( + out bool found, + out string path, + out string callArguments + ) { var (_found, _path) = GetExecutableFile(); found = _found; @@ -146,8 +178,8 @@ protected override void _loadManagerVersion(out string version) RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true, - StandardOutputEncoding = Encoding.UTF8 - } + StandardOutputEncoding = Encoding.UTF8, + }, }; process.Start(); version = process.StandardOutput.ReadToEnd().Trim(); diff --git a/src/UniGetUI.PackageEngine.Managers.PowerShell7/UniGetUI.PackageEngine.Managers.PowerShell7.csproj b/src/UniGetUI.PackageEngine.Managers.PowerShell7/UniGetUI.PackageEngine.Managers.PowerShell7.csproj index cccbb33784..fa307d2579 100644 --- a/src/UniGetUI.PackageEngine.Managers.PowerShell7/UniGetUI.PackageEngine.Managers.PowerShell7.csproj +++ b/src/UniGetUI.PackageEngine.Managers.PowerShell7/UniGetUI.PackageEngine.Managers.PowerShell7.csproj @@ -1,25 +1,27 @@ + + $(SharedTargetFrameworks) + + + + + + + + + + + + + + - - - - - - - - - - - - - + + + - - - - - - - + + + diff --git a/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopPkgDetailsHelper.cs b/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopPkgDetailsHelper.cs index a727be6b46..6b9a8bf2dd 100644 --- a/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopPkgDetailsHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopPkgDetailsHelper.cs @@ -11,7 +11,8 @@ namespace UniGetUI.PackageEngine.Managers.ScoopManager { internal sealed class ScoopPkgDetailsHelper : BasePkgDetailsHelper { - public ScoopPkgDetailsHelper(Scoop manager) : base(manager) { } + public ScoopPkgDetailsHelper(Scoop manager) + : base(manager) { } protected override void GetDetails_UnSafe(IPackageDetails details) { @@ -22,9 +23,16 @@ protected override void GetDetails_UnSafe(IPackageDetails details) if (details.Package.Source.Name.StartsWith("http")) details.ManifestUrl = new Uri(details.Package.Source.Name); else if (details.Package.Source.Name.Contains(":\\")) - details.ManifestUrl = new Uri("file:///" + details.Package.Source.Name.Replace("\\", "/")); + details.ManifestUrl = new Uri( + "file:///" + details.Package.Source.Name.Replace("\\", "/") + ); else - details.ManifestUrl = new Uri(details.Package.Source.Url + "/blob/master/bucket/" + details.Package.Id + ".json"); + details.ManifestUrl = new Uri( + details.Package.Source.Url + + "/blob/master/bucket/" + + details.Package.Id + + ".json" + ); } catch (Exception ex) { @@ -35,7 +43,10 @@ protected override void GetDetails_UnSafe(IPackageDetails details) string packageId; // If source is ellpised or source is a local path, omit source argument - if (details.Package.Source.Name.Contains("...") || details.Package.Source.Name.Contains(":\\")) + if ( + details.Package.Source.Name.Contains("...") + || details.Package.Source.Name.Contains(":\\") + ) packageId = $"{details.Package.Id}"; else packageId = $"{details.Package.Source.Name}/{details.Package.Id}"; @@ -51,10 +62,13 @@ protected override void GetDetails_UnSafe(IPackageDetails details) UseShellExecute = false, CreateNoWindow = true, StandardOutputEncoding = System.Text.Encoding.UTF8, - } + }, }; - IProcessTaskLogger logger = Manager.TaskLogger.CreateNew(Enums.LoggableTaskType.LoadPackageDetails, p); + IProcessTaskLogger logger = Manager.TaskLogger.CreateNew( + Enums.LoggableTaskType.LoadPackageDetails, + p + ); p.Start(); string JsonString = p.StandardOutput.ReadToEnd(); @@ -87,12 +101,21 @@ protected override void GetDetails_UnSafe(IPackageDetails details) details.InstallerType = CoreTools.Translate("Scoop package"); // Load homepage and author - if (Uri.TryCreate(contents?["homepage"]?.ToString() ?? "", UriKind.RelativeOrAbsolute, out var homepageUrl)) + if ( + Uri.TryCreate( + contents?["homepage"]?.ToString() ?? "", + UriKind.RelativeOrAbsolute, + out var homepageUrl + ) + ) { details.HomepageUrl = homepageUrl; if (homepageUrl.ToString().StartsWith("https://github.com/")) - details.Author = homepageUrl.ToString().Replace("https://github.com/", "").Split("/")[0]; + details.Author = homepageUrl + .ToString() + .Replace("https://github.com/", "") + .Split("/")[0]; else details.Author = homepageUrl.Host.Split(".")[^2]; } @@ -114,7 +137,13 @@ protected override void GetDetails_UnSafe(IPackageDetails details) if (contents?["license"] is JsonObject licenseDetails) { details.License = licenseDetails["identifier"]?.ToString(); - if (Uri.TryCreate(licenseDetails["url"]?.ToString(), UriKind.RelativeOrAbsolute, out var licenseUrl)) + if ( + Uri.TryCreate( + licenseDetails["url"]?.ToString(), + UriKind.RelativeOrAbsolute, + out var licenseUrl + ) + ) details.LicenseUrl = licenseUrl; } else @@ -126,7 +155,13 @@ protected override void GetDetails_UnSafe(IPackageDetails details) if (contents?["url"] is JsonArray urlList) { // Only one installer - if (Uri.TryCreate(urlList[0]?.ToString(), UriKind.RelativeOrAbsolute, out var installerUrl)) + if ( + Uri.TryCreate( + urlList[0]?.ToString(), + UriKind.RelativeOrAbsolute, + out var installerUrl + ) + ) details.InstallerUrl = installerUrl; details.InstallerHash = (contents?["hash"] as JsonArray)?[0]?.ToString(); @@ -134,7 +169,13 @@ protected override void GetDetails_UnSafe(IPackageDetails details) else if (contents?["url"] is JsonValue value) { // Multiple installers - if (Uri.TryCreate(value.ToString(), UriKind.RelativeOrAbsolute, out var installerUrl)) + if ( + Uri.TryCreate( + value.ToString(), + UriKind.RelativeOrAbsolute, + out var installerUrl + ) + ) details.InstallerUrl = installerUrl; details.InstallerHash = contents?["hash"]?.ToString(); @@ -144,7 +185,13 @@ protected override void GetDetails_UnSafe(IPackageDetails details) // Architecture-based installer string arch = archNode.ContainsKey("64bit") ? "64bit" : archNode.First().Key; - if (Uri.TryCreate(archNode[arch]?["url"]?.ToString(), UriKind.RelativeOrAbsolute, out var installerUrl)) + if ( + Uri.TryCreate( + archNode[arch]?["url"]?.ToString(), + UriKind.RelativeOrAbsolute, + out var installerUrl + ) + ) details.InstallerUrl = installerUrl; details.InstallerHash = archNode[arch]?["hash"]?.ToString(); @@ -154,8 +201,14 @@ protected override void GetDetails_UnSafe(IPackageDetails details) details.InstallerSize = CoreTools.GetFileSizeAsLong(details.InstallerUrl); // Load release notes URL - if (contents?["checkver"] is JsonObject checkver && Uri.TryCreate(checkver["url"]?.ToString(), UriKind.RelativeOrAbsolute, - out var releaseNotesUrl)) + if ( + contents?["checkver"] is JsonObject checkver + && Uri.TryCreate( + checkver["url"]?.ToString(), + UriKind.RelativeOrAbsolute, + out var releaseNotesUrl + ) + ) details.ReleaseNotesUrl = releaseNotesUrl; details.Dependencies.Clear(); @@ -171,23 +224,27 @@ private static void _getSuggests(IPackageDetails details, JsonObject? contents) { List innerDeps = []; - if(rawDep.Value is JsonValue value) innerDeps.Add(value.GetValue()); + if (rawDep.Value is JsonValue value) + innerDeps.Add(value.GetValue()); else { foreach (var iDep in rawDep.Value?.AsArray() ?? []) { string? val = iDep?.GetValue(); - if(val is not null) innerDeps.Add(val); + if (val is not null) + innerDeps.Add(val); } } - foreach(var val in innerDeps) - details.Dependencies.Add(new() - { - Name = val, - Version = "", - Mandatory = false, - }); + foreach (var val in innerDeps) + details.Dependencies.Add( + new() + { + Name = val, + Version = "", + Mandatory = false, + } + ); } } @@ -196,23 +253,27 @@ private static void _getDepends(IPackageDetails details, JsonObject? contents) var node = contents?["depends"]; List innerDeps = []; - if(node is JsonValue value) innerDeps.Add(value.GetValue()); + if (node is JsonValue value) + innerDeps.Add(value.GetValue()); else { foreach (var iDep in node?.AsArray() ?? []) { string? val = iDep?.GetValue(); - if(val is not null) innerDeps.Add(val); + if (val is not null) + innerDeps.Add(val); } } - foreach(var val in innerDeps) - details.Dependencies.Add(new() - { - Name = val, - Version = "", - Mandatory = true, - }); + foreach (var val in innerDeps) + details.Dependencies.Add( + new() + { + Name = val, + Version = "", + Mandatory = true, + } + ); } protected override CacheableIcon? GetIcon_UnSafe(IPackage package) @@ -227,8 +288,13 @@ protected override IReadOnlyList GetScreenshots_UnSafe(IPackage package) protected override string? GetInstallLocation_UnSafe(IPackage package) { - return Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "scoop", "apps", - package.Id, "current"); + return Path.Join( + Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), + "scoop", + "apps", + package.Id, + "current" + ); } protected override IReadOnlyList GetInstallableVersions_UnSafe(IPackage package) diff --git a/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopPkgOperationHelper.cs b/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopPkgOperationHelper.cs index 64dbd9c2ce..d9b0ebc96c 100644 --- a/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopPkgOperationHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopPkgOperationHelper.cs @@ -5,19 +5,28 @@ using Architecture = UniGetUI.PackageEngine.Enums.Architecture; namespace UniGetUI.PackageEngine.Managers.ScoopManager; + internal sealed class ScoopPkgOperationHelper : BasePkgOperationHelper { - public ScoopPkgOperationHelper(Scoop manager) : base(manager) { } + public ScoopPkgOperationHelper(Scoop manager) + : base(manager) { } - protected override IReadOnlyList _getOperationParameters(IPackage package, - InstallOptions options, OperationType operation) + protected override IReadOnlyList _getOperationParameters( + IPackage package, + InstallOptions options, + OperationType operation + ) { - List parameters = [operation switch { - OperationType.Install => Manager.Properties.InstallVerb, - OperationType.Update => Manager.Properties.UpdateVerb, - OperationType.Uninstall => Manager.Properties.UninstallVerb, - _ => throw new InvalidDataException("Invalid package operation") - }]; + List parameters = + [ + operation switch + { + OperationType.Install => Manager.Properties.InstallVerb, + OperationType.Update => Manager.Properties.UpdateVerb, + OperationType.Uninstall => Manager.Properties.UninstallVerb, + _ => throw new InvalidDataException("Invalid package operation"), + }, + ]; // If source is ellpised or source is a local path, omit source argument if (package.Source.Name.Contains("...") || package.Source.Name.Contains(":\\")) @@ -25,20 +34,27 @@ protected override IReadOnlyList _getOperationParameters(IPackage packag else parameters.Add($"{package.Source.Name}/{package.Id}"); - if (package.OverridenOptions.Scope == PackageScope.Global || - (package.OverridenOptions.Scope is null && options.InstallationScope == PackageScope.Global)) + if ( + package.OverridenOptions.Scope == PackageScope.Global + || ( + package.OverridenOptions.Scope is null + && options.InstallationScope == PackageScope.Global + ) + ) { // Scoop requires admin rights to install global packages package.OverridenOptions.RunAsAdministrator = true; parameters.Add("--global"); } - parameters.AddRange(operation switch - { - OperationType.Update => options.CustomParameters_Update, - OperationType.Uninstall => options.CustomParameters_Uninstall, - _ => options.CustomParameters_Install, - }); + parameters.AddRange( + operation switch + { + OperationType.Update => options.CustomParameters_Update, + OperationType.Uninstall => options.CustomParameters_Uninstall, + _ => options.CustomParameters_Install, + } + ); if (operation is OperationType.Uninstall) { @@ -51,15 +67,17 @@ protected override IReadOnlyList _getOperationParameters(IPackage packag parameters.Add("--skip-hash-check"); } - if(operation is OperationType.Install) + if (operation is OperationType.Install) { - parameters.AddRange(options.Architecture switch - { - Architecture.x64 => ["--arch", "64bit"], - Architecture.x86 => ["--arch", "32bit"], - Architecture.arm64 => ["--arch", "arm64"], - _ => [] - }); + parameters.AddRange( + options.Architecture switch + { + Architecture.x64 => ["--arch", "64bit"], + Architecture.x86 => ["--arch", "32bit"], + Architecture.arm64 => ["--arch", "arm64"], + _ => [], + } + ); } return parameters; @@ -69,20 +87,28 @@ protected override OperationVeredict _getOperationResult( IPackage package, OperationType operation, IReadOnlyList processOutput, - int returnCode) + int returnCode + ) { string output_string = string.Join("\n", processOutput); - if (package.OverridenOptions.Scope != PackageScope.Global && output_string.Contains("Try again with the --global (or -g) flag instead")) + if ( + package.OverridenOptions.Scope != PackageScope.Global + && output_string.Contains("Try again with the --global (or -g) flag instead") + ) { package.OverridenOptions.Scope = PackageScope.Global; package.OverridenOptions.RunAsAdministrator = true; return OperationVeredict.AutoRetry; } - if (package.OverridenOptions.RunAsAdministrator != true - && (output_string.Contains("requires admin rights") + if ( + package.OverridenOptions.RunAsAdministrator != true + && ( + output_string.Contains("requires admin rights") || output_string.Contains("requires administrator rights") - || output_string.Contains("you need admin rights to install global apps"))) + || output_string.Contains("you need admin rights to install global apps") + ) + ) { package.OverridenOptions.RunAsAdministrator = true; return OperationVeredict.AutoRetry; diff --git a/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopSourceHelper.cs b/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopSourceHelper.cs index 961239d364..11dfa45281 100644 --- a/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopSourceHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopSourceHelper.cs @@ -11,9 +11,14 @@ namespace UniGetUI.PackageEngine.Managers.ScoopManager { internal sealed class ScoopSourceHelper : BaseSourceHelper { - public ScoopSourceHelper(Scoop manager) : base(manager) { } + public ScoopSourceHelper(Scoop manager) + : base(manager) { } - protected override OperationVeredict _getAddSourceOperationVeredict(IManagerSource source, int ReturnCode, string[] Output) + protected override OperationVeredict _getAddSourceOperationVeredict( + IManagerSource source, + int ReturnCode, + string[] Output + ) { return ReturnCode == 0 ? OperationVeredict.Success : OperationVeredict.Failure; } @@ -23,7 +28,11 @@ public override string[] GetAddSourceParameters(IManagerSource source) return ["bucket", "add", source.Name, source.Url.ToString()]; } - protected override OperationVeredict _getRemoveSourceOperationVeredict(IManagerSource source, int ReturnCode, string[] Output) + protected override OperationVeredict _getRemoveSourceOperationVeredict( + IManagerSource source, + int ReturnCode, + string[] Output + ) { return ReturnCode == 0 ? OperationVeredict.Success : OperationVeredict.Failure; } @@ -48,10 +57,13 @@ protected override IReadOnlyList GetSources_UnSafe() CreateNoWindow = true, StandardInputEncoding = System.Text.Encoding.UTF8, StandardOutputEncoding = System.Text.Encoding.UTF8, - } + }, }; - IProcessTaskLogger logger = Manager.TaskLogger.CreateNew(LoggableTaskType.ListSources, p); + IProcessTaskLogger logger = Manager.TaskLogger.CreateNew( + LoggableTaskType.ListSources, + p + ); List sources = []; p.Start(); @@ -73,13 +85,28 @@ protected override IReadOnlyList GetSources_UnSafe() } else if (line.Trim() != "") { - string[] elements = Regex.Replace(Regex.Replace(line, "[1234567890 :.-][AaPp][Mm][\\W]", "").Trim(), " {2,}", " ").Split(' '); + string[] elements = Regex + .Replace( + Regex.Replace(line, "[1234567890 :.-][AaPp][Mm][\\W]", "").Trim(), + " {2,}", + " " + ) + .Split(' '); if (elements.Length >= 5) { - if (!elements[1].Contains("https://") && !elements[1].Contains("http://")) + if ( + !elements[1].Contains("https://") + && !elements[1].Contains("http://") + ) { - elements[1] = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), - "scoop", "buckets", elements[0].Trim()); + elements[1] = Path.Join( + Environment.GetFolderPath( + Environment.SpecialFolder.UserProfile + ), + "scoop", + "buckets", + elements[0].Trim() + ); } else { @@ -88,13 +115,28 @@ protected override IReadOnlyList GetSources_UnSafe() try { - sources.Add(new ManagerSource(Manager, elements[0].Trim(), new Uri(elements[1]), - int.Parse(elements[4].Trim()), elements[2].Trim() + " " + elements[3].Trim())); + sources.Add( + new ManagerSource( + Manager, + elements[0].Trim(), + new Uri(elements[1]), + int.Parse(elements[4].Trim()), + elements[2].Trim() + " " + elements[3].Trim() + ) + ); } catch (Exception ex) { logger.AddToStdErr(ex.ToString()); - sources.Add(new ManagerSource(Manager, elements[0].Trim(), new Uri(elements[1]), -1, "1/1/1970")); + sources.Add( + new ManagerSource( + Manager, + elements[0].Trim(), + new Uri(elements[1]), + -1, + "1/1/1970" + ) + ); } } } diff --git a/src/UniGetUI.PackageEngine.Managers.Scoop/Scoop.cs b/src/UniGetUI.PackageEngine.Managers.Scoop/Scoop.cs index 8341913c3d..736a728085 100644 --- a/src/UniGetUI.PackageEngine.Managers.Scoop/Scoop.cs +++ b/src/UniGetUI.PackageEngine.Managers.Scoop/Scoop.cs @@ -19,31 +19,42 @@ namespace UniGetUI.PackageEngine.Managers.ScoopManager { - public class Scoop : PackageManager { public static string[] FALSE_PACKAGE_IDS = ["No", "WARN"]; - public static string[] FALSE_PACKAGE_VERSIONS = ["Matches", "Install", "failed", "failed,", "Manifest", "removed", "removed,"]; + public static string[] FALSE_PACKAGE_VERSIONS = + [ + "Matches", + "Install", + "failed", + "failed,", + "Manifest", + "removed", + "removed,", + ]; private long LastScoopSourceUpdateTime; public Scoop() { - Dependencies = [ + Dependencies = + [ // Scoop-Search is required for search to work new ManagerDependency( "Scoop-Search", CoreData.PowerShell5, "-ExecutionPolicy Bypass -NoLogo -NoProfile -Command \"& {scoop install main/scoop-search; if($error.count -ne 0){pause}}\"", "scoop install main/scoop-search", - async () => (await CoreTools.WhichAsync("scoop-search.exe")).Item1), + async () => (await CoreTools.WhichAsync("scoop-search.exe")).Item1 + ), // GIT is required for scoop updates to work new ManagerDependency( "Git", CoreData.PowerShell5, "-ExecutionPolicy Bypass -NoLogo -NoProfile -Command \"& {scoop install main/git; if($error.count -ne 0){pause}}\"", "scoop install main/git", - async () => (await CoreTools.WhichAsync("git.exe")).Item1) + async () => (await CoreTools.WhichAsync("git.exe")).Item1 + ), ]; Capabilities = new ManagerCapabilities @@ -54,39 +65,93 @@ public Scoop() CanListDependencies = true, CanRemoveDataOnUninstall = true, SupportsCustomArchitectures = true, - SupportedCustomArchitectures = [Architecture.x86, Architecture.x64, Architecture.arm64], + SupportedCustomArchitectures = + [ + Architecture.x86, + Architecture.x64, + Architecture.arm64, + ], SupportsCustomScopes = true, SupportsCustomSources = true, Sources = new SourceCapabilities { KnowsPackageCount = true, - KnowsUpdateDate = true + KnowsUpdateDate = true, }, SupportsProxy = ProxySupport.No, - SupportsProxyAuth = false + SupportsProxyAuth = false, }; Properties = new ManagerProperties { Name = "Scoop", - Description = CoreTools.Translate("Great repository of unknown but useful utilities and other interesting packages.
Contains: Utilities, Command-line programs, General Software (extras bucket required)"), + Description = CoreTools.Translate( + "Great repository of unknown but useful utilities and other interesting packages.
Contains: Utilities, Command-line programs, General Software (extras bucket required)" + ), IconId = IconType.Scoop, ColorIconId = "scoop_color", ExecutableFriendlyName = "scoop", InstallVerb = "install", UpdateVerb = "update", UninstallVerb = "uninstall", - KnownSources = [new ManagerSource(this, "main", new Uri("https://github.com/ScoopInstaller/Main")), - new ManagerSource(this, "extras", new Uri("https://github.com/ScoopInstaller/Extras")), - new ManagerSource(this, "versions", new Uri("https://github.com/ScoopInstaller/Versions")), - new ManagerSource(this, "nirsoft", new Uri("https://github.com/ScoopInstaller/Nirsoft")), - new ManagerSource(this, "sysinternals", new Uri("https://github.com/niheaven/scoop-sysinternals")), - new ManagerSource(this, "php", new Uri("https://github.com/ScoopInstaller/PHP")), - new ManagerSource(this, "nerd-fonts", new Uri("https://github.com/matthewjberger/scoop-nerd-fonts")), - new ManagerSource(this, "nonportable", new Uri("https://github.com/ScoopInstaller/Nonportable")), - new ManagerSource(this, "java", new Uri("https://github.com/ScoopInstaller/Java")), - new ManagerSource(this, "games", new Uri("https://github.com/Calinou/scoop-games"))], - DefaultSource = new ManagerSource(this, "main", new Uri("https://github.com/ScoopInstaller/Main")), + KnownSources = + [ + new ManagerSource( + this, + "main", + new Uri("https://github.com/ScoopInstaller/Main") + ), + new ManagerSource( + this, + "extras", + new Uri("https://github.com/ScoopInstaller/Extras") + ), + new ManagerSource( + this, + "versions", + new Uri("https://github.com/ScoopInstaller/Versions") + ), + new ManagerSource( + this, + "nirsoft", + new Uri("https://github.com/ScoopInstaller/Nirsoft") + ), + new ManagerSource( + this, + "sysinternals", + new Uri("https://github.com/niheaven/scoop-sysinternals") + ), + new ManagerSource( + this, + "php", + new Uri("https://github.com/ScoopInstaller/PHP") + ), + new ManagerSource( + this, + "nerd-fonts", + new Uri("https://github.com/matthewjberger/scoop-nerd-fonts") + ), + new ManagerSource( + this, + "nonportable", + new Uri("https://github.com/ScoopInstaller/Nonportable") + ), + new ManagerSource( + this, + "java", + new Uri("https://github.com/ScoopInstaller/Java") + ), + new ManagerSource( + this, + "games", + new Uri("https://github.com/Calinou/scoop-games") + ), + ], + DefaultSource = new ManagerSource( + this, + "main", + new Uri("https://github.com/ScoopInstaller/Main") + ), }; SourcesHelper = new ScoopSourceHelper(this); @@ -110,10 +175,13 @@ protected override IReadOnlyList FindPackages_UnSafe(string query) UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, - CreateNoWindow = true - } + CreateNoWindow = true, + }, }; - IProcessTaskLogger aux_logger = TaskLogger.CreateNew(LoggableTaskType.InstallManagerDependency, proc); + IProcessTaskLogger aux_logger = TaskLogger.CreateNew( + LoggableTaskType.InstallManagerDependency, + proc + ); proc.Start(); aux_logger.AddToStdOut(proc.StandardOutput.ReadToEnd()); aux_logger.AddToStdErr(proc.StandardError.ReadToEnd()); @@ -132,8 +200,8 @@ protected override IReadOnlyList FindPackages_UnSafe(string query) RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true, - StandardOutputEncoding = System.Text.Encoding.UTF8 - } + StandardOutputEncoding = System.Text.Encoding.UTF8, + }, }; p.StartInfo = CoreTools.UpdateEnvironmentVariables(p.StartInfo); IProcessTaskLogger logger = TaskLogger.CreateNew(LoggableTaskType.FindPackages, p); @@ -163,18 +231,23 @@ protected override IReadOnlyList FindPackages_UnSafe(string query) elements[i] = elements[i].Trim(); } - if (FALSE_PACKAGE_IDS.Contains(elements[0]) - || FALSE_PACKAGE_VERSIONS.Contains(elements[1])) + if ( + FALSE_PACKAGE_IDS.Contains(elements[0]) + || FALSE_PACKAGE_VERSIONS.Contains(elements[1]) + ) { continue; } - Packages.Add(new Package( - CoreTools.FormatAsName(elements[0]), - elements[0], - elements[1].Replace("(", "").Replace(")", ""), - source, - this)); + Packages.Add( + new Package( + CoreTools.FormatAsName(elements[0]), + elements[0], + elements[1].Replace("(", "").Replace(")", ""), + source, + this + ) + ); } } logger.AddToStdErr(p.StandardError.ReadToEnd()); @@ -188,9 +261,16 @@ protected override IReadOnlyList GetAvailableUpdates_UnSafe() Dictionary InstalledPackages = []; foreach (IPackage InstalledPackage in GetInstalledPackages()) { - if (!InstalledPackages.ContainsKey(InstalledPackage.Id + "." + InstalledPackage.VersionString)) + if ( + !InstalledPackages.ContainsKey( + InstalledPackage.Id + "." + InstalledPackage.VersionString + ) + ) { - InstalledPackages.Add(InstalledPackage.Id + "." + InstalledPackage.VersionString, InstalledPackage); + InstalledPackages.Add( + InstalledPackage.Id + "." + InstalledPackage.VersionString, + InstalledPackage + ); } } @@ -206,8 +286,8 @@ protected override IReadOnlyList GetAvailableUpdates_UnSafe() RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true, - StandardOutputEncoding = System.Text.Encoding.UTF8 - } + StandardOutputEncoding = System.Text.Encoding.UTF8, + }, }; IProcessTaskLogger logger = TaskLogger.CreateNew(LoggableTaskType.ListUpdates, p); @@ -238,28 +318,43 @@ protected override IReadOnlyList GetAvailableUpdates_UnSafe() elements[i] = elements[i].Trim(); } - if (FALSE_PACKAGE_IDS.Contains(elements[0]) + if ( + FALSE_PACKAGE_IDS.Contains(elements[0]) || FALSE_PACKAGE_VERSIONS.Contains(elements[1]) - || FALSE_PACKAGE_VERSIONS.Contains(elements[2])) + || FALSE_PACKAGE_VERSIONS.Contains(elements[2]) + ) { continue; } - if (InstalledPackages.TryGetValue(elements[0] + "." + elements[1], out IPackage? InstalledPackage)) + if ( + InstalledPackages.TryGetValue( + elements[0] + "." + elements[1], + out IPackage? InstalledPackage + ) + ) { - OverridenInstallationOptions options = new(InstalledPackage.OverridenOptions.Scope); - Packages.Add(new Package( - CoreTools.FormatAsName(elements[0]), - elements[0], - elements[1], - elements[2], - InstalledPackage.Source, - this, - options)); + OverridenInstallationOptions options = new( + InstalledPackage.OverridenOptions.Scope + ); + Packages.Add( + new Package( + CoreTools.FormatAsName(elements[0]), + elements[0], + elements[1], + elements[2], + InstalledPackage.Source, + this, + options + ) + ); } else { - Logger.Warn("Upgradable scoop package not listed on installed packages - id=" + elements[0]); + Logger.Warn( + "Upgradable scoop package not listed on installed packages - id=" + + elements[0] + ); } } } @@ -269,8 +364,9 @@ protected override IReadOnlyList GetAvailableUpdates_UnSafe() return Packages; } - protected override IReadOnlyList GetInstalledPackages_UnSafe() - => TaskRecycler>.RunOrAttach(_getInstalledPackages_UnSafe, 15); + protected override IReadOnlyList GetInstalledPackages_UnSafe() => + TaskRecycler>.RunOrAttach(_getInstalledPackages_UnSafe, 15); + private IReadOnlyList _getInstalledPackages_UnSafe() { List Packages = []; @@ -285,10 +381,13 @@ private IReadOnlyList _getInstalledPackages_UnSafe() RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true, - StandardOutputEncoding = System.Text.Encoding.UTF8 - } + StandardOutputEncoding = System.Text.Encoding.UTF8, + }, }; - IProcessTaskLogger logger = TaskLogger.CreateNew(LoggableTaskType.ListInstalledPackages, p); + IProcessTaskLogger logger = TaskLogger.CreateNew( + LoggableTaskType.ListInstalledPackages, + p + ); p.Start(); string? line; @@ -311,7 +410,10 @@ private IReadOnlyList _getInstalledPackages_UnSafe() if (elements[2].Contains(":\\")) { - var path = Regex.Match(line, "[A-Za-z]:(?:[\\\\\\/][^\\\\\\/\\n]+)+(?:.json|…)"); + var path = Regex.Match( + line, + "[A-Za-z]:(?:[\\\\\\/][^\\\\\\/\\n]+)+(?:.json|…)" + ); elements[2] = path.Value; } @@ -320,7 +422,10 @@ private IReadOnlyList _getInstalledPackages_UnSafe() elements[i] = elements[i].Trim(); } - if (FALSE_PACKAGE_IDS.Contains(elements[0]) || FALSE_PACKAGE_VERSIONS.Contains(elements[1])) + if ( + FALSE_PACKAGE_IDS.Contains(elements[0]) + || FALSE_PACKAGE_VERSIONS.Contains(elements[1]) + ) { continue; } @@ -329,13 +434,16 @@ private IReadOnlyList _getInstalledPackages_UnSafe() line.Contains("Global install") ? PackageScope.Global : PackageScope.User ); - Packages.Add(new Package( - CoreTools.FormatAsName(elements[0]), - elements[0], - elements[1], - SourcesHelper.Factory.GetSourceOrDefault(elements[2]), - this, - options)); + Packages.Add( + new Package( + CoreTools.FormatAsName(elements[0]), + elements[0], + elements[1], + SourcesHelper.Factory.GetSourceOrDefault(elements[2]), + this, + options + ) + ); } } logger.AddToStdErr(p.StandardError.ReadToEnd()); @@ -348,7 +456,9 @@ public override void RefreshPackageIndexes() { if (new TimeSpan(DateTime.Now.Ticks - LastScoopSourceUpdateTime).TotalMinutes < 10) { - Logger.Info("Scoop buckets have been already refreshed in the last ten minutes, skipping."); + Logger.Info( + "Scoop buckets have been already refreshed in the last ten minutes, skipping." + ); return; } LastScoopSourceUpdateTime = DateTime.Now.Ticks; @@ -362,7 +472,7 @@ public override void RefreshPackageIndexes() RedirectStandardError = true, RedirectStandardInput = true, CreateNoWindow = true, - StandardOutputEncoding = System.Text.Encoding.UTF8 + StandardOutputEncoding = System.Text.Encoding.UTF8, }; p.StartInfo = StartInfo; IProcessTaskLogger logger = TaskLogger.CreateNew(LoggableTaskType.RefreshIndexes, p); @@ -373,18 +483,24 @@ public override void RefreshPackageIndexes() logger.Close(p.ExitCode); } - public override IReadOnlyList FindCandidateExecutableFiles() - => CoreTools.WhichMultiple("scoop.ps1"); + public override IReadOnlyList FindCandidateExecutableFiles() => + CoreTools.WhichMultiple("scoop.ps1"); - protected override void _loadManagerExecutableFile(out bool found, out string path, out string callArguments) + protected override void _loadManagerExecutableFile( + out bool found, + out string path, + out string callArguments + ) { path = CoreData.PowerShell5; var (pwshFound, pwshPath) = CoreTools.Which("pwsh.exe"); - if (pwshFound) path = pwshPath; + if (pwshFound) + path = pwshPath; var (_found, executable) = GetExecutableFile(); found = _found; - callArguments = $"-NoProfile -ExecutionPolicy Bypass -Command \"{executable.Replace(" ", "` ")}\" "; + callArguments = + $"-NoProfile -ExecutionPolicy Bypass -Command \"{executable.Replace(" ", "` ")}\" "; } protected override void _loadManagerVersion(out string version) @@ -399,8 +515,8 @@ protected override void _loadManagerVersion(out string version) RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true, - StandardOutputEncoding = System.Text.Encoding.UTF8 - } + StandardOutputEncoding = System.Text.Encoding.UTF8, + }, }; process.Start(); version = process.StandardOutput.ReadToEnd().Trim(); @@ -408,17 +524,25 @@ protected override void _loadManagerVersion(out string version) protected override void _performExtraLoadingSteps() { - if(Settings.Get(Settings.K.EnableScoopCleanup)) + if (Settings.Get(Settings.K.EnableScoopCleanup)) { RunCleanup(); } } private void RunCleanup() => _ = _runCleanup(); + private async Task _runCleanup() { Logger.Info("Starting scoop cleanup..."); - foreach (string command in new[] { " cache rm *", " cleanup --all --cache", " cleanup --all --global --cache" }) + foreach ( + string command in new[] + { + " cache rm *", + " cleanup --all --cache", + " cleanup --all --global --cache", + } + ) { using Process p = new() { @@ -430,8 +554,8 @@ private async Task _runCleanup() RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true, - StandardOutputEncoding = System.Text.Encoding.UTF8 - } + StandardOutputEncoding = System.Text.Encoding.UTF8, + }, }; p.Start(); await p.WaitForExitAsync(); diff --git a/src/UniGetUI.PackageEngine.Managers.Scoop/UniGetUI.PackageEngine.Managers.Scoop.csproj b/src/UniGetUI.PackageEngine.Managers.Scoop/UniGetUI.PackageEngine.Managers.Scoop.csproj index 53f07f9f83..ac096df665 100644 --- a/src/UniGetUI.PackageEngine.Managers.Scoop/UniGetUI.PackageEngine.Managers.Scoop.csproj +++ b/src/UniGetUI.PackageEngine.Managers.Scoop/UniGetUI.PackageEngine.Managers.Scoop.csproj @@ -1,31 +1,28 @@ + + $(WindowsTargetFramework) + + - - $(WindowsTargetFramework) - - + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - + + + diff --git a/src/UniGetUI.PackageEngine.Managers.Vcpkg/Helpers/VcpkgPkgDetailsHelper.cs b/src/UniGetUI.PackageEngine.Managers.Vcpkg/Helpers/VcpkgPkgDetailsHelper.cs index e11e9d6618..a772e443e2 100644 --- a/src/UniGetUI.PackageEngine.Managers.Vcpkg/Helpers/VcpkgPkgDetailsHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Vcpkg/Helpers/VcpkgPkgDetailsHelper.cs @@ -12,11 +12,14 @@ namespace UniGetUI.PackageEngine.Managers.VcpkgManager { internal sealed class VcpkgPkgDetailsHelper : BasePkgDetailsHelper { - public VcpkgPkgDetailsHelper(Vcpkg manager) : base(manager) { } + public VcpkgPkgDetailsHelper(Vcpkg manager) + : base(manager) { } - protected override void GetDetails_UnSafe(IPackageDetails details) + protected override void GetDetails_UnSafe(IPackageDetails details) { - INativeTaskLogger logger = Manager.TaskLogger.CreateNew(LoggableTaskType.LoadPackageDetails); + INativeTaskLogger logger = Manager.TaskLogger.CreateNew( + LoggableTaskType.LoadPackageDetails + ); const string VCPKG_REPO = "microsoft/vcpkg"; const string VCPKG_PORT_PATH = "master/ports"; @@ -27,17 +30,30 @@ protected override void GetDetails_UnSafe(IPackageDetails details) string JsonString; HttpClient client = new(CoreTools.GenericHttpClientParameters); client.DefaultRequestHeaders.UserAgent.ParseAdd(CoreData.UserAgentString); - JsonString = client.GetStringAsync($"https://raw.githubusercontent.com/{VCPKG_REPO}/refs/heads/{VCPKG_PORT_PATH}/{PackageName}/{VCPKG_PORT_FILE}").GetAwaiter().GetResult(); + JsonString = client + .GetStringAsync( + $"https://raw.githubusercontent.com/{VCPKG_REPO}/refs/heads/{VCPKG_PORT_PATH}/{PackageName}/{VCPKG_PORT_FILE}" + ) + .GetAwaiter() + .GetResult(); JsonObject? contents = JsonNode.Parse(JsonString) as JsonObject; details.Description = contents?["description"]?.ToString(); details.Publisher = contents?["maintainers"]?.ToString(); // vcpkg doesn't store the author, for some reason??? - if (Uri.TryCreate(contents?["homepage"]?.ToString(), UriKind.RelativeOrAbsolute, out var homepageUrl)) + if ( + Uri.TryCreate( + contents?["homepage"]?.ToString(), + UriKind.RelativeOrAbsolute, + out var homepageUrl + ) + ) details.HomepageUrl = homepageUrl; details.License = contents?["license"]?.ToString(); - details.ManifestUrl = new Uri($"https://github.com/{VCPKG_REPO}/blob/{VCPKG_PORT_PATH}/{PackageName}/{VCPKG_PORT_FILE}"); + details.ManifestUrl = new Uri( + $"https://github.com/{VCPKG_REPO}/blob/{VCPKG_PORT_PATH}/{PackageName}/{VCPKG_PORT_FILE}" + ); // TODO: since each change results in a new commit to the file, you could determine the `UpdateDate` via figuring out the date of the last commit that changed the file was. // Unfortunately, the GitHub API doesn't seem to allow getting the commit that changed a file, but you can get the date of a commit with // https://api.github.com/repos/{VCPKG_REPO}/commits/{CommitHash} @@ -49,7 +65,9 @@ protected override void GetDetails_UnSafe(IPackageDetails details) if (PackagePrefix.Contains('[')) { Tags.Add($"{CoreTools.Translate("library")}: " + PackageName); - Tags.Add($"{CoreTools.Translate("feature")}: " + PackagePrefix.Split('[')[^1][..^1]); + Tags.Add( + $"{CoreTools.Translate("feature")}: " + PackagePrefix.Split('[')[^1][..^1] + ); } details.Tags = Tags.ToArray(); @@ -60,7 +78,14 @@ protected override void GetDetails_UnSafe(IPackageDetails details) string? val = iDep?.GetValue(); if (val is not null) { - details.Dependencies.Add(new() { Name = val, Version = "", Mandatory = true, }); + details.Dependencies.Add( + new() + { + Name = val, + Version = "", + Mandatory = true, + } + ); } } @@ -88,7 +113,13 @@ protected override IReadOnlyList GetScreenshots_UnSafe(IPackage package) string PackageId = Regex.Replace(package.Id.Replace(":", "_"), @"\[.*\]", String.Empty); var PackagePath = Path.Join(rootPath, "packages", PackageId); var VcpkgInstalledPath = Path.Join(rootPath, "installed", package.Id.Split(":")[1]); - return Directory.Exists(PackagePath) ? PackagePath : (Directory.Exists(VcpkgInstalledPath) ? VcpkgInstalledPath : Path.GetDirectoryName(PackageId)); + return Directory.Exists(PackagePath) + ? PackagePath + : ( + Directory.Exists(VcpkgInstalledPath) + ? VcpkgInstalledPath + : Path.GetDirectoryName(PackageId) + ); } protected override IReadOnlyList GetInstallableVersions_UnSafe(IPackage package) diff --git a/src/UniGetUI.PackageEngine.Managers.Vcpkg/Helpers/VcpkgPkgOperationHelper.cs b/src/UniGetUI.PackageEngine.Managers.Vcpkg/Helpers/VcpkgPkgOperationHelper.cs index 8c68363d50..c8993b8d68 100644 --- a/src/UniGetUI.PackageEngine.Managers.Vcpkg/Helpers/VcpkgPkgOperationHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Vcpkg/Helpers/VcpkgPkgOperationHelper.cs @@ -4,26 +4,34 @@ using UniGetUI.PackageEngine.Serializable; namespace UniGetUI.PackageEngine.Managers.VcpkgManager; + internal sealed class VcpkgPkgOperationHelper : BasePkgOperationHelper { - public VcpkgPkgOperationHelper(Vcpkg manager) : base(manager) { } + public VcpkgPkgOperationHelper(Vcpkg manager) + : base(manager) { } - protected override IReadOnlyList _getOperationParameters(IPackage package, - InstallOptions options, OperationType operation) + protected override IReadOnlyList _getOperationParameters( + IPackage package, + InstallOptions options, + OperationType operation + ) { - List parameters = operation switch { + List parameters = operation switch + { OperationType.Install => [Manager.Properties.InstallVerb, package.Id], OperationType.Update => [Manager.Properties.UpdateVerb, package.Id, "--no-dry-run"], OperationType.Uninstall => [Manager.Properties.UninstallVerb, package.Id], - _ => throw new InvalidDataException("Invalid package operation") + _ => throw new InvalidDataException("Invalid package operation"), }; - parameters.AddRange(operation switch - { - OperationType.Update => options.CustomParameters_Update, - OperationType.Uninstall => options.CustomParameters_Uninstall, - _ => options.CustomParameters_Install, - }); + parameters.AddRange( + operation switch + { + OperationType.Update => options.CustomParameters_Update, + OperationType.Uninstall => options.CustomParameters_Uninstall, + _ => options.CustomParameters_Install, + } + ); return parameters; } @@ -32,7 +40,8 @@ protected override OperationVeredict _getOperationResult( IPackage package, OperationType operation, IReadOnlyList processOutput, - int returnCode) + int returnCode + ) { return returnCode == 0 ? OperationVeredict.Success : OperationVeredict.Failure; } diff --git a/src/UniGetUI.PackageEngine.Managers.Vcpkg/Helpers/VcpkgSourceHelper.cs b/src/UniGetUI.PackageEngine.Managers.Vcpkg/Helpers/VcpkgSourceHelper.cs index 3b27bd21e1..3cf9aba957 100644 --- a/src/UniGetUI.PackageEngine.Managers.Vcpkg/Helpers/VcpkgSourceHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Vcpkg/Helpers/VcpkgSourceHelper.cs @@ -7,30 +7,37 @@ namespace UniGetUI.PackageEngine.Managers.VcpkgManager { internal sealed class VcpkgSourceHelper : BaseSourceHelper { - public VcpkgSourceHelper(Vcpkg manager) : base(manager) { } + public VcpkgSourceHelper(Vcpkg manager) + : base(manager) { } - public override string[] GetAddSourceParameters(IManagerSource source) - => throw new NotImplementedException(); + public override string[] GetAddSourceParameters(IManagerSource source) => + throw new NotImplementedException(); - public override string[] GetRemoveSourceParameters(IManagerSource source) - => throw new NotImplementedException(); + public override string[] GetRemoveSourceParameters(IManagerSource source) => + throw new NotImplementedException(); - protected override OperationVeredict _getAddSourceOperationVeredict(IManagerSource source, int ReturnCode, string[] Output) - => throw new NotImplementedException(); + protected override OperationVeredict _getAddSourceOperationVeredict( + IManagerSource source, + int ReturnCode, + string[] Output + ) => throw new NotImplementedException(); - protected override OperationVeredict _getRemoveSourceOperationVeredict(IManagerSource source, int ReturnCode, string[] Output) - => throw new NotImplementedException(); + protected override OperationVeredict _getRemoveSourceOperationVeredict( + IManagerSource source, + int ReturnCode, + string[] Output + ) => throw new NotImplementedException(); protected override IReadOnlyList GetSources_UnSafe() { List Sources = []; - foreach (string Triplet in Vcpkg.GetSystemTriplets()) { - Sources.Add(new ManagerSource(Manager, Triplet, Vcpkg.URI_VCPKG_IO)); - } + foreach (string Triplet in Vcpkg.GetSystemTriplets()) + { + Sources.Add(new ManagerSource(Manager, Triplet, Vcpkg.URI_VCPKG_IO)); + } return Sources; } - } } diff --git a/src/UniGetUI.PackageEngine.Managers.Vcpkg/UniGetUI.PackageEngine.Managers.Vcpkg.csproj b/src/UniGetUI.PackageEngine.Managers.Vcpkg/UniGetUI.PackageEngine.Managers.Vcpkg.csproj index 19dba2617d..00d99aa0e4 100644 --- a/src/UniGetUI.PackageEngine.Managers.Vcpkg/UniGetUI.PackageEngine.Managers.Vcpkg.csproj +++ b/src/UniGetUI.PackageEngine.Managers.Vcpkg/UniGetUI.PackageEngine.Managers.Vcpkg.csproj @@ -1,20 +1,23 @@ + + $(SharedTargetFrameworks) + - - - - - - - - - - - - - + + + + + + + + + + + + + - - - + + + diff --git a/src/UniGetUI.PackageEngine.Managers.Vcpkg/Vcpkg.cs b/src/UniGetUI.PackageEngine.Managers.Vcpkg/Vcpkg.cs index 3cca7d83a4..f24d3bd834 100644 --- a/src/UniGetUI.PackageEngine.Managers.Vcpkg/Vcpkg.cs +++ b/src/UniGetUI.PackageEngine.Managers.Vcpkg/Vcpkg.cs @@ -25,7 +25,8 @@ public class Vcpkg : PackageManager public Vcpkg() { - Dependencies = [ + Dependencies = + [ // GIT is required for vcpkg updates to work new ManagerDependency( "Git", @@ -33,7 +34,8 @@ public Vcpkg() "-ExecutionPolicy Bypass -NoLogo -NoProfile -Command \"& {winget install --id Git.Git --exact " + "--source winget --accept-source-agreements --accept-package-agreements --force; if($error.count -ne 0){pause}}\"", "winget install --id Git.Git --exact --source winget", - async () => (await CoreTools.WhichAsync("git.exe")).Item1) + async () => (await CoreTools.WhichAsync("git.exe")).Item1 + ), ]; Capabilities = new ManagerCapabilities @@ -57,16 +59,20 @@ public Vcpkg() { "x64-linux", new ManagerSource(this, "x64-linux", URI_VCPKG_IO) }, { "x64-osx", new ManagerSource(this, "x64-osx", URI_VCPKG_IO) }, { "x64-uwp", new ManagerSource(this, "x64-uwp", URI_VCPKG_IO) }, - { "x64-windows-static", new ManagerSource(this, "x64-windows-static", URI_VCPKG_IO) }, + { + "x64-windows-static", + new ManagerSource(this, "x64-windows-static", URI_VCPKG_IO) + }, { "x64-windows", new ManagerSource(this, "x64-windows", URI_VCPKG_IO) }, - { "x86-windows", new ManagerSource(this, "x86-windows", URI_VCPKG_IO) } + { "x86-windows", new ManagerSource(this, "x86-windows", URI_VCPKG_IO) }, }; Properties = new ManagerProperties { Name = "vcpkg", Description = CoreTools.Translate( - "A popular C/C++ library manager. Full of C/C++ libraries and other C/C++-related utilities
Contains: C/C++ libraries and related utilities"), + "A popular C/C++ library manager. Full of C/C++ libraries and other C/C++-related utilities
Contains: C/C++ libraries and related utilities" + ), IconId = IconType.Vcpkg, ColorIconId = "vcpkg_color", ExecutableFriendlyName = "vcpkg", @@ -91,15 +97,17 @@ protected override IReadOnlyList FindPackages_UnSafe(string query) StartInfo = new ProcessStartInfo { FileName = Status.ExecutablePath, - Arguments = Status.ExecutableCallArgs + $" search \"{CoreTools.EnsureSafeQueryString(query)}\"", + Arguments = + Status.ExecutableCallArgs + + $" search \"{CoreTools.EnsureSafeQueryString(query)}\"", // vcpkg has an --x-json flag that would list installed packages in JSON, but it doesn't work for this call (as of 2024-09-30-ab8988503c7cffabfd440b243a383c0a352a023d) // TODO: Perhaps use --x-json when it is fixed RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true, - StandardOutputEncoding = Encoding.UTF8 - } + StandardOutputEncoding = Encoding.UTF8, + }, }; IProcessTaskLogger logger = TaskLogger.CreateNew(LoggableTaskType.FindPackages, p); @@ -126,14 +134,16 @@ protected override IReadOnlyList FindPackages_UnSafe(string query) string[] PackageData = Regex.Replace(line, @"\s+", " ").Split(' '); string PackageId = PackageData[0]; // the id with the suboption string PackageName = PackageId; // the actual name (id - suboption) - string - PackageDetailedName = PackageName; // the name with a reformatted suboption reapplied (display name) + string PackageDetailedName = PackageName; // the name with a reformatted suboption reapplied (display name) string PackageVersion = PackageData[1]; - if (PackageName.Contains('[') /* meaning its a suboption, and thus has no version */) + if ( + PackageName.Contains('[') /* meaning its a suboption, and thus has no version */ + ) { PackageName = PackageId.Split('[')[0]; //..PackageName.IndexOf("[", StringComparison.Ordinal)]; - PackageDetailedName = PackageName + $" ({optionString}: {PackageId.Split('[')[1][..^1]})"; + PackageDetailedName = + PackageName + $" ({optionString}: {PackageId.Split('[')[1][..^1]})"; if (PackageVersions.TryGetValue(PackageName, out string? value)) { @@ -155,8 +165,15 @@ protected override IReadOnlyList FindPackages_UnSafe(string query) TripletSourceMap.Add(Triplet, source); } - Packages.Add(new Package(CoreTools.FormatAsName(PackageDetailedName), PackageId + ":" + Triplet, - PackageVersion, source, this)); + Packages.Add( + new Package( + CoreTools.FormatAsName(PackageDetailedName), + PackageId + ":" + Triplet, + PackageVersion, + source, + this + ) + ); } logger.AddToStdErr(p.StandardError.ReadToEnd()); @@ -179,8 +196,8 @@ protected override IReadOnlyList GetAvailableUpdates_UnSafe() RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true, - StandardOutputEncoding = Encoding.UTF8 - } + StandardOutputEncoding = Encoding.UTF8, + }, }; IProcessTaskLogger logger = TaskLogger.CreateNew(LoggableTaskType.ListUpdates, p); @@ -210,8 +227,16 @@ protected override IReadOnlyList GetAvailableUpdates_UnSafe() TripletSourceMap[PackageTriplet] = value; } - Packages.Add(new Package(CoreTools.FormatAsName(PackageName), PackageId, PackageVersionCurrent, - PackageVersionLatest, value, this)); + Packages.Add( + new Package( + CoreTools.FormatAsName(PackageName), + PackageId, + PackageVersionCurrent, + PackageVersionLatest, + value, + this + ) + ); } } @@ -235,11 +260,14 @@ protected override IReadOnlyList GetInstalledPackages_UnSafe() RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true, - StandardOutputEncoding = Encoding.UTF8 - } + StandardOutputEncoding = Encoding.UTF8, + }, }; - IProcessTaskLogger logger = TaskLogger.CreateNew(LoggableTaskType.ListInstalledPackages, p); + IProcessTaskLogger logger = TaskLogger.CreateNew( + LoggableTaskType.ListInstalledPackages, + p + ); string? line; List Packages = []; @@ -262,7 +290,9 @@ protected override IReadOnlyList GetInstalledPackages_UnSafe() string PackageName = PackageId.Split(':')[0], PackageTriplet = PackageId.Split(':')[1], PackageVersion = PackageData[1]; - if (PackageId.Contains('[') /* meaning its a suboption, and thus has no version */) + if ( + PackageId.Contains('[') /* meaning its a suboption, and thus has no version */ + ) { PackageVersion = PackageVersions[PackageName.Split("[")[0]]; } @@ -277,7 +307,15 @@ protected override IReadOnlyList GetInstalledPackages_UnSafe() TripletSourceMap[PackageTriplet] = value; } - Packages.Add(new Package(CoreTools.FormatAsName(PackageName), PackageId, PackageVersion, value, this)); + Packages.Add( + new Package( + CoreTools.FormatAsName(PackageName), + PackageId, + PackageVersion, + value, + this + ) + ); } logger.AddToStdErr(p.StandardError.ReadToEnd()); @@ -294,18 +332,26 @@ public override IReadOnlyList FindCandidateExecutableFiles() if (rootFound) { string VcpkgLocation = Path.Join(rootPath, "vcpkg.exe"); - if (File.Exists(VcpkgLocation)) candidates.Add(VcpkgLocation); + if (File.Exists(VcpkgLocation)) + candidates.Add(VcpkgLocation); } return candidates; } - protected override void _loadManagerExecutableFile(out bool found, out string path, out string callArguments) + protected override void _loadManagerExecutableFile( + out bool found, + out string path, + out string callArguments + ) { var (exeFound, exePath) = GetExecutableFile(); var (rootFound, _) = GetVcpkgRoot(); - if(!rootFound) Logger.Error("Vcpkg root was not found. Please define the %VCPKG_ROOT% environment variable or define it from UniGetUI Settings"); + if (!rootFound) + Logger.Error( + "Vcpkg root was not found. Please define the %VCPKG_ROOT% environment variable or define it from UniGetUI Settings" + ); found = exeFound && rootFound; path = exePath; @@ -328,8 +374,8 @@ protected override void _loadManagerVersion(out string version) RedirectStandardError = true, CreateNoWindow = true, StandardOutputEncoding = Encoding.UTF8, - StandardErrorEncoding = Encoding.UTF8 - } + StandardErrorEncoding = Encoding.UTF8, + }, }; process.Start(); version = process.StandardOutput.ReadLine()?.Trim() ?? ""; @@ -347,10 +393,13 @@ protected override void _performExtraLoadingSteps() WorkingDirectory = rootPath, Arguments = "/C .\\bootstrap-vcpkg.bat", UseShellExecute = false, - CreateNoWindow = true - } + CreateNoWindow = true, + }, }; - IProcessTaskLogger processLogger2 = TaskLogger.CreateNew(LoggableTaskType.RefreshIndexes, p2); + IProcessTaskLogger processLogger2 = TaskLogger.CreateNew( + LoggableTaskType.RefreshIndexes, + p2 + ); p2.Start(); p2.WaitForExit(); processLogger2.Close(p2.ExitCode); @@ -364,10 +413,16 @@ public override void RefreshPackageIndexes() if (!Status.Found || !gitFound || !vcpkgRootFound) { INativeTaskLogger logger = TaskLogger.CreateNew(LoggableTaskType.RefreshIndexes); - if (Settings.Get(Settings.K.DisableUpdateVcpkgGitPorts)) logger.Error("User has disabled updating sources"); - if (!Status.Found) logger.Error("Vcpkg was not found???"); - if (!gitFound) logger.Error("Vcpkg sources won't be updated since git was not found"); - if (!vcpkgRootFound) logger.Error("Cannot update vcpkg port files as requested: the VCPKG_ROOT environment variable or custom vcpkg root setting was not set"); + if (Settings.Get(Settings.K.DisableUpdateVcpkgGitPorts)) + logger.Error("User has disabled updating sources"); + if (!Status.Found) + logger.Error("Vcpkg was not found???"); + if (!gitFound) + logger.Error("Vcpkg sources won't be updated since git was not found"); + if (!vcpkgRootFound) + logger.Error( + "Cannot update vcpkg port files as requested: the VCPKG_ROOT environment variable or custom vcpkg root setting was not set" + ); logger.Close(Settings.Get(Settings.K.DisableUpdateVcpkgGitPorts) ? 0 : 1); return; } @@ -382,10 +437,13 @@ public override void RefreshPackageIndexes() UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, - CreateNoWindow = true - } + CreateNoWindow = true, + }, }; - IProcessTaskLogger processLogger = TaskLogger.CreateNew(LoggableTaskType.RefreshIndexes, p); + IProcessTaskLogger processLogger = TaskLogger.CreateNew( + LoggableTaskType.RefreshIndexes, + p + ); p.Start(); p.WaitForExit(); processLogger.AddToStdOut(p.StandardOutput.ReadToEnd()); @@ -436,13 +494,19 @@ public static string GetDefaultTriplet() if (DefaultTriplet == "") { - if (RuntimeInformation.OSArchitecture is Architecture.X64) DefaultTriplet = "x64-"; - else if (RuntimeInformation.OSArchitecture is Architecture.X86) DefaultTriplet = "x86-"; - else if (RuntimeInformation.OSArchitecture is Architecture.Arm64) DefaultTriplet = "arm64-"; - - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) DefaultTriplet += "windows"; - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) DefaultTriplet += "osx"; - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) DefaultTriplet += "linux"; + if (RuntimeInformation.OSArchitecture is Architecture.X64) + DefaultTriplet = "x64-"; + else if (RuntimeInformation.OSArchitecture is Architecture.X86) + DefaultTriplet = "x86-"; + else if (RuntimeInformation.OSArchitecture is Architecture.Arm64) + DefaultTriplet = "arm64-"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + DefaultTriplet += "windows"; + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + DefaultTriplet += "osx"; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + DefaultTriplet += "linux"; } return DefaultTriplet; @@ -465,16 +529,22 @@ public static List GetSystemTriplets() } else { - Logger.Warn($"The built-in triplet directory {tripletLocation} does not exist; triplets will not be loaded."); + Logger.Warn( + $"The built-in triplet directory {tripletLocation} does not exist; triplets will not be loaded." + ); } if (Path.Exists(communityTripletLocation)) { - tripletFiles = tripletFiles.Concat(Directory.EnumerateFiles(communityTripletLocation)); + tripletFiles = tripletFiles.Concat( + Directory.EnumerateFiles(communityTripletLocation) + ); } else { - Logger.Warn($"The community triplet directory {communityTripletLocation} does not exist; community triplets will not be loaded."); + Logger.Warn( + $"The community triplet directory {communityTripletLocation} does not exist; community triplets will not be loaded." + ); } foreach (string tripletFile in tripletFiles) diff --git a/src/UniGetUI.PackageEngine.Managers.WinGet/ClientHelpers/BundledWinGetHelper.cs b/src/UniGetUI.PackageEngine.Managers.WinGet/ClientHelpers/BundledWinGetHelper.cs index 882ea86ac2..f61163221a 100644 --- a/src/UniGetUI.PackageEngine.Managers.WinGet/ClientHelpers/BundledWinGetHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.WinGet/ClientHelpers/BundledWinGetHelper.cs @@ -28,14 +28,16 @@ public IReadOnlyList GetAvailableUpdates_UnSafe() StartInfo = new() { FileName = WinGet.BundledWinGetPath, - Arguments = Manager.Status.ExecutableCallArgs + - " update --include-unknown --accept-source-agreements " + WinGet.GetProxyArgument(), + Arguments = + Manager.Status.ExecutableCallArgs + + " update --include-unknown --accept-source-agreements " + + WinGet.GetProxyArgument(), RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true, - StandardOutputEncoding = Encoding.UTF8 - } + StandardOutputEncoding = Encoding.UTF8, + }, }; IProcessTaskLogger logger = Manager.TaskLogger.CreateNew(LoggableTaskType.ListUpdates, p); @@ -43,7 +45,9 @@ public IReadOnlyList GetAvailableUpdates_UnSafe() if (CoreTools.IsAdministrator()) { string WinGetTemp = Path.Join(Path.GetTempPath(), "UniGetUI", "ElevatedWinGetTemp"); - logger.AddToStdErr($"[WARN] Redirecting %TEMP% folder to {WinGetTemp}, since UniGetUI was run as admin"); + logger.AddToStdErr( + $"[WARN] Redirecting %TEMP% folder to {WinGetTemp}, since UniGetUI was run as admin" + ); p.StartInfo.Environment["TEMP"] = WinGetTemp; p.StartInfo.Environment["TMP"] = WinGetTemp; } @@ -71,16 +75,33 @@ public IReadOnlyList GetAvailableUpdates_UnSafe() string HeaderPrefix = OldLine.Contains("SearchId") ? "Search" : ""; string HeaderSuffix = OldLine.Contains("SearchId") ? "Header" : ""; IdIndex = OldLine.IndexOf(HeaderPrefix + "Id", StringComparison.InvariantCulture); - VersionIndex = OldLine.IndexOf(HeaderPrefix + "Version", StringComparison.InvariantCulture); - NewVersionIndex = OldLine.IndexOf("Available" + HeaderSuffix, StringComparison.InvariantCulture); - SourceIndex = OldLine.IndexOf(HeaderPrefix + "Source", StringComparison.InvariantCulture); + VersionIndex = OldLine.IndexOf( + HeaderPrefix + "Version", + StringComparison.InvariantCulture + ); + NewVersionIndex = OldLine.IndexOf( + "Available" + HeaderSuffix, + StringComparison.InvariantCulture + ); + SourceIndex = OldLine.IndexOf( + HeaderPrefix + "Source", + StringComparison.InvariantCulture + ); DashesPassed = true; } else if (line.Trim() == "") { DashesPassed = false; } - else if (DashesPassed && IdIndex > 0 && VersionIndex > 0 && NewVersionIndex > 0 && IdIndex < VersionIndex && VersionIndex < NewVersionIndex && NewVersionIndex < line.Length) + else if ( + DashesPassed + && IdIndex > 0 + && VersionIndex > 0 + && NewVersionIndex > 0 + && IdIndex < VersionIndex + && VersionIndex < NewVersionIndex + && NewVersionIndex < line.Length + ) { int offset = 0; // Account for non-unicode character length while (line[IdIndex - offset - 1] != ' ' || offset > (IdIndex - 5)) @@ -119,7 +140,9 @@ public IReadOnlyList GetAvailableUpdates_UnSafe() } else { - Logger.Warn($"WinGet package {package.Id} not being shown as an updated as this version has already been marked as installed"); + Logger.Warn( + $"WinGet package {package.Id} not being shown as an updated as this version has already been marked as installed" + ); } } OldLine = line; @@ -140,21 +163,29 @@ public IReadOnlyList GetInstalledPackages_UnSafe() StartInfo = new() { FileName = WinGet.BundledWinGetPath, - Arguments = Manager.Status.ExecutableCallArgs + " list --accept-source-agreements " + WinGet.GetProxyArgument(), + Arguments = + Manager.Status.ExecutableCallArgs + + " list --accept-source-agreements " + + WinGet.GetProxyArgument(), RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true, - StandardOutputEncoding = Encoding.UTF8 - } + StandardOutputEncoding = Encoding.UTF8, + }, }; - IProcessTaskLogger logger = Manager.TaskLogger.CreateNew(LoggableTaskType.ListInstalledPackages, p); + IProcessTaskLogger logger = Manager.TaskLogger.CreateNew( + LoggableTaskType.ListInstalledPackages, + p + ); if (CoreTools.IsAdministrator()) { string WinGetTemp = Path.Join(Path.GetTempPath(), "UniGetUI", "ElevatedWinGetTemp"); - logger.AddToStdErr($"[WARN] Redirecting %TEMP% folder to {WinGetTemp}, since UniGetUI was run as admin"); + logger.AddToStdErr( + $"[WARN] Redirecting %TEMP% folder to {WinGetTemp}, since UniGetUI was run as admin" + ); p.StartInfo.Environment["TEMP"] = WinGetTemp; p.StartInfo.Environment["TMP"] = WinGetTemp; } @@ -177,16 +208,37 @@ public IReadOnlyList GetInstalledPackages_UnSafe() { string HeaderPrefix = OldLine.Contains("SearchId") ? "Search" : ""; string HeaderSuffix = OldLine.Contains("SearchId") ? "Header" : ""; - IdIndex = OldLine.IndexOf(HeaderPrefix + "Id", StringComparison.InvariantCulture); - VersionIndex = OldLine.IndexOf(HeaderPrefix + "Version", StringComparison.InvariantCulture); - NewVersionIndex = OldLine.IndexOf("Available" + HeaderSuffix, StringComparison.InvariantCulture); - SourceIndex = OldLine.IndexOf(HeaderPrefix + "Source", StringComparison.InvariantCulture); + IdIndex = OldLine.IndexOf( + HeaderPrefix + "Id", + StringComparison.InvariantCulture + ); + VersionIndex = OldLine.IndexOf( + HeaderPrefix + "Version", + StringComparison.InvariantCulture + ); + NewVersionIndex = OldLine.IndexOf( + "Available" + HeaderSuffix, + StringComparison.InvariantCulture + ); + SourceIndex = OldLine.IndexOf( + HeaderPrefix + "Source", + StringComparison.InvariantCulture + ); DashesPassed = true; } - else if (DashesPassed && IdIndex > 0 && VersionIndex > 0 && IdIndex < VersionIndex && VersionIndex < line.Length) + else if ( + DashesPassed + && IdIndex > 0 + && VersionIndex > 0 + && IdIndex < VersionIndex + && VersionIndex < line.Length + ) { int offset = 0; // Account for non-unicode character length - while (((IdIndex - offset) <= line.Length && line[IdIndex - offset - 1] != ' ') || offset > (IdIndex - 5)) + while ( + ((IdIndex - offset) <= line.Length && line[IdIndex - offset - 1] != ' ') + || offset > (IdIndex - 5) + ) { offset++; } @@ -202,7 +254,8 @@ public IReadOnlyList GetInstalledPackages_UnSafe() NewVersionIndex = line.Length - 1; } - string version = line[(VersionIndex - offset)..(NewVersionIndex - offset)].Trim(); + string version = line[(VersionIndex - offset)..(NewVersionIndex - offset)] + .Trim(); IManagerSource source; if (SourceIndex == -1 || (SourceIndex - offset) >= line.Length) @@ -211,7 +264,10 @@ public IReadOnlyList GetInstalledPackages_UnSafe() } else { - string sourceName = line[(SourceIndex - offset)..].Trim().Split(' ')[0].Trim(); + string sourceName = line[(SourceIndex - offset)..] + .Trim() + .Split(' ')[0] + .Trim(); source = Manager.SourcesHelper.Factory.GetSourceOrDefault(sourceName); } Packages.Add(new Package(name, id, version, source, Manager)); @@ -239,14 +295,18 @@ public IReadOnlyList FindPackages_UnSafe(string query) StartInfo = new() { FileName = WinGet.BundledWinGetPath, - Arguments = Manager.Status.ExecutableCallArgs + " search \"" + query + - "\" --accept-source-agreements " + WinGet.GetProxyArgument(), + Arguments = + Manager.Status.ExecutableCallArgs + + " search \"" + + query + + "\" --accept-source-agreements " + + WinGet.GetProxyArgument(), RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true, - StandardOutputEncoding = Encoding.UTF8 - } + StandardOutputEncoding = Encoding.UTF8, + }, }; IProcessTaskLogger logger = Manager.TaskLogger.CreateNew(LoggableTaskType.FindPackages, p); @@ -254,7 +314,9 @@ public IReadOnlyList FindPackages_UnSafe(string query) if (CoreTools.IsAdministrator()) { string WinGetTemp = Path.Join(Path.GetTempPath(), "UniGetUI", "ElevatedWinGetTemp"); - logger.AddToStdErr($"[WARN] Redirecting %TEMP% folder to {WinGetTemp}, since UniGetUI was run as admin"); + logger.AddToStdErr( + $"[WARN] Redirecting %TEMP% folder to {WinGetTemp}, since UniGetUI was run as admin" + ); p.StartInfo.Environment["TEMP"] = WinGetTemp; p.StartInfo.Environment["TMP"] = WinGetTemp; } @@ -274,11 +336,23 @@ public IReadOnlyList FindPackages_UnSafe(string query) { string HeaderPrefix = OldLine.Contains("SearchId") ? "Search" : ""; IdIndex = OldLine.IndexOf(HeaderPrefix + "Id", StringComparison.InvariantCulture); - VersionIndex = OldLine.IndexOf(HeaderPrefix + "Version", StringComparison.InvariantCulture); - SourceIndex = OldLine.IndexOf(HeaderPrefix + "Source", StringComparison.InvariantCulture); + VersionIndex = OldLine.IndexOf( + HeaderPrefix + "Version", + StringComparison.InvariantCulture + ); + SourceIndex = OldLine.IndexOf( + HeaderPrefix + "Source", + StringComparison.InvariantCulture + ); DashesPassed = true; } - else if (DashesPassed && IdIndex > 0 && VersionIndex > 0 && IdIndex < VersionIndex && VersionIndex < line.Length) + else if ( + DashesPassed + && IdIndex > 0 + && VersionIndex > 0 + && IdIndex < VersionIndex + && VersionIndex < line.Length + ) { int offset = 0; // Account for non-unicode character length while (line[IdIndex - offset - 1] != ' ' || offset > (IdIndex - 5)) @@ -315,18 +389,25 @@ public void GetPackageDetails_UnSafe(IPackageDetails details) { if (details.Package.Source.Name == "winget") { - details.ManifestUrl = new Uri("https://github.com/microsoft/winget-pkgs/tree/master/manifests/" - + details.Package.Id[0].ToString().ToLower() + "/" - + details.Package.Id.Split('.')[0] + "/" - + string.Join("/", - details.Package.Id.Contains('.') - ? details.Package.Id.Split('.')[1..] - : details.Package.Id.Split('.')) + details.ManifestUrl = new Uri( + "https://github.com/microsoft/winget-pkgs/tree/master/manifests/" + + details.Package.Id[0].ToString().ToLower() + + "/" + + details.Package.Id.Split('.')[0] + + "/" + + string.Join( + "/", + details.Package.Id.Contains('.') + ? details.Package.Id.Split('.')[1..] + : details.Package.Id.Split('.') + ) ); } else if (details.Package.Source.Name == "msstore") { - details.ManifestUrl = new Uri("https://apps.microsoft.com/detail/" + details.Package.Id); + details.ManifestUrl = new Uri( + "https://apps.microsoft.com/detail/" + details.Package.Id + ); } // Get the output for the best matching locale @@ -337,22 +418,29 @@ public void GetPackageDetails_UnSafe(IPackageDetails details) ProcessStartInfo startInfo = new() { FileName = WinGet.BundledWinGetPath, - Arguments = Manager.Status.ExecutableCallArgs + " show " + WinGetPkgOperationHelper.GetIdNamePiece(details.Package) + - " --disable-interactivity --accept-source-agreements --locale " + - System.Globalization.CultureInfo.CurrentCulture + " " + WinGet.GetProxyArgument(), + Arguments = + Manager.Status.ExecutableCallArgs + + " show " + + WinGetPkgOperationHelper.GetIdNamePiece(details.Package) + + " --disable-interactivity --accept-source-agreements --locale " + + System.Globalization.CultureInfo.CurrentCulture + + " " + + WinGet.GetProxyArgument(), RedirectStandardOutput = true, RedirectStandardError = true, RedirectStandardInput = true, UseShellExecute = false, CreateNoWindow = true, - StandardOutputEncoding = Encoding.UTF8 + StandardOutputEncoding = Encoding.UTF8, }; process.StartInfo = startInfo; if (CoreTools.IsAdministrator()) { string WinGetTemp = Path.Join(Path.GetTempPath(), "UniGetUI", "ElevatedWinGetTemp"); - Logger.Warn($"[WARN] Redirecting %TEMP% folder to {WinGetTemp}, since UniGetUI was run as admin"); + Logger.Warn( + $"[WARN] Redirecting %TEMP% folder to {WinGetTemp}, since UniGetUI was run as admin" + ); process.StartInfo.Environment["TEMP"] = WinGetTemp; process.StartInfo.Environment["TMP"] = WinGetTemp; } @@ -365,8 +453,12 @@ public void GetPackageDetails_UnSafe(IPackageDetails details) if (_line.Trim() != "") { output.Add(_line); - if (_line.Contains("The value provided for the `locale` argument is invalid") || - _line.Contains("No applicable installer found; see Logger.Logs for more details.")) + if ( + _line.Contains("The value provided for the `locale` argument is invalid") + || _line.Contains( + "No applicable installer found; see Logger.Logs for more details." + ) + ) { LocaleFound = false; break; @@ -378,27 +470,39 @@ public void GetPackageDetails_UnSafe(IPackageDetails details) if (!LocaleFound) { output.Clear(); - Logger.Info("Winget could not found culture data for package Id=" + details.Package.Id + " and Culture=" + - System.Globalization.CultureInfo.CurrentCulture + ". Trying to get data for en-US"); + Logger.Info( + "Winget could not found culture data for package Id=" + + details.Package.Id + + " and Culture=" + + System.Globalization.CultureInfo.CurrentCulture + + ". Trying to get data for en-US" + ); process = new Process(); LocaleFound = true; startInfo = new() { FileName = WinGet.BundledWinGetPath, - Arguments = Manager.Status.ExecutableCallArgs + " show " + WinGetPkgOperationHelper.GetIdNamePiece(details.Package) + - " --disable-interactivity --accept-source-agreements --locale en-US " + " " + WinGet.GetProxyArgument(), + Arguments = + Manager.Status.ExecutableCallArgs + + " show " + + WinGetPkgOperationHelper.GetIdNamePiece(details.Package) + + " --disable-interactivity --accept-source-agreements --locale en-US " + + " " + + WinGet.GetProxyArgument(), RedirectStandardOutput = true, RedirectStandardError = true, RedirectStandardInput = true, UseShellExecute = false, CreateNoWindow = true, - StandardOutputEncoding = Encoding.UTF8 + StandardOutputEncoding = Encoding.UTF8, }; process.StartInfo = startInfo; if (CoreTools.IsAdministrator()) { string WinGetTemp = Path.Join(Path.GetTempPath(), "UniGetUI", "ElevatedWinGetTemp"); - Logger.Warn($"[WARN] Redirecting %TEMP% folder to {WinGetTemp}, since UniGetUI was run as admin"); + Logger.Warn( + $"[WARN] Redirecting %TEMP% folder to {WinGetTemp}, since UniGetUI was run as admin" + ); process.StartInfo.Environment["TEMP"] = WinGetTemp; process.StartInfo.Environment["TMP"] = WinGetTemp; } @@ -409,8 +513,12 @@ public void GetPackageDetails_UnSafe(IPackageDetails details) if (_line.Trim() != "") { output.Add(_line); - if (_line.Contains("The value provided for the `locale` argument is invalid") || - _line.Contains("No applicable installer found; see Logger.Logs for more details.")) + if ( + _line.Contains("The value provided for the `locale` argument is invalid") + || _line.Contains( + "No applicable installer found; see Logger.Logs for more details." + ) + ) { LocaleFound = false; break; @@ -423,26 +531,36 @@ public void GetPackageDetails_UnSafe(IPackageDetails details) if (!LocaleFound) { output.Clear(); - Logger.Info("Winget could not found culture data for package Id=" + details.Package.Id + - " and Culture=en-US. Loading default"); + Logger.Info( + "Winget could not found culture data for package Id=" + + details.Package.Id + + " and Culture=en-US. Loading default" + ); process = new Process(); startInfo = new() { FileName = WinGet.BundledWinGetPath, - Arguments = Manager.Status.ExecutableCallArgs + " show " + WinGetPkgOperationHelper.GetIdNamePiece(details.Package) + - " --disable-interactivity --accept-source-agreements " + " " + WinGet.GetProxyArgument(), + Arguments = + Manager.Status.ExecutableCallArgs + + " show " + + WinGetPkgOperationHelper.GetIdNamePiece(details.Package) + + " --disable-interactivity --accept-source-agreements " + + " " + + WinGet.GetProxyArgument(), RedirectStandardOutput = true, RedirectStandardError = true, RedirectStandardInput = true, UseShellExecute = false, CreateNoWindow = true, - StandardOutputEncoding = Encoding.UTF8 + StandardOutputEncoding = Encoding.UTF8, }; process.StartInfo = startInfo; if (CoreTools.IsAdministrator()) { string WinGetTemp = Path.Join(Path.GetTempPath(), "UniGetUI", "ElevatedWinGetTemp"); - Logger.Warn($"[WARN] Redirecting %TEMP% folder to {WinGetTemp}, since UniGetUI was run as admin"); + Logger.Warn( + $"[WARN] Redirecting %TEMP% folder to {WinGetTemp}, since UniGetUI was run as admin" + ); process.StartInfo.Environment["TEMP"] = WinGetTemp; process.StartInfo.Environment["TMP"] = WinGetTemp; } @@ -489,14 +607,15 @@ public void GetPackageDetails_UnSafe(IPackageDetails details) else if (line.StartsWith(" ") && IsCapturingDependencies) { line = line.Trim(); - details.Dependencies.Add(new() - { - Name = line.Split(' ')[0], - Version = line.Contains('[') ? line.Split('[')[1].TrimEnd(']'): "", - Mandatory = true - }); + details.Dependencies.Add( + new() + { + Name = line.Split(' ')[0], + Version = line.Contains('[') ? line.Split('[')[1].TrimEnd(']') : "", + Mandatory = true, + } + ); } - // Stop loading multiline fields else if (IsLoadingDescription) { @@ -551,7 +670,9 @@ public void GetPackageDetails_UnSafe(IPackageDetails details) } else if (line.Contains("Release Notes Url:")) { - details.ReleaseNotesUrl = new Uri(line.Replace("Release Notes Url:", "").Trim()); + details.ReleaseNotesUrl = new Uri( + line.Replace("Release Notes Url:", "").Trim() + ); } else if (line.Contains("Installer Type:")) { @@ -594,22 +715,32 @@ public IReadOnlyList GetInstallableVersions_Unsafe(IPackage package) StartInfo = new ProcessStartInfo { FileName = WinGet.BundledWinGetPath, - Arguments = Manager.Status.ExecutableCallArgs + " show " + WinGetPkgOperationHelper.GetIdNamePiece(package) + - $" --versions --accept-source-agreements " + " " + WinGet.GetProxyArgument(), + Arguments = + Manager.Status.ExecutableCallArgs + + " show " + + WinGetPkgOperationHelper.GetIdNamePiece(package) + + $" --versions --accept-source-agreements " + + " " + + WinGet.GetProxyArgument(), UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, RedirectStandardInput = true, CreateNoWindow = true, - StandardOutputEncoding = Encoding.UTF8 - } + StandardOutputEncoding = Encoding.UTF8, + }, }; - IProcessTaskLogger logger = Manager.TaskLogger.CreateNew(LoggableTaskType.LoadPackageVersions, p); + IProcessTaskLogger logger = Manager.TaskLogger.CreateNew( + LoggableTaskType.LoadPackageVersions, + p + ); if (CoreTools.IsAdministrator()) { string WinGetTemp = Path.Join(Path.GetTempPath(), "UniGetUI", "ElevatedWinGetTemp"); - Logger.Warn($"[WARN] Redirecting %TEMP% folder to {WinGetTemp}, since UniGetUI was run as admin"); + Logger.Warn( + $"[WARN] Redirecting %TEMP% folder to {WinGetTemp}, since UniGetUI was run as admin" + ); p.StartInfo.Environment["TEMP"] = WinGetTemp; p.StartInfo.Environment["TMP"] = WinGetTemp; } @@ -649,21 +780,24 @@ public IReadOnlyList GetSources_UnSafe() StartInfo = new() { FileName = Manager.Status.ExecutablePath, - Arguments = Manager.Status.ExecutableCallArgs + " source list " + WinGet.GetProxyArgument(), + Arguments = + Manager.Status.ExecutableCallArgs + " source list " + WinGet.GetProxyArgument(), RedirectStandardOutput = true, RedirectStandardError = true, RedirectStandardInput = true, UseShellExecute = false, CreateNoWindow = true, - StandardOutputEncoding = Encoding.UTF8 - } + StandardOutputEncoding = Encoding.UTF8, + }, }; IProcessTaskLogger logger = Manager.TaskLogger.CreateNew(LoggableTaskType.FindPackages, p); if (CoreTools.IsAdministrator()) { string WinGetTemp = Path.Join(Path.GetTempPath(), "UniGetUI", "ElevatedWinGetTemp"); - Logger.Warn($"[WARN] Redirecting %TEMP% folder to {WinGetTemp}, since UniGetUI was run as admin"); + Logger.Warn( + $"[WARN] Redirecting %TEMP% folder to {WinGetTemp}, since UniGetUI was run as admin" + ); p.StartInfo.Environment["TEMP"] = WinGetTemp; p.StartInfo.Environment["TMP"] = WinGetTemp; } @@ -693,7 +827,9 @@ public IReadOnlyList GetSources_UnSafe() string[] parts = Regex.Replace(line.Trim(), " {2,}", " ").Split(' '); if (parts.Length > 1) { - sources.Add(new ManagerSource(Manager, parts[0].Trim(), new Uri(parts[1].Trim()))); + sources.Add( + new ManagerSource(Manager, parts[0].Trim(), new Uri(parts[1].Trim())) + ); } } } @@ -707,6 +843,5 @@ public IReadOnlyList GetSources_UnSafe() p.WaitForExit(); logger.Close(p.ExitCode); return sources; - } } diff --git a/src/UniGetUI.PackageEngine.Managers.WinGet/ClientHelpers/NativePackageHandler.cs b/src/UniGetUI.PackageEngine.Managers.WinGet/ClientHelpers/NativePackageHandler.cs index 5a9f76f487..cc04985058 100644 --- a/src/UniGetUI.PackageEngine.Managers.WinGet/ClientHelpers/NativePackageHandler.cs +++ b/src/UniGetUI.PackageEngine.Managers.WinGet/ClientHelpers/NativePackageHandler.cs @@ -10,9 +10,12 @@ namespace UniGetUI.PackageEngine.Managers.WingetManager; public static class NativePackageHandler { private static readonly ConcurrentDictionary __nativePackages = new(); - private static readonly ConcurrentDictionary __nativeDetails = new(); - private static ConcurrentDictionary __nativeInstallers_Install = new(); - private static ConcurrentDictionary __nativeInstallers_Uninstall = new(); + private static readonly ConcurrentDictionary __nativeDetails = + new(); + private static ConcurrentDictionary __nativeInstallers_Install = + new(); + private static ConcurrentDictionary __nativeInstallers_Uninstall = + new(); /// /// Get (cache or load) the native package for the given package, if any; @@ -20,7 +23,10 @@ public static class NativePackageHandler /// public static CatalogPackage? GetPackage(IPackage package) { - if (NativeWinGetHelper.ExternalFactory is null || NativeWinGetHelper.ExternalWinGetManager is null) + if ( + NativeWinGetHelper.ExternalFactory is null + || NativeWinGetHelper.ExternalWinGetManager is null + ) return null; __nativePackages.TryGetValue(package.GetHash(), out CatalogPackage? catalogPackage); @@ -30,7 +36,8 @@ public static class NativePackageHandler // Rarely a package will not be available in cache (native WinGet helper should always call AddPackage) // so it makes no sense to add TaskRecycler.RunOrAttach() here. (Only imported packages may arrive at this point) catalogPackage = _findPackageOnCatalog(package); - if (catalogPackage is not null) AddPackage(package, catalogPackage); + if (catalogPackage is not null) + AddPackage(package, (CatalogPackage)catalogPackage); return catalogPackage; } @@ -53,16 +60,21 @@ public static void AddPackage(IPackage package, CatalogPackage catalogPackage) { try { - if (__nativeDetails.TryGetValue(package.GetHash(), out CatalogPackageMetadata? metadata)) + if ( + __nativeDetails.TryGetValue(package.GetHash(), out CatalogPackageMetadata? metadata) + ) return metadata; CatalogPackage? catalogPackage = GetPackage(package); - if (catalogPackage is null) return null; + if (catalogPackage is null) + return null; var availableVersions = catalogPackage.AvailableVersions?.ToArray() ?? []; if (availableVersions.Length > 0) { - metadata = catalogPackage.GetPackageVersionInfo(availableVersions[0]).GetCatalogPackageMetadata(); + metadata = catalogPackage + .GetPackageVersionInfo(availableVersions[0]) + .GetCatalogPackageMetadata(); } if (metadata is not null) @@ -79,7 +91,11 @@ public static void AddPackage(IPackage package, CatalogPackage catalogPackage) /// /// Get (cached or load) the native installer for the given package, if any. The operation type determines wether /// - public static PackageInstallerInfo? GetInstallationOptions(IPackage package, InstallOptions unigetuiOptions, OperationType operation) + public static PackageInstallerInfo? GetInstallationOptions( + IPackage package, + InstallOptions unigetuiOptions, + OperationType operation + ) // => TaskRecycler.RunOrAttach(_getInstallationOptions, package, operation); // //private static PackageInstallerInfo? _getInstallationOptions(IPackage package, OperationType operation) @@ -89,9 +105,19 @@ public static void AddPackage(IPackage package, CatalogPackage catalogPackage) PackageInstallerInfo? installerInfo; if (operation is OperationType.Uninstall) - installerInfo = _getInstallationOptionsOnDict(package, ref __nativeInstallers_Uninstall, true, unigetuiOptions); + installerInfo = _getInstallationOptionsOnDict( + package, + ref __nativeInstallers_Uninstall, + true, + unigetuiOptions + ); else - installerInfo = _getInstallationOptionsOnDict(package, ref __nativeInstallers_Install, false, unigetuiOptions); + installerInfo = _getInstallationOptionsOnDict( + package, + ref __nativeInstallers_Install, + false, + unigetuiOptions + ); return installerInfo; } @@ -104,18 +130,26 @@ public static void Clear() __nativeInstallers_Uninstall.Clear(); } - private static PackageInstallerInfo? _getInstallationOptionsOnDict(IPackage package, - ref ConcurrentDictionary source, bool installed, InstallOptions unigetuiOptions) + private static PackageInstallerInfo? _getInstallationOptionsOnDict( + IPackage package, + ref ConcurrentDictionary source, + bool installed, + InstallOptions unigetuiOptions + ) { if (source.TryGetValue(package.GetHash(), out PackageInstallerInfo? installerInfo)) return installerInfo; PackageVersionInfo? catalogPackage; - if (installed) catalogPackage = GetPackage(package)?.InstalledVersion; - else catalogPackage = GetPackage(package)?.DefaultInstallVersion; + if (installed) + catalogPackage = GetPackage(package)?.InstalledVersion; + else + catalogPackage = GetPackage(package)?.DefaultInstallVersion; - Microsoft.Management.Deployment.InstallOptions? wingetOptions = NativeWinGetHelper.ExternalFactory?.CreateInstallOptions(); - Microsoft.Management.Deployment.InstallOptions? wingetDefaultOptions = NativeWinGetHelper.ExternalFactory?.CreateInstallOptions(); + Microsoft.Management.Deployment.InstallOptions? wingetOptions = + NativeWinGetHelper.ExternalFactory?.CreateInstallOptions(); + Microsoft.Management.Deployment.InstallOptions? wingetDefaultOptions = + NativeWinGetHelper.ExternalFactory?.CreateInstallOptions(); if (wingetOptions is null) { @@ -143,13 +177,19 @@ public static void Clear() private static CatalogPackage? _findPackageOnCatalog(IPackage package) { - if (NativeWinGetHelper.ExternalWinGetManager is null || NativeWinGetHelper.ExternalFactory is null) + if ( + NativeWinGetHelper.ExternalWinGetManager is null + || NativeWinGetHelper.ExternalFactory is null + ) return null; - PackageCatalogReference Catalog = NativeWinGetHelper.ExternalWinGetManager.GetPackageCatalogByName(package.Source.Name); + PackageCatalogReference Catalog = + NativeWinGetHelper.ExternalWinGetManager.GetPackageCatalogByName(package.Source.Name); if (Catalog is null) { - Logger.Error("Failed to get catalog " + package.Source.Name + ". Is the package local?"); + Logger.Error( + "Failed to get catalog " + package.Source.Name + ". Is the package local?" + ); return null; } @@ -163,19 +203,23 @@ public static void Clear() } // Match only the exact same Id - FindPackagesOptions packageMatchFilter = NativeWinGetHelper.ExternalFactory.CreateFindPackagesOptions(); + FindPackagesOptions packageMatchFilter = + NativeWinGetHelper.ExternalFactory.CreateFindPackagesOptions(); PackageMatchFilter filters = NativeWinGetHelper.ExternalFactory.CreatePackageMatchFilter(); filters.Field = PackageMatchField.Id; filters.Value = package.Id; filters.Option = PackageFieldMatchOption.Equals; packageMatchFilter.Filters.Add(filters); packageMatchFilter.ResultLimit = 1; - var SearchResult = Task.Run(() => ConnectResult.PackageCatalog.FindPackages(packageMatchFilter)); + var SearchResult = Task.Run(() => + ConnectResult.PackageCatalog.FindPackages(packageMatchFilter) + ); - if (SearchResult?.Result?.Matches is null || - SearchResult.Result.Matches.Count == 0) + if (SearchResult?.Result?.Matches is null || SearchResult.Result.Matches.Count == 0) { - Logger.Error("Failed to find package " + package.Id + " in catalog " + package.Source.Name); + Logger.Error( + "Failed to find package " + package.Id + " in catalog " + package.Source.Name + ); return null; } diff --git a/src/UniGetUI.PackageEngine.Managers.WinGet/ClientHelpers/NativeWinGetHelper.cs b/src/UniGetUI.PackageEngine.Managers.WinGet/ClientHelpers/NativeWinGetHelper.cs index af91312158..dceb44ffbe 100644 --- a/src/UniGetUI.PackageEngine.Managers.WinGet/ClientHelpers/NativeWinGetHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.WinGet/ClientHelpers/NativeWinGetHelper.cs @@ -27,7 +27,9 @@ public NativeWinGetHelper(WinGet manager) Manager = manager; if (CoreTools.IsAdministrator()) { - Logger.Info("Running elevated, WinGet class registration is likely to fail unless using lower trust class registration is allowed in settings"); + Logger.Info( + "Running elevated, WinGet class registration is likely to fail unless using lower trust class registration is allowed in settings" + ); } try @@ -39,7 +41,9 @@ public NativeWinGetHelper(WinGet manager) } catch { - Logger.Warn("Couldn't connect to WinGet API, attempting to connect with lower trust... (Are you running as administrator?)"); + Logger.Warn( + "Couldn't connect to WinGet API, attempting to connect with lower trust... (Are you running as administrator?)" + ); Factory = new WindowsPackageManagerStandardFactory(allowLowerTrustRegistration: true); WinGetManager = Factory.CreatePackageManager(); ExternalFactory = Factory; @@ -51,11 +55,15 @@ public IReadOnlyList FindPackages_UnSafe(string query) { List packages = []; INativeTaskLogger logger = Manager.TaskLogger.CreateNew(LoggableTaskType.FindPackages); - Dictionary<(PackageCatalogReference, PackageMatchField), Task> FindPackageTasks = []; + Dictionary< + (PackageCatalogReference, PackageMatchField), + Task + > FindPackageTasks = []; // Load catalogs logger.Log("Loading available catalogs..."); - IReadOnlyList AvailableCatalogs = WinGetManager.GetPackageCatalogs(); + IReadOnlyList AvailableCatalogs = + WinGetManager.GetPackageCatalogs(); // Spawn Tasks to find packages on catalogs logger.Log("Spawning catalog fetching tasks..."); @@ -67,7 +75,14 @@ public IReadOnlyList FindPackages_UnSafe(string query) ConnectResult result = CatalogReference.Connect(); if (result.Status == ConnectResultStatus.Ok) { - foreach (var filter_type in new[] { PackageMatchField.Name, PackageMatchField.Id, PackageMatchField.Moniker }) + foreach ( + var filter_type in new[] + { + PackageMatchField.Name, + PackageMatchField.Id, + PackageMatchField.Moniker, + } + ) { FindPackagesOptions PackageFilters = Factory.CreateFindPackagesOptions(); @@ -82,26 +97,30 @@ public IReadOnlyList FindPackages_UnSafe(string query) try { // Create task and spawn it - Task task = new(() => result.PackageCatalog.FindPackages(PackageFilters)); + Task task = new(() => + result.PackageCatalog.FindPackages(PackageFilters) + ); task.Start(); // Add task to list - FindPackageTasks.Add( - (CatalogReference, filter_type), - task - ); + FindPackageTasks.Add((CatalogReference, filter_type), task); } catch (Exception e) { - logger.Error("WinGet: Catalog " + CatalogReference.Info.Name + - " failed to spawn FindPackages task."); + logger.Error( + "WinGet: Catalog " + + CatalogReference.Info.Name + + " failed to spawn FindPackages task." + ); logger.Error(e); } } } else { - logger.Error("WinGet: Catalog " + CatalogReference.Info.Name + " failed to connect."); + logger.Error( + "WinGet: Catalog " + CatalogReference.Info.Name + " failed to connect." + ); } } @@ -114,7 +133,9 @@ public IReadOnlyList FindPackages_UnSafe(string query) try { // Get the source for the catalog - IManagerSource source = Manager.SourcesHelper.Factory.GetSourceOrDefault(CatalogTaskPair.Key.Item1.Info.Name); + IManagerSource source = Manager.SourcesHelper.Factory.GetSourceOrDefault( + CatalogTaskPair.Key.Item1.Info.Name + ); FindPackagesResult FoundPackages = CatalogTaskPair.Value.Result; foreach (MatchResult matchResult in FoundPackages.Matches.ToArray()) @@ -122,7 +143,8 @@ public IReadOnlyList FindPackages_UnSafe(string query) CatalogPackage nativePackage = matchResult.CatalogPackage; // Create the Package item and add it to the list logger.Log( - $"Found package: {nativePackage.Name}|{nativePackage.Id}|{nativePackage.DefaultInstallVersion.Version} on catalog {source.Name}"); + $"Found package: {nativePackage.Name}|{nativePackage.Id}|{nativePackage.DefaultInstallVersion.Version} on catalog {source.Name}" + ); var overriden_options = new OverridenInstallationOptions(); @@ -132,15 +154,19 @@ public IReadOnlyList FindPackages_UnSafe(string query) nativePackage.DefaultInstallVersion.Version, source, Manager, - overriden_options); + overriden_options + ); NativePackageHandler.AddPackage(UniGetUIPackage, nativePackage); packages.Add(UniGetUIPackage); } } catch (Exception e) { - logger.Error("WinGet: Catalog " + CatalogTaskPair.Key.Item1.Info.Name + - " failed to get available packages."); + logger.Error( + "WinGet: Catalog " + + CatalogTaskPair.Key.Item1.Info.Name + + " failed to get available packages." + ); logger.Error(e); } } @@ -153,16 +179,22 @@ public IReadOnlyList GetAvailableUpdates_UnSafe() { var logger = Manager.TaskLogger.CreateNew(LoggableTaskType.ListUpdates); List packages = []; - foreach (var nativePackage in TaskRecycler>.RunOrAttach(GetLocalWinGetPackages)) + foreach ( + var nativePackage in TaskRecycler>.RunOrAttach( + GetLocalWinGetPackages + ) + ) { if (nativePackage.IsUpdateAvailable) { IManagerSource source; - source = Manager.SourcesHelper.Factory.GetSourceOrDefault(nativePackage.DefaultInstallVersion - .PackageCatalog.Info.Name); + source = Manager.SourcesHelper.Factory.GetSourceOrDefault( + nativePackage.DefaultInstallVersion.PackageCatalog.Info.Name + ); string version = nativePackage.InstalledVersion.Version; - if (version == "Unknown") version = WinGetPkgOperationHelper.GetLastInstalledVersion(nativePackage.Id); + if (version == "Unknown") + version = WinGetPkgOperationHelper.GetLastInstalledVersion(nativePackage.Id); var UniGetUIPackage = new Package( nativePackage.Name, @@ -170,38 +202,49 @@ public IReadOnlyList GetAvailableUpdates_UnSafe() version, nativePackage.DefaultInstallVersion.Version, source, - Manager); + Manager + ); if (!WinGetPkgOperationHelper.UpdateAlreadyInstalled(UniGetUIPackage)) { NativePackageHandler.AddPackage(UniGetUIPackage, nativePackage); packages.Add(UniGetUIPackage); - logger.Log($"Found package {nativePackage.Name} {nativePackage.Id} on source {source.Name}, from version {version} to version {nativePackage.DefaultInstallVersion.Version}"); + logger.Log( + $"Found package {nativePackage.Name} {nativePackage.Id} on source {source.Name}, from version {version} to version {nativePackage.DefaultInstallVersion.Version}" + ); } else { - Logger.Warn($"WinGet package {nativePackage.Id} not being shown as an updated as this version has already been marked as installed"); + Logger.Warn( + $"WinGet package {nativePackage.Id} not being shown as an updated as this version has already been marked as installed" + ); } } } logger.Close(0); return packages; - } public IReadOnlyList GetInstalledPackages_UnSafe() { var logger = Manager.TaskLogger.CreateNew(LoggableTaskType.ListInstalledPackages); List packages = []; - foreach (var nativePackage in TaskRecycler>.RunOrAttach(GetLocalWinGetPackages, 15)) + foreach ( + var nativePackage in TaskRecycler>.RunOrAttach( + GetLocalWinGetPackages, + 15 + ) + ) { IManagerSource source; var availableVersions = nativePackage.AvailableVersions?.ToArray() ?? []; if (availableVersions.Length > 0) { var installPackage = nativePackage.GetPackageVersionInfo(availableVersions[0]); - source = Manager.SourcesHelper.Factory.GetSourceOrDefault(installPackage.PackageCatalog.Info.Name); + source = Manager.SourcesHelper.Factory.GetSourceOrDefault( + installPackage.PackageCatalog.Info.Name + ); } else { @@ -209,15 +252,19 @@ public IReadOnlyList GetInstalledPackages_UnSafe() } string version = nativePackage.InstalledVersion.Version; - if (version == "Unknown") version = WinGetPkgOperationHelper.GetLastInstalledVersion(nativePackage.Id); + if (version == "Unknown") + version = WinGetPkgOperationHelper.GetLastInstalledVersion(nativePackage.Id); - logger.Log($"Found package {nativePackage.Name} {nativePackage.Id} on source {source.Name}"); + logger.Log( + $"Found package {nativePackage.Name} {nativePackage.Id} on source {source.Name}" + ); var UniGetUIPackage = new Package( nativePackage.Name, nativePackage.Id, version, source, - Manager); + Manager + ); NativePackageHandler.AddPackage(UniGetUIPackage, nativePackage); packages.Add(UniGetUIPackage); } @@ -230,14 +277,18 @@ private IReadOnlyList GetLocalWinGetPackages() var logger = Manager.TaskLogger.CreateNew(LoggableTaskType.OtherTask); logger.Log("OtherTask: GetWinGetLocalPackages"); PackageCatalogReference installedSearchCatalogRef; - CreateCompositePackageCatalogOptions createCompositePackageCatalogOptions = Factory.CreateCreateCompositePackageCatalogOptions(); + CreateCompositePackageCatalogOptions createCompositePackageCatalogOptions = + Factory.CreateCreateCompositePackageCatalogOptions(); foreach (var catalogRef in WinGetManager.GetPackageCatalogs().ToArray()) { logger.Log($"Adding catalog {catalogRef.Info.Name} to composite catalog"); createCompositePackageCatalogOptions.Catalogs.Add(catalogRef); } - createCompositePackageCatalogOptions.CompositeSearchBehavior = CompositeSearchBehavior.LocalCatalogs; - installedSearchCatalogRef = WinGetManager.CreateCompositePackageCatalog(createCompositePackageCatalogOptions); + createCompositePackageCatalogOptions.CompositeSearchBehavior = + CompositeSearchBehavior.LocalCatalogs; + installedSearchCatalogRef = WinGetManager.CreateCompositePackageCatalog( + createCompositePackageCatalogOptions + ); var ConnectResult = installedSearchCatalogRef.Connect(); if (ConnectResult.Status != ConnectResultStatus.Ok) @@ -274,12 +325,21 @@ public IReadOnlyList GetSources_UnSafe() { try { - logger.Log($"Found source {catalog.Info.Name} with argument {catalog.Info.Argument}"); - sources.Add(new ManagerSource( - Manager, - catalog.Info.Name, - new Uri(catalog.Info.Argument), - updateDate: (catalog.Info.LastUpdateTime.Second != 0 ? catalog.Info.LastUpdateTime : DateTime.Now).ToString())); + logger.Log( + $"Found source {catalog.Info.Name} with argument {catalog.Info.Argument}" + ); + sources.Add( + new ManagerSource( + Manager, + catalog.Info.Name, + new Uri(catalog.Info.Argument), + updateDate: ( + catalog.Info.LastUpdateTime.Second != 0 + ? catalog.Info.LastUpdateTime + : DateTime.Now + ).ToString() + ) + ); } catch (Exception e) { @@ -293,10 +353,13 @@ public IReadOnlyList GetSources_UnSafe() public IReadOnlyList GetInstallableVersions_Unsafe(IPackage package) { - INativeTaskLogger logger = Manager.TaskLogger.CreateNew(LoggableTaskType.LoadPackageVersions); + INativeTaskLogger logger = Manager.TaskLogger.CreateNew( + LoggableTaskType.LoadPackageVersions + ); var nativePackage = NativePackageHandler.GetPackage(package); - if (nativePackage is null) return []; + if (nativePackage is null) + return []; string[] versions = nativePackage.AvailableVersions.Select(x => x.Version).ToArray(); foreach (string? version in versions) @@ -310,26 +373,36 @@ public IReadOnlyList GetInstallableVersions_Unsafe(IPackage package) public void GetPackageDetails_UnSafe(IPackageDetails details) { - INativeTaskLogger logger = Manager.TaskLogger.CreateNew(LoggableTaskType.LoadPackageDetails); + INativeTaskLogger logger = Manager.TaskLogger.CreateNew( + LoggableTaskType.LoadPackageDetails + ); if (details.Package.Source.Name == "winget") { - details.ManifestUrl = new Uri("https://github.com/microsoft/winget-pkgs/tree/master/manifests/" - + details.Package.Id[0].ToString().ToLower() + "/" - + details.Package.Id.Split('.')[0] + "/" - + string.Join("/", - details.Package.Id.Contains('.') - ? details.Package.Id.Split('.')[1..] - : details.Package.Id.Split('.')) + details.ManifestUrl = new Uri( + "https://github.com/microsoft/winget-pkgs/tree/master/manifests/" + + details.Package.Id[0].ToString().ToLower() + + "/" + + details.Package.Id.Split('.')[0] + + "/" + + string.Join( + "/", + details.Package.Id.Contains('.') + ? details.Package.Id.Split('.')[1..] + : details.Package.Id.Split('.') + ) ); } else if (details.Package.Source.Name == "msstore") { - details.ManifestUrl = new Uri("https://apps.microsoft.com/detail/" + details.Package.Id); + details.ManifestUrl = new Uri( + "https://apps.microsoft.com/detail/" + details.Package.Id + ); } CatalogPackageMetadata? NativeDetails = NativePackageHandler.GetDetails(details.Package); - if (NativeDetails is null) return; + if (NativeDetails is null) + return; // Extract data from NativeDetails if (NativeDetails.Author != "") @@ -366,21 +439,26 @@ public void GetPackageDetails_UnSafe(IPackageDetails details) ProcessStartInfo startInfo = new() { FileName = WinGet.BundledWinGetPath, - Arguments = Manager.Status.ExecutableCallArgs + " show " + WinGetPkgOperationHelper.GetIdNamePiece(details.Package) + - " --disable-interactivity --accept-source-agreements --source " + - details.Package.Source.Name, + Arguments = + Manager.Status.ExecutableCallArgs + + " show " + + WinGetPkgOperationHelper.GetIdNamePiece(details.Package) + + " --disable-interactivity --accept-source-agreements --source " + + details.Package.Source.Name, RedirectStandardOutput = true, RedirectStandardError = true, RedirectStandardInput = true, UseShellExecute = false, CreateNoWindow = true, - StandardOutputEncoding = System.Text.Encoding.UTF8 + StandardOutputEncoding = System.Text.Encoding.UTF8, }; process.StartInfo = startInfo; if (CoreTools.IsAdministrator()) { string WinGetTemp = Path.Join(Path.GetTempPath(), "UniGetUI", "ElevatedWinGetTemp"); - Logger.Warn($"[WARN] Redirecting %TEMP% folder to {WinGetTemp}, since UniGetUI was run as admin"); + Logger.Warn( + $"[WARN] Redirecting %TEMP% folder to {WinGetTemp}, since UniGetUI was run as admin" + ); process.StartInfo.Environment["TEMP"] = WinGetTemp; process.StartInfo.Environment["TMP"] = WinGetTemp; } @@ -434,14 +512,17 @@ public void GetPackageDetails_UnSafe(IPackageDetails details) } else if (__line.Contains(" ") && capturingDependencies) { - details.Dependencies.Add(new() - { - Name = line.Split(' ')[0], - Version = line.Contains('[') ? line.Split('[')[1].TrimEnd(']'): "", - Mandatory = true - }); + details.Dependencies.Add( + new() + { + Name = line.Split(' ')[0], + Version = line.Contains('[') ? line.Split('[')[1].TrimEnd(']') : "", + Mandatory = true, + } + ); } - else if (!__line.Contains(" ")) capturingDependencies = false; + else if (!__line.Contains(" ")) + capturingDependencies = false; } catch (Exception e) { diff --git a/src/UniGetUI.PackageEngine.Managers.WinGet/ClientHelpers/WinGetIconsHelper.cs b/src/UniGetUI.PackageEngine.Managers.WinGet/ClientHelpers/WinGetIconsHelper.cs index 8523ac33c0..6c3082c5ad 100644 --- a/src/UniGetUI.PackageEngine.Managers.WinGet/ClientHelpers/WinGetIconsHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.WinGet/ClientHelpers/WinGetIconsHelper.cs @@ -9,6 +9,7 @@ using UniGetUI.PackageEngine.Managers.WingetManager; namespace UniGetUI.PackageEngine.Managers.WinGet.ClientHelpers; + internal static class WinGetIconsHelper { private static readonly Dictionary __msstore_package_manifests = []; @@ -20,7 +21,8 @@ internal static class WinGetIconsHelper string CountryCode = CultureInfo.CurrentCulture.Name.Split("-")[^1]; string Locale = CultureInfo.CurrentCulture.Name; - string url = $"https://storeedgefd.dsx.mp.microsoft.com/v8.0/sdk/products?market={CountryCode}&locale={Locale}&deviceFamily=Windows.Desktop"; + string url = + $"https://storeedgefd.dsx.mp.microsoft.com/v8.0/sdk/products?market={CountryCode}&locale={Locale}&deviceFamily=Windows.Desktop"; #pragma warning disable SYSLIB0014 var httpRequest = (HttpWebRequest)WebRequest.Create(url); @@ -75,11 +77,17 @@ internal static class WinGetIconsHelper if (!ImageEntry.Success) continue; - Match ImagePurpose = Regex.Match(CurrentImage, "(?:\"|')ImagePurpose(?:\"|'): ?(?:\"|')([^'\"]+)(?:\"|')"); + Match ImagePurpose = Regex.Match( + CurrentImage, + "(?:\"|')ImagePurpose(?:\"|'): ?(?:\"|')([^'\"]+)(?:\"|')" + ); if (!ImagePurpose.Success || ImagePurpose.Groups[1].Value != "Tile") continue; - Match ImageUrl = Regex.Match(CurrentImage, "(?:\"|')Uri(?:\"|'): ?(?:\"|')([^'\"]+)(?:\"|')"); + Match ImageUrl = Regex.Match( + CurrentImage, + "(?:\"|')Uri(?:\"|'): ?(?:\"|')([^'\"]+)(?:\"|')" + ); Match ImageSize = Regex.Match(CurrentImage, "(?:\"|')Height(?:\"|'): ?([^,]+)"); if (!ImageUrl.Success || !ImageSize.Success) @@ -90,11 +98,19 @@ internal static class WinGetIconsHelper if (FoundIcons.Count == 0) { - Logger.Warn($"No Logo image found for package {package.Id} in Microsoft Store response"); + Logger.Warn( + $"No Logo image found for package {package.Id} in Microsoft Store response" + ); return null; } - Logger.Debug("Choosing icon with size " + FoundIcons.Keys.Max() + " for package " + package.Id + " from Microsoft Store"); + Logger.Debug( + "Choosing icon with size " + + FoundIcons.Keys.Max() + + " for package " + + package.Id + + " from Microsoft Store" + ); string uri = "https:" + FoundIcons[FoundIcons.Keys.Max()]; @@ -104,7 +120,8 @@ internal static class WinGetIconsHelper public static CacheableIcon? GetWinGetPackageIcon(IPackage package) { CatalogPackageMetadata? NativeDetails = NativePackageHandler.GetDetails(package); - if (NativeDetails is null) return null; + if (NativeDetails is null) + return null; // Get the actual icon and return it foreach (Icon? icon in NativeDetails.Icons.ToArray()) @@ -119,10 +136,18 @@ internal static class WinGetIconsHelper public static CacheableIcon? GetAppxPackageIcon(IPackage package) { string appxId = package.Id.Replace("MSIX\\", ""); - string globalPath = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "WindowsApps", appxId); + string globalPath = Path.Join( + Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), + "WindowsApps", + appxId + ); if (!Directory.Exists(globalPath)) - globalPath = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "SystemApps", appxId); + globalPath = Path.Join( + Environment.GetFolderPath(Environment.SpecialFolder.Windows), + "SystemApps", + appxId + ); if (!Directory.Exists(globalPath)) return null; @@ -135,9 +160,21 @@ internal static class WinGetIconsHelper return null; } - string path = string.Join('.', Path.Join(globalPath, match.Groups[1].ToString()).Split('.')[..^1]); - foreach (string ending in new[] { ".png", ".scale-100.png", ".scale-125.png", ".scale-150.png", - ".scale-175.png", ".scale-200.png" }) + string path = string.Join( + '.', + Path.Join(globalPath, match.Groups[1].ToString()).Split('.')[..^1] + ); + foreach ( + string ending in new[] + { + ".png", + ".scale-100.png", + ".scale-125.png", + ".scale-150.png", + ".scale-175.png", + ".scale-200.png", + } + ) if (Path.Exists(path + ending)) { return new CacheableIcon(path + ending); @@ -149,7 +186,8 @@ internal static class WinGetIconsHelper public static CacheableIcon? GetARPPackageIcon(IPackage package) { var bits = package.Id.Split("\\"); - if (bits.Length < 4) return null; + if (bits.Length < 4) + return null; string regKey = ""; regKey += bits[1] == "Machine" ? "HKEY_LOCAL_MACHINE" : "HKEY_CURRENT_USER"; @@ -161,7 +199,11 @@ internal static class WinGetIconsHelper regKey += bits[3]; string? displayIcon = (string?)Registry.GetValue(regKey, "DisplayIcon", null); - if (!string.IsNullOrEmpty(displayIcon) && File.Exists(displayIcon) && !displayIcon.EndsWith(".exe")) + if ( + !string.IsNullOrEmpty(displayIcon) + && File.Exists(displayIcon) + && !displayIcon.EndsWith(".exe") + ) return new CacheableIcon(displayIcon); return null; diff --git a/src/UniGetUI.PackageEngine.Managers.WinGet/Helpers/WinGetPkgDetailsHelper.cs b/src/UniGetUI.PackageEngine.Managers.WinGet/Helpers/WinGetPkgDetailsHelper.cs index 71ee33ab9d..2d503a8ead 100644 --- a/src/UniGetUI.PackageEngine.Managers.WinGet/Helpers/WinGetPkgDetailsHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.WinGet/Helpers/WinGetPkgDetailsHelper.cs @@ -9,7 +9,8 @@ namespace UniGetUI.PackageEngine.Managers.WingetManager { internal sealed class WinGetPkgDetailsHelper : BasePkgDetailsHelper { - public WinGetPkgDetailsHelper(WinGet manager) : base(manager) { } + public WinGetPkgDetailsHelper(WinGet manager) + : base(manager) { } protected override IReadOnlyList GetInstallableVersions_UnSafe(IPackage package) { @@ -25,11 +26,10 @@ protected override void GetDetails_UnSafe(IPackageDetails details) { if (package.Source is LocalWinGetSource localSource) { - if(localSource.Type is LocalWinGetSource.Type_t.MicrosftStore) + if (localSource.Type is LocalWinGetSource.Type_t.MicrosftStore) return WinGetIconsHelper.GetAppxPackageIcon(package); - else if (localSource.Type is LocalWinGetSource.Type_t.LocalPC) - return WinGetIconsHelper.GetARPPackageIcon(package); + return WinGetIconsHelper.GetARPPackageIcon(package); return null; } @@ -42,25 +42,46 @@ protected override void GetDetails_UnSafe(IPackageDetails details) protected override string? GetInstallLocation_UnSafe(IPackage package) { - foreach (var base_path in new[] - { - Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), - Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), - Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Programs"), - Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Microsoft", "WinGet", "Packages"), - Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "WinGet", "Packages"), - Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.Programs), "WinGet", "Packages"), - Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), - }) + foreach ( + var base_path in new[] + { + Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), + Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), + Path.Join( + Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), + "Programs" + ), + Path.Join( + Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), + "Microsoft", + "WinGet", + "Packages" + ), + Path.Join( + Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), + "WinGet", + "Packages" + ), + Path.Join( + Environment.GetFolderPath(Environment.SpecialFolder.Programs), + "WinGet", + "Packages" + ), + Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), + } + ) { var path_with_name = Path.Join(base_path, package.Name); - if (Directory.Exists(path_with_name)) return path_with_name; + if (Directory.Exists(path_with_name)) + return path_with_name; var path_with_id = Path.Join(base_path, package.Id); - if (Directory.Exists(path_with_id)) return path_with_id; + if (Directory.Exists(path_with_id)) + return path_with_id; var path_with_source = Path.Join(base_path, $"{package.Id}_{package.Source.Name}"); - if (Directory.Exists(path_with_source)) return path_with_source; + if (Directory.Exists(path_with_source)) + return path_with_source; } return null; @@ -79,7 +100,10 @@ protected override IReadOnlyList GetScreenshots_UnSafe(IPackage package) return []; } - Match IconArray = Regex.Match(ResponseContent, "(?:\"|')Images(?:\"|'): ?\\[([^\\]]+)\\]"); + Match IconArray = Regex.Match( + ResponseContent, + "(?:\"|')Images(?:\"|'): ?\\[([^\\]]+)\\]" + ); if (!IconArray.Success) { Logger.Warn("Could not parse Images array from Microsoft Store response"); @@ -90,19 +114,24 @@ protected override IReadOnlyList GetScreenshots_UnSafe(IPackage package) foreach (Match ImageEntry in Regex.Matches(IconArray.Groups[1].Value, "{([^}]+)}")) { - if (!ImageEntry.Success) { continue; } - Match ImagePurpose = Regex.Match(ImageEntry.Groups[1].Value, "(?:\"|')ImagePurpose(?:\"|'): ?(?:\"|')([^'\"]+)(?:\"|')"); + Match ImagePurpose = Regex.Match( + ImageEntry.Groups[1].Value, + "(?:\"|')ImagePurpose(?:\"|'): ?(?:\"|')([^'\"]+)(?:\"|')" + ); if (!ImagePurpose.Success || ImagePurpose.Groups[1].Value != "Screenshot") { continue; } - Match ImageUrl = Regex.Match(ImageEntry.Groups[1].Value, "(?:\"|')Uri(?:\"|'): ?(?:\"|')([^'\"]+)(?:\"|')"); + Match ImageUrl = Regex.Match( + ImageEntry.Groups[1].Value, + "(?:\"|')Uri(?:\"|'): ?(?:\"|')([^'\"]+)(?:\"|')" + ); if (!ImageUrl.Success) { continue; @@ -113,6 +142,5 @@ protected override IReadOnlyList GetScreenshots_UnSafe(IPackage package) return FoundIcons; } - } } diff --git a/src/UniGetUI.PackageEngine.Managers.WinGet/Helpers/WinGetPkgOperationHelper.cs b/src/UniGetUI.PackageEngine.Managers.WinGet/Helpers/WinGetPkgOperationHelper.cs index a58dbb903e..9408712f35 100644 --- a/src/UniGetUI.PackageEngine.Managers.WinGet/Helpers/WinGetPkgOperationHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.WinGet/Helpers/WinGetPkgOperationHelper.cs @@ -11,6 +11,7 @@ using InstallOptions = UniGetUI.PackageEngine.Serializable.InstallOptions; namespace UniGetUI.PackageEngine.Managers.WingetManager; + internal sealed class WinGetPkgOperationHelper : BasePkgOperationHelper { public static string GetIdNamePiece(IPackage package) @@ -24,30 +25,48 @@ public static string GetIdNamePiece(IPackage package) return $"--id \"{package.Id.TrimEnd('…')}\""; } - public WinGetPkgOperationHelper(WinGet manager) : base(manager) { } + public WinGetPkgOperationHelper(WinGet manager) + : base(manager) { } - protected override IReadOnlyList _getOperationParameters(IPackage package, - InstallOptions options, OperationType operation) + protected override IReadOnlyList _getOperationParameters( + IPackage package, + InstallOptions options, + OperationType operation + ) { - List parameters = [operation switch { - OperationType.Install => Manager.Properties.InstallVerb, - OperationType.Update => Manager.Properties.UpdateVerb, - OperationType.Uninstall => Manager.Properties.UninstallVerb, - _ => throw new InvalidDataException("Invalid package operation") - }]; + List parameters = + [ + operation switch + { + OperationType.Install => Manager.Properties.InstallVerb, + OperationType.Update => Manager.Properties.UpdateVerb, + OperationType.Uninstall => Manager.Properties.UninstallVerb, + _ => throw new InvalidDataException("Invalid package operation"), + }, + ]; parameters.AddRange(GetIdNamePiece(package).Split(" ")); - parameters.AddRange(["--source", package.Source.IsVirtualManager ? "winget" : package.Source.Name]); + parameters.AddRange([ + "--source", + package.Source.IsVirtualManager ? "winget" : package.Source.Name, + ]); parameters.AddRange(["--accept-source-agreements", "--disable-interactivity"]); // package.OverridenInstallationOptions.Scope is meaningless in WinGet packages. Default is unspecified, hence the _ => []. - parameters.AddRange((package.OverridenOptions.Scope ?? options.InstallationScope) switch { - PackageScope.User => ["--scope", "user"], - PackageScope.Machine => ["--scope", "machine"], - _ => [] - }); + parameters.AddRange( + (package.OverridenOptions.Scope ?? options.InstallationScope) switch + { + PackageScope.User => ["--scope", "user"], + PackageScope.Machine => ["--scope", "machine"], + _ => [], + } + ); - if (operation is OperationType.Uninstall && package.VersionString != "Unknown" && package.OverridenOptions.WinGet_SpecifyVersion is not false) + if ( + operation is OperationType.Uninstall + && package.VersionString != "Unknown" + && package.OverridenOptions.WinGet_SpecifyVersion is not false + ) { parameters.AddRange(["--version", $"\"{package.VersionString}\""]); } @@ -70,7 +89,10 @@ protected override IReadOnlyList _getOperationParameters(IPackage packag } parameters.Add("--include-unknown"); - if(Settings.Get(Settings.K.WinGetForceLocationOnUpdate) && options.CustomInstallLocation != "") + if ( + Settings.Get(Settings.K.WinGetForceLocationOnUpdate) + && options.CustomInstallLocation != "" + ) parameters.AddRange(["--location", $"\"{options.CustomInstallLocation}\""]); } else if (operation is OperationType.Install) @@ -86,46 +108,75 @@ protected override IReadOnlyList _getOperationParameters(IPackage packag if (options.SkipHashCheck) parameters.Add("--ignore-security-hash"); - parameters.AddRange(options.Architecture switch - { - Architecture.x86 => ["--architecture", "x86"], - Architecture.x64 => ["--architecture", "x64"], - Architecture.arm64 => ["--architecture", "arm64"], - _ => [] - }); + parameters.AddRange( + options.Architecture switch + { + Architecture.x86 => ["--architecture", "x86"], + Architecture.x64 => ["--architecture", "x64"], + Architecture.arm64 => ["--architecture", "arm64"], + _ => [], + } + ); } try { - var installOptions = NativePackageHandler.GetInstallationOptions(package, options, operation); - if (installOptions?.ElevationRequirement is ElevationRequirement.ElevationRequired or ElevationRequirement.ElevatesSelf) + var installOptions = NativePackageHandler.GetInstallationOptions( + package, + options, + operation + ); + if ( + installOptions?.ElevationRequirement + is ElevationRequirement.ElevationRequired + or ElevationRequirement.ElevatesSelf + ) { - Logger.Info($"WinGet package {package.Id} requires elevation, forcing administrator rights..."); + Logger.Info( + $"WinGet package {package.Id} requires elevation, forcing administrator rights..." + ); package.OverridenOptions.RunAsAdministrator = true; } - else if (installOptions?.ElevationRequirement is ElevationRequirement.ElevationProhibited) + else if ( + installOptions?.ElevationRequirement is ElevationRequirement.ElevationProhibited + ) { if (CoreTools.IsAdministrator()) throw new UnauthorizedAccessException( - CoreTools.Translate("This package cannot be installed from an elevated context.") - + CoreTools.Translate("Please run UniGetUI as a regular user and try again.")); + CoreTools.Translate( + "This package cannot be installed from an elevated context." + ) + + CoreTools.Translate( + "Please run UniGetUI as a regular user and try again." + ) + ); if (options.RunAsAdministrator) throw new UnauthorizedAccessException( - CoreTools.Translate("This package cannot be installed from an elevated context.") - + CoreTools.Translate("Please check the installation options for this package and try again")); + CoreTools.Translate( + "This package cannot be installed from an elevated context." + ) + + CoreTools.Translate( + "Please check the installation options for this package and try again" + ) + ); package.OverridenOptions.RunAsAdministrator = false; } - else if(installOptions?.Scope is PackageInstallerScope.System/* or PackageInstallerScope.Unknown*/) + else if ( + installOptions?.Scope is PackageInstallerScope.System /* or PackageInstallerScope.Unknown*/ + ) { - Logger.Info($"WinGet package {package.Id} is installed on a system-wide scope, forcing administrator rights..."); + Logger.Info( + $"WinGet package {package.Id} is installed on a system-wide scope, forcing administrator rights..." + ); package.OverridenOptions.RunAsAdministrator = true; } } catch (Exception ex) { - if (ex is UnauthorizedAccessException) throw; + if (ex is UnauthorizedAccessException) + throw; Logger.Error("Recovered from fatal WinGet exception:"); Logger.Error(ex); @@ -133,12 +184,14 @@ protected override IReadOnlyList _getOperationParameters(IPackage packag parameters.Add(WinGet.GetProxyArgument()); - parameters.AddRange(operation switch - { - OperationType.Update => options.CustomParameters_Update, - OperationType.Uninstall => options.CustomParameters_Uninstall, - _ => options.CustomParameters_Install, - }); + parameters.AddRange( + operation switch + { + OperationType.Update => options.CustomParameters_Update, + OperationType.Uninstall => options.CustomParameters_Uninstall, + _ => options.CustomParameters_Install, + } + ); return parameters; } @@ -146,30 +199,36 @@ protected override OperationVeredict _getOperationResult( IPackage package, OperationType operation, IReadOnlyList processOutput, - int returnCode) + int returnCode + ) { // See https://github.com/microsoft/winget-cli/blob/master/doc/windows/package-manager/winget/returnCodes.md for reference uint uintCode = (uint)returnCode; if (uintCode is 0x8A150109) - { // TODO: Restart required to finish installation - if (operation is OperationType.Update or OperationType.Install) MarkUpgradeAsDone(package); + { // TODO: Restart required to finish installation + if (operation is OperationType.Update or OperationType.Install) + MarkUpgradeAsDone(package); return OperationVeredict.Success; } if (uintCode is 0x8A150077 or 0x8A15010C or 0x8A150005) - { // At some point, the user clicked cancel or Ctrl+C + { // At some point, the user clicked cancel or Ctrl+C return OperationVeredict.Canceled; } - if (operation is OperationType.Uninstall && uintCode is 0x8A150017 && package.OverridenOptions.WinGet_SpecifyVersion is not false) - { // No manifest found matching criteria + if ( + operation is OperationType.Uninstall + && uintCode is 0x8A150017 + && package.OverridenOptions.WinGet_SpecifyVersion is not false + ) + { // No manifest found matching criteria package.OverridenOptions.WinGet_SpecifyVersion = false; return OperationVeredict.AutoRetry; } if (uintCode is 0x8A150011) - { // TODO: Integrity failed + { // TODO: Integrity failed return OperationVeredict.Failure; } @@ -177,40 +236,58 @@ protected override OperationVeredict _getOperationResult( { //if (Settings.Get(Settings.K.IgnoreUpdatesNotApplicable)) //{ - Logger.Warn($"Ignoring update {package.Id} as the update is not applicable to the platform, and the user has enabled IgnoreUpdatesNotApplicable"); - IgnoredUpdatesDatabase.Add(IgnoredUpdatesDatabase.GetIgnoredIdForPackage(package), package.VersionString); + Logger.Warn( + $"Ignoring update {package.Id} as the update is not applicable to the platform, and the user has enabled IgnoreUpdatesNotApplicable" + ); + IgnoredUpdatesDatabase.Add( + IgnoredUpdatesDatabase.GetIgnoredIdForPackage(package), + package.VersionString + ); return OperationVeredict.Success; //} //return OperationVeredict.Failure; } if (uintCode is 0x8A15010D or 0x8A15004F or 0x8A15010E) - { // Application is already installed - if (operation is OperationType.Update or OperationType.Install) MarkUpgradeAsDone(package); + { // Application is already installed + if (operation is OperationType.Update or OperationType.Install) + MarkUpgradeAsDone(package); return OperationVeredict.Success; } if (returnCode is 0) - { // Operation succeeded - if (operation is OperationType.Update or OperationType.Install) MarkUpgradeAsDone(package); + { // Operation succeeded + if (operation is OperationType.Update or OperationType.Install) + MarkUpgradeAsDone(package); return OperationVeredict.Success; } - if (uintCode is 0x8A150056 && package.OverridenOptions.RunAsAdministrator is not false && !CoreTools.IsAdministrator()) - { // Installer can't run elevated, but this condition hasn't been forced on UniGetUI + if ( + uintCode is 0x8A150056 + && package.OverridenOptions.RunAsAdministrator is not false + && !CoreTools.IsAdministrator() + ) + { // Installer can't run elevated, but this condition hasn't been forced on UniGetUI package.OverridenOptions.RunAsAdministrator = false; return OperationVeredict.AutoRetry; } - if ((uintCode is 0x8A150019 or 0x80073D28) && package.OverridenOptions.RunAsAdministrator is not true) - { // Installer needs to run elevated, handle autoelevation + if ( + (uintCode is 0x8A150019 or 0x80073D28) + && package.OverridenOptions.RunAsAdministrator is not true + ) + { // Installer needs to run elevated, handle autoelevation // Code 0x80073D28 was added after https://github.com/Devolutions/UniGetUI/issues/3093 package.OverridenOptions.RunAsAdministrator = true; return OperationVeredict.AutoRetry; } - if (operation is OperationType.Uninstall && (uintCode is 0x8A150030) && package.OverridenOptions.RunAsAdministrator is not true) - { // Sometimes, when uninstalling, error code 0x8A150030 can be caused by missing permissions. + if ( + operation is OperationType.Uninstall + && (uintCode is 0x8A150030) + && package.OverridenOptions.RunAsAdministrator is not true + ) + { // Sometimes, when uninstalling, error code 0x8A150030 can be caused by missing permissions. package.OverridenOptions.RunAsAdministrator = true; return OperationVeredict.AutoRetry; } @@ -222,20 +299,35 @@ private static void MarkUpgradeAsDone(IPackage package) { var options = InstallOptionsFactory.LoadApplicable(package); string version; - if (package.IsUpgradable) version = package.NewVersionString; - else if (options.Version != "") version = options.Version; - else version = package.VersionString; - Settings.SetDictionaryItem(Settings.K.WinGetAlreadyUpgradedPackages, package.Id, version); + if (package.IsUpgradable) + version = package.NewVersionString; + else if (options.Version != "") + version = options.Version; + else + version = package.VersionString; + Settings.SetDictionaryItem( + Settings.K.WinGetAlreadyUpgradedPackages, + package.Id, + version + ); } public static bool UpdateAlreadyInstalled(IPackage package) { - return Settings.GetDictionaryItem(Settings.K.WinGetAlreadyUpgradedPackages, package.Id) == package.NewVersionString; + return Settings.GetDictionaryItem( + Settings.K.WinGetAlreadyUpgradedPackages, + package.Id + ) == package.NewVersionString; } + public static string GetLastInstalledVersion(string id) { - var val = Settings.GetDictionaryItem(Settings.K.WinGetAlreadyUpgradedPackages, id); - if (val is null || val == "") val = "Unknown"; + var val = Settings.GetDictionaryItem( + Settings.K.WinGetAlreadyUpgradedPackages, + id + ); + if (val is null || val == "") + val = "Unknown"; return val; } } diff --git a/src/UniGetUI.PackageEngine.Managers.WinGet/Helpers/WinGetSourceHelper.cs b/src/UniGetUI.PackageEngine.Managers.WinGet/Helpers/WinGetSourceHelper.cs index 1c72b43e62..9ca3bc6574 100644 --- a/src/UniGetUI.PackageEngine.Managers.WinGet/Helpers/WinGetSourceHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.WinGet/Helpers/WinGetSourceHelper.cs @@ -14,11 +14,22 @@ internal sealed class WinGetSourceHelper : BaseSourceHelper ]; private readonly Dictionary _attemptedSourceTypes = new(); - public WinGetSourceHelper(WinGet manager) : base(manager) { } + public WinGetSourceHelper(WinGet manager) + : base(manager) { } public override string[] GetAddSourceParameters(IManagerSource source) { - List args = ["source", "add", "--name", source.Name, "--arg", source.Url.ToString(), "--accept-source-agreements", "--disable-interactivity"]; + List args = + [ + "source", + "add", + "--name", + source.Name, + "--arg", + source.Url.ToString(), + "--accept-source-agreements", + "--disable-interactivity", + ]; if (source.Name != "winget") { @@ -34,8 +45,11 @@ public override string[] GetRemoveSourceParameters(IManagerSource source) return ["source", "remove", "--name", source.Name, "--disable-interactivity"]; } - protected override OperationVeredict _getAddSourceOperationVeredict(IManagerSource source, int ReturnCode, - string[] Output) + protected override OperationVeredict _getAddSourceOperationVeredict( + IManagerSource source, + int ReturnCode, + string[] Output + ) { // If operation succeeded, or the source already exists if ((uint)ReturnCode is 0 or 0x8A15000C) @@ -55,7 +69,11 @@ protected override OperationVeredict _getAddSourceOperationVeredict(IManagerSour return OperationVeredict.AutoRetry; } - protected override OperationVeredict _getRemoveSourceOperationVeredict(IManagerSource source, int ReturnCode, string[] Output) + protected override OperationVeredict _getRemoveSourceOperationVeredict( + IManagerSource source, + int ReturnCode, + string[] Output + ) { return ReturnCode == 0 ? OperationVeredict.Success : OperationVeredict.Failure; } diff --git a/src/UniGetUI.PackageEngine.Managers.WinGet/UniGetUI.PackageEngine.Managers.WinGet.csproj b/src/UniGetUI.PackageEngine.Managers.WinGet/UniGetUI.PackageEngine.Managers.WinGet.csproj index 0194d4718d..c023189b03 100644 --- a/src/UniGetUI.PackageEngine.Managers.WinGet/UniGetUI.PackageEngine.Managers.WinGet.csproj +++ b/src/UniGetUI.PackageEngine.Managers.WinGet/UniGetUI.PackageEngine.Managers.WinGet.csproj @@ -1,51 +1,60 @@ - - - $(WindowsTargetFramework) - - $(Platform) - x64 - $(MSBuildProjectDirectory)\winget-cli_$(WingetCliArchitecture) - $(WingetCliDirectory)\winget.exe - $(MSBuildProjectDirectory)\..\..\scripts\fetch-winget-cli.ps1 - - - - - - - - - - - - - - - - - - - - - - - - - - - PreserveNewest - - - - - - - - - - + + $(WindowsTargetFramework) + + $(Platform) + x64 + $(MSBuildProjectDirectory)\winget-cli_$(WingetCliArchitecture) + $(WingetCliDirectory)\winget.exe + $(MSBuildProjectDirectory)\..\..\scripts\fetch-winget-cli.ps1 + + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + + + + + + + + diff --git a/src/UniGetUI.PackageEngine.Managers.WinGet/WinGet.cs b/src/UniGetUI.PackageEngine.Managers.WinGet/WinGet.cs index cb8ea82339..0fa062380e 100644 --- a/src/UniGetUI.PackageEngine.Managers.WinGet/WinGet.cs +++ b/src/UniGetUI.PackageEngine.Managers.WinGet/WinGet.cs @@ -1,8 +1,8 @@ using System.Diagnostics; +using System.Runtime.InteropServices; using System.Security.AccessControl; using System.Security.Principal; using System.Text; -using System.Runtime.InteropServices; using UniGetUI.Core.Data; using UniGetUI.Core.Logging; using UniGetUI.Core.SettingsEngine; @@ -21,8 +21,29 @@ namespace UniGetUI.PackageEngine.Managers.WingetManager public class WinGet : PackageManager { public static string[] FALSE_PACKAGE_NAMES = ["", "e(s)", "have", "the", "Id"]; - public static string[] FALSE_PACKAGE_IDS = ["", "e(s)", "have", "an", "'winget", "pin'", "have", "an", "Version"]; - public static string[] FALSE_PACKAGE_VERSIONS = ["", "have", "an", "'winget", "pin'", "have", "an", "Version"]; + public static string[] FALSE_PACKAGE_IDS = + [ + "", + "e(s)", + "have", + "an", + "'winget", + "pin'", + "have", + "an", + "Version", + ]; + public static string[] FALSE_PACKAGE_VERSIONS = + [ + "", + "have", + "an", + "'winget", + "pin'", + "have", + "an", + "Version", + ]; public LocalWinGetSource LocalPcSource { get; } public LocalWinGetSource AndroidSubsystemSource { get; } public LocalWinGetSource SteamSource { get; } @@ -40,13 +61,17 @@ private static string GetBundledWinGetPath() System.Runtime.InteropServices.Architecture.Arm64 => "winget-cli_arm64", System.Runtime.InteropServices.Architecture.X64 => "winget-cli_x64", System.Runtime.InteropServices.Architecture.X86 => "winget-cli_x86", - _ => "winget-cli_x64" + _ => "winget-cli_x64", }; var path = Path.Join(CoreData.UniGetUIExecutableDirectory, folder, "winget.exe"); if (!File.Exists(path) && folder != "winget-cli_x64") { - path = Path.Join(CoreData.UniGetUIExecutableDirectory, "winget-cli_x64", "winget.exe"); + path = Path.Join( + CoreData.UniGetUIExecutableDirectory, + "winget-cli_x64", + "winget.exe" + ); } return path; @@ -65,7 +90,12 @@ public WinGet() CanDownloadInstaller = true, CanListDependencies = true, SupportsCustomArchitectures = true, - SupportedCustomArchitectures = [Architecture.x86, Architecture.x64, Architecture.arm64], + SupportedCustomArchitectures = + [ + Architecture.x86, + Architecture.x64, + Architecture.arm64, + ], SupportsCustomScopes = true, SupportsCustomLocations = true, SupportsCustomSources = true, @@ -78,47 +108,92 @@ public WinGet() MustBeInstalledAsAdmin = true, }, SupportsProxy = ProxySupport.Partially, - SupportsProxyAuth = false + SupportsProxyAuth = false, }; Properties = new ManagerProperties { Name = "Winget", DisplayName = "WinGet", - Description = CoreTools.Translate("Microsoft's official package manager. Full of well-known and verified packages
Contains: General Software, Microsoft Store apps"), + Description = CoreTools.Translate( + "Microsoft's official package manager. Full of well-known and verified packages
Contains: General Software, Microsoft Store apps" + ), IconId = IconType.WinGet, ColorIconId = "winget_color", ExecutableFriendlyName = "winget.exe", InstallVerb = "install", UninstallVerb = "uninstall", UpdateVerb = "update", - KnownSources = [ new ManagerSource(this, "winget", new Uri("https://cdn.winget.microsoft.com/cache")), - new ManagerSource(this, "winget-fonts", new Uri("https://cdn.winget.microsoft.com/fonts")), - new ManagerSource(this, "msstore", new Uri("https://storeedgefd.dsx.mp.microsoft.com/v9.0")) ], - DefaultSource = new ManagerSource(this, "winget", new Uri("https://cdn.winget.microsoft.com/cache")) + KnownSources = + [ + new ManagerSource( + this, + "winget", + new Uri("https://cdn.winget.microsoft.com/cache") + ), + new ManagerSource( + this, + "winget-fonts", + new Uri("https://cdn.winget.microsoft.com/fonts") + ), + new ManagerSource( + this, + "msstore", + new Uri("https://storeedgefd.dsx.mp.microsoft.com/v9.0") + ), + ], + DefaultSource = new ManagerSource( + this, + "winget", + new Uri("https://cdn.winget.microsoft.com/cache") + ), }; SourcesHelper = new WinGetSourceHelper(this); DetailsHelper = new WinGetPkgDetailsHelper(this); OperationHelper = new WinGetPkgOperationHelper(this); - LocalPcSource = new LocalWinGetSource(this, CoreTools.Translate("Local PC"), IconType.LocalPc, LocalWinGetSource.Type_t.LocalPC); - AndroidSubsystemSource = new(this, CoreTools.Translate("Android Subsystem"), IconType.Android, LocalWinGetSource.Type_t.Android); + LocalPcSource = new LocalWinGetSource( + this, + CoreTools.Translate("Local PC"), + IconType.LocalPc, + LocalWinGetSource.Type_t.LocalPC + ); + AndroidSubsystemSource = new( + this, + CoreTools.Translate("Android Subsystem"), + IconType.Android, + LocalWinGetSource.Type_t.Android + ); SteamSource = new(this, "Steam", IconType.Steam, LocalWinGetSource.Type_t.Steam); - UbisoftConnectSource = new(this, "Ubisoft Connect", IconType.UPlay, LocalWinGetSource.Type_t.Ubisoft); + UbisoftConnectSource = new( + this, + "Ubisoft Connect", + IconType.UPlay, + LocalWinGetSource.Type_t.Ubisoft + ); GOGSource = new(this, "GOG", IconType.GOG, LocalWinGetSource.Type_t.GOG); - MicrosoftStoreSource = new(this, "Microsoft Store", IconType.MsStore, LocalWinGetSource.Type_t.MicrosftStore); + MicrosoftStoreSource = new( + this, + "Microsoft Store", + IconType.MsStore, + LocalWinGetSource.Type_t.MicrosftStore + ); } public static string GetProxyArgument() { - if (!Settings.Get(Settings.K.EnableProxy)) return ""; + if (!Settings.Get(Settings.K.EnableProxy)) + return ""; var proxyUri = Settings.GetProxyUrl(); - if (proxyUri is null) return ""; + if (proxyUri is null) + return ""; if (Settings.Get(Settings.K.EnableProxyAuth)) { - Logger.Warn("Proxy is enabled, but WinGet does not support proxy authentication, so the proxy setting will be ignored"); + Logger.Warn( + "Proxy is enabled, but WinGet does not support proxy authentication, so the proxy setting will be ignored" + ); return ""; } return $"--proxy {proxyUri.ToString().TrimEnd('/')}"; @@ -131,7 +206,10 @@ protected override IReadOnlyList FindPackages_UnSafe(string query) protected override IReadOnlyList GetAvailableUpdates_UnSafe() { - return WinGetHelper.Instance.GetAvailableUpdates_UnSafe().Where(p => p.Id != "Chocolatey.Chocolatey").ToArray(); + return WinGetHelper + .Instance.GetAvailableUpdates_UnSafe() + .Where(p => p.Id != "Chocolatey.Chocolatey") + .ToArray(); } protected override IReadOnlyList GetInstalledPackages_UnSafe() @@ -166,7 +244,12 @@ public ManagerSource GetLocalSource(string id) } // Check if source is android - if (MeaningfulId.Count(x => x == '.') >= 2 && MeaningfulId.All(c => (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '.' || c == '…')) + if ( + MeaningfulId.Count(x => x == '.') >= 2 + && MeaningfulId.All(c => + (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '.' || c == '…' + ) + ) { return AndroidSubsystemSource; } @@ -184,8 +267,10 @@ public ManagerSource GetLocalSource(string id) } // Check if source is GOG - if (MeaningfulId.EndsWith("_is1") && - MeaningfulId.Replace("_is1", "").All(c => (c >= '0' && c <= '9'))) + if ( + MeaningfulId.EndsWith("_is1") + && MeaningfulId.Replace("_is1", "").All(c => (c >= '0' && c <= '9')) + ) { return GOGSource; } @@ -206,7 +291,11 @@ public override IReadOnlyList FindCandidateExecutableFiles() return candidates; } - protected override void _loadManagerExecutableFile(out bool found, out string path, out string callArguments) + protected override void _loadManagerExecutableFile( + out bool found, + out string path, + out string callArguments + ) { bool FORCE_BUNDLED = Settings.Get(Settings.K.ForceLegacyBundledWinGet); var (_found, _path) = GetExecutableFile(); @@ -223,16 +312,19 @@ protected override void _loadManagerExecutableFile(out bool found, out string pa try { - if (FORCE_BUNDLED) WinGetHelper.Instance = new BundledWinGetHelper(this); - else WinGetHelper.Instance = new NativeWinGetHelper(this); + if (FORCE_BUNDLED) + WinGetHelper.Instance = new BundledWinGetHelper(this); + else + WinGetHelper.Instance = new NativeWinGetHelper(this); } catch (Exception ex) { - Logger.Warn($"Cannot instantiate {(FORCE_BUNDLED ? "Bundled" : "Native")} WinGet Helper due to error: {ex.Message}"); + Logger.Warn( + $"Cannot instantiate {(FORCE_BUNDLED ? "Bundled" : "Native")} WinGet Helper due to error: {ex.Message}" + ); Logger.Warn(ex); Logger.Warn("WinGet will resort to using BundledWinGetHelper()"); WinGetHelper.Instance = new BundledWinGetHelper(this); - } } @@ -251,8 +343,8 @@ protected override void _loadManagerVersion(out string version) RedirectStandardError = true, CreateNoWindow = true, StandardOutputEncoding = Encoding.UTF8, - StandardErrorEncoding = Encoding.UTF8 - } + StandardErrorEncoding = Encoding.UTF8, + }, }; if (CoreTools.IsAdministrator()) @@ -263,13 +355,17 @@ protected override void _loadManagerVersion(out string version) } process.Start(); - version = $"{(IS_BUNDLED ? "Bundled" : "System")} WinGet (CLI) Version: {process.StandardOutput.ReadToEnd().Trim()}"; + version = + $"{(IS_BUNDLED ? "Bundled" : "System")} WinGet (CLI) Version: {process.StandardOutput.ReadToEnd().Trim()}"; - if(IS_BUNDLED) version += "\nUsing bundled WinGet helper (CLI parsing)"; - else version += "\nUsing Native WinGet helper (COM Api)"; + if (IS_BUNDLED) + version += "\nUsing bundled WinGet helper (CLI parsing)"; + else + version += "\nUsing Native WinGet helper (COM Api)"; string error = process.StandardError.ReadToEnd(); - if (error != "") Logger.Error("WinGet STDERR not empty: " + error); + if (error != "") + Logger.Error("WinGet STDERR not empty: " + error); } protected override void _performExtraLoadingSteps() @@ -296,7 +392,9 @@ public override void AttemptFastRepair() } else { - Logger.Warn("Attempted to reconnect to COM Server but Bundled WinGet is being used."); + Logger.Warn( + "Attempted to reconnect to COM Server but Bundled WinGet is being used." + ); } } catch (Exception ex) @@ -330,7 +428,12 @@ private static void TryRepairTempFolderPermissions() foreach (FileSystemAccessRule rule in rules) { - if (rule.IdentityReference.Value.Equals(currentUser, StringComparison.CurrentCultureIgnoreCase)) + if ( + rule.IdentityReference.Value.Equals( + currentUser, + StringComparison.CurrentCultureIgnoreCase + ) + ) { userHasAccess = true; break; @@ -339,14 +442,16 @@ private static void TryRepairTempFolderPermissions() if (!userHasAccess) { - Logger.Warn("WinGet temp folder does not have correct permissions set, adding the current user..."); + Logger.Warn( + "WinGet temp folder does not have correct permissions set, adding the current user..." + ); var rule = new FileSystemAccessRule( currentUser, FileSystemRights.FullControl, - InheritanceFlags.ContainerInherit | - InheritanceFlags.ObjectInherit, + InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, - AccessControlType.Allow); + AccessControlType.Allow + ); accessControl.AddAccessRule(rule); directoryInfo.SetAccessControl(accessControl); @@ -354,7 +459,9 @@ private static void TryRepairTempFolderPermissions() } catch (Exception ex) { - Logger.Error("An error occurred while attempting to properly configure WinGet's temp folder permissions."); + Logger.Error( + "An error occurred while attempting to properly configure WinGet's temp folder permissions." + ); Logger.Error(ex); } } @@ -366,14 +473,17 @@ public override void RefreshPackageIndexes() StartInfo = new ProcessStartInfo { FileName = Status.ExecutablePath, - Arguments = Status.ExecutableCallArgs + " source update --disable-interactivity " + GetProxyArgument(), + Arguments = + Status.ExecutableCallArgs + + " source update --disable-interactivity " + + GetProxyArgument(), UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, RedirectStandardInput = true, CreateNoWindow = true, - StandardOutputEncoding = Encoding.UTF8 - } + StandardOutputEncoding = Encoding.UTF8, + }, }; IProcessTaskLogger logger = TaskLogger.CreateNew(LoggableTaskType.RefreshIndexes, p); @@ -381,7 +491,9 @@ public override void RefreshPackageIndexes() if (CoreTools.IsAdministrator()) { string WinGetTemp = Path.Join(Path.GetTempPath(), "UniGetUI", "ElevatedWinGetTemp"); - logger.AddToStdErr($"[WARN] Redirecting %TEMP% folder to {WinGetTemp}, since UniGetUI was run as admin"); + logger.AddToStdErr( + $"[WARN] Redirecting %TEMP% folder to {WinGetTemp}, since UniGetUI was run as admin" + ); p.StartInfo.Environment["TEMP"] = WinGetTemp; p.StartInfo.Environment["TMP"] = WinGetTemp; } @@ -404,16 +516,24 @@ public enum Type_t Steam, GOG, Android, - Ubisoft + Ubisoft, } public readonly Type_t Type; private readonly string name; private readonly IconType __icon_id; - public override IconType IconId { get => __icon_id; } + public override IconType IconId + { + get => __icon_id; + } public LocalWinGetSource(WinGet manager, string name, IconType iconId, Type_t type) - : base(manager, name, new Uri("https://microsoft.com/local-pc-source"), isVirtualManager: true) + : base( + manager, + name, + new Uri("https://microsoft.com/local-pc-source"), + isVirtualManager: true + ) { Type = type; this.name = name; diff --git a/src/UniGetUI.PackageEngine.Operations/AbstractOperation.cs b/src/UniGetUI.PackageEngine.Operations/AbstractOperation.cs index 45366c932e..0b5b6bd621 100644 --- a/src/UniGetUI.PackageEngine.Operations/AbstractOperation.cs +++ b/src/UniGetUI.PackageEngine.Operations/AbstractOperation.cs @@ -29,7 +29,11 @@ public abstract partial class AbstractOperation : IDisposable public OperationStatus Status { get => _status; - set { _status = value; StatusChanged?.Invoke(this, value); } + set + { + _status = value; + StatusChanged?.Invoke(this, value); + } } public void ApplyCapabilities(bool admin, bool interactive, bool skiphash, string? scope) @@ -43,11 +47,14 @@ public void ApplyCapabilities(bool admin, bool interactive, bool skiphash, strin public AbstractOperation( bool queue_enabled, IReadOnlyList? preOps = null, - IReadOnlyList? postOps = null) + IReadOnlyList? postOps = null + ) { QUEUE_ENABLED = queue_enabled; - if (preOps is not null) PreOperations = preOps; - if (postOps is not null) PostOperations = postOps; + if (preOps is not null) + PreOperations = preOps; + if (postOps is not null) + PostOperations = postOps; Status = OperationStatus.InQueue; Line("Please wait...", LineType.ProgressIndicator); @@ -74,13 +81,15 @@ public void Cancel() break; case OperationStatus.Running: Status = OperationStatus.Canceled; - while(OperationQueue.Remove(this)); + while (OperationQueue.Remove(this)) + ; CancelRequested?.Invoke(this, EventArgs.Empty); Status = OperationStatus.Canceled; break; case OperationStatus.InQueue: Status = OperationStatus.Canceled; - while(OperationQueue.Remove(this)); + while (OperationQueue.Remove(this)) + ; Status = OperationStatus.Canceled; break; case OperationStatus.Succeeded: @@ -90,7 +99,8 @@ public void Cancel() protected void Line(string line, LineType type) { - if (type != LineType.ProgressIndicator) LogList.Add((line, type)); + if (type != LineType.ProgressIndicator) + LogList.Add((line, type)); LogLineAdded?.Invoke(this, (line, type)); } @@ -103,14 +113,20 @@ public async Task MainThread() { try { - if (Metadata.Status == "") throw new InvalidDataException("Metadata.Status was not set!"); - if (Metadata.Title == "") throw new InvalidDataException("Metadata.Title was not set!"); + if (Metadata.Status == "") + throw new InvalidDataException("Metadata.Status was not set!"); + if (Metadata.Title == "") + throw new InvalidDataException("Metadata.Title was not set!"); if (Metadata.OperationInformation == "") throw new InvalidDataException("Metadata.OperationInformation was not set!"); - if (Metadata.SuccessTitle == "") throw new InvalidDataException("Metadata.SuccessTitle was not set!"); - if (Metadata.SuccessMessage == "") throw new InvalidDataException("Metadata.SuccessMessage was not set!"); - if (Metadata.FailureTitle == "") throw new InvalidDataException("Metadata.FailureTitle was not set!"); - if (Metadata.FailureMessage == "") throw new InvalidDataException("Metadata.FailureMessage was not set!"); + if (Metadata.SuccessTitle == "") + throw new InvalidDataException("Metadata.SuccessTitle was not set!"); + if (Metadata.SuccessMessage == "") + throw new InvalidDataException("Metadata.SuccessMessage was not set!"); + if (Metadata.FailureTitle == "") + throw new InvalidDataException("Metadata.FailureTitle was not set!"); + if (Metadata.FailureMessage == "") + throw new InvalidDataException("Metadata.FailureMessage was not set!"); Started = true; @@ -130,17 +146,24 @@ public async Task MainThread() OperationQueue.Add(this); int lastPos = -2; - while (FORCE_HOLD_QUEUE || (OperationQueue.IndexOf(this) >= MAX_OPERATIONS && !SKIP_QUEUE)) + while ( + FORCE_HOLD_QUEUE + || (OperationQueue.IndexOf(this) >= MAX_OPERATIONS && !SKIP_QUEUE) + ) { int pos = OperationQueue.IndexOf(this) - MAX_OPERATIONS + 1; - if (pos == -1) return; + if (pos == -1) + return; // In this case, operation was canceled; if (pos != lastPos) { lastPos = pos; - Line(CoreTools.Translate("Operation on queue (position {0})...", pos), LineType.ProgressIndicator); + Line( + CoreTools.Translate("Operation on queue (position {0})...", pos), + LineType.ProgressIndicator + ); } await Task.Delay(100); @@ -149,7 +172,8 @@ public async Task MainThread() // END QUEUE HANDLER var result = await _runOperation(); - while (OperationQueue.Remove(this)); + while (OperationQueue.Remove(this)) + ; if (result == OperationVeredict.Success) { @@ -164,8 +188,12 @@ public async Task MainThread() OperationFailed?.Invoke(this, EventArgs.Empty); OperationFinished?.Invoke(this, EventArgs.Empty); Line(Metadata.FailureMessage, LineType.Error); - Line(Metadata.FailureMessage + " - " + CoreTools.Translate("Click here for more details"), - LineType.ProgressIndicator); + Line( + Metadata.FailureMessage + + " - " + + CoreTools.Translate("Click here for more details"), + LineType.ProgressIndicator + ); } else if (result == OperationVeredict.Canceled) { @@ -186,7 +214,8 @@ public async Task MainThread() Line(line, LineType.Error); } - while (OperationQueue.Remove(this)) ; + while (OperationQueue.Remove(this)) + ; Status = OperationStatus.Failed; try @@ -196,7 +225,10 @@ public async Task MainThread() } catch (Exception e2) { - Line("An internal error occurred while handling an internal error:", LineType.Error); + Line( + "An internal error occurred while handling an internal error:", + LineType.Error + ); foreach (var line in e2.ToString().Split("\n")) { Line(line, LineType.Error); @@ -204,8 +236,12 @@ public async Task MainThread() } Line(Metadata.FailureMessage, LineType.Error); - Line(Metadata.FailureMessage + " - " + CoreTools.Translate("Click here for more details"), - LineType.ProgressIndicator); + Line( + Metadata.FailureMessage + + " - " + + CoreTools.Translate("Click here for more details"), + LineType.ProgressIndicator + ); } } @@ -214,29 +250,43 @@ private async Task _runOperation() OperationVeredict result; // Process preoperations - int i = 0, count = PreOperations.Count; - if(count > 0) Line("", LineType.VerboseDetails); + int i = 0, + count = PreOperations.Count; + if (count > 0) + Line("", LineType.VerboseDetails); foreach (var preReq in PreOperations) { i++; - Line(CoreTools.Translate($"Running PreOperation ({i}/{count})..."), LineType.Information); + Line( + CoreTools.Translate($"Running PreOperation ({i}/{count})..."), + LineType.Information + ); preReq.Operation.LogLineAdded += (_, line) => Line(line.Item1, line.Item2); await preReq.Operation.MainThread(); if (preReq.Operation.Status is not OperationStatus.Succeeded && preReq.MustSucceed) { Line( - CoreTools.Translate($"PreOperation {i} out of {count} failed, and was tagged as necessary. Aborting..."), - LineType.Error); + CoreTools.Translate( + $"PreOperation {i} out of {count} failed, and was tagged as necessary. Aborting..." + ), + LineType.Error + ); return OperationVeredict.Failure; } - Line(CoreTools.Translate($"PreOperation {i} out of {count} finished with result {preReq.Operation.Status}"), LineType.Information); + Line( + CoreTools.Translate( + $"PreOperation {i} out of {count} finished with result {preReq.Operation.Status}" + ), + LineType.Information + ); Line("--------------------------------", LineType.Information); Line("", LineType.VerboseDetails); } // BEGIN ACTUAL OPERATION Line(CoreTools.Translate("Starting operation..."), LineType.Information); - if (Status is OperationStatus.InQueue) Status = OperationStatus.Running; + if (Status is OperationStatus.InQueue) + Status = OperationStatus.Running; do { @@ -252,10 +302,13 @@ private async Task _runOperation() } Task op = PerformOperation(); - while (Status != OperationStatus.Canceled && !op.IsCompleted) await Task.Delay(100); + while (Status != OperationStatus.Canceled && !op.IsCompleted) + await Task.Delay(100); - if (Status is OperationStatus.Canceled) result = OperationVeredict.Canceled; - else result = op.GetAwaiter().GetResult(); + if (Status is OperationStatus.Canceled) + result = OperationVeredict.Canceled; + else + result = op.GetAwaiter().GetResult(); } catch (Exception e) { @@ -272,23 +325,35 @@ private async Task _runOperation() return result; // Process postoperations - i = 0; count = PostOperations.Count; + i = 0; + count = PostOperations.Count; foreach (var postReq in PostOperations) { i++; Line("--------------------------------", LineType.Information); Line("", LineType.VerboseDetails); - Line(CoreTools.Translate($"Running PostOperation ({i}/{count})..."), LineType.Information); + Line( + CoreTools.Translate($"Running PostOperation ({i}/{count})..."), + LineType.Information + ); postReq.Operation.LogLineAdded += (_, line) => Line(line.Item1, line.Item2); await postReq.Operation.MainThread(); if (postReq.Operation.Status is not OperationStatus.Succeeded && postReq.MustSucceed) { Line( - CoreTools.Translate($"PostOperation {i} out of {count} failed, and was tagged as necessary. Aborting..."), - LineType.Error); + CoreTools.Translate( + $"PostOperation {i} out of {count} failed, and was tagged as necessary. Aborting..." + ), + LineType.Error + ); return OperationVeredict.Failure; } - Line(CoreTools.Translate($"PostOperation {i} out of {count} finished with result {postReq.Operation.Status}"), LineType.Information); + Line( + CoreTools.Translate( + $"PostOperation {i} out of {count} finished with result {postReq.Operation.Status}" + ), + LineType.Information + ); } return result; @@ -298,29 +363,37 @@ private async Task _runOperation() public void SkipQueue() { - if (Status != OperationStatus.InQueue) return; - while(OperationQueue.Remove(this)); + if (Status != OperationStatus.InQueue) + return; + while (OperationQueue.Remove(this)) + ; SKIP_QUEUE = true; } public void RunNext() { - if (Status != OperationStatus.InQueue) return; - if (!OperationQueue.Contains(this)) return; + if (Status != OperationStatus.InQueue) + return; + if (!OperationQueue.Contains(this)) + return; FORCE_HOLD_QUEUE = true; - while(OperationQueue.Remove(this)); + while (OperationQueue.Remove(this)) + ; OperationQueue.Insert(Math.Min(MAX_OPERATIONS, OperationQueue.Count), this); FORCE_HOLD_QUEUE = false; } public void BackOfTheQueue() { - if (Status != OperationStatus.InQueue) return; - if (!OperationQueue.Contains(this)) return; + if (Status != OperationStatus.InQueue) + return; + if (!OperationQueue.Contains(this)) + return; FORCE_HOLD_QUEUE = true; - while(OperationQueue.Remove(this)); + while (OperationQueue.Remove(this)) + ; OperationQueue.Add(this); FORCE_HOLD_QUEUE = false; } @@ -335,15 +408,18 @@ public void Retry(string retryMode) Line($"-----------------------", LineType.VerboseDetails); Line($"Retrying operation with RetryMode={retryMode}", LineType.VerboseDetails); Line($"", LineType.VerboseDetails); - if (Status is OperationStatus.Running or OperationStatus.InQueue) return; + if (Status is OperationStatus.Running or OperationStatus.InQueue) + return; _ = MainThread(); } protected abstract void ApplyRetryAction(string retryMode); protected abstract Task PerformOperation(); public abstract Task GetOperationIcon(); + public void Dispose() { - while(OperationQueue.Remove(this)); + while (OperationQueue.Remove(this)) + ; } } diff --git a/src/UniGetUI.PackageEngine.Operations/AbstractOperation_Auxiliaries.cs b/src/UniGetUI.PackageEngine.Operations/AbstractOperation_Auxiliaries.cs index 71e607e4c1..41becca366 100644 --- a/src/UniGetUI.PackageEngine.Operations/AbstractOperation_Auxiliaries.cs +++ b/src/UniGetUI.PackageEngine.Operations/AbstractOperation_Auxiliaries.cs @@ -55,7 +55,7 @@ public class OperationMetadata public OperationMetadata() { - Identifier = new Random().NextInt64(1000000, 9999999).ToString(); + Identifier = new Random().NextInt64(1000000, 9999999).ToString(); } } @@ -80,7 +80,7 @@ public enum LineType VerboseDetails, ProgressIndicator, Information, - Error + Error, } public struct InnerOperation @@ -95,5 +95,4 @@ public InnerOperation(AbstractOperation op, bool mustSucceed) op.IsInnerOperation = true; } } - } diff --git a/src/UniGetUI.PackageEngine.Operations/AbstractProcessOperation.cs b/src/UniGetUI.PackageEngine.Operations/AbstractProcessOperation.cs index 13ed763699..95d8888970 100644 --- a/src/UniGetUI.PackageEngine.Operations/AbstractProcessOperation.cs +++ b/src/UniGetUI.PackageEngine.Operations/AbstractProcessOperation.cs @@ -15,7 +15,9 @@ public abstract class AbstractProcessOperation : AbstractOperation protected AbstractProcessOperation( bool queue_enabled, IReadOnlyList? preOps = null, - IReadOnlyList? postOps = null) : base(queue_enabled, preOps, postOps) + IReadOnlyList? postOps = null + ) + : base(queue_enabled, preOps, postOps) { process = new(); CancelRequested += (_, _) => @@ -27,7 +29,10 @@ protected AbstractProcessOperation( } catch (InvalidOperationException e) { - Line("Attempted to cancel a process that hasn't ben created yet: " + e.Message, LineType.Error); + Line( + "Attempted to cancel a process that hasn't ben created yet: " + e.Message, + LineType.Error + ); } }; OperationStarting += (_, _) => @@ -42,12 +47,15 @@ protected AbstractProcessOperation( process.StartInfo.StandardOutputEncoding = Encoding.UTF8; process.StartInfo.StandardErrorEncoding = Encoding.UTF8; process.StartInfo.StandardInputEncoding = Encoding.UTF8; - process.StartInfo.WorkingDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); + process.StartInfo.WorkingDirectory = Environment.GetFolderPath( + Environment.SpecialFolder.UserProfile + ); process.StartInfo.FileName = "lol"; process.StartInfo.Arguments = "lol"; process.ErrorDataReceived += (_, e) => { - if (e.Data is null) return; + if (e.Data is null) + return; string line = e.Data.ToString().Trim(); var lineType = LineType.Error; if (line.Length < 6 || line.Contains("Waiting for another install...")) @@ -62,6 +70,7 @@ protected AbstractProcessOperation( } private bool _requiresUACCache; + protected void RequestCachingOfUACPrompt() { _requiresUACCache = true; @@ -76,12 +85,18 @@ protected void RedirectWinGetTempFolder() protected override async Task PerformOperation() { - if (process.StartInfo.UseShellExecute) throw new InvalidOperationException("UseShellExecute must be set to false"); - if (!process.StartInfo.RedirectStandardOutput) throw new InvalidOperationException("RedirectStandardOutput must be set to true"); - if (!process.StartInfo.RedirectStandardInput) throw new InvalidOperationException("RedirectStandardInput must be set to true"); - if (!process.StartInfo.RedirectStandardError) throw new InvalidOperationException("RedirectStandardError must be set to true"); - if (process.StartInfo.FileName == "lol") throw new InvalidOperationException("StartInfo.FileName has not been set"); - if (process.StartInfo.Arguments == "lol") throw new InvalidOperationException("StartInfo.Arguments has not been set"); + if (process.StartInfo.UseShellExecute) + throw new InvalidOperationException("UseShellExecute must be set to false"); + if (!process.StartInfo.RedirectStandardOutput) + throw new InvalidOperationException("RedirectStandardOutput must be set to true"); + if (!process.StartInfo.RedirectStandardInput) + throw new InvalidOperationException("RedirectStandardInput must be set to true"); + if (!process.StartInfo.RedirectStandardError) + throw new InvalidOperationException("RedirectStandardError must be set to true"); + if (process.StartInfo.FileName == "lol") + throw new InvalidOperationException("StartInfo.FileName has not been set"); + if (process.StartInfo.Arguments == "lol") + throw new InvalidOperationException("StartInfo.Arguments has not been set"); Line($"Executing process with StartInfo:", LineType.VerboseDetails); Line($" - FileName: \"{process.StartInfo.FileName.Trim()}\"", LineType.VerboseDetails); @@ -101,10 +116,16 @@ protected override async Task PerformOperation() process.StandardInput.Close(); } // process.BeginOutputReadLine(); - try { process.BeginErrorReadLine(); } - catch (Exception ex) { Logger.Error(ex); } + try + { + process.BeginErrorReadLine(); + } + catch (Exception ex) + { + Logger.Error(ex); + } - StringBuilder currentLine= new(); + StringBuilder currentLine = new(); char[] buffer = new char[1]; string? lastStringBeforeLF = null; @@ -129,7 +150,8 @@ protected override async Task PerformOperation() } else if (c == '\r') { - if (currentLine.Length == 0) continue; + if (currentLine.Length == 0) + continue; lastStringBeforeLF = currentLine.ToString(); Line(lastStringBeforeLF, LineType.ProgressIndicator); currentLine.Clear(); @@ -143,7 +165,10 @@ protected override async Task PerformOperation() await process.WaitForExitAsync(); Line($"End Time: \"{DateTime.Now}\"", LineType.VerboseDetails); - Line($"Process return value: \"{process.ExitCode}\" (0x{process.ExitCode:X})", LineType.VerboseDetails); + Line( + $"Process return value: \"{process.ExitCode}\" (0x{process.ExitCode:X})", + LineType.VerboseDetails + ); if (ProcessKilled) return OperationVeredict.Canceled; @@ -151,13 +176,18 @@ protected override async Task PerformOperation() List output = new(); foreach (var line in GetOutput()) { - if (line.Item2 is LineType.VerboseDetails && line.Item1 == "-----------------------") output.Clear(); - if (line.Item2 is LineType.Error or LineType.Information) output.Add(line.Item1); + if (line.Item2 is LineType.VerboseDetails && line.Item1 == "-----------------------") + output.Clear(); + if (line.Item2 is LineType.Error or LineType.Information) + output.Add(line.Item1); } return await GetProcessVeredict(process.ExitCode, output); } - protected abstract Task GetProcessVeredict(int ReturnCode, List Output); + protected abstract Task GetProcessVeredict( + int ReturnCode, + List Output + ); protected abstract void PrepareProcessStartInfo(); } diff --git a/src/UniGetUI.PackageEngine.Operations/DownloadOperation.cs b/src/UniGetUI.PackageEngine.Operations/DownloadOperation.cs index 26c2e5c1dc..5b34cb6988 100644 --- a/src/UniGetUI.PackageEngine.Operations/DownloadOperation.cs +++ b/src/UniGetUI.PackageEngine.Operations/DownloadOperation.cs @@ -4,6 +4,7 @@ using UniGetUI.PackageOperations; namespace UniGetUI.PackageEngine.Operations; + public class DownloadOperation : AbstractOperation { private readonly IPackage _package; @@ -14,24 +15,40 @@ public string DownloadLocation } private bool canceled; - public DownloadOperation(IPackage package, string downloadPath): base(true, null) + public DownloadOperation(IPackage package, string downloadPath) + : base(true, null) { downloadLocation = downloadPath; _package = package; - Metadata.OperationInformation = "Downloading installer for Package=" + _package.Id + " with Manager=" + _package.Manager.Name; - Metadata.Title = CoreTools.Translate("{package} installer download", new Dictionary { { "package", _package.Name } }); + Metadata.OperationInformation = + "Downloading installer for Package=" + + _package.Id + + " with Manager=" + + _package.Manager.Name; + Metadata.Title = CoreTools.Translate( + "{package} installer download", + new Dictionary { { "package", _package.Name } } + ); Metadata.Status = CoreTools.Translate("{0} installer is being downloaded", _package.Name); Metadata.SuccessTitle = CoreTools.Translate("Download succeeded"); - Metadata.SuccessMessage = CoreTools.Translate("{package} installer was downloaded successfully", new Dictionary { { "package", _package.Name } }); - Metadata.FailureTitle = CoreTools.Translate("Download failed", new Dictionary { { "package", _package.Name } }); - Metadata.FailureMessage = CoreTools.Translate("{package} installer could not be downloaded", new Dictionary { { "package", _package.Name } }); + Metadata.SuccessMessage = CoreTools.Translate( + "{package} installer was downloaded successfully", + new Dictionary { { "package", _package.Name } } + ); + Metadata.FailureTitle = CoreTools.Translate( + "Download failed", + new Dictionary { { "package", _package.Name } } + ); + Metadata.FailureMessage = CoreTools.Translate( + "{package} installer could not be downloaded", + new Dictionary { { "package", _package.Name } } + ); CancelRequested += (_, _) => { canceled = true; }; - } public override Task GetOperationIcon() @@ -49,13 +66,19 @@ protected override async Task PerformOperation() canceled = false; try { - Line($"Fetching download url for package {_package.Name} from {_package.Manager.DisplayName}...", LineType.Information); + Line( + $"Fetching download url for package {_package.Name} from {_package.Manager.DisplayName}...", + LineType.Information + ); await _package.Details.Load(); Uri? downloadUrl = _package.Details.InstallerUrl; if (downloadUrl is null) { - Line($"UniGetUI was not able to find any installer for this package. " + - $"Please check that this package has an applicable installer and try again later", LineType.Error); + Line( + $"UniGetUI was not able to find any installer for this package. " + + $"Please check that this package has an applicable installer and try again later", + LineType.Error + ); return OperationVeredict.Failure; } @@ -64,7 +87,10 @@ protected override async Task PerformOperation() string? fileName = await _package.GetInstallerFileName(); if (fileName is null) { - Line("An error occurred while retrieving file name, default will be used!", LineType.Error); + Line( + "An error occurred while retrieving file name, default will be used!", + LineType.Error + ); fileName = CoreTools.MakeValidFileName(_package.Name); } downloadLocation = Path.Join(downloadLocation, fileName); @@ -72,7 +98,10 @@ protected override async Task PerformOperation() Line($"Download URL found at {downloadUrl} ", LineType.Information); using var httpClient = new HttpClient(CoreTools.GenericHttpClientParameters); - using var response = await httpClient.GetAsync(downloadUrl, HttpCompletionOption.ResponseHeadersRead); + using var response = await httpClient.GetAsync( + downloadUrl, + HttpCompletionOption.ResponseHeadersRead + ); response.EnsureSuccessStatusCode(); @@ -80,9 +109,16 @@ protected override async Task PerformOperation() var canReportProgress = totalBytes > 0; using var contentStream = await response.Content.ReadAsStreamAsync(); - using var fileStream = new FileStream(downloadLocation, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true); - - var buffer = new byte[4*1024*1024]; + using var fileStream = new FileStream( + downloadLocation, + FileMode.Create, + FileAccess.Write, + FileShare.None, + 8192, + true + ); + + var buffer = new byte[4 * 1024 * 1024]; long totalRead = 0; int bytesRead; @@ -98,10 +134,14 @@ protected override async Task PerformOperation() if (progress != oldProgress) { oldProgress = progress; - Line(CoreTools.TextProgressGenerator( - 30, progress, - $"{CoreTools.FormatAsSize(totalRead)}/{CoreTools.FormatAsSize(totalBytes)}" - ), LineType.ProgressIndicator); + Line( + CoreTools.TextProgressGenerator( + 30, + progress, + $"{CoreTools.FormatAsSize(totalRead)}/{CoreTools.FormatAsSize(totalBytes)}" + ), + LineType.ProgressIndicator + ); } } diff --git a/src/UniGetUI.PackageEngine.Operations/KillProcessOperation.cs b/src/UniGetUI.PackageEngine.Operations/KillProcessOperation.cs index 9d8d34342e..f179d8644d 100644 --- a/src/UniGetUI.PackageEngine.Operations/KillProcessOperation.cs +++ b/src/UniGetUI.PackageEngine.Operations/KillProcessOperation.cs @@ -1,4 +1,3 @@ - using System.Diagnostics; using UniGetUI.Core.SettingsEngine; using UniGetUI.Core.Tools; @@ -6,10 +5,12 @@ namespace UniGetUI.PackageOperations; -public class KillProcessOperation: AbstractOperation +public class KillProcessOperation : AbstractOperation { private readonly string ProcessName; - public KillProcessOperation(string procName) : base(false) + + public KillProcessOperation(string procName) + : base(false) { ProcessName = CoreTools.MakeValidFileName(procName); Metadata.Status = $"Closing process(es) {procName}"; @@ -21,32 +22,43 @@ public KillProcessOperation(string procName) : base(false) Metadata.FailureMessage = $"The process(es) {procName} could not be closed"; } - protected override void ApplyRetryAction(string retryMode) - { - } + protected override void ApplyRetryAction(string retryMode) { } protected override async Task PerformOperation() { try { - Line($"Attempting to close all processes with name {ProcessName}...", LineType.Information); + Line( + $"Attempting to close all processes with name {ProcessName}...", + LineType.Information + ); var procs = Process.GetProcessesByName(ProcessName.Replace(".exe", "")); foreach (var proc in procs) { - if(proc.HasExited) continue; - Line($"Attempting to close process {ProcessName} with pid={proc.Id}...", LineType.VerboseDetails); + if (proc.HasExited) + continue; + Line( + $"Attempting to close process {ProcessName} with pid={proc.Id}...", + LineType.VerboseDetails + ); proc.CloseMainWindow(); await Task.WhenAny(proc.WaitForExitAsync(), Task.Delay(1000)); if (!proc.HasExited) { - if(Settings.Get(Settings.K.KillProcessesThatRefuseToDie)) + if (Settings.Get(Settings.K.KillProcessesThatRefuseToDie)) { - Line($"Timeout for process {ProcessName}, attempting to kill...", LineType.Information); + Line( + $"Timeout for process {ProcessName}, attempting to kill...", + LineType.Information + ); proc.Kill(); } else { - Line($"{ProcessName} with pid={proc.Id} did not exit and will not be killed. You can change this from UniGetUI settings.", LineType.Error); + Line( + $"{ProcessName} with pid={proc.Id} did not exit and will not be killed. You can change this from UniGetUI settings.", + LineType.Error + ); } } } @@ -60,6 +72,5 @@ protected override async Task PerformOperation() } } - public override Task GetOperationIcon() - => Task.FromResult(new Uri("about:blank")); + public override Task GetOperationIcon() => Task.FromResult(new Uri("about:blank")); } diff --git a/src/UniGetUI.PackageEngine.Operations/PackageOperations.cs b/src/UniGetUI.PackageEngine.Operations/PackageOperations.cs index 40853cd143..e3e86131fa 100644 --- a/src/UniGetUI.PackageEngine.Operations/PackageOperations.cs +++ b/src/UniGetUI.PackageEngine.Operations/PackageOperations.cs @@ -34,8 +34,13 @@ public PackageOperation( InstallOptions options, OperationType role, bool IgnoreParallelInstalls = false, - AbstractOperation? req = null) - : base(!IgnoreParallelInstalls, _getPreInstallOps(options, role, req), _getPostInstallOps(options, role, package)) + AbstractOperation? req = null + ) + : base( + !IgnoreParallelInstalls, + _getPreInstallOps(options, role, req), + _getPostInstallOps(options, role, package) + ) { Package = package; Options = options; @@ -45,10 +50,12 @@ public PackageOperation( Enqueued += (_, _) => { - ApplyCapabilities(RequiresAdminRights(), + ApplyCapabilities( + RequiresAdminRights(), Options.InteractiveInstallation, (Options.SkipHashCheck && Role is not OperationType.Uninstall), - Package.OverridenOptions.Scope ?? Options.InstallationScope); + Package.OverridenOptions.Scope ?? Options.InstallationScope + ); Package.SetTag(PackageTag.OnQueue); }; @@ -57,9 +64,9 @@ public PackageOperation( OperationFailed += (_, _) => HandleFailure(); } - private bool RequiresAdminRights() - => !Settings.Get(Settings.K.ProhibitElevation) - && (Package.OverridenOptions.RunAsAdministrator is true || Options.RunAsAdministrator); + private bool RequiresAdminRights() => + !Settings.Get(Settings.K.ProhibitElevation) + && (Package.OverridenOptions.RunAsAdministrator is true || Options.RunAsAdministrator); protected override void ApplyRetryAction(string retryMode) { @@ -77,30 +84,46 @@ protected override void ApplyRetryAction(string retryMode) case RetryMode.Retry: break; default: - throw new InvalidOperationException($"Retry mode {retryMode} is not supported in this context"); + throw new InvalidOperationException( + $"Retry mode {retryMode} is not supported in this context" + ); } - Metadata.OperationInformation = "Retried package operation for Package=" + Package.Id + " with Manager=" + - Package.Manager.Name + "\nUpdated installation options: " + Options.ToString() - + "\nOverriden options: " + Package.OverridenOptions.ToString(); + Metadata.OperationInformation = + "Retried package operation for Package=" + + Package.Id + + " with Manager=" + + Package.Manager.Name + + "\nUpdated installation options: " + + Options.ToString() + + "\nOverriden options: " + + Package.OverridenOptions.ToString(); } protected sealed override void PrepareProcessStartInfo() { bool IsAdmin = CoreTools.IsAdministrator(); Package.SetTag(PackageTag.OnQueue); - string operation_args = string.Join(" ", Package.Manager.OperationHelper.GetParameters(Package, Options, Role)); - string FileName, Arguments; + string operation_args = string.Join( + " ", + Package.Manager.OperationHelper.GetParameters(Package, Options, Role) + ); + string FileName, + Arguments; if (RequiresAdminRights() && IsAdmin is false) { IsAdmin = true; - if (Settings.Get(Settings.K.DoCacheAdminRights) || Settings.Get(Settings.K.DoCacheAdminRightsForBatches)) + if ( + Settings.Get(Settings.K.DoCacheAdminRights) + || Settings.Get(Settings.K.DoCacheAdminRightsForBatches) + ) { RequestCachingOfUACPrompt(); } FileName = CoreData.ElevatorPath; - Arguments = $"\"{Package.Manager.Status.ExecutablePath}\" {Package.Manager.Status.ExecutableCallArgs} {operation_args}"; + Arguments = + $"\"{Package.Manager.Status.ExecutablePath}\" {Package.Manager.Status.ExecutableCallArgs} {operation_args}"; } else { @@ -124,9 +147,14 @@ protected sealed override void PrepareProcessStartInfo() ); } - protected sealed override Task GetProcessVeredict(int ReturnCode, List Output) + protected sealed override Task GetProcessVeredict( + int ReturnCode, + List Output + ) { - return Task.FromResult(Package.Manager.OperationHelper.GetResult(Package, Role, Output, ReturnCode)); + return Task.FromResult( + Package.Manager.OperationHelper.GetResult(Package, Role, Output, ReturnCode) + ); } private static bool IsWinGetManager(IPackageManager manager) @@ -143,27 +171,41 @@ public override Task GetOperationIcon() return TaskRecycler.RunOrAttachAsync(Package.GetIconUrl); } - private static IReadOnlyList _getPreInstallOps(InstallOptions opts, OperationType role, AbstractOperation? preReq = null) + private static IReadOnlyList _getPreInstallOps( + InstallOptions opts, + OperationType role, + AbstractOperation? preReq = null + ) { List l = new(); - if(preReq is not null) l.Add(new(preReq, true)); + if (preReq is not null) + l.Add(new(preReq, true)); foreach (var process in opts.KillBeforeOperation) - l.Add(new InnerOperation( - new KillProcessOperation(process), - mustSucceed: false)); + l.Add(new InnerOperation(new KillProcessOperation(process), mustSucceed: false)); if (role is OperationType.Install && opts.PreInstallCommand.Any()) - l.Add(new(new PrePostOperation(opts.PreInstallCommand), opts.AbortOnPreInstallFail)); + l.Add( + new(new PrePostOperation(opts.PreInstallCommand), opts.AbortOnPreInstallFail) + ); else if (role is OperationType.Update && opts.PreUpdateCommand.Any()) l.Add(new(new PrePostOperation(opts.PreUpdateCommand), opts.AbortOnPreUpdateFail)); else if (role is OperationType.Uninstall && opts.PreUninstallCommand.Any()) - l.Add(new(new PrePostOperation(opts.PreUninstallCommand), opts.AbortOnPreUninstallFail)); + l.Add( + new( + new PrePostOperation(opts.PreUninstallCommand), + opts.AbortOnPreUninstallFail + ) + ); return l; } - private static IReadOnlyList _getPostInstallOps(InstallOptions opts, OperationType role, IPackage package) + private static IReadOnlyList _getPostInstallOps( + InstallOptions opts, + OperationType role, + IPackage package + ) { List l = new(); @@ -176,11 +218,14 @@ private static IReadOnlyList _getPostInstallOps(InstallOptions o if (role is OperationType.Update && opts.UninstallPreviousVersionsOnUpdate) { - var matches = InstalledPackagesLoader.Instance.Packages.Where( - p => p.IsEquivalentTo(package) && p.NormalizedVersion < package.NormalizedNewVersion); + var matches = InstalledPackagesLoader.Instance.Packages.Where(p => + p.IsEquivalentTo(package) && p.NormalizedVersion < package.NormalizedNewVersion + ); foreach (var match in matches) { - Logger.Info($"Queuing {match} version {match.VersionString} for automatic uninstall after update..."); + Logger.Info( + $"Queuing {match} version {match.VersionString} for automatic uninstall after update..." + ); l.Add(new(new UninstallPackageOperation(match, opts.Copy()), false)); } } @@ -204,9 +249,9 @@ public InstallPackageOperation( IPackage package, InstallOptions options, bool IgnoreParallelInstalls = false, - AbstractOperation? req = null) - : base(package, options, OperationType.Install, IgnoreParallelInstalls, req) - { } + AbstractOperation? req = null + ) + : base(package, options, OperationType.Install, IgnoreParallelInstalls, req) { } protected override Task HandleFailure() { @@ -235,16 +280,34 @@ protected override async Task HandleSuccess() protected override void Initialize() { - Metadata.OperationInformation = "Package install operation for Package=" + Package.Id + " with Manager=" - + Package.Manager.Name + "\nInstallation options: " + Options.ToString() - + "\nOverriden options: " + Package.OverridenOptions.ToString(); - - Metadata.Title = CoreTools.Translate("{package} Installation", new Dictionary { { "package", Package.Name } }); + Metadata.OperationInformation = + "Package install operation for Package=" + + Package.Id + + " with Manager=" + + Package.Manager.Name + + "\nInstallation options: " + + Options.ToString() + + "\nOverriden options: " + + Package.OverridenOptions.ToString(); + + Metadata.Title = CoreTools.Translate( + "{package} Installation", + new Dictionary { { "package", Package.Name } } + ); Metadata.Status = CoreTools.Translate("{0} is being installed", Package.Name); Metadata.SuccessTitle = CoreTools.Translate("Installation succeeded"); - Metadata.SuccessMessage = CoreTools.Translate("{package} was installed successfully", new Dictionary { { "package", Package.Name } }); - Metadata.FailureTitle = CoreTools.Translate("Installation failed", new Dictionary { { "package", Package.Name } }); - Metadata.FailureMessage = CoreTools.Translate("{package} could not be installed", new Dictionary { { "package", Package.Name } }); + Metadata.SuccessMessage = CoreTools.Translate( + "{package} was installed successfully", + new Dictionary { { "package", Package.Name } } + ); + Metadata.FailureTitle = CoreTools.Translate( + "Installation failed", + new Dictionary { { "package", Package.Name } } + ); + Metadata.FailureMessage = CoreTools.Translate( + "{package} could not be installed", + new Dictionary { { "package", Package.Name } } + ); if (Settings.Get(Settings.K.AskToDeleteNewDesktopShortcuts)) { @@ -255,15 +318,13 @@ protected override void Initialize() public class UpdatePackageOperation : PackageOperation { - public UpdatePackageOperation( IPackage package, InstallOptions options, bool IgnoreParallelInstalls = false, - AbstractOperation? req = null) - : base(package, options, OperationType.Update, IgnoreParallelInstalls, req) - { - } + AbstractOperation? req = null + ) + : base(package, options, OperationType.Update, IgnoreParallelInstalls, req) { } protected override Task HandleFailure() { @@ -286,23 +347,51 @@ protected override async Task HandleSuccess() DesktopShortcutsDatabase.HandleNewShortcuts(DesktopShortcutsBeforeStart); } - if (await Package.HasUpdatesIgnoredAsync() && await Package.GetIgnoredUpdatesVersionAsync() != "*") + if ( + await Package.HasUpdatesIgnoredAsync() + && await Package.GetIgnoredUpdatesVersionAsync() != "*" + ) await Package.RemoveFromIgnoredUpdatesAsync(); } protected override void Initialize() { - Metadata.OperationInformation = "Package update operation for Package=" + Package.Id + " with Manager=" + - Package.Manager.Name + "\nInstallation options: " + Options.ToString() - + "\nOverriden options: " + Package.OverridenOptions.ToString() + - "\nVersion: " + Package.VersionString + " -> " + Package.NewVersionString; - - Metadata.Title = CoreTools.Translate("{package} Update", new Dictionary { { "package", Package.Name } }); - Metadata.Status = CoreTools.Translate("{0} is being updated to version {1}", Package.Name, Package.NewVersionString); + Metadata.OperationInformation = + "Package update operation for Package=" + + Package.Id + + " with Manager=" + + Package.Manager.Name + + "\nInstallation options: " + + Options.ToString() + + "\nOverriden options: " + + Package.OverridenOptions.ToString() + + "\nVersion: " + + Package.VersionString + + " -> " + + Package.NewVersionString; + + Metadata.Title = CoreTools.Translate( + "{package} Update", + new Dictionary { { "package", Package.Name } } + ); + Metadata.Status = CoreTools.Translate( + "{0} is being updated to version {1}", + Package.Name, + Package.NewVersionString + ); Metadata.SuccessTitle = CoreTools.Translate("Update succeeded"); - Metadata.SuccessMessage = CoreTools.Translate("{package} was updated successfully", new Dictionary { { "package", Package.Name } }); - Metadata.FailureTitle = CoreTools.Translate("Update failed", new Dictionary { { "package", Package.Name } }); - Metadata.FailureMessage = CoreTools.Translate("{package} could not be updated", new Dictionary { { "package", Package.Name } }); + Metadata.SuccessMessage = CoreTools.Translate( + "{package} was updated successfully", + new Dictionary { { "package", Package.Name } } + ); + Metadata.FailureTitle = CoreTools.Translate( + "Update failed", + new Dictionary { { "package", Package.Name } } + ); + Metadata.FailureMessage = CoreTools.Translate( + "{package} could not be updated", + new Dictionary { { "package", Package.Name } } + ); if (Settings.Get(Settings.K.AskToDeleteNewDesktopShortcuts)) { @@ -313,14 +402,13 @@ protected override void Initialize() public class UninstallPackageOperation : PackageOperation { - public UninstallPackageOperation( IPackage package, InstallOptions options, bool IgnoreParallelInstalls = false, - AbstractOperation? req = null) - : base(package, options, OperationType.Uninstall, IgnoreParallelInstalls, req) - { } + AbstractOperation? req = null + ) + : base(package, options, OperationType.Uninstall, IgnoreParallelInstalls, req) { } protected override Task HandleFailure() { @@ -340,16 +428,34 @@ protected override Task HandleSuccess() protected override void Initialize() { - Metadata.OperationInformation = "Package uninstall operation for Package=" + Package.Id + " with Manager=" + - Package.Manager.Name + "\nInstallation options: " + Options.ToString() - + "\nOverriden options: " + Package.OverridenOptions.ToString(); - - Metadata.Title = CoreTools.Translate("{package} Uninstall", new Dictionary { { "package", Package.Name } }); + Metadata.OperationInformation = + "Package uninstall operation for Package=" + + Package.Id + + " with Manager=" + + Package.Manager.Name + + "\nInstallation options: " + + Options.ToString() + + "\nOverriden options: " + + Package.OverridenOptions.ToString(); + + Metadata.Title = CoreTools.Translate( + "{package} Uninstall", + new Dictionary { { "package", Package.Name } } + ); Metadata.Status = CoreTools.Translate("{0} is being uninstalled", Package.Name); Metadata.SuccessTitle = CoreTools.Translate("Uninstall succeeded"); - Metadata.SuccessMessage = CoreTools.Translate("{package} was uninstalled successfully", new Dictionary { { "package", Package.Name } }); - Metadata.FailureTitle = CoreTools.Translate("Uninstall failed", new Dictionary { { "package", Package.Name } }); - Metadata.FailureMessage = CoreTools.Translate("{package} could not be uninstalled", new Dictionary { { "package", Package.Name } }); + Metadata.SuccessMessage = CoreTools.Translate( + "{package} was uninstalled successfully", + new Dictionary { { "package", Package.Name } } + ); + Metadata.FailureTitle = CoreTools.Translate( + "Uninstall failed", + new Dictionary { { "package", Package.Name } } + ); + Metadata.FailureMessage = CoreTools.Translate( + "{package} could not be uninstalled", + new Dictionary { { "package", Package.Name } } + ); } } } diff --git a/src/UniGetUI.PackageEngine.Operations/PrePostOperation.cs b/src/UniGetUI.PackageEngine.Operations/PrePostOperation.cs index 372f6ef02f..692db4b176 100644 --- a/src/UniGetUI.PackageEngine.Operations/PrePostOperation.cs +++ b/src/UniGetUI.PackageEngine.Operations/PrePostOperation.cs @@ -6,7 +6,9 @@ namespace UniGetUI.PackageEngine.Operations; public class PrePostOperation : AbstractOperation { private readonly string Payload; - public PrePostOperation(string payload) : base(true) + + public PrePostOperation(string payload) + : base(true) { Payload = payload.Replace("\r", "\n").Replace("\n\n", "\n").Replace("\n", "&"); Metadata.Status = $"Running custom operation {Payload}"; @@ -16,12 +18,9 @@ public PrePostOperation(string payload) : base(true) Metadata.SuccessMessage = $"Done!"; Metadata.FailureTitle = $"Custom operation failed"; Metadata.FailureMessage = $"The custom operation {Payload} failed to run"; - } - protected override void ApplyRetryAction(string retryMode) - { - } + protected override void ApplyRetryAction(string retryMode) { } protected override async Task PerformOperation() { @@ -35,8 +34,8 @@ protected override async Task PerformOperation() RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, - CreateNoWindow = true - } + CreateNoWindow = true, + }, }; process.Start(); @@ -44,11 +43,13 @@ protected override async Task PerformOperation() process.BeginOutputReadLine(); process.OutputDataReceived += (s, e) => { - if (e.Data is not null) Line(e.Data, LineType.Information); + if (e.Data is not null) + Line(e.Data, LineType.Information); }; process.ErrorDataReceived += (s, e) => { - if (e.Data is not null) Line(e.Data, LineType.Error); + if (e.Data is not null) + Line(e.Data, LineType.Error); }; await process.WaitForExitAsync(); @@ -57,7 +58,5 @@ protected override async Task PerformOperation() return (exitCode == 0 ? OperationVeredict.Success : OperationVeredict.Failure); } - public override Task GetOperationIcon() - => Task.FromResult(new Uri("about:blank")); - + public override Task GetOperationIcon() => Task.FromResult(new Uri("about:blank")); } diff --git a/src/UniGetUI.PackageEngine.Operations/SourceOperations.cs b/src/UniGetUI.PackageEngine.Operations/SourceOperations.cs index bead74ecc0..65954aa182 100644 --- a/src/UniGetUI.PackageEngine.Operations/SourceOperations.cs +++ b/src/UniGetUI.PackageEngine.Operations/SourceOperations.cs @@ -10,7 +10,6 @@ namespace UniGetUI.PackageEngine.Operations { - public abstract class SourceOperation : AbstractProcessOperation { protected abstract void Initialize(); @@ -18,9 +17,7 @@ public abstract class SourceOperation : AbstractProcessOperation protected IManagerSource Source; public bool ForceAsAdministrator { get; private set; } - public SourceOperation( - IManagerSource source, - IReadOnlyList? preOps) + public SourceOperation(IManagerSource source, IReadOnlyList? preOps) : base(false, preOps) { Source = source; @@ -29,12 +26,14 @@ public SourceOperation( public override Task GetOperationIcon() { - return Task.FromResult(new Uri($"ms-appx:///Assets/Images/{Source.Manager.Properties.ColorIconId}.png")); + return Task.FromResult( + new Uri($"ms-appx:///Assets/Images/{Source.Manager.Properties.ColorIconId}.png") + ); } - protected bool RequiresAdminRights() - => !Settings.Get(Settings.K.ProhibitElevation) - && (ForceAsAdministrator || Source.Manager.Capabilities.Sources.MustBeInstalledAsAdmin); + protected bool RequiresAdminRights() => + !Settings.Get(Settings.K.ProhibitElevation) + && (ForceAsAdministrator || Source.Manager.Capabilities.Sources.MustBeInstalledAsAdmin); protected override void ApplyRetryAction(string retryMode) { @@ -46,23 +45,37 @@ protected override void ApplyRetryAction(string retryMode) ForceAsAdministrator = true; break; default: - throw new InvalidOperationException($"Retry mode {retryMode} is not supported in this context"); + throw new InvalidOperationException( + $"Retry mode {retryMode} is not supported in this context" + ); } } - public static IReadOnlyList CreateInstallPreOps(IManagerSource source, bool forceLocalWinGet) + public static IReadOnlyList CreateInstallPreOps( + IManagerSource source, + bool forceLocalWinGet + ) { - if (!IsWinGetManager(source.Manager)) return []; - if (forceLocalWinGet) return []; - if (source.Manager.Status.ExecutablePath == GetBundledWinGetPath()) return []; + if (!IsWinGetManager(source.Manager)) + return []; + if (forceLocalWinGet) + return []; + if (source.Manager.Status.ExecutablePath == GetBundledWinGetPath()) + return []; return [new(new AddSourceOperation(source, true), mustSucceed: true)]; } - public static IReadOnlyList CreateUninstallPreOps(IManagerSource source, bool forceLocalWinGet) + public static IReadOnlyList CreateUninstallPreOps( + IManagerSource source, + bool forceLocalWinGet + ) { - if (!IsWinGetManager(source.Manager)) return []; - if (forceLocalWinGet) return []; - if (source.Manager.Status.ExecutablePath == GetBundledWinGetPath()) return []; + if (!IsWinGetManager(source.Manager)) + return []; + if (forceLocalWinGet) + return []; + if (source.Manager.Status.ExecutablePath == GetBundledWinGetPath()) + return []; // In this case, must succeed is set to false since we cannot ensure that bundled WinGet will // have this source added return [new(new RemoveSourceOperation(source, true), mustSucceed: false)]; @@ -90,6 +103,7 @@ protected static bool IsWinGetManager(IPackageManager manager) public class AddSourceOperation : SourceOperation { private readonly bool _forceLocalWinGet; + public AddSourceOperation(IManagerSource source, bool forceLocalWinGet = false) : base(source, CreateInstallPreOps(source, forceLocalWinGet)) { @@ -107,7 +121,10 @@ protected override void PrepareProcessStartInfo() bool admin = false; if (RequiresAdminRights()) { - if (Settings.Get(Settings.K.DoCacheAdminRights) || Settings.Get(Settings.K.DoCacheAdminRightsForBatches)) + if ( + Settings.Get(Settings.K.DoCacheAdminRights) + || Settings.Get(Settings.K.DoCacheAdminRightsForBatches) + ) RequestCachingOfUACPrompt(); if (IsWinGetManager(Source.Manager)) @@ -115,42 +132,84 @@ protected override void PrepareProcessStartInfo() admin = true; process.StartInfo.FileName = CoreData.ElevatorPath; - process.StartInfo.Arguments = $"\"{exePath}\" " + Source.Manager.Status.ExecutableCallArgs + " " + string.Join(" ", Source.Manager.SourcesHelper.GetAddSourceParameters(Source)); - + process.StartInfo.Arguments = + $"\"{exePath}\" " + + Source.Manager.Status.ExecutableCallArgs + + " " + + string.Join(" ", Source.Manager.SourcesHelper.GetAddSourceParameters(Source)); } else { process.StartInfo.FileName = exePath; - process.StartInfo.Arguments = Source.Manager.Status.ExecutableCallArgs + " " + string.Join(" ", Source.Manager.SourcesHelper.GetAddSourceParameters(Source)); + process.StartInfo.Arguments = + Source.Manager.Status.ExecutableCallArgs + + " " + + string.Join(" ", Source.Manager.SourcesHelper.GetAddSourceParameters(Source)); } - ApplyCapabilities(admin, false, false, null); + ApplyCapabilities(admin, false, false, null); } - protected override Task GetProcessVeredict(int ReturnCode, List Output) + protected override Task GetProcessVeredict( + int ReturnCode, + List Output + ) { - return Task.Run(() => Source.Manager.SourcesHelper.GetAddOperationVeredict(Source, ReturnCode, Output.ToArray())); + return Task.Run(() => + Source.Manager.SourcesHelper.GetAddOperationVeredict( + Source, + ReturnCode, + Output.ToArray() + ) + ); } protected override void Initialize() { - Metadata.OperationInformation = "Starting adding source operation for source=" + Source.Name + - "with Manager=" + Source.Manager.Name; + Metadata.OperationInformation = + "Starting adding source operation for source=" + + Source.Name + + "with Manager=" + + Source.Manager.Name; - Metadata.Title = CoreTools.Translate("Adding source {source}", new Dictionary { { "source", Source.Name } }); - Metadata.Status = CoreTools.Translate("Adding source {source} to {manager}", new Dictionary { { "source", Source.Name }, { "manager", Source.Manager.Name } });; + Metadata.Title = CoreTools.Translate( + "Adding source {source}", + new Dictionary { { "source", Source.Name } } + ); + Metadata.Status = CoreTools.Translate( + "Adding source {source} to {manager}", + new Dictionary + { + { "source", Source.Name }, + { "manager", Source.Manager.Name }, + } + ); + ; Metadata.SuccessTitle = CoreTools.Translate("Source added successfully"); - Metadata.SuccessMessage = CoreTools.Translate("The source {source} was added to {manager} successfully", - new Dictionary { { "source", Source.Name }, { "manager", Source.Manager.Name } }); + Metadata.SuccessMessage = CoreTools.Translate( + "The source {source} was added to {manager} successfully", + new Dictionary + { + { "source", Source.Name }, + { "manager", Source.Manager.Name }, + } + ); Metadata.FailureTitle = CoreTools.Translate("Could not add source"); - Metadata.FailureMessage = CoreTools.Translate("Could not add source {source} to {manager}", - new Dictionary { { "source", Source.Name }, { "manager", Source.Manager.Name } }); + Metadata.FailureMessage = CoreTools.Translate( + "Could not add source {source} to {manager}", + new Dictionary + { + { "source", Source.Name }, + { "manager", Source.Manager.Name }, + } + ); } } public class RemoveSourceOperation : SourceOperation { private readonly bool _forceLocalWinGet; + public RemoveSourceOperation(IManagerSource source, bool forceLocalWinGet = false) : base(source, CreateUninstallPreOps(source, forceLocalWinGet)) { @@ -167,7 +226,10 @@ protected override void PrepareProcessStartInfo() bool admin = false; if (RequiresAdminRights()) { - if (Settings.Get(Settings.K.DoCacheAdminRights) || Settings.Get(Settings.K.DoCacheAdminRightsForBatches)) + if ( + Settings.Get(Settings.K.DoCacheAdminRights) + || Settings.Get(Settings.K.DoCacheAdminRightsForBatches) + ) RequestCachingOfUACPrompt(); if (IsWinGetManager(Source.Manager)) @@ -175,33 +237,82 @@ protected override void PrepareProcessStartInfo() admin = true; process.StartInfo.FileName = CoreData.ElevatorPath; - process.StartInfo.Arguments = $"\"{exePath}\" " + Source.Manager.Status.ExecutableCallArgs + " " + string.Join(" ", Source.Manager.SourcesHelper.GetRemoveSourceParameters(Source)); + process.StartInfo.Arguments = + $"\"{exePath}\" " + + Source.Manager.Status.ExecutableCallArgs + + " " + + string.Join( + " ", + Source.Manager.SourcesHelper.GetRemoveSourceParameters(Source) + ); } else { process.StartInfo.FileName = exePath; - process.StartInfo.Arguments = Source.Manager.Status.ExecutableCallArgs + " " + string.Join(" ", Source.Manager.SourcesHelper.GetRemoveSourceParameters(Source)); + process.StartInfo.Arguments = + Source.Manager.Status.ExecutableCallArgs + + " " + + string.Join( + " ", + Source.Manager.SourcesHelper.GetRemoveSourceParameters(Source) + ); } ApplyCapabilities(admin, false, false, null); } - protected override Task GetProcessVeredict(int ReturnCode, List Output) + protected override Task GetProcessVeredict( + int ReturnCode, + List Output + ) { - return Task.Run(() => Source.Manager.SourcesHelper.GetRemoveOperationVeredict(Source, ReturnCode, Output.ToArray())); + return Task.Run(() => + Source.Manager.SourcesHelper.GetRemoveOperationVeredict( + Source, + ReturnCode, + Output.ToArray() + ) + ); } protected override void Initialize() { - Metadata.OperationInformation = "Starting remove source operation for source=" + Source.Name + "with Manager=" + Source.Manager.Name; + Metadata.OperationInformation = + "Starting remove source operation for source=" + + Source.Name + + "with Manager=" + + Source.Manager.Name; - Metadata.Title = CoreTools.Translate("Removing source {source}", new Dictionary { { "source", Source.Name } }); - Metadata.Status = CoreTools.Translate("Removing source {source} from {manager}", new Dictionary { { "source", Source.Name }, { "manager", Source.Manager.Name } });; + Metadata.Title = CoreTools.Translate( + "Removing source {source}", + new Dictionary { { "source", Source.Name } } + ); + Metadata.Status = CoreTools.Translate( + "Removing source {source} from {manager}", + new Dictionary + { + { "source", Source.Name }, + { "manager", Source.Manager.Name }, + } + ); + ; Metadata.SuccessTitle = CoreTools.Translate("Source removed successfully"); - Metadata.SuccessMessage = CoreTools.Translate("The source {source} was removed from {manager} successfully", - new Dictionary { { "source", Source.Name }, { "manager", Source.Manager.Name } }); + Metadata.SuccessMessage = CoreTools.Translate( + "The source {source} was removed from {manager} successfully", + new Dictionary + { + { "source", Source.Name }, + { "manager", Source.Manager.Name }, + } + ); Metadata.FailureTitle = CoreTools.Translate("Could not remove source"); - Metadata.FailureMessage = CoreTools.Translate("Could not remove source {source} from {manager}", - new Dictionary { { "source", Source.Name }, { "manager", Source.Manager.Name } }); + Metadata.FailureMessage = CoreTools.Translate( + "Could not remove source {source} from {manager}", + new Dictionary + { + { "source", Source.Name }, + { "manager", Source.Manager.Name }, + } + ); } } } diff --git a/src/UniGetUI.PackageEngine.Operations/UniGetUI.PackageEngine.Operations.csproj b/src/UniGetUI.PackageEngine.Operations/UniGetUI.PackageEngine.Operations.csproj index b4a1fe2c19..6b664b6de2 100644 --- a/src/UniGetUI.PackageEngine.Operations/UniGetUI.PackageEngine.Operations.csproj +++ b/src/UniGetUI.PackageEngine.Operations/UniGetUI.PackageEngine.Operations.csproj @@ -1,4 +1,7 @@ + + $(SharedTargetFrameworks) + diff --git a/src/UniGetUI.PackageEngine.PackageEngine/PEInterface.cs b/src/UniGetUI.PackageEngine.PackageEngine/PEInterface.cs index 45a3fcc1f3..06fc5eed2e 100644 --- a/src/UniGetUI.PackageEngine.PackageEngine/PEInterface.cs +++ b/src/UniGetUI.PackageEngine.PackageEngine/PEInterface.cs @@ -24,7 +24,6 @@ namespace UniGetUI.PackageEngine public static class PEInterface { private const int ManagerLoadTimeout = 60; // 60 seconds timeout for Package Manager initialization (in seconds) - #if WINDOWS public static readonly WinGet WinGet = new(); public static readonly Scoop Scoop = new(); @@ -90,9 +89,8 @@ public static void LoadManagers() public class PackageBundlesLoader_I : PackageBundlesLoader { - public PackageBundlesLoader_I(IReadOnlyList managers): base(managers) - { - } + public PackageBundlesLoader_I(IReadOnlyList managers) + : base(managers) { } public override async Task AddPackagesAsync(IReadOnlyList foreign_packages) { @@ -105,32 +103,49 @@ public override async Task AddPackagesAsync(IReadOnlyList foreign_pack { if (native.Source.IsVirtualManager) { - Logger.Debug($"Adding native package with id={native.Id} to bundle as an INVALID package..."); - package = new InvalidImportedPackage(native.AsSerializable_Incompatible(), NullSource.Instance); + Logger.Debug( + $"Adding native package with id={native.Id} to bundle as an INVALID package..." + ); + package = new InvalidImportedPackage( + native.AsSerializable_Incompatible(), + NullSource.Instance + ); } else { - Logger.Debug($"Adding native package with id={native.Id} to bundle as a VALID package..."); - package = new ImportedPackage(await native.AsSerializableAsync(), native.Manager, native.Source); + Logger.Debug( + $"Adding native package with id={native.Id} to bundle as a VALID package..." + ); + package = new ImportedPackage( + await native.AsSerializableAsync(), + native.Manager, + native.Source + ); } } else if (foreign is ImportedPackage imported) { - Logger.Debug($"Adding loaded imported package with id={imported.Id} to bundle..."); + Logger.Debug( + $"Adding loaded imported package with id={imported.Id} to bundle..." + ); package = imported; } else if (foreign is InvalidImportedPackage invalid) { - Logger.Debug($"Adding loaded incompatible package with id={invalid.Id} to bundle..."); + Logger.Debug( + $"Adding loaded incompatible package with id={invalid.Id} to bundle..." + ); package = invalid; } else { - Logger.Error($"An IPackage instance id={foreign.Id} did not match the types Package, ImportedPackage or InvalidImportedPackage. This should never be the case"); + Logger.Error( + $"An IPackage instance id={foreign.Id} did not match the types Package, ImportedPackage or InvalidImportedPackage. This should never be the case" + ); } if (package is not null) - { // Here, AddForeign is not used so a single PackagesChangedEvent can be invoked. + { // Here, AddForeign is not used so a single PackagesChangedEvent can be invoked. await AddPackage(package); added.Add(package); } diff --git a/src/UniGetUI.PackageEngine.PackageEngine/UniGetUI.PackageEngine.PEInterface.csproj b/src/UniGetUI.PackageEngine.PackageEngine/UniGetUI.PackageEngine.PEInterface.csproj index e44ad4e6a7..de7b506261 100644 --- a/src/UniGetUI.PackageEngine.PackageEngine/UniGetUI.PackageEngine.PEInterface.csproj +++ b/src/UniGetUI.PackageEngine.PackageEngine/UniGetUI.PackageEngine.PEInterface.csproj @@ -1,37 +1,40 @@ + + $(SharedTargetFrameworks) + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + - - - + + + - - - + + + diff --git a/src/UniGetUI.PackageEngine.PackageLoader/AbstractPackageLoader.cs b/src/UniGetUI.PackageEngine.PackageLoader/AbstractPackageLoader.cs index 4dd16cb2bb..ad85de9a73 100644 --- a/src/UniGetUI.PackageEngine.PackageLoader/AbstractPackageLoader.cs +++ b/src/UniGetUI.PackageEngine.PackageLoader/AbstractPackageLoader.cs @@ -7,7 +7,11 @@ namespace UniGetUI.PackageEngine.PackageLoader { public class PackagesChangedEvent { - public PackagesChangedEvent(bool proceduralChange, IReadOnlyList addedPackages, IReadOnlyList removedPackages) + public PackagesChangedEvent( + bool proceduralChange, + IReadOnlyList addedPackages, + IReadOnlyList removedPackages + ) { ProceduralChange = proceduralChange; AddedPackages = addedPackages; @@ -75,7 +79,8 @@ public AbstractPackageLoader( bool AllowMultiplePackageVersions, bool DisableReload, bool CheckedBydefault, - bool RequiresInternet) + bool RequiresInternet + ) { Managers = managers; PackageReference = new ConcurrentDictionary(); @@ -97,10 +102,15 @@ public void StopLoading(bool emitFinishSignal = true) LoadOperationIdentifier = -1; IsLoaded = false; IsLoading = false; - if (emitFinishSignal) InvokeFinishedLoadingEvent(); + if (emitFinishSignal) + InvokeFinishedLoadingEvent(); } - protected void InvokePackagesChangedEvent(bool proceduralChange, IReadOnlyList toAdd, IReadOnlyList toRemove) + protected void InvokePackagesChangedEvent( + bool proceduralChange, + IReadOnlyList toAdd, + IReadOnlyList toRemove + ) { PackagesChanged?.Invoke(this, new(proceduralChange, toAdd, toRemove)); } @@ -151,7 +161,9 @@ public virtual async Task ReloadPackages() { if (manager.IsReady()) { - Task> task = Task.Run(() => LoadPackagesFromManager(manager)); + Task> task = Task.Run(() => + LoadPackagesFromManager(manager) + ); tasks.Add(task); } } @@ -167,7 +179,10 @@ public virtual async Task ReloadPackages() if (task.IsCompleted) { - if (LoadOperationIdentifier == current_identifier && task.IsCompletedSuccessfully) + if ( + LoadOperationIdentifier == current_identifier + && task.IsCompletedSuccessfully + ) { var toAdd = new List(); foreach (IPackage package in task.Result) diff --git a/src/UniGetUI.PackageEngine.PackageLoader/DiscoverablePackagesLoader.cs b/src/UniGetUI.PackageEngine.PackageLoader/DiscoverablePackagesLoader.cs index 1622ad34e9..64eff070cf 100644 --- a/src/UniGetUI.PackageEngine.PackageLoader/DiscoverablePackagesLoader.cs +++ b/src/UniGetUI.PackageEngine.PackageLoader/DiscoverablePackagesLoader.cs @@ -11,12 +11,14 @@ public class DiscoverablePackagesLoader : AbstractPackageLoader private string QUERY_TEXT = string.Empty; public DiscoverablePackagesLoader(IReadOnlyList managers) - : base(managers, + : base( + managers, identifier: "DISCOVERABLE_PACKAGES", AllowMultiplePackageVersions: false, DisableReload: false, CheckedBydefault: false, - RequiresInternet: true) + RequiresInternet: true + ) { Instance = this; } @@ -51,7 +53,7 @@ protected override IReadOnlyList LoadPackagesFromManager(IPackageManag return []; } - return manager.FindPackages(text); + return manager.FindPackages(text); } protected override Task WhenAddingPackage(IPackage package) @@ -67,7 +69,11 @@ protected override Task WhenAddingPackage(IPackage package) return Task.CompletedTask; } - public (IPackage?, string?) GetPackageFromIdAndManager(string id, string managerName, string sourceName) + public (IPackage?, string?) GetPackageFromIdAndManager( + string id, + string managerName, + string sourceName + ) { IPackageManager? manager = null; @@ -81,19 +87,41 @@ protected override Task WhenAddingPackage(IPackage package) } if (manager is null) - return (null, CoreTools.Translate("The package manager \"{0}\" was not found", managerName)); + return ( + null, + CoreTools.Translate("The package manager \"{0}\" was not found", managerName) + ); if (!manager.IsEnabled()) - return (null, CoreTools.Translate("The package manager \"{0}\" is disabled", manager.DisplayName)); + return ( + null, + CoreTools.Translate( + "The package manager \"{0}\" is disabled", + manager.DisplayName + ) + ); if (!manager.Status.Found) - return (null, CoreTools.Translate("There is an error with the configuration of the package manager \"{0}\"", manager.DisplayName)); + return ( + null, + CoreTools.Translate( + "There is an error with the configuration of the package manager \"{0}\"", + manager.DisplayName + ) + ); var results = manager.FindPackages(id); var candidates = results.Where(p => p.Id == id).ToArray(); if (candidates.Length == 0) - return (null, CoreTools.Translate("The package \"{0}\" was not found on the package manager \"{1}\"", id, manager.DisplayName)); + return ( + null, + CoreTools.Translate( + "The package \"{0}\" was not found on the package manager \"{1}\"", + id, + manager.DisplayName + ) + ); IPackage package = candidates[0]; diff --git a/src/UniGetUI.PackageEngine.PackageLoader/InstalledPackagesLoader.cs b/src/UniGetUI.PackageEngine.PackageLoader/InstalledPackagesLoader.cs index d9127fbc93..abba4cbff9 100644 --- a/src/UniGetUI.PackageEngine.PackageLoader/InstalledPackagesLoader.cs +++ b/src/UniGetUI.PackageEngine.PackageLoader/InstalledPackagesLoader.cs @@ -9,13 +9,14 @@ public class InstalledPackagesLoader : AbstractPackageLoader public static InstalledPackagesLoader Instance = null!; public InstalledPackagesLoader(IReadOnlyList managers) - : base( - managers, - identifier: "INSTALLED_PACKAGES", - AllowMultiplePackageVersions: true, - DisableReload: false, - CheckedBydefault: false, - RequiresInternet: true) + : base( + managers, + identifier: "INSTALLED_PACKAGES", + AllowMultiplePackageVersions: true, + DisableReload: false, + CheckedBydefault: false, + RequiresInternet: true + ) { Instance = this; } @@ -63,7 +64,9 @@ public async Task ReloadPackagesSilently() { if (manager.IsEnabled() && manager.Status.Found) { - Task> task = Task.Run(() => LoadPackagesFromManager(manager)); + Task> task = Task.Run(() => + LoadPackagesFromManager(manager) + ); tasks.Add(task); } } @@ -89,7 +92,9 @@ public async Task ReloadPackagesSilently() continue; } - Logger.ImportantInfo($"Adding missing package {package.Id} to installed packages list"); + Logger.ImportantInfo( + $"Adding missing package {package.Id} to installed packages list" + ); toAdd.Add(package); await AddPackage(package); } diff --git a/src/UniGetUI.PackageEngine.PackageLoader/PackageBundlesLoader.cs b/src/UniGetUI.PackageEngine.PackageLoader/PackageBundlesLoader.cs index f1f1c84c20..01ffdd1340 100644 --- a/src/UniGetUI.PackageEngine.PackageLoader/PackageBundlesLoader.cs +++ b/src/UniGetUI.PackageEngine.PackageLoader/PackageBundlesLoader.cs @@ -8,12 +8,14 @@ public abstract class PackageBundlesLoader : AbstractPackageLoader public static PackageBundlesLoader Instance = null!; public PackageBundlesLoader(IReadOnlyList managers) - : base(managers, - identifier: "PACKAGE_BUNDLES", - AllowMultiplePackageVersions: true, - DisableReload: true, - CheckedBydefault: false, - RequiresInternet: false) + : base( + managers, + identifier: "PACKAGE_BUNDLES", + AllowMultiplePackageVersions: true, + DisableReload: true, + CheckedBydefault: false, + RequiresInternet: false + ) { Instance = this; } @@ -50,9 +52,10 @@ protected override Task WhenAddingPackage(IPackage package) public void RemoveRange(IReadOnlyList packages) { - foreach(IPackage package in packages) + foreach (IPackage package in packages) { - if (!Contains(package)) continue; + if (!Contains(package)) + continue; PackageReference.Remove(HashPackage(package), out IPackage? _); } InvokePackagesChangedEvent(true, [], packages); diff --git a/src/UniGetUI.PackageEngine.PackageLoader/UniGetUI.PackageEngine.PackageLoaders.csproj b/src/UniGetUI.PackageEngine.PackageLoader/UniGetUI.PackageEngine.PackageLoaders.csproj index 37e3af7d3f..c28716f384 100644 --- a/src/UniGetUI.PackageEngine.PackageLoader/UniGetUI.PackageEngine.PackageLoaders.csproj +++ b/src/UniGetUI.PackageEngine.PackageLoader/UniGetUI.PackageEngine.PackageLoaders.csproj @@ -1,15 +1,19 @@ - - - - - - - - - + + $(SharedTargetFrameworks) + - - - + + + + + + + + + + + + + diff --git a/src/UniGetUI.PackageEngine.PackageLoader/UpgradablePackagesLoader.cs b/src/UniGetUI.PackageEngine.PackageLoader/UpgradablePackagesLoader.cs index d859886c5c..80008139e7 100644 --- a/src/UniGetUI.PackageEngine.PackageLoader/UpgradablePackagesLoader.cs +++ b/src/UniGetUI.PackageEngine.PackageLoader/UpgradablePackagesLoader.cs @@ -17,12 +17,14 @@ public class UpgradablePackagesLoader : AbstractPackageLoader public ConcurrentDictionary IgnoredPackages = new(); public UpgradablePackagesLoader(IReadOnlyList managers) - : base(managers, - identifier: "UPGRADABLE_PACKAGES", - AllowMultiplePackageVersions: false, - DisableReload: false, - CheckedBydefault: !Settings.Get(Settings.K.DisableSelectingUpdatesByDefault), - RequiresInternet: true) + : base( + managers, + identifier: "UPGRADABLE_PACKAGES", + AllowMultiplePackageVersions: false, + DisableReload: false, + CheckedBydefault: !Settings.Get(Settings.K.DisableSelectingUpdatesByDefault), + RequiresInternet: true + ) { Instance = this; FinishedLoading += (_, _) => StartAutoCheckTimeout(); @@ -38,7 +40,9 @@ protected override async Task IsPackageValid(IPackage package) if (package.IsUpdateMinor() && (await package.GetInstallOptions()).SkipMinorUpdates) { - Logger.Info($"Ignoring package {package.Id} because it is a minor update ({package.VersionString} -> {package.NewVersionString}) and SkipMinorUpdates is set to true."); + Logger.Info( + $"Ignoring package {package.Id} because it is a minor update ({package.VersionString} -> {package.NewVersionString}) and SkipMinorUpdates is set to true." + ); return false; } @@ -60,7 +64,7 @@ protected override Task WhenAddingPackage(IPackage package) { package.GetAvailablePackage()?.SetTag(PackageTag.IsUpgradable); - foreach(var p in package.GetInstalledPackages()) + foreach (var p in package.GetInstalledPackages()) p.SetTag(PackageTag.IsUpgradable); return Task.CompletedTask; @@ -74,11 +78,15 @@ protected void StartAutoCheckTimeout() try { waitTime = long.Parse(Settings.GetValue(Settings.K.UpdatesCheckInterval)); - Logger.Debug($"Starting check for updates wait interval with waitTime={waitTime}"); + Logger.Debug( + $"Starting check for updates wait interval with waitTime={waitTime}" + ); } catch { - Logger.Debug("Invalid value for UpdatesCheckInterval, using default value of 3600 seconds"); + Logger.Debug( + "Invalid value for UpdatesCheckInterval, using default value of 3600 seconds" + ); } if (UpdatesTimer is not null) @@ -90,7 +98,7 @@ protected void StartAutoCheckTimeout() UpdatesTimer = new System.Timers.Timer(waitTime * 1000) { Enabled = false, - AutoReset = false + AutoReset = false, }; UpdatesTimer.Elapsed += (s, e) => _ = ReloadPackages(); UpdatesTimer.Start(); diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Classes/ManagerLogger.cs b/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Classes/ManagerLogger.cs index 7c1babe8fa..f456056583 100644 --- a/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Classes/ManagerLogger.cs +++ b/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Classes/ManagerLogger.cs @@ -9,7 +9,10 @@ public class ManagerLogger : IManagerLogger private readonly IPackageManager Manager; private readonly List operations = []; - public IReadOnlyList Operations { get => (IReadOnlyList)operations; } + public IReadOnlyList Operations + { + get => (IReadOnlyList)operations; + } public ManagerLogger(IPackageManager manager) { @@ -20,10 +23,17 @@ public IProcessTaskLogger CreateNew(LoggableTaskType type, Process process) { if (process.StartInfo is null) { - throw new InvalidOperationException("Given process instance did not have a valid StartInfo value"); + throw new InvalidOperationException( + "Given process instance did not have a valid StartInfo value" + ); } - ProcessTaskLogger operation = new(Manager, type, process.StartInfo.FileName, process.StartInfo.Arguments); + ProcessTaskLogger operation = new( + Manager, + type, + process.StartInfo.FileName, + process.StartInfo.Arguments + ); operations.Add(operation); return operation; } @@ -96,7 +106,12 @@ public class ProcessTaskLogger : TaskLogger, IProcessTaskLogger private readonly List StdOut = []; private readonly List StdErr = []; - public ProcessTaskLogger(IPackageManager manager, LoggableTaskType type, string executable, string arguments) + public ProcessTaskLogger( + IPackageManager manager, + LoggableTaskType type, + string executable, + string arguments + ) { Type = type; Manager = manager; @@ -116,7 +131,9 @@ public void AddToStdIn(IReadOnlyList lines) { if (!isOpen) { - throw new InvalidOperationException("Attempted to write log into an already-closed ProcessTaskLogger"); + throw new InvalidOperationException( + "Attempted to write log into an already-closed ProcessTaskLogger" + ); } foreach (string line in lines) @@ -140,7 +157,9 @@ public void AddToStdOut(IReadOnlyList lines) { if (!isOpen) { - throw new InvalidOperationException("Attempted to write log into an already-closed ProcessTaskLogger"); + throw new InvalidOperationException( + "Attempted to write log into an already-closed ProcessTaskLogger" + ); } foreach (string line in lines) @@ -164,7 +183,9 @@ public void AddToStdErr(IReadOnlyList lines) { if (!isOpen) { - throw new InvalidOperationException("Attempted to write log into an already-closed ProcessTaskLogger"); + throw new InvalidOperationException( + "Attempted to write log into an already-closed ProcessTaskLogger" + ); } foreach (string line in lines) @@ -194,7 +215,9 @@ public override IReadOnlyList AsColoredString(bool verbose = false) $"0Subprocess executable: \"{Executable}\"", $"0Command-line arguments: \"{Arguments}\"", $"0Process start time: {StartTime}", - EndTime is null ? "2Process end time: UNFINISHED" : $"0Process end time: {EndTime}", + EndTime is null + ? "2Process end time: UNFINISHED" + : $"0Process end time: {EndTime}", ]; if (StdIn.Count > 0) @@ -253,7 +276,9 @@ public override IReadOnlyList AsColoredString(bool verbose = false) } else { - result.Add($"2Return code: FAILED (0x{(uint)ReturnCode:X}, {(uint)ReturnCode}, {ReturnCode})"); + result.Add( + $"2Return code: FAILED (0x{(uint)ReturnCode:X}, {(uint)ReturnCode}, {ReturnCode})" + ); } result.Add("0"); @@ -287,7 +312,9 @@ public void Log(IReadOnlyList lines) { if (!isOpen) { - throw new InvalidOperationException("Attempted to write log into an already-closed NativeTaskLogger"); + throw new InvalidOperationException( + "Attempted to write log into an already-closed NativeTaskLogger" + ); } foreach (string line in lines) @@ -311,7 +338,9 @@ public void Error(IReadOnlyList lines) { if (!isOpen) { - throw new InvalidOperationException("Attempted to write log into an already-closed NativeTaskLogger"); + throw new InvalidOperationException( + "Attempted to write log into an already-closed NativeTaskLogger" + ); } foreach (string line in lines) @@ -355,7 +384,9 @@ public override IReadOnlyList AsColoredString(bool verbose = false) [ $"0Logged native task on manager {Manager.Name}. Task type is {Type}", $"0Process start time: {StartTime}", - EndTime is null ? "2Process end time: UNFINISHED" : $"0Process end time: {EndTime}", + EndTime is null + ? "2Process end time: UNFINISHED" + : $"0Process end time: {EndTime}", ]; if (Info.Count > 0) @@ -398,7 +429,9 @@ public override IReadOnlyList AsColoredString(bool verbose = false) } else { - result.Add($"2The task reported a failure (0x{(uint)ReturnCode:X}, {(uint)ReturnCode}, {ReturnCode})"); + result.Add( + $"2The task reported a failure (0x{(uint)ReturnCode:X}, {(uint)ReturnCode}, {ReturnCode})" + ); } result.Add("0"); diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Classes/ManagerSource.cs b/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Classes/ManagerSource.cs index 49fe335715..a1ee6495d7 100644 --- a/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Classes/ManagerSource.cs +++ b/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Classes/ManagerSource.cs @@ -5,7 +5,10 @@ namespace UniGetUI.PackageEngine.Classes.Manager { public class ManagerSource : IManagerSource { - public virtual IconType IconId { get { return Manager.Properties.IconId; } } + public virtual IconType IconId + { + get { return Manager.Properties.IconId; } + } public IPackageManager Manager { get; } public string Name { get; } @@ -17,7 +20,14 @@ public class ManagerSource : IManagerSource public bool IsVirtualManager { get; } - public ManagerSource(IPackageManager manager, string name, Uri url, int? packageCount = 0, string updateDate = "", bool isVirtualManager = false) + public ManagerSource( + IPackageManager manager, + string name, + Uri url, + int? packageCount = 0, + string updateDate = "", + bool isVirtualManager = false + ) { IsVirtualManager = isVirtualManager; Manager = manager; @@ -35,6 +45,7 @@ public ManagerSource(IPackageManager manager, string name, Uri url, int? package } public override string ToString() => AsString; + /// /// Replaces the current URL with the new one. Must be used only when a placeholder URL is used. /// @@ -48,9 +59,13 @@ public void ReplaceUrl(Uri newUrl) ///
public void RefreshSourceNames() { - AsString = Manager.Capabilities.SupportsCustomSources ? $"{Manager.Properties.Name}: {Name}" : Manager.Properties.Name; + AsString = Manager.Capabilities.SupportsCustomSources + ? $"{Manager.Properties.Name}: {Name}" + : Manager.Properties.Name; if (Manager.Properties.DisplayName is string display_name) - AsString_DisplayName = Manager.Capabilities.SupportsCustomSources ? $"{display_name}: {Name}" : display_name; + AsString_DisplayName = Manager.Capabilities.SupportsCustomSources + ? $"{display_name}: {Name}" + : display_name; else AsString_DisplayName = AsString; } diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Classes/NullPackageManager.cs b/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Classes/NullPackageManager.cs index da7178e90c..bbe18012a8 100644 --- a/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Classes/NullPackageManager.cs +++ b/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Classes/NullPackageManager.cs @@ -19,10 +19,22 @@ public class NullPackageManager : IPackageManager public ManagerProperties Properties { get; } public ManagerCapabilities Capabilities { get; } public ManagerStatus Status { get; } - public string Name { get => Properties.Name; } - public string DisplayName { get => Properties.DisplayName ?? Properties.Name; } - public IManagerSource DefaultSource { get => Properties.DefaultSource; } - public bool ManagerReady { get => true; } + public string Name + { + get => Properties.Name; + } + public string DisplayName + { + get => Properties.DisplayName ?? Properties.Name; + } + public IManagerSource DefaultSource + { + get => Properties.DefaultSource; + } + public bool ManagerReady + { + get => true; + } public IManagerLogger TaskLogger { get; } public IMultiSourceHelper SourcesHelper { get; } public IPackageDetailsHelper DetailsHelper { get; } @@ -56,49 +68,88 @@ public NullPackageManager() ExecutablePath = "C:/file.exe", ExecutableCallArgs = "Unset", Found = false, - Version = "0" + Version = "0", }; Dependencies = []; } - public IReadOnlyList FindPackages(string query) => throw new NotImplementedException(); + + public IReadOnlyList FindPackages(string query) => + throw new NotImplementedException(); + public IReadOnlyList GetAvailableUpdates() => throw new NotImplementedException(); - public IReadOnlyList GetInstalledPackages() => throw new NotImplementedException(); + + public IReadOnlyList GetInstalledPackages() => + throw new NotImplementedException(); + public void Initialize() => throw new NotImplementedException(); + public bool IsEnabled() => throw new NotImplementedException(); + public bool IsReady() => throw new NotImplementedException(); + public void RefreshPackageIndexes() => throw new NotImplementedException(); + public void AttemptFastRepair() => throw new NotImplementedException(); - public IReadOnlyList FindCandidateExecutableFiles() => throw new NotImplementedException(); + + public IReadOnlyList FindCandidateExecutableFiles() => + throw new NotImplementedException(); + public Tuple GetExecutableFile() => throw new NotImplementedException(); } internal sealed class NullSourceHelper : IMultiSourceHelper { public ISourceFactory Factory => throw new NotImplementedException(); - public string[] GetAddSourceParameters(IManagerSource source) => throw new NotImplementedException(); - public string[] GetRemoveSourceParameters(IManagerSource source) => throw new NotImplementedException(); - public OperationVeredict GetAddOperationVeredict(IManagerSource source, int ReturnCode, string[] Output) => throw new NotImplementedException(); - public OperationVeredict GetRemoveOperationVeredict(IManagerSource source, int ReturnCode, string[] Output) => throw new NotImplementedException(); - public IReadOnlyList GetSources() => throw new NotImplementedException(); + public string[] GetAddSourceParameters(IManagerSource source) => + throw new NotImplementedException(); + + public string[] GetRemoveSourceParameters(IManagerSource source) => + throw new NotImplementedException(); + + public OperationVeredict GetAddOperationVeredict( + IManagerSource source, + int ReturnCode, + string[] Output + ) => throw new NotImplementedException(); + + public OperationVeredict GetRemoveOperationVeredict( + IManagerSource source, + int ReturnCode, + string[] Output + ) => throw new NotImplementedException(); + + public IReadOnlyList GetSources() => throw new NotImplementedException(); } internal sealed class NullPkgDetailsHelper : IPackageDetailsHelper { public void GetDetails(IPackageDetails details) => throw new NotImplementedException(); - public IReadOnlyList GetVersions(IPackage package) => throw new NotImplementedException(); + + public IReadOnlyList GetVersions(IPackage package) => + throw new NotImplementedException(); + public CacheableIcon? GetIcon(IPackage package) => throw new NotImplementedException(); - public IReadOnlyList GetScreenshots(IPackage package) => throw new NotImplementedException(); + + public IReadOnlyList GetScreenshots(IPackage package) => + throw new NotImplementedException(); + public string? GetInstallLocation(IPackage package) => throw new NotImplementedException(); } internal sealed class NullPkgOperationHelper : IPackageOperationHelper { - public IReadOnlyList GetParameters(IPackage package, InstallOptions options, - OperationType operation) - => throw new NotImplementedException(); + public IReadOnlyList GetParameters( + IPackage package, + InstallOptions options, + OperationType operation + ) => throw new NotImplementedException(); - public OperationVeredict GetResult(IPackage package, OperationType operation, IReadOnlyList processOutput, int returnCode) - => throw new NotImplementedException(); + public OperationVeredict GetResult( + IPackage package, + OperationType operation, + IReadOnlyList processOutput, + int returnCode + ) => throw new NotImplementedException(); } } diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Helpers/BasePkgDetailsHelper.cs b/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Helpers/BasePkgDetailsHelper.cs index 56bd585988..ebb7ab048b 100644 --- a/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Helpers/BasePkgDetailsHelper.cs +++ b/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Helpers/BasePkgDetailsHelper.cs @@ -16,11 +16,19 @@ public BasePkgDetailsHelper(IPackageManager manager) public void GetDetails(IPackageDetails details) { - if (!Manager.IsReady()) { Logger.Warn($"Manager {Manager.Name} is disabled but yet GetPackageDetails was called"); return; } + if (!Manager.IsReady()) + { + Logger.Warn( + $"Manager {Manager.Name} is disabled but yet GetPackageDetails was called" + ); + return; + } try { GetDetails_UnSafe(details); - Logger.Info($"Loaded details for package {details.Package.Id} on manager {Manager.Name}"); + Logger.Info( + $"Loaded details for package {details.Package.Id} on manager {Manager.Name}" + ); } catch (Exception e) { @@ -33,7 +41,9 @@ public IReadOnlyList GetVersions(IPackage package) { if (!Manager.IsReady()) { - Logger.Warn($"Manager {Manager.Name} is disabled but yet GetPackageVersions was called"); + Logger.Warn( + $"Manager {Manager.Name} is disabled but yet GetPackageVersions was called" + ); return []; } try @@ -41,16 +51,23 @@ public IReadOnlyList GetVersions(IPackage package) if (Manager.Capabilities.SupportsCustomVersions) { var result = GetInstallableVersions_UnSafe(package); - Logger.Debug($"Found {result.Count} versions for package Id={package.Id} on manager {Manager.Name}"); + Logger.Debug( + $"Found {result.Count} versions for package Id={package.Id} on manager {Manager.Name}" + ); return result; } - Logger.Warn($"Manager {Manager.Name} does not support version retrieving, this method should have not been called"); + Logger.Warn( + $"Manager {Manager.Name} does not support version retrieving, this method should have not been called" + ); return []; } catch (Exception e) { - Logger.Error($"Error finding available package versions for package {package.Id} on manager " + Manager.Name); + Logger.Error( + $"Error finding available package versions for package {package.Id} on manager " + + Manager.Name + ); Logger.Error(e); return []; } @@ -71,17 +88,25 @@ public IReadOnlyList GetVersions(IPackage package) } // Try to get the icon especially for this package - string? iconUrl = IconDatabase.Instance.GetIconUrlForId(Manager.Name + "." + package.Id); - if (iconUrl is not null) return new CacheableIcon(new Uri(iconUrl)); + string? iconUrl = IconDatabase.Instance.GetIconUrlForId( + Manager.Name + "." + package.Id + ); + if (iconUrl is not null) + return new CacheableIcon(new Uri(iconUrl)); // Try to get other corresponding icons for the package iconUrl = IconDatabase.Instance.GetIconUrlForId(package.GetIconId()); - if (iconUrl is not null) return new CacheableIcon(new Uri(iconUrl)); + if (iconUrl is not null) + return new CacheableIcon(new Uri(iconUrl)); return null; - } catch (Exception e) + } + catch (Exception e) { - Logger.Error($"Error when loading the package icon for the package {package.Id} on manager " + Manager.Name); + Logger.Error( + $"Error when loading the package icon for the package {package.Id} on manager " + + Manager.Name + ); Logger.Error(e); return null; } @@ -106,11 +131,14 @@ public IReadOnlyList GetScreenshots(IPackage package) // Try to get exact screenshots for this package if (!URIs.Any()) { - string[] UrlArray = IconDatabase.Instance.GetScreenshotsUrlForId(Manager.Name + "." + package.Id); + string[] UrlArray = IconDatabase.Instance.GetScreenshotsUrlForId( + Manager.Name + "." + package.Id + ); List UriList = []; foreach (string url in UrlArray) { - if (url != "") UriList.Add(new Uri(url)); + if (url != "") + UriList.Add(new Uri(url)); } URIs = UriList; } @@ -118,11 +146,14 @@ public IReadOnlyList GetScreenshots(IPackage package) // Try to get matching screenshots for this package if (!URIs.Any()) { - string[] UrlArray = IconDatabase.Instance.GetScreenshotsUrlForId(package.GetIconId()); + string[] UrlArray = IconDatabase.Instance.GetScreenshotsUrlForId( + package.GetIconId() + ); List UriList = []; foreach (string url in UrlArray) { - if (url != "") UriList.Add(new Uri(url)); + if (url != "") + UriList.Add(new Uri(url)); } URIs = UriList; } @@ -132,7 +163,10 @@ public IReadOnlyList GetScreenshots(IPackage package) } catch (Exception e) { - Logger.Error($"Error when loading the package icon for the package {package.Id} on manager " + Manager.Name); + Logger.Error( + $"Error when loading the package icon for the package {package.Id} on manager " + + Manager.Name + ); Logger.Error(e); return []; } @@ -151,7 +185,9 @@ public IReadOnlyList GetScreenshots(IPackage package) string? path = GetInstallLocation_UnSafe(package); if (path is not null && !Directory.Exists(path)) { - Logger.Warn($"Path returned by the package manager \"{path}\" did not exist while loading package install location for package Id={package.Id} with Manager={package.Manager.Name}"); + Logger.Warn( + $"Path returned by the package manager \"{path}\" did not exist while loading package install location for package Id={package.Id} with Manager={package.Manager.Name}" + ); return null; } @@ -159,7 +195,9 @@ public IReadOnlyList GetScreenshots(IPackage package) } catch (Exception ex) { - Logger.Error($"An error occurred while loading package install location for package Id={package.Id} with Manager={package.Manager.Name}"); + Logger.Error( + $"An error occurred while loading package install location for package Id={package.Id} with Manager={package.Manager.Name}" + ); Logger.Error(ex); return null; } diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Helpers/BasePkgOperationHelper.cs b/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Helpers/BasePkgOperationHelper.cs index 31c017b42b..497bb9f69d 100644 --- a/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Helpers/BasePkgOperationHelper.cs +++ b/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Helpers/BasePkgOperationHelper.cs @@ -15,37 +15,52 @@ public BasePkgOperationHelper(IPackageManager manager) Manager = manager; } - protected abstract IReadOnlyList _getOperationParameters(IPackage package, + protected abstract IReadOnlyList _getOperationParameters( + IPackage package, InstallOptions options, - OperationType operation); + OperationType operation + ); protected abstract OperationVeredict _getOperationResult( IPackage package, OperationType operation, IReadOnlyList processOutput, - int returnCode); + int returnCode + ); - public IReadOnlyList GetParameters(IPackage package, + public IReadOnlyList GetParameters( + IPackage package, InstallOptions options, - OperationType operation) + OperationType operation + ) { var parameters = _getOperationParameters(package, options, operation); - Logger.Info($"Loaded operation parameters for package id={package.Id} on manager {Manager.Name} and operation {operation}: " + - string.Join(' ', parameters)); + Logger.Info( + $"Loaded operation parameters for package id={package.Id} on manager {Manager.Name} and operation {operation}: " + + string.Join(' ', parameters) + ); return parameters.Where(x => x.Any()).ToArray(); - } public OperationVeredict GetResult( IPackage package, OperationType operation, IReadOnlyList processOutput, - int returnCode) + int returnCode + ) { - - if (returnCode is 999 && (!processOutput.Any() || processOutput[processOutput.Count - 1] == "Error: The operation was canceled by the user.")) + if ( + returnCode is 999 + && ( + !processOutput.Any() + || processOutput[processOutput.Count - 1] + == "Error: The operation was canceled by the user." + ) + ) { - Logger.Warn("Elevator [or GSudo] UAC prompt was canceled, not showing error message..."); + Logger.Warn( + "Elevator [or GSudo] UAC prompt was canceled, not showing error message..." + ); return OperationVeredict.Canceled; } diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Helpers/BaseSourceHelper.cs b/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Helpers/BaseSourceHelper.cs index 93de0d3f8e..d44166e228 100644 --- a/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Helpers/BaseSourceHelper.cs +++ b/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Helpers/BaseSourceHelper.cs @@ -23,26 +23,52 @@ public BaseSourceHelper(IPackageManager manager) public abstract string[] GetAddSourceParameters(IManagerSource source); public abstract string[] GetRemoveSourceParameters(IManagerSource source); - protected abstract OperationVeredict _getAddSourceOperationVeredict(IManagerSource source, int ReturnCode, string[] Output); - protected abstract OperationVeredict _getRemoveSourceOperationVeredict(IManagerSource source, int ReturnCode, string[] Output); + protected abstract OperationVeredict _getAddSourceOperationVeredict( + IManagerSource source, + int ReturnCode, + string[] Output + ); + protected abstract OperationVeredict _getRemoveSourceOperationVeredict( + IManagerSource source, + int ReturnCode, + string[] Output + ); - public OperationVeredict GetAddOperationVeredict(IManagerSource source, int ReturnCode, string[] Output) + public OperationVeredict GetAddOperationVeredict( + IManagerSource source, + int ReturnCode, + string[] Output + ) { TaskRecycler>.RemoveFromCache(_getSources); - if (ReturnCode is 999 && Output.Last() == "Error: The operation was canceled by the user.") + if ( + ReturnCode is 999 + && Output.Last() == "Error: The operation was canceled by the user." + ) { - Logger.Warn("Elevator [or GSudo] UAC prompt was canceled, not showing error message..."); + Logger.Warn( + "Elevator [or GSudo] UAC prompt was canceled, not showing error message..." + ); return OperationVeredict.Canceled; } return _getAddSourceOperationVeredict(source, ReturnCode, Output); } - public OperationVeredict GetRemoveOperationVeredict(IManagerSource source, int ReturnCode, string[] Output) + public OperationVeredict GetRemoveOperationVeredict( + IManagerSource source, + int ReturnCode, + string[] Output + ) { TaskRecycler>.RemoveFromCache(_getSources); - if (ReturnCode is 999 && Output.Last() == "Error: The operation was canceled by the user.") + if ( + ReturnCode is 999 + && Output.Last() == "Error: The operation was canceled by the user." + ) { - Logger.Warn("Elevator [or GSudo] UAC prompt was canceled, not showing error message..."); + Logger.Warn( + "Elevator [or GSudo] UAC prompt was canceled, not showing error message..." + ); return OperationVeredict.Canceled; } return _getRemoveSourceOperationVeredict(source, ReturnCode, Output); @@ -53,8 +79,8 @@ public OperationVeredict GetRemoveOperationVeredict(IManagerSource source, int R ///
protected abstract IReadOnlyList GetSources_UnSafe(); - public virtual IReadOnlyList GetSources() - => TaskRecycler>.RunOrAttach(_getSources, 15); + public virtual IReadOnlyList GetSources() => + TaskRecycler>.RunOrAttach(_getSources, 15); public virtual IReadOnlyList _getSources() { @@ -66,9 +92,11 @@ public virtual IReadOnlyList _getSources() if (!Settings.Get(Settings.K.DisableTimeoutOnPackageListingTasks)) { CoreTools.FinalizeDangerousTask(task); - throw new TimeoutException($"Task _getInstalledPackages for manager {Manager.Name} did not finish after " + - $"{PackageListingTaskTimeout} seconds, aborting. You may disable " + - $"timeouts from UniGetUI Advanced Settings"); + throw new TimeoutException( + $"Task _getInstalledPackages for manager {Manager.Name} did not finish after " + + $"{PackageListingTaskTimeout} seconds, aborting. You may disable " + + $"timeouts from UniGetUI Advanced Settings" + ); } task.Wait(); diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/PackageManager.cs b/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/PackageManager.cs index 8e46a0fbc1..0461a0a688 100644 --- a/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/PackageManager.cs +++ b/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/PackageManager.cs @@ -20,9 +20,18 @@ public abstract class PackageManager : IPackageManager public ManagerProperties Properties { get; set; } = new(IsDummy: true); public ManagerCapabilities Capabilities { get; set; } = new(IsDummy: true); public ManagerStatus Status { get; set; } = new() { Found = false }; - public string Name { get => Properties.Name; } - public string DisplayName { get => Properties.DisplayName ?? Name; } - public IManagerSource DefaultSource { get => Properties.DefaultSource; } + public string Name + { + get => Properties.Name; + } + public string DisplayName + { + get => Properties.DisplayName ?? Name; + } + public IManagerSource DefaultSource + { + get => Properties.DefaultSource; + } public IManagerLogger TaskLogger { get; } public IReadOnlyList Dependencies { get; protected set; } = []; public IMultiSourceHelper SourcesHelper { get; protected set; } = new NullSourceHelper(); @@ -43,8 +52,13 @@ private static void Throw(string message) throw new InvalidDataException(message); } - protected abstract void _loadManagerExecutableFile(out bool found, out string path, out string callArguments); + protected abstract void _loadManagerExecutableFile( + out bool found, + out string path, + out string callArguments + ); protected abstract void _loadManagerVersion(out string version); + protected virtual void _performExtraLoadingSteps() { } public virtual void Initialize() @@ -55,22 +69,29 @@ public virtual void Initialize() _ensurePropertlyConstructed(); if (!IsEnabled()) - { // Do NOT initialise disabled package managers + { // Do NOT initialise disabled package managers Status = new() { Version = CoreTools.Translate("{0} is disabled", DisplayName) }; Logger.ImportantInfo($"{Name} is not enabled"); return; } // Find package manager executable - _loadManagerExecutableFile(out bool found, out string path, out string callArguments); + _loadManagerExecutableFile( + out bool found, + out string path, + out string callArguments + ); Status = new ManagerStatus(); Status.Found = found; Status.ExecutablePath = path; Status.ExecutableCallArgs = callArguments; if (!Status.Found) - { // Do not load version of managers that were not found - Status.Version = CoreTools.Translate("{pm} was not found!").Replace("{pm}", DisplayName).Trim('!'); + { // Do not load version of managers that were not found + Status.Version = CoreTools + .Translate("{pm} was not found!") + .Replace("{pm}", DisplayName) + .Trim('!'); Logger.Error($"{Name} is enabled but was not found on the system!"); return; } @@ -100,15 +121,26 @@ public virtual void Initialize() ///
private void _ensurePropertlyConstructed() { - if (!_baseConstructorCalled) Throw($"The Manager {Properties.Name} has not called the base constructor."); - if (Capabilities.IsDummy) Throw($"The current instance of PackageManager with name ${Properties.Name} does not have a valid Capabilities object"); - if (Properties.IsDummy) Throw($"The current instance of PackageManager with name ${Properties.Name} does not have a valid Properties object"); - - if (OperationHelper is NullPkgOperationHelper) Throw($"Manager {Name} does not have an OperationProvider"); - if (DetailsHelper is NullPkgDetailsHelper) Throw($"Manager {Name} does not have a valid DetailsHelper"); + if (!_baseConstructorCalled) + Throw($"The Manager {Properties.Name} has not called the base constructor."); + if (Capabilities.IsDummy) + Throw( + $"The current instance of PackageManager with name ${Properties.Name} does not have a valid Capabilities object" + ); + if (Properties.IsDummy) + Throw( + $"The current instance of PackageManager with name ${Properties.Name} does not have a valid Properties object" + ); + + if (OperationHelper is NullPkgOperationHelper) + Throw($"Manager {Name} does not have an OperationProvider"); + if (DetailsHelper is NullPkgDetailsHelper) + Throw($"Manager {Name} does not have a valid DetailsHelper"); if (Capabilities.SupportsCustomSources && SourcesHelper is NullSourceHelper) - Throw($"Manager {Name} has been declared as SupportsCustomSources but has no helper associated with it"); + Throw( + $"Manager {Name} has been declared as SupportsCustomSources but has no helper associated with it" + ); } /// @@ -161,17 +193,20 @@ public Tuple GetExecutableFile() if (candidates.Count == 0) { // No paths were found - return new (false, ""); + return new(false, ""); } // If custom package manager paths are DISABLED, get the first one (as old UniGetUI did) and return it. - if(!SecureSettings.Get(SecureSettings.K.AllowCustomManagerPaths)) + if (!SecureSettings.Get(SecureSettings.K.AllowCustomManagerPaths)) { return new(true, candidates[0]); } else { - string? exeSelection = Settings.GetDictionaryItem(Settings.K.ManagerPaths, Name); + string? exeSelection = Settings.GetDictionaryItem( + Settings.K.ManagerPaths, + Name + ); // If there is no executable selection for this package manager if (string.IsNullOrEmpty(exeSelection)) { @@ -179,7 +214,9 @@ public Tuple GetExecutableFile() } else if (!File.Exists(exeSelection)) { - Logger.Error($"The selected executable path {exeSelection} for manager {Name} does not exist, the default one will be used..."); + Logger.Error( + $"The selected executable path {exeSelection} for manager {Name} does not exist, the default one will be used..." + ); return new(true, candidates[0]); } @@ -193,11 +230,12 @@ public Tuple GetExecutableFile() } else { - Logger.Error($"The selected executable path {exeSelection} for manager {Name} was not found among the candidates " + - $"(executables found are [{string.Join(',', candidates)}]), the default will be used..."); + Logger.Error( + $"The selected executable path {exeSelection} for manager {Name} was not found among the candidates " + + $"(executables found are [{string.Join(',', candidates)}]), the default will be used..." + ); return new(true, candidates[0]); } - } } @@ -221,12 +259,15 @@ public bool IsReady() /// Returns an array of Package objects that the manager lists for the given query. Depending on the manager, the list may /// also include similar results. This method is fail-safe and will return an empty array if an error occurs. /// - public IReadOnlyList FindPackages(string query) - => _findPackages(query, false); + public IReadOnlyList FindPackages(string query) => _findPackages(query, false); private IReadOnlyList _findPackages(string query, bool SecondAttempt) { - if (!IsReady()) { Logger.Warn($"Manager {Name} is disabled but yet FindPackages was called"); return []; } + if (!IsReady()) + { + Logger.Warn($"Manager {Name} is disabled but yet FindPackages was called"); + return []; + } try { var task = Task.Run(() => FindPackages_UnSafe(query)); @@ -235,25 +276,36 @@ private IReadOnlyList _findPackages(string query, bool SecondAttempt) if (!Settings.Get(Settings.K.DisableTimeoutOnPackageListingTasks)) { CoreTools.FinalizeDangerousTask(task); - throw new TimeoutException($"Task _getInstalledPackages for manager {Name} did not finish after " + - $"{PackageListingTaskTimeout} seconds, aborting. You may disable " + - $"timeouts from UniGetUI Advanced Settings"); + throw new TimeoutException( + $"Task _getInstalledPackages for manager {Name} did not finish after " + + $"{PackageListingTaskTimeout} seconds, aborting. You may disable " + + $"timeouts from UniGetUI Advanced Settings" + ); } task.Wait(); } var packages = task.GetAwaiter().GetResult(); - Logger.Info($"Found {packages.Count} available packages from {Name} with the query {query}"); + Logger.Info( + $"Found {packages.Count} available packages from {Name} with the query {query}" + ); return packages; } catch (Exception e) { if (!SecondAttempt) { - while (e is AggregateException) e = e.InnerException ?? new InvalidOperationException("How did we get here?"); - Logger.Warn($"Manager {DisplayName} failed to find packages with exception {e.GetType().Name}: {e.Message}"); - Logger.Warn($"Since this was the first attempt, {Name}.AttemptFastRepair() will be called and the procedure will be restarted"); + while (e is AggregateException) + e = + e.InnerException + ?? new InvalidOperationException("How did we get here?"); + Logger.Warn( + $"Manager {DisplayName} failed to find packages with exception {e.GetType().Name}: {e.Message}" + ); + Logger.Warn( + $"Since this was the first attempt, {Name}.AttemptFastRepair() will be called and the procedure will be restarted" + ); AttemptFastRepair(); return _findPackages(query, true); } @@ -268,15 +320,19 @@ private IReadOnlyList _findPackages(string query, bool SecondAttempt) /// Returns an array of UpgradablePackage objects that represent the available updates reported by the manager. /// This method is fail-safe and will return an empty array if an error occurs. ///
- public IReadOnlyList GetAvailableUpdates() - => _getAvailableUpdates(false); + public IReadOnlyList GetAvailableUpdates() => _getAvailableUpdates(false); private IReadOnlyList _getAvailableUpdates(bool SecondAttempt) { - if (!IsReady()) { Logger.Warn($"Manager {Name} is disabled but yet GetAvailableUpdates was called"); return []; } + if (!IsReady()) + { + Logger.Warn($"Manager {Name} is disabled but yet GetAvailableUpdates was called"); + return []; + } try { - Task.Run(RefreshPackageIndexes).Wait(TimeSpan.FromSeconds(PackageListingTaskTimeout)); + Task.Run(RefreshPackageIndexes) + .Wait(TimeSpan.FromSeconds(PackageListingTaskTimeout)); var task = Task.Run(GetAvailableUpdates_UnSafe); if (!task.Wait(TimeSpan.FromSeconds(PackageListingTaskTimeout))) @@ -284,9 +340,11 @@ private IReadOnlyList _getAvailableUpdates(bool SecondAttempt) if (!Settings.Get(Settings.K.DisableTimeoutOnPackageListingTasks)) { CoreTools.FinalizeDangerousTask(task); - throw new TimeoutException($"Task _getInstalledPackages for manager {Name} did not finish after " + - $"{PackageListingTaskTimeout} seconds, aborting. You may disable " + - $"timeouts from UniGetUI Advanced Settings"); + throw new TimeoutException( + $"Task _getInstalledPackages for manager {Name} did not finish after " + + $"{PackageListingTaskTimeout} seconds, aborting. You may disable " + + $"timeouts from UniGetUI Advanced Settings" + ); } task.Wait(); @@ -300,9 +358,16 @@ private IReadOnlyList _getAvailableUpdates(bool SecondAttempt) { if (!SecondAttempt) { - while (e is AggregateException) e = e.InnerException ?? new InvalidOperationException("How did we get here?"); - Logger.Warn($"Manager {DisplayName} failed to list available updates with exception {e.GetType().Name}: {e.Message}"); - Logger.Warn($"Since this was the first attempt, {Name}.AttemptFastRepair() will be called and the procedure will be restarted"); + while (e is AggregateException) + e = + e.InnerException + ?? new InvalidOperationException("How did we get here?"); + Logger.Warn( + $"Manager {DisplayName} failed to list available updates with exception {e.GetType().Name}: {e.Message}" + ); + Logger.Warn( + $"Since this was the first attempt, {Name}.AttemptFastRepair() will be called and the procedure will be restarted" + ); AttemptFastRepair(); return _getAvailableUpdates(true); } @@ -317,12 +382,15 @@ private IReadOnlyList _getAvailableUpdates(bool SecondAttempt) /// Returns an array of Package objects that represent the installed reported by the manager. /// This method is fail-safe and will return an empty array if an error occurs. /// - public IReadOnlyList GetInstalledPackages() - => _getInstalledPackages(false); + public IReadOnlyList GetInstalledPackages() => _getInstalledPackages(false); private IReadOnlyList _getInstalledPackages(bool SecondAttempt) { - if (!IsReady()) { Logger.Warn($"Manager {Name} is disabled but yet GetInstalledPackages was called"); return []; } + if (!IsReady()) + { + Logger.Warn($"Manager {Name} is disabled but yet GetInstalledPackages was called"); + return []; + } try { var task = Task.Run(GetInstalledPackages_UnSafe); @@ -331,9 +399,11 @@ private IReadOnlyList _getInstalledPackages(bool SecondAttempt) if (!Settings.Get(Settings.K.DisableTimeoutOnPackageListingTasks)) { CoreTools.FinalizeDangerousTask(task); - throw new TimeoutException($"Task _getInstalledPackages for manager {Name} did not finish after " + - $"{PackageListingTaskTimeout} seconds, aborting. You may disable " + - $"timeouts from UniGetUI Advanced Settings"); + throw new TimeoutException( + $"Task _getInstalledPackages for manager {Name} did not finish after " + + $"{PackageListingTaskTimeout} seconds, aborting. You may disable " + + $"timeouts from UniGetUI Advanced Settings" + ); } task.Wait(); @@ -347,9 +417,16 @@ private IReadOnlyList _getInstalledPackages(bool SecondAttempt) { if (!SecondAttempt) { - while (e is AggregateException) e = e.InnerException ?? new InvalidOperationException("How did we get here?"); - Logger.Warn($"Manager {DisplayName} failed to list installed packages with exception {e.GetType().Name}: {e.Message}"); - Logger.Warn($"Since this was the first attempt, {Name}.AttemptFastRepair() will be called and the procedure will be restarted"); + while (e is AggregateException) + e = + e.InnerException + ?? new InvalidOperationException("How did we get here?"); + Logger.Warn( + $"Manager {DisplayName} failed to list installed packages with exception {e.GetType().Name}: {e.Message}" + ); + Logger.Warn( + $"Since this was the first attempt, {Name}.AttemptFastRepair() will be called and the procedure will be restarted" + ); AttemptFastRepair(); return _getInstalledPackages(true); } diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Classes/DesktopShortcutsDatabase.cs b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Classes/DesktopShortcutsDatabase.cs index 833bf3afb4..bdad20e735 100644 --- a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Classes/DesktopShortcutsDatabase.cs +++ b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Classes/DesktopShortcutsDatabase.cs @@ -16,7 +16,8 @@ public enum Status public static IReadOnlyDictionary GetDatabase() { - return Settings.GetDictionary(Settings.K.DeletableDesktopShortcuts) ?? new Dictionary(); + return Settings.GetDictionary(Settings.K.DeletableDesktopShortcuts) + ?? new Dictionary(); } public static void ResetDatabase() @@ -32,9 +33,16 @@ public static void ResetDatabase() public static void AddToDatabase(string shortcutPath, Status shortcutStatus) { if (shortcutStatus is Status.Unknown) - Settings.RemoveDictionaryKey(Settings.K.DeletableDesktopShortcuts, shortcutPath); + Settings.RemoveDictionaryKey( + Settings.K.DeletableDesktopShortcuts, + shortcutPath + ); else - Settings.SetDictionaryItem(Settings.K.DeletableDesktopShortcuts, shortcutPath, shortcutStatus is Status.Delete); + Settings.SetDictionaryItem( + Settings.K.DeletableDesktopShortcuts, + shortcutPath, + shortcutStatus is Status.Delete + ); } /// @@ -45,7 +53,12 @@ public static void AddToDatabase(string shortcutPath, Status shortcutStatus) public static bool Remove(string shortcutPath) { // Remove the entry if present - if (Settings.DictionaryContainsKey(Settings.K.DeletableDesktopShortcuts, shortcutPath)) + if ( + Settings.DictionaryContainsKey( + Settings.K.DeletableDesktopShortcuts, + shortcutPath + ) + ) { // Remove the entry and propagate changes to disk Settings.SetDictionaryItem(Settings.K.DeletableDesktopShortcuts, shortcutPath, false); @@ -53,7 +66,9 @@ public static bool Remove(string shortcutPath) } // Do nothing if the entry was not there - Logger.Warn($"Attempted to remove from deletable desktop shortcuts a shortcut {{shortcutPath={shortcutPath}}} that was not found there"); + Logger.Warn( + $"Attempted to remove from deletable desktop shortcuts a shortcut {{shortcutPath={shortcutPath}}} that was not found there" + ); return false; } @@ -88,9 +103,17 @@ public static bool DeleteFromDisk(string shortcutPath) public static Status GetStatus(string shortcutPath) { // Check if the package is ignored - if (Settings.DictionaryContainsKey(Settings.K.DeletableDesktopShortcuts, shortcutPath)) + if ( + Settings.DictionaryContainsKey( + Settings.K.DeletableDesktopShortcuts, + shortcutPath + ) + ) { - bool canDelete = Settings.GetDictionaryItem(Settings.K.DeletableDesktopShortcuts, shortcutPath); + bool canDelete = Settings.GetDictionaryItem( + Settings.K.DeletableDesktopShortcuts, + shortcutPath + ); return canDelete ? Status.Delete : Status.Maintain; } @@ -106,10 +129,16 @@ public static List GetShortcutsOnDisk() try { List shortcuts = []; - string UserDesktop = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory); - string CommonDesktop = Environment.GetFolderPath(Environment.SpecialFolder.CommonDesktopDirectory); - if (UserDesktop != "") shortcuts.AddRange(Directory.EnumerateFiles(UserDesktop, "*.lnk")); - if (CommonDesktop != "") shortcuts.AddRange(Directory.EnumerateFiles(CommonDesktop, "*.lnk")); + string UserDesktop = Environment.GetFolderPath( + Environment.SpecialFolder.DesktopDirectory + ); + string CommonDesktop = Environment.GetFolderPath( + Environment.SpecialFolder.CommonDesktopDirectory + ); + if (UserDesktop != "") + shortcuts.AddRange(Directory.EnumerateFiles(UserDesktop, "*.lnk")); + if (CommonDesktop != "") + shortcuts.AddRange(Directory.EnumerateFiles(CommonDesktop, "*.lnk")); return shortcuts; } catch (Exception ex) @@ -183,14 +212,16 @@ public static void HandleNewShortcuts(IReadOnlyList PreviousShortCutList { // If a shortcut has not been detected yet, and it // existed before an operation started, then do nothing. - if(PreviousShortcuts.Contains(shortcut)) + if (PreviousShortcuts.Contains(shortcut)) continue; if (DeleteUnknownShortcuts) { // If the shortcut was created during an operation // and autodelete is enabled, delete that icon - Logger.Warn($"New shortcut {shortcut} will be set for deletion (this shortcut was never seen before)"); + Logger.Warn( + $"New shortcut {shortcut} will be set for deletion (this shortcut was never seen before)" + ); AddToDatabase(shortcut, Status.Delete); DeleteFromDisk(shortcut); } diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Classes/IgnoredUpdatesDatabase.cs b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Classes/IgnoredUpdatesDatabase.cs index 618b9dfcb7..577cceaa2d 100644 --- a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Classes/IgnoredUpdatesDatabase.cs +++ b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Classes/IgnoredUpdatesDatabase.cs @@ -10,9 +10,21 @@ public static class IgnoredUpdatesDatabase public class PauseTime { private int _daysTill; - public int Months { get { return Weeks / 4; } set { Weeks = value * 4; } } - public int Weeks { get { return Days / 7; } set { Days = value * 7; } } - public int Days { get { return _daysTill; } set { _daysTill = value; } } + public int Months + { + get { return Weeks / 4; } + set { Weeks = value * 4; } + } + public int Weeks + { + get { return Days / 7; } + set { Days = value * 7; } + } + public int Days + { + get { return _daysTill; } + set { _daysTill = value; } + } public string GetDateFromNow() { @@ -24,7 +36,11 @@ public void Parse(string Date) { try { - DateTime ParsedDate = DateTime.ParseExact(Date, "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture); + DateTime ParsedDate = DateTime.ParseExact( + Date, + "yyyy-MM-dd", + System.Globalization.CultureInfo.InvariantCulture + ); DateTime Now = DateTime.Now; if (ParsedDate > Now) { @@ -47,32 +63,38 @@ public string StringRepresentation() if (Months >= 12 && Months % 12 == 0) { int Years = Months / 12; - if (Years > 1) return CoreTools.Translate("{0} years", Years); + if (Years > 1) + return CoreTools.Translate("{0} years", Years); return CoreTools.Translate("1 year"); } if (Months >= 1) { - if (Months > 1) return CoreTools.Translate("{0} months", Months); + if (Months > 1) + return CoreTools.Translate("{0} months", Months); return CoreTools.Translate("1 month"); } if (Weeks >= 1) { - if (Weeks > 1) return CoreTools.Translate("{0} weeks", Weeks); + if (Weeks > 1) + return CoreTools.Translate("{0} weeks", Weeks); return CoreTools.Translate("1 week"); } - if (Days != 1) return CoreTools.Translate("{0} days", Days); + if (Days != 1) + return CoreTools.Translate("{0} days", Days); return CoreTools.Translate("1 day"); } } public static IReadOnlyDictionary GetDatabase() { - return Settings.GetDictionary(Settings.K.IgnoredPackageUpdates)? - .Where(kvp => kvp.Value is not null) - .ToDictionary(kvp => kvp.Key, kvp => kvp.Value!) ?? new Dictionary(); + return Settings + .GetDictionary(Settings.K.IgnoredPackageUpdates) + ?.Where(kvp => kvp.Value is not null) + .ToDictionary(kvp => kvp.Key, kvp => kvp.Value!) + ?? new Dictionary(); } public static string GetIgnoredIdForPackage(IPackage package) @@ -98,14 +120,24 @@ public static void Add(string ignoredId, string version = "*") public static bool Remove(string ignoredId) { // Remove the entry if present - if (Settings.DictionaryContainsKey(Settings.K.IgnoredPackageUpdates, ignoredId)) + if ( + Settings.DictionaryContainsKey( + Settings.K.IgnoredPackageUpdates, + ignoredId + ) + ) { // Remove the entry and propagate changes to disk - return Settings.RemoveDictionaryKey(Settings.K.IgnoredPackageUpdates, ignoredId) != null; + return Settings.RemoveDictionaryKey( + Settings.K.IgnoredPackageUpdates, + ignoredId + ) != null; } // Do nothing if the entry was not there - Logger.Warn($"Attempted to remove from ignored updates a package {{ignoredId={ignoredId}}} that was not found there"); + Logger.Warn( + $"Attempted to remove from ignored updates a package {{ignoredId={ignoredId}}} that was not found there" + ); return false; } @@ -123,14 +155,22 @@ public static bool Remove(string ignoredId) /// True if the package is ignored, false otherwise public static bool HasUpdatesIgnored(string ignoredId, string version = "*") { - string? ignoredVersion = Settings.GetDictionaryItem(Settings.K.IgnoredPackageUpdates, ignoredId); + string? ignoredVersion = Settings.GetDictionaryItem( + Settings.K.IgnoredPackageUpdates, + ignoredId + ); if (ignoredVersion != null && ignoredVersion.StartsWith("<")) { try { - var ignoreDate = DateTime.ParseExact(ignoredVersion[1..], "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture); - if (ignoreDate > DateTime.Now) return true; + var ignoreDate = DateTime.ParseExact( + ignoredVersion[1..], + "yyyy-MM-dd", + System.Globalization.CultureInfo.InvariantCulture + ); + if (ignoreDate > DateTime.Now) + return true; Remove(ignoredId); } catch (FormatException ex) @@ -153,6 +193,9 @@ public static bool HasUpdatesIgnored(string ignoredId, string version = "*") /// If **no** versions are ignored, null will be returned. public static string? GetIgnoredVersion(string ignoredId) { - return Settings.GetDictionaryItem(Settings.K.IgnoredPackageUpdates, ignoredId); + return Settings.GetDictionaryItem( + Settings.K.IgnoredPackageUpdates, + ignoredId + ); } } diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Classes/InstallOptionsFactory.cs b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Classes/InstallOptionsFactory.cs index 26c242169d..2bc13c95b1 100644 --- a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Classes/InstallOptionsFactory.cs +++ b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Classes/InstallOptionsFactory.cs @@ -10,7 +10,6 @@ namespace UniGetUI.PackageEngine.PackageClasses { - /// /// This class represents the options in which a package must be installed, updated or uninstalled. /// @@ -18,38 +17,38 @@ public static class InstallOptionsFactory { private static class StoragePath { - public static string Get(IPackageManager manager) - => "GlobalValues." + manager.Name.Replace(" ", "").Replace(".", "") + ".json"; + public static string Get(IPackageManager manager) => + "GlobalValues." + manager.Name.Replace(" ", "").Replace(".", "") + ".json"; - public static string Get(IPackage package) - => package.Manager.Name.Replace(" ", "").Replace(".", "") + "." + package.Id + ".json"; + public static string Get(IPackage package) => + package.Manager.Name.Replace(" ", "").Replace(".", "") + "." + package.Id + ".json"; } // Loading from disk (package and manager) - public static InstallOptions LoadForPackage(IPackage package) - => _loadFromDisk(StoragePath.Get(package)); + public static InstallOptions LoadForPackage(IPackage package) => + _loadFromDisk(StoragePath.Get(package)); - public static Task LoadForPackageAsync(IPackage package) - => Task.Run(() => LoadForPackage(package)); + public static Task LoadForPackageAsync(IPackage package) => + Task.Run(() => LoadForPackage(package)); - public static InstallOptions LoadForManager(IPackageManager manager) - => _loadFromDisk(StoragePath.Get(manager)); + public static InstallOptions LoadForManager(IPackageManager manager) => + _loadFromDisk(StoragePath.Get(manager)); - public static Task LoadForManagerAsync(IPackageManager manager) - => Task.Run(() => LoadForManager(manager)); + public static Task LoadForManagerAsync(IPackageManager manager) => + Task.Run(() => LoadForManager(manager)); // Saving to disk (package and manager) - public static void SaveForPackage(InstallOptions options, IPackage package) - => _saveToDisk(options, StoragePath.Get(package)); + public static void SaveForPackage(InstallOptions options, IPackage package) => + _saveToDisk(options, StoragePath.Get(package)); - public static Task SaveForPackageAsync(InstallOptions options, IPackage package) - => Task.Run(() => _saveToDisk(options, StoragePath.Get(package))); + public static Task SaveForPackageAsync(InstallOptions options, IPackage package) => + Task.Run(() => _saveToDisk(options, StoragePath.Get(package))); - public static void SaveForManager(InstallOptions options, IPackageManager manager) - => _saveToDisk(options, StoragePath.Get(manager)); + public static void SaveForManager(InstallOptions options, IPackageManager manager) => + _saveToDisk(options, StoragePath.Get(manager)); - public static Task SaveForManagerAsync(InstallOptions options, IPackageManager manager) - => Task.Run(() => _saveToDisk(options, StoragePath.Get(manager))); + public static Task SaveForManagerAsync(InstallOptions options, IPackageManager manager) => + Task.Run(() => _saveToDisk(options, StoragePath.Get(manager))); /// /// Loads the applicable InstallationOptions, and applies @@ -69,22 +68,32 @@ public static InstallOptions LoadApplicable( bool? interactive = null, bool? no_integrity = null, bool? remove_data = null, - InstallOptions? overridePackageOptions = null) + InstallOptions? overridePackageOptions = null + ) { var instance = overridePackageOptions ?? LoadForPackage(package); if (!instance.OverridesNextLevelOpts) { - Logger.Debug($"Package {package.Id} does not override options, will use package manager's default..."); + Logger.Debug( + $"Package {package.Id} does not override options, will use package manager's default..." + ); instance = LoadForManager(package.Manager); var legalizedId = CoreTools.MakeValidFileName(package.Id); - instance.CustomInstallLocation = instance.CustomInstallLocation.Replace("%PACKAGE%", legalizedId); + instance.CustomInstallLocation = instance.CustomInstallLocation.Replace( + "%PACKAGE%", + legalizedId + ); } - if (elevated is not null) instance.RunAsAdministrator = (bool)elevated; - if (interactive is not null) instance.InteractiveInstallation = (bool)interactive; - if (no_integrity is not null) instance.SkipHashCheck = (bool)no_integrity; - if (remove_data is not null) instance.RemoveDataOnUninstall = (bool)remove_data; + if (elevated is not null) + instance.RunAsAdministrator = (bool)elevated; + if (interactive is not null) + instance.InteractiveInstallation = (bool)interactive; + if (no_integrity is not null) + instance.SkipHashCheck = (bool)no_integrity; + if (remove_data is not null) + instance.RemoveDataOnUninstall = (bool)remove_data; return EnsureSecureOptions(instance); } @@ -107,8 +116,18 @@ public static Task LoadApplicableAsync( bool? interactive = null, bool? no_integrity = null, bool? remove_data = null, - InstallOptions? overridePackageOptions = null) - => Task.Run(() => LoadApplicable(package, elevated, interactive, no_integrity, remove_data, overridePackageOptions)); + InstallOptions? overridePackageOptions = null + ) => + Task.Run(() => + LoadApplicable( + package, + elevated, + interactive, + no_integrity, + remove_data, + overridePackageOptions + ) + ); /* * @@ -168,8 +187,19 @@ private static InstallOptions _loadFromDisk(string key) } catch (JsonException) { - Logger.Warn("An error occurred while parsing package " + key + ". The file will be overwritten"); - try { File.WriteAllText(filePath, "{}"); } catch (Exception ex) { Logger.Warn(ex); } + Logger.Warn( + "An error occurred while parsing package " + + key + + ". The file will be overwritten" + ); + try + { + File.WriteAllText(filePath, "{}"); + } + catch (Exception ex) + { + Logger.Warn(ex); + } return new(); } catch (Exception e) @@ -187,32 +217,53 @@ private static InstallOptions EnsureSecureOptions(InstallOptions options) // If CLI arguments are allowed, sanitize them for (int i = 0; i < options.CustomParameters_Install.Count; i++) { - options.CustomParameters_Install[i] = options.CustomParameters_Install[i] - .Replace("&", "").Replace("|", "").Replace(";", "").Replace("<", "") - .Replace(">", "").Replace("\n", ""); + options.CustomParameters_Install[i] = options + .CustomParameters_Install[i] + .Replace("&", "") + .Replace("|", "") + .Replace(";", "") + .Replace("<", "") + .Replace(">", "") + .Replace("\n", ""); } for (int i = 0; i < options.CustomParameters_Update.Count; i++) { - options.CustomParameters_Update[i] = options.CustomParameters_Update[i] - .Replace("&", "").Replace("|", "").Replace(";", "").Replace("<", "") - .Replace(">", "").Replace("\n", ""); + options.CustomParameters_Update[i] = options + .CustomParameters_Update[i] + .Replace("&", "") + .Replace("|", "") + .Replace(";", "") + .Replace("<", "") + .Replace(">", "") + .Replace("\n", ""); } for (int i = 0; i < options.CustomParameters_Uninstall.Count; i++) { - options.CustomParameters_Uninstall[i] = options.CustomParameters_Uninstall[i] - .Replace("&", "").Replace("|", "").Replace(";", "").Replace("<", "") - .Replace(">", "").Replace("\n", ""); + options.CustomParameters_Uninstall[i] = options + .CustomParameters_Uninstall[i] + .Replace("&", "") + .Replace("|", "") + .Replace(";", "") + .Replace("<", "") + .Replace(">", "") + .Replace("\n", ""); } } else { // Otherwhise, clear them if (options.CustomParameters_Install.Count > 0) - Logger.Warn($"Custom install parameters [{string.Join(' ', options.CustomParameters_Install)}] will be discarded"); + Logger.Warn( + $"Custom install parameters [{string.Join(' ', options.CustomParameters_Install)}] will be discarded" + ); if (options.CustomParameters_Update.Count > 0) - Logger.Warn($"Custom update parameters [{string.Join(' ', options.CustomParameters_Update)}] will be discarded"); + Logger.Warn( + $"Custom update parameters [{string.Join(' ', options.CustomParameters_Update)}] will be discarded" + ); if (options.CustomParameters_Uninstall.Count > 0) - Logger.Warn($"Custom uninstall parameters [{string.Join(' ', options.CustomParameters_Uninstall)}] will be discarded"); + Logger.Warn( + $"Custom uninstall parameters [{string.Join(' ', options.CustomParameters_Uninstall)}] will be discarded" + ); options.CustomParameters_Install = []; options.CustomParameters_Update = []; @@ -221,12 +272,28 @@ private static InstallOptions EnsureSecureOptions(InstallOptions options) if (!SecureSettings.Get(SecureSettings.K.AllowPrePostOpCommand)) { - if (options.PreInstallCommand.Any()) Logger.Warn($"Pre-install command {options.PreInstallCommand} will be discarded"); - if (options.PostInstallCommand.Any()) Logger.Warn($"Post-install command {options.PostInstallCommand} will be discarded"); - if (options.PreUpdateCommand.Any()) Logger.Warn($"Pre-update command {options.PreUpdateCommand} will be discarded"); - if (options.PostUpdateCommand.Any()) Logger.Warn($"Post-update command {options.PostUpdateCommand} will be discarded"); - if (options.PreUninstallCommand.Any()) Logger.Warn($"Pre-uninstall command {options.PreUninstallCommand} will be discarded"); - if (options.PostUninstallCommand.Any()) Logger.Warn($"Post-uninstall command {options.PostUninstallCommand} will be discarded"); + if (options.PreInstallCommand.Any()) + Logger.Warn( + $"Pre-install command {options.PreInstallCommand} will be discarded" + ); + if (options.PostInstallCommand.Any()) + Logger.Warn( + $"Post-install command {options.PostInstallCommand} will be discarded" + ); + if (options.PreUpdateCommand.Any()) + Logger.Warn($"Pre-update command {options.PreUpdateCommand} will be discarded"); + if (options.PostUpdateCommand.Any()) + Logger.Warn( + $"Post-update command {options.PostUpdateCommand} will be discarded" + ); + if (options.PreUninstallCommand.Any()) + Logger.Warn( + $"Pre-uninstall command {options.PreUninstallCommand} will be discarded" + ); + if (options.PostUninstallCommand.Any()) + Logger.Warn( + $"Post-uninstall command {options.PostUninstallCommand} will be discarded" + ); options.PreInstallCommand = ""; options.PostInstallCommand = ""; diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/ImportedPackage.cs b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/ImportedPackage.cs index 7b0e25390b..14b87461f8 100644 --- a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/ImportedPackage.cs +++ b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/ImportedPackage.cs @@ -26,7 +26,11 @@ public override string VersionString } } - public ImportedPackage(SerializablePackage raw_data, IPackageManager manager, IManagerSource source) + public ImportedPackage( + SerializablePackage raw_data, + IPackageManager manager, + IManagerSource source + ) : base(raw_data.Name, raw_data.Id, raw_data.Version, source, manager) { _version = raw_data.Version; @@ -45,27 +49,28 @@ public async Task RegisterAndGetPackageAsync() return package; } - public override Task GetInstallOptions() - => Task.FromResult(installation_options.Copy()); + public override Task GetInstallOptions() => + Task.FromResult(installation_options.Copy()); public override Task AsSerializableAsync() { - return Task.FromResult(new SerializablePackage - { - Id = Id, - Name = Name, - Version = _version, - Source = Source.Name, - ManagerName = Manager.Name, - InstallationOptions = installation_options.Copy(), - Updates = updates_options.Copy() - }); + return Task.FromResult( + new SerializablePackage + { + Id = Id, + Name = Name, + Version = _version, + Source = Source.Name, + ManagerName = Manager.Name, + InstallationOptions = installation_options.Copy(), + Updates = updates_options.Copy(), + } + ); } public void FirePackageVersionChangedEvent() { OnPropertyChanged(nameof(VersionString)); } - } } diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/InvalidImportedPackage.cs b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/InvalidImportedPackage.cs index 9afca9836b..77f773a5bd 100644 --- a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/InvalidImportedPackage.cs +++ b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/InvalidImportedPackage.cs @@ -15,20 +15,31 @@ public partial class InvalidImportedPackage : IPackage, INotifyPropertyChanged { public IPackageDetails Details { get; } - public PackageTag Tag { get => PackageTag.Unavailable; set { } } + public PackageTag Tag + { + get => PackageTag.Unavailable; + set { } + } private bool __is_checked; public bool IsChecked { get { return __is_checked; } - set { __is_checked = value; OnPropertyChanged(nameof(IsChecked)); } + set + { + __is_checked = value; + OnPropertyChanged(nameof(IsChecked)); + } } private readonly long __hash; private readonly long __extended_hash; private static OverridenInstallationOptions __overriden_options; - public ref OverridenInstallationOptions OverridenOptions { get => ref __overriden_options; } + public ref OverridenInstallationOptions OverridenOptions + { + get => ref __overriden_options; + } public string Name { get; } @@ -38,17 +49,30 @@ public bool IsChecked public CoreTools.Version NormalizedVersion { get; } - public CoreTools.Version NormalizedNewVersion { get => CoreTools.Version.Null; } + public CoreTools.Version NormalizedNewVersion + { + get => CoreTools.Version.Null; + } public IManagerSource Source { get; } public IPackageManager Manager { get; } - public string NewVersionString { get => ""; } + public string NewVersionString + { + get => ""; + } - public bool IsUpgradable { get => false; } + public bool IsUpgradable + { + get => false; + } - public string Scope { get => PackageScope.Local; set { } } + public string Scope + { + get => PackageScope.Local; + set { } + } public string SourceAsString { get; } @@ -71,13 +95,13 @@ public InvalidImportedPackage(SerializableIncompatiblePackage data, IManagerSour __hash = CoreTools.HashStringAsLong(data.Name + data.Id); __extended_hash = CoreTools.HashStringAsLong(data.Name + data.Id + data.Version); } + public Task AddToIgnoredUpdatesAsync(string version = "*") { return Task.CompletedTask; } - public Task GetInstallOptions() - => Task.FromResult(new InstallOptions()); + public Task GetInstallOptions() => Task.FromResult(new InstallOptions()); public Task AsSerializableAsync() { @@ -204,8 +228,14 @@ public class NullSource : IManagerSource public int? PackageCount { get; } public string? UpdateDate { get; } - public string AsString { get => Name; } - public string AsString_DisplayName { get => Name; } + public string AsString + { + get => Name; + } + public string AsString_DisplayName + { + get => Name; + } public NullSource(string name) { @@ -224,8 +254,6 @@ public override string ToString() return Name; } - public void RefreshSourceNames() - { } - + public void RefreshSourceNames() { } } } diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Package.cs b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Package.cs index dabdd39343..19dbec4a5e 100644 --- a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Package.cs +++ b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Package.cs @@ -39,17 +39,28 @@ public IPackageDetails Details public PackageTag Tag { get => __tag; - set { __tag = value; OnPropertyChanged(); } + set + { + __tag = value; + OnPropertyChanged(); + } } public bool IsChecked { get => __is_checked; - set { __is_checked = value; OnPropertyChanged(); } + set + { + __is_checked = value; + OnPropertyChanged(); + } } private OverridenInstallationOptions _overridenOptions; - public ref OverridenInstallationOptions OverridenOptions { get => ref _overridenOptions; } + public ref OverridenInstallationOptions OverridenOptions + { + get => ref _overridenOptions; + } public string Name { get; } public string AutomationName { get; } public string Id { get; } @@ -75,15 +86,9 @@ public Package( string version, IManagerSource source, IPackageManager manager, - OverridenInstallationOptions? options = null) : this( - name, - id, - version, - version, - source, - manager, - options - ) + OverridenInstallationOptions? options = null + ) + : this(name, id, version, version, source, manager, options) { IsUpgradable = false; } @@ -98,7 +103,8 @@ public Package( string new_version, IManagerSource source, IPackageManager manager, - OverridenInstallationOptions? options = null) + OverridenInstallationOptions? options = null + ) { Name = name; Id = id; @@ -112,28 +118,29 @@ public Package( IsUpgradable = true; Tag = PackageTag.Default; - AutomationName = CoreTools.Translate("Package {name} from {manager}") + AutomationName = CoreTools + .Translate("Package {name} from {manager}") .Replace("{name}", name) .Replace("{manager}", Source.AsString_DisplayName); _overridenOptions = options ?? _overridenOptions; - _hash = CoreTools.HashStringAsLong($"{Manager.Name}\\{Source.AsString_DisplayName}\\{Id}"); - _versionedHash = CoreTools.HashStringAsLong($"{Manager.Name}\\{Source.AsString_DisplayName}\\{Id}\\{installed_version}"); + _hash = CoreTools.HashStringAsLong( + $"{Manager.Name}\\{Source.AsString_DisplayName}\\{Id}" + ); + _versionedHash = CoreTools.HashStringAsLong( + $"{Manager.Name}\\{Source.AsString_DisplayName}\\{Id}\\{installed_version}" + ); _ignoredId = IgnoredUpdatesDatabase.GetIgnoredIdForPackage(this); _iconId = GenerateIconId(this); } - public long GetHash() - => _hash; + public long GetHash() => _hash; - public long GetVersionedHash() - => _versionedHash; + public long GetVersionedHash() => _versionedHash; - public bool Equals(IPackage? other) - => _versionedHash == other?.GetHash(); + public bool Equals(IPackage? other) => _versionedHash == other?.GetHash(); - public override int GetHashCode() - => (int)_versionedHash; + public override int GetHashCode() => (int)_versionedHash; /// /// Check whether two package instances represent the same package. @@ -144,11 +151,9 @@ public override int GetHashCode() /// /// A package /// Whether the two instances refer to the same instance - public bool IsEquivalentTo(IPackage? other) - => _hash == other?.GetHash(); + public bool IsEquivalentTo(IPackage? other) => _hash == other?.GetHash(); - public string GetIconId() - => _iconId; + public string GetIconId() => _iconId; public virtual Uri GetIconUrl() { @@ -170,9 +175,16 @@ public virtual Uri GetIconUrl() { try { - CacheableIcon? icon = TaskRecycler.RunOrAttach(Manager.DetailsHelper.GetIcon, this); - string? path = IconCacheEngine.GetCacheOrDownloadIcon(icon, Manager.Name, CoreTools.MakeValidFileName(Id)); - return path is null? null: new Uri("file:///" + path); + CacheableIcon? icon = TaskRecycler.RunOrAttach( + Manager.DetailsHelper.GetIcon, + this + ); + string? path = IconCacheEngine.GetCacheOrDownloadIcon( + icon, + Manager.Name, + CoreTools.MakeValidFileName(Id) + ); + return path is null ? null : new Uri("file:///" + path); } catch (Exception ex) { @@ -192,7 +204,7 @@ public virtual async Task AddToIgnoredUpdatesAsync(string version = "*") try { await Task.Run(() => IgnoredUpdatesDatabase.Add(_ignoredId, version)); - foreach(var p in GetInstalledPackages()) + foreach (var p in GetInstalledPackages()) p.SetTag(PackageTag.Pinned); } catch (Exception ex) @@ -207,7 +219,7 @@ public virtual async Task RemoveFromIgnoredUpdatesAsync() try { await Task.Run(() => IgnoredUpdatesDatabase.Remove(_ignoredId)); - foreach(var p in GetInstalledPackages()) + foreach (var p in GetInstalledPackages()) p.SetTag(PackageTag.Default); } catch (Exception ex) @@ -227,7 +239,9 @@ public virtual async Task HasUpdatesIgnoredAsync(string version = "*") { try { - return await Task.Run(() => IgnoredUpdatesDatabase.HasUpdatesIgnored(_ignoredId, version)); + return await Task.Run(() => + IgnoredUpdatesDatabase.HasUpdatesIgnored(_ignoredId, version) + ); } catch (Exception ex) { @@ -235,7 +249,6 @@ public virtual async Task HasUpdatesIgnoredAsync(string version = "*") Logger.Error(ex); return false; } - } /// @@ -247,7 +260,8 @@ public virtual async Task GetIgnoredUpdatesVersionAsync() { try { - return await Task.Run(() => IgnoredUpdatesDatabase.GetIgnoredVersion(_ignoredId)) ?? ""; + return await Task.Run(() => IgnoredUpdatesDatabase.GetIgnoredVersion(_ignoredId)) + ?? ""; } catch (Exception ex) { @@ -262,14 +276,14 @@ protected void OnPropertyChanged([CallerMemberName] string? name = null) PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); } - public IPackage? GetAvailablePackage() - => DiscoverablePackagesLoader.Instance.GetEquivalentPackage(this); + public IPackage? GetAvailablePackage() => + DiscoverablePackagesLoader.Instance.GetEquivalentPackage(this); - public IPackage? GetUpgradablePackage() - => UpgradablePackagesLoader.Instance.GetEquivalentPackage(this); + public IPackage? GetUpgradablePackage() => + UpgradablePackagesLoader.Instance.GetEquivalentPackage(this); - public IReadOnlyList GetInstalledPackages() - => InstalledPackagesLoader.Instance.GetEquivalentPackages(this); + public IReadOnlyList GetInstalledPackages() => + InstalledPackagesLoader.Instance.GetEquivalentPackages(this); public virtual void SetTag(PackageTag tag) { @@ -285,7 +299,7 @@ public virtual bool NewerVersionIsInstalled() return true; } } - + return false; } @@ -297,22 +311,29 @@ public virtual bool NewerVersionIsInstalled() } else { - if (!Details.IsPopulated) await Details.Load(); - if (Details.InstallerUrl is null) return null; + if (!Details.IsPopulated) + await Details.Load(); + if (Details.InstallerUrl is null) + return null; return await CoreTools.GetFileNameAsync(Details.InstallerUrl); } } public virtual bool IsUpdateMinor() { - if (!IsUpgradable) return false; + if (!IsUpgradable) + return false; - return NormalizedVersion.Major == NormalizedNewVersion.Major && NormalizedVersion.Minor == NormalizedNewVersion.Minor && - (NormalizedVersion.Patch != NormalizedNewVersion.Patch || NormalizedVersion.Remainder != NormalizedNewVersion.Remainder); + return NormalizedVersion.Major == NormalizedNewVersion.Major + && NormalizedVersion.Minor == NormalizedNewVersion.Minor + && ( + NormalizedVersion.Patch != NormalizedNewVersion.Patch + || NormalizedVersion.Remainder != NormalizedNewVersion.Remainder + ); } - public virtual Task GetInstallOptions() - => InstallOptionsFactory.LoadApplicableAsync(this); + public virtual Task GetInstallOptions() => + InstallOptionsFactory.LoadApplicableAsync(this); public virtual async Task AsSerializableAsync() { @@ -328,7 +349,7 @@ public virtual async Task AsSerializableAsync() { IgnoredVersion = await GetIgnoredUpdatesVersionAsync(), UpdatesIgnored = await HasUpdatesIgnoredAsync(), - } + }, }; } @@ -350,29 +371,42 @@ public static void ResetIconCache() private static string GenerateIconId(Package p) { - return (p.Manager.Name switch - { - "Winget" => p.Source.Name switch + return ( + p.Manager.Name switch { - "Steam" => p.Id.ToLower().Split("\\")[^1].Replace("steam app ", "steam-").Trim(), - "Local PC" => p.Id.Split("\\")[^1], - // If the first underscore is before the period, this ID has no publisher - "Microsoft Store" => p.Id.IndexOf('_') < p.Id.IndexOf('.') ? - // no publisher: remove `MSIX\`, then the standard ending _version_arch__{random p.Id} - string.Join('_', p.Id.Split("\\")[1].Split("_")[0..^4]) : - // remove the publisher (before the first .), then the standard _version_arch__{random p.Id} - string.Join('_', - string.Join('.', p.Id.Split(".")[1..]) - .Split("_") - [0..^4]), - _ => string.Join('.', p.Id.Split(".")[1..]), - }, - "Scoop" => p.Id.Replace(".app", ""), - "Chocolatey" => p.Id.Replace(".install", "").Replace(".portable", ""), - "vcpkg" => p.Id.Split(":")[0].Split("[")[0], - _ => p.Id - }).ToLower().Replace('_', '-').Replace('.', '-').Replace(' ', '-').Replace('/', '-').Replace(',', '-'); + "Winget" => p.Source.Name switch + { + "Steam" => p + .Id.ToLower() + .Split("\\")[^1] + .Replace("steam app ", "steam-") + .Trim(), + "Local PC" => p.Id.Split("\\")[^1], + // If the first underscore is before the period, this ID has no publisher + "Microsoft Store" => p.Id.IndexOf('_') < p.Id.IndexOf('.') + ? + // no publisher: remove `MSIX\`, then the standard ending _version_arch__{random p.Id} + string.Join('_', p.Id.Split("\\")[1].Split("_")[0..^4]) + : + // remove the publisher (before the first .), then the standard _version_arch__{random p.Id} + string.Join( + '_', + string.Join('.', p.Id.Split(".")[1..]).Split("_")[0..^4] + ), + _ => string.Join('.', p.Id.Split(".")[1..]), + }, + "Scoop" => p.Id.Replace(".app", ""), + "Chocolatey" => p.Id.Replace(".install", "").Replace(".portable", ""), + "vcpkg" => p.Id.Split(":")[0].Split("[")[0], + _ => p.Id, + } + ) + .ToLower() + .Replace('_', '-') + .Replace('.', '-') + .Replace(' ', '-') + .Replace('/', '-') + .Replace(',', '-'); } } } - diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/UniGetUI.PackageEngine.Classes.csproj b/src/UniGetUI.PackageEngine.PackageManagerClasses/UniGetUI.PackageEngine.Classes.csproj index 0724f7b3ab..91a4418fd9 100644 --- a/src/UniGetUI.PackageEngine.PackageManagerClasses/UniGetUI.PackageEngine.Classes.csproj +++ b/src/UniGetUI.PackageEngine.PackageManagerClasses/UniGetUI.PackageEngine.Classes.csproj @@ -1,25 +1,28 @@ + + $(SharedTargetFrameworks) + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - + + + - - - + + + diff --git a/src/UniGetUI.PackageEngine.Serializable.Tests/TestDuplicateUpdateDetection.cs b/src/UniGetUI.PackageEngine.Serializable.Tests/TestDuplicateUpdateDetection.cs index 9733381654..719c85df0d 100644 --- a/src/UniGetUI.PackageEngine.Serializable.Tests/TestDuplicateUpdateDetection.cs +++ b/src/UniGetUI.PackageEngine.Serializable.Tests/TestDuplicateUpdateDetection.cs @@ -15,7 +15,7 @@ public class TestDuplicateUpdateDetection /// /// Test that verifies Package.GetHash() returns the same value for identical packages. /// This is the core mechanism used to detect duplicate operations in the queue. - /// + /// /// Background: Issue #4131 - When unattended updates trigger repeatedly while UAC prompts /// are pending, UpdateAll() was creating dozens of duplicate operations for the same package. /// The fix uses GetHash() to check if an operation for a package already exists in the queue. @@ -185,9 +185,8 @@ public void SimulateDuplicateDetection_MultipleIdenticalPackages_ShouldHaveSameH Assert.Equal(hash1, hash2); Assert.Equal(hash2, hash3); Assert.Equal(hash1, hash3); - + // In the actual implementation, the second and third calls would find // an existing operation with matching hash and skip creating duplicates } } - diff --git a/src/UniGetUI.PackageEngine.Serializable.Tests/TestInstallOptions.cs b/src/UniGetUI.PackageEngine.Serializable.Tests/TestInstallOptions.cs index dd911b5667..fd60f2c54e 100644 --- a/src/UniGetUI.PackageEngine.Serializable.Tests/TestInstallOptions.cs +++ b/src/UniGetUI.PackageEngine.Serializable.Tests/TestInstallOptions.cs @@ -7,12 +7,48 @@ public class TestInstallOptions { [Theory] [InlineData(false, false, "", "", "", "", "", "", false, false, false, "")] - [InlineData(true, true, "testval", "testval", "testval", "testval", "testval", "testval", true, true, true, - "testval")] - [InlineData(true, false, "true", "helloWorld", "testval", "heheheheeheh", "--parse\n-int", "12", false, true, false, - "4.4.0-beta2")] - public void ToAndFromJsonNode(bool a, bool b, string c, string d, string e, string f, string g, string h, bool i, - bool j, bool k, string l) + [InlineData( + true, + true, + "testval", + "testval", + "testval", + "testval", + "testval", + "testval", + true, + true, + true, + "testval" + )] + [InlineData( + true, + false, + "true", + "helloWorld", + "testval", + "heheheheeheh", + "--parse\n-int", + "12", + false, + true, + false, + "4.4.0-beta2" + )] + public void ToAndFromJsonNode( + bool a, + bool b, + string c, + string d, + string e, + string f, + string g, + string h, + bool i, + bool j, + bool k, + string l + ) { var originalObject1 = new InstallOptions() { @@ -27,7 +63,7 @@ public void ToAndFromJsonNode(bool a, bool b, string c, string d, string e, stri PreRelease = i, RunAsAdministrator = j, SkipMinorUpdates = k, - Version = l + Version = l, }; Assert.Equal(a, originalObject1.DiffersFromDefault()); @@ -49,33 +85,76 @@ public void ToAndFromJsonNode(bool a, bool b, string c, string d, string e, stri [Theory] [InlineData("{}", false, false, "", "", "", "", "", "", false, false, false, "", false)] - [InlineData(""" - { - "SkipHashCheck": true, - "InteractiveInstallation": true, - "RunAsAdministrator": false, - "Architecture": "lol", - "InstallationScope": "", - "CustomParameters": [ - "a" - ] - } - """, true, true, "", "a", "", "", "", "lol", false, false, false, "", true)] - - [InlineData(""" - { - "PreRelease": false, - "CustomInstallLocation": "", - "Version": "heyheyhey", - "SkipMinorUpdates": true, - "UNKNOWN_VAL1": true, - "UNKNOWN_VAL2": null, - "UNKNOWN_VAL3": 22, - "UNKNOWN_VAL4": "hehe" - } - """, false, false, "", "", "", "", - "", "", false, false, true, "heyheyhey", true)] - public void FromJson(string JSON, bool hash, bool inter, string installLoc, string arg1, string arg2, string arg3, string scope, string arch, bool pre, bool admin, bool skipMin, string ver, bool mod) + [InlineData( + """ + { + "SkipHashCheck": true, + "InteractiveInstallation": true, + "RunAsAdministrator": false, + "Architecture": "lol", + "InstallationScope": "", + "CustomParameters": [ + "a" + ] + } + """, + true, + true, + "", + "a", + "", + "", + "", + "lol", + false, + false, + false, + "", + true + )] + [InlineData( + """ + { + "PreRelease": false, + "CustomInstallLocation": "", + "Version": "heyheyhey", + "SkipMinorUpdates": true, + "UNKNOWN_VAL1": true, + "UNKNOWN_VAL2": null, + "UNKNOWN_VAL3": 22, + "UNKNOWN_VAL4": "hehe" + } + """, + false, + false, + "", + "", + "", + "", + "", + "", + false, + false, + true, + "heyheyhey", + true + )] + public void FromJson( + string JSON, + bool hash, + bool inter, + string installLoc, + string arg1, + string arg2, + string arg3, + string scope, + string arch, + bool pre, + bool admin, + bool skipMin, + string ver, + bool mod + ) { Assert.NotEmpty(JSON); var jsonContent = JsonNode.Parse(JSON); @@ -89,9 +168,18 @@ public void FromJson(string JSON, bool hash, bool inter, string installLoc, stri Assert.Equal(hash, o2.SkipHashCheck); Assert.Equal(arch, o2.Architecture); Assert.Equal(installLoc, o2.CustomInstallLocation); - Assert.Equal(list.Where(x => x.Any()).ToList(), o2.CustomParameters_Install.Where(x => x.Any()).ToList()); - Assert.Equal(list.Where(x => x.Any()).ToList(), o2.CustomParameters_Update.Where(x => x.Any()).ToList()); - Assert.Equal(list.Where(x => x.Any()).ToList(), o2.CustomParameters_Uninstall.Where(x => x.Any()).ToList()); + Assert.Equal( + list.Where(x => x.Any()).ToList(), + o2.CustomParameters_Install.Where(x => x.Any()).ToList() + ); + Assert.Equal( + list.Where(x => x.Any()).ToList(), + o2.CustomParameters_Update.Where(x => x.Any()).ToList() + ); + Assert.Equal( + list.Where(x => x.Any()).ToList(), + o2.CustomParameters_Uninstall.Where(x => x.Any()).ToList() + ); Assert.Equal(scope, o2.InstallationScope); Assert.Equal(inter, o2.InteractiveInstallation); Assert.Equal(pre, o2.PreRelease); @@ -142,7 +230,8 @@ private static InstallOptions GenerateRandom(int seed) foreach (var key in o1._listKeys) { - var randomList = Enumerable.Range(0, r.Next(0, 11)) + var randomList = Enumerable + .Range(0, r.Next(0, 11)) .Select(_ => r.Next().ToString()) .ToList(); o1._listVal[key] = randomList; @@ -157,23 +246,20 @@ internal static void AssertAreEqual(InstallOptions o1, InstallOptions o2) foreach (var (key, _) in o1._defaultBoolValues) { - Assert.Equal( - o1._boolVal[key], - o2._boolVal[key]); + Assert.Equal(o1._boolVal[key], o2._boolVal[key]); } foreach (var key in o1._stringKeys) { - Assert.Equal( - o1._strVal[key], - o2._strVal[key]); + Assert.Equal(o1._strVal[key], o2._strVal[key]); } foreach (var key in o1._listKeys) { Assert.Equal( o1._listVal[key].Where(x => x.Any()), - o2._listVal[key].Where(x => x.Any())); + o2._listVal[key].Where(x => x.Any()) + ); } } } diff --git a/src/UniGetUI.PackageEngine.Serializable.Tests/TestSerializableBundle.cs b/src/UniGetUI.PackageEngine.Serializable.Tests/TestSerializableBundle.cs index ee9ea7f8ff..cad1f3d171 100644 --- a/src/UniGetUI.PackageEngine.Serializable.Tests/TestSerializableBundle.cs +++ b/src/UniGetUI.PackageEngine.Serializable.Tests/TestSerializableBundle.cs @@ -18,13 +18,9 @@ public class TestSerializableBundle Architecture = "4+1€", CustomParameters_Install = ["--hello-world", "--another-param", "-help"], CustomParameters_Update = ["--update", "--another-param", "-help"], - CustomParameters_Uninstall = ["--uninstall", "--another-param", "-help"] + CustomParameters_Uninstall = ["--uninstall", "--another-param", "-help"], }, - Updates = new() - { - IgnoredVersion = "12", - UpdatesIgnored = false - } + Updates = new() { IgnoredVersion = "12", UpdatesIgnored = false }, }; public static SerializablePackage TestPackage2 = new() @@ -51,8 +47,9 @@ public void ToAndFromJsonNode() { export_version = 5, packages = [TestPackage1, TestPackage2], - incompatible_packages_info = "I'm trying to reach you regarding your car's extended warranty", - incompatible_packages = [TestIncompatiblePackage] + incompatible_packages_info = + "I'm trying to reach you regarding your car's extended warranty", + incompatible_packages = [TestIncompatiblePackage], }; var object2 = new SerializableBundle(); @@ -72,25 +69,30 @@ public void ToAndFromJsonNode() [Theory] [InlineData("{}", "", "", "")] - [InlineData(""" + [InlineData( + """ + { + "export_version": 2.1, + "packages": [ + { + "Id": "Hello" + }, + { + "Id": "World" + } + ], + "incompatible_packages_info": "hey", + "incompatible_packages": [ { - "export_version": 2.1, - "packages": [ - { - "Id": "Hello" - }, - { - "Id": "World" - } - ], - "incompatible_packages_info": "hey", - "incompatible_packages": [ - { - "Id": "3" - } - ] + "Id": "3" } - """, "Hello", "World", "3")] + ] + } + """, + "Hello", + "World", + "3" + )] public void FromJson(string JSON, string id1, string id2, string id3) { Assert.NotEmpty(JSON); @@ -126,6 +128,9 @@ internal static void AreEqual(SerializableBundle o1, SerializableBundle o2) Assert.Equal(o1.incompatible_packages.Count, o2.incompatible_packages.Count); for (int i = 0; i < o1.incompatible_packages.Count; i++) - TestSerializableIncompatiblePackage.AreEqual(o1.incompatible_packages[i], o2.incompatible_packages[i]); + TestSerializableIncompatiblePackage.AreEqual( + o1.incompatible_packages[i], + o2.incompatible_packages[i] + ); } } diff --git a/src/UniGetUI.PackageEngine.Serializable.Tests/TestSerializableIncompatiblePackage.cs b/src/UniGetUI.PackageEngine.Serializable.Tests/TestSerializableIncompatiblePackage.cs index b1948e36b7..067a1ef527 100644 --- a/src/UniGetUI.PackageEngine.Serializable.Tests/TestSerializableIncompatiblePackage.cs +++ b/src/UniGetUI.PackageEngine.Serializable.Tests/TestSerializableIncompatiblePackage.cs @@ -16,7 +16,7 @@ public void ToAndFromJsonNode(string id, string name, string version, string man Id = id, Name = name, Source = manager, - Version = version + Version = version, }; var object2 = new SerializableIncompatiblePackage(); @@ -36,23 +36,34 @@ public void ToAndFromJsonNode(string id, string name, string version, string man [Theory] [InlineData("{}", "", "", "", "")] - [InlineData(""" - { - "Name": "name", - "Id": "true" - } - """, "true", "name", "", "")] - - [InlineData(""" - { - "Version": "false", - "Source": "lol", - "UNKNOWN_VAL1": true, - "UNKNOWN_VAL2": null, - "UNKNOWN_VAL3": 22, - "UNKNOWN_VAL4": "hehe" - } - """, "", "", "false", "lol")] + [InlineData( + """ + { + "Name": "name", + "Id": "true" + } + """, + "true", + "name", + "", + "" + )] + [InlineData( + """ + { + "Version": "false", + "Source": "lol", + "UNKNOWN_VAL1": true, + "UNKNOWN_VAL2": null, + "UNKNOWN_VAL3": 22, + "UNKNOWN_VAL4": "hehe" + } + """, + "", + "", + "false", + "lol" + )] public void FromJson(string JSON, string id, string name, string version, string manager) { Assert.NotEmpty(JSON); @@ -64,10 +75,12 @@ public void FromJson(string JSON, string id, string name, string version, string Assert.Equal(id, o2.Id); Assert.Equal(manager, o2.Source); Assert.Equal(version, o2.Version); - } - internal static void AreEqual(SerializableIncompatiblePackage o1, SerializableIncompatiblePackage o2) + internal static void AreEqual( + SerializableIncompatiblePackage o1, + SerializableIncompatiblePackage o2 + ) { Assert.Equal(o1.Name, o2.Name); Assert.Equal(o1.Id, o2.Id); diff --git a/src/UniGetUI.PackageEngine.Serializable.Tests/TestSerializablePackage.cs b/src/UniGetUI.PackageEngine.Serializable.Tests/TestSerializablePackage.cs index df9269e05d..19f4fe187d 100644 --- a/src/UniGetUI.PackageEngine.Serializable.Tests/TestSerializablePackage.cs +++ b/src/UniGetUI.PackageEngine.Serializable.Tests/TestSerializablePackage.cs @@ -13,7 +13,7 @@ public class TestSerializablePackage CustomParameters_Uninstall = ["c", "b", "a"], Architecture = "ia64", Version = "-1", - RunAsAdministrator = true + RunAsAdministrator = true, }; public static SerializableUpdatesOptions TestUpdatesOpts = new() @@ -33,7 +33,7 @@ public void ToAndFromJsonNode(string id, string name, string version, string man Id = id, Name = name, Source = manager, - Version = version + Version = version, }; var object2 = new SerializablePackage(); @@ -53,33 +53,58 @@ public void ToAndFromJsonNode(string id, string name, string version, string man [Theory] [InlineData("{}", "", "", "", "", "", false, "")] - [InlineData(""" - { - "Name": "name", - "Id": "true", - "Updates" : { - "IgnoredVersion": "Hey" - } + [InlineData( + """ + { + "Name": "name", + "Id": "true", + "Updates" : { + "IgnoredVersion": "Hey" + } + } + """, + "true", + "name", + "", + "", + "", + false, + "Hey" + )] + [InlineData( + """ + { + "Version": "false", + "Source": "lol", + "ManagerName": "Rodolfo Chikilicuatre", + "UNKNOWN_VAL1": true, + "UNKNOWN_VAL2": null, + "UNKNOWN_VAL3": 22, + "UNKNOWN_VAL4": "hehe", + "InstallationOptions" : { + "SkipHashCheck": true, + "OverridesNextLevelOpts": false } - """, "true", "name", "", "", "", false, "Hey")] - - [InlineData(""" - { - "Version": "false", - "Source": "lol", - "ManagerName": "Rodolfo Chikilicuatre", - "UNKNOWN_VAL1": true, - "UNKNOWN_VAL2": null, - "UNKNOWN_VAL3": 22, - "UNKNOWN_VAL4": "hehe", - "InstallationOptions" : { - "SkipHashCheck": true, - "OverridesNextLevelOpts": false - } - } - """, "", "", "false", "Rodolfo Chikilicuatre", "lol", true, "")] - - public void FromJson(string JSON, string id, string name, string version, string manager, string source, bool skipHash, string ignoredVer) + } + """, + "", + "", + "false", + "Rodolfo Chikilicuatre", + "lol", + true, + "" + )] + public void FromJson( + string JSON, + string id, + string name, + string version, + string manager, + string source, + bool skipHash, + string ignoredVer + ) { Assert.NotEmpty(JSON); var jsonContent = JsonNode.Parse(JSON); @@ -91,8 +116,11 @@ public void FromJson(string JSON, string id, string name, string version, string Assert.Equal(manager, o2.ManagerName); Assert.Equal(source, o2.Source); Assert.Equal(version, o2.Version); - TestInstallOptions.AssertAreEqual(new() { SkipHashCheck = skipHash }, o2.InstallationOptions); - TestSerializableUpdatesOptions.AreEqual(new(){IgnoredVersion = ignoredVer}, o2.Updates); + TestInstallOptions.AssertAreEqual( + new() { SkipHashCheck = skipHash }, + o2.InstallationOptions + ); + TestSerializableUpdatesOptions.AreEqual(new() { IgnoredVersion = ignoredVer }, o2.Updates); } internal static void AreEqual(SerializablePackage o1, SerializablePackage o2) diff --git a/src/UniGetUI.PackageEngine.Serializable.Tests/TestSerializableUpdatesOptions.cs b/src/UniGetUI.PackageEngine.Serializable.Tests/TestSerializableUpdatesOptions.cs index d5c3832ab3..2fc5e179ea 100644 --- a/src/UniGetUI.PackageEngine.Serializable.Tests/TestSerializableUpdatesOptions.cs +++ b/src/UniGetUI.PackageEngine.Serializable.Tests/TestSerializableUpdatesOptions.cs @@ -35,21 +35,28 @@ public void ToAndFromJsonNode(bool ign, string ver) [Theory] [InlineData("{}", false, "")] - [InlineData(""" - { - "UpdatesIgnored": true - } - """, true, "")] - - [InlineData(""" - { - "IgnoredVersion": "lol", - "UNKNOWN_VAL1": true, - "UNKNOWN_VAL2": null, - "UNKNOWN_VAL3": 22, - "UNKNOWN_VAL4": "hehe" - } - """, false, "lol")] + [InlineData( + """ + { + "UpdatesIgnored": true + } + """, + true, + "" + )] + [InlineData( + """ + { + "IgnoredVersion": "lol", + "UNKNOWN_VAL1": true, + "UNKNOWN_VAL2": null, + "UNKNOWN_VAL3": 22, + "UNKNOWN_VAL4": "hehe" + } + """, + false, + "lol" + )] public void FromJson(string JSON, bool ign, string ver) { Assert.NotEmpty(JSON); diff --git a/src/UniGetUI.PackageEngine.Serializable.Tests/UniGetUI.PackageEngine.Serializable.Tests.csproj b/src/UniGetUI.PackageEngine.Serializable.Tests/UniGetUI.PackageEngine.Serializable.Tests.csproj index 6017a732f4..2896c361fc 100644 --- a/src/UniGetUI.PackageEngine.Serializable.Tests/UniGetUI.PackageEngine.Serializable.Tests.csproj +++ b/src/UniGetUI.PackageEngine.Serializable.Tests/UniGetUI.PackageEngine.Serializable.Tests.csproj @@ -1,32 +1,30 @@ - - $(PortableTargetFramework) - + $(PortableTargetFramework) + false true - + - + - all - runtime; build; native; contentfiles; analyzers; buildtransitive + all + runtime; build; native; contentfiles; analyzers; buildtransitive - + - - - - + + + + - diff --git a/src/UniGetUI.PackageEngine.Serializable/InstallOptions.cs b/src/UniGetUI.PackageEngine.Serializable/InstallOptions.cs index c9532f7def..a39b27525e 100644 --- a/src/UniGetUI.PackageEngine.Serializable/InstallOptions.cs +++ b/src/UniGetUI.PackageEngine.Serializable/InstallOptions.cs @@ -5,7 +5,7 @@ namespace UniGetUI.PackageEngine.Serializable { - public class InstallOptions: SerializableComponent + public class InstallOptions : SerializableComponent { private const string SKIP_HASH = "SkipHashCheck"; private const string INTERACTIVE = "InteractiveInstallation"; @@ -35,8 +35,11 @@ public class InstallOptions: SerializableComponent private const string UNINST_PARAMS = "CustomParameters_Uninstall"; private const string KILL_BEFORE_OP = "KillBeforeOperation"; - public readonly IReadOnlyDictionary _defaultBoolValues = new Dictionary() - { // OverridesNextLevelOpts is deliberately skipped here + public readonly IReadOnlyDictionary _defaultBoolValues = new Dictionary< + string, + bool + >() + { // OverridesNextLevelOpts is deliberately skipped here { SKIP_HASH, false }, { INTERACTIVE, false }, { AS_ADMIN, false }, @@ -50,7 +53,8 @@ public class InstallOptions: SerializableComponent { AUTO_UPDATE_PACKAGE, false }, }; - public readonly IReadOnlyList _stringKeys = [ + public readonly IReadOnlyList _stringKeys = + [ ARCH, SCOPE, LOCATION, @@ -63,7 +67,8 @@ public class InstallOptions: SerializableComponent POST_UNINST_CMD, ]; - public readonly IReadOnlyList _listKeys = [ + public readonly IReadOnlyList _listKeys = + [ INST_PARAMS, UPD_PARAMS, UNINST_PARAMS, @@ -74,33 +79,133 @@ public class InstallOptions: SerializableComponent public readonly ConcurrentDictionary _strVal = new(); public readonly ConcurrentDictionary> _listVal = new(); - public bool SkipHashCheck { get => _boolVal[SKIP_HASH]; set => _boolVal[SKIP_HASH] = value; } - public bool InteractiveInstallation { get => _boolVal[INTERACTIVE]; set => _boolVal[INTERACTIVE] = value; } - public bool RunAsAdministrator { get => _boolVal[AS_ADMIN]; set => _boolVal[AS_ADMIN] = value; } - public bool PreRelease { get => _boolVal[PRERELEASE]; set => _boolVal[PRERELEASE] = value; } - public bool SkipMinorUpdates { get => _boolVal[SKIP_MINOR]; set => _boolVal[SKIP_MINOR] = value; } - public bool RemoveDataOnUninstall { get => _boolVal[REMOVE_DATA_UNINST]; set => _boolVal[REMOVE_DATA_UNINST] = value; } - public bool UninstallPreviousVersionsOnUpdate { get => _boolVal[CLEAR_PREV_VER]; set => _boolVal[CLEAR_PREV_VER] = value; } - public bool AbortOnPreInstallFail { get => _boolVal[ABORT_PRE_INST_FAIL]; set => _boolVal[ABORT_PRE_INST_FAIL] = value; } - public bool AbortOnPreUpdateFail { get => _boolVal[ABORT_PRE_UPD_FAIL]; set => _boolVal[ABORT_PRE_UPD_FAIL] = value; } - public bool AbortOnPreUninstallFail { get => _boolVal[ABORT_PRE_UNINST_FAIL]; set => _boolVal[ABORT_PRE_UNINST_FAIL] = value; } - public bool AutoUpdatePackage { get => _boolVal[AUTO_UPDATE_PACKAGE]; set => _boolVal[AUTO_UPDATE_PACKAGE] = value; } - - public string Architecture { get => _strVal[ARCH]; set => _strVal[ARCH] = value; } - public string InstallationScope { get => _strVal[SCOPE]; set => _strVal[SCOPE] = value; } - public string CustomInstallLocation { get => _strVal[LOCATION]; set => _strVal[LOCATION] = value; } - public string Version { get => _strVal[VERSION]; set => _strVal[VERSION] = value; } - public string PreInstallCommand { get => _strVal[PRE_INST_CMD]; set => _strVal[PRE_INST_CMD] = value; } - public string PostInstallCommand { get => _strVal[POST_INST_CMD]; set => _strVal[POST_INST_CMD] = value; } - public string PreUpdateCommand { get => _strVal[PRE_UPD_CMD]; set => _strVal[PRE_UPD_CMD] = value; } - public string PostUpdateCommand { get => _strVal[POST_UPD_CMD]; set => _strVal[POST_UPD_CMD] = value; } - public string PreUninstallCommand { get => _strVal[PRE_UNINST_CMD]; set => _strVal[PRE_UNINST_CMD] = value; } - public string PostUninstallCommand { get => _strVal[POST_UNINST_CMD]; set => _strVal[POST_UNINST_CMD] = value; } - - public List CustomParameters_Install { get => _listVal[INST_PARAMS]; set => _listVal[INST_PARAMS] = value; } - public List CustomParameters_Update { get => _listVal[UPD_PARAMS]; set => _listVal[UPD_PARAMS] = value; } - public List CustomParameters_Uninstall { get => _listVal[UNINST_PARAMS]; set => _listVal[UNINST_PARAMS] = value; } - public List KillBeforeOperation { get => _listVal[KILL_BEFORE_OP]; set => _listVal[KILL_BEFORE_OP] = value; } + public bool SkipHashCheck + { + get => _boolVal[SKIP_HASH]; + set => _boolVal[SKIP_HASH] = value; + } + public bool InteractiveInstallation + { + get => _boolVal[INTERACTIVE]; + set => _boolVal[INTERACTIVE] = value; + } + public bool RunAsAdministrator + { + get => _boolVal[AS_ADMIN]; + set => _boolVal[AS_ADMIN] = value; + } + public bool PreRelease + { + get => _boolVal[PRERELEASE]; + set => _boolVal[PRERELEASE] = value; + } + public bool SkipMinorUpdates + { + get => _boolVal[SKIP_MINOR]; + set => _boolVal[SKIP_MINOR] = value; + } + public bool RemoveDataOnUninstall + { + get => _boolVal[REMOVE_DATA_UNINST]; + set => _boolVal[REMOVE_DATA_UNINST] = value; + } + public bool UninstallPreviousVersionsOnUpdate + { + get => _boolVal[CLEAR_PREV_VER]; + set => _boolVal[CLEAR_PREV_VER] = value; + } + public bool AbortOnPreInstallFail + { + get => _boolVal[ABORT_PRE_INST_FAIL]; + set => _boolVal[ABORT_PRE_INST_FAIL] = value; + } + public bool AbortOnPreUpdateFail + { + get => _boolVal[ABORT_PRE_UPD_FAIL]; + set => _boolVal[ABORT_PRE_UPD_FAIL] = value; + } + public bool AbortOnPreUninstallFail + { + get => _boolVal[ABORT_PRE_UNINST_FAIL]; + set => _boolVal[ABORT_PRE_UNINST_FAIL] = value; + } + public bool AutoUpdatePackage + { + get => _boolVal[AUTO_UPDATE_PACKAGE]; + set => _boolVal[AUTO_UPDATE_PACKAGE] = value; + } + + public string Architecture + { + get => _strVal[ARCH]; + set => _strVal[ARCH] = value; + } + public string InstallationScope + { + get => _strVal[SCOPE]; + set => _strVal[SCOPE] = value; + } + public string CustomInstallLocation + { + get => _strVal[LOCATION]; + set => _strVal[LOCATION] = value; + } + public string Version + { + get => _strVal[VERSION]; + set => _strVal[VERSION] = value; + } + public string PreInstallCommand + { + get => _strVal[PRE_INST_CMD]; + set => _strVal[PRE_INST_CMD] = value; + } + public string PostInstallCommand + { + get => _strVal[POST_INST_CMD]; + set => _strVal[POST_INST_CMD] = value; + } + public string PreUpdateCommand + { + get => _strVal[PRE_UPD_CMD]; + set => _strVal[PRE_UPD_CMD] = value; + } + public string PostUpdateCommand + { + get => _strVal[POST_UPD_CMD]; + set => _strVal[POST_UPD_CMD] = value; + } + public string PreUninstallCommand + { + get => _strVal[PRE_UNINST_CMD]; + set => _strVal[PRE_UNINST_CMD] = value; + } + public string PostUninstallCommand + { + get => _strVal[POST_UNINST_CMD]; + set => _strVal[POST_UNINST_CMD] = value; + } + + public List CustomParameters_Install + { + get => _listVal[INST_PARAMS]; + set => _listVal[INST_PARAMS] = value; + } + public List CustomParameters_Update + { + get => _listVal[UPD_PARAMS]; + set => _listVal[UPD_PARAMS] = value; + } + public List CustomParameters_Uninstall + { + get => _listVal[UNINST_PARAMS]; + set => _listVal[UNINST_PARAMS] = value; + } + public List KillBeforeOperation + { + get => _listVal[KILL_BEFORE_OP]; + set => _listVal[KILL_BEFORE_OP] = value; + } public bool OverridesNextLevelOpts { get; set; } @@ -134,10 +239,12 @@ public override void LoadFromJson(JsonNode data) _listVal[listKey] = _readArrayFromJson(data, listKey); // Handle case where setting has not been migrated yet to have three different entries for CustomParameters - if (this.CustomParameters_Install.Count is 0 && - this.CustomParameters_Update.Count is 0 && - this.CustomParameters_Uninstall.Count is 0 && - ((data as JsonObject)?.ContainsKey("CustomParameters") ?? false)) + if ( + this.CustomParameters_Install.Count is 0 + && this.CustomParameters_Update.Count is 0 + && this.CustomParameters_Uninstall.Count is 0 + && ((data as JsonObject)?.ContainsKey("CustomParameters") ?? false) + ) { this.CustomParameters_Install = _readArrayFromJson(data, "CustomParameters"); this.CustomParameters_Update = _readArrayFromJson(data, "CustomParameters"); @@ -147,7 +254,8 @@ this.CustomParameters_Uninstall.Count is 0 && // if OverridesNextLevelOpts is not found on the JSON, set it to true or false depending // on whether the current settings instances are different from the default values. // This entry shall be checked the last one, to ensure all other properties are set - this.OverridesNextLevelOpts = data[nameof(OverridesNextLevelOpts)]?.GetValue() ?? DiffersFromDefault(); + this.OverridesNextLevelOpts = + data[nameof(OverridesNextLevelOpts)]?.GetValue() ?? DiffersFromDefault(); } public override JsonObject AsJsonNode() @@ -161,13 +269,15 @@ public override JsonObject AsJsonNode() foreach (var (boolKey, defValue) in _defaultBoolValues) { bool currentValue = _boolVal[boolKey]; - if (currentValue != defValue) obj.Add(boolKey, currentValue); + if (currentValue != defValue) + obj.Add(boolKey, currentValue); } foreach (var stringKey in _stringKeys) { string currentValue = _strVal[stringKey]; - if (currentValue.Any()) obj.Add(stringKey, currentValue); + if (currentValue.Any()) + obj.Add(stringKey, currentValue); } foreach (var listKey in _listKeys) @@ -175,7 +285,12 @@ public override JsonObject AsJsonNode() var currentValue = _listVal[listKey]; if (currentValue.Where(x => x.Any()).Any()) { - obj.Add(listKey, new JsonArray(currentValue.Select(x => JsonValue.Create(x) as JsonNode).ToArray())); + obj.Add( + listKey, + new JsonArray( + currentValue.Select(x => JsonValue.Create(x) as JsonNode).ToArray() + ) + ); } } @@ -194,20 +309,24 @@ private static List _readArrayFromJson(JsonNode data, string name) public bool DiffersFromDefault() { foreach (var (boolKey, defValue) in _defaultBoolValues) - if (_boolVal[boolKey] != defValue) return true; + if (_boolVal[boolKey] != defValue) + return true; foreach (var stringKey in _stringKeys) - if (_strVal[stringKey].Any()) return true; + if (_strVal[stringKey].Any()) + return true; foreach (var listKey in _listKeys) - if (_listVal[listKey].Where(x => x.Any()).Any()) return true; + if (_listVal[listKey].Where(x => x.Any()).Any()) + return true; return false; // OverridesNextLevelOpts does not need to be checked here, since // this method is invoked before this property has been set } - public InstallOptions() : base() + public InstallOptions() + : base() { // Initialize default values, ensure keys exist foreach (var (boolKey, defValue) in _defaultBoolValues) @@ -232,13 +351,15 @@ public override string ToString() foreach (var (boolKey, defValue) in _defaultBoolValues) { bool currentValue = _boolVal[boolKey]; - if (currentValue != defValue) b.Append($"\n\t{boolKey}: {currentValue}"); + if (currentValue != defValue) + b.Append($"\n\t{boolKey}: {currentValue}"); } foreach (var stringKey in _stringKeys) { string currentValue = _strVal[stringKey]; - if (currentValue.Any()) b.Append($"\n\t{stringKey}: \"{currentValue}\""); + if (currentValue.Any()) + b.Append($"\n\t{stringKey}: \"{currentValue}\""); } foreach (var listKey in _listKeys) diff --git a/src/UniGetUI.PackageEngine.Serializable/SerializableBundle.cs b/src/UniGetUI.PackageEngine.Serializable/SerializableBundle.cs index 99109f23c4..7c4bbafb66 100644 --- a/src/UniGetUI.PackageEngine.Serializable/SerializableBundle.cs +++ b/src/UniGetUI.PackageEngine.Serializable/SerializableBundle.cs @@ -1,16 +1,17 @@ using System.Text.Json.Nodes; -using UniGetUI.PackageEngine.Serializable; using UniGetUI.Core.Data; +using UniGetUI.PackageEngine.Serializable; namespace UniGetUI.PackageEngine.Classes.Serializable { - public class SerializableBundle: SerializableComponent + public class SerializableBundle : SerializableComponent { public const double ExpectedVersion = 3; - public const string IncompatMessage = "Incompatible packages cannot be installed from UniGetUI, " + - "either because they came from a local source (for example Local PC) " + - "or because the package manager was unavailable. " + - "Nevertheless, they have been listed here for logging purposes."; + public const string IncompatMessage = + "Incompatible packages cannot be installed from UniGetUI, " + + "either because they came from a local source (for example Local PC) " + + "or because the package manager was unavailable. " + + "Nevertheless, they have been listed here for logging purposes."; public double export_version { get; set; } = 3; public List packages { get; set; } = []; @@ -22,10 +23,10 @@ public override SerializableBundle Copy() var _packages = new List(); var _incompatPackages = new List(); - foreach(var package in this.packages) + foreach (var package in this.packages) _packages.Add(package.Copy()); - foreach(var incompatPackage in this.incompatible_packages) + foreach (var incompatPackage in this.incompatible_packages) _incompatPackages.Add(incompatPackage.Copy()); return new() @@ -33,26 +34,29 @@ public override SerializableBundle Copy() export_version = this.export_version, packages = _packages, incompatible_packages_info = this.incompatible_packages_info, - incompatible_packages = _incompatPackages + incompatible_packages = _incompatPackages, }; } public override void LoadFromJson(JsonNode data) { this.export_version = data[nameof(export_version)]?.GetVal() ?? 0; - this.incompatible_packages_info = data[nameof(incompatible_packages_info)]?.GetVal() ?? IncompatMessage; + this.incompatible_packages_info = + data[nameof(incompatible_packages_info)]?.GetVal() ?? IncompatMessage; this.packages = new List(); this.incompatible_packages = new List(); foreach (JsonNode? pkg in data[nameof(packages)]?.AsArray2() ?? new()) { - if (pkg is null) throw new InvalidDataException("JsonNode? pkg was null, when it shouldn't"); + if (pkg is null) + throw new InvalidDataException("JsonNode? pkg was null, when it shouldn't"); packages.Add(new SerializablePackage(pkg)); } foreach (JsonNode? inc_pkg in data[nameof(incompatible_packages)]?.AsArray2() ?? new()) { - if (inc_pkg is null) throw new InvalidDataException("JsonNode? inc_pkg was null, when it shouldn't"); + if (inc_pkg is null) + throw new InvalidDataException("JsonNode? inc_pkg was null, when it shouldn't"); incompatible_packages.Add(new SerializableIncompatiblePackage(inc_pkg)); } } @@ -61,18 +65,22 @@ public override JsonObject AsJsonNode() { JsonObject obj = new(); obj.Add(nameof(export_version), export_version); - obj.Add(nameof(packages), new JsonArray(packages.Select(p => p.AsJsonNode()).ToArray())); + obj.Add( + nameof(packages), + new JsonArray(packages.Select(p => p.AsJsonNode()).ToArray()) + ); obj.Add(nameof(incompatible_packages_info), incompatible_packages_info); - obj.Add(nameof(incompatible_packages), new JsonArray(incompatible_packages.Select(p => p.AsJsonNode()).ToArray())); + obj.Add( + nameof(incompatible_packages), + new JsonArray(incompatible_packages.Select(p => p.AsJsonNode()).ToArray()) + ); return obj; } - public SerializableBundle() : base() - { - } + public SerializableBundle() + : base() { } - public SerializableBundle(JsonNode data) : base(data) - { - } + public SerializableBundle(JsonNode data) + : base(data) { } } } diff --git a/src/UniGetUI.PackageEngine.Serializable/SerializableComponent.cs b/src/UniGetUI.PackageEngine.Serializable/SerializableComponent.cs index e66cfe1781..1e40f934dc 100644 --- a/src/UniGetUI.PackageEngine.Serializable/SerializableComponent.cs +++ b/src/UniGetUI.PackageEngine.Serializable/SerializableComponent.cs @@ -4,7 +4,8 @@ namespace UniGetUI.PackageEngine.Serializable; -public abstract class SerializableComponent where T: class +public abstract class SerializableComponent + where T : class { /// /// Creates a deep copy of the object @@ -36,9 +37,7 @@ public string AsJsonString() /// /// Creates an instance of this object with the default data /// - public SerializableComponent() - { - } + public SerializableComponent() { } /// /// Creates an instance of this object, and loads the data from the given JsonNode object diff --git a/src/UniGetUI.PackageEngine.Serializable/SerializableIncompatiblePackage.cs b/src/UniGetUI.PackageEngine.Serializable/SerializableIncompatiblePackage.cs index bdd4f2adda..dcbaf40954 100644 --- a/src/UniGetUI.PackageEngine.Serializable/SerializableIncompatiblePackage.cs +++ b/src/UniGetUI.PackageEngine.Serializable/SerializableIncompatiblePackage.cs @@ -1,10 +1,11 @@ -using System.Text.Json.Nodes; +using System.Text.Json.Nodes; using UniGetUI.Core.Data; using UniGetUI.PackageEngine.Serializable; namespace UniGetUI.PackageEngine.Classes.Serializable { - public class SerializableIncompatiblePackage: SerializableComponent + public class SerializableIncompatiblePackage + : SerializableComponent { public string Id { get; set; } = ""; public string Name { get; set; } = ""; @@ -15,7 +16,10 @@ public override SerializableIncompatiblePackage Copy() { return new() { - Id = this.Id, Name = this.Name, Version = this.Version, Source = this.Source, + Id = this.Id, + Name = this.Name, + Version = this.Version, + Source = this.Source, }; } @@ -37,12 +41,10 @@ public override JsonObject AsJsonNode() return obj; } - public SerializableIncompatiblePackage(JsonNode data) : base(data) - { - } + public SerializableIncompatiblePackage(JsonNode data) + : base(data) { } - public SerializableIncompatiblePackage(): base() - { - } + public SerializableIncompatiblePackage() + : base() { } } } diff --git a/src/UniGetUI.PackageEngine.Serializable/SerializablePackage.cs b/src/UniGetUI.PackageEngine.Serializable/SerializablePackage.cs index 016887561e..88de99cc56 100644 --- a/src/UniGetUI.PackageEngine.Serializable/SerializablePackage.cs +++ b/src/UniGetUI.PackageEngine.Serializable/SerializablePackage.cs @@ -4,7 +4,7 @@ namespace UniGetUI.PackageEngine.Classes.Serializable { - public class SerializablePackage: SerializableComponent + public class SerializablePackage : SerializableComponent { public string Id { get; set; } = ""; public string Name { get; set; } = ""; @@ -65,13 +65,11 @@ public override JsonObject AsJsonNode() return obj; } - public SerializablePackage() : base() - { - } + public SerializablePackage() + : base() { } - public SerializablePackage(JsonNode data) : base(data) - { - } + public SerializablePackage(JsonNode data) + : base(data) { } /// /// Returns an equivalent copy of the current package as an Invalid Serializable Package. diff --git a/src/UniGetUI.PackageEngine.Serializable/SerializableUpdatesOptions.cs b/src/UniGetUI.PackageEngine.Serializable/SerializableUpdatesOptions.cs index 30171dd91f..205ce1e8b7 100644 --- a/src/UniGetUI.PackageEngine.Serializable/SerializableUpdatesOptions.cs +++ b/src/UniGetUI.PackageEngine.Serializable/SerializableUpdatesOptions.cs @@ -4,14 +4,18 @@ namespace UniGetUI.PackageEngine.Classes.Serializable { - public class SerializableUpdatesOptions: SerializableComponent + public class SerializableUpdatesOptions : SerializableComponent { public bool UpdatesIgnored { get; set; } public string IgnoredVersion { get; set; } = ""; public override SerializableUpdatesOptions Copy() { - return new() { UpdatesIgnored = this.UpdatesIgnored, IgnoredVersion = this.IgnoredVersion }; + return new() + { + UpdatesIgnored = this.UpdatesIgnored, + IgnoredVersion = this.IgnoredVersion, + }; } public override void LoadFromJson(JsonNode data) @@ -23,17 +27,17 @@ public override void LoadFromJson(JsonNode data) public override JsonObject AsJsonNode() { JsonObject obj = new(); - if(UpdatesIgnored is not false) obj.Add(nameof(UpdatesIgnored), UpdatesIgnored); - if(IgnoredVersion.Any()) obj.Add(nameof(IgnoredVersion), IgnoredVersion); + if (UpdatesIgnored is not false) + obj.Add(nameof(UpdatesIgnored), UpdatesIgnored); + if (IgnoredVersion.Any()) + obj.Add(nameof(IgnoredVersion), IgnoredVersion); return obj; } - public SerializableUpdatesOptions() : base() - { - } + public SerializableUpdatesOptions() + : base() { } - public SerializableUpdatesOptions(JsonNode data) : base(data) - { - } + public SerializableUpdatesOptions(JsonNode data) + : base(data) { } } } diff --git a/src/UniGetUI.PackageEngine.Serializable/UniGetUI.PackageEngine.Serializable.csproj b/src/UniGetUI.PackageEngine.Serializable/UniGetUI.PackageEngine.Serializable.csproj index 3ed00d4994..139499fb15 100644 --- a/src/UniGetUI.PackageEngine.Serializable/UniGetUI.PackageEngine.Serializable.csproj +++ b/src/UniGetUI.PackageEngine.Serializable/UniGetUI.PackageEngine.Serializable.csproj @@ -1,12 +1,13 @@ + + $(SharedTargetFrameworks) + - - - + + + - - - - - + + + diff --git a/src/UniGetUI.sln b/src/UniGetUI.sln index 5fdbdef3f9..958ff0606e 100644 --- a/src/UniGetUI.sln +++ b/src/UniGetUI.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.9.34407.89 +# Visual Studio Version 18 +VisualStudioVersion = 18.0.11123.170 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UniGetUI", "UniGetUI\UniGetUI.csproj", "{80305A17-2534-48DC-8F75-41F70FCCEAAF}" EndProject diff --git a/src/UniGetUI/App.xaml b/src/UniGetUI/App.xaml index cb852e3cc1..0766abe55c 100644 --- a/src/UniGetUI/App.xaml +++ b/src/UniGetUI/App.xaml @@ -1,718 +1,985 @@ - - - - - - - - - - - - - /Assets/Symbols/Font/fonts/UniGetUI-Symbols.ttf#UniGetUI-Symbols - - - - - - - - - - - - - - - + x:Class="UniGetUI.MainApp" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:local="using:UniGetUI" + xmlns:widgets="using:UniGetUI.Interface.Widgets" +> + + + + + + + + + + + + + /Assets/Symbols/Font/fonts/UniGetUI-Symbols.ttf#UniGetUI-Symbols + + + + + + + + + + diff --git a/src/UniGetUI/App.xaml.cs b/src/UniGetUI/App.xaml.cs index 3f492efe30..dfb70bb391 100644 --- a/src/UniGetUI/App.xaml.cs +++ b/src/UniGetUI/App.xaml.cs @@ -1,25 +1,25 @@ using System.Diagnostics; using System.Text.RegularExpressions; -using Windows.ApplicationModel.Activation; using CommunityToolkit.WinUI.Helpers; using Microsoft.UI.Dispatching; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; +using Microsoft.Windows.AppLifecycle; +using Microsoft.Windows.AppNotifications; using UniGetUI.Core.Data; using UniGetUI.Core.IconEngine; using UniGetUI.Core.Logging; using UniGetUI.Core.SettingsEngine; +using UniGetUI.Core.SettingsEngine.SecureSettings; using UniGetUI.Core.Tools; using UniGetUI.Interface; +using UniGetUI.Interface.Telemetry; using UniGetUI.PackageEngine; using UniGetUI.PackageEngine.Classes.Manager.Classes; -using Microsoft.Windows.AppLifecycle; -using Microsoft.Windows.AppNotifications; -using UniGetUI.Core.SettingsEngine.SecureSettings; -using UniGetUI.Interface.Telemetry; using UniGetUI.PackageEngine.Interfaces; -using LaunchActivatedEventArgs = Microsoft.UI.Xaml.LaunchActivatedEventArgs; using UniGetUI.Pages.DialogPages; +using Windows.ApplicationModel.Activation; +using LaunchActivatedEventArgs = Microsoft.UI.Xaml.LaunchActivatedEventArgs; namespace UniGetUI { @@ -33,21 +33,33 @@ public static class Tooltip public static int ErrorsOccurred { get => _errors_occurred; - set { _errors_occurred = value; Instance?.MainWindow?.UpdateSystemTrayStatus(); } + set + { + _errors_occurred = value; + Instance?.MainWindow?.UpdateSystemTrayStatus(); + } } private static bool _restart_required; public static bool RestartRequired { get => _restart_required; - set { _restart_required = value; Instance?.MainWindow?.UpdateSystemTrayStatus(); } + set + { + _restart_required = value; + Instance?.MainWindow?.UpdateSystemTrayStatus(); + } } private static int _available_updates; public static int AvailableUpdates { get => _available_updates; - set { _available_updates = value; Instance?.MainWindow?.UpdateSystemTrayStatus(); } + set + { + _available_updates = value; + Instance?.MainWindow?.UpdateSystemTrayStatus(); + } } } @@ -99,7 +111,9 @@ private static async Task LoadGSudo() { if (Settings.Get(Settings.K.ProhibitElevation)) { - Logger.Warn("UniGetUI Elevator has been disabled since elevation is prohibited!"); + Logger.Warn( + "UniGetUI Elevator has been disabled since elevation is prohibited!" + ); } if (SecureSettings.Get(SecureSettings.K.ForceUserGSudo)) @@ -108,16 +122,25 @@ private static async Task LoadGSudo() if (res.Item1) { CoreData.ElevatorPath = res.Item2; - Logger.Warn($"Using user GSudo (forced by user) at {CoreData.ElevatorPath}"); + Logger.Warn( + $"Using user GSudo (forced by user) at {CoreData.ElevatorPath}" + ); return; } } #if DEBUG - Logger.Warn($"Using bundled GSudo at {CoreData.ElevatorPath} since UniGetUI Elevator is not available!"); + Logger.Warn( + $"Using bundled GSudo at {CoreData.ElevatorPath} since UniGetUI Elevator is not available!" + ); CoreData.ElevatorPath = (await CoreTools.WhichAsync("gsudo.exe")).Item2; #else - CoreData.ElevatorPath = Path.Join(CoreData.UniGetUIExecutableDirectory, "Assets", "Utilities", "UniGetUI Elevator.exe"); + CoreData.ElevatorPath = Path.Join( + CoreData.UniGetUIExecutableDirectory, + "Assets", + "Utilities", + "UniGetUI Elevator.exe" + ); Logger.Debug($"Using built-in UniGetUI Elevator at {CoreData.ElevatorPath}"); #endif } @@ -134,7 +157,8 @@ private void RegisterErrorHandling() { UnhandledException += (_, e) => { - if (Debugger.IsAttached) Debugger.Break(); + if (Debugger.IsAttached) + Debugger.Break(); string message = $"Unhandled Exception raised: {e.Message}"; string stackTrace = $"Stack Trace: \n{e.Exception.StackTrace}"; Logger.Error(" -"); @@ -145,18 +169,24 @@ private void RegisterErrorHandling() Logger.Error(" ⚠️⚠️⚠️ END OF UNHANDLED ERROR TRACE ⚠️⚠️⚠️"); Logger.Error(" -"); Logger.Error(" -"); - if (Environment.GetCommandLineArgs().Contains("--report-all-errors") || RaiseExceptionAsFatal || MainWindow is null) + if ( + Environment.GetCommandLineArgs().Contains("--report-all-errors") + || RaiseExceptionAsFatal + || MainWindow is null + ) { CrashHandler.ReportFatalException(e.Exception); } else { MainWindow.ErrorBanner.Title = CoreTools.Translate("Something went wrong"); - MainWindow.ErrorBanner.Message = - CoreTools.Translate("An interal error occurred. Please view the log for further details."); + MainWindow.ErrorBanner.Message = CoreTools.Translate( + "An interal error occurred. Please view the log for further details." + ); MainWindow.ErrorBanner.IsOpen = true; - Button button = new() { Content = CoreTools.Translate("WingetUI Log"), }; - button.Click += (sender, args) => MainWindow.NavigationPage.UniGetUILogs_Click(sender, args); + Button button = new() { Content = CoreTools.Translate("WingetUI Log") }; + button.Click += (sender, args) => + MainWindow.NavigationPage.UniGetUILogs_Click(sender, args); MainWindow.ErrorBanner.ActionButton = button; DialogHelper.HideAllLoadingDialogs(); e.Handled = true; @@ -165,7 +195,8 @@ private void RegisterErrorHandling() } catch (Exception ex) { - if(Debugger.IsAttached) Debugger.Break(); + if (Debugger.IsAttached) + Debugger.Break(); Logger.Error(ex); } @@ -173,7 +204,9 @@ private void RegisterErrorHandling() { TaskScheduler.UnobservedTaskException += (sender, args) => { - Logger.Error($"An unhandled exception occurred in a Task (sender: {sender?.GetType().ToString() ?? "null"})"); + Logger.Error( + $"An unhandled exception occurred in a Task (sender: {sender?.GetType().ToString() ?? "null"})" + ); Exception? e = args.Exception.InnerException; Logger.Error(args.Exception); while (e is not null) @@ -183,7 +216,8 @@ private void RegisterErrorHandling() e = e.InnerException; } - if (Debugger.IsAttached) Debugger.Break(); + if (Debugger.IsAttached) + Debugger.Break(); Dispatcher.TryEnqueue(() => { @@ -191,14 +225,18 @@ private void RegisterErrorHandling() return; // MainWindow could have not been loaded yet try { - MainWindow.ErrorBanner.Title = CoreTools.Translate("Something went wrong"); + MainWindow.ErrorBanner.Title = CoreTools.Translate( + "Something went wrong" + ); MainWindow.ErrorBanner.Message = CoreTools.Translate( - "An interal error occurred. Please view the log for further details."); + "An interal error occurred. Please view the log for further details." + ); MainWindow.ErrorBanner.IsOpen = true; - Button button = new() { Content = CoreTools.Translate("WingetUI Log"), }; + Button button = new() { Content = CoreTools.Translate("WingetUI Log") }; if (MainWindow.NavigationPage is not null) - { // MainWindow.NavigationPage could have not been loaded yet - button.Click += (s, a) => MainWindow.NavigationPage.UniGetUILogs_Click(s, a); + { // MainWindow.NavigationPage could have not been loaded yet + button.Click += (s, a) => + MainWindow.NavigationPage.UniGetUILogs_Click(s, a); } MainWindow.ErrorBanner.ActionButton = button; DialogHelper.HideAllLoadingDialogs(); @@ -214,7 +252,8 @@ private void RegisterErrorHandling() } catch (Exception ex) { - if (Debugger.IsAttached) Debugger.Break(); + if (Debugger.IsAttached) + Debugger.Break(); Logger.Error(ex); } } @@ -243,10 +282,7 @@ private static void SetUpWebViewUserDataFolder() /// private void InitializeMainWindow() { - MainWindow = new MainWindow - { - BlockLoading = true - }; + MainWindow = new MainWindow { BlockLoading = true }; MainWindow.Closed += (_, _) => DisposeAndQuit(0); nint hWnd = MainWindow.GetWindowHandle(); @@ -314,7 +350,9 @@ private async Task LoadComponentsAsync() _ = IconDatabase.Instance.LoadIconAndScreenshotsDatabaseAsync(); // Load interface - Logger.Info("LoadComponentsAsync finished executing. All managers loaded. Proceeding to interface."); + Logger.Info( + "LoadComponentsAsync finished executing. All managers loaded. Proceeding to interface." + ); MainWindow.SwitchToInterface(); RaiseExceptionAsFatal = false; @@ -351,21 +389,24 @@ private async Task InitializeBackgroundAPI() BackgroundApi.OnOpenWindow += (_, _) => MainWindow.DispatcherQueue.TryEnqueue(() => MainWindow.Activate()); - BackgroundApi.OnOpenUpdatesPage += (_, _) => MainWindow.DispatcherQueue.TryEnqueue(() => - { - MainWindow?.NavigationPage?.NavigateTo(PageType.Updates); - MainWindow?.Activate(); - }); + BackgroundApi.OnOpenUpdatesPage += (_, _) => + MainWindow.DispatcherQueue.TryEnqueue(() => + { + MainWindow?.NavigationPage?.NavigateTo(PageType.Updates); + MainWindow?.Activate(); + }); - BackgroundApi.OnShowSharedPackage += (_, package) => MainWindow.DispatcherQueue.TryEnqueue(() => - { - DialogHelper.ShowSharedPackage_ThreadSafe(package.Key, package.Value); - }); + BackgroundApi.OnShowSharedPackage += (_, package) => + MainWindow.DispatcherQueue.TryEnqueue(() => + { + DialogHelper.ShowSharedPackage_ThreadSafe(package.Key, package.Value); + }); - BackgroundApi.OnUpgradeAll += (_, _) => MainWindow.DispatcherQueue.TryEnqueue(() => - { - _ = Operations.UpdateAll(); - }); + BackgroundApi.OnUpgradeAll += (_, _) => + MainWindow.DispatcherQueue.TryEnqueue(() => + { + _ = Operations.UpdateAll(); + }); BackgroundApi.OnUpgradeAllForManager += (s, managerName) => MainWindow.DispatcherQueue.TryEnqueue(() => @@ -373,10 +414,11 @@ private async Task InitializeBackgroundAPI() _ = Operations.UpdateAllForManager(managerName); }); - BackgroundApi.OnUpgradePackage += (s, packageId) => MainWindow.DispatcherQueue.TryEnqueue(() => - { - _ = Operations.UpdateForId(packageId); - }); + BackgroundApi.OnUpgradePackage += (s, packageId) => + MainWindow.DispatcherQueue.TryEnqueue(() => + { + _ = Operations.UpdateForId(packageId); + }); await BackgroundApi.Start(); } @@ -385,7 +427,6 @@ private async Task InitializeBackgroundAPI() Logger.Error("Could not initialize Background API:"); Logger.Error(ex); } - } private async Task CheckForMissingDependencies() @@ -409,25 +450,37 @@ private async Task CheckForMissingDependencies() catch (Exception ex) { Logger.Error( - $"An error occurred while checking if dependency {dependency.Name} was installed:"); + $"An error occurred while checking if dependency {dependency.Name} was installed:" + ); Logger.Error(ex); } if (!isInstalled) { - if (Settings.GetDictionaryItem(Settings.K.DependencyManagement, dependency.Name) == "skipped") + if ( + Settings.GetDictionaryItem( + Settings.K.DependencyManagement, + dependency.Name + ) == "skipped" + ) { - Logger.Error($"Dependency {dependency.Name} was not found, and the user set it to not be reminded of the missing dependency"); + Logger.Error( + $"Dependency {dependency.Name} was not found, and the user set it to not be reminded of the missing dependency" + ); } else { - Logger.Warn($"Dependency {dependency.Name} was not found for manager {manager.Name}, marking to prompt..."); + Logger.Warn( + $"Dependency {dependency.Name} was not found for manager {manager.Name}, marking to prompt..." + ); missing_deps.Add(dependency); } } else { - Logger.Info($"Dependency {dependency.Name} for manager {manager.Name} is present"); + Logger.Info( + $"Dependency {dependency.Name} for manager {manager.Name} is present" + ); } } } @@ -451,15 +504,21 @@ public async Task ShowMainWindowFromRedirectAsync(AppActivationArguments rawArgs { // If the app redirection event comes from a launch, extract // the CLI arguments and redirect them to the ParameterProcessor - foreach (Match argument in Regex.Matches(launchArguments.Arguments, - "([^ \"']+|\"[^\"]+\"|'[^']+')")) + foreach ( + Match argument in Regex.Matches( + launchArguments.Arguments, + "([^ \"']+|\"[^\"]+\"|'[^']+')" + ) + ) { MainWindow.ParametersToProcess.Enqueue(argument.Value); } } else { - Logger.Error("REDIRECTOR ACTIVATOR: args.Data was null when casted to ILaunchActivatedEventArgs"); + Logger.Error( + "REDIRECTOR ACTIVATOR: args.Data was null when casted to ILaunchActivatedEventArgs" + ); } } else diff --git a/src/UniGetUI/AppOperationHelper.cs b/src/UniGetUI/AppOperationHelper.cs index 481adb063b..fcf0d57306 100644 --- a/src/UniGetUI/AppOperationHelper.cs +++ b/src/UniGetUI/AppOperationHelper.cs @@ -1,23 +1,23 @@ using System.Collections.Concurrent; using System.Collections.ObjectModel; -using Windows.Storage; -using Windows.Storage.Pickers; using Microsoft.UI.Xaml.Controls; using UniGetUI.Controls.OperationWidgets; using UniGetUI.Core.Logging; using UniGetUI.Core.Tools; using UniGetUI.Interface; +using UniGetUI.Interface.Enums; using UniGetUI.Interface.Telemetry; +using UniGetUI.PackageEngine; using UniGetUI.PackageEngine.Enums; using UniGetUI.PackageEngine.Interfaces; using UniGetUI.PackageEngine.Managers.PowerShellManager; using UniGetUI.PackageEngine.Operations; using UniGetUI.PackageEngine.PackageClasses; +using UniGetUI.PackageEngine.PackageLoader; using UniGetUI.PackageOperations; using UniGetUI.Pages.DialogPages; -using UniGetUI.Interface.Enums; -using UniGetUI.PackageEngine; -using UniGetUI.PackageEngine.PackageLoader; +using Windows.Storage; +using Windows.Storage.Pickers; namespace UniGetUI; @@ -27,21 +27,21 @@ public static class Operations { public static bool AreThereRunningOperations() { - return _operationList.Any() && - _operationList.Any(x => x.Operation.Status is OperationStatus.Running or OperationStatus.InQueue); + return _operationList.Any() + && _operationList.Any(x => + x.Operation.Status is OperationStatus.Running or OperationStatus.InQueue + ); } public static ObservableCollection _operationList = new(); - public static void Add(AbstractOperation op) - => _operationList.Add(new(op)); + public static void Add(AbstractOperation op) => _operationList.Add(new(op)); - public static void Remove(OperationControl control) - => _operationList.Remove(control); + public static void Remove(OperationControl control) => _operationList.Remove(control); public static void Remove(AbstractOperation op) { - foreach(var control in _operationList.Where(x => x.Operation == op).ToArray()) + foreach (var control in _operationList.Where(x => x.Operation == op).ToArray()) { _operationList.Remove(control); } @@ -52,21 +52,29 @@ public static void Remove(AbstractOperation op) * OPERATION CREATION HELPERS * */ - public static async Task AskLocationAndDownload(IPackage? package, TEL_InstallReferral referral) + public static async Task AskLocationAndDownload( + IPackage? package, + TEL_InstallReferral referral + ) { - if (package is null) return null; + if (package is null) + return null; int loadingId = DialogHelper.ShowLoadingDialog(CoreTools.Translate("Please wait...")); try { - var details = package.Details; await details.Load(); if (details.InstallerUrl is null) { DialogHelper.HideLoadingDialog(loadingId); - var dialog = new ContentDialog { Title = CoreTools.Translate("Download failed"), - Content = CoreTools.Translate("No applicable installer was found for the package {0}", package.Name), + var dialog = new ContentDialog + { + Title = CoreTools.Translate("Download failed"), + Content = CoreTools.Translate( + "No applicable installer was found for the package {0}", + package.Name + ), PrimaryButtonText = CoreTools.Translate("Ok"), DefaultButton = ContentDialogButton.Primary, XamlRoot = Instance.MainWindow.Content.XamlRoot, @@ -84,7 +92,7 @@ public static void Remove(AbstractOperation op) string name = await package.GetInstallerFileName() ?? ""; string extension; if (!name.Where(x => x == '.').Any()) - { // As a last resort, we need an extension for the file picker to work + { // As a last resort, we need an extension for the file picker to work extension = "unknown"; name = name + "." + extension; } @@ -116,8 +124,10 @@ public static void Remove(AbstractOperation op) if (file is not null) { var op = new DownloadOperation(package, file.Path); - op.OperationSucceeded += (_, _) => TelemetryHandler.DownloadPackage(package, TEL_OP_RESULT.SUCCESS, referral); - op.OperationFailed += (_, _) => TelemetryHandler.DownloadPackage(package, TEL_OP_RESULT.FAILED, referral); + op.OperationSucceeded += (_, _) => + TelemetryHandler.DownloadPackage(package, TEL_OP_RESULT.SUCCESS, referral); + op.OperationFailed += (_, _) => + TelemetryHandler.DownloadPackage(package, TEL_OP_RESULT.FAILED, referral); Add(op); Instance.MainWindow.UpdateSystemTrayStatus(); return op; @@ -127,18 +137,24 @@ public static void Remove(AbstractOperation op) } catch (Exception ex) { - Logger.Error($"An error occurred while downloading the installer for the package {package.Id}"); + Logger.Error( + $"An error occurred while downloading the installer for the package {package.Id}" + ); Logger.Error(ex); DialogHelper.HideLoadingDialog(loadingId); return null; } } - public static async Task Download(IEnumerable packages, TEL_InstallReferral referral) + public static async Task Download( + IEnumerable packages, + TEL_InstallReferral referral + ) { try { - if (!packages.Any()) return; + if (!packages.Any()) + return; var hWnd = MainApp.Instance.MainWindow.GetWindowHandle(); var a = new ExternalLibraries.Pickers.FolderPicker(hWnd); @@ -148,15 +164,20 @@ public static async Task Download(IEnumerable packages, TEL_InstallRef foreach (var package in packages) { - if (package.Source.IsVirtualManager || !package.Manager.Capabilities.CanDownloadInstaller) + if ( + package.Source.IsVirtualManager + || !package.Manager.Capabilities.CanDownloadInstaller + ) { Logger.Warn($"Package {package.Id} cannot have its installer downloaded."); continue; } var op = new DownloadOperation(package, outputPath); - op.OperationSucceeded += (_, _) => TelemetryHandler.DownloadPackage(package, TEL_OP_RESULT.SUCCESS, referral); - op.OperationFailed += (_, _) => TelemetryHandler.DownloadPackage(package, TEL_OP_RESULT.FAILED, referral); + op.OperationSucceeded += (_, _) => + TelemetryHandler.DownloadPackage(package, TEL_OP_RESULT.SUCCESS, referral); + op.OperationFailed += (_, _) => + TelemetryHandler.DownloadPackage(package, TEL_OP_RESULT.FAILED, referral); Add(op); } } @@ -174,22 +195,42 @@ public static async Task Download(IEnumerable packages, TEL_InstallRef * * */ - public static async Task Install(IPackage? package, TEL_InstallReferral referral, - bool? elevated = null, bool? interactive = null, bool? no_integrity = null, bool ignoreParallel = false, - AbstractOperation? req = null) + public static async Task Install( + IPackage? package, + TEL_InstallReferral referral, + bool? elevated = null, + bool? interactive = null, + bool? no_integrity = null, + bool ignoreParallel = false, + AbstractOperation? req = null + ) { - if (package is null) return null; + if (package is null) + return null; - var options = await InstallOptionsFactory.LoadApplicableAsync(package, elevated, interactive, no_integrity); + var options = await InstallOptionsFactory.LoadApplicableAsync( + package, + elevated, + interactive, + no_integrity + ); var operation = new InstallPackageOperation(package, options, ignoreParallel, req); - operation.OperationSucceeded += (_, _) => TelemetryHandler.InstallPackage(package, TEL_OP_RESULT.SUCCESS, referral); - operation.OperationFailed += (_, _) => TelemetryHandler.InstallPackage(package, TEL_OP_RESULT.FAILED, referral); + operation.OperationSucceeded += (_, _) => + TelemetryHandler.InstallPackage(package, TEL_OP_RESULT.SUCCESS, referral); + operation.OperationFailed += (_, _) => + TelemetryHandler.InstallPackage(package, TEL_OP_RESULT.FAILED, referral); Add(operation); Instance.MainWindow.UpdateSystemTrayStatus(); return operation; } - public static void Install(IReadOnlyList packages, TEL_InstallReferral referral, bool? elevated = null, bool? interactive = null, bool? no_integrity = null) + public static void Install( + IReadOnlyList packages, + TEL_InstallReferral referral, + bool? elevated = null, + bool? interactive = null, + bool? no_integrity = null + ) { foreach (var package in packages) { @@ -197,19 +238,27 @@ public static void Install(IReadOnlyList packages, TEL_InstallReferral } } - public static async Task UninstallThenReinstall(IPackage? package, TEL_InstallReferral referral) + public static async Task UninstallThenReinstall( + IPackage? package, + TEL_InstallReferral referral + ) { - if (package is null) return null; + if (package is null) + return null; var options = await InstallOptionsFactory.LoadApplicableAsync(package); var uninstallOp = new UninstallPackageOperation(package, options); - uninstallOp.OperationSucceeded += (_, _) => TelemetryHandler.UninstallPackage(package, TEL_OP_RESULT.SUCCESS); - uninstallOp.OperationFailed += (_, _) => TelemetryHandler.UninstallPackage(package, TEL_OP_RESULT.FAILED); + uninstallOp.OperationSucceeded += (_, _) => + TelemetryHandler.UninstallPackage(package, TEL_OP_RESULT.SUCCESS); + uninstallOp.OperationFailed += (_, _) => + TelemetryHandler.UninstallPackage(package, TEL_OP_RESULT.FAILED); var installOp = new InstallPackageOperation(package, options, req: uninstallOp); - installOp.OperationSucceeded += (_, _) => TelemetryHandler.InstallPackage(package, TEL_OP_RESULT.SUCCESS, referral); - installOp.OperationFailed += (_, _) => TelemetryHandler.InstallPackage(package, TEL_OP_RESULT.FAILED, referral); + installOp.OperationSucceeded += (_, _) => + TelemetryHandler.InstallPackage(package, TEL_OP_RESULT.SUCCESS, referral); + installOp.OperationFailed += (_, _) => + TelemetryHandler.InstallPackage(package, TEL_OP_RESULT.FAILED, referral); Add(installOp); Instance.MainWindow.UpdateSystemTrayStatus(); @@ -223,31 +272,53 @@ public static void Install(IReadOnlyList packages, TEL_InstallReferral * * */ - public static async Task Update(IPackage? package, bool? elevated = null, bool? interactive = null, bool? no_integrity = null, bool ignoreParallel = false, AbstractOperation? req = null) + public static async Task Update( + IPackage? package, + bool? elevated = null, + bool? interactive = null, + bool? no_integrity = null, + bool ignoreParallel = false, + AbstractOperation? req = null + ) { - if (package is null) return null; + if (package is null) + return null; if (package.NewerVersionIsInstalled()) { - Logger.Warn($"A newer version of {package.Id} has been detected, the update will not be performed!"); + Logger.Warn( + $"A newer version of {package.Id} has been detected, the update will not be performed!" + ); UpgradablePackagesLoader.Instance.Remove(package); foreach (var eq in InstalledPackagesLoader.Instance.GetEquivalentPackages(package)) - { // Remove upgradable tag from all installed packages + { // Remove upgradable tag from all installed packages eq.Tag = PackageTag.Default; } return null; } - var options = await InstallOptionsFactory.LoadApplicableAsync(package, elevated, interactive, no_integrity); + var options = await InstallOptionsFactory.LoadApplicableAsync( + package, + elevated, + interactive, + no_integrity + ); var operation = new UpdatePackageOperation(package, options, ignoreParallel, req); - operation.OperationSucceeded += (_, _) => TelemetryHandler.UpdatePackage(package, TEL_OP_RESULT.SUCCESS); - operation.OperationFailed += (_, _) => TelemetryHandler.UpdatePackage(package, TEL_OP_RESULT.FAILED); + operation.OperationSucceeded += (_, _) => + TelemetryHandler.UpdatePackage(package, TEL_OP_RESULT.SUCCESS); + operation.OperationFailed += (_, _) => + TelemetryHandler.UpdatePackage(package, TEL_OP_RESULT.FAILED); Add(operation); Instance.MainWindow.UpdateSystemTrayStatus(); return operation; } - public static void Update(IReadOnlyList packages, bool? elevated = null, bool? interactive = null, bool? no_integrity = null) + public static void Update( + IReadOnlyList packages, + bool? elevated = null, + bool? interactive = null, + bool? no_integrity = null + ) { foreach (var package in packages) { @@ -258,18 +329,25 @@ public static void Update(IReadOnlyList packages, bool? elevated = nul private static bool AlreadyBeingUpdated(IPackage package) { // Check for duplicate operations already in the queue (prevents duplicates during unattended updates) - return _operationList.Any(x => x.Operation is UpdatePackageOperation updateOp + return _operationList.Any(x => + x.Operation is UpdatePackageOperation updateOp && (x.Operation.Status is OperationStatus.InQueue or OperationStatus.Running) - && updateOp.Package.GetHash() == package.GetHash()); + && updateOp.Package.GetHash() == package.GetHash() + ); } public static async Task UpdateAll() { foreach (IPackage package in UpgradablePackagesLoader.Instance.Packages) - { // First check will only work if the package has not been reloaded, deeper check is needed, hence AlreadyBeingUpdated - if (package.Tag is PackageTag.BeingProcessed or PackageTag.OnQueue || AlreadyBeingUpdated(package)) + { // First check will only work if the package has not been reloaded, deeper check is needed, hence AlreadyBeingUpdated + if ( + package.Tag is PackageTag.BeingProcessed or PackageTag.OnQueue + || AlreadyBeingUpdated(package) + ) { - Logger.Warn($"Update operation for package {package.Id} is already queued or running. Skipping duplicate in UpdateAll."); + Logger.Warn( + $"Update operation for package {package.Id} is already queued or running. Skipping duplicate in UpdateAll." + ); continue; } @@ -281,13 +359,21 @@ public static async Task UpdateAllForManager(string managerName) { foreach (IPackage package in UpgradablePackagesLoader.Instance.Packages) { - if (package.Manager.Name != managerName && package.Manager.DisplayName != managerName) + if ( + package.Manager.Name != managerName + && package.Manager.DisplayName != managerName + ) continue; // Package not from the desired package manager // First check will only work if the package has not been reloaded, deeper check is needed, hence AlreadyBeingUpdated - if (package.Tag is PackageTag.BeingProcessed or PackageTag.OnQueue || AlreadyBeingUpdated(package)) + if ( + package.Tag is PackageTag.BeingProcessed or PackageTag.OnQueue + || AlreadyBeingUpdated(package) + ) { - Logger.Warn($"Update operation for package {package.Id} is already queued or running. Skipping duplicate in UpdateAll."); + Logger.Warn( + $"Update operation for package {package.Id} is already queued or running. Skipping duplicate in UpdateAll." + ); continue; } @@ -312,19 +398,24 @@ public static async Task UpdateForId(string packageId) public static async Task UninstallThenUpdate(IPackage? package) { - if (package is null) return null; + if (package is null) + return null; var options = await InstallOptionsFactory.LoadApplicableAsync(package); var uninstallOp = new UninstallPackageOperation(package, options); - uninstallOp.OperationSucceeded += (_, _) => TelemetryHandler.UninstallPackage(package, TEL_OP_RESULT.SUCCESS); - uninstallOp.OperationFailed += (_, _) => TelemetryHandler.UninstallPackage(package, TEL_OP_RESULT.FAILED); + uninstallOp.OperationSucceeded += (_, _) => + TelemetryHandler.UninstallPackage(package, TEL_OP_RESULT.SUCCESS); + uninstallOp.OperationFailed += (_, _) => + TelemetryHandler.UninstallPackage(package, TEL_OP_RESULT.FAILED); options.Version = package.NewVersionString; options.OverridesNextLevelOpts = true; var installOp = new InstallPackageOperation(package, options, req: uninstallOp); - installOp.OperationSucceeded += (_, _) => TelemetryHandler.UpdatePackage(package, TEL_OP_RESULT.SUCCESS); - installOp.OperationFailed += (_, _) => TelemetryHandler.UpdatePackage(package, TEL_OP_RESULT.FAILED); + installOp.OperationSucceeded += (_, _) => + TelemetryHandler.UpdatePackage(package, TEL_OP_RESULT.SUCCESS); + installOp.OperationFailed += (_, _) => + TelemetryHandler.UpdatePackage(package, TEL_OP_RESULT.FAILED); Add(installOp); Instance.MainWindow.UpdateSystemTrayStatus(); @@ -339,7 +430,12 @@ public static async Task UpdateForId(string packageId) * */ - public static async Task ConfirmAndUninstall(IReadOnlyList packages, bool? elevated = null, bool? interactive = null, bool? remove_data = null) + public static async Task ConfirmAndUninstall( + IReadOnlyList packages, + bool? elevated = null, + bool? interactive = null, + bool? remove_data = null + ) { if (!await DialogHelper.ConfirmUninstallation(packages)) return; @@ -347,28 +443,55 @@ public static async Task ConfirmAndUninstall(IReadOnlyList packages, b await Uninstall(packages, elevated, interactive, remove_data); } - public static async Task ConfirmAndUninstall(IPackage? package, bool? elevated = null, bool? interactive = null, bool? remove_data = null) + public static async Task ConfirmAndUninstall( + IPackage? package, + bool? elevated = null, + bool? interactive = null, + bool? remove_data = null + ) { - if (package is null) return; - if (!await DialogHelper.ConfirmUninstallation(package)) return; + if (package is null) + return; + if (!await DialogHelper.ConfirmUninstallation(package)) + return; await Uninstall(package, elevated, interactive, remove_data); } - public static async Task Uninstall(IPackage? package, bool? elevated = null, bool? interactive = null, bool? remove_data = null, bool ignoreParallel = false, AbstractOperation? req = null) + public static async Task Uninstall( + IPackage? package, + bool? elevated = null, + bool? interactive = null, + bool? remove_data = null, + bool ignoreParallel = false, + AbstractOperation? req = null + ) { - if (package is null) return null; + if (package is null) + return null; - var options = await InstallOptionsFactory.LoadApplicableAsync(package, elevated, interactive, remove_data: remove_data); + var options = await InstallOptionsFactory.LoadApplicableAsync( + package, + elevated, + interactive, + remove_data: remove_data + ); var operation = new UninstallPackageOperation(package, options, ignoreParallel, req); - operation.OperationSucceeded += (_, _) => TelemetryHandler.UninstallPackage(package, TEL_OP_RESULT.SUCCESS); - operation.OperationFailed += (_, _) => TelemetryHandler.UninstallPackage(package, TEL_OP_RESULT.FAILED); + operation.OperationSucceeded += (_, _) => + TelemetryHandler.UninstallPackage(package, TEL_OP_RESULT.SUCCESS); + operation.OperationFailed += (_, _) => + TelemetryHandler.UninstallPackage(package, TEL_OP_RESULT.FAILED); Add(operation); Instance.MainWindow.UpdateSystemTrayStatus(); return operation; } - public static async Task Uninstall(IReadOnlyList packages, bool? elevated = null, bool? interactive = null, bool? remove_data = null) + public static async Task Uninstall( + IReadOnlyList packages, + bool? elevated = null, + bool? interactive = null, + bool? remove_data = null + ) { foreach (var package in packages) { diff --git a/src/UniGetUI/AutoUpdater.cs b/src/UniGetUI/AutoUpdater.cs index 01baa7eaab..59b4851db5 100644 --- a/src/UniGetUI/AutoUpdater.cs +++ b/src/UniGetUI/AutoUpdater.cs @@ -5,9 +5,9 @@ using System.Security.Cryptography.X509Certificates; using System.Text.Json; using System.Text.Json.Serialization; -using Microsoft.Win32; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; +using Microsoft.Win32; using Microsoft.Windows.AppNotifications; using Microsoft.Windows.AppNotifications.Builder; using UniGetUI.Core.Data; @@ -39,15 +39,22 @@ public partial class AutoUpdater "50f753333811ff11f1920274afde3ffd4468b210", ]; - private static readonly AutoUpdaterJsonContext ProductInfoJsonContext = new(SerializationHelpers.DefaultOptions); + private static readonly AutoUpdaterJsonContext ProductInfoJsonContext = new( + SerializationHelpers.DefaultOptions + ); public static Window Window = null!; public static InfoBar Banner = null!; + //------------------------------------------------------------------------------------------------------------------ - private const string STABLE_ENDPOINT = "https://www.marticliment.com/versions/unigetui/stable.ver"; + private const string STABLE_ENDPOINT = + "https://www.marticliment.com/versions/unigetui/stable.ver"; private const string BETA_ENDPOINT = "https://www.marticliment.com/versions/unigetui/beta.ver"; - private const string STABLE_INSTALLER_URL = "https://github.com/Devolutions/UniGetUI/releases/latest/download/UniGetUI.Installer.exe"; - private const string BETA_INSTALLER_URL = "https://github.com/Devolutions/UniGetUI/releases/download/$TAG/UniGetUI.Installer.exe"; + private const string STABLE_INSTALLER_URL = + "https://github.com/Devolutions/UniGetUI/releases/latest/download/UniGetUI.Installer.exe"; + private const string BETA_INSTALLER_URL = + "https://github.com/Devolutions/UniGetUI/releases/download/$TAG/UniGetUI.Installer.exe"; + //------------------------------------------------------------------------------------------------------------------ public static bool ReleaseLockForAutoupdate_Notification; public static bool ReleaseLockForAutoupdate_Window; @@ -75,7 +82,12 @@ public static async Task UpdateCheckLoop(Window window, InfoBar banner) Logger.Warn("User has disabled updates"); return; } - bool updateSucceeded = await CheckAndInstallUpdates(window, banner, false, IsFirstLaunch); + bool updateSucceeded = await CheckAndInstallUpdates( + window, + banner, + false, + IsFirstLaunch + ); IsFirstLaunch = false; await Task.Delay(TimeSpan.FromMinutes(updateSucceeded ? 60 : 10)); } @@ -84,7 +96,13 @@ public static async Task UpdateCheckLoop(Window window, InfoBar banner) /// /// Performs the entire update process, and returns true/false whether the process finished successfully; /// - public static async Task CheckAndInstallUpdates(Window window, InfoBar banner, bool Verbose, bool AutoLaunch = false, bool ManualCheck = false) + public static async Task CheckAndInstallUpdates( + Window window, + InfoBar banner, + bool Verbose, + bool AutoLaunch = false, + bool ManualCheck = false + ) { Window = window; Banner = banner; @@ -93,77 +111,116 @@ public static async Task CheckAndInstallUpdates(Window window, InfoBar ban try { - if (Verbose) ShowMessage_ThreadSafe( - CoreTools.Translate("We are checking for updates."), - CoreTools.Translate("Please wait"), - InfoBarSeverity.Informational, - false - ); + if (Verbose) + ShowMessage_ThreadSafe( + CoreTools.Translate("We are checking for updates."), + CoreTools.Translate("Please wait"), + InfoBarSeverity.Informational, + false + ); // Check for updates UpdateCandidate updateCandidate = await GetUpdateCandidate(updaterOverrides); - Logger.Info($"Updater source '{updateCandidate.SourceName}' returned version {updateCandidate.VersionName} (upgradable={updateCandidate.IsUpgradable})"); + Logger.Info( + $"Updater source '{updateCandidate.SourceName}' returned version {updateCandidate.VersionName} (upgradable={updateCandidate.IsUpgradable})" + ); if (updateCandidate.IsUpgradable) { WasCheckingForUpdates = false; - Logger.Info($"An update to UniGetUI version {updateCandidate.VersionName} is available"); - string InstallerPath = Path.Join(CoreData.UniGetUIDataDirectory, "UniGetUI Updater.exe"); + Logger.Info( + $"An update to UniGetUI version {updateCandidate.VersionName} is available" + ); + string InstallerPath = Path.Join( + CoreData.UniGetUIDataDirectory, + "UniGetUI Updater.exe" + ); - if (File.Exists(InstallerPath) - && await CheckInstallerHash(InstallerPath, updateCandidate.InstallerHash, updaterOverrides) - && CheckInstallerSignerThumbprint(InstallerPath, updaterOverrides)) + if ( + File.Exists(InstallerPath) + && await CheckInstallerHash( + InstallerPath, + updateCandidate.InstallerHash, + updaterOverrides + ) + && CheckInstallerSignerThumbprint(InstallerPath, updaterOverrides) + ) { Logger.Info($"A cached valid installer was found, launching update process..."); - return await PrepairToLaunchInstaller(InstallerPath, updateCandidate.VersionName, AutoLaunch, ManualCheck); + return await PrepairToLaunchInstaller( + InstallerPath, + updateCandidate.VersionName, + AutoLaunch, + ManualCheck + ); } File.Delete(InstallerPath); ShowMessage_ThreadSafe( - CoreTools.Translate("UniGetUI version {0} is being downloaded.", updateCandidate.VersionName.ToString(CultureInfo.InvariantCulture)), + CoreTools.Translate( + "UniGetUI version {0} is being downloaded.", + updateCandidate.VersionName.ToString(CultureInfo.InvariantCulture) + ), CoreTools.Translate("This may take a minute or two"), InfoBarSeverity.Informational, - false); + false + ); // Download the installer - await DownloadInstaller(updateCandidate.InstallerDownloadUrl, InstallerPath, updaterOverrides); + await DownloadInstaller( + updateCandidate.InstallerDownloadUrl, + InstallerPath, + updaterOverrides + ); - if (await CheckInstallerHash(InstallerPath, updateCandidate.InstallerHash, updaterOverrides) - && CheckInstallerSignerThumbprint(InstallerPath, updaterOverrides)) + if ( + await CheckInstallerHash( + InstallerPath, + updateCandidate.InstallerHash, + updaterOverrides + ) && CheckInstallerSignerThumbprint(InstallerPath, updaterOverrides) + ) { Logger.Info("The downloaded installer is valid, launching update process..."); - return await PrepairToLaunchInstaller(InstallerPath, updateCandidate.VersionName, AutoLaunch, ManualCheck); + return await PrepairToLaunchInstaller( + InstallerPath, + updateCandidate.VersionName, + AutoLaunch, + ManualCheck + ); } ShowMessage_ThreadSafe( CoreTools.Translate("The installer authenticity could not be verified."), CoreTools.Translate("The update process has been aborted."), InfoBarSeverity.Error, - true); + true + ); return false; } - if (Verbose) ShowMessage_ThreadSafe( - CoreTools.Translate("Great! You are on the latest version."), - CoreTools.Translate("There are no new UniGetUI versions to be installed"), - InfoBarSeverity.Success, - true - ); + if (Verbose) + ShowMessage_ThreadSafe( + CoreTools.Translate("Great! You are on the latest version."), + CoreTools.Translate("There are no new UniGetUI versions to be installed"), + InfoBarSeverity.Success, + true + ); return true; - } catch (Exception e) { Logger.Error("An error occurred while checking for updates: "); Logger.Error(e); // We don't want an error popping if updates can't - if (Verbose || !WasCheckingForUpdates) ShowMessage_ThreadSafe( - CoreTools.Translate("An error occurred when checking for updates: "), - e.Message, - InfoBarSeverity.Error, - true - ); + if (Verbose || !WasCheckingForUpdates) + ShowMessage_ThreadSafe( + CoreTools.Translate("An error occurred when checking for updates: "), + e.Message, + InfoBarSeverity.Error, + true + ); return false; } } @@ -181,7 +238,9 @@ private static async Task GetUpdateCandidate(UpdaterOverrides u } catch (Exception ex) { - Logger.Warn("Productinfo updater source failed. Falling back to legacy GitHub updater source."); + Logger.Warn( + "Productinfo updater source failed. Falling back to legacy GitHub updater source." + ); Logger.Warn(ex); return await CheckForUpdatesFromLegacyGitHub(updaterOverrides); } @@ -190,13 +249,19 @@ private static async Task GetUpdateCandidate(UpdaterOverrides u /// /// Default update source using Devolutions productinfo.json /// - private static async Task CheckForUpdatesFromProductInfo(UpdaterOverrides updaterOverrides) + private static async Task CheckForUpdatesFromProductInfo( + UpdaterOverrides updaterOverrides + ) { - Logger.Debug($"Begin check for updates on productinfo source {updaterOverrides.ProductInfoUrl}"); + Logger.Debug( + $"Begin check for updates on productinfo source {updaterOverrides.ProductInfoUrl}" + ); if (!IsSourceUrlAllowed(updaterOverrides.ProductInfoUrl, updaterOverrides.AllowUnsafeUrls)) { - throw new InvalidOperationException($"Productinfo URL is not allowed: {updaterOverrides.ProductInfoUrl}"); + throw new InvalidOperationException( + $"Productinfo URL is not allowed: {updaterOverrides.ProductInfoUrl}" + ); } string productInfo; @@ -207,54 +272,83 @@ private static async Task CheckForUpdatesFromProductInfo(Update productInfo = await client.GetStringAsync(updaterOverrides.ProductInfoUrl); } - Dictionary? productInfoRoot = JsonSerializer.Deserialize( - productInfo, - typeof(Dictionary), - ProductInfoJsonContext) as Dictionary; + Dictionary? productInfoRoot = + JsonSerializer.Deserialize( + productInfo, + typeof(Dictionary), + ProductInfoJsonContext + ) as Dictionary; if (productInfoRoot is null || productInfoRoot.Count == 0) { throw new FormatException("productinfo.json content is empty or invalid"); } - if (!productInfoRoot.TryGetValue(updaterOverrides.ProductInfoProductKey, out ProductInfoProduct? product)) + if ( + !productInfoRoot.TryGetValue( + updaterOverrides.ProductInfoProductKey, + out ProductInfoProduct? product + ) + ) { - throw new KeyNotFoundException($"Product '{updaterOverrides.ProductInfoProductKey}' was not found in productinfo.json"); + throw new KeyNotFoundException( + $"Product '{updaterOverrides.ProductInfoProductKey}' was not found in productinfo.json" + ); } - ProductInfoChannel? channel = Settings.Get(Settings.K.EnableUniGetUIBeta) ? product.Beta : product.Current; + ProductInfoChannel? channel = Settings.Get(Settings.K.EnableUniGetUIBeta) + ? product.Beta + : product.Current; if (channel is null) { - string missingChannel = Settings.Get(Settings.K.EnableUniGetUIBeta) ? "Beta" : "Current"; - throw new KeyNotFoundException($"Channel '{missingChannel}' was not found for product '{updaterOverrides.ProductInfoProductKey}'"); + string missingChannel = Settings.Get(Settings.K.EnableUniGetUIBeta) + ? "Beta" + : "Current"; + throw new KeyNotFoundException( + $"Channel '{missingChannel}' was not found for product '{updaterOverrides.ProductInfoProductKey}'" + ); } ProductInfoFile installerFile = SelectInstallerFile(channel.Files); if (!IsSourceUrlAllowed(installerFile.Url, updaterOverrides.AllowUnsafeUrls)) { - throw new InvalidOperationException($"Installer URL is not allowed: {installerFile.Url}"); + throw new InvalidOperationException( + $"Installer URL is not allowed: {installerFile.Url}" + ); } - Version currentVersion = ParseVersionOrFallback(CoreData.VersionName, new Version(0, 0, 0, CoreData.BuildNumber)); + Version currentVersion = ParseVersionOrFallback( + CoreData.VersionName, + new Version(0, 0, 0, CoreData.BuildNumber) + ); Version availableVersion = ParseVersionOrFallback(channel.Version, new Version(0, 0, 0, 0)); bool isUpgradable = availableVersion > currentVersion; - Logger.Debug($"Productinfo check result: current={currentVersion}, available={availableVersion}, upgradable={isUpgradable}"); + Logger.Debug( + $"Productinfo check result: current={currentVersion}, available={availableVersion}, upgradable={isUpgradable}" + ); return new UpdateCandidate( isUpgradable, channel.Version, installerFile.Hash, installerFile.Url, - "ProductInfo"); + "ProductInfo" + ); } /// /// Legacy updater source. Kept for compatibility and manual fallback testing. /// - private static async Task CheckForUpdatesFromLegacyGitHub(UpdaterOverrides updaterOverrides) + private static async Task CheckForUpdatesFromLegacyGitHub( + UpdaterOverrides updaterOverrides + ) { - string endpoint = Settings.Get(Settings.K.EnableUniGetUIBeta) ? BETA_ENDPOINT : STABLE_ENDPOINT; - string installerDownloadUrl = Settings.Get(Settings.K.EnableUniGetUIBeta) ? BETA_INSTALLER_URL : STABLE_INSTALLER_URL; + string endpoint = Settings.Get(Settings.K.EnableUniGetUIBeta) + ? BETA_ENDPOINT + : STABLE_ENDPOINT; + string installerDownloadUrl = Settings.Get(Settings.K.EnableUniGetUIBeta) + ? BETA_INSTALLER_URL + : STABLE_INSTALLER_URL; Logger.Warn("Using legacy GitHub updater source due to registry override."); Logger.Debug($"Begin check for updates on endpoint {endpoint}"); @@ -269,26 +363,37 @@ private static async Task CheckForUpdatesFromLegacyGitHub(Updat if (updateResponse.Length >= 3) { - int latestVersion = int.Parse(updateResponse[0].Replace("\n", "").Replace("\r", "").Trim()); + int latestVersion = int.Parse( + updateResponse[0].Replace("\n", "").Replace("\r", "").Trim() + ); string installerHash = updateResponse[1].Replace("\n", "").Replace("\r", "").Trim(); string versionName = updateResponse[2].Replace("\n", "").Replace("\r", "").Trim(); - Logger.Debug($"Got response from endpoint: ({latestVersion}, {versionName}, {installerHash})"); + Logger.Debug( + $"Got response from endpoint: ({latestVersion}, {versionName}, {installerHash})" + ); return new UpdateCandidate( latestVersion > CoreData.BuildNumber, versionName, installerHash, installerDownloadUrl.Replace("$TAG", versionName), - "LegacyGitHub"); + "LegacyGitHub" + ); } Logger.Warn($"Received update string is {updateResponse[0]}"); - throw new FormatException("The updates file does not follow the FloatVersion////Sha256Hash////VersionName format"); + throw new FormatException( + "The updates file does not follow the FloatVersion////Sha256Hash////VersionName format" + ); } /// /// Checks whether the downloaded updater matches the hash. /// - private static async Task CheckInstallerHash(string installerLocation, string expectedHash, UpdaterOverrides updaterOverrides) + private static async Task CheckInstallerHash( + string installerLocation, + string expectedHash, + UpdaterOverrides updaterOverrides + ) { if (updaterOverrides.SkipHashValidation) { @@ -299,7 +404,9 @@ private static async Task CheckInstallerHash(string installerLocation, str Logger.Debug($"Checking updater hash on location {installerLocation}"); using (FileStream stream = File.OpenRead(installerLocation)) { - string hash = Convert.ToHexString(await SHA256.Create().ComputeHashAsync(stream)).ToLower(); + string hash = Convert + .ToHexString(await SHA256.Create().ComputeHashAsync(stream)) + .ToLower(); if (hash == expectedHash.ToLower()) { Logger.Debug($"The hashes match ({hash})"); @@ -310,27 +417,41 @@ private static async Task CheckInstallerHash(string installerLocation, str } } - private static bool CheckInstallerSignerThumbprint(string installerLocation, UpdaterOverrides updaterOverrides) + private static bool CheckInstallerSignerThumbprint( + string installerLocation, + UpdaterOverrides updaterOverrides + ) { if (updaterOverrides.SkipSignerThumbprintCheck) { - Logger.Warn("Registry override enabled: skipping updater signer thumbprint validation."); + Logger.Warn( + "Registry override enabled: skipping updater signer thumbprint validation." + ); return true; } try { - X509Certificate signerCertificate = X509Certificate.CreateFromSignedFile(installerLocation); + X509Certificate signerCertificate = X509Certificate.CreateFromSignedFile( + installerLocation + ); using X509Certificate2 cert = new(signerCertificate); string signerThumbprint = NormalizeThumbprint(cert.Thumbprint ?? string.Empty); if (string.IsNullOrWhiteSpace(signerThumbprint)) { - Logger.Warn($"Could not read signer thumbprint for installer '{installerLocation}'"); + Logger.Warn( + $"Could not read signer thumbprint for installer '{installerLocation}'" + ); return false; } - if (DEVOLUTIONS_CERT_THUMBPRINTS.Contains(signerThumbprint, StringComparer.OrdinalIgnoreCase)) + if ( + DEVOLUTIONS_CERT_THUMBPRINTS.Contains( + signerThumbprint, + StringComparer.OrdinalIgnoreCase + ) + ) { Logger.Debug($"Installer signer thumbprint is trusted: {signerThumbprint}"); return true; @@ -350,7 +471,11 @@ private static bool CheckInstallerSignerThumbprint(string installerLocation, Upd /// /// Downloads the given installer to the given location /// - private static async Task DownloadInstaller(string downloadUrl, string installerLocation, UpdaterOverrides updaterOverrides) + private static async Task DownloadInstaller( + string downloadUrl, + string installerLocation, + UpdaterOverrides updaterOverrides + ) { if (!IsSourceUrlAllowed(downloadUrl, updaterOverrides.AllowUnsafeUrls)) { @@ -373,7 +498,12 @@ private static async Task DownloadInstaller(string downloadUrl, string installer /// /// Waits for the window to be closed if it is open and launches the updater /// - private static async Task PrepairToLaunchInstaller(string installerLocation, string NewVersion, bool AutoLaunch, bool ManualCheck) + private static async Task PrepairToLaunchInstaller( + string installerLocation, + string NewVersion, + bool AutoLaunch, + bool ManualCheck + ) { Logger.Debug("Starting the process to launch the installer."); UpdateReadyToBeInstalled = true; @@ -399,22 +529,32 @@ private static async Task PrepairToLaunchInstaller(string installerLocatio CoreTools.Translate("The update process will start after closing UniGetUI"), InfoBarSeverity.Success, true, - UpdateNowButton); + UpdateNowButton + ); // Show a toast notification AppNotificationBuilder builder = new AppNotificationBuilder() .SetScenario(AppNotificationScenario.Default) .SetTag(CoreData.UniGetUICanBeUpdated.ToString()) - .AddText(CoreTools.Translate("{0} can be updated to version {1}", "UniGetUI", NewVersion)) - .SetAttributionText(CoreTools.Translate("You have currently version {0} installed", CoreData.VersionName)) + .AddText( + CoreTools.Translate("{0} can be updated to version {1}", "UniGetUI", NewVersion) + ) + .SetAttributionText( + CoreTools.Translate( + "You have currently version {0} installed", + CoreData.VersionName + ) + ) .AddArgument("action", NotificationArguments.Show) - .AddButton(new AppNotificationButton(CoreTools.Translate("Update now")) - .AddArgument("action", NotificationArguments.ReleaseSelfUpdateLock) + .AddButton( + new AppNotificationButton(CoreTools.Translate("Update now")).AddArgument( + "action", + NotificationArguments.ReleaseSelfUpdateLock + ) ); AppNotification notification = builder.BuildNotification(); notification.ExpiresOnReboot = true; AppNotificationManager.Default.Show(notification); - }); if (AutoLaunch && !Window.Visible) @@ -423,11 +563,14 @@ private static async Task PrepairToLaunchInstaller(string installerLocatio } else { - Logger.Debug("Waiting for mainWindow to be closed or for user to trigger the update from the notification..."); + Logger.Debug( + "Waiting for mainWindow to be closed or for user to trigger the update from the notification..." + ); while ( - !(ReleaseLockForAutoupdate_Window && !ManualCheck) && - !ReleaseLockForAutoupdate_Notification && - !ReleaseLockForAutoupdate_UpdateBanner) + !(ReleaseLockForAutoupdate_Window && !ManualCheck) + && !ReleaseLockForAutoupdate_Notification + && !ReleaseLockForAutoupdate_UpdateBanner + ) { await Task.Delay(100); } @@ -455,10 +598,11 @@ private static async Task LaunchInstallerAndQuit(string installerLocation) StartInfo = new() { FileName = installerLocation, - Arguments = "/SILENT /SUPPRESSMSGBOXES /NORESTART /SP- /NoVCRedist /NoEdgeWebView /NoWinGet /NoChocolatey", + Arguments = + "/SILENT /SUPPRESSMSGBOXES /NORESTART /SP- /NoVCRedist /NoEdgeWebView /NoWinGet /NoChocolatey", UseShellExecute = true, CreateNoWindow = true, - } + }, }; p.Start(); ShowMessage_ThreadSafe( @@ -476,14 +620,27 @@ private static async Task LaunchInstallerAndQuit(string installerLocation) ); } - private static void ShowMessage_ThreadSafe(string Title, string Message, InfoBarSeverity MessageSeverity, bool BannerClosable, Button? ActionButton = null) + private static void ShowMessage_ThreadSafe( + string Title, + string Message, + InfoBarSeverity MessageSeverity, + bool BannerClosable, + Button? ActionButton = null + ) { try { if (Microsoft.UI.Dispatching.DispatcherQueue.GetForCurrentThread() is null) { Window.DispatcherQueue.TryEnqueue(() => - ShowMessage_ThreadSafe(Title, Message, MessageSeverity, BannerClosable, ActionButton)); + ShowMessage_ThreadSafe( + Title, + Message, + MessageSeverity, + BannerClosable, + ActionButton + ) + ); return; } @@ -498,7 +655,6 @@ private static void ShowMessage_ThreadSafe(string Title, string Message, InfoBar { Logger.Error(ex); } - } private static HttpClientHandler CreateHttpClientHandler(UpdaterOverrides updaterOverrides) @@ -506,7 +662,9 @@ private static HttpClientHandler CreateHttpClientHandler(UpdaterOverrides update HttpClientHandler handler = CoreTools.GenericHttpClientParameters; if (updaterOverrides.DisableTlsValidation) { - Logger.Warn("Registry override enabled: TLS certificate validation is disabled for updater requests."); + Logger.Warn( + "Registry override enabled: TLS certificate validation is disabled for updater requests." + ); handler.ServerCertificateCustomValidationCallback = static (_, _, _, _) => true; } @@ -522,7 +680,9 @@ private static bool IsSourceUrlAllowed(string url, bool allowUnsafeUrls) if (allowUnsafeUrls) { - Logger.Warn($"Registry override enabled: allowing potentially unsafe updater URL {url}"); + Logger.Warn( + $"Registry override enabled: allowing potentially unsafe updater URL {url}" + ); return true; } @@ -534,7 +694,10 @@ private static bool IsSourceUrlAllowed(string url, bool allowUnsafeUrls) return uri.Host.EndsWith("devolutions.net", StringComparison.OrdinalIgnoreCase) || uri.Host.Equals("github.com", StringComparison.OrdinalIgnoreCase) || uri.Host.Equals("objects.githubusercontent.com", StringComparison.OrdinalIgnoreCase) - || uri.Host.Equals("release-assets.githubusercontent.com", StringComparison.OrdinalIgnoreCase) + || uri.Host.Equals( + "release-assets.githubusercontent.com", + StringComparison.OrdinalIgnoreCase + ) || uri.Host.Equals("marticliment.com", StringComparison.OrdinalIgnoreCase) || uri.Host.EndsWith("marticliment.com", StringComparison.OrdinalIgnoreCase); } @@ -545,28 +708,34 @@ private static ProductInfoFile SelectInstallerFile(List files) { Architecture.Arm64 => "arm64", Architecture.X64 => "x64", - _ => "x64" + _ => "x64", }; ProductInfoFile? match = files.FirstOrDefault(file => file.Type.Equals("exe", StringComparison.OrdinalIgnoreCase) - && file.Arch.Equals(targetArch, StringComparison.OrdinalIgnoreCase)); + && file.Arch.Equals(targetArch, StringComparison.OrdinalIgnoreCase) + ); match ??= files.FirstOrDefault(file => file.Type.Equals("exe", StringComparison.OrdinalIgnoreCase) - && file.Arch.Equals("Any", StringComparison.OrdinalIgnoreCase)); + && file.Arch.Equals("Any", StringComparison.OrdinalIgnoreCase) + ); match ??= files.FirstOrDefault(file => file.Type.Equals("msi", StringComparison.OrdinalIgnoreCase) - && file.Arch.Equals(targetArch, StringComparison.OrdinalIgnoreCase)); + && file.Arch.Equals(targetArch, StringComparison.OrdinalIgnoreCase) + ); match ??= files.FirstOrDefault(file => file.Type.Equals("msi", StringComparison.OrdinalIgnoreCase) - && file.Arch.Equals("Any", StringComparison.OrdinalIgnoreCase)); + && file.Arch.Equals("Any", StringComparison.OrdinalIgnoreCase) + ); if (match is null) { - throw new KeyNotFoundException($"No compatible installer file found in productinfo for architecture '{targetArch}'"); + throw new KeyNotFoundException( + $"No compatible installer file found in productinfo for architecture '{targetArch}'" + ); } return match; @@ -591,10 +760,7 @@ private static Version ParseVersionOrFallback(string rawVersion, Version fallbac private static string NormalizeThumbprint(string thumbprint) { - char[] normalized = thumbprint - .ToLowerInvariant() - .Where(char.IsAsciiHexDigit) - .ToArray(); + char[] normalized = thumbprint.ToLowerInvariant().Where(char.IsAsciiHexDigit).ToArray(); return new string(normalized); } @@ -603,8 +769,10 @@ private static UpdaterOverrides LoadUpdaterOverrides() { using RegistryKey? key = Registry.CurrentUser.OpenSubKey(REGISTRY_PATH); - string productInfoUrl = GetRegistryString(key, REG_PRODUCTINFO_URL) ?? DEFAULT_PRODUCTINFO_URL; - string productInfoProductKey = GetRegistryString(key, REG_PRODUCTINFO_KEY) ?? DEFAULT_PRODUCTINFO_KEY; + string productInfoUrl = + GetRegistryString(key, REG_PRODUCTINFO_URL) ?? DEFAULT_PRODUCTINFO_URL; + string productInfoProductKey = + GetRegistryString(key, REG_PRODUCTINFO_KEY) ?? DEFAULT_PRODUCTINFO_KEY; bool allowUnsafeUrls = GetRegistryBool(key, REG_ALLOW_UNSAFE_URLS); bool skipHashValidation = GetRegistryBool(key, REG_SKIP_HASH_VALIDATION); @@ -624,7 +792,8 @@ private static UpdaterOverrides LoadUpdaterOverrides() skipHashValidation, skipSignerThumbprintCheck, disableTlsValidation, - useLegacyGithub); + useLegacyGithub + ); } private static string? GetRegistryString(RegistryKey? key, string valueName) @@ -674,7 +843,8 @@ private sealed record UpdateCandidate( string VersionName, string InstallerHash, string InstallerDownloadUrl, - string SourceName); + string SourceName + ); private sealed record UpdaterOverrides( string ProductInfoUrl, @@ -683,7 +853,8 @@ private sealed record UpdaterOverrides( bool SkipHashValidation, bool SkipSignerThumbprintCheck, bool DisableTlsValidation, - bool UseLegacyGithub); + bool UseLegacyGithub + ); private sealed class ProductInfoProduct { @@ -707,8 +878,5 @@ private sealed class ProductInfoFile [JsonSourceGenerationOptions(AllowTrailingCommas = true)] [JsonSerializable(typeof(Dictionary))] - private sealed partial class AutoUpdaterJsonContext : JsonSerializerContext - { - } - + private sealed partial class AutoUpdaterJsonContext : JsonSerializerContext { } } diff --git a/src/UniGetUI/CLIHandler.cs b/src/UniGetUI/CLIHandler.cs index f22eaf547c..6a404add25 100644 --- a/src/UniGetUI/CLIHandler.cs +++ b/src/UniGetUI/CLIHandler.cs @@ -37,7 +37,8 @@ private enum HRESULT public static int Help() { - var url = "https://github.com/Devolutions/UniGetUI/blob/main/cli-arguments.md#unigetui-command-line-parameters"; + var url = + "https://github.com/Devolutions/UniGetUI/blob/main/cli-arguments.md#unigetui-command-line-parameters"; CoreTools.Launch(url); return 0; } @@ -50,7 +51,7 @@ public static int ImportSettings() if (filePos < 0) return (int)HRESULT.STATUS_INVALID_PARAMETER; // The base paramater --import-settings was not found - if (filePos +1 >= args.Count) + if (filePos + 1 >= args.Count) return (int)HRESULT.STATUS_INVALID_PARAMETER; // The file parameter does not exist (import settings requires "--import-settings file") var file = args[filePos + 1].Trim('"').Trim('\''); @@ -77,7 +78,7 @@ public static int ExportSettings() if (filePos < 0) return (int)HRESULT.STATUS_INVALID_PARAMETER; // The base paramater --export-settings was not found - if (filePos +1 >= args.Count) + if (filePos + 1 >= args.Count) return (int)HRESULT.STATUS_INVALID_PARAMETER; // The file parameter does not exist (export settings requires "--export-settings file") var file = args[filePos + 1].Trim('"').Trim('\''); @@ -102,7 +103,7 @@ public static int EnableSetting() if (basePos < 0) return (int)HRESULT.STATUS_INVALID_PARAMETER; // The base paramater --export-settings was not found - if (basePos +1 >= args.Count) + if (basePos + 1 >= args.Count) return (int)HRESULT.STATUS_INVALID_PARAMETER; // The file parameter does not exist (export settings requires "--export-settings file") var setting = args[basePos + 1].Trim('"').Trim('\''); @@ -129,7 +130,7 @@ public static int DisableSetting() if (basePos < 0) return (int)HRESULT.STATUS_INVALID_PARAMETER; // The base paramater --export-settings was not found - if (basePos +1 >= args.Count) + if (basePos + 1 >= args.Count) return (int)HRESULT.STATUS_INVALID_PARAMETER; // The file parameter does not exist (export settings requires "--export-settings file") var setting = args[basePos + 1].Trim('"').Trim('\''); @@ -155,7 +156,7 @@ public static int SetSettingsValue() if (basePos < 0) return (int)HRESULT.STATUS_INVALID_PARAMETER; // The base paramater --export-settings was not found - if (basePos +2 >= args.Count) + if (basePos + 2 >= args.Count) return (int)HRESULT.STATUS_INVALID_PARAMETER; // The file parameter does not exist (export settings requires "--export-settings file") var setting = args[basePos + 1].Trim('"').Trim('\''); @@ -183,20 +184,25 @@ public static int WingetUIToUniGetUIMigrator() [ // User desktop icon Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), - // User start menu icon Environment.GetFolderPath(Environment.SpecialFolder.StartMenu), - // Common desktop icon Environment.GetFolderPath(Environment.SpecialFolder.CommonDesktopDirectory), - // User start menu icon Environment.GetFolderPath(Environment.SpecialFolder.CommonStartMenu), ]; foreach (string path in BasePaths) { - foreach (string old_wingetui_icon in new[] { "WingetUI.lnk", "WingetUI .lnk", "UniGetUI (formerly WingetUI) .lnk", "UniGetUI (formerly WingetUI).lnk" }) + foreach ( + string old_wingetui_icon in new[] + { + "WingetUI.lnk", + "WingetUI .lnk", + "UniGetUI (formerly WingetUI) .lnk", + "UniGetUI (formerly WingetUI).lnk", + } + ) { try { @@ -209,7 +215,11 @@ public static int WingetUIToUniGetUIMigrator() if (File.Exists(old_file) && File.Exists(new_file)) { - Logger.Info("Deleting shortcut " + old_file + " since new shortcut already exists"); + Logger.Info( + "Deleting shortcut " + + old_file + + " since new shortcut already exists" + ); File.Delete(old_file); } else if (File.Exists(old_file) && !File.Exists(new_file)) @@ -220,7 +230,9 @@ public static int WingetUIToUniGetUIMigrator() } catch (Exception ex) { - Logger.Warn($"An error occurred while migrating the shortcut {Path.Join(path, old_wingetui_icon)}"); + Logger.Warn( + $"An error occurred while migrating the shortcut {Path.Join(path, old_wingetui_icon)}" + ); Logger.Warn(ex); } } @@ -249,7 +261,7 @@ public static int EnableSecureSetting() if (basePos < 0) return (int)HRESULT.STATUS_INVALID_PARAMETER; // The base paramater was not found - if (basePos +1 >= args.Count) + if (basePos + 1 >= args.Count) return (int)HRESULT.STATUS_INVALID_PARAMETER; // The file parameter does not exist (export settings requires "--export-settings file") var setting = args[basePos + 1].Trim('"').Trim('\''); @@ -259,8 +271,10 @@ public static int EnableSecureSetting() try { bool success = SecureSettings.TrySet(validKey, true).GetAwaiter().GetResult(); - if (!success) return (int)HRESULT.STATUS_FAILED; - else return (int)HRESULT.SUCCESS; + if (!success) + return (int)HRESULT.STATUS_FAILED; + else + return (int)HRESULT.SUCCESS; } catch (Exception ex) { @@ -276,7 +290,7 @@ public static int DisableSecureSetting() if (basePos < 0) return (int)HRESULT.STATUS_INVALID_PARAMETER; // The base paramater was not found - if (basePos +1 >= args.Count) + if (basePos + 1 >= args.Count) return (int)HRESULT.STATUS_INVALID_PARAMETER; // The first positional argument does not exist var setting = args[basePos + 1].Trim('"').Trim('\''); @@ -286,8 +300,10 @@ public static int DisableSecureSetting() try { bool success = SecureSettings.TrySet(validKey, false).GetAwaiter().GetResult(); - if (!success) return (int)HRESULT.STATUS_FAILED; - else return (int)HRESULT.SUCCESS; + if (!success) + return (int)HRESULT.STATUS_FAILED; + else + return (int)HRESULT.SUCCESS; } catch (Exception ex) { @@ -303,7 +319,7 @@ public static int EnableSecureSettingForUser() if (basePos < 0) return (int)HRESULT.STATUS_INVALID_PARAMETER; // The base paramater was not found - if (basePos +2 >= args.Count) + if (basePos + 2 >= args.Count) return (int)HRESULT.STATUS_INVALID_PARAMETER; // The required parameters do not exist var user = args[basePos + 1].Trim('"').Trim('\''); @@ -327,7 +343,7 @@ public static int DisableSecureSettingForUser() if (basePos < 0) return (int)HRESULT.STATUS_INVALID_PARAMETER; // The base paramater was not found - if (basePos +2 >= args.Count) + if (basePos + 2 >= args.Count) return (int)HRESULT.STATUS_INVALID_PARAMETER; // The required parameters do not exist var user = args[basePos + 1].Trim('"').Trim('\''); diff --git a/src/UniGetUI/Controls/CustomNavViewItem.cs b/src/UniGetUI/Controls/CustomNavViewItem.cs index 9b6da38c58..b1b45000cb 100644 --- a/src/UniGetUI/Controls/CustomNavViewItem.cs +++ b/src/UniGetUI/Controls/CustomNavViewItem.cs @@ -6,13 +6,13 @@ using UniGetUI.Interface.Widgets; namespace UniGetUI.Controls; + internal sealed partial class CustomNavViewItem : NavigationViewItem { int _iconSize = 28; public IconType LocalIcon { set => base.Icon = new LocalIcon(value); - } public string GlyphIcon { @@ -27,8 +27,10 @@ public bool IsLoading { set { - if (value) _ = increaseMargins(); - else _ = decreaseMargins(); + if (value) + _ = increaseMargins(); + else + _ = decreaseMargins(); _progressRing.Visibility = value ? Visibility.Visible : Visibility.Collapsed; } } @@ -46,7 +48,6 @@ public string Text _textBlock.Text = text; ToolTipService.SetToolTip(this, text); } - } private readonly TextBlock _textBlock; @@ -76,10 +77,7 @@ public CustomNavViewItem() Visibility = Visibility.Collapsed, }; - _textBlock = new TextBlock - { - VerticalAlignment = VerticalAlignment.Center, - }; + _textBlock = new TextBlock { VerticalAlignment = VerticalAlignment.Center }; grid.Children.Add(_progressRing); grid.Children.Add(_textBlock); @@ -88,7 +86,7 @@ public CustomNavViewItem() public async Task increaseMargins() { - for(int i = (int)base.Icon.Margin.Left; i < 6; i += 2) + for (int i = (int)base.Icon.Margin.Left; i < 6; i += 2) { base.Icon.Margin = new Thickness(i); await Task.Delay(15); diff --git a/src/UniGetUI/Controls/DialogCloseButton.xaml b/src/UniGetUI/Controls/DialogCloseButton.xaml index 63a2c58994..63919052f2 100644 --- a/src/UniGetUI/Controls/DialogCloseButton.xaml +++ b/src/UniGetUI/Controls/DialogCloseButton.xaml @@ -1,37 +1,35 @@ + + HorizontalAlignment="Stretch" + VerticalAlignment="Stretch" + Background="Transparent" + BorderThickness="0" + Click="CloseButton_Click" + CornerRadius="0,0,0,0" + > + + + + + + + diff --git a/src/UniGetUI/Controls/DialogCloseButton.xaml.cs b/src/UniGetUI/Controls/DialogCloseButton.xaml.cs index 68f3ce6ee1..30647aba6a 100644 --- a/src/UniGetUI/Controls/DialogCloseButton.xaml.cs +++ b/src/UniGetUI/Controls/DialogCloseButton.xaml.cs @@ -5,6 +5,7 @@ // and more about our project templates, see: http://aka.ms/winui-project-info. namespace UniGetUI.Interface.Widgets; + public sealed partial class DialogCloseButton : UserControl { public event EventHandler? Click; diff --git a/src/UniGetUI/Controls/LocalIcon.cs b/src/UniGetUI/Controls/LocalIcon.cs index ccd352d0ef..cc0335412e 100644 --- a/src/UniGetUI/Controls/LocalIcon.cs +++ b/src/UniGetUI/Controls/LocalIcon.cs @@ -19,7 +19,8 @@ public LocalIcon() FontFamily = font; } - public LocalIcon(IconType icon) : this() + public LocalIcon(IconType icon) + : this() { Glyph = $"{(char)icon}"; } @@ -71,7 +72,8 @@ public LocalIconSource() FontFamily = font; } - public LocalIconSource(IconType icon) : this() + public LocalIconSource(IconType icon) + : this() { Glyph = $"{(char)icon}"; } diff --git a/src/UniGetUI/Controls/MenuForPackage.cs b/src/UniGetUI/Controls/MenuForPackage.cs index cfb5556ef3..9d8d563c73 100644 --- a/src/UniGetUI/Controls/MenuForPackage.cs +++ b/src/UniGetUI/Controls/MenuForPackage.cs @@ -1,4 +1,3 @@ - using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Media; @@ -9,7 +8,9 @@ namespace UniGetUI.Interface.Widgets { public partial class BetterMenu : MenuFlyout { - private readonly Style menuyStyle = (Style)Application.Current.Resources["BetterContextMenu"]; + private readonly Style menuyStyle = (Style) + Application.Current.Resources["BetterContextMenu"]; + public BetterMenu() { MenuFlyoutPresenterStyle = menuyStyle; @@ -29,8 +30,14 @@ public IconType IconName } } - public string UntranslatedText { set => base.Text = value; } - public new string Text { set => base.Text = CoreTools.Translate(value); } + public string UntranslatedText + { + set => base.Text = value; + } + public new string Text + { + set => base.Text = CoreTools.Translate(value); + } public BetterMenuItem() { @@ -40,7 +47,8 @@ public BetterMenuItem() public partial class BetterToggleMenuItem : ToggleMenuFlyoutItem { - private readonly Style menuStyle = (Style)Application.Current.Resources["BetterToggleMenuItem"]; + private readonly Style menuStyle = (Style) + Application.Current.Resources["BetterToggleMenuItem"]; public IconType IconName { @@ -66,10 +74,27 @@ public partial class BetterTabViewItem : TabViewItem { string line1 = ""; string line2 = ""; - public string Line1 { set { line1 = value; LoadText(); } } - public string Line2 { set { line2 = value; LoadText(); } } + public string Line1 + { + set + { + line1 = value; + LoadText(); + } + } + public string Line2 + { + set + { + line2 = value; + LoadText(); + } + } - public IconType IconName { set => IconSource = new LocalIconSource(value); } + public IconType IconName + { + set => IconSource = new LocalIconSource(value); + } public BetterTabViewItem() { @@ -82,20 +107,23 @@ public void LoadText() string text = ""; // The invisible U+200E character here is used to prevent the text from being // trimmed in the TabViewItem header, adding a little bit of padding at the end. - if (line1 != "") text += CoreTools.Translate(line1) + " ‎‎ "; - if (line2 != "") text += (text.Length> 0?"\n":"") + CoreTools.Translate(line2) + " ‎ "; + if (line1 != "") + text += CoreTools.Translate(line1) + " ‎‎ "; + if (line2 != "") + text += (text.Length > 0 ? "\n" : "") + CoreTools.Translate(line2) + " ‎ "; Header = text; } } - public partial class BetterFlyout: Flyout + public partial class BetterFlyout : Flyout { - public BetterFlyout() : base() + public BetterFlyout() + : base() { ShouldConstrainToRootBounds = false; SystemBackdrop = new DesktopAcrylicBackdrop(); - FlyoutPresenterStyle = (Style)Application.Current.Resources["BetterFlyoutPresenterStyle"]; + FlyoutPresenterStyle = (Style) + Application.Current.Resources["BetterFlyoutPresenterStyle"]; } } - } diff --git a/src/UniGetUI/Controls/ObservablePackageCollection.cs b/src/UniGetUI/Controls/ObservablePackageCollection.cs index fd6cf9c54d..4ec5698d8a 100644 --- a/src/UniGetUI/Controls/ObservablePackageCollection.cs +++ b/src/UniGetUI/Controls/ObservablePackageCollection.cs @@ -17,6 +17,7 @@ public enum Sorter NewVersion, Source, } + public Sorter CurrentSorter { get; private set; } public ObservablePackageCollection() diff --git a/src/UniGetUI/Controls/OperationWidgets/OperationBadge.cs b/src/UniGetUI/Controls/OperationWidgets/OperationBadge.cs index dc59452a17..b1a2e62b80 100644 --- a/src/UniGetUI/Controls/OperationWidgets/OperationBadge.cs +++ b/src/UniGetUI/Controls/OperationWidgets/OperationBadge.cs @@ -1,6 +1,7 @@ using UniGetUI.Interface.Enums; namespace UniGetUI.Controls.OperationWidgets; + public class OperationBadge { public string Tooltip; @@ -9,7 +10,12 @@ public class OperationBadge public bool SecondaryBannerVisible; public IconType Icon; - public OperationBadge(string tooltip, IconType icon, string primaryBanner, string? secondaryBanner = null) + public OperationBadge( + string tooltip, + IconType icon, + string primaryBanner, + string? secondaryBanner = null + ) { Tooltip = tooltip; Icon = icon; diff --git a/src/UniGetUI/Controls/OperationWidgets/OperationControl.cs b/src/UniGetUI/Controls/OperationWidgets/OperationControl.cs index cd5fb35cd4..0e08db769e 100644 --- a/src/UniGetUI/Controls/OperationWidgets/OperationControl.cs +++ b/src/UniGetUI/Controls/OperationWidgets/OperationControl.cs @@ -1,7 +1,10 @@ +using System.Collections.ObjectModel; using System.ComponentModel; +using System.Diagnostics; using System.Runtime.CompilerServices; -using Windows.UI; +using CommunityToolkit.WinUI; using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Media; using Microsoft.Windows.AppNotifications; using Microsoft.Windows.AppNotifications.Builder; @@ -9,23 +12,20 @@ using UniGetUI.Core.SettingsEngine; using UniGetUI.Core.Tools; using UniGetUI.Interface.Enums; +using UniGetUI.Interface.Telemetry; +using UniGetUI.Interface.Widgets; +using UniGetUI.PackageEngine; using UniGetUI.PackageEngine.Classes.Packages.Classes; using UniGetUI.PackageEngine.Enums; -using UniGetUI.PackageOperations; -using UniGetUI.Pages.DialogPages; -using CommunityToolkit.WinUI; -using Microsoft.UI.Xaml.Controls; -using UniGetUI.Interface.Widgets; using UniGetUI.PackageEngine.Operations; -using System.Collections.ObjectModel; -using System.Diagnostics; -using UniGetUI.Interface.Telemetry; -using UniGetUI.PackageEngine; using UniGetUI.PackageEngine.PackageLoader; +using UniGetUI.PackageOperations; +using UniGetUI.Pages.DialogPages; +using Windows.UI; namespace UniGetUI.Controls.OperationWidgets; -public partial class OperationControl: INotifyPropertyChanged +public partial class OperationControl : INotifyPropertyChanged { public AbstractOperation Operation; public BetterMenu OpMenu; @@ -47,26 +47,41 @@ public OperationControl(AbstractOperation operation) Operation.BadgesChanged += (_, badges) => { Badges.Clear(); - if (badges.AsAdministrator) Badges.Add(new( - CoreTools.Translate("Administrator privileges"), - IconType.UAC, - CoreTools.Translate("This operation is running with administrator privileges."), - "" - )); - - if (badges.Interactive) Badges.Add(new( - CoreTools.Translate("Interactive operation"), - IconType.Interactive, - CoreTools.Translate("This operation is running interactively."), - CoreTools.Translate("You will likely need to interact with the installer.") - )); - - if (badges.SkipHashCheck) Badges.Add(new( - CoreTools.Translate("Integrity checks skipped"), - IconType.Checksum, - CoreTools.Translate("Integrity checks will not be performed during this operation"), - CoreTools.Translate("This is not recommended.") + " " + CoreTools.Translate("Proceed at your own risk.") - )); + if (badges.AsAdministrator) + Badges.Add( + new( + CoreTools.Translate("Administrator privileges"), + IconType.UAC, + CoreTools.Translate( + "This operation is running with administrator privileges." + ), + "" + ) + ); + + if (badges.Interactive) + Badges.Add( + new( + CoreTools.Translate("Interactive operation"), + IconType.Interactive, + CoreTools.Translate("This operation is running interactively."), + CoreTools.Translate("You will likely need to interact with the installer.") + ) + ); + + if (badges.SkipHashCheck) + Badges.Add( + new( + CoreTools.Translate("Integrity checks skipped"), + IconType.Checksum, + CoreTools.Translate( + "Integrity checks will not be performed during this operation" + ), + CoreTools.Translate("This is not recommended.") + + " " + + CoreTools.Translate("Proceed at your own risk.") + ) + ); /*if (badges.Scope is not null) { @@ -88,7 +103,9 @@ public OperationControl(AbstractOperation operation) }; _title = Operation.Metadata.Title; - _liveLine = operation.GetOutput().Any()? operation.GetOutput()[operation.GetOutput().Count - 1].Item1 : CoreTools.Translate("Please wait..."); + _liveLine = operation.GetOutput().Any() + ? operation.GetOutput()[operation.GetOutput().Count - 1].Item1 + : CoreTools.Translate("Please wait..."); _buttonText = ""; OnOperationStatusChanged(this, operation.Status); _ = LoadIcon(); @@ -101,18 +118,24 @@ private void OnOperationStarting(object? sender, EventArgs e) ShowProgressToast(); if (MainApp.Instance.MainWindow.NavigationPage.OperationList.Items.Contains(this)) { - MainApp.Instance.MainWindow.NavigationPage.OperationList.SmoothScrollIntoViewWithItemAsync(this); + MainApp.Instance.MainWindow.NavigationPage.OperationList.SmoothScrollIntoViewWithItemAsync( + this + ); } } private void OnOperationSucceeded(object? sender, EventArgs e) => _ = _onOperationSucceeded(); + private async Task _onOperationSucceeded() { // Success notification ShowSuccessToast(); // Clean succesful operation from list - if (!Settings.Get(Settings.K.MaintainSuccessfulInstalls) && Operation is not DownloadOperation) + if ( + !Settings.Get(Settings.K.MaintainSuccessfulInstalls) + && Operation is not DownloadOperation + ) { await TimeoutAndClose(); } @@ -124,10 +147,13 @@ private void OnOperationFailed(object? sender, EventArgs e) } private void OnOperationFinished(object? sender, EventArgs e) => _ = _onOperationFinished(); + private async Task _onOperationFinished() { // Remove progress notification (if any) - _ = AppNotificationManager.Default.RemoveByTagAsync(Operation.Metadata.Identifier + "progress"); + _ = AppNotificationManager.Default.RemoveByTagAsync( + Operation.Metadata.Identifier + "progress" + ); if (Operation.Status is OperationStatus.Failed) { @@ -153,7 +179,8 @@ private async Task _onOperationFinished() } string[] oldHistory = Settings.GetValue(Settings.K.OperationHistory).Split("\n"); - if (oldHistory.Length > 300) oldHistory = oldHistory.Take(300).ToArray(); + if (oldHistory.Length > 300) + oldHistory = oldHistory.Take(300).ToArray(); List newHistory = [.. rawOutput, .. oldHistory]; Settings.SetValue(Settings.K.OperationHistory, string.Join('\n', newHistory)); @@ -172,9 +199,11 @@ private async Task _onOperationFinished() } // Handle newly created shortcuts - if(Settings.Get(Settings.K.AskToDeleteNewDesktopShortcuts) + if ( + Settings.Get(Settings.K.AskToDeleteNewDesktopShortcuts) && !MainApp.Operations.AreThereRunningOperations() - && DesktopShortcutsDatabase.GetUnknownShortcuts().Any()) + && DesktopShortcutsDatabase.GetUnknownShortcuts().Any() + ) { _ = DialogHelper.HandleNewDesktopShortcuts(); } @@ -192,35 +221,45 @@ private void OnOperationStatusChanged(object? sender, OperationStatus newStatus) case OperationStatus.InQueue: ProgressIndeterminate = false; ProgressValue = 0; - ProgressForeground = (SolidColorBrush)Application.Current.Resources["SystemFillColorNeutralBrush"]; - Background = (SolidColorBrush)Application.Current.Resources["SystemFillColorNeutralBackgroundBrush"]; + ProgressForeground = (SolidColorBrush) + Application.Current.Resources["SystemFillColorNeutralBrush"]; + Background = (SolidColorBrush) + Application.Current.Resources["SystemFillColorNeutralBackgroundBrush"]; ButtonText = CoreTools.Translate("Cancel"); break; case OperationStatus.Running: ProgressIndeterminate = true; ButtonText = CoreTools.Translate("Cancel"); - ProgressForeground = (SolidColorBrush)Application.Current.Resources["SystemFillColorAttentionBrush"]; - Background = (SolidColorBrush)Application.Current.Resources["SystemFillColorAttentionBackgroundBrush"]; + ProgressForeground = (SolidColorBrush) + Application.Current.Resources["SystemFillColorAttentionBrush"]; + Background = (SolidColorBrush) + Application.Current.Resources["SystemFillColorAttentionBackgroundBrush"]; break; case OperationStatus.Succeeded: ProgressIndeterminate = false; ProgressValue = 100; - ProgressForeground = (SolidColorBrush)Application.Current.Resources["SystemFillColorSuccessBrush"]; - Background = (SolidColorBrush)Application.Current.Resources["SystemFillColorNeutralBackgroundBrush"]; + ProgressForeground = (SolidColorBrush) + Application.Current.Resources["SystemFillColorSuccessBrush"]; + Background = (SolidColorBrush) + Application.Current.Resources["SystemFillColorNeutralBackgroundBrush"]; ButtonText = CoreTools.Translate("Close"); break; case OperationStatus.Failed: ProgressIndeterminate = false; ProgressValue = 100; - ProgressForeground = (SolidColorBrush)Application.Current.Resources["SystemFillColorCriticalBrush"]; - Background = (SolidColorBrush)Application.Current.Resources["SystemFillColorCriticalBackgroundBrush"]; + ProgressForeground = (SolidColorBrush) + Application.Current.Resources["SystemFillColorCriticalBrush"]; + Background = (SolidColorBrush) + Application.Current.Resources["SystemFillColorCriticalBackgroundBrush"]; ButtonText = CoreTools.Translate("Close"); break; case OperationStatus.Canceled: ProgressIndeterminate = false; ProgressValue = 100; - ProgressForeground = (SolidColorBrush)Application.Current.Resources["SystemFillColorCautionBrush"]; - Background = (SolidColorBrush)Application.Current.Resources["SystemFillColorNeutralBackgroundBrush"]; + ProgressForeground = (SolidColorBrush) + Application.Current.Resources["SystemFillColorCautionBrush"]; + Background = (SolidColorBrush) + Application.Current.Resources["SystemFillColorNeutralBackgroundBrush"]; ButtonText = CoreTools.Translate("Close"); break; default: @@ -228,8 +267,7 @@ private void OnOperationStatusChanged(object? sender, OperationStatus newStatus) } } - public void LiveLineClick() - => _ = LiveLineClickAsync(); + public void LiveLineClick() => _ = LiveLineClickAsync(); private async Task LiveLineClickAsync() { @@ -257,7 +295,8 @@ public void ButtonClick() public void LoadMenu() { - if (MenuStateOnLoaded == Operation.Status) return; + if (MenuStateOnLoaded == Operation.Status) + return; MenuStateOnLoaded = Operation.Status; // Reset menu @@ -267,7 +306,7 @@ public void LoadMenu() var normalOptions = GetOperationOptions(); if (normalOptions.Count != 0) { - foreach(var item in normalOptions) + foreach (var item in normalOptions) { OpMenu.Items.Add(item); } @@ -277,15 +316,27 @@ public void LoadMenu() if (Operation.Status is OperationStatus.InQueue) { - var skipQueue = new BetterMenuItem { Text = CoreTools.Translate("Run now"), Icon = new FontIcon {Glyph = "\uE768"} }; + var skipQueue = new BetterMenuItem + { + Text = CoreTools.Translate("Run now"), + Icon = new FontIcon { Glyph = "\uE768" }, + }; skipQueue.Click += (_, _) => Operation.SkipQueue(); OpMenu.Items.Add(skipQueue); - var putNext = new BetterMenuItem { Text = CoreTools.Translate("Run next"), Icon = new FontIcon {Glyph = "\uEB9D"} }; + var putNext = new BetterMenuItem + { + Text = CoreTools.Translate("Run next"), + Icon = new FontIcon { Glyph = "\uEB9D" }, + }; putNext.Click += (_, _) => Operation.RunNext(); OpMenu.Items.Add(putNext); - var putLast = new BetterMenuItem { Text = CoreTools.Translate("Run last"), Icon = new FontIcon {Glyph = "\uEB9E"} }; + var putLast = new BetterMenuItem + { + Text = CoreTools.Translate("Run last"), + Icon = new FontIcon { Glyph = "\uEB9E" }, + }; putLast.Click += (_, _) => Operation.BackOfTheQueue(); OpMenu.Items.Add(putLast); @@ -295,13 +346,21 @@ public void LoadMenu() // Create Cancel/Retry buttons if (Operation.Status is OperationStatus.InQueue or OperationStatus.Running) { - var cancel = new BetterMenuItem { Text = CoreTools.Translate("Cancel"), IconName = IconType.Cross, }; + var cancel = new BetterMenuItem + { + Text = CoreTools.Translate("Cancel"), + IconName = IconType.Cross, + }; cancel.Click += (_, _) => Operation.Cancel(); OpMenu.Items.Add(cancel); } else { - var retry = new BetterMenuItem { Text = CoreTools.Translate("Retry"), IconName = IconType.Reload, }; + var retry = new BetterMenuItem + { + Text = CoreTools.Translate("Retry"), + IconName = IconType.Reload, + }; retry.Click += (_, _) => Operation.Retry(AbstractOperation.RetryMode.Retry); OpMenu.Items.Add(retry); @@ -311,7 +370,7 @@ public void LoadMenu() { OpMenu.Items.Add(new MenuFlyoutSeparator()); - foreach(var item in extraRetry) + foreach (var item in extraRetry) { OpMenu.Items.Add(item); } @@ -335,70 +394,105 @@ public void Close() MainApp.Instance.MainWindow.UpdateSystemTrayStatus(); MainApp.Operations._operationList.Remove(this); - while(AbstractOperation.OperationQueue.Remove(Operation)); + while (AbstractOperation.OperationQueue.Remove(Operation)) + ; } private string _buttonText; public string ButtonText { get => _buttonText; - set { _buttonText = value; OnPropertyChanged(); } + set + { + _buttonText = value; + OnPropertyChanged(); + } } private string _liveLine; public string LiveLine { get => _liveLine; - set { _liveLine = value; OnPropertyChanged(); } + set + { + _liveLine = value; + OnPropertyChanged(); + } } private string _title; public string Title { get => _title; - set { _title = value; OnPropertyChanged(); } + set + { + _title = value; + OnPropertyChanged(); + } } private bool _progressIndeterminate; public bool ProgressIndeterminate { get => _progressIndeterminate; - set { _progressIndeterminate = value; OnPropertyChanged(); } + set + { + _progressIndeterminate = value; + OnPropertyChanged(); + } } private int _progressValue; public int ProgressValue { get => _progressValue; - set { _progressValue = value; OnPropertyChanged(); } + set + { + _progressValue = value; + OnPropertyChanged(); + } } private Uri _icon = new("ms-appx:///Assets/images/package_color.png"); public Uri Icon { get => _icon; - set { _icon = value; OnPropertyChanged(); } + set + { + _icon = value; + OnPropertyChanged(); + } } private SolidColorBrush _background = new(Color.FromArgb(0, 0, 0, 0)); public SolidColorBrush Background { get => _background; - set { _background = value; OnPropertyChanged(); } + set + { + _background = value; + OnPropertyChanged(); + } } private SolidColorBrush _progressForeground = new(Color.FromArgb(0, 0, 0, 0)); public SolidColorBrush ProgressForeground { get => _progressForeground; - set { _progressForeground = value; OnPropertyChanged(); } + set + { + _progressForeground = value; + OnPropertyChanged(); + } } public event PropertyChangedEventHandler? PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) { - MainApp.Dispatcher.TryEnqueue(() => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName))); + MainApp.Dispatcher.TryEnqueue(() => + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)) + ); } private void ShowProgressToast() @@ -408,15 +502,19 @@ private void ShowProgressToast() try { - _ = AppNotificationManager.Default.RemoveByTagAsync(Operation.Metadata.Identifier + "progress"); + _ = AppNotificationManager.Default.RemoveByTagAsync( + Operation.Metadata.Identifier + "progress" + ); AppNotificationBuilder builder = new AppNotificationBuilder() .SetScenario(AppNotificationScenario.Default) .SetTag(Operation.Metadata.Identifier + "progress") - .AddProgressBar(new AppNotificationProgressBar() - .SetStatus(CoreTools.Translate("Please wait...")) - .SetValueStringOverride("\u2003") - .SetTitle(Operation.Metadata.Status) - .SetValue(1.0)) + .AddProgressBar( + new AppNotificationProgressBar() + .SetStatus(CoreTools.Translate("Please wait...")) + .SetValueStringOverride("\u2003") + .SetTitle(Operation.Metadata.Status) + .SetValue(1.0) + ) .AddArgument("action", NotificationArguments.Show); AppNotification notification = builder.BuildNotification(); notification.ExpiresOnReboot = true; @@ -486,7 +584,8 @@ public List GetRetryOptions(Action callback) if (Operation is SourceOperation sourceOp && !sourceOp.ForceAsAdministrator) { - var adminButton = new BetterMenuItem { + var adminButton = new BetterMenuItem + { Text = CoreTools.Translate("Retry as administrator"), IconName = IconType.UAC, }; @@ -499,9 +598,13 @@ public List GetRetryOptions(Action callback) } else if (Operation is PackageOperation packageOp) { - if (!packageOp.Options.RunAsAdministrator && packageOp.Package.Manager.Capabilities.CanRunAsAdmin) + if ( + !packageOp.Options.RunAsAdministrator + && packageOp.Package.Manager.Capabilities.CanRunAsAdmin + ) { - var adminButton = new BetterMenuItem { + var adminButton = new BetterMenuItem + { Text = CoreTools.Translate("Retry as administrator"), IconName = IconType.UAC, }; @@ -513,10 +616,13 @@ public List GetRetryOptions(Action callback) retryOptionsMenu.Add(adminButton); } - if (!packageOp.Options.InteractiveInstallation && - packageOp.Package.Manager.Capabilities.CanRunInteractively) + if ( + !packageOp.Options.InteractiveInstallation + && packageOp.Package.Manager.Capabilities.CanRunInteractively + ) { - var interactiveButton = new BetterMenuItem { + var interactiveButton = new BetterMenuItem + { Text = CoreTools.Translate("Retry interactively"), IconName = IconType.Interactive, }; @@ -528,13 +634,16 @@ public List GetRetryOptions(Action callback) retryOptionsMenu.Add(interactiveButton); } - if (!packageOp.Options.SkipHashCheck && packageOp.Package.Manager.Capabilities.CanSkipIntegrityChecks) + if ( + !packageOp.Options.SkipHashCheck + && packageOp.Package.Manager.Capabilities.CanSkipIntegrityChecks + ) { - var skiphashButton = - new BetterMenuItem { - Text = CoreTools.Translate("Retry skipping integrity checks"), - IconName = IconType.Checksum, - }; + var skiphashButton = new BetterMenuItem + { + Text = CoreTools.Translate("Retry skipping integrity checks"), + IconName = IconType.Checksum, + }; skiphashButton.Click += (_, _) => { callback(); @@ -543,46 +652,74 @@ public List GetRetryOptions(Action callback) retryOptionsMenu.Add(skiphashButton); } - if (packageOp is UpdatePackageOperation && - packageOp.Status is OperationStatus.Failed or OperationStatus.Canceled) + if ( + packageOp is UpdatePackageOperation + && packageOp.Status is OperationStatus.Failed or OperationStatus.Canceled + ) { retryOptionsMenu.Add(new MenuFlyoutSeparator()); - var reinstall = new BetterMenuItem() { Text = CoreTools.Translate("Reinstall package") }; + var reinstall = new BetterMenuItem() + { + Text = CoreTools.Translate("Reinstall package"), + }; reinstall.IconName = IconType.Download; reinstall.Click += async (_, _) => { callback(); this.Close(); - _ = MainApp.Operations.Install(packageOp.Package, TEL_InstallReferral.ALREADY_INSTALLED, ignoreParallel: true); + _ = MainApp.Operations.Install( + packageOp.Package, + TEL_InstallReferral.ALREADY_INSTALLED, + ignoreParallel: true + ); }; retryOptionsMenu.Add(reinstall); - var uninstallReinstall = new BetterMenuItem() { Text = CoreTools.Translate("Uninstall package, then reinstall it") }; + var uninstallReinstall = new BetterMenuItem() + { + Text = CoreTools.Translate("Uninstall package, then reinstall it"), + }; uninstallReinstall.IconName = IconType.Undelete; uninstallReinstall.Click += async (_, _) => { callback(); this.Close(); - var op = await MainApp.Operations.Uninstall(packageOp.Package, ignoreParallel: true); - _ = MainApp.Operations.Install(packageOp.Package, TEL_InstallReferral.ALREADY_INSTALLED, ignoreParallel: true, req: op); + var op = await MainApp.Operations.Uninstall( + packageOp.Package, + ignoreParallel: true + ); + _ = MainApp.Operations.Install( + packageOp.Package, + TEL_InstallReferral.ALREADY_INSTALLED, + ignoreParallel: true, + req: op + ); }; retryOptionsMenu.Add(uninstallReinstall); retryOptionsMenu.Add(new MenuFlyoutSeparator()); - var skipThisVersion = new BetterMenuItem() { Text = CoreTools.Translate("Skip this version") }; + var skipThisVersion = new BetterMenuItem() + { + Text = CoreTools.Translate("Skip this version"), + }; skipThisVersion.IconName = IconType.Skip; skipThisVersion.Click += async (_, _) => { callback(); - await packageOp.Package.AddToIgnoredUpdatesAsync(packageOp.Package.NewVersionString); + await packageOp.Package.AddToIgnoredUpdatesAsync( + packageOp.Package.NewVersionString + ); UpgradablePackagesLoader.Instance.Remove(packageOp.Package); Close(); }; retryOptionsMenu.Add(skipThisVersion); - var ignoreUpdates = new BetterMenuItem() { Text = CoreTools.Translate("Ignore updates for this package") }; + var ignoreUpdates = new BetterMenuItem() + { + Text = CoreTools.Translate("Ignore updates for this package"), + }; ignoreUpdates.IconName = IconType.Pin; ignoreUpdates.Click += async (_, _) => { @@ -603,14 +740,19 @@ public List GetOperationOptions() var optionsMenu = new List(); if (Operation is PackageOperation packageOp) { - var details = new BetterMenuItem { + var details = new BetterMenuItem + { Text = CoreTools.Translate("Package details"), IconName = IconType.Info_Round, - IsEnabled = !packageOp.Package.Source.IsVirtualManager + IsEnabled = !packageOp.Package.Source.IsVirtualManager, }; details.Click += (_, _) => { - _ = DialogHelper.ShowPackageDetails(packageOp.Package, OperationType.None, TEL_InstallReferral.DIRECT_SEARCH); + _ = DialogHelper.ShowPackageDetails( + packageOp.Package, + OperationType.None, + TEL_InstallReferral.DIRECT_SEARCH + ); }; optionsMenu.Add(details); @@ -618,16 +760,22 @@ public List GetOperationOptions() { Text = CoreTools.Translate("Installation options"), IconName = IconType.Options, - IsEnabled = !packageOp.Package.Source.IsVirtualManager + IsEnabled = !packageOp.Package.Source.IsVirtualManager, }; installationSettings.Click += (_, _) => { - _ = DialogHelper.ShowInstallatOptions_Continue(packageOp.Package, OperationType.None); + _ = DialogHelper.ShowInstallatOptions_Continue( + packageOp.Package, + OperationType.None + ); }; optionsMenu.Add(installationSettings); - string? location = packageOp.Package.Manager.DetailsHelper.GetInstallLocation(packageOp.Package); - var openLocation = new BetterMenuItem { + string? location = packageOp.Package.Manager.DetailsHelper.GetInstallLocation( + packageOp.Package + ); + var openLocation = new BetterMenuItem + { Text = CoreTools.Translate("Open install location"), IconName = IconType.OpenFolder, }; @@ -635,10 +783,10 @@ public List GetOperationOptions() openLocation.IsEnabled = location is not null && Directory.Exists(location); optionsMenu.Add(openLocation); } - else if (Operation is DownloadOperation downloadOp) { - var launchInstaller = new BetterMenuItem { + var launchInstaller = new BetterMenuItem + { Text = CoreTools.Translate("Open"), IconName = IconType.Launch, }; @@ -646,11 +794,13 @@ public List GetOperationOptions() launchInstaller.IsEnabled = downloadOp.Status is OperationStatus.Succeeded; optionsMenu.Add(launchInstaller); - var showFileInExplorer = new BetterMenuItem { + var showFileInExplorer = new BetterMenuItem + { Text = CoreTools.Translate("Show in explorer"), IconName = IconType.OpenFolder, }; - showFileInExplorer.Click += (_, _) => _ = CoreTools.ShowFileOnExplorer(downloadOp.DownloadLocation); + showFileInExplorer.Click += (_, _) => + _ = CoreTools.ShowFileOnExplorer(downloadOp.DownloadLocation); showFileInExplorer.IsEnabled = downloadOp.Status is OperationStatus.Succeeded; optionsMenu.Add(showFileInExplorer); } diff --git a/src/UniGetUI/Controls/PackageItemContainer.cs b/src/UniGetUI/Controls/PackageItemContainer.cs index de8a78ce22..988d9a59b8 100644 --- a/src/UniGetUI/Controls/PackageItemContainer.cs +++ b/src/UniGetUI/Controls/PackageItemContainer.cs @@ -1,4 +1,4 @@ -using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Controls; using UniGetUI.PackageEngine.Interfaces; using UniGetUI.PackageEngine.PackageClasses; diff --git a/src/UniGetUI/Controls/PackageWrapper.cs b/src/UniGetUI/Controls/PackageWrapper.cs index c6fb52787e..aefd9c77e6 100644 --- a/src/UniGetUI/Controls/PackageWrapper.cs +++ b/src/UniGetUI/Controls/PackageWrapper.cs @@ -57,8 +57,14 @@ public Uri? PackageIcon public readonly string ExtendedTooltip = ""; public float ListedOpacity = 1.0f; - public int NewVersionLabelWidth { get => Package.IsUpgradable ? 125 : 0; } - public int NewVersionIconWidth { get => Package.IsUpgradable ? 24 : 0; } + public int NewVersionLabelWidth + { + get => Package.IsUpgradable ? 125 : 0; + } + public int NewVersionIconWidth + { + get => Package.IsUpgradable ? 24 : 0; + } public int Index { get; set; } public event PropertyChangedEventHandler? PropertyChanged; @@ -76,25 +82,29 @@ public PackageWrapper(IPackage package, AbstractPackagesPage page) WhenTagHasChanged(); Package.PropertyChanged += Package_PropertyChanged; UpdatePackageIcon(); - VersionComboString = package.IsUpgradable ? $"{package.VersionString} -> {package.NewVersionString}" : package.VersionString; + VersionComboString = package.IsUpgradable + ? $"{package.VersionString} -> {package.NewVersionString}" + : package.VersionString; - if(package.Name.ToLower() != package.Id.ToLower()) - ExtendedTooltip = $"{package.Name} ({package.Id} from {package.Source.AsString_DisplayName})"; + if (package.Name.ToLower() != package.Id.ToLower()) + ExtendedTooltip = + $"{package.Name} ({package.Id} from {package.Source.AsString_DisplayName})"; else ExtendedTooltip = $"{package.Name} (from {package.Source.AsString_DisplayName})"; } - public void PackageItemContainer_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e) - => _page.PackageItemContainer_DoubleTapped(sender, e); + public void PackageItemContainer_DoubleTapped( + object sender, + DoubleTappedRoutedEventArgs e + ) => _page.PackageItemContainer_DoubleTapped(sender, e); - public void PackageItemContainer_PreviewKeyDown(object sender, KeyRoutedEventArgs e) - => _page.PackageItemContainer_PreviewKeyDown(sender, e); + public void PackageItemContainer_PreviewKeyDown(object sender, KeyRoutedEventArgs e) => + _page.PackageItemContainer_PreviewKeyDown(sender, e); - public void PackageItemContainer_RightTapped(object sender, RightTappedRoutedEventArgs e) - => _page.PackageItemContainer_RightTapped(sender, e); + public void PackageItemContainer_RightTapped(object sender, RightTappedRoutedEventArgs e) => + _page.PackageItemContainer_RightTapped(sender, e); - public void RightClick() - => _ = RightClickAsync(); + public void RightClick() => _ = RightClickAsync(); private async Task RightClickAsync() { @@ -108,11 +118,23 @@ public void Package_PropertyChanged(object? sender, PropertyChangedEventArgs e) if (e.PropertyName == nameof(Package.Tag)) { WhenTagHasChanged(); - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ListedOpacity))); - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(AlternateIconId))); + PropertyChanged?.Invoke( + this, + new PropertyChangedEventArgs(nameof(ListedOpacity)) + ); + PropertyChanged?.Invoke( + this, + new PropertyChangedEventArgs(nameof(AlternateIconId)) + ); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(MainIconId))); - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(AlternateIdIconVisible))); - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ListedNameTooltip))); + PropertyChanged?.Invoke( + this, + new PropertyChangedEventArgs(nameof(AlternateIdIconVisible)) + ); + PropertyChanged?.Invoke( + this, + new PropertyChangedEventArgs(nameof(ListedNameTooltip)) + ); } else if (e.PropertyName == nameof(Package.IsChecked)) { @@ -166,19 +188,32 @@ public void WhenTagHasChanged() }; AlternateIdIconVisible = AlternateIconId != IconType.Empty; - ListedNameTooltip = Package.Tag switch - { - PackageTag.Default => "", - PackageTag.AlreadyInstalled => CoreTools.Translate("This package is already installed") + " - ", - PackageTag.IsUpgradable => CoreTools.Translate("This package can be upgraded to version {0}", - Package.GetUpgradablePackage()?.NewVersionString ?? "-1") + " - ", - PackageTag.Pinned => CoreTools.Translate("Updates for this package are ignored") + " - ", - PackageTag.OnQueue => CoreTools.Translate("This package is on the queue" + " - "), - PackageTag.BeingProcessed => CoreTools.Translate("This package is being processed") + " - ", - PackageTag.Failed => CoreTools.Translate("An error occurred while processing this package") + " - ", - PackageTag.Unavailable => CoreTools.Translate("This package is not available") + " - ", - _ => throw new ArgumentException($"Unknown tag {Package.Tag}"), - } + Package.Name; + ListedNameTooltip = + Package.Tag switch + { + PackageTag.Default => "", + PackageTag.AlreadyInstalled => CoreTools.Translate( + "This package is already installed" + ) + " - ", + PackageTag.IsUpgradable => CoreTools.Translate( + "This package can be upgraded to version {0}", + Package.GetUpgradablePackage()?.NewVersionString ?? "-1" + ) + " - ", + PackageTag.Pinned => CoreTools.Translate("Updates for this package are ignored") + + " - ", + PackageTag.OnQueue => CoreTools.Translate( + "This package is on the queue" + " - " + ), + PackageTag.BeingProcessed => CoreTools.Translate( + "This package is being processed" + ) + " - ", + PackageTag.Failed => CoreTools.Translate( + "An error occurred while processing this package" + ) + " - ", + PackageTag.Unavailable => CoreTools.Translate("This package is not available") + + " - ", + _ => throw new ArgumentException($"Unknown tag {Package.Tag}"), + } + Package.Name; ListedOpacity = Package.Tag switch { @@ -193,7 +228,6 @@ public void WhenTagHasChanged() _ => throw new ArgumentException($"Unknown tag {Package.Tag}"), }; #pragma warning restore CS8524 - } public void UpdatePackageIcon() @@ -215,8 +249,14 @@ public void UpdatePackageIcon() ShowCustomPackageIcon = false; ShowDefaultPackageIcon = true; } - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ShowCustomPackageIcon))); - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ShowDefaultPackageIcon))); + PropertyChanged?.Invoke( + this, + new PropertyChangedEventArgs(nameof(ShowCustomPackageIcon)) + ); + PropertyChanged?.Invoke( + this, + new PropertyChangedEventArgs(nameof(ShowDefaultPackageIcon)) + ); } } } diff --git a/src/UniGetUI/Controls/SettingsWidgets/ButtonCard.cs b/src/UniGetUI/Controls/SettingsWidgets/ButtonCard.cs index e7e54f8c68..c84139a7ec 100644 --- a/src/UniGetUI/Controls/SettingsWidgets/ButtonCard.cs +++ b/src/UniGetUI/Controls/SettingsWidgets/ButtonCard.cs @@ -26,7 +26,10 @@ public string Text public ButtonCard() { _button.MinWidth = 200; - _button.Click += (_, _) => { Click?.Invoke(this, EventArgs.Empty); }; + _button.Click += (_, _) => + { + Click?.Invoke(this, EventArgs.Empty); + }; Content = _button; } } diff --git a/src/UniGetUI/Controls/SettingsWidgets/CheckboxButtonCard.cs b/src/UniGetUI/Controls/SettingsWidgets/CheckboxButtonCard.cs index 09846f75a3..666be3a8a4 100644 --- a/src/UniGetUI/Controls/SettingsWidgets/CheckboxButtonCard.cs +++ b/src/UniGetUI/Controls/SettingsWidgets/CheckboxButtonCard.cs @@ -22,12 +22,13 @@ public sealed partial class CheckboxButtonCard : SettingsCard private Settings.K setting_name = Settings.K.Unset; public Settings.K SettingName { - set { + set + { setting_name = value; IS_INVERTED = Settings.ResolveKey(value).StartsWith("Disable"); _checkbox.IsOn = Settings.Get(setting_name) ^ IS_INVERTED ^ ForceInversion; _textblock.Opacity = _checkbox.IsOn ? 1 : 0.7; - Button.IsEnabled = (_checkbox.IsOn) || _buttonAlwaysOn ; + Button.IsEnabled = (_checkbox.IsOn) || _buttonAlwaysOn; } } @@ -56,31 +57,27 @@ public bool ButtonAlwaysOn set { _buttonAlwaysOn = value; - Button.IsEnabled = (_checkbox.IsOn) || _buttonAlwaysOn ; + Button.IsEnabled = (_checkbox.IsOn) || _buttonAlwaysOn; } } public CheckboxButtonCard() { - Button = new Button() - { - Margin = new Thickness(0, 8, 0, 0) - - }; + Button = new Button() { Margin = new Thickness(0, 8, 0, 0) }; _checkbox = new ToggleSwitch() { - Margin = new Thickness(0, 0, 8, 0), + Margin = new Thickness(0, 0, 8, 0), OnContent = new TextBlock() { Text = CoreTools.Translate("Enabled") }, OffContent = new TextBlock() { Text = CoreTools.Translate("Disabled") }, }; _textblock = new TextBlock() { - Margin = new Thickness(2,0,0,0), + Margin = new Thickness(2, 0, 0, 0), VerticalAlignment = VerticalAlignment.Center, TextWrapping = TextWrapping.Wrap, Style = (Style)Application.Current.Resources["BaseTextBlockStyle"], FontWeight = new FontWeight(450), - Foreground = (SolidColorBrush)Application.Current.Resources["ButtonForeground"] + Foreground = (SolidColorBrush)Application.Current.Resources["ButtonForeground"], }; IS_INVERTED = false; diff --git a/src/UniGetUI/Controls/SettingsWidgets/CheckboxCard.cs b/src/UniGetUI/Controls/SettingsWidgets/CheckboxCard.cs index 2f10e84b7e..e002555a72 100644 --- a/src/UniGetUI/Controls/SettingsWidgets/CheckboxCard.cs +++ b/src/UniGetUI/Controls/SettingsWidgets/CheckboxCard.cs @@ -73,7 +73,7 @@ public CheckboxCard() { VerticalAlignment = VerticalAlignment.Center, Margin = new Thickness(0, 0, 0, 0), - TextWrapping = TextWrapping.Wrap + TextWrapping = TextWrapping.Wrap, }; _warningBlock = new TextBlock() { @@ -90,12 +90,13 @@ public CheckboxCard() { Spacing = 4, Orientation = Orientation.Vertical, - Children = { _textblock, _warningBlock } + Children = { _textblock, _warningBlock }, }; _checkbox.HorizontalAlignment = HorizontalAlignment.Stretch; _checkbox.Toggled += _checkbox_Toggled; } + protected virtual void _checkbox_Toggled(object sender, RoutedEventArgs e) { Settings.Set(setting_name, _checkbox.IsOn ^ IS_INVERTED ^ ForceInversion); @@ -112,17 +113,23 @@ public partial class CheckboxCard_Dict : CheckboxCard private bool _disableStateChangedEvent; private string _keyName = ""; - public string KeyName { set + public string KeyName { - _keyName = value; - if (_dictName != Settings.K.Unset && _keyName.Any()) + set { - _disableStateChangedEvent = true; - _checkbox.IsOn = Settings.GetDictionaryItem(_dictName, _keyName) ^ IS_INVERTED ^ ForceInversion; - _textblock.Opacity = _checkbox.IsOn ? 1 : 0.7; - _disableStateChangedEvent = false; + _keyName = value; + if (_dictName != Settings.K.Unset && _keyName.Any()) + { + _disableStateChangedEvent = true; + _checkbox.IsOn = + Settings.GetDictionaryItem(_dictName, _keyName) + ^ IS_INVERTED + ^ ForceInversion; + _textblock.Opacity = _checkbox.IsOn ? 1 : 0.7; + _disableStateChangedEvent = false; + } } - } } + } public Settings.K DictionaryName { @@ -132,20 +139,27 @@ public Settings.K DictionaryName IS_INVERTED = Settings.ResolveKey(value).StartsWith("Disable"); if (_dictName != Settings.K.Unset && _keyName.Any()) { - _checkbox.IsOn = Settings.GetDictionaryItem(_dictName, _keyName) ^ IS_INVERTED ^ ForceInversion; + _checkbox.IsOn = + Settings.GetDictionaryItem(_dictName, _keyName) + ^ IS_INVERTED + ^ ForceInversion; _textblock.Opacity = _checkbox.IsOn ? 1 : 0.7; } } } - public CheckboxCard_Dict() : base() - { - } + public CheckboxCard_Dict() + : base() { } protected override void _checkbox_Toggled(object sender, RoutedEventArgs e) { - if (_disableStateChangedEvent) return; - Settings.SetDictionaryItem(_dictName, _keyName, _checkbox.IsOn ^ IS_INVERTED ^ ForceInversion); + if (_disableStateChangedEvent) + return; + Settings.SetDictionaryItem( + _dictName, + _keyName, + _checkbox.IsOn ^ IS_INVERTED ^ ForceInversion + ); StateChanged?.Invoke(this, EventArgs.Empty); _textblock.Opacity = _checkbox.IsOn ? 1 : 0.7; } diff --git a/src/UniGetUI/Controls/SettingsWidgets/ComboboxCard.cs b/src/UniGetUI/Controls/SettingsWidgets/ComboboxCard.cs index 3c29cc974d..97a75feb6d 100644 --- a/src/UniGetUI/Controls/SettingsWidgets/ComboboxCard.cs +++ b/src/UniGetUI/Controls/SettingsWidgets/ComboboxCard.cs @@ -21,10 +21,7 @@ public sealed partial class ComboboxCard : SettingsCard private Settings.K settings_name = Settings.K.Unset; public Settings.K SettingName { - set - { - settings_name = value; - } + set { settings_name = value; } } public string Text @@ -37,7 +34,10 @@ public string Text public ComboboxCard() { _combobox.MinWidth = 200; - _combobox.SetBinding(ItemsControl.ItemsSourceProperty, new Binding { Source = _elements }); + _combobox.SetBinding( + ItemsControl.ItemsSourceProperty, + new Binding { Source = _elements } + ); Content = _combobox; } @@ -73,7 +73,10 @@ public void ShowAddedItems() { try { - Settings.SetValue(settings_name, _values_ref[_combobox.SelectedItem?.ToString() ?? ""]); + Settings.SetValue( + settings_name, + _values_ref[_combobox.SelectedItem?.ToString() ?? ""] + ); ValueChanged?.Invoke(this, EventArgs.Empty); } catch (Exception ex) @@ -83,7 +86,9 @@ public void ShowAddedItems() }; } - public string SelectedValue() => _combobox.SelectedValue.ToString() ?? throw new InvalidCastException(); + public string SelectedValue() => + _combobox.SelectedValue.ToString() ?? throw new InvalidCastException(); + public void SelectIndex(int index) => _combobox.SelectedIndex = index; } } diff --git a/src/UniGetUI/Controls/SettingsWidgets/SecureCheckboxCard.cs b/src/UniGetUI/Controls/SettingsWidgets/SecureCheckboxCard.cs index d8f66c42b3..b46597b9f3 100644 --- a/src/UniGetUI/Controls/SettingsWidgets/SecureCheckboxCard.cs +++ b/src/UniGetUI/Controls/SettingsWidgets/SecureCheckboxCard.cs @@ -74,19 +74,24 @@ public SecureCheckboxCard() OffContent = new TextBlock() { Text = CoreTools.Translate("Disabled") }, }; - _loading = new ProgressRing() { IsIndeterminate = true, Visibility = Visibility.Collapsed}; + _loading = new ProgressRing() + { + IsIndeterminate = true, + Visibility = Visibility.Collapsed, + }; _textblock = new TextBlock() { VerticalAlignment = VerticalAlignment.Center, Margin = new Thickness(0, 0, 0, 0), - TextWrapping = TextWrapping.Wrap + TextWrapping = TextWrapping.Wrap, }; _warningBlock = new TextBlock() { VerticalAlignment = VerticalAlignment.Center, Margin = new Thickness(0, 0, 0, 0), TextWrapping = TextWrapping.Wrap, - Foreground = (SolidColorBrush)Application.Current.Resources["SystemControlErrorTextForegroundBrush"], + Foreground = (SolidColorBrush) + Application.Current.Resources["SystemControlErrorTextForegroundBrush"], FontSize = 12, Visibility = Visibility.Collapsed, }; @@ -102,12 +107,13 @@ public SecureCheckboxCard() { Spacing = 4, Orientation = Orientation.Vertical, - Children = { _textblock, _warningBlock } + Children = { _textblock, _warningBlock }, }; _checkbox.HorizontalAlignment = HorizontalAlignment.Stretch; _checkbox.Toggled += (s, e) => _ = _checkbox_Toggled(); } + protected virtual async Task _checkbox_Toggled() { try @@ -117,7 +123,10 @@ protected virtual async Task _checkbox_Toggled() _loading.Visibility = Visibility.Visible; _checkbox.IsEnabled = false; - await SecureSettings.TrySet(setting_name, _checkbox.IsOn ^ IS_INVERTED ^ ForceInversion); + await SecureSettings.TrySet( + setting_name, + _checkbox.IsOn ^ IS_INVERTED ^ ForceInversion + ); StateChanged?.Invoke(this, EventArgs.Empty); _textblock.Opacity = _checkbox.IsOn ? 1 : 0.7; _checkbox.IsOn = SecureSettings.Get(setting_name) ^ IS_INVERTED ^ ForceInversion; diff --git a/src/UniGetUI/Controls/SettingsWidgets/TextboxCard.cs b/src/UniGetUI/Controls/SettingsWidgets/TextboxCard.cs index bb6b4cce5b..6167e7966d 100644 --- a/src/UniGetUI/Controls/SettingsWidgets/TextboxCard.cs +++ b/src/UniGetUI/Controls/SettingsWidgets/TextboxCard.cs @@ -17,7 +17,8 @@ public sealed partial class TextboxCard : SettingsCard private Settings.K setting_name = Settings.K.Unset; public Settings.K SettingName { - set { + set + { setting_name = value; _textbox.Text = Settings.GetValue(setting_name); _textbox.TextChanged += (_, _) => SaveValue(); @@ -48,22 +49,11 @@ public Uri HelpUrl public TextboxCard() { + _helpbutton = new HyperlinkButton { Visibility = Visibility.Collapsed }; - _helpbutton = new HyperlinkButton - { - Visibility = Visibility.Collapsed - }; + _textbox = new TextBox { MinWidth = 200, MaxWidth = 300 }; - _textbox = new TextBox - { - MinWidth = 200, - MaxWidth = 300 - }; - - StackPanel s = new() - { - Orientation = Orientation.Horizontal - }; + StackPanel s = new() { Orientation = Orientation.Horizontal }; s.Children.Add(_helpbutton); s.Children.Add(_textbox); @@ -90,6 +80,5 @@ public void SaveValue() ValueChanged?.Invoke(this, EventArgs.Empty); } - } } diff --git a/src/UniGetUI/Controls/SourceManager.xaml b/src/UniGetUI/Controls/SourceManager.xaml index 72111d3590..d759b3461d 100644 --- a/src/UniGetUI/Controls/SourceManager.xaml +++ b/src/UniGetUI/Controls/SourceManager.xaml @@ -1,137 +1,140 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + x:Class="UniGetUI.Interface.Widgets.SourceManager" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:animatedvisuals="using:Microsoft.UI.Xaml.Controls.AnimatedVisuals" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="using:UniGetUI.Interface.Widgets" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:widgets="using:UniGetUI.Interface.Widgets" + mc:Ignorable="d" +> + + + - - - + - + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/UniGetUI/Controls/SourceManager.xaml.cs b/src/UniGetUI/Controls/SourceManager.xaml.cs index 884e53ee93..aca311e74e 100644 --- a/src/UniGetUI/Controls/SourceManager.xaml.cs +++ b/src/UniGetUI/Controls/SourceManager.xaml.cs @@ -29,13 +29,17 @@ public void Remove(object sender, RoutedEventArgs e) { var op = new OperationControl(new RemoveSourceOperation(Source)); MainApp.Operations._operationList.Add(op); - op.Operation.OperationSucceeded += (_, _) => { Parent.RemoveSourceItem(this); }; + op.Operation.OperationSucceeded += (_, _) => + { + Parent.RemoveSourceItem(this); + }; } } public sealed partial class SourceManager : UserControl { private IPackageManager Manager { get; set; } + // ReSharper disable once FieldCanBeMadeReadOnly.Local private ObservableCollection Sources = []; @@ -48,7 +52,9 @@ public SourceManager(IPackageManager Manager) if (!Manager.Capabilities.SupportsCustomSources) { - throw new InvalidOperationException($"Attempted to create a SourceManager class from Manager {Manager.Name}, which does not support custom sources"); + throw new InvalidOperationException( + $"Attempted to create a SourceManager class from Manager {Manager.Name}, which does not support custom sources" + ); } Header.Text = CoreTools.Translate("Manage {0} sources", Manager.DisplayName); @@ -57,10 +63,7 @@ public SourceManager(IPackageManager Manager) { try { - ContentDialog d = new() - { - Title = CoreTools.Translate("Add source") - }; + ContentDialog d = new() { Title = CoreTools.Translate("Add source") }; ComboBox SourcesCombo = new(); Dictionary NameSourceRef = []; @@ -71,22 +74,51 @@ public SourceManager(IPackageManager Manager) } d.Style = Application.Current.Resources["DefaultContentDialogStyle"] as Style; - StackPanel p = new() - { - Spacing = 8 - }; - p.Children.Add(new TextBlock { Text = CoreTools.Translate("Select the source you want to add:") }); + StackPanel p = new() { Spacing = 8 }; + p.Children.Add( + new TextBlock + { + Text = CoreTools.Translate("Select the source you want to add:"), + } + ); p.Children.Add(SourcesCombo); - TextBox SourceNameTextBox = new() { HorizontalAlignment = HorizontalAlignment.Stretch, Width = 400 }; - TextBox SourceUrlTextBox = new() { HorizontalAlignment = HorizontalAlignment.Stretch }; + TextBox SourceNameTextBox = new() + { + HorizontalAlignment = HorizontalAlignment.Stretch, + Width = 400, + }; + TextBox SourceUrlTextBox = new() + { + HorizontalAlignment = HorizontalAlignment.Stretch, + }; - StackPanel p1 = new() { Spacing = 2, HorizontalAlignment = HorizontalAlignment.Stretch }; - p1.Children.Add(new TextBlock { Text = CoreTools.Translate("Source name:"), VerticalAlignment = VerticalAlignment.Center }); + StackPanel p1 = new() + { + Spacing = 2, + HorizontalAlignment = HorizontalAlignment.Stretch, + }; + p1.Children.Add( + new TextBlock + { + Text = CoreTools.Translate("Source name:"), + VerticalAlignment = VerticalAlignment.Center, + } + ); p1.Children.Add(SourceNameTextBox); - StackPanel p2 = new() { Spacing = 2, HorizontalAlignment = HorizontalAlignment.Stretch }; - p2.Children.Add(new TextBlock { Text = CoreTools.Translate("Source URL:"), VerticalAlignment = VerticalAlignment.Center }); + StackPanel p2 = new() + { + Spacing = 2, + HorizontalAlignment = HorizontalAlignment.Stretch, + }; + p2.Children.Add( + new TextBlock + { + Text = CoreTools.Translate("Source URL:"), + VerticalAlignment = VerticalAlignment.Center, + } + ); p2.Children.Add(SourceUrlTextBox); p.Children.Add(p1); @@ -112,7 +144,9 @@ public SourceManager(IPackageManager Manager) } else { - Logger.Warn("SourcesCombo.SelectedValue.ToString() was null on SourceManager.SourceManager"); + Logger.Warn( + "SourcesCombo.SelectedValue.ToString() was null on SourceManager.SourceManager" + ); } } }; @@ -128,9 +162,17 @@ public SourceManager(IPackageManager Manager) { PackageOperations.AbstractOperation op; if (CoreTools.Translate("Other") != SourcesCombo.SelectedValue.ToString()) - op = new AddSourceOperation(NameSourceRef[SourcesCombo.SelectedValue.ToString() ?? ""]); + op = new AddSourceOperation( + NameSourceRef[SourcesCombo.SelectedValue.ToString() ?? ""] + ); else - op = new AddSourceOperation(new ManagerSource(this.Manager, SourceNameTextBox.Text, new Uri(SourceUrlTextBox.Text))); + op = new AddSourceOperation( + new ManagerSource( + this.Manager, + SourceNameTextBox.Text, + new Uri(SourceUrlTextBox.Text) + ) + ); MainApp.Operations.Add(op); op.OperationSucceeded += (_, _) => _ = LoadSources(); @@ -143,7 +185,9 @@ public SourceManager(IPackageManager Manager) XamlRoot = XamlRoot, Title = CoreTools.Translate("An error occurred"), Style = Application.Current.Resources["DefaultContentDialogStyle"] as Style, - Content = CoreTools.Translate("An error occurred when adding the source: ") + ex.Message + Content = + CoreTools.Translate("An error occurred when adding the source: ") + + ex.Message, }; _ = DialogHelper.ShowDialogAsync(d, HighPriority: true); d.PrimaryButtonText = CoreTools.Translate("Close"); @@ -184,7 +228,6 @@ public void RemoveSourceItem(SourceItem Item) Sources.Remove(Item); } - private void ReloadButton_Click(object sender, RoutedEventArgs e) - => _ = LoadSources(); + private void ReloadButton_Click(object sender, RoutedEventArgs e) => _ = LoadSources(); } } diff --git a/src/UniGetUI/Controls/TranslatedTextBlock.xaml b/src/UniGetUI/Controls/TranslatedTextBlock.xaml index 9bfd544969..aa8d47674f 100644 --- a/src/UniGetUI/Controls/TranslatedTextBlock.xaml +++ b/src/UniGetUI/Controls/TranslatedTextBlock.xaml @@ -1,20 +1,21 @@ - - + x:Class="UniGetUI.Interface.Widgets.TranslatedTextBlock" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + x:Name="_parent" + mc:Ignorable="d" +> + diff --git a/src/UniGetUI/Controls/TranslatedTextBlock.xaml.cs b/src/UniGetUI/Controls/TranslatedTextBlock.xaml.cs index 871e421f3a..6407db09ee 100644 --- a/src/UniGetUI/Controls/TranslatedTextBlock.xaml.cs +++ b/src/UniGetUI/Controls/TranslatedTextBlock.xaml.cs @@ -19,12 +19,20 @@ public string Text public string __suffix = ""; public string Suffix { - set { __suffix = value; ApplyText(null); } + set + { + __suffix = value; + ApplyText(null); + } } public string __prefix = ""; public string Prefix { - set { __prefix = value; ApplyText(null); } + set + { + __prefix = value; + ApplyText(null); + } } public TextWrapping WrappingMode @@ -41,7 +49,8 @@ public void ApplyText(string? text) { try { - if (text is not null) __text = CoreTools.Translate(text); + if (text is not null) + __text = CoreTools.Translate(text); _textBlock?.Text = __prefix + __text + __suffix; } catch (Exception ex) diff --git a/src/UniGetUI/CrashHandler.cs b/src/UniGetUI/CrashHandler.cs index 28a7a84840..2f810d7fa1 100644 --- a/src/UniGetUI/CrashHandler.cs +++ b/src/UniGetUI/CrashHandler.cs @@ -16,45 +16,67 @@ public static class CrashHandler private const int IDYES = 6; private const int IDNO = 7; - [System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Unicode)] + [System.Runtime.InteropServices.DllImport( + "user32.dll", + CharSet = System.Runtime.InteropServices.CharSet.Unicode + )] private static extern int MessageBox(IntPtr hWnd, string lpText, string lpCaption, uint uType); private static void _reportMissingFiles(out bool showDetailedReport) { try { - string installerPath = Path.Join(CoreData.UniGetUIExecutableDirectory, "UniGetUI.Installer.exe"); + string installerPath = Path.Join( + CoreData.UniGetUIExecutableDirectory, + "UniGetUI.Installer.exe" + ); bool canAutoRepair = File.Exists(installerPath); var title = "UniGetUI - Missing Files"; if (canAutoRepair) { - var errorMessage = "UniGetUI has detected that some required files are missing." - + "\n\nThis might be caused by an incomplete installation or corrupted files. Please reinstall UniGetUI." - + "\n\nPress YES to reinstall UniGetUI right now." - + "\nPress NO to close this prompt." - + "\nPress CANCEL to get more details about the crash."; - - var msgboxResult = MessageBox(IntPtr.Zero, errorMessage, title, MB_ICONSTOP | MB_YESNOCANCEL); + var errorMessage = + "UniGetUI has detected that some required files are missing." + + "\n\nThis might be caused by an incomplete installation or corrupted files. Please reinstall UniGetUI." + + "\n\nPress YES to reinstall UniGetUI right now." + + "\nPress NO to close this prompt." + + "\nPress CANCEL to get more details about the crash."; + + var msgboxResult = MessageBox( + IntPtr.Zero, + errorMessage, + title, + MB_ICONSTOP | MB_YESNOCANCEL + ); if (msgboxResult is IDYES) { Process.Start(installerPath, "/silent /NoDeployInstaller"); } - if (msgboxResult is IDYES or IDNO) showDetailedReport = false; - else showDetailedReport = true; // msgboxResult is IDCANCEL + if (msgboxResult is IDYES or IDNO) + showDetailedReport = false; + else + showDetailedReport = true; // msgboxResult is IDCANCEL } else { - var errorMessage = "UniGetUI has detected that some required files are missing." - + "\n\nThis might be caused by an incomplete installation or corrupted files. Please reinstall UniGetUI." - + "\n\nPress OK to close this prompt." - + "\nPress CANCEL to get more details about the crash."; - - var msgboxResult = MessageBox(IntPtr.Zero, errorMessage, title, MB_ICONSTOP | MB_OKCANCEL); - if (msgboxResult is IDOK) showDetailedReport = false; - else showDetailedReport = true; // msgboxResult is IDCANCEL + var errorMessage = + "UniGetUI has detected that some required files are missing." + + "\n\nThis might be caused by an incomplete installation or corrupted files. Please reinstall UniGetUI." + + "\n\nPress OK to close this prompt." + + "\nPress CANCEL to get more details about the crash."; + + var msgboxResult = MessageBox( + IntPtr.Zero, + errorMessage, + title, + MB_ICONSTOP | MB_OKCANCEL + ); + if (msgboxResult is IDOK) + showDetailedReport = false; + else + showDetailedReport = true; // msgboxResult is IDCANCEL } } catch @@ -105,7 +127,7 @@ static string GetExceptionData(Exception e) } string r = b.ToString(); - return r.Any()? r: "No extra data was provided"; + return r.Any() ? r : "No extra data was provided"; } catch (Exception ex) { @@ -122,7 +144,7 @@ static string GetExceptionData(Exception e) catch (Exception ex) { iReport = "Failed to compute integrity report: "; - iReport += ex.GetType() + ": " + ex.Message; + iReport += ex.GetType() + ": " + ex.Message; } string Error_String = $$""" @@ -136,7 +158,7 @@ static string GetExceptionData(Exception e) Integrity report: {{iReport.Replace("\n", "\n ")}} - + Exception type: {{e.GetType()?.Name}} ({{e.GetType()}}) Crash HResult: 0x{{(uint)e.HResult:X}} ({{(uint)e.HResult}}, {{e.HResult}}) Crash Message: {{e.Message}} @@ -155,36 +177,41 @@ static string GetExceptionData(Exception e) { i++; e = e.InnerException; - Error_String += "\n\n\n\n" + $$""" - ——————————————————————————————————————————————————————————— - Inner exception details (depth level: {{i}}) - Crash HResult: 0x{{(uint)e.HResult:X}} ({{(uint)e.HResult}}, {{e.HResult}}) - Crash Message: {{e.Message}} - - Crash Data: - {{GetExceptionData(e).Replace("\n", "\n ")}} - - Crash Traceback: - {{e.StackTrace?.Replace("\n", "\n ")}} - """; + Error_String += + "\n\n\n\n" + + $$""" + ——————————————————————————————————————————————————————————— + Inner exception details (depth level: {{i}}) + Crash HResult: 0x{{(uint)e.HResult:X}} ({{(uint) + e.HResult}}, {{e.HResult}}) + Crash Message: {{e.Message}} + + Crash Data: + {{GetExceptionData(e).Replace("\n", "\n ")}} + + Crash Traceback: + {{e.StackTrace?.Replace("\n", "\n ")}} + """; } if (i == 0) { Error_String += $"\n\n\nNo inner exceptions found"; } - } catch + } + catch { // ignore } - Console.WriteLine(Error_String); + Console.WriteLine(Error_String); - string ErrorUrl = $"https://www.marticliment.com/error-report/" + - $"?appName=UniGetUI" + - $"&appVersion={Uri.EscapeDataString(CoreData.VersionName)}" + - $"&buildNumber={Uri.EscapeDataString(CoreData.BuildNumber.ToString())}" + - $"&errorBody={Uri.EscapeDataString(Error_String)}"; + string ErrorUrl = + $"https://www.marticliment.com/error-report/" + + $"?appName=UniGetUI" + + $"&appVersion={Uri.EscapeDataString(CoreData.VersionName)}" + + $"&buildNumber={Uri.EscapeDataString(CoreData.BuildNumber.ToString())}" + + $"&errorBody={Uri.EscapeDataString(Error_String)}"; Console.WriteLine(ErrorUrl); using Process p = new(); diff --git a/src/UniGetUI/EntryPoint.cs b/src/UniGetUI/EntryPoint.cs index 37f88c4db8..286be63a12 100644 --- a/src/UniGetUI/EntryPoint.cs +++ b/src/UniGetUI/EntryPoint.cs @@ -24,7 +24,10 @@ private static void Main(string[] args) int ret = CLIHandler.WingetUIToUniGetUIMigrator(); Environment.Exit(ret); } - else if (args.Contains(CLIHandler.UNINSTALL_UNIGETUI) || args.Contains(CLIHandler.UNINSTALL_WINGETUI)) + else if ( + args.Contains(CLIHandler.UNINSTALL_UNIGETUI) + || args.Contains(CLIHandler.UNINSTALL_WINGETUI) + ) { int ret = CLIHandler.UninstallUniGetUI(); Environment.Exit(ret); @@ -94,13 +97,13 @@ private static async Task AsyncMain() try { string textart = $""" - __ __ _ ______ __ __ ______ - / / / /___ (_) ____/__ / /_/ / / / _/ - / / / / __ \/ / / __/ _ \/ __/ / / // / - / /_/ / / / / / /_/ / __/ /_/ /_/ // / - \____/_/ /_/_/\____/\___/\__/\____/___/ - Welcome to UniGetUI Version {CoreData.VersionName} - """; + __ __ _ ______ __ __ ______ + / / / /___ (_) ____/__ / /_/ / / / _/ + / / / / __ \/ / / __/ _ \/ __/ / / // / + / /_/ / / / / / /_/ / __/ /_/ /_/ // / + \____/_/ /_/_/\____/\___/\__/\____/___/ + Welcome to UniGetUI Version {CoreData.VersionName} + """; Logger.ImportantInfo(textart); Logger.ImportantInfo(" "); @@ -115,12 +118,16 @@ Welcome to UniGetUI Version {CoreData.VersionName} // If this is the main instance, start the app if (!isRedirect) { - Application.Start((_) => - { - DispatcherQueueSynchronizationContext context = new(DispatcherQueue.GetForCurrentThread()); - SynchronizationContext.SetSynchronizationContext(context); - var app = new MainApp(); - }); + Application.Start( + (_) => + { + DispatcherQueueSynchronizationContext context = new( + DispatcherQueue.GetForCurrentThread() + ); + SynchronizationContext.SetSynchronizationContext(context); + var app = new MainApp(); + } + ); } } catch (Exception e) diff --git a/src/UniGetUI/MainWindow.xaml b/src/UniGetUI/MainWindow.xaml index 8fb68cbf3d..27052a27a6 100644 --- a/src/UniGetUI/MainWindow.xaml +++ b/src/UniGetUI/MainWindow.xaml @@ -1,203 +1,202 @@ + x:Class="UniGetUI.Interface.MainWindow" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:animations="using:CommunityToolkit.WinUI.Animations" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:services="using:UniGetUI.Services" + xmlns:widgets="using:UniGetUI.Interface.Widgets" + Title="UniGetUI" + mc:Ignorable="d" +> + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + BorderThickness="0,1,0,1" + CornerRadius="0" + IsOpen="False" + Severity="Informational" + Visibility="Collapsed" + /> + + + - + + + - - - + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - + + diff --git a/src/UniGetUI/MainWindow.xaml.cs b/src/UniGetUI/MainWindow.xaml.cs index 32366070c3..1fd4303872 100644 --- a/src/UniGetUI/MainWindow.xaml.cs +++ b/src/UniGetUI/MainWindow.xaml.cs @@ -1,38 +1,37 @@ extern alias DrawingCommon; +using System.Diagnostics; using System.Runtime.InteropServices; using System.Text.RegularExpressions; using System.Web; using H.NotifyIcon; +using H.NotifyIcon.EfficiencyMode; using Microsoft.UI; using Microsoft.UI.Windowing; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Input; using Microsoft.Win32; +using Microsoft.Windows.AppNotifications; +using UniGetUI.Core.Classes; using UniGetUI.Core.Data; using UniGetUI.Core.Logging; using UniGetUI.Core.SettingsEngine; using UniGetUI.Core.Tools; +using UniGetUI.Interface.Enums; using UniGetUI.PackageEngine; using UniGetUI.PackageEngine.Classes.Manager.Classes; using UniGetUI.PackageEngine.Interfaces; -using Windows.ApplicationModel.DataTransfer; -using H.NotifyIcon.EfficiencyMode; -using Microsoft.Windows.AppNotifications; -using UniGetUI.Core.Classes; -using UniGetUI.Interface.Enums; using UniGetUI.PackageEngine.PackageClasses; +using UniGetUI.PackageEngine.PackageLoader; using UniGetUI.Pages.DialogPages; -using WindowExtensions = H.NotifyIcon.WindowExtensions; -using System.Diagnostics; +using Windows.ApplicationModel.DataTransfer; using Windows.UI.Text.Core; -using UniGetUI.PackageEngine.PackageLoader; +using WindowExtensions = H.NotifyIcon.WindowExtensions; namespace UniGetUI.Interface { public sealed partial class MainWindow : Window { - public XamlRoot XamlRoot { get => MainContentGrid.XamlRoot; @@ -61,7 +60,9 @@ public MainWindow() ExtendsContentIntoTitleBar = true; AppWindow.TitleBar.PreferredHeightOption = TitleBarHeightOption.Tall; SetTitleBar(MainContentGrid); - AppWindow.SetIcon(Path.Join(CoreData.UniGetUIExecutableDirectory, "Assets", "Images", "icon.ico")); + AppWindow.SetIcon( + Path.Join(CoreData.UniGetUIExecutableDirectory, "Assets", "Images", "icon.ico") + ); LoadTrayMenu(); ApplyTheme(); @@ -78,8 +79,11 @@ public MainWindow() SizeChanged += (_, _) => _ = SaveGeometry(); Activated += (_, e) => { - if (e.WindowActivationState is WindowActivationState.CodeActivated - or WindowActivationState.PointerActivated) + if ( + e.WindowActivationState + is WindowActivationState.CodeActivated + or WindowActivationState.PointerActivated + ) { DWMThreadHelper.ChangeState_DWM(false); DWMThreadHelper.ChangeState_XAML(false); @@ -153,7 +157,11 @@ public static void ApplyProxyVariableToProcess() var proxyUri = Settings.GetProxyUrl(); if (proxyUri is null || !Settings.Get(Settings.K.EnableProxy)) { - Environment.SetEnvironmentVariable("HTTP_PROXY", "", EnvironmentVariableTarget.Process); + Environment.SetEnvironmentVariable( + "HTTP_PROXY", + "", + EnvironmentVariableTarget.Process + ); return; } @@ -171,13 +179,18 @@ public static void ApplyProxyVariableToProcess() } else { - content = $"{proxyUri.Scheme}://{Uri.EscapeDataString(creds.UserName)}" + - $":{Uri.EscapeDataString(creds.Password)}" + - $"@{proxyUri.AbsoluteUri.Replace($"{proxyUri.Scheme}://", "")}"; + content = + $"{proxyUri.Scheme}://{Uri.EscapeDataString(creds.UserName)}" + + $":{Uri.EscapeDataString(creds.Password)}" + + $"@{proxyUri.AbsoluteUri.Replace($"{proxyUri.Scheme}://", "")}"; } } - Environment.SetEnvironmentVariable("HTTP_PROXY", content, EnvironmentVariableTarget.Process); + Environment.SetEnvironmentVariable( + "HTTP_PROXY", + content, + EnvironmentVariableTarget.Process + ); } catch (Exception ex) { @@ -193,13 +206,14 @@ private void AddToSubtitle(string line) _currentSubtitle += line; _currentSubtitlePxLength = _currentSubtitle.Length * 4; Title = "UniGetUI - " + _currentSubtitle; - TitleBar.Subtitle = subtitleCollapsed is true? "": _currentSubtitle; + TitleBar.Subtitle = subtitleCollapsed is true ? "" : _currentSubtitle; } public void HandleNotificationActivation(AppNotificationActivatedEventArgs args) { args.Arguments.TryGetValue("action", out string? action); - if (action is null) action = ""; + if (action is null) + action = ""; if (action == NotificationArguments.UpdateAllPackages) { @@ -221,7 +235,8 @@ public void HandleNotificationActivation(AppNotificationActivatedEventArgs args) else { throw new ArgumentException( - $"args.Argument was not set to a value present in Enums.NotificationArguments (value is {action})"); + $"args.Argument was not set to a value present in Enums.NotificationArguments (value is {action})" + ); } Logger.Debug("Notification activated: " + args.Arguments); @@ -236,7 +251,10 @@ public void HandleClosingEvent(AppWindow sender, AppWindowClosingEventArgs args) { AutoUpdater.ReleaseLockForAutoupdate_Window = true; _ = SaveGeometry(Force: true); - if (!Settings.Get(Settings.K.DisableSystemTray) || AutoUpdater.UpdateReadyToBeInstalled) + if ( + !Settings.Get(Settings.K.DisableSystemTray) + || AutoUpdater.UpdateReadyToBeInstalled + ) { args.Cancel = true; DWMThreadHelper.ChangeState_DWM(true); @@ -293,8 +311,12 @@ private void HandleDeepLink(string link) if (baseUrl.StartsWith("showPackage")) { string Id = Regex.Match(baseUrl, "id=([^&]+)").Value.Split("=")[^1]; - string CombinedManagerName = Regex.Match(baseUrl, "combinedManagerName=([^&]+)").Value.Split("=")[^1]; - string ManagerName = Regex.Match(baseUrl, "managerName=([^&]+)").Value.Split("=")[^1]; + string CombinedManagerName = Regex + .Match(baseUrl, "combinedManagerName=([^&]+)") + .Value.Split("=")[^1]; + string ManagerName = Regex.Match(baseUrl, "managerName=([^&]+)").Value.Split("=")[ + ^1 + ]; string SourceName = Regex.Match(baseUrl, "sourceName=([^&]+)").Value.Split("=")[^1]; if (Id != "" && CombinedManagerName != "" && ManagerName == "" && SourceName == "") @@ -353,11 +375,16 @@ public void ProcessCommandLineParameters() { NavigationPage.ShowHelp(); } - else if (new[] - { - "--daemon", "--updateapps", "--report-all-errors", "--uninstall-unigetui", - "--migrate-wingetui-to-unigetui" - }.Contains(param)) + else if ( + new[] + { + "--daemon", + "--updateapps", + "--report-all-errors", + "--uninstall-unigetui", + "--migrate-wingetui-to-unigetui", + }.Contains(param) + ) { /* Skip */ } @@ -372,8 +399,12 @@ public void ProcessCommandLineParameters() } else if (Path.IsPathFullyQualified(param) && File.Exists(param)) { - if (param.EndsWith(".ubundle") || param.EndsWith(".json") || param.EndsWith(".xml") || - param.EndsWith(".yaml")) + if ( + param.EndsWith(".ubundle") + || param.EndsWith(".json") + || param.EndsWith(".xml") + || param.EndsWith(".yaml") + ) { // Handle potential JSON files Logger.ImportantInfo("Begin attempt to open the package bundle " + param); @@ -450,7 +481,10 @@ private void LoadTrayMenu() { DiscoverPackages, CoreTools.Translate("Discover Packages") }, { AvailableUpdates, CoreTools.Translate("Available Updates") }, { InstalledPackages, CoreTools.Translate("Installed Packages") }, - { AboutUniGetUI, CoreTools.Translate("WingetUI Version {0}", CoreData.VersionName) }, + { + AboutUniGetUI, + CoreTools.Translate("WingetUI Version {0}", CoreData.VersionName) + }, { ShowUniGetUI, CoreTools.Translate("Show WingetUI") }, { QuitUniGetUI, CoreTools.Translate("Quit") }, }; @@ -491,8 +525,14 @@ private void LoadTrayMenu() Activate(); }; AboutUniGetUI.Label = CoreTools.Translate("WingetUI Version {0}", CoreData.VersionName); - ShowUniGetUI.ExecuteRequested += (_, _) => { Activate(); }; - QuitUniGetUI.ExecuteRequested += (_, _) => { MainApp.Instance.DisposeAndQuit(); }; + ShowUniGetUI.ExecuteRequested += (_, _) => + { + Activate(); + }; + QuitUniGetUI.ExecuteRequested += (_, _) => + { + MainApp.Instance.DisposeAndQuit(); + }; TrayMenu.Items.Add(new MenuFlyoutItem { Command = DiscoverPackages }); TrayMenu.Items.Add(new MenuFlyoutItem { Command = AvailableUpdates }); @@ -525,7 +565,8 @@ private void LoadTrayMenu() UpdateSystemTrayStatus(); } - private string LastTrayIcon = ""; + private string LastTrayIcon = ""; + public void UpdateSystemTrayStatus() { try @@ -557,8 +598,13 @@ public void UpdateSystemTrayStatus() } else { - tooltip = CoreTools.Translate("{0} updates are available", - MainApp.Tooltip.AvailableUpdates) + " - " + Title; + tooltip = + CoreTools.Translate( + "{0} updates are available", + MainApp.Tooltip.AvailableUpdates + ) + + " - " + + Title; } } @@ -571,7 +617,8 @@ public void UpdateSystemTrayStatus() TrayIcon.ToolTipText = tooltip; ApplicationTheme theme = ApplicationTheme.Light; - string RegistryKeyPath = @"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize"; + string RegistryKeyPath = + @"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize"; string RegistryValueName = "SystemUsesLightTheme"; RegistryKey? key = Registry.CurrentUser.OpenSubKey(RegistryKeyPath); object? registryValueObject = key?.GetValue(RegistryValueName) ?? null; @@ -590,7 +637,10 @@ public void UpdateSystemTrayStatus() modifier += "_white"; } - string FullIconPath = Path.Join(CoreData.UniGetUIExecutableDirectory, "\\Assets\\Images\\tray" + modifier + ".ico"); + string FullIconPath = Path.Join( + CoreData.UniGetUIExecutableDirectory, + "\\Assets\\Images\\tray" + modifier + ".ico" + ); if (LastTrayIcon != FullIconPath) { LastTrayIcon = FullIconPath; @@ -608,7 +658,6 @@ public void UpdateSystemTrayStatus() { TrayIcon.Visibility = Visibility.Visible; } - } catch (Exception ex) { @@ -639,7 +688,11 @@ public void SwitchToInterface() Activated += (_, e) => { - if(e.WindowActivationState is WindowActivationState.CodeActivated or WindowActivationState.PointerActivated) + if ( + e.WindowActivationState + is WindowActivationState.CodeActivated + or WindowActivationState.PointerActivated + ) MainContentFrame.Content = NavigationPage; }; @@ -701,8 +754,14 @@ public async Task HandleMissingDependencies(IReadOnlyList dep int total = dependencies.Count; foreach (ManagerDependency dependency in dependencies) { - await DialogHelper.ShowMissingDependency(dependency.Name, dependency.InstallFileName, - dependency.InstallArguments, dependency.FancyInstallCommand, current++, total); + await DialogHelper.ShowMissingDependency( + dependency.Name, + dependency.InstallFileName, + dependency.InstallArguments, + dependency.FancyInstallCommand, + current++, + total + ); } } @@ -738,7 +797,9 @@ private async Task SaveGeometry(bool Force = false) } else { - Logger.Warn("MainWindow.AppWindow.Presenter is not OverlappedPresenter presenter!"); + Logger.Warn( + "MainWindow.AppWindow.Presenter is not OverlappedPresenter presenter!" + ); } string geometry = @@ -755,16 +816,21 @@ private async Task SaveGeometry(bool Force = false) private void RestoreGeometry() { - string geometry = Settings.GetValue(Settings.K.WindowGeometry); string[] items = geometry.Split(","); if (items.Length != 5) { - Logger.Warn($"The restored geometry did not have exactly 5 items (found length was {items.Length})"); + Logger.Warn( + $"The restored geometry did not have exactly 5 items (found length was {items.Length})" + ); return; } - int X, Y, Width, Height, State; + int X, + Y, + Width, + Height, + State; try { X = int.Parse(items[0]); @@ -788,7 +854,9 @@ private void RestoreGeometry() } else { - Logger.Warn("MainWindow.AppWindow.Presenter is not OverlappedPresenter presenter!"); + Logger.Warn( + "MainWindow.AppWindow.Presenter is not OverlappedPresenter presenter!" + ); } } else if (IsRectangleFullyVisible(X, Y, Width, Height)) @@ -806,20 +874,24 @@ private static bool IsRectangleFullyVisible(int x, int y, int width, int height) { List monitorInfos = []; - NativeHelpers.MonitorEnumDelegate callback = - (IntPtr hMonitor, IntPtr _, ref NativeHelpers.RECT _, IntPtr _) => + NativeHelpers.MonitorEnumDelegate callback = ( + IntPtr hMonitor, + IntPtr _, + ref NativeHelpers.RECT _, + IntPtr _ + ) => + { + NativeHelpers.MONITORINFO monitorInfo = new() { - NativeHelpers.MONITORINFO monitorInfo = new() - { - cbSize = Marshal.SizeOf(typeof(NativeHelpers.MONITORINFO)) - }; - if (NativeHelpers.GetMonitorInfo(hMonitor, ref monitorInfo)) - { - monitorInfos.Add(monitorInfo); - } - - return true; + cbSize = Marshal.SizeOf(typeof(NativeHelpers.MONITORINFO)), }; + if (NativeHelpers.GetMonitorInfo(hMonitor, ref monitorInfo)) + { + monitorInfos.Add(monitorInfo); + } + + return true; + }; NativeHelpers.EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, callback, IntPtr.Zero); @@ -851,8 +923,7 @@ private static bool IsRectangleFullyVisible(int x, int y, int width, int height) } } - if (x + 10 < minX || x + width - 10 > maxX - || y + 10 < minY || y + height - 10 > maxY) + if (x + 10 < minX || x + width - 10 > maxX || y + 10 < minY || y + height - 10 > maxY) { return false; } @@ -865,14 +936,18 @@ private void TitleBar_PaneToggleRequested(TitleBar sender, object args) if (NavigationPage is null) return; - if(this.AppWindow.Size.Width >= 1600) + if (this.AppWindow.Size.Width >= 1600) { - Settings.Set(Settings.K.CollapseNavMenuOnWideScreen, NavigationPage.NavView.IsPaneOpen); + Settings.Set( + Settings.K.CollapseNavMenuOnWideScreen, + NavigationPage.NavView.IsPaneOpen + ); } NavigationPage.NavView.IsPaneOpen = !NavigationPage.NavView.IsPaneOpen; } private void TitleBar_OnBackRequested(TitleBar sender, object args) => GoBack(); + public void GoBack() => NavigationPage?.NavigateBack(); private bool? subtitleCollapsed; @@ -881,11 +956,15 @@ private void TitleBar_PaneToggleRequested(TitleBar sender, object args) private const int HIDE_TITLE_LIMIT = 870; private const int MIN_SEARCHBOX_W = 50; private const int MAX_SEARCHBOX_W = 400; + private void TitleBar_SizeChanged(object sender, SizeChangedEventArgs e) { - if(TitleBar.ActualWidth <= DYNAMIC_SEARCHBOX_LIMIT) + if (TitleBar.ActualWidth <= DYNAMIC_SEARCHBOX_LIMIT) { - GlobalSearchBox.Width = Math.Max(MIN_SEARCHBOX_W, MAX_SEARCHBOX_W - (DYNAMIC_SEARCHBOX_LIMIT - TitleBar.ActualWidth)); + GlobalSearchBox.Width = Math.Max( + MIN_SEARCHBOX_W, + MAX_SEARCHBOX_W - (DYNAMIC_SEARCHBOX_LIMIT - TitleBar.ActualWidth) + ); } if (titleCollapsed is not true && TitleBar.ActualWidth < HIDE_TITLE_LIMIT) @@ -900,12 +979,18 @@ private void TitleBar_SizeChanged(object sender, SizeChangedEventArgs e) titleCollapsed = false; } - if (subtitleCollapsed is not true && TitleBar.ActualWidth < (HIDE_TITLE_LIMIT + _currentSubtitlePxLength)) + if ( + subtitleCollapsed is not true + && TitleBar.ActualWidth < (HIDE_TITLE_LIMIT + _currentSubtitlePxLength) + ) { TitleBar.Subtitle = ""; subtitleCollapsed = true; } - else if (subtitleCollapsed is not false && TitleBar.ActualWidth > (HIDE_TITLE_LIMIT + _currentSubtitlePxLength)) + else if ( + subtitleCollapsed is not false + && TitleBar.ActualWidth > (HIDE_TITLE_LIMIT + _currentSubtitlePxLength) + ) { TitleBar.Subtitle = _currentSubtitle; GlobalSearchBox.Width = MAX_SEARCHBOX_W; @@ -940,12 +1025,20 @@ public struct MONITORINFO public uint dwFlags; } - public delegate bool MonitorEnumDelegate(IntPtr hMonitor, IntPtr hdcMonitor, ref RECT lprcMonitor, - IntPtr dwData); + public delegate bool MonitorEnumDelegate( + IntPtr hMonitor, + IntPtr hdcMonitor, + ref RECT lprcMonitor, + IntPtr dwData + ); [DllImport("user32.dll")] - public static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lprcClip, MonitorEnumDelegate lpfnEnum, - IntPtr dwData); + public static extern bool EnumDisplayMonitors( + IntPtr hdc, + IntPtr lprcClip, + MonitorEnumDelegate lpfnEnum, + IntPtr dwData + ); [DllImport("user32.dll")] public static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO lpmi); diff --git a/src/UniGetUI/Pages/AboutPages/AboutUniGetUI.xaml b/src/UniGetUI/Pages/AboutPages/AboutUniGetUI.xaml index 893f7b1b3a..f6ec49bc14 100644 --- a/src/UniGetUI/Pages/AboutPages/AboutUniGetUI.xaml +++ b/src/UniGetUI/Pages/AboutPages/AboutUniGetUI.xaml @@ -1,60 +1,69 @@ + x:Class="UniGetUI.Interface.Pages.AboutPages.AboutUniGetUI" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="using:UniGetUI.Interface.Pages.AboutPages" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:widgets="using:UniGetUI.Interface.Widgets" + NavigationCacheMode="Required" + mc:Ignorable="d" +> + + + + + + - + - - - - - - - - - - - - - - - - - - - - + NavigateUri="https://www.marticliment.com/unigetui" + > + + + + + + + + + + diff --git a/src/UniGetUI/Pages/AboutPages/AboutUniGetUI.xaml.cs b/src/UniGetUI/Pages/AboutPages/AboutUniGetUI.xaml.cs index e81e032186..c58a80b0aa 100644 --- a/src/UniGetUI/Pages/AboutPages/AboutUniGetUI.xaml.cs +++ b/src/UniGetUI/Pages/AboutPages/AboutUniGetUI.xaml.cs @@ -7,7 +7,6 @@ namespace UniGetUI.Interface.Pages.AboutPages { - /// /// An empty page that can be used on its own or navigated to within a Frame. /// @@ -16,9 +15,14 @@ public sealed partial class AboutUniGetUI : Page public AboutUniGetUI() { InitializeComponent(); - VersionText.Text = CoreTools.Translate("You have installed WingetUI Version {0}", CoreData.VersionName); + VersionText.Text = CoreTools.Translate( + "You have installed WingetUI Version {0}", + CoreData.VersionName + ); DisclaimerBanner.Title = CoreTools.Translate("Disclaimer"); - DisclaimerBanner.Message = CoreTools.Translate("UniGetUI is not related to any of the compatible package managers. UniGetUI is an independent project."); + DisclaimerBanner.Message = CoreTools.Translate( + "UniGetUI is not related to any of the compatible package managers. UniGetUI is an independent project." + ); } } } diff --git a/src/UniGetUI/Pages/AboutPages/Contributors.xaml b/src/UniGetUI/Pages/AboutPages/Contributors.xaml index d8bf56c2d0..40b49cd3c7 100644 --- a/src/UniGetUI/Pages/AboutPages/Contributors.xaml +++ b/src/UniGetUI/Pages/AboutPages/Contributors.xaml @@ -1,72 +1,70 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + x:Class="UniGetUI.Interface.Pages.AboutPages.Contributors" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="using:UniGetUI.Core.Classes" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:widgets="using:UniGetUI.Interface.Widgets" + NavigationCacheMode="Required" + mc:Ignorable="d" +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/UniGetUI/Pages/AboutPages/Contributors.xaml.cs b/src/UniGetUI/Pages/AboutPages/Contributors.xaml.cs index 36f5d0dd5c..8b09ced150 100644 --- a/src/UniGetUI/Pages/AboutPages/Contributors.xaml.cs +++ b/src/UniGetUI/Pages/AboutPages/Contributors.xaml.cs @@ -14,6 +14,7 @@ namespace UniGetUI.Interface.Pages.AboutPages public sealed partial class Contributors : Page { public ObservableCollection ContributorList = []; + public Contributors() { InitializeComponent(); diff --git a/src/UniGetUI/Pages/AboutPages/ThirdPartyLicenses.xaml b/src/UniGetUI/Pages/AboutPages/ThirdPartyLicenses.xaml index 7cac12be4e..5c53ed4b89 100644 --- a/src/UniGetUI/Pages/AboutPages/ThirdPartyLicenses.xaml +++ b/src/UniGetUI/Pages/AboutPages/ThirdPartyLicenses.xaml @@ -1,71 +1,70 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + x:Class="UniGetUI.Interface.Pages.AboutPages.ThirdPartyLicenses" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="using:UniGetUI.Interface.Pages.AboutPages" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:widgets="using:UniGetUI.Interface.Widgets" + NavigationCacheMode="Required" + mc:Ignorable="d" +> + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/UniGetUI/Pages/AboutPages/ThirdPartyLicenses.xaml.cs b/src/UniGetUI/Pages/AboutPages/ThirdPartyLicenses.xaml.cs index 8a30b0951e..bf9758aef0 100644 --- a/src/UniGetUI/Pages/AboutPages/ThirdPartyLicenses.xaml.cs +++ b/src/UniGetUI/Pages/AboutPages/ThirdPartyLicenses.xaml.cs @@ -11,7 +11,7 @@ namespace UniGetUI.Interface.Pages.AboutPages /// /// An empty page that can be used on its own or navigated to within a Frame. /// - /// + /// public class LibraryLicense { public string Name { get; set; } = ""; @@ -30,16 +30,17 @@ public ThirdPartyLicenses() InitializeComponent(); foreach (string license in LicenseData.LicenseNames.Keys) { - Licenses.Add(new LibraryLicense - { - Name = license, - License = LicenseData.LicenseNames[license], - LicenseURL = LicenseData.LicenseURLs[license], - HomepageUrl = LicenseData.HomepageUrls[license], - HomepageText = CoreTools.Translate("{0} homepage", license) - }); + Licenses.Add( + new LibraryLicense + { + Name = license, + License = LicenseData.LicenseNames[license], + LicenseURL = LicenseData.LicenseURLs[license], + HomepageUrl = LicenseData.HomepageUrls[license], + HomepageText = CoreTools.Translate("{0} homepage", license), + } + ); } - } } } diff --git a/src/UniGetUI/Pages/AboutPages/Translators.xaml b/src/UniGetUI/Pages/AboutPages/Translators.xaml index 727ead9a9e..3fb3a63bd2 100644 --- a/src/UniGetUI/Pages/AboutPages/Translators.xaml +++ b/src/UniGetUI/Pages/AboutPages/Translators.xaml @@ -1,86 +1,86 @@ - - + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + NavigateUri="{x:Bind GitHubUrl}" + Visibility="{x:Bind HasGitHubProfile}" + > + + + + + + + + diff --git a/src/UniGetUI/Pages/AboutPages/Translators.xaml.cs b/src/UniGetUI/Pages/AboutPages/Translators.xaml.cs index 92a42fa652..9feae67140 100644 --- a/src/UniGetUI/Pages/AboutPages/Translators.xaml.cs +++ b/src/UniGetUI/Pages/AboutPages/Translators.xaml.cs @@ -14,6 +14,7 @@ namespace UniGetUI.Interface.Pages.AboutPages public sealed partial class Translators : Page { public ObservableCollection TranslatorList = []; + public Translators() { InitializeComponent(); diff --git a/src/UniGetUI/Pages/DialogPages/AboutUniGetUI.xaml b/src/UniGetUI/Pages/DialogPages/AboutUniGetUI.xaml index af419d5691..7084495c8b 100644 --- a/src/UniGetUI/Pages/DialogPages/AboutUniGetUI.xaml +++ b/src/UniGetUI/Pages/DialogPages/AboutUniGetUI.xaml @@ -1,70 +1,60 @@ - - - - - + x:Class="UniGetUI.Interface.AboutUniGetUI" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="using:UniGetUI.Interface" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:widgets="using:UniGetUI.Interface.Widgets" + MaxWidth="650" + MaxHeight="600" + mc:Ignorable="d" +> + + + + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + diff --git a/src/UniGetUI/Pages/DialogPages/AboutUniGetUI.xaml.cs b/src/UniGetUI/Pages/DialogPages/AboutUniGetUI.xaml.cs index c9b85971cf..442a8613e7 100644 --- a/src/UniGetUI/Pages/DialogPages/AboutUniGetUI.xaml.cs +++ b/src/UniGetUI/Pages/DialogPages/AboutUniGetUI.xaml.cs @@ -11,12 +11,11 @@ namespace UniGetUI.Interface /// /// An empty page that can be used on its own or navigated to within a Frame. /// - public sealed partial class AboutUniGetUI : Page { - public event EventHandler? Close; private int previousSelectedIndex; + public AboutUniGetUI() { InitializeComponent(); @@ -26,7 +25,10 @@ public AboutUniGetUI() SelectorBarItemPage4.Text = CoreTools.Translate("Translators"); } - private void SelectorBar_SelectionChanged(SelectorBar sender, SelectorBarSelectionChangedEventArgs args) + private void SelectorBar_SelectionChanged( + SelectorBar sender, + SelectorBarSelectionChangedEventArgs args + ) { SelectorBarItem selectedItem = sender.SelectedItem; int currentSelectedIndex = sender.Items.IndexOf(selectedItem); @@ -37,12 +39,18 @@ private void SelectorBar_SelectionChanged(SelectorBar sender, SelectorBarSelecti 2 => typeof(Contributors), _ => typeof(Translators), }; - SlideNavigationTransitionEffect slideNavigationTransitionEffect = currentSelectedIndex - previousSelectedIndex > 0 ? SlideNavigationTransitionEffect.FromRight : SlideNavigationTransitionEffect.FromLeft; + SlideNavigationTransitionEffect slideNavigationTransitionEffect = + currentSelectedIndex - previousSelectedIndex > 0 + ? SlideNavigationTransitionEffect.FromRight + : SlideNavigationTransitionEffect.FromLeft; - ContentFrame.Navigate(pageType, null, new SlideNavigationTransitionInfo { Effect = slideNavigationTransitionEffect }); + ContentFrame.Navigate( + pageType, + null, + new SlideNavigationTransitionInfo { Effect = slideNavigationTransitionEffect } + ); previousSelectedIndex = currentSelectedIndex; - } private void CloseButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) diff --git a/src/UniGetUI/Pages/DialogPages/DesktopShortcuts.xaml b/src/UniGetUI/Pages/DialogPages/DesktopShortcuts.xaml index 8ce295f2ee..7d3a9d6a0e 100644 --- a/src/UniGetUI/Pages/DialogPages/DesktopShortcuts.xaml +++ b/src/UniGetUI/Pages/DialogPages/DesktopShortcuts.xaml @@ -1,44 +1,36 @@ + x:Class="UniGetUI.Interface.DesktopShortcutsManager" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="using:UniGetUI.Interface" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:widgets="using:UniGetUI.Interface.Widgets" + MaxWidth="950" + MaxHeight="500" + mc:Ignorable="d" +> + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/UniGetUI/Pages/DialogPages/DesktopShortcuts.xaml.cs b/src/UniGetUI/Pages/DialogPages/DesktopShortcuts.xaml.cs index 373c9bf633..f6d2cfb0da 100644 --- a/src/UniGetUI/Pages/DialogPages/DesktopShortcuts.xaml.cs +++ b/src/UniGetUI/Pages/DialogPages/DesktopShortcuts.xaml.cs @@ -4,10 +4,10 @@ using System.Runtime.CompilerServices; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; -using UniGetUI.PackageEngine.Classes.Packages.Classes; -using UniGetUI.Pages.DialogPages; using UniGetUI.Core.SettingsEngine; using UniGetUI.Core.Tools; +using UniGetUI.PackageEngine.Classes.Packages.Classes; +using UniGetUI.Pages.DialogPages; // To learn more about WinUI, the WinUI project structure, // and more about our project templates, see: http://aka.ms/winui-project-info. @@ -27,7 +27,9 @@ public DesktopShortcutsManager() InitializeComponent(); DeletableDesktopShortcutsList.ItemsSource = Shortcuts; - AutoDeleteShortcutsCheckbox.IsChecked = Settings.Get(Settings.K.RemoveAllDesktopShortcuts); + AutoDeleteShortcutsCheckbox.IsChecked = Settings.Get( + Settings.K.RemoveAllDesktopShortcuts + ); AutoDeleteShortcutsCheckbox.Checked += HandleAllDesktop_Checked; AutoDeleteShortcutsCheckbox.Unchecked += HandleAllDesktop_Unchecked; } @@ -39,7 +41,10 @@ public void LoadShortcuts(IReadOnlyList NewShortcuts) foreach (var shortcut in NewShortcuts) { var status = DesktopShortcutsDatabase.GetStatus(shortcut); - var entry = new ShortcutEntry(shortcut, status is DesktopShortcutsDatabase.Status.Delete); + var entry = new ShortcutEntry( + shortcut, + status is DesktopShortcutsDatabase.Status.Delete + ); entry.OnReset += (_, _) => Shortcuts.Remove(entry); items.Add(entry); } @@ -112,7 +117,12 @@ public void SaveChanges() { foreach (var shortcut in Shortcuts) { - DesktopShortcutsDatabase.AddToDatabase(shortcut.Path, shortcut.IsDeletable? DesktopShortcutsDatabase.Status.Delete: DesktopShortcutsDatabase.Status.Maintain); + DesktopShortcutsDatabase.AddToDatabase( + shortcut.Path, + shortcut.IsDeletable + ? DesktopShortcutsDatabase.Status.Delete + : DesktopShortcutsDatabase.Status.Maintain + ); DesktopShortcutsDatabase.RemoveFromUnknownShortcuts(shortcut.Path); if (shortcut.IsDeletable && File.Exists(shortcut.Path)) @@ -139,7 +149,7 @@ public partial class ShortcutEntry : INotifyPropertyChanged public bool IsDeletable { - get => _deletable; + get => _deletable; set { _deletable = value; @@ -163,7 +173,10 @@ public ShortcutEntry(string path, bool isDeletable) public void ResetShortcut() { - DesktopShortcutsDatabase.AddToDatabase(this.Path, DesktopShortcutsDatabase.Status.Unknown); + DesktopShortcutsDatabase.AddToDatabase( + this.Path, + DesktopShortcutsDatabase.Status.Unknown + ); OnReset?.Invoke(this, EventArgs.Empty); } diff --git a/src/UniGetUI/Pages/DialogPages/DialogHelper_Generic.cs b/src/UniGetUI/Pages/DialogPages/DialogHelper_Generic.cs index e6394fe28c..93dd218965 100644 --- a/src/UniGetUI/Pages/DialogPages/DialogHelper_Generic.cs +++ b/src/UniGetUI/Pages/DialogPages/DialogHelper_Generic.cs @@ -1,5 +1,4 @@ using System.Diagnostics; -using Windows.UI; using Microsoft.UI; using Microsoft.UI.Text; using Microsoft.UI.Xaml; @@ -18,27 +17,40 @@ using UniGetUI.PackageEngine; using UniGetUI.PackageEngine.Classes.Packages.Classes; using UniGetUI.PackageEngine.PackageLoader; +using Windows.UI; namespace UniGetUI.Pages.DialogPages; public static partial class DialogHelper { - public static async Task ShowMissingDependency(string dep_name, string exe_name, string exe_args, - string fancy_command, int current, int total) + public static async Task ShowMissingDependency( + string dep_name, + string exe_name, + string exe_args, + string fancy_command, + int current, + int total + ) { - - if (Settings.GetDictionaryItem(Settings.K.DependencyManagement, dep_name) == "skipped") + if ( + Settings.GetDictionaryItem(Settings.K.DependencyManagement, dep_name) + == "skipped" + ) { Logger.Error( - $"Dependency {dep_name} was not found, and the user set it to not be reminded of the missing dependency"); + $"Dependency {dep_name} was not found, and the user set it to not be reminded of the missing dependency" + ); return; } - bool NotFirstTime = Settings.GetDictionaryItem(Settings.K.DependencyManagement, dep_name) == "attempted"; + bool NotFirstTime = + Settings.GetDictionaryItem(Settings.K.DependencyManagement, dep_name) + == "attempted"; Settings.SetDictionaryItem(Settings.K.DependencyManagement, dep_name, "attempted"); var dialog = DialogFactory.Create(); - dialog.Title = CoreTools.Translate("Missing dependency") + (total > 1 ? $" ({current}/{total})" : ""); + dialog.Title = + CoreTools.Translate("Missing dependency") + (total > 1 ? $" ({current}/{total})" : ""); dialog.SecondaryButtonText = CoreTools.Translate("Not right now"); dialog.PrimaryButtonText = CoreTools.Translate("Install {0}", dep_name); dialog.DefaultButton = ContentDialogButton.Primary; @@ -48,18 +60,23 @@ public static async Task ShowMissingDependency(string dep_name, string exe_name, StackPanel p = new(); - p.Children.Add(new TextBlock - { - Text = CoreTools.Translate( - "UniGetUI requires {0} to operate, but it was not found on your system.", dep_name), - TextWrapping = TextWrapping.Wrap, - Margin = new Thickness(0, 0, 0, 5) - }); + p.Children.Add( + new TextBlock + { + Text = CoreTools.Translate( + "UniGetUI requires {0} to operate, but it was not found on your system.", + dep_name + ), + TextWrapping = TextWrapping.Wrap, + Margin = new Thickness(0, 0, 0, 5), + } + ); TextBlock infotext = new() { Text = CoreTools.Translate( - "Click on Install to begin the installation process. If you skip the installation, UniGetUI may not work as expected."), + "Click on Install to begin the installation process. If you skip the installation, UniGetUI may not work as expected." + ), TextWrapping = TextWrapping.Wrap, Margin = new Thickness(0, 0, 0, 10), Opacity = .7F, @@ -71,7 +88,8 @@ public static async Task ShowMissingDependency(string dep_name, string exe_name, { Text = CoreTools.Translate( "Alternatively, you can also install {0} by running the following command in a Windows PowerShell prompt:", - dep_name), + dep_name + ), TextWrapping = TextWrapping.Wrap, Margin = new Thickness(0, 0, 0, 4), Opacity = .7F, @@ -94,8 +112,10 @@ public static async Task ShowMissingDependency(string dep_name, string exe_name, { c.Content = CoreTools.Translate("Do not show this dialog again for {0}", dep_name); c.IsChecked = false; - c.Checked += (_, _) => Settings.SetDictionaryItem(Settings.K.DependencyManagement, dep_name, "skipped"); - c.Unchecked += (_, _) => Settings.SetDictionaryItem(Settings.K.DependencyManagement, dep_name, "attempted"); + c.Checked += (_, _) => + Settings.SetDictionaryItem(Settings.K.DependencyManagement, dep_name, "skipped"); + c.Unchecked += (_, _) => + Settings.SetDictionaryItem(Settings.K.DependencyManagement, dep_name, "attempted"); p.Children.Add(c); } @@ -117,13 +137,17 @@ public static async Task ShowMissingDependency(string dep_name, string exe_name, dialog.IsSecondaryButtonEnabled = false; dialog.SecondaryButtonText = ""; dialog.PrimaryButtonText = CoreTools.Translate("Please wait"); - infotext.Text = - CoreTools.Translate( - "Please wait while {0} is being installed. A black window may show up. Please wait until it closes.", - dep_name); + infotext.Text = CoreTools.Translate( + "Please wait while {0} is being installed. A black window may show up. Please wait until it closes.", + dep_name + ); Process install_dep_p = new() { - StartInfo = new ProcessStartInfo { FileName = exe_name, Arguments = exe_args, }, + StartInfo = new ProcessStartInfo + { + FileName = exe_name, + Arguments = exe_args, + }, }; install_dep_p.Start(); await install_dep_p.WaitForExitAsync(); @@ -132,19 +156,23 @@ public static async Task ShowMissingDependency(string dep_name, string exe_name, if (current < total) { // When finished, but more dependencies need to be installed - infotext.Text = CoreTools.Translate("{0} has been installed successfully.", dep_name) + - " " + CoreTools.Translate("Please click on \"Continue\" to continue", - dep_name); + infotext.Text = + CoreTools.Translate("{0} has been installed successfully.", dep_name) + + " " + + CoreTools.Translate( + "Please click on \"Continue\" to continue", + dep_name + ); dialog.SecondaryButtonText = ""; dialog.PrimaryButtonText = CoreTools.Translate("Continue"); } else { // When finished, and no more dependencies need to be installed - infotext.Text = - CoreTools.Translate( - "{0} has been installed successfully. It is recommended to restart UniGetUI to finish the installation", - dep_name); + infotext.Text = CoreTools.Translate( + "{0} has been installed successfully. It is recommended to restart UniGetUI to finish the installation", + dep_name + ); dialog.SecondaryButtonText = CoreTools.Translate("Restart later"); dialog.PrimaryButtonText = CoreTools.Translate("Restart UniGetUI"); } @@ -155,12 +183,17 @@ public static async Task ShowMissingDependency(string dep_name, string exe_name, Logger.Error(ex); dialog.IsPrimaryButtonEnabled = true; dialog.IsSecondaryButtonEnabled = true; - infotext.Text = CoreTools.Translate("An error occurred:") + " " + ex.Message + "\n" + - CoreTools.Translate("Please click on \"Continue\" to continue"); + infotext.Text = + CoreTools.Translate("An error occurred:") + + " " + + ex.Message + + "\n" + + CoreTools.Translate("Please click on \"Continue\" to continue"); dialog.SecondaryButtonText = ""; - dialog.PrimaryButtonText = (current < total) - ? CoreTools.Translate("Continue") - : CoreTools.Translate("Close"); + dialog.PrimaryButtonText = + (current < total) + ? CoreTools.Translate("Continue") + : CoreTools.Translate("Close"); } has_installed = true; @@ -199,12 +232,14 @@ public static async Task ManageIgnoredUpdates() await ShowDialogAsync(dialog); } - public static async Task ManageDesktopShortcuts(IReadOnlyList? NewShortucts = null) + public static async Task ManageDesktopShortcuts(IReadOnlyList? NewShortucts = null) { ContentDialog dialog = DialogFactory.Create_AsWindow(true); DesktopShortcutsManager DesktopShortcutsPage = new(); - DesktopShortcutsPage.LoadShortcuts(NewShortucts ?? DesktopShortcutsDatabase.GetAllShortcuts()); + DesktopShortcutsPage.LoadShortcuts( + NewShortucts ?? DesktopShortcutsDatabase.GetAllShortcuts() + ); DesktopShortcutsPage.Close += (_, _) => dialog.Hide(); dialog.Title = CoreTools.Translate("Automatic desktop shortcut remover"); @@ -219,7 +254,9 @@ public static async Task HandleNewDesktopShortcuts() if (!Settings.AreNotificationsDisabled()) { - await AppNotificationManager.Default.RemoveByTagAsync(CoreData.NewShortcutsNotificationTag.ToString()); + await AppNotificationManager.Default.RemoveByTagAsync( + CoreData.NewShortcutsNotificationTag.ToString() + ); AppNotification notification; if (unknownShortcuts.Count == 1) @@ -228,10 +265,16 @@ public static async Task HandleNewDesktopShortcuts() .SetScenario(AppNotificationScenario.Default) .SetTag(CoreData.NewShortcutsNotificationTag.ToString()) .AddText(CoreTools.Translate("Desktop shortcut created")) - .AddText(CoreTools.Translate("UniGetUI has detected a new desktop shortcut that can be deleted automatically.")) + .AddText( + CoreTools.Translate( + "UniGetUI has detected a new desktop shortcut that can be deleted automatically." + ) + ) .SetAttributionText(unknownShortcuts.First().Split("\\").Last()) - .AddButton(new AppNotificationButton(CoreTools.Translate("Open UniGetUI").Replace("'", "´")) - .AddArgument("action", NotificationArguments.Show) + .AddButton( + new AppNotificationButton( + CoreTools.Translate("Open UniGetUI").Replace("'", "´") + ).AddArgument("action", NotificationArguments.Show) ) .AddArgument("action", NotificationArguments.Show); @@ -250,11 +293,20 @@ public static async Task HandleNewDesktopShortcuts() AppNotificationBuilder builder = new AppNotificationBuilder() .SetScenario(AppNotificationScenario.Default) .SetTag(CoreData.NewShortcutsNotificationTag.ToString()) - .AddText(CoreTools.Translate("{0} desktop shortcuts created", unknownShortcuts.Count)) - .AddText(CoreTools.Translate("UniGetUI has detected {0} new desktop shortcuts that can be deleted automatically.", unknownShortcuts.Count)) + .AddText( + CoreTools.Translate("{0} desktop shortcuts created", unknownShortcuts.Count) + ) + .AddText( + CoreTools.Translate( + "UniGetUI has detected {0} new desktop shortcuts that can be deleted automatically.", + unknownShortcuts.Count + ) + ) .SetAttributionText(attribution) - .AddButton(new AppNotificationButton(CoreTools.Translate("Open UniGetUI").Replace("'", "´")) - .AddArgument("action", NotificationArguments.ShowOnUpdatesTab) + .AddButton( + new AppNotificationButton( + CoreTools.Translate("Open UniGetUI").Replace("'", "´") + ).AddArgument("action", NotificationArguments.ShowOnUpdatesTab) ) .AddArgument("action", NotificationArguments.ShowOnUpdatesTab); @@ -272,7 +324,7 @@ public static async Task WarnAboutAdminRights() { ContentDialog AdminDialog = new() { - Style = Application.Current.Resources["DefaultContentDialogStyle"] as Style + Style = Application.Current.Resources["DefaultContentDialogStyle"] as Style, }; while (Window.XamlRoot is null) @@ -285,7 +337,8 @@ public static async Task WarnAboutAdminRights() AdminDialog.DefaultButton = ContentDialogButton.Primary; AdminDialog.Title = CoreTools.Translate("Administrator privileges"); AdminDialog.Content = CoreTools.Translate( - "WingetUI has been ran as administrator, which is not recommended. When running WingetUI as administrator, EVERY operation launched from WingetUI will have administrator privileges. You can still use the program, but we highly recommend not running WingetUI with administrator privileges."); + "WingetUI has been ran as administrator, which is not recommended. When running WingetUI as administrator, EVERY operation launched from WingetUI will have administrator privileges. You can still use the program, but we highly recommend not running WingetUI with administrator privileges." + ); await ShowDialogAsync(AdminDialog); } @@ -317,8 +370,10 @@ public static async Task HandleBrokenWinGet() bool bannerWasOpen = false; try { - int loadingId = ShowLoadingDialog("Attempting to repair WinGet...", - "WinGet is being repaired. Please wait until the process finishes."); + int loadingId = ShowLoadingDialog( + "Attempting to repair WinGet...", + "WinGet is being repaired. Please wait until the process finishes." + ); bannerWasOpen = Window.WinGetWarningBanner.IsOpen; Window.WinGetWarningBanner.IsOpen = false; using Process p = new Process @@ -327,20 +382,20 @@ public static async Task HandleBrokenWinGet() { FileName = CoreData.PowerShell5, Arguments = - "-ExecutionPolicy Bypass -NoLogo -NoProfile -Command \"& {" + - "cmd.exe /C \"rmdir /Q /S `\"%temp%\\WinGet`\"\"; " + - "cmd.exe /C \"`\"%localappdata%\\Microsoft\\WindowsApps\\winget.exe`\" source reset --force\"; " + - "taskkill /im winget.exe /f; " + - "taskkill /im WindowsPackageManagerServer.exe /f; " + - "Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force; " + - "Install-Module Microsoft.WinGet.Client -Force -AllowClobber; " + - "Import-Module Microsoft.WinGet.Client; " + - "Repair-WinGetPackageManager -Force -Latest; " + - "Get-AppxPackage -Name 'Microsoft.DesktopAppInstaller' | Reset-AppxPackage; " + - "}\"", + "-ExecutionPolicy Bypass -NoLogo -NoProfile -Command \"& {" + + "cmd.exe /C \"rmdir /Q /S `\"%temp%\\WinGet`\"\"; " + + "cmd.exe /C \"`\"%localappdata%\\Microsoft\\WindowsApps\\winget.exe`\" source reset --force\"; " + + "taskkill /im winget.exe /f; " + + "taskkill /im WindowsPackageManagerServer.exe /f; " + + "Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force; " + + "Install-Module Microsoft.WinGet.Client -Force -AllowClobber; " + + "Import-Module Microsoft.WinGet.Client; " + + "Repair-WinGetPackageManager -Force -Latest; " + + "Get-AppxPackage -Name 'Microsoft.DesktopAppInstaller' | Reset-AppxPackage; " + + "}\"", UseShellExecute = true, - Verb = "runas" - } + Verb = "runas", + }, }; p.Start(); await p.WaitForExitAsync(); @@ -352,10 +407,14 @@ public static async Task HandleBrokenWinGet() var c = DialogFactory.Create(); c.Title = CoreTools.Translate("WinGet was repaired successfully"); - c.Content = CoreTools.Translate("It is recommended to restart UniGetUI after WinGet has been repaired") + - "\n\n" + - CoreTools.Translate( - "NOTE: This troubleshooter can be disabled from UniGetUI Settings, on the WinGet section"); + c.Content = + CoreTools.Translate( + "It is recommended to restart UniGetUI after WinGet has been repaired" + ) + + "\n\n" + + CoreTools.Translate( + "NOTE: This troubleshooter can be disabled from UniGetUI Settings, on the WinGet section" + ); c.PrimaryButtonText = CoreTools.Translate("Close"); c.SecondaryButtonText = CoreTools.Translate("Restart"); c.DefaultButton = ContentDialogButton.Secondary; @@ -381,15 +440,20 @@ public static async Task HandleBrokenWinGet() var c = DialogFactory.Create(); c.Title = CoreTools.Translate("WinGet could not be repaired"); - c.Content = CoreTools.Translate( - "An unexpected issue occurred while attempting to repair WinGet. Please try again later") + - "\n\n" + ex.Message + "\n\n" + CoreTools.Translate( - "NOTE: This troubleshooter can be disabled from UniGetUI Settings, on the WinGet section"); + c.Content = + CoreTools.Translate( + "An unexpected issue occurred while attempting to repair WinGet. Please try again later" + ) + + "\n\n" + + ex.Message + + "\n\n" + + CoreTools.Translate( + "NOTE: This troubleshooter can be disabled from UniGetUI Settings, on the WinGet section" + ); c.PrimaryButtonText = CoreTools.Translate("Close"); c.DefaultButton = ContentDialogButton.None; await ShowDialogAsync(c); } - } public static async Task ShowTelemetryDialog() @@ -403,38 +467,58 @@ public static async Task ShowTelemetryDialog() var p = new Paragraph(); MessageBlock.Blocks.Add(p); - p.Inlines.Add(new Run - { - Text = CoreTools.Translate("UniGetUI collects anonymous usage data with the sole purpose of understanding and improving the user experience.") - }); + p.Inlines.Add( + new Run + { + Text = CoreTools.Translate( + "UniGetUI collects anonymous usage data with the sole purpose of understanding and improving the user experience." + ), + } + ); p.Inlines.Add(new LineBreak()); - p.Inlines.Add(new Run - { - Text = CoreTools.Translate("No personal information is collected nor sent, and the collected data is anonimized, so it can't be back-tracked to you.") - }); + p.Inlines.Add( + new Run + { + Text = CoreTools.Translate( + "No personal information is collected nor sent, and the collected data is anonimized, so it can't be back-tracked to you." + ), + } + ); p.Inlines.Add(new LineBreak()); p.Inlines.Add(new LineBreak()); - var link = new Hyperlink { NavigateUri = new Uri("https://www.marticliment.com/unigetui/privacy/"), }; - link.Inlines.Add(new Run + var link = new Hyperlink { - Text = CoreTools.Translate("More details about the shared data and how it will be processed"), - }); + NavigateUri = new Uri("https://www.marticliment.com/unigetui/privacy/"), + }; + link.Inlines.Add( + new Run + { + Text = CoreTools.Translate( + "More details about the shared data and how it will be processed" + ), + } + ); p.Inlines.Add(link); p.Inlines.Add(new LineBreak()); p.Inlines.Add(new LineBreak()); - p.Inlines.Add(new Run - { - Text = CoreTools.Translate("Do you accept that UniGetUI collects and sends anonymous usage statistics, with the sole purpose of understanding and improving the user experience?"), - FontWeight = FontWeights.SemiBold - }); + p.Inlines.Add( + new Run + { + Text = CoreTools.Translate( + "Do you accept that UniGetUI collects and sends anonymous usage statistics, with the sole purpose of understanding and improving the user experience?" + ), + FontWeight = FontWeights.SemiBold, + } + ); dialog.SecondaryButtonText = CoreTools.Translate("Decline"); dialog.PrimaryButtonText = CoreTools.Translate("Accept"); dialog.DefaultButton = ContentDialogButton.Primary; dialog.Closing += (_, e) => { - if (e.Result == ContentDialogResult.None) e.Cancel = true; + if (e.Result == ContentDialogResult.None) + e.Cancel = true; }; var res = await ShowDialogAsync(dialog); @@ -452,7 +536,9 @@ public static async Task ShowTelemetryDialog() public static void ShowTelemetryBanner() { Window.TelemetryWarner.Title = CoreTools.Translate("Share anonymous usage data"); - Window.TelemetryWarner.Message = CoreTools.Translate("UniGetUI collects anonymous usage data in order to improve the user experience."); + Window.TelemetryWarner.Message = CoreTools.Translate( + "UniGetUI collects anonymous usage data in order to improve the user experience." + ); Window.TelemetryWarner.IsOpen = true; Window.TelemetryWarner.IsClosable = true; @@ -461,7 +547,7 @@ public static void ShowTelemetryBanner() var AcceptBtn = new Button() { Content = CoreTools.Translate("Accept"), - Style = Application.Current.Resources["AccentButtonStyle"] as Style + Style = Application.Current.Resources["AccentButtonStyle"] as Style, }; AcceptBtn.Click += (_, _) => { @@ -470,10 +556,7 @@ public static void ShowTelemetryBanner() Settings.Set(Settings.K.ShownTelemetryBanner, true); }; - var SettingsBtn = new Button() - { - Content = CoreTools.Translate("Settings"), - }; + var SettingsBtn = new Button() { Content = CoreTools.Translate("Settings") }; SettingsBtn.Click += (_, _) => { Window.TelemetryWarner.Visibility = Visibility.Collapsed; @@ -482,7 +565,12 @@ public static void ShowTelemetryBanner() Settings.Set(Settings.K.ShownTelemetryBanner, true); }; - StackPanel btns = new() { Margin = new Thickness(4,0,4,0), Spacing = 4, Orientation = Orientation.Horizontal }; + StackPanel btns = new() + { + Margin = new Thickness(4, 0, 4, 0), + Spacing = 4, + Orientation = Orientation.Horizontal, + }; btns.Children.Add(AcceptBtn); btns.Children.Add(SettingsBtn); @@ -493,19 +581,29 @@ public static void ShowTelemetryBanner() Background = new SolidColorBrush(Colors.Transparent), BorderBrush = new SolidColorBrush(Colors.Transparent), }; - mainButton.Resources["HyperlinkButtonBackgroundPointerOver"] = new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)); - - Window.TelemetryWarner.CloseButtonClick += (_, _) => Settings.Set(Settings.K.ShownTelemetryBanner, true); + mainButton.Resources["HyperlinkButtonBackgroundPointerOver"] = new SolidColorBrush( + Color.FromArgb(0, 0, 0, 0) + ); + Window.TelemetryWarner.CloseButtonClick += (_, _) => + Settings.Set(Settings.K.ShownTelemetryBanner, true); } public static async Task ConfirmSetDeleteAllShortcutsSetting() { var dialog = DialogFactory.Create(); dialog.Title = CoreTools.Translate("Are you sure you want to delete all shortcuts?"); - dialog.Content = CoreTools.Translate("Any new shorcuts created during an install or an update operation will be deleted automatically, instead of showing a confirmation prompt the first time they are detected.") - + " " + CoreTools.Translate("Any shorcuts created or modified outside of UniGetUI will be ignored. You will be able to add them via the {0} button.", $"\"{CoreTools.Translate("Manual scan")}\"") - + " " + CoreTools.Translate("Are you really sure you want to enable this feature?"); + dialog.Content = + CoreTools.Translate( + "Any new shorcuts created during an install or an update operation will be deleted automatically, instead of showing a confirmation prompt the first time they are detected." + ) + + " " + + CoreTools.Translate( + "Any shorcuts created or modified outside of UniGetUI will be ignored. You will be able to add them via the {0} button.", + $"\"{CoreTools.Translate("Manual scan")}\"" + ) + + " " + + CoreTools.Translate("Are you really sure you want to enable this feature?"); dialog.PrimaryButtonText = CoreTools.Translate("Yes"); dialog.CloseButtonText = CoreTools.Translate("No"); dialog.DefaultButton = ContentDialogButton.Close; @@ -530,24 +628,46 @@ public static async Task HowToAddPackagesToBundle() { var dialog = DialogFactory.Create(); dialog.Title = CoreTools.Translate("How to add packages to a bundle"); - dialog.Content = CoreTools.Translate("In order to add packages to a bundle, you will need to: ") - + "\n " + CoreTools.Translate("1. Navigate to the \"{0}\" or \"{1}\" page.", CoreTools.Translate("Discover packages"), CoreTools.Translate("Installed packages")) - + "\n " + CoreTools.Translate("2. Locate the package(s) you want to add to the bundle, and select their leftmost checkbox.") - + "\n " + CoreTools.Translate("3. When the packages you want to add to the bundle are selected, find and click the option \"{0}\" on the toolbar.", CoreTools.Translate("Add selection to bundle")) - + "\n " + CoreTools.Translate("4. Your packages will have been added to the bundle. You can continue adding packages, or export the bundle."); + dialog.Content = + CoreTools.Translate("In order to add packages to a bundle, you will need to: ") + + "\n " + + CoreTools.Translate( + "1. Navigate to the \"{0}\" or \"{1}\" page.", + CoreTools.Translate("Discover packages"), + CoreTools.Translate("Installed packages") + ) + + "\n " + + CoreTools.Translate( + "2. Locate the package(s) you want to add to the bundle, and select their leftmost checkbox." + ) + + "\n " + + CoreTools.Translate( + "3. When the packages you want to add to the bundle are selected, find and click the option \"{0}\" on the toolbar.", + CoreTools.Translate("Add selection to bundle") + ) + + "\n " + + CoreTools.Translate( + "4. Your packages will have been added to the bundle. You can continue adding packages, or export the bundle." + ); dialog.PrimaryButtonText = CoreTools.Translate("Discover packages"); dialog.SecondaryButtonText = CoreTools.Translate("Installed packages"); dialog.CloseButtonText = CoreTools.Translate("Close"); dialog.DefaultButton = ContentDialogButton.None; var result = await ShowDialogAsync(dialog); - if(result is ContentDialogResult.Primary) Window.NavigationPage.NavigateTo(PageType.Discover); - else if(result is ContentDialogResult.Secondary) Window.NavigationPage.NavigateTo(PageType.Installed); + if (result is ContentDialogResult.Primary) + Window.NavigationPage.NavigateTo(PageType.Discover); + else if (result is ContentDialogResult.Secondary) + Window.NavigationPage.NavigateTo(PageType.Installed); } public static void ShowDismissableBalloon(string title, string message) { Window.DismissableNotification.Title = title; - Window.DismissableNotification.Content = new TextBlock() { Text = message, TextWrapping = TextWrapping.Wrap }; + Window.DismissableNotification.Content = new TextBlock() + { + Text = message, + TextWrapping = TextWrapping.Wrap, + }; Window.DismissableNotification.IsOpen = true; } @@ -561,7 +681,8 @@ public static void ShowDismissableBalloon(string title, string message) dialog.IsPrimaryButtonEnabled = false; RadioButtons buttons = new RadioButtons(); - foreach(var name in availableBackups) buttons.Items.Add(name); + foreach (var name in availableBackups) + buttons.Items.Add(name); buttons.SelectionChanged += (_, _) => dialog.IsPrimaryButtonEnabled = true; dialog.Content = new StackPanel() @@ -570,20 +691,22 @@ public static void ShowDismissableBalloon(string title, string message) Spacing = 4, Children = { - new TextBlock() { + new TextBlock() + { Text = CoreTools.Translate( - "Select the backup you want to open. Later, you will be able to review which packages you want to install."), - TextWrapping = TextWrapping.Wrap + "Select the backup you want to open. Later, you will be able to review which packages you want to install." + ), + TextWrapping = TextWrapping.Wrap, }, new ScrollViewer() { Content = buttons, - HorizontalScrollMode = ScrollMode.Disabled - } - } + HorizontalScrollMode = ScrollMode.Disabled, + }, + }, }; - if(await ShowDialogAsync(dialog) is ContentDialogResult.Primary) + if (await ShowDialogAsync(dialog) is ContentDialogResult.Primary) return buttons.SelectedItem.ToString() ?? null; return null; @@ -597,7 +720,9 @@ public static async Task AskContinueClosing_RunningOps() { var d = DialogFactory.Create(); d.Title = CoreTools.Translate("Operation in progress"); - d.Content = CoreTools.Translate("There are ongoing operations. Quitting WingetUI may cause them to fail. Do you want to continue?"); + d.Content = CoreTools.Translate( + "There are ongoing operations. Quitting WingetUI may cause them to fail. Do you want to continue?" + ); d.PrimaryButtonText = CoreTools.Translate("Quit"); d.SecondaryButtonText = CoreTools.Translate("Cancel"); d.DefaultButton = ContentDialogButton.Secondary; diff --git a/src/UniGetUI/Pages/DialogPages/DialogHelper_Infrastructure.cs b/src/UniGetUI/Pages/DialogPages/DialogHelper_Infrastructure.cs index fe74af19c0..b22a8767f0 100644 --- a/src/UniGetUI/Pages/DialogPages/DialogHelper_Infrastructure.cs +++ b/src/UniGetUI/Pages/DialogPages/DialogHelper_Infrastructure.cs @@ -1,7 +1,5 @@ using System.Diagnostics; using System.Runtime.InteropServices; -using Windows.UI; -using Windows.UI.Text; using Microsoft.UI; using Microsoft.UI.Text; using Microsoft.UI.Windowing; @@ -20,6 +18,8 @@ using UniGetUI.Interface.Enums; using UniGetUI.PackageEngine; using UniGetUI.PackageEngine.Classes.Packages.Classes; +using Windows.UI; +using Windows.UI.Text; namespace UniGetUI.Pages.DialogPages; @@ -32,7 +32,7 @@ public static ContentDialog Create() var dialog = new ContentDialog() { XamlRoot = Window.MainContentGrid.XamlRoot, - Style = Application.Current.Resources["DefaultContentDialogStyle"] as Style + Style = Application.Current.Resources["DefaultContentDialogStyle"] as Style, }; return dialog; } @@ -46,18 +46,32 @@ public static ContentDialog Create_AsWindow(bool hasTitle, bool hasButtons = fal { if (dialog.Content is FrameworkElement page) { - double maxW, maxH; - int tresholdW = 1300, tresholdH = 1300; - if (Window.NavigationPage.ActualWidth < tresholdW) maxW = 100; - else if (Window.NavigationPage.ActualWidth >= tresholdW + 200) maxW = 300; - else maxW = Window.NavigationPage.ActualWidth - (tresholdW - 100); + double maxW, + maxH; + int tresholdW = 1300, + tresholdH = 1300; + if (Window.NavigationPage.ActualWidth < tresholdW) + maxW = 100; + else if (Window.NavigationPage.ActualWidth >= tresholdW + 200) + maxW = 300; + else + maxW = Window.NavigationPage.ActualWidth - (tresholdW - 100); - if (Window.NavigationPage.ActualHeight < tresholdH) maxH = (hasTitle? 104: 64) + (hasButtons? 80: 0); - else if (Window.NavigationPage.ActualHeight >= tresholdH + 200) maxH = (hasTitle ? 320 : 280) + (hasButtons ? 80 : 0); - else maxH = Window.NavigationPage.ActualHeight - (tresholdH - (hasTitle ? 120 : 80)) + (hasButtons ? 80 : 0); + if (Window.NavigationPage.ActualHeight < tresholdH) + maxH = (hasTitle ? 104 : 64) + (hasButtons ? 80 : 0); + else if (Window.NavigationPage.ActualHeight >= tresholdH + 200) + maxH = (hasTitle ? 320 : 280) + (hasButtons ? 80 : 0); + else + maxH = + Window.NavigationPage.ActualHeight + - (tresholdH - (hasTitle ? 120 : 80)) + + (hasButtons ? 80 : 0); page.Width = Math.Min(Math.Abs(Window.NavigationPage.ActualWidth - maxW), 8192); - page.Height = Math.Min(Math.Abs(Window.NavigationPage.ActualHeight - maxH), 4096); + page.Height = Math.Min( + Math.Abs(Window.NavigationPage.ActualHeight - maxH), + 4096 + ); } }; return dialog; @@ -91,7 +105,20 @@ public interface IDataTransferManagerInterop IntPtr GetForWindow([In] IntPtr appWindow, [In] ref Guid riid); void ShowShareUIForWindow(IntPtr appWindow); } - public static readonly Guid _dtm_iid = new(0xa5caee9b,0x8708,0x49d1,0x8d,0x36,0x67,0xd2,0x5a,0x8d,0xa0,0x0c); + + public static readonly Guid _dtm_iid = new( + 0xa5caee9b, + 0x8708, + 0x49d1, + 0x8d, + 0x36, + 0x67, + 0xd2, + 0x5a, + 0x8d, + 0xa0, + 0x0c + ); } private static readonly List _loadingDialogQueue = new(); @@ -100,6 +127,7 @@ public interface IDataTransferManagerInterop private static ContentDialog? _currentLoadingDialog; public static int ShowLoadingDialog(string text) => ShowLoadingDialog(text, ""); + public static int ShowLoadingDialog(string title, string description) { var dialogData = new LoadingDialog(title, description); @@ -131,7 +159,8 @@ public static void HideAllLoadingDialogs() public static void _showNextLoadingDialogIfPossible() { - if (!_loadingDialogQueue.Any()) return; + if (!_loadingDialogQueue.Any()) + return; var data = _loadingDialogQueue.First(); if (Window.LoadingDialogCount == 0 && _dialogQueue.Count == 0) @@ -152,21 +181,24 @@ public static void _showNextLoadingDialogIfPossible() { HorizontalAlignment = HorizontalAlignment.Stretch, TextWrapping = TextWrapping.Wrap, - Text = data.Text + Text = data.Text, }, new ProgressRing() { IsIndeterminate = true, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center, - } - } + }, + }, }; _ = ShowDialogAsync(_currentLoadingDialog, HighPriority: true); } } - public static async Task ShowDialogAsync(ContentDialog dialog, bool HighPriority = false) + public static async Task ShowDialogAsync( + ContentDialog dialog, + bool HighPriority = false + ) { try { @@ -189,7 +221,8 @@ public static async Task ShowDialogAsync(ContentDialog dial ContentDialogResult result = await dialog.ShowAsync(); Window.AppWindow.TitleBar.PreferredHeightOption = TitleBarHeightOption.Tall; _dialogQueue.Remove(dialog); - if (!_dialogQueue.Any()) DialogHelper._showNextLoadingDialogIfPossible(); + if (!_dialogQueue.Any()) + DialogHelper._showNextLoadingDialogIfPossible(); return result; } catch (Exception e) @@ -216,29 +249,48 @@ public static async Task ShowIntegrityResult() { new TextBlock() { - Text = CoreTools.Translate("UniGetUI or some of its components are missing or corrupt.") - + " " + CoreTools.Translate("It is strongly recommended to reinstall UniGetUI to adress the situation."), + Text = + CoreTools.Translate( + "UniGetUI or some of its components are missing or corrupt." + ) + + " " + + CoreTools.Translate( + "It is strongly recommended to reinstall UniGetUI to adress the situation." + ), FontWeight = new FontWeight(600), TextWrapping = TextWrapping.Wrap, - Foreground = Application.Current.Resources["SystemControlErrorTextForegroundBrush"] as Brush, + Foreground = + Application.Current.Resources["SystemControlErrorTextForegroundBrush"] + as Brush, }, new TextBlock() { - Text = " ● " + CoreTools.Translate("Refer to the UniGetUI Logs to get more details regarding the affected file(s)"), + Text = + " ● " + + CoreTools.Translate( + "Refer to the UniGetUI Logs to get more details regarding the affected file(s)" + ), TextWrapping = TextWrapping.Wrap, }, new TextBlock() { - Text = " ● " + CoreTools.Translate("Integrity checks can be disabled from the Experimental Settings"), + Text = + " ● " + + CoreTools.Translate( + "Integrity checks can be disabled from the Experimental Settings" + ), TextWrapping = TextWrapping.Wrap, - } - } + }, + }, }, HorizontalAlignment = HorizontalAlignment.Stretch, - VerticalAlignment = VerticalAlignment.Stretch + VerticalAlignment = VerticalAlignment.Stretch, }; - string installerPath = Path.Join(CoreData.UniGetUIExecutableDirectory, "UniGetUI.Installer.exe"); + string installerPath = Path.Join( + CoreData.UniGetUIExecutableDirectory, + "UniGetUI.Installer.exe" + ); if (File.Exists(installerPath)) { dialog.SecondaryButtonText = CoreTools.Translate("Repair UniGetUI"); diff --git a/src/UniGetUI/Pages/DialogPages/DialogHelper_Operations.cs b/src/UniGetUI/Pages/DialogPages/DialogHelper_Operations.cs index e15e803ba7..f41b2e1b23 100644 --- a/src/UniGetUI/Pages/DialogPages/DialogHelper_Operations.cs +++ b/src/UniGetUI/Pages/DialogPages/DialogHelper_Operations.cs @@ -7,7 +7,10 @@ namespace UniGetUI.Pages.DialogPages; public static partial class DialogHelper { - public static async Task ShowOperationFailedDialog(AbstractOperation operation, OperationControl opControl) + public static async Task ShowOperationFailedDialog( + AbstractOperation operation, + OperationControl opControl + ) { ContentDialog dialog = DialogFactory.Create_AsWindow(true, true); dialog.Title = operation.Metadata.FailureTitle; diff --git a/src/UniGetUI/Pages/DialogPages/DialogHelper_Packages.cs b/src/UniGetUI/Pages/DialogPages/DialogHelper_Packages.cs index 8a39f1bed2..3966ee70e1 100644 --- a/src/UniGetUI/Pages/DialogPages/DialogHelper_Packages.cs +++ b/src/UniGetUI/Pages/DialogPages/DialogHelper_Packages.cs @@ -1,6 +1,4 @@ using System.Web; -using Windows.ApplicationModel.DataTransfer; -using Windows.UI.Text; using ABI.Microsoft.UI.Text; using Microsoft.UI; using Microsoft.UI.Xaml; @@ -19,6 +17,8 @@ using UniGetUI.PackageEngine.PackageLoader; using UniGetUI.PackageEngine.Serializable; using UniGetUI.Pages.SettingsPages.GeneralPages; +using Windows.ApplicationModel.DataTransfer; +using Windows.UI.Text; namespace UniGetUI.Pages.DialogPages; @@ -27,7 +27,10 @@ public static partial class DialogHelper /// /// Will update the Installation Options for the given Package, and will return whether the user choose to continue /// - public static async Task ShowInstallatOptions_Continue(IPackage package, OperationType operation) + public static async Task ShowInstallatOptions_Continue( + IPackage package, + OperationType operation + ) { var options = await InstallOptionsFactory.LoadForPackageAsync(package); var (dialogOptions, dialogResult) = await ShowInstallOptions(package, operation, options); @@ -39,7 +42,9 @@ public static async Task ShowInstallatOptions_Continue(IPackage package, O } else { - Logger.Debug($"Install options dialog for {package.Id} was canceled, no changes will be saved"); + Logger.Debug( + $"Install options dialog for {package.Id} was canceled, no changes will be saved" + ); } return dialogResult is ContentDialogResult.Secondary; @@ -48,10 +53,15 @@ public static async Task ShowInstallatOptions_Continue(IPackage package, O /// /// Will update the Installation Options for the given imported package /// - public static async Task ShowInstallOptions_ImportedPackage(ImportedPackage importedPackage) + public static async Task ShowInstallOptions_ImportedPackage( + ImportedPackage importedPackage + ) { - var (options, dialogResult) = - await ShowInstallOptions(importedPackage, OperationType.None, importedPackage.installation_options.Copy()); + var (options, dialogResult) = await ShowInstallOptions( + importedPackage, + OperationType.None, + importedPackage.installation_options.Copy() + ); if (dialogResult != ContentDialogResult.None) { @@ -65,7 +75,8 @@ public static async Task ShowInstallOptions_ImportedPackage private static async Task<(InstallOptions, ContentDialogResult)> ShowInstallOptions( IPackage package, OperationType operation, - InstallOptions options) + InstallOptions options + ) { InstallOptionsPage OptionsPage = new(package, operation, options); @@ -76,26 +87,36 @@ public static async Task ShowInstallOptions_ImportedPackage OperationType.Install => CoreTools.Translate("Install"), OperationType.Uninstall => CoreTools.Translate("Uninstall"), OperationType.Update => CoreTools.Translate("Update"), - _ => "" + _ => "", }; OptionsDialog.PrimaryButtonText = CoreTools.Translate("Save and close"); OptionsDialog.DefaultButton = ContentDialogButton.Secondary; // OptionsDialog.Title = CoreTools.Translate("{0} installation options", package.Name); OptionsDialog.Content = OptionsPage; - OptionsPage.Close += (_, _) => { OptionsDialog.Hide(); }; + OptionsPage.Close += (_, _) => + { + OptionsDialog.Hide(); + }; ContentDialogResult result = await ShowDialogAsync(OptionsDialog); return (await OptionsPage.GetUpdatedOptions(), result); } - public static async Task ShowPackageDetails(IPackage package, OperationType operation, TEL_InstallReferral referral) + public static async Task ShowPackageDetails( + IPackage package, + OperationType operation, + TEL_InstallReferral referral + ) { PackageDetailsPage DetailsPage = new(package, operation, referral); ContentDialog DetailsDialog = DialogFactory.Create_AsWindow(false); DetailsDialog.Content = DetailsPage; - DetailsPage.Close += (_, _) => { DetailsDialog.Hide(); }; + DetailsPage.Close += (_, _) => + { + DetailsDialog.Hide(); + }; await ShowDialogAsync(DetailsDialog); } @@ -131,12 +152,16 @@ public static async Task ConfirmUninstallation(IReadOnlyList pac dialog.DefaultButton = ContentDialogButton.Secondary; StackPanel p = new(); - p.Children.Add(new TextBlock - { - Text = CoreTools.Translate("Do you really want to uninstall the following {0} packages?", - packages.Count), - Margin = new Thickness(0, 0, 0, 5) - }); + p.Children.Add( + new TextBlock + { + Text = CoreTools.Translate( + "Do you really want to uninstall the following {0} packages?", + packages.Count + ), + Margin = new Thickness(0, 0, 0, 5), + } + ); string pkgList = ""; foreach (IPackage package in packages) @@ -144,8 +169,11 @@ public static async Task ConfirmUninstallation(IReadOnlyList pac pkgList += " ● " + package.Name + "\x0a"; } - TextBlock PackageListTextBlock = - new() { FontFamily = new FontFamily("Consolas"), Text = pkgList }; + TextBlock PackageListTextBlock = new() + { + FontFamily = new FontFamily("Consolas"), + Text = pkgList, + }; p.Children.Add(new ScrollView { Content = PackageListTextBlock, MaxHeight = 200 }); dialog.Content = p; @@ -158,11 +186,16 @@ public static void ShowSharedPackage_ThreadSafe(string id, string combinedSource var contents = combinedSourceName.Split(':'); string managerName = contents[0]; string sourceName = ""; - if (contents.Length > 1) sourceName = contents[1]; + if (contents.Length > 1) + sourceName = contents[1]; _ = GetPackageFromIdAndManager(id, managerName, sourceName, "LEGACY_COMBINEDSOURCE"); } - public static void ShowSharedPackage_ThreadSafe(string id, string managerName, string sourceName) + public static void ShowSharedPackage_ThreadSafe( + string id, + string managerName, + string sourceName + ) { MainApp.Instance.MainWindow.DispatcherQueue.TryEnqueue(() => { @@ -170,22 +203,37 @@ public static void ShowSharedPackage_ThreadSafe(string id, string managerName, s }); } - private static async Task GetPackageFromIdAndManager(string id, string managerName, string sourceName, string eventSource) + private static async Task GetPackageFromIdAndManager( + string id, + string managerName, + string sourceName, + string eventSource + ) { int loadingId = ShowLoadingDialog(CoreTools.Translate("Please wait...")); try { Window.Activate(); - var findResult = await Task.Run(() => DiscoverablePackagesLoader.Instance.GetPackageFromIdAndManager(id, managerName, sourceName)); + var findResult = await Task.Run(() => + DiscoverablePackagesLoader.Instance.GetPackageFromIdAndManager( + id, + managerName, + sourceName + ) + ); HideLoadingDialog(loadingId); - if (findResult.Item1 is null) throw new KeyNotFoundException(findResult.Item2 ?? "Unknown error"); + if (findResult.Item1 is null) + throw new KeyNotFoundException(findResult.Item2 ?? "Unknown error"); TelemetryHandler.SharedPackage(findResult.Item1, eventSource); - _ = ShowPackageDetails(findResult.Item1, OperationType.Install, TEL_InstallReferral.FROM_WEB_SHARE); - + _ = ShowPackageDetails( + findResult.Item1, + OperationType.Install, + TEL_InstallReferral.FROM_WEB_SHARE + ); } catch (Exception ex) { @@ -195,18 +243,25 @@ private static async Task GetPackageFromIdAndManager(string id, string managerNa var warningDialog = new ContentDialog { Title = CoreTools.Translate("Package not found"), - Content = CoreTools.Translate("An error occurred when attempting to show the package with Id {0}", id) + ":\n" + ex.Message, + Content = + CoreTools.Translate( + "An error occurred when attempting to show the package with Id {0}", + id + ) + + ":\n" + + ex.Message, CloseButtonText = CoreTools.Translate("Ok"), DefaultButton = ContentDialogButton.Close, - XamlRoot = MainApp.Instance.MainWindow.Content.XamlRoot // Ensure the dialog is shown in the correct context + XamlRoot = MainApp.Instance.MainWindow.Content.XamlRoot, // Ensure the dialog is shown in the correct context }; await ShowDialogAsync(warningDialog); - } } - public static async Task ShowBundleSecurityReport(Dictionary> packageReport) + public static async Task ShowBundleSecurityReport( + Dictionary> packageReport + ) { var dialog = DialogFactory.Create_AsWindow(true, true); Brush bad = new SolidColorBrush(Colors.PaleVioletRed); @@ -223,22 +278,26 @@ public static async Task ShowBundleSecurityReport(Dictionary { + a.Click += (_, _) => + { dialog.Hide(); Window.NavigationPage.OpenSettingsPage(typeof(Administrator)); }; @@ -320,23 +410,30 @@ public static void SharePackage(IPackage? package) DataTransferManager.As(); IntPtr result = interop.GetForWindow(hWnd, NativeHelpers._dtm_iid); - DataTransferManager dataTransferManager = WinRT.MarshalInterface - .FromAbi(result); + DataTransferManager dataTransferManager = + WinRT.MarshalInterface.FromAbi(result); dataTransferManager.DataRequested += (_, args) => { DataRequest dataPackage = args.Request; - Uri ShareUrl = new("https://marticliment.com/unigetui/share?" - + "name=" + HttpUtility.UrlEncode(package.Name) - + "&id=" + HttpUtility.UrlEncode(package.Id) - + "&sourceName=" + HttpUtility.UrlEncode(package.Source.Name) - + "&managerName=" + HttpUtility.UrlEncode(package.Manager.DisplayName)); + Uri ShareUrl = new( + "https://marticliment.com/unigetui/share?" + + "name=" + + HttpUtility.UrlEncode(package.Name) + + "&id=" + + HttpUtility.UrlEncode(package.Id) + + "&sourceName=" + + HttpUtility.UrlEncode(package.Source.Name) + + "&managerName=" + + HttpUtility.UrlEncode(package.Manager.DisplayName) + ); dataPackage.Data.SetWebLink(ShareUrl); dataPackage.Data.Properties.Title = "Sharing " + package.Name; dataPackage.Data.Properties.ApplicationName = "WingetUI"; dataPackage.Data.Properties.ContentSourceWebLink = ShareUrl; - dataPackage.Data.Properties.Description = "Share " + package.Name + " with your friends"; + dataPackage.Data.Properties.Description = + "Share " + package.Name + " with your friends"; dataPackage.Data.Properties.PackageFamilyName = "WingetUI"; }; @@ -352,9 +449,22 @@ public static async Task AskLoseChangesAndCreateBundle() RichTextBlock rtb = new(); var p = new Paragraph(); rtb.Blocks.Add(p); - p.Inlines.Add(new Run {Text = CoreTools.Translate("Are you sure you want to create a new package bundle? ")}); + p.Inlines.Add( + new Run + { + Text = CoreTools.Translate( + "Are you sure you want to create a new package bundle? " + ), + } + ); p.Inlines.Add(new LineBreak()); - p.Inlines.Add(new Run {Text = CoreTools.Translate("Any unsaved changes will be lost"), FontWeight = new FontWeight(600)}); + p.Inlines.Add( + new Run + { + Text = CoreTools.Translate("Any unsaved changes will be lost"), + FontWeight = new FontWeight(600), + } + ); ContentDialog dialog = DialogFactory.Create(); dialog.Title = CoreTools.Translate("Warning!"); @@ -365,5 +475,4 @@ public static async Task AskLoseChangesAndCreateBundle() return await DialogHelper.ShowDialogAsync(dialog) is ContentDialogResult.Primary; } - } diff --git a/src/UniGetUI/Pages/DialogPages/IgnoredUpdates.xaml b/src/UniGetUI/Pages/DialogPages/IgnoredUpdates.xaml index 2aae4a6535..fb029c64a4 100644 --- a/src/UniGetUI/Pages/DialogPages/IgnoredUpdates.xaml +++ b/src/UniGetUI/Pages/DialogPages/IgnoredUpdates.xaml @@ -1,173 +1,157 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + x:Class="UniGetUI.Interface.IgnoredUpdatesManager" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="using:UniGetUI.Interface" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:widgets="using:UniGetUI.Interface.Widgets" + MaxWidth="1100" + MaxHeight="500" + mc:Ignorable="d" +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/UniGetUI/Pages/DialogPages/IgnoredUpdates.xaml.cs b/src/UniGetUI/Pages/DialogPages/IgnoredUpdates.xaml.cs index 85d6712b15..f069dd5532 100644 --- a/src/UniGetUI/Pages/DialogPages/IgnoredUpdates.xaml.cs +++ b/src/UniGetUI/Pages/DialogPages/IgnoredUpdates.xaml.cs @@ -17,7 +17,6 @@ namespace UniGetUI.Interface /// /// An empty page that can be used on its own or navigated to within a Frame. /// - public sealed partial class IgnoredUpdatesManager : Page { public event EventHandler? Close; @@ -43,7 +42,7 @@ private void UpdateData() var rawIgnoredPackages = IgnoredUpdatesDatabase.GetDatabase(); - foreach (var(ignoredId, version) in rawIgnoredPackages) + foreach (var (ignoredId, version) in rawIgnoredPackages) { IPackageManager manager = PEInterface.WinGet; // Manager by default if (ManagerNameReference.ContainsKey(ignoredId.Split("\\")[0])) @@ -51,7 +50,14 @@ private void UpdateData() manager = ManagerNameReference[ignoredId.Split("\\")[0]]; } - ignoredPackages.Add(new IgnoredPackageEntry(ignoredId.Split("\\")[^1], version, manager, ignoredPackages)); + ignoredPackages.Add( + new IgnoredPackageEntry( + ignoredId.Split("\\")[^1], + version, + manager, + ignoredPackages + ) + ); } } @@ -68,7 +74,9 @@ private void CloseButton_Click(object sender, RoutedEventArgs e) Close?.Invoke(this, EventArgs.Empty); } - private void YesResetButton_Click(object sender, RoutedEventArgs e) => _ = _yesResetButton_Click(); + private void YesResetButton_Click(object sender, RoutedEventArgs e) => + _ = _yesResetButton_Click(); + private async Task _yesResetButton_Click() { foreach (IgnoredPackageEntry package in ignoredPackages.ToArray()) @@ -92,12 +100,20 @@ public class IgnoredPackageEntry public string NewVersion { get; } public IPackageManager Manager { get; } private ObservableCollection List { get; } - public IgnoredPackageEntry(string id, string version, IPackageManager manager, ObservableCollection list) + + public IgnoredPackageEntry( + string id, + string version, + IPackageManager manager, + ObservableCollection list + ) { Id = id; - if (manager is WinGet && id.Contains('.')) Name = String.Join(' ', id.Split('.')[1..]); - else Name = CoreTools.FormatAsName(id); + if (manager is WinGet && id.Contains('.')) + Name = String.Join(' ', id.Split('.')[1..]); + else + Name = CoreTools.FormatAsName(id); if (version == "*") { @@ -108,16 +124,23 @@ public IgnoredPackageEntry(string id, string version, IPackageManager manager, O Version = version; } - string CurrentVersion = InstalledPackagesLoader.Instance.GetPackageForId(id)?.VersionString ?? "Unknown"; + string CurrentVersion = + InstalledPackagesLoader.Instance.GetPackageForId(id)?.VersionString ?? "Unknown"; - if (UpgradablePackagesLoader.Instance.IgnoredPackages.TryGetValue(Id, out IPackage? package) - && package.NewVersionString != package.VersionString) + if ( + UpgradablePackagesLoader.Instance.IgnoredPackages.TryGetValue( + Id, + out IPackage? package + ) + && package.NewVersionString != package.VersionString + ) { NewVersion = CurrentVersion + " \u27a4 " + package.NewVersionString; } else if (CurrentVersion != "Unknown") { - NewVersion = CoreTools.Translate("Up to date") + $" ({CurrentVersion})";; + NewVersion = CoreTools.Translate("Up to date") + $" ({CurrentVersion})"; + ; } else { @@ -128,8 +151,7 @@ public IgnoredPackageEntry(string id, string version, IPackageManager manager, O List = list; } - public void RemoveFromIgnoredUpdates() - => _ = RemoveFromIgnoredUpdatesAsync(); + public void RemoveFromIgnoredUpdates() => _ = RemoveFromIgnoredUpdatesAsync(); public async Task RemoveFromIgnoredUpdatesAsync() { @@ -137,8 +159,13 @@ public async Task RemoveFromIgnoredUpdatesAsync() await Task.Run(() => IgnoredUpdatesDatabase.Remove(ignoredId)); // If possible, add the package to the software updates tab again - if (UpgradablePackagesLoader.Instance.IgnoredPackages.TryRemove(Id, out IPackage? nativePackage) - && nativePackage.NewVersionString != nativePackage.VersionString) + if ( + UpgradablePackagesLoader.Instance.IgnoredPackages.TryRemove( + Id, + out IPackage? nativePackage + ) + && nativePackage.NewVersionString != nativePackage.VersionString + ) { await UpgradablePackagesLoader.Instance.AddForeign(nativePackage); } diff --git a/src/UniGetUI/Pages/DialogPages/InstallOptions_Manager.xaml b/src/UniGetUI/Pages/DialogPages/InstallOptions_Manager.xaml index 815f3ff3d8..b29e83cb4e 100644 --- a/src/UniGetUI/Pages/DialogPages/InstallOptions_Manager.xaml +++ b/src/UniGetUI/Pages/DialogPages/InstallOptions_Manager.xaml @@ -1,235 +1,233 @@ + x:Class="UniGetUI.Pages.DialogPages.InstallOptions_Manager" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:controls="using:CommunityToolkit.WinUI.Controls" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="using:UniGetUI.Pages.DialogPages" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:widgets="using:UniGetUI.Interface.Widgets" + mc:Ignorable="d" +> + + + - - - + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + diff --git a/src/UniGetUI/Pages/DialogPages/InstallOptions_Package.xaml.cs b/src/UniGetUI/Pages/DialogPages/InstallOptions_Package.xaml.cs index 30c096e633..648cd32448 100644 --- a/src/UniGetUI/Pages/DialogPages/InstallOptions_Package.xaml.cs +++ b/src/UniGetUI/Pages/DialogPages/InstallOptions_Package.xaml.cs @@ -36,7 +36,9 @@ public sealed partial class InstallOptionsPage : Page private readonly ObservableCollection _runningProcesses = new(); public ObservableCollection SuggestedProcesses { get; set; } = new(); - public InstallOptionsPage(IPackage package, InstallOptions options) : this(package, OperationType.None, options) { } + public InstallOptionsPage(IPackage package, InstallOptions options) + : this(package, OperationType.None, options) { } + public InstallOptionsPage(IPackage package, OperationType operation, InstallOptions options) { Package = package; @@ -44,31 +46,42 @@ public InstallOptionsPage(IPackage package, OperationType operation, InstallOpti Operation = operation; Options = options; - KillProcessesThatWontDie.IsChecked = Settings.Get(Settings.K.KillProcessesThatRefuseToDie); + KillProcessesThatWontDie.IsChecked = Settings.Get( + Settings.K.KillProcessesThatRefuseToDie + ); ProfileComboBox.Items.Add(CoreTools.Translate("Install")); ProfileComboBox.Items.Add(CoreTools.Translate("Update")); ProfileComboBox.Items.Add(CoreTools.Translate("Uninstall")); - ProfileComboBox.SelectedIndex = operation switch { OperationType.Update => 1, OperationType.Uninstall => 2, _ => 0 }; + ProfileComboBox.SelectedIndex = operation switch + { + OperationType.Update => 1, + OperationType.Uninstall => 2, + _ => 0, + }; ProfileComboBox.SelectionChanged += (_, _) => { - EnableDisableControls(ProfileComboBox.SelectedIndex switch - { - 1 => OperationType.Update, - 2 => OperationType.Uninstall, - _ => OperationType.Install, - }); + EnableDisableControls( + ProfileComboBox.SelectedIndex switch + { + 1 => OperationType.Update, + 2 => OperationType.Uninstall, + _ => OperationType.Install, + } + ); }; FollowGlobalOptionsSwitch.IsOn = !options.OverridesNextLevelOpts; FollowGlobalOptionsSwitch.Toggled += (_, _) => { - EnableDisableControls(ProfileComboBox.SelectedIndex switch - { - 1 => OperationType.Update, - 2 => OperationType.Uninstall, - _ => OperationType.Install, - }); + EnableDisableControls( + ProfileComboBox.SelectedIndex switch + { + 1 => OperationType.Update, + 2 => OperationType.Uninstall, + _ => OperationType.Install, + } + ); }; var iconSource = new BitmapImage() @@ -76,8 +89,7 @@ public InstallOptionsPage(IPackage package, OperationType operation, InstallOpti UriSource = package.GetIconUrl(), DecodePixelHeight = 32, DecodePixelWidth = 32, - DecodePixelType = - DecodePixelType.Logical + DecodePixelType = DecodePixelType.Logical, }; PackageIcon.Source = iconSource; @@ -87,12 +99,21 @@ async Task LoadImage() } _ = LoadImage(); DialogTitle.Text = CoreTools.Translate("{0} installation options", package.Name); - PlaceholderText.Text = CoreTools.Translate("{0} Install options are currently locked because {0} follows the default install options.", package.Name); - - KillProcessesLabel.Text = CoreTools.Translate("Select the processes that should be closed before this package is installed, updated or uninstalled."); - KillProcessesBox.PlaceholderText = CoreTools.Translate("Write here the process names here, separated by commas (,)"); - - packageInstallLocation = Package.Manager.DetailsHelper.GetInstallLocation(package) ?? CoreTools.Translate("Unset or unknown"); + PlaceholderText.Text = CoreTools.Translate( + "{0} Install options are currently locked because {0} follows the default install options.", + package.Name + ); + + KillProcessesLabel.Text = CoreTools.Translate( + "Select the processes that should be closed before this package is installed, updated or uninstalled." + ); + KillProcessesBox.PlaceholderText = CoreTools.Translate( + "Write here the process names here, separated by commas (,)" + ); + + packageInstallLocation = + Package.Manager.DetailsHelper.GetInstallLocation(package) + ?? CoreTools.Translate("Unset or unknown"); AdminCheckBox.IsChecked = Options.RunAsAdministrator; InteractiveCheckBox.IsChecked = Options.InteractiveInstallation; @@ -116,13 +137,14 @@ async Task LoadImage() VersionComboBox.SelectionChanged += (_, _) => { - IgnoreUpdatesCheckbox.IsChecked = - !(new [] + IgnoreUpdatesCheckbox.IsChecked = !( + new[] { CoreTools.Translate("Latest"), CoreTools.Translate("PreRelease"), - "" - }.Contains(VersionComboBox.SelectedValue.ToString())); + "", + }.Contains(VersionComboBox.SelectedValue.ToString()) + ); }; AutoUpdatePackageCheckbox.IsChecked = Options.AutoUpdatePackage; @@ -152,26 +174,32 @@ async Task LoadImage() ScopeCombo.SelectedIndex = 0; if (package.Manager.Capabilities.SupportsCustomScopes) { - ScopeCombo.Items.Add(CoreTools.Translate(CommonTranslations.ScopeNames[PackageScope.Local])); + ScopeCombo.Items.Add( + CoreTools.Translate(CommonTranslations.ScopeNames[PackageScope.Local]) + ); if (Options.InstallationScope == PackageScope.Local) { ScopeCombo.SelectedValue = CommonTranslations.ScopeNames[PackageScope.Local]; } - ScopeCombo.Items.Add(CoreTools.Translate(CommonTranslations.ScopeNames[PackageScope.Global])); + ScopeCombo.Items.Add( + CoreTools.Translate(CommonTranslations.ScopeNames[PackageScope.Global]) + ); if (Options.InstallationScope == PackageScope.Global) { ScopeCombo.SelectedValue = CommonTranslations.ScopeNames[PackageScope.Global]; } } - foreach(var p in Options.KillBeforeOperation) + foreach (var p in Options.KillBeforeOperation) { ProcessesToKill.Add(new(p)); } - if (Options.CustomInstallLocation == "") CustomInstallLocation.Text = packageInstallLocation; - else CustomInstallLocation.Text = Options.CustomInstallLocation; + if (Options.CustomInstallLocation == "") + CustomInstallLocation.Text = packageInstallLocation; + else + CustomInstallLocation.Text = Options.CustomInstallLocation; CustomParameters1.Text = string.Join(' ', Options.CustomParameters_Install); CustomParameters2.Text = string.Join(' ', Options.CustomParameters_Update); @@ -196,17 +224,20 @@ async Task LoadImage() private async Task _loadProcesses() { var processNames = await Task.Run(() => - Process.GetProcesses().Select(p => p.ProcessName).Distinct().ToList()); + Process.GetProcesses().Select(p => p.ProcessName).Distinct().ToList() + ); _runningProcesses.Clear(); foreach (var name in processNames) { - if(name.Any()) _runningProcesses.Add(new(name + ".exe")); + if (name.Any()) + _runningProcesses.Add(new(name + ".exe")); } } + private void EnableDisableControls(OperationType operation) { - if(FollowGlobalOptionsSwitch.IsOn) + if (FollowGlobalOptionsSwitch.IsOn) { OptionsPanel0.Opacity = 0.3; SettingsSwitchPresenter.Opacity = 0.3; @@ -228,8 +259,16 @@ private void EnableDisableControls(OperationType operation) operation is not OperationType.Uninstall && Package.Manager.Capabilities.CanSkipIntegrityChecks; - UninstallPreviousOnUpdate.IsEnabled = Package.Manager.Capabilities.CanUninstallPreviousVersionsAfterUpdate; - UninstallPreviousOnUpdate.Visibility = Package.Manager.Capabilities.CanUninstallPreviousVersionsAfterUpdate? Visibility.Visible: Visibility.Collapsed; + UninstallPreviousOnUpdate.IsEnabled = Package + .Manager + .Capabilities + .CanUninstallPreviousVersionsAfterUpdate; + UninstallPreviousOnUpdate.Visibility = Package + .Manager + .Capabilities + .CanUninstallPreviousVersionsAfterUpdate + ? Visibility.Visible + : Visibility.Collapsed; ArchitectureComboBox.IsEnabled = operation is not OperationType.Uninstall @@ -237,7 +276,10 @@ operation is not OperationType.Uninstall VersionComboBox.IsEnabled = operation is OperationType.Install or OperationType.None - && (Package.Manager.Capabilities.SupportsCustomVersions || Package.Manager.Capabilities.SupportsPreRelease); + && ( + Package.Manager.Capabilities.SupportsCustomVersions + || Package.Manager.Capabilities.SupportsPreRelease + ); ScopeCombo.IsEnabled = Package.Manager.Capabilities.SupportsCustomScopes; ResetDir.IsEnabled = Package.Manager.Capabilities.SupportsCustomLocations; SelectDir.IsEnabled = Package.Manager.Capabilities.SupportsCustomLocations; @@ -270,8 +312,12 @@ operation is OperationType.Install or OperationType.None PeUniLabel.Opacity = IsPrePostOpEnabled ? 1 : 0.5; PoUniLabel.Opacity = IsPrePostOpEnabled ? 1 : 0.5; CustomCommandsHeaderExplainer.Opacity = IsPrePostOpEnabled ? 1 : 0.5; - GoToPrePostSettings.Visibility = IsPrePostOpEnabled ? Visibility.Collapsed : Visibility.Visible; - PrePostDisabled.Visibility = IsPrePostOpEnabled ? Visibility.Collapsed : Visibility.Visible; + GoToPrePostSettings.Visibility = IsPrePostOpEnabled + ? Visibility.Collapsed + : Visibility.Visible; + PrePostDisabled.Visibility = IsPrePostOpEnabled + ? Visibility.Collapsed + : Visibility.Visible; _ = GenerateCommand(); } @@ -285,7 +331,9 @@ private async Task LoadVersions() { VersionComboBox.IsEnabled = false; - IReadOnlyList versions = await Task.Run(() => Package.Manager.DetailsHelper.GetVersions(Package)); + IReadOnlyList versions = await Task.Run(() => + Package.Manager.DetailsHelper.GetVersions(Package) + ); foreach (string ver in versions) { VersionComboBox.Items.Add(ver); @@ -296,8 +344,12 @@ private async Task LoadVersions() } IgnoreUpdatesCheckbox.IsChecked = await Package.HasUpdatesIgnoredAsync(); - VersionComboBox.IsEnabled = Operation is OperationType.Install or OperationType.None - && (Package.Manager.Capabilities.SupportsCustomVersions || Package.Manager.Capabilities.SupportsPreRelease); + VersionComboBox.IsEnabled = + Operation is OperationType.Install or OperationType.None + && ( + Package.Manager.Capabilities.SupportsCustomVersions + || Package.Manager.Capabilities.SupportsPreRelease + ); VersionProgress.Visibility = Visibility.Collapsed; } @@ -307,7 +359,8 @@ public async Task GetUpdatedOptions(bool updateDetachedOptions = options.RunAsAdministrator = AdminCheckBox?.IsChecked ?? false; options.InteractiveInstallation = InteractiveCheckBox?.IsChecked ?? false; options.SkipHashCheck = HashCheckbox?.IsChecked ?? false; - options.UninstallPreviousVersionsOnUpdate = UninstallPreviousOnUpdate?.IsChecked ?? false; + options.UninstallPreviousVersionsOnUpdate = + UninstallPreviousOnUpdate?.IsChecked ?? false; options.OverridesNextLevelOpts = !FollowGlobalOptionsSwitch.IsOn; options.AutoUpdatePackage = AutoUpdatePackageCheckbox.IsChecked ?? false; @@ -325,13 +378,16 @@ public async Task GetUpdatedOptions(bool updateDetachedOptions = options.InstallationScope = value; } - if (CustomInstallLocation.Text == packageInstallLocation) options.CustomInstallLocation = ""; - else options.CustomInstallLocation = CustomInstallLocation.Text; + if (CustomInstallLocation.Text == packageInstallLocation) + options.CustomInstallLocation = ""; + else + options.CustomInstallLocation = CustomInstallLocation.Text; options.CustomParameters_Install = CustomParameters1.Text.Split(' ').ToList(); options.CustomParameters_Update = CustomParameters2.Text.Split(' ').ToList(); options.CustomParameters_Uninstall = CustomParameters3.Text.Split(' ').ToList(); - options.PreRelease = VersionComboBox.SelectedValue.ToString() == CoreTools.Translate("PreRelease"); + options.PreRelease = + VersionComboBox.SelectedValue.ToString() == CoreTools.Translate("PreRelease"); options.PreInstallCommand = PreInstallCommandBox.Text; options.PostInstallCommand = PostInstallCommandBox.Text; @@ -344,9 +400,13 @@ public async Task GetUpdatedOptions(bool updateDetachedOptions = options.AbortOnPreUninstallFail = AbortUniFailedCheck.IsChecked ?? true; options.KillBeforeOperation.Clear(); - foreach(var p in ProcessesToKill) options.KillBeforeOperation.Add(p.Name); + foreach (var p in ProcessesToKill) + options.KillBeforeOperation.Add(p.Name); - if (VersionComboBox.SelectedValue.ToString() != CoreTools.Translate("PreRelease") && VersionComboBox.SelectedValue.ToString() != CoreTools.Translate("Latest")) + if ( + VersionComboBox.SelectedValue.ToString() != CoreTools.Translate("PreRelease") + && VersionComboBox.SelectedValue.ToString() != CoreTools.Translate("Latest") + ) { options.Version = VersionComboBox.SelectedValue.ToString() ?? ""; } @@ -358,7 +418,10 @@ public async Task GetUpdatedOptions(bool updateDetachedOptions = if (updateDetachedOptions) { - Settings.Set(Settings.K.KillProcessesThatRefuseToDie, KillProcessesThatWontDie.IsChecked ?? false); + Settings.Set( + Settings.K.KillProcessesThatRefuseToDie, + KillProcessesThatWontDie.IsChecked ?? false + ); if (IgnoreUpdatesCheckbox?.IsChecked ?? false) { @@ -377,7 +440,9 @@ public async Task GetUpdatedOptions(bool updateDetachedOptions = private void SelectDir_Click(object sender, RoutedEventArgs e) { - ExternalLibraries.Pickers.FolderPicker openPicker = new(MainApp.Instance.MainWindow.GetWindowHandle()); + ExternalLibraries.Pickers.FolderPicker openPicker = new( + MainApp.Instance.MainWindow.GetWindowHandle() + ); string folder = openPicker.Show(); if (folder != string.Empty) { @@ -397,19 +462,36 @@ private void CloseButton_Click(object sender, RoutedEventArgs e) Close?.Invoke(this, EventArgs.Empty); } - private void CustomParameters_TextChanged(object sender, TextChangedEventArgs e) => _ = GenerateCommand(); - private void ScopeCombo_SelectionChanged(object sender, SelectionChangedEventArgs e) => _ = GenerateCommand(); - private void VersionComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) => _ = GenerateCommand(); + private void CustomParameters_TextChanged(object sender, TextChangedEventArgs e) => + _ = GenerateCommand(); + + private void ScopeCombo_SelectionChanged(object sender, SelectionChangedEventArgs e) => + _ = GenerateCommand(); + + private void VersionComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) => + _ = GenerateCommand(); + private void AdminCheckBox_Click(object sender, RoutedEventArgs e) => _ = GenerateCommand(); - private void InteractiveCheckBox_Click(object sender, RoutedEventArgs e) => _ = GenerateCommand(); + + private void InteractiveCheckBox_Click(object sender, RoutedEventArgs e) => + _ = GenerateCommand(); + private void HashCheckbox_Click(object sender, RoutedEventArgs e) => _ = GenerateCommand(); - private void ArchitectureComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) => _ = GenerateCommand(); + + private void ArchitectureComboBox_SelectionChanged( + object sender, + SelectionChangedEventArgs e + ) => _ = GenerateCommand(); private async Task GenerateCommand() { - if (!UiLoaded) return; + if (!UiLoaded) + return; InstallOptions options = await GetUpdatedOptions(updateDetachedOptions: false); - options = await InstallOptionsFactory.LoadApplicableAsync(this.Package, overridePackageOptions: options); + options = await InstallOptionsFactory.LoadApplicableAsync( + this.Package, + overridePackageOptions: options + ); var op = ProfileComboBox.SelectedIndex switch { @@ -417,13 +499,19 @@ private async Task GenerateCommand() 2 => OperationType.Uninstall, _ => OperationType.Install, }; - var commandline = await Task.Run(() => Package.Manager.OperationHelper.GetParameters(Package, options, op)); - CommandBox.Text = Package.Manager.Properties.ExecutableFriendlyName + " " + string.Join(" ", commandline); + var commandline = await Task.Run(() => + Package.Manager.OperationHelper.GetParameters(Package, options, op) + ); + CommandBox.Text = + Package.Manager.Properties.ExecutableFriendlyName + + " " + + string.Join(" ", commandline); } private void LayoutGrid_SizeChanged(object sender, SizeChangedEventArgs e) { - if(LayoutGrid.ActualSize.Y > 1 && LayoutGrid.ActualSize.Y < double.PositiveInfinity) MaxHeight = LayoutGrid.ActualSize.Y; + if (LayoutGrid.ActualSize.Y > 1 && LayoutGrid.ActualSize.Y < double.PositiveInfinity) + MaxHeight = LayoutGrid.ActualSize.Y; } private void UnlockSettingsButton_Click(object sender, RoutedEventArgs e) @@ -443,18 +531,28 @@ private void GoToSecureSettings_Click(object sender, RoutedEventArgs e) MainApp.Instance.MainWindow.NavigationPage.OpenSettingsPage(typeof(Administrator)); } - private void KillProcessesBox_TokenItemAdding(TokenizingTextBox sender, TokenItemAddingEventArgs args) + private void KillProcessesBox_TokenItemAdding( + TokenizingTextBox sender, + TokenItemAddingEventArgs args + ) { - args.Item = _runningProcesses.FirstOrDefault((item) => item.Name.Contains(args.TokenText)); - if(args.Item is null) + args.Item = _runningProcesses.FirstOrDefault( + (item) => item.Name.Contains(args.TokenText) + ); + if (args.Item is null) { string text = args.TokenText; - if (!text.EndsWith(".exe")) text += ".exe"; + if (!text.EndsWith(".exe")) + text += ".exe"; args.Item = new IOP_Proc(text); } } - private void KillProcessesBox_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args) => _ = _killProcessesBox_TextChanged(); + private void KillProcessesBox_TextChanged( + AutoSuggestBox sender, + AutoSuggestBoxTextChangedEventArgs args + ) => _ = _killProcessesBox_TextChanged(); + private async Task _killProcessesBox_TextChanged() { var text = KillProcessesBox.Text; @@ -468,7 +566,9 @@ private async Task _killProcessesBox_TextChanged() if (!text.EndsWith(".exe")) text = text.Trim() + ".exe"; SuggestedProcesses.Add(new(text)); - foreach (var item in _runningProcesses.Where(x => x.Name.Contains(KillProcessesBox.Text))) + foreach ( + var item in _runningProcesses.Where(x => x.Name.Contains(KillProcessesBox.Text)) + ) { SuggestedProcesses.Add(item); } @@ -477,7 +577,8 @@ private async Task _killProcessesBox_TextChanged() private void SettingsTabBar_SelectionChanged(object sender, SelectionChangedEventArgs e) { - CommandLineViewBox.Visibility = SettingsTabBar.SelectedIndex < 3 ? Visibility.Visible : Visibility.Collapsed; + CommandLineViewBox.Visibility = + SettingsTabBar.SelectedIndex < 3 ? Visibility.Visible : Visibility.Collapsed; } public void HideCloseButton() @@ -495,6 +596,7 @@ internal void HideHeaderBar() public class IOP_Proc { public readonly string Name; + public IOP_Proc(string name) { Name = name; diff --git a/src/UniGetUI/Pages/DialogPages/OperationFailedDialog.xaml b/src/UniGetUI/Pages/DialogPages/OperationFailedDialog.xaml index ab0b24d192..ad937f1f9b 100644 --- a/src/UniGetUI/Pages/DialogPages/OperationFailedDialog.xaml +++ b/src/UniGetUI/Pages/DialogPages/OperationFailedDialog.xaml @@ -1,50 +1,50 @@ - - - - - - - - - - - - - - - - - - + x:Class="UniGetUI.Pages.DialogPages.OperationFailedDialog" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="using:UniGetUI.Pages.DialogPages" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:widgets="using:UniGetUI.Interface.Widgets" + MaxWidth="800" + MaxHeight="600" + mc:Ignorable="d" +> + + + + + + + + + + + + + + + + + diff --git a/src/UniGetUI/Pages/DialogPages/OperationFailedDialog.xaml.cs b/src/UniGetUI/Pages/DialogPages/OperationFailedDialog.xaml.cs index 75f5c611fa..f55db0948e 100644 --- a/src/UniGetUI/Pages/DialogPages/OperationFailedDialog.xaml.cs +++ b/src/UniGetUI/Pages/DialogPages/OperationFailedDialog.xaml.cs @@ -11,6 +11,7 @@ // and more about our project templates, see: http://aka.ms/winui-project-info. namespace UniGetUI.Pages.DialogPages; + /// /// An empty page that can be used on its own or navigated to within a Frame. /// @@ -26,11 +27,16 @@ public OperationFailedDialog(AbstractOperation operation, OperationControl opCon { this.InitializeComponent(); - errorColor ??= (SolidColorBrush)Application.Current.Resources["SystemFillColorCriticalBrush"]; - debugColor ??= (SolidColorBrush)Application.Current.Resources["SystemFillColorNeutralBrush"]; + errorColor ??= (SolidColorBrush) + Application.Current.Resources["SystemFillColorCriticalBrush"]; + debugColor ??= (SolidColorBrush) + Application.Current.Resources["SystemFillColorNeutralBrush"]; - headerContent.Text = $"{operation.Metadata.FailureMessage}.\n" - + CoreTools.Translate("Please see the Command-line Output or refer to the Operation History for further information about the issue."); + headerContent.Text = + $"{operation.Metadata.FailureMessage}.\n" + + CoreTools.Translate( + "Please see the Command-line Output or refer to the Operation History for further information about the issue." + ); par = new Paragraph(); foreach (var line in operation.GetOutput()) diff --git a/src/UniGetUI/Pages/DialogPages/OperationLiveLogPage.xaml b/src/UniGetUI/Pages/DialogPages/OperationLiveLogPage.xaml index cfc5a25662..955a520c44 100644 --- a/src/UniGetUI/Pages/DialogPages/OperationLiveLogPage.xaml +++ b/src/UniGetUI/Pages/DialogPages/OperationLiveLogPage.xaml @@ -1,39 +1,43 @@ - - - - - - - - - - - - + x:Class="UniGetUI.Pages.DialogPages.OperationLiveLogPage" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="using:UniGetUI.Pages.DialogPages" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:widgets="using:UniGetUI.Interface.Widgets" + Background="Transparent" + mc:Ignorable="d" +> + + + + + + + + + + + + diff --git a/src/UniGetUI/Pages/DialogPages/OperationLiveLogPage.xaml.cs b/src/UniGetUI/Pages/DialogPages/OperationLiveLogPage.xaml.cs index 82c0fb3238..9b65eb7520 100644 --- a/src/UniGetUI/Pages/DialogPages/OperationLiveLogPage.xaml.cs +++ b/src/UniGetUI/Pages/DialogPages/OperationLiveLogPage.xaml.cs @@ -8,6 +8,7 @@ // and more about our project templates, see: http://aka.ms/winui-project-info. namespace UniGetUI.Pages.DialogPages; + /// /// An empty page that can be used on its own or navigated to within a Frame. /// @@ -22,8 +23,10 @@ public sealed partial class OperationLiveLogPage : Page public OperationLiveLogPage(AbstractOperation operation) { this.InitializeComponent(); - errorColor ??= (SolidColorBrush)Application.Current.Resources["SystemFillColorCriticalBrush"]; - debugColor ??= (SolidColorBrush)Application.Current.Resources["SystemFillColorNeutralBrush"]; + errorColor ??= (SolidColorBrush) + Application.Current.Resources["SystemFillColorCriticalBrush"]; + debugColor ??= (SolidColorBrush) + Application.Current.Resources["SystemFillColorNeutralBrush"]; par = new Paragraph() { LineHeight = 4.8 }; TextBlock.Blocks.Clear(); TextBlock.Blocks.Add(par); @@ -47,37 +50,36 @@ public OperationLiveLogPage(AbstractOperation operation) public void AddLine_ThreadSafe(object? sender, (string, AbstractOperation.LineType) line) => MainApp.Dispatcher.TryEnqueue(() => - { - if (LastLineWasProgress) par.Inlines.RemoveAt(par.Inlines.Count - 1); - - LastLineWasProgress = false; - if (line.Item2 is AbstractOperation.LineType.Information) - { - par.Inlines.Add(new Run { Text = line.Item1 + "\x0a" }); - } - else if (line.Item2 is AbstractOperation.LineType.VerboseDetails) - { - par.Inlines.Add(new Run { Text = line.Item1 + "\x0a", Foreground = debugColor }); - } - else if (line.Item2 is AbstractOperation.LineType.Error) { - par.Inlines.Add(new Run { Text = line.Item1 + "\x0a", Foreground = errorColor }); - } - else - { - LastLineWasProgress = true; - par.Inlines.Add(new Run { Text = line.Item1 + "\x0a" }); - } + if (LastLineWasProgress) + par.Inlines.RemoveAt(par.Inlines.Count - 1); - this.TextBlock.Blocks.Clear(); - this.TextBlock.Blocks.Add(par); - this.ScrollBar.ScrollToVerticalOffset(this.ScrollBar.ScrollableHeight); + LastLineWasProgress = false; + if (line.Item2 is AbstractOperation.LineType.Information) + { + par.Inlines.Add(new Run { Text = line.Item1 + "\x0a" }); + } + else if (line.Item2 is AbstractOperation.LineType.VerboseDetails) + { + par.Inlines.Add(new Run { Text = line.Item1 + "\x0a", Foreground = debugColor }); + } + else if (line.Item2 is AbstractOperation.LineType.Error) + { + par.Inlines.Add(new Run { Text = line.Item1 + "\x0a", Foreground = errorColor }); + } + else + { + LastLineWasProgress = true; + par.Inlines.Add(new Run { Text = line.Item1 + "\x0a" }); + } - }); + this.TextBlock.Blocks.Clear(); + this.TextBlock.Blocks.Add(par); + this.ScrollBar.ScrollToVerticalOffset(this.ScrollBar.ScrollableHeight); + }); private void CloseButton_Click(object sender, RoutedEventArgs e) { Close?.Invoke(this, EventArgs.Empty); } } - diff --git a/src/UniGetUI/Pages/DialogPages/PackageDetailsPage.xaml b/src/UniGetUI/Pages/DialogPages/PackageDetailsPage.xaml index 74737375fe..0cf1db206c 100644 --- a/src/UniGetUI/Pages/DialogPages/PackageDetailsPage.xaml +++ b/src/UniGetUI/Pages/DialogPages/PackageDetailsPage.xaml @@ -1,352 +1,347 @@ + x:Class="UniGetUI.Interface.Dialogs.PackageDetailsPage" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="using:UniGetUI.Interface.Dialogs" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:toolkit="using:CommunityToolkit.WinUI.Controls" + xmlns:widgets="using:UniGetUI.Interface.Widgets" + xmlns:xaml="using:Microsoft.UI.Xaml.Controls" + mc:Ignorable="d" +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - HOMEPAGE_LABEL: - Helo - - PUBLISHER_LABEL: - Helo - - AUTHOR_LABEL: - Helo - - LICENSE_LABEL: - Helo - (Helo) - - Update date: - Helo - - SOURCE_LABEL: - Helo - - + + + + + + + HOMEPAGE_LABEL: + Helo + + PUBLISHER_LABEL: + Helo + + AUTHOR_LABEL: + Helo + + LICENSE_LABEL: + Helo + (Helo) + + Update date: + Helo + + SOURCE_LABEL: + Helo + + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - + - - - - + + + + + + + + + + + + + + + + + - - - - Package Id: - Helo - - Manifest: : - Helo - - (Installed) Version: - Helo - - - Installer type: - Helo - - Installer Url: - (Helo) - - Installer hash: - Helo - - + + + + Package Id: + Helo + + Manifest: : + Helo + + (Installed) Version: + Helo + + + Installer type: + Helo + + Installer Url: + (Helo) + + Installer hash: + Helo + + Download installer - - - - Dependencies: - - - - - Release Notes: - Helo - - Release notes Url: - (Helo) - - - - - - - - + + + + Dependencies: + + + + + Release Notes: + Helo + + Release notes Url: + (Helo) + + + + + + + diff --git a/src/UniGetUI/Pages/DialogPages/PackageDetailsPage.xaml.cs b/src/UniGetUI/Pages/DialogPages/PackageDetailsPage.xaml.cs index 15c7a724e5..963db2f08a 100644 --- a/src/UniGetUI/Pages/DialogPages/PackageDetailsPage.xaml.cs +++ b/src/UniGetUI/Pages/DialogPages/PackageDetailsPage.xaml.cs @@ -1,21 +1,21 @@ using System.Collections.ObjectModel; -using Windows.UI; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Documents; using Microsoft.UI.Xaml.Media; using Microsoft.UI.Xaml.Media.Imaging; -using Microsoft.UI.Xaml.Documents; -using Windows.UI.Text; +using UniGetUI.Core.Logging; using UniGetUI.Core.Tools; +using UniGetUI.Interface.Enums; +using UniGetUI.Interface.Telemetry; +using UniGetUI.Interface.Widgets; using UniGetUI.PackageEngine; using UniGetUI.PackageEngine.Enums; using UniGetUI.PackageEngine.Interfaces; using UniGetUI.PackageEngine.PackageClasses; -using UniGetUI.Interface.Enums; -using UniGetUI.Interface.Telemetry; -using UniGetUI.Interface.Widgets; -using UniGetUI.Core.Logging; using UniGetUI.Pages.DialogPages; +using Windows.UI; +using Windows.UI.Text; // To learn more about WinUI, the WinUI project structure, // and more about our project templates, see: http://aka.ms/winui-project-info. @@ -43,13 +43,18 @@ private enum LayoutMode { Normal, Wide, - Unset + Unset, } private readonly TEL_InstallReferral InstallReferral; private LayoutMode __layout_mode = LayoutMode.Unset; - public PackageDetailsPage(IPackage package, OperationType role, TEL_InstallReferral referral) + + public PackageDetailsPage( + IPackage package, + OperationType role, + TEL_InstallReferral referral + ) { if (role == OperationType.None) role = OperationType.Install; @@ -97,7 +102,13 @@ public PackageDetailsPage(IPackage package, OperationType role, TEL_InstallRefer SetTextToItem(UpdateDate_Content, LoadingString); SetTextToItem(Dependencies_Label, CoreTools.Translate("Dependencies:") + " "); DependenciesParagraph.Inlines.Clear(); - DependenciesParagraph.Inlines.Add(new Run() { Text = LoadingString, Foreground = new SolidColorBrush(color: Color.FromArgb(255, 127, 127, 127)), }); + DependenciesParagraph.Inlines.Add( + new Run() + { + Text = LoadingString, + Foreground = new SolidColorBrush(color: Color.FromArgb(255, 127, 127, 127)), + } + ); SetTextToItem(ReleaseNotes_Label, CoreTools.Translate("Release notes") + ": "); SetTextToItem(ReleaseNotes_Content, LoadingString); SetTextToItem(ReleaseNotesUrl_Label, CoreTools.Translate("Release notes URL") + ": "); @@ -122,7 +133,7 @@ public PackageDetailsPage(IPackage package, OperationType role, TEL_InstallRefer { TextWrapping = TextWrapping.WrapWholeWords, Padding = new Thickness(0), - TextAlignment = TextAlignment.Center + TextAlignment = TextAlignment.Center, }; MainActionButton.Content = textBlock; if (OperationRole is OperationType.Install) @@ -134,10 +145,16 @@ public PackageDetailsPage(IPackage package, OperationType role, TEL_InstallRefer } else if (OperationRole is OperationType.Update) { - textBlock.Text = CoreTools.Translate("Update to version {0}", UpgradablePackage?.NewVersionString ?? "NULL"); + textBlock.Text = CoreTools.Translate( + "Update to version {0}", + UpgradablePackage?.NewVersionString ?? "NULL" + ); SetTextToItem(Version_Label, CoreTools.Translate("Installed Version")); - SetTextToItem(Version_Content, (UpgradablePackage?.VersionString ?? "NULL") - + $" - {CoreTools.Translate("Update to {0} available", UpgradablePackage?.NewVersionString ?? "NULL")}"); + SetTextToItem( + Version_Content, + (UpgradablePackage?.VersionString ?? "NULL") + + $" - {CoreTools.Translate("Update to {0} available", UpgradablePackage?.NewVersionString ?? "NULL")}" + ); SetUpActionButtonAsUpdate(); } else /* OperationRole is OperationType.Uninstall */ @@ -158,24 +175,26 @@ public void SetUpActionButtonAsInstall() { Text = CoreTools.Translate("Install as administrator"), IconName = IconType.UAC, - IsEnabled = Package.Manager.Capabilities.CanRunAsAdmin + IsEnabled = Package.Manager.Capabilities.CanRunAsAdmin, }; var Interactive = new BetterMenuItem { Text = CoreTools.Translate("Interactive installation"), IconName = IconType.Interactive, - IsEnabled = Package.Manager.Capabilities.CanRunInteractively + IsEnabled = Package.Manager.Capabilities.CanRunInteractively, }; var SkipHash = new BetterMenuItem { Text = CoreTools.Translate("Skip hash check"), IconName = IconType.Checksum, - IsEnabled = Package.Manager.Capabilities.CanSkipIntegrityChecks + IsEnabled = Package.Manager.Capabilities.CanSkipIntegrityChecks, }; AsAdmin.Click += (_, _) => _ = DoAction(Package, OperationType.Install, AsAdmin: true); - Interactive.Click += (_, _) => _ = DoAction(Package, OperationType.Install, Interactive: true); - SkipHash.Click += (_, _) => _ = DoAction(Package, OperationType.Install, SkipHash: true); + Interactive.Click += (_, _) => + _ = DoAction(Package, OperationType.Install, Interactive: true); + SkipHash.Click += (_, _) => + _ = DoAction(Package, OperationType.Install, SkipHash: true); ExtendedActionsMenu.Items.Add(AsAdmin); ExtendedActionsMenu.Items.Add(Interactive); @@ -186,8 +205,11 @@ public void SetUpActionButtonAsInstall() ExtendedActionsMenu.Items.Add(new MenuFlyoutSeparator()); var Upgrade = new BetterMenuItem { - Text = CoreTools.Translate("Update to version {0}", UpgradablePackage.NewVersionString), - IconName = IconType.Update + Text = CoreTools.Translate( + "Update to version {0}", + UpgradablePackage.NewVersionString + ), + IconName = IconType.Update, }; Upgrade.Click += (_, _) => _ = DoAction(UpgradablePackage, OperationType.Update); ExtendedActionsMenu.Items.Add(Upgrade); @@ -199,9 +221,10 @@ public void SetUpActionButtonAsInstall() var Uninstall = new BetterMenuItem { Text = CoreTools.Translate("Uninstall"), - IconName = IconType.Delete + IconName = IconType.Delete, }; - Uninstall.Click += (_, _) => _ = DoAction(InstalledPackage, OperationType.Uninstall); + Uninstall.Click += (_, _) => + _ = DoAction(InstalledPackage, OperationType.Uninstall); ExtendedActionsMenu.Items.Add(Uninstall); } } @@ -212,23 +235,24 @@ public void SetUpActionButtonAsUpdate() { Text = CoreTools.Translate("Update as administrator"), IconName = IconType.UAC, - IsEnabled = Package.Manager.Capabilities.CanRunAsAdmin + IsEnabled = Package.Manager.Capabilities.CanRunAsAdmin, }; var Interactive = new BetterMenuItem { Text = CoreTools.Translate("Interactive update"), IconName = IconType.Interactive, - IsEnabled = Package.Manager.Capabilities.CanRunInteractively + IsEnabled = Package.Manager.Capabilities.CanRunInteractively, }; var SkipHash = new BetterMenuItem { Text = CoreTools.Translate("Skip hash check"), IconName = IconType.Checksum, - IsEnabled = Package.Manager.Capabilities.CanSkipIntegrityChecks + IsEnabled = Package.Manager.Capabilities.CanSkipIntegrityChecks, }; AsAdmin.Click += (_, _) => _ = DoAction(Package, OperationType.Update, AsAdmin: true); - Interactive.Click += (_, _) => _ = DoAction(Package, OperationType.Update, Interactive: true); + Interactive.Click += (_, _) => + _ = DoAction(Package, OperationType.Update, Interactive: true); SkipHash.Click += (_, _) => _ = DoAction(Package, OperationType.Update, SkipHash: true); ExtendedActionsMenu.Items.Add(AsAdmin); @@ -240,9 +264,11 @@ public void SetUpActionButtonAsUpdate() ExtendedActionsMenu.Items.Add(new MenuFlyoutSeparator()); var Uninstall = new BetterMenuItem { - Text = CoreTools.Translate("Uninstall"), IconName = IconType.Delete + Text = CoreTools.Translate("Uninstall"), + IconName = IconType.Delete, }; - Uninstall.Click += (_, _) => _ = DoAction(InstalledPackage, OperationType.Uninstall); + Uninstall.Click += (_, _) => + _ = DoAction(InstalledPackage, OperationType.Uninstall); ExtendedActionsMenu.Items.Add(Uninstall); } @@ -250,7 +276,7 @@ public void SetUpActionButtonAsUpdate() var Reinstall = new BetterMenuItem { Text = CoreTools.Translate("Reinstall"), - IconName = IconType.Download + IconName = IconType.Download, }; Reinstall.Click += (_, _) => _ = DoAction(Package, OperationType.Install); ExtendedActionsMenu.Items.Add(Reinstall); @@ -262,24 +288,27 @@ public void SetUpActionButtonAsUninstall() { Text = CoreTools.Translate("Uninstall as administrator"), IconName = IconType.UAC, - IsEnabled = Package.Manager.Capabilities.CanRunAsAdmin + IsEnabled = Package.Manager.Capabilities.CanRunAsAdmin, }; var Interactive = new BetterMenuItem { Text = CoreTools.Translate("Interactive uninstall"), IconName = IconType.Interactive, - IsEnabled = Package.Manager.Capabilities.CanRunInteractively + IsEnabled = Package.Manager.Capabilities.CanRunInteractively, }; var RemoveData = new BetterMenuItem { Text = CoreTools.Translate("Uninstall and remove data"), IconName = IconType.Close_Round, - IsEnabled = Package.Manager.Capabilities.CanRemoveDataOnUninstall + IsEnabled = Package.Manager.Capabilities.CanRemoveDataOnUninstall, }; - AsAdmin.Click += (_, _) => _ = DoAction(Package, OperationType.Uninstall, AsAdmin: true); - Interactive.Click += (_, _) => _ = DoAction(Package, OperationType.Uninstall, Interactive: true); - RemoveData.Click += (_, _) => _ = DoAction(Package, OperationType.Uninstall, RemoveData: true); + AsAdmin.Click += (_, _) => + _ = DoAction(Package, OperationType.Uninstall, AsAdmin: true); + Interactive.Click += (_, _) => + _ = DoAction(Package, OperationType.Uninstall, Interactive: true); + RemoveData.Click += (_, _) => + _ = DoAction(Package, OperationType.Uninstall, RemoveData: true); ExtendedActionsMenu.Items.Add(AsAdmin); ExtendedActionsMenu.Items.Add(Interactive); @@ -290,8 +319,11 @@ public void SetUpActionButtonAsUninstall() ExtendedActionsMenu.Items.Add(new MenuFlyoutSeparator()); var Upgrade = new BetterMenuItem { - Text = CoreTools.Translate("Update to version {0}", UpgradablePackage.NewVersionString), - IconName = IconType.Update + Text = CoreTools.Translate( + "Update to version {0}", + UpgradablePackage.NewVersionString + ), + IconName = IconType.Update, }; Upgrade.Click += (_, _) => _ = DoAction(UpgradablePackage, OperationType.Update); ExtendedActionsMenu.Items.Add(Upgrade); @@ -300,7 +332,8 @@ public void SetUpActionButtonAsUninstall() ExtendedActionsMenu.Items.Add(new MenuFlyoutSeparator()); var Reinstall = new BetterMenuItem { - Text = CoreTools.Translate("Reinstall"), IconName = IconType.Download + Text = CoreTools.Translate("Reinstall"), + IconName = IconType.Download, }; Reinstall.Click += (_, _) => _ = DoAction(Package, OperationType.Install); ExtendedActionsMenu.Items.Add(Reinstall); @@ -362,13 +395,21 @@ public async Task LoadInformation() SetTextToItem(InstallerHash_Content, details.InstallerHash); if (Package.Manager.Capabilities.CanDownloadInstaller) { - SetTextToItem(InstallerSize_Content, details.InstallerSize > 0 ? $" ({CoreTools.FormatAsSize(details.InstallerSize, 2)})" : $" ({CoreTools.Translate("Unknown size")})"); + SetTextToItem( + InstallerSize_Content, + details.InstallerSize > 0 + ? $" ({CoreTools.FormatAsSize(details.InstallerSize, 2)})" + : $" ({CoreTools.Translate("Unknown size")})" + ); SetTextToItem(DownloadInstaller_Button, CoreTools.Translate("Download installer")); } else { SetTextToItem(InstallerSize_Content, ""); - SetTextToItem(DownloadInstaller_Button, CoreTools.Translate("Installer not available")); + SetTextToItem( + DownloadInstaller_Button, + CoreTools.Translate("Installer not available") + ); } SetTextToItem(InstallerUrl_Content, details.InstallerUrl); SetTextToItem(InstallerType_Content, details.InstallerType); @@ -379,11 +420,13 @@ public async Task LoadInformation() if (!details.Package.Manager.Capabilities.CanListDependencies) { DependenciesParagraph.Inlines.Clear(); - DependenciesParagraph.Inlines.Add(new Run() - { - Text = CoreTools.Translate("Not available"), - Foreground = new SolidColorBrush(color: Color.FromArgb(255, 127, 127, 127)), - }); + DependenciesParagraph.Inlines.Add( + new Run() + { + Text = CoreTools.Translate("Not available"), + Foreground = new SolidColorBrush(color: Color.FromArgb(255, 127, 127, 127)), + } + ); } else if (details.Dependencies.Any()) { @@ -391,46 +434,59 @@ public async Task LoadInformation() foreach (var dep in details.Dependencies) { - DependenciesParagraph.Inlines.Add(new Run() - { - Text = $"  • {dep.Name}", - FontStyle = dep.Mandatory? FontStyle.Normal : FontStyle.Italic, - FontWeight = new FontWeight(600) - }); + DependenciesParagraph.Inlines.Add( + new Run() + { + Text = $"  • {dep.Name}", + FontStyle = dep.Mandatory ? FontStyle.Normal : FontStyle.Italic, + FontWeight = new FontWeight(600), + } + ); string line = $" ("; - if (dep.Version.Any()) line += CoreTools.Translate("Version:") + $" {dep.Version}, "; - line += $"{(dep.Mandatory ? CoreTools.Translate("mandatory") : CoreTools.Translate("optional"))})"; - - DependenciesParagraph.Inlines.Add(new Run() - { - Text = line, - FontStyle = dep.Mandatory? FontStyle.Normal : FontStyle.Italic, - }); + if (dep.Version.Any()) + line += CoreTools.Translate("Version:") + $" {dep.Version}, "; + line += + $"{(dep.Mandatory ? CoreTools.Translate("mandatory") : CoreTools.Translate("optional"))})"; + + DependenciesParagraph.Inlines.Add( + new Run() + { + Text = line, + FontStyle = dep.Mandatory ? FontStyle.Normal : FontStyle.Italic, + } + ); DependenciesParagraph.Inlines.Add(new LineBreak()); } - if(DependenciesParagraph.Inlines.Any() && DependenciesParagraph.Inlines.Last() is LineBreak) - DependenciesParagraph.Inlines.RemoveAt(DependenciesParagraph.Inlines.Count-1); + if ( + DependenciesParagraph.Inlines.Any() + && DependenciesParagraph.Inlines.Last() is LineBreak + ) + DependenciesParagraph.Inlines.RemoveAt(DependenciesParagraph.Inlines.Count - 1); } else { DependenciesParagraph.Inlines.Clear(); - DependenciesParagraph.Inlines.Add(new Run() - { - Text = "\t" + CoreTools.Translate("No dependencies specified"), - Foreground = new SolidColorBrush(color: Color.FromArgb(255, 127, 127, 127)), - }); + DependenciesParagraph.Inlines.Add( + new Run() + { + Text = "\t" + CoreTools.Translate("No dependencies specified"), + Foreground = new SolidColorBrush(color: Color.FromArgb(255, 127, 127, 127)), + } + ); } ShowableTags.Clear(); foreach (string tag in details.Tags) { - ShowableTags.Add(new TextBlock - { - Text = tag, - VerticalAlignment = VerticalAlignment.Center, - TextLineBounds = TextLineBounds.Tight - }); + ShowableTags.Add( + new TextBlock + { + Text = tag, + VerticalAlignment = VerticalAlignment.Center, + TextLineBounds = TextLineBounds.Tight, + } + ); } } @@ -453,12 +509,14 @@ public void SetTextToItem(Hyperlink h, Uri? u, string prefix = "", string suffix if (u is null) { h.Inlines.Clear(); - h.Inlines.Add(new Run - { - Text = CoreTools.Translate("Not available"), - TextDecorations = TextDecorations.None, - Foreground = new SolidColorBrush(color: Color.FromArgb(255, 127, 127, 127)) - }); + h.Inlines.Add( + new Run + { + Text = CoreTools.Translate("Not available"), + TextDecorations = TextDecorations.None, + Foreground = new SolidColorBrush(color: Color.FromArgb(255, 127, 127, 127)), + } + ); h.NavigateUri = u; } else @@ -468,6 +526,7 @@ public void SetTextToItem(Hyperlink h, Uri? u, string prefix = "", string suffix h.NavigateUri = u; } } + public void SetTextToItem(Hyperlink h, string s) { h.Inlines.Clear(); @@ -477,10 +536,7 @@ public void SetTextToItem(Hyperlink h, string s) public async Task LoadIcon() { - PackageIcon.Source = new BitmapImage - { - UriSource = await Task.Run(Package.GetIconUrl) - }; + PackageIcon.Source = new BitmapImage { UriSource = await Task.Run(Package.GetIconUrl) }; } public async Task LoadScreenshots() @@ -500,7 +556,6 @@ public async Task LoadScreenshots() __layout_mode = LayoutMode.Unset; PackageDetailsPage_SizeChanged(); - } public void ShareButton_Click(object sender, RoutedEventArgs e) @@ -510,7 +565,8 @@ public void ShareButton_Click(object sender, RoutedEventArgs e) public void DownloadInstallerButton_Click(object sender, RoutedEventArgs e) { - if (!Package.Manager.Capabilities.CanDownloadInstaller) return; + if (!Package.Manager.Capabilities.CanDownloadInstaller) + return; Close?.Invoke(this, EventArgs.Empty); _ = MainApp.Operations.AskLocationAndDownload(Package, InstallReferral); } @@ -520,7 +576,10 @@ public void CloseButton_Click(object sender, RoutedEventArgs e) Close?.Invoke(this, EventArgs.Empty); } - public void PackageDetailsPage_SizeChanged(object? sender = null, SizeChangedEventArgs? e = null) + public void PackageDetailsPage_SizeChanged( + object? sender = null, + SizeChangedEventArgs? e = null + ) { if (MainApp.Instance.MainWindow.AppWindow.Size.Width < 950) { @@ -529,7 +588,9 @@ public void PackageDetailsPage_SizeChanged(object? sender = null, SizeChangedEve __layout_mode = LayoutMode.Normal; MainGrid.ColumnDefinitions.Clear(); - MainGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }); + MainGrid.ColumnDefinitions.Add( + new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) } + ); Grid.SetColumn(TitlePanel, 0); Grid.SetColumn(BasicInfoPanelText, 0); Grid.SetColumn(ScreenshotsPanel, 0); @@ -538,13 +599,27 @@ public void PackageDetailsPage_SizeChanged(object? sender = null, SizeChangedEve Grid.SetColumn(DetailsPanelText, 0); MainGrid.RowDefinitions.Clear(); - MainGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) }); - MainGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) }); - MainGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) }); - MainGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) }); - MainGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) }); - MainGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) }); - MainGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) }); + MainGrid.RowDefinitions.Add( + new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) } + ); + MainGrid.RowDefinitions.Add( + new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) } + ); + MainGrid.RowDefinitions.Add( + new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) } + ); + MainGrid.RowDefinitions.Add( + new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) } + ); + MainGrid.RowDefinitions.Add( + new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) } + ); + MainGrid.RowDefinitions.Add( + new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) } + ); + MainGrid.RowDefinitions.Add( + new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) } + ); Grid.SetRow(TitlePanel, 0); Grid.SetRow(DescriptionPanel, 1); Grid.SetRow(BasicInfoPanelText, 2); @@ -566,7 +641,6 @@ public void PackageDetailsPage_SizeChanged(object? sender = null, SizeChangedEve ScreenshotsCarroussel.Height = PackageHasScreenshots ? 225 : 150; InstallOptionsExpander.IsExpanded = false; - } } else @@ -576,15 +650,21 @@ public void PackageDetailsPage_SizeChanged(object? sender = null, SizeChangedEve __layout_mode = LayoutMode.Wide; MainGrid.ColumnDefinitions.Clear(); - MainGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }); - MainGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }); + MainGrid.ColumnDefinitions.Add( + new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) } + ); + MainGrid.ColumnDefinitions.Add( + new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) } + ); Grid.SetColumn(LeftPanel, 0); Grid.SetColumn(RightPanel, 1); Grid.SetColumn(TitlePanel, 0); Grid.SetColumnSpan(TitlePanel, 1); MainGrid.RowDefinitions.Clear(); - MainGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) }); + MainGrid.RowDefinitions.Add( + new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) } + ); Grid.SetRow(LeftPanel, 0); Grid.SetRow(RightPanel, 0); @@ -615,7 +695,6 @@ public void PackageDetailsPage_SizeChanged(object? sender = null, SizeChangedEve MainGrid.Children.Add(LeftPanel); MainGrid.Children.Add(RightPanel); - } } } @@ -631,25 +710,41 @@ public async Task DoAction( bool? AsAdmin = null, bool? Interactive = null, bool? SkipHash = null, - bool? RemoveData = null) + bool? RemoveData = null + ) { Close?.Invoke(this, EventArgs.Empty); var newOptions = await InstallOptionsPage.GetUpdatedOptions(); await InstallOptionsFactory.SaveForPackageAsync(newOptions, package); - if (AsAdmin is not null) newOptions.RunAsAdministrator = (bool)AsAdmin; - if (Interactive is not null) newOptions.InteractiveInstallation = (bool)Interactive; - if (SkipHash is not null) newOptions.SkipHashCheck = (bool)SkipHash; - if (RemoveData is not null) newOptions.RemoveDataOnUninstall = (bool)RemoveData; + if (AsAdmin is not null) + newOptions.RunAsAdministrator = (bool)AsAdmin; + if (Interactive is not null) + newOptions.InteractiveInstallation = (bool)Interactive; + if (SkipHash is not null) + newOptions.SkipHashCheck = (bool)SkipHash; + if (RemoveData is not null) + newOptions.RemoveDataOnUninstall = (bool)RemoveData; if (action is OperationType.Install) { - _ = MainApp.Operations.Install(package, InstallReferral, AsAdmin, Interactive, SkipHash); + _ = MainApp.Operations.Install( + package, + InstallReferral, + AsAdmin, + Interactive, + SkipHash + ); } else if (action is OperationType.Uninstall) { - _ = MainApp.Operations.ConfirmAndUninstall(package, AsAdmin, Interactive, RemoveData); + _ = MainApp.Operations.ConfirmAndUninstall( + package, + AsAdmin, + Interactive, + RemoveData + ); } else if (action is OperationType.Update) { @@ -657,11 +752,15 @@ public async Task DoAction( } else { - throw new ArgumentException("PackageDetailsPage.DoAction should never be called with action=None"); + throw new ArgumentException( + "PackageDetailsPage.DoAction should never be called with action=None" + ); } } - private void SaveInstallOptionsButton_Click(object sender, RoutedEventArgs e) => _ = _saveInstallOptionsButton_Click(); + private void SaveInstallOptionsButton_Click(object sender, RoutedEventArgs e) => + _ = _saveInstallOptionsButton_Click(); + private async Task _saveInstallOptionsButton_Click() { try diff --git a/src/UniGetUI/Pages/DialogPages/ReleaseNotes.xaml b/src/UniGetUI/Pages/DialogPages/ReleaseNotes.xaml index 2abc7c326a..5a9998a3d6 100644 --- a/src/UniGetUI/Pages/DialogPages/ReleaseNotes.xaml +++ b/src/UniGetUI/Pages/DialogPages/ReleaseNotes.xaml @@ -1,38 +1,41 @@ - - - - - - - - - - - - - + x:Class="UniGetUI.Interface.Dialogs.ReleaseNotes" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:controls="using:Microsoft.UI.Xaml.Controls" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="using:UniGetUI.Interface.Dialogs" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:widgets="using:UniGetUI.Interface.Widgets" + HorizontalAlignment="Stretch" + VerticalAlignment="Stretch" + mc:Ignorable="d" +> + + + + + + + + + + + + + diff --git a/src/UniGetUI/Pages/DialogPages/ReleaseNotes.xaml.cs b/src/UniGetUI/Pages/DialogPages/ReleaseNotes.xaml.cs index ba2cd463e7..6f82790801 100644 --- a/src/UniGetUI/Pages/DialogPages/ReleaseNotes.xaml.cs +++ b/src/UniGetUI/Pages/DialogPages/ReleaseNotes.xaml.cs @@ -12,21 +12,29 @@ namespace UniGetUI.Interface.Dialogs /// public sealed partial class ReleaseNotes : Page, IDisposable { - public event EventHandler? Close; + public ReleaseNotes() { InitializeComponent(); _ = InitializeWebView(); - WebView.NavigationStarting += (_, _) => { ProgressBar.Visibility = Visibility.Visible; }; - WebView.NavigationCompleted += (_, _) => { ProgressBar.Visibility = Visibility.Collapsed; }; + WebView.NavigationStarting += (_, _) => + { + ProgressBar.Visibility = Visibility.Visible; + }; + WebView.NavigationCompleted += (_, _) => + { + ProgressBar.Visibility = Visibility.Collapsed; + }; } private async Task InitializeWebView() { await WebView.EnsureCoreWebView2Async(); - WebView.Source = new Uri("https://github.com/Devolutions/UniGetUI/releases/tag/" + CoreData.VersionName); + WebView.Source = new Uri( + "https://github.com/Devolutions/UniGetUI/releases/tag/" + CoreData.VersionName + ); } public void Dispose() diff --git a/src/UniGetUI/Pages/HelpPage.xaml b/src/UniGetUI/Pages/HelpPage.xaml index 98894168a2..d2f7150bfb 100644 --- a/src/UniGetUI/Pages/HelpPage.xaml +++ b/src/UniGetUI/Pages/HelpPage.xaml @@ -1,112 +1,105 @@ + x:Class="UniGetUI.Interface.Dialogs.HelpPage" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:animations="using:CommunityToolkit.WinUI.Animations" + xmlns:controls="using:Microsoft.UI.Xaml.Controls" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:widgets="using:UniGetUI.Interface.Widgets" + HorizontalAlignment="Stretch" + VerticalAlignment="Stretch" + NavigationCacheMode="Required" + mc:Ignorable="d" +> + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/UniGetUI/Pages/HelpPage.xaml.cs b/src/UniGetUI/Pages/HelpPage.xaml.cs index dd05bfe1d7..f7dc16ae6a 100644 --- a/src/UniGetUI/Pages/HelpPage.xaml.cs +++ b/src/UniGetUI/Pages/HelpPage.xaml.cs @@ -32,7 +32,10 @@ private async Task InitializeWebView() { ProgressBar.Visibility = Visibility.Visible; lastUri = new Uri(e.Uri); - if (e.Uri.ToString().Contains("marticliment.com") && !e.Uri.ToString().Contains("isWingetUIIframe")) + if ( + e.Uri.ToString().Contains("marticliment.com") + && !e.Uri.ToString().Contains("isWingetUIIframe") + ) { e.Cancel = true; if (e.Uri.ToString().Contains('?')) @@ -55,12 +58,13 @@ private async Task InitializeWebView() Initialized = true; } - public void NavigateTo(string piece, bool skipWait = false) - => _ = _navigateTo(piece, skipWait); + public void NavigateTo(string piece, bool skipWait = false) => + _ = _navigateTo(piece, skipWait); private async Task _navigateTo(string piece, bool skipWait) { - while (!Initialized && !skipWait) await Task.Delay(50); + while (!Initialized && !skipWait) + await Task.Delay(50); ArgumentNullException.ThrowIfNull(webView); webView.Source = new Uri("https://marticliment.com/unigetui/help/" + piece); } @@ -75,8 +79,7 @@ private void BackButton_Click(object sender, RoutedEventArgs e) private void RightButton_Click(object sender, RoutedEventArgs e) { - - if (Initialized && webView is not null && webView.CanGoForward) + if (Initialized && webView is not null && webView.CanGoForward) { webView.GoForward(); } @@ -103,7 +106,10 @@ private void BrowserButton_Click(object sender, RoutedEventArgs e) if (!Initialized || webView is null) return; - string uri = webView.Source.ToString().Replace("?isWingetUIIframe", "").Replace("&isWingetUIIframe", ""); + string uri = webView + .Source.ToString() + .Replace("?isWingetUIIframe", "") + .Replace("&isWingetUIIframe", ""); CoreTools.Launch(uri); } @@ -117,7 +123,8 @@ public void Dispose() public void OnEnter() { - if (webView is null) _ = InitializeWebView(); + if (webView is null) + _ = InitializeWebView(); } public void OnLeave() diff --git a/src/UniGetUI/Pages/LogPages/LogPage.xaml b/src/UniGetUI/Pages/LogPages/LogPage.xaml index 0650dfc74e..7bdea35cc9 100644 --- a/src/UniGetUI/Pages/LogPages/LogPage.xaml +++ b/src/UniGetUI/Pages/LogPages/LogPage.xaml @@ -1,91 +1,73 @@ + x:Class="UniGetUI.Interface.Pages.BaseLogPage" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:animations="using:CommunityToolkit.WinUI.Animations" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="using:UniGetUI.Interface.Pages" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:widgets="using:UniGetUI.Interface.Widgets" + mc:Ignorable="d" +> + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/UniGetUI/Pages/LogPages/LogPage.xaml.cs b/src/UniGetUI/Pages/LogPages/LogPage.xaml.cs index acb869667d..eea688655a 100644 --- a/src/UniGetUI/Pages/LogPages/LogPage.xaml.cs +++ b/src/UniGetUI/Pages/LogPages/LogPage.xaml.cs @@ -26,7 +26,8 @@ public BaseLogPage(bool log_level_enabled) { InitializeComponent(); LogLevelPane.Visibility = log_level_enabled ? Visibility.Visible : Visibility.Collapsed; - if (log_level_enabled) LoadLogLevels(); + if (log_level_enabled) + LoadLogLevels(); ActualThemeChanged += (_, _) => LoadLog(); } @@ -36,14 +37,11 @@ protected void SelectLogLevelByName(string name) LogLevelCombo.SelectedValue = name; } - public void ReloadTriggered() - => LoadLog(isReload: true); + public void ReloadTriggered() => LoadLog(isReload: true); - public void SelectAllTriggered() - => LogTextBox.SelectAll(); + public void SelectAllTriggered() => LogTextBox.SelectAll(); - public void SearchTriggered() - { } + public void SearchTriggered() { } // Dark theme colors protected Color DARK_GREY = Color.FromArgb(255, 130, 130, 130); @@ -70,14 +68,19 @@ public void CopyButton_Click(object sender, RoutedEventArgs e) LogTextBox.Select(LogTextBox.SelectionStart, LogTextBox.SelectionStart); } - public void ExportButton_Click(object sender, RoutedEventArgs e) => _ = _exportButton_Click(); + public void ExportButton_Click(object sender, RoutedEventArgs e) => + _ = _exportButton_Click(); + public async Task _exportButton_Click() { FileSavePicker savePicker = new() { - SuggestedStartLocation = PickerLocationId.DocumentsLibrary + SuggestedStartLocation = PickerLocationId.DocumentsLibrary, }; - WinRT.Interop.InitializeWithWindow.Initialize(savePicker, WinRT.Interop.WindowNative.GetWindowHandle(MainApp.Instance.MainWindow)); + WinRT.Interop.InitializeWithWindow.Initialize( + savePicker, + WinRT.Interop.WindowNative.GetWindowHandle(MainApp.Instance.MainWindow) + ); savePicker.FileTypeChoices.Add(CoreTools.Translate("Text"), [".txt"]); savePicker.SuggestedFileName = CoreTools.Translate("WingetUI Log"); @@ -91,8 +94,7 @@ public async Task _exportButton_Click() } } - public void ReloadButton_Click(object sender, RoutedEventArgs e) - => LoadLog(); + public void ReloadButton_Click(object sender, RoutedEventArgs e) => LoadLog(); private void LogLevelCombo_SelectionChanged(object sender, SelectionChangedEventArgs e) { @@ -100,10 +102,8 @@ private void LogLevelCombo_SelectionChanged(object sender, SelectionChangedEvent LoadLog(); } - public void OnEnter() - => LoadLog(); + public void OnEnter() => LoadLog(); - public void OnLeave() - => LogTextBox.Blocks.Clear(); + public void OnLeave() => LogTextBox.Blocks.Clear(); } } diff --git a/src/UniGetUI/Pages/LogPages/ManagerLogsPage.cs b/src/UniGetUI/Pages/LogPages/ManagerLogsPage.cs index 083f9febd5..261870eafa 100644 --- a/src/UniGetUI/Pages/LogPages/ManagerLogsPage.cs +++ b/src/UniGetUI/Pages/LogPages/ManagerLogsPage.cs @@ -10,25 +10,29 @@ namespace UniGetUI.Interface.Pages.LogPage { public partial class ManagerLogsPage : BaseLogPage { - - public ManagerLogsPage() : base(true) - { - - } + public ManagerLogsPage() + : base(true) { } public void LoadForManager(IPackageManager manager) { bool IS_DARK = this.ActualTheme == ElementTheme.Dark; - bool verbose = LogLevelCombo.SelectedValue?.ToString()?.Contains(CoreTools.Translate("Verbose")) ?? false; + bool verbose = + LogLevelCombo.SelectedValue?.ToString()?.Contains(CoreTools.Translate("Verbose")) + ?? false; - if (!verbose) SelectLogLevelByName(manager.DisplayName); + if (!verbose) + SelectLogLevelByName(manager.DisplayName); IManagerLogger TaskLogger = manager.TaskLogger; LogTextBox.Blocks.Clear(); Paragraph versionParagraph = new(); - versionParagraph.Inlines.Add(new Run { Text = $"Manager {manager.DisplayName} with version:\n" }); + versionParagraph.Inlines.Add( + new Run { Text = $"Manager {manager.DisplayName} with version:\n" } + ); versionParagraph.Inlines.Add(new Run { Text = manager.Status.Version }); - versionParagraph.Inlines.Add(new Run { Text = "\n\n——————————————————————————————————————————\n\n" }); + versionParagraph.Inlines.Add( + new Run { Text = "\n\n——————————————————————————————————————————\n\n" } + ); LogTextBox.Blocks.Add(versionParagraph); foreach (ITaskLogger operation in TaskLogger.Operations) @@ -39,7 +43,10 @@ public void LoadForManager(IPackageManager manager) Brush color = line[0] switch { '0' => new SolidColorBrush { Color = IS_DARK ? DARK_WHITE : LIGHT_WHITE }, - '1' => new SolidColorBrush { Color = IS_DARK ? DARK_LIGHT_GREY : LIGHT_LIGHT_GREY }, + '1' => new SolidColorBrush + { + Color = IS_DARK ? DARK_LIGHT_GREY : LIGHT_LIGHT_GREY, + }, '2' => new SolidColorBrush { Color = IS_DARK ? DARK_RED : LIGHT_RED }, '3' => new SolidColorBrush { Color = IS_DARK ? DARK_BLUE : LIGHT_BLUE }, '4' => new SolidColorBrush { Color = IS_DARK ? DARK_GREEN : LIGHT_GREEN }, @@ -63,7 +70,8 @@ public override void LoadLog(bool isReload = false) break; } - if (isReload) MainScroller.ScrollToVerticalOffset(MainScroller.ScrollableHeight); + if (isReload) + MainScroller.ScrollToVerticalOffset(MainScroller.ScrollableHeight); } } @@ -73,7 +81,9 @@ protected override void LoadLogLevels() foreach (IPackageManager manager in PEInterface.Managers) { LogLevelCombo.Items.Add(manager.DisplayName); - LogLevelCombo.Items.Add($"{manager.DisplayName} ({CoreTools.Translate("Verbose")})"); + LogLevelCombo.Items.Add( + $"{manager.DisplayName} ({CoreTools.Translate("Verbose")})" + ); } LogLevelCombo.SelectedIndex = 0; } diff --git a/src/UniGetUI/Pages/LogPages/OperationHistoryPage.cs b/src/UniGetUI/Pages/LogPages/OperationHistoryPage.cs index 7cb581e7f4..6be9bd8208 100644 --- a/src/UniGetUI/Pages/LogPages/OperationHistoryPage.cs +++ b/src/UniGetUI/Pages/LogPages/OperationHistoryPage.cs @@ -1,14 +1,12 @@ -using Microsoft.UI.Xaml.Documents; +using Microsoft.UI.Xaml.Documents; using UniGetUI.Core.SettingsEngine; namespace UniGetUI.Interface.Pages.LogPage { public partial class OperationHistoryPage : BaseLogPage { - public OperationHistoryPage() : base(false) - { - - } + public OperationHistoryPage() + : base(false) { } public override void LoadLog(bool isReload = false) { @@ -25,7 +23,6 @@ public override void LoadLog(bool isReload = false) } LogTextBox.Blocks.Clear(); LogTextBox.Blocks.Add(paragraph); - } protected override void LoadLogLevels() diff --git a/src/UniGetUI/Pages/LogPages/UniGetUILogPage.cs b/src/UniGetUI/Pages/LogPages/UniGetUILogPage.cs index 7135094bc9..be7bff406d 100644 --- a/src/UniGetUI/Pages/LogPages/UniGetUILogPage.cs +++ b/src/UniGetUI/Pages/LogPages/UniGetUILogPage.cs @@ -7,9 +7,8 @@ namespace UniGetUI.Interface.Pages.LogPage { public sealed partial class UniGetUILogPage : BaseLogPage { - public UniGetUILogPage() : base(true) - { - } + public UniGetUILogPage() + : base(true) { } protected override void LoadLogLevels() { @@ -39,17 +38,38 @@ public override void LoadLog(bool isReload = false) continue; } - if (LOG_LEVEL == 1 && (log_entry.Severity == LogEntry.SeverityLevel.Debug || log_entry.Severity == LogEntry.SeverityLevel.Info || log_entry.Severity == LogEntry.SeverityLevel.Success || log_entry.Severity == LogEntry.SeverityLevel.Warning)) + if ( + LOG_LEVEL == 1 + && ( + log_entry.Severity == LogEntry.SeverityLevel.Debug + || log_entry.Severity == LogEntry.SeverityLevel.Info + || log_entry.Severity == LogEntry.SeverityLevel.Success + || log_entry.Severity == LogEntry.SeverityLevel.Warning + ) + ) { continue; } - if (LOG_LEVEL == 2 && (log_entry.Severity == LogEntry.SeverityLevel.Debug || log_entry.Severity == LogEntry.SeverityLevel.Info || log_entry.Severity == LogEntry.SeverityLevel.Success)) + if ( + LOG_LEVEL == 2 + && ( + log_entry.Severity == LogEntry.SeverityLevel.Debug + || log_entry.Severity == LogEntry.SeverityLevel.Info + || log_entry.Severity == LogEntry.SeverityLevel.Success + ) + ) { continue; } - if (LOG_LEVEL == 3 && (log_entry.Severity == LogEntry.SeverityLevel.Debug || log_entry.Severity == LogEntry.SeverityLevel.Info)) + if ( + LOG_LEVEL == 3 + && ( + log_entry.Severity == LogEntry.SeverityLevel.Debug + || log_entry.Severity == LogEntry.SeverityLevel.Info + ) + ) { continue; } @@ -61,11 +81,26 @@ public override void LoadLog(bool isReload = false) Brush color = log_entry.Severity switch { - LogEntry.SeverityLevel.Debug => new SolidColorBrush { Color = IS_DARK ? DARK_GREY : LIGHT_GREY }, - LogEntry.SeverityLevel.Info => new SolidColorBrush { Color = IS_DARK ? DARK_LIGHT_GREY : LIGHT_LIGHT_GREY }, - LogEntry.SeverityLevel.Success => new SolidColorBrush { Color = IS_DARK ? DARK_WHITE : LIGHT_WHITE }, - LogEntry.SeverityLevel.Warning => new SolidColorBrush { Color = IS_DARK ? DARK_YELLOW : LIGHT_YELLOW }, - LogEntry.SeverityLevel.Error => new SolidColorBrush { Color = IS_DARK ? DARK_RED : LIGHT_RED }, + LogEntry.SeverityLevel.Debug => new SolidColorBrush + { + Color = IS_DARK ? DARK_GREY : LIGHT_GREY, + }, + LogEntry.SeverityLevel.Info => new SolidColorBrush + { + Color = IS_DARK ? DARK_LIGHT_GREY : LIGHT_LIGHT_GREY, + }, + LogEntry.SeverityLevel.Success => new SolidColorBrush + { + Color = IS_DARK ? DARK_WHITE : LIGHT_WHITE, + }, + LogEntry.SeverityLevel.Warning => new SolidColorBrush + { + Color = IS_DARK ? DARK_YELLOW : LIGHT_YELLOW, + }, + LogEntry.SeverityLevel.Error => new SolidColorBrush + { + Color = IS_DARK ? DARK_RED : LIGHT_RED, + }, _ => new SolidColorBrush { Color = IS_DARK ? DARK_GREY : LIGHT_GREY }, }; string[] lines = log_entry.Content.Split('\n'); @@ -74,17 +109,27 @@ public override void LoadLog(bool isReload = false) { if (date_length == -1) { - p.Inlines.Add(new Run { Text = $"[{log_entry.Time}] {line}\n", Foreground = color }); + p.Inlines.Add( + new Run { Text = $"[{log_entry.Time}] {line}\n", Foreground = color } + ); date_length = $"[{log_entry.Time}] ".Length; } else { - p.Inlines.Add(new Run { Text = new string(' ', date_length) + line + "\n", Foreground = color }); + p.Inlines.Add( + new Run + { + Text = new string(' ', date_length) + line + "\n", + Foreground = color, + } + ); } - } ((Run)p.Inlines[^1]).Text = ((Run)p.Inlines[^1]).Text.TrimEnd(); + } + ((Run)p.Inlines[^1]).Text = ((Run)p.Inlines[^1]).Text.TrimEnd(); LogTextBox.Blocks.Add(p); } - if (isReload) MainScroller.ScrollToVerticalOffset(MainScroller.ScrollableHeight); + if (isReload) + MainScroller.ScrollToVerticalOffset(MainScroller.ScrollableHeight); } } } diff --git a/src/UniGetUI/Pages/MainView.xaml b/src/UniGetUI/Pages/MainView.xaml index 1e1262898a..bb230ce5fb 100644 --- a/src/UniGetUI/Pages/MainView.xaml +++ b/src/UniGetUI/Pages/MainView.xaml @@ -1,430 +1,443 @@ + x:Class="UniGetUI.Interface.MainView" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:animatedvisuals="using:Microsoft.UI.Xaml.Controls.AnimatedVisuals" + xmlns:controls="using:CommunityToolkit.WinUI.Controls" + xmlns:controls1="using:UniGetUI.Controls" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:interface="using:UniGetUI.Interface" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:operationWidgets="using:UniGetUI.Controls.OperationWidgets" + xmlns:operations="using:UniGetUI.PackageOperations" + xmlns:pages="using:UniGetUI.Interface" + xmlns:widgets="using:UniGetUI.Interface.Widgets" + MinWidth="200" + MinHeight="200" + mc:Ignorable="d" +> + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + - - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0,0,0,0 - 0,0,0,0 - 0,0,0,0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - + + + + + + - - - + - + + + + + + + + + + + + + + + + + + + + + + 0,0,0,0 + 0,0,0,0 + 0,0,0,0 + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/UniGetUI/Pages/MainView.xaml.cs b/src/UniGetUI/Pages/MainView.xaml.cs index 65bca78529..b184047dbb 100644 --- a/src/UniGetUI/Pages/MainView.xaml.cs +++ b/src/UniGetUI/Pages/MainView.xaml.cs @@ -1,8 +1,8 @@ -using Windows.System; using Microsoft.UI.Input; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Controls.Primitives; +using UniGetUI.Controls; using UniGetUI.Core.Data; using UniGetUI.Core.SettingsEngine; using UniGetUI.Core.Tools; @@ -10,16 +10,16 @@ using UniGetUI.Interface.Pages; using UniGetUI.Interface.Pages.LogPage; using UniGetUI.Interface.SoftwarePages; -using Windows.UI.Core; -using UniGetUI.PackageEngine.Interfaces; -using UniGetUI.Pages.DialogPages; -using UniGetUI.PackageEngine.Enums; -using UniGetUI.PackageOperations; -using UniGetUI.Pages.SettingsPages; -using UniGetUI.Controls; using UniGetUI.PackageEngine; +using UniGetUI.PackageEngine.Enums; +using UniGetUI.PackageEngine.Interfaces; using UniGetUI.PackageEngine.PackageLoader; +using UniGetUI.PackageOperations; +using UniGetUI.Pages.DialogPages; using UniGetUI.Pages.PageInterfaces; +using UniGetUI.Pages.SettingsPages; +using Windows.System; +using Windows.UI.Core; // To learn more about WinUI, the WinUI project structure, // and more about our project templates, see: http://aka.ms/winui-project-info. @@ -38,7 +38,7 @@ public enum PageType ManagerLog, OperationHistory, Help, - Null // Used for initializers + Null, // Used for initializers } public sealed partial class MainView : UserControl @@ -81,13 +81,21 @@ public MainView(AutoSuggestBox mainTextBlock) return; } - bool IS_CONTROL_PRESSED = InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.Control).HasFlag(CoreVirtualKeyStates.Down); - bool IS_SHIFT_PRESSED = InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.Shift).HasFlag(CoreVirtualKeyStates.Down); + bool IS_CONTROL_PRESSED = InputKeyboardSource + .GetKeyStateForCurrentThread(VirtualKey.Control) + .HasFlag(CoreVirtualKeyStates.Down); + bool IS_SHIFT_PRESSED = InputKeyboardSource + .GetKeyStateForCurrentThread(VirtualKey.Shift) + .HasFlag(CoreVirtualKeyStates.Down); Page currentPage = GetPageForType(CurrentPage_t); if (e.Key is VirtualKey.Tab && IS_CONTROL_PRESSED) { - NavigateTo(IS_SHIFT_PRESSED ? GetPreviousPage(CurrentPage_t) : GetNextPage(CurrentPage_t)); + NavigateTo( + IS_SHIFT_PRESSED + ? GetPreviousPage(CurrentPage_t) + : GetNextPage(CurrentPage_t) + ); } else if (!IS_CONTROL_PRESSED && !IS_SHIFT_PRESSED && e.Key == VirtualKey.F1) { @@ -114,31 +122,43 @@ public MainView(AutoSuggestBox mainTextBlock) /* * Connect different loaders and UI Sections to bundles page */ - foreach(var pair in new Dictionary - { - { DiscoverNavBtn, DiscoverablePackagesLoader.Instance }, - { UpdatesNavBtn, UpgradablePackagesLoader.Instance }, - { InstalledNavBtn, InstalledPackagesLoader.Instance }, - }) + foreach ( + var pair in new Dictionary + { + { DiscoverNavBtn, DiscoverablePackagesLoader.Instance }, + { UpdatesNavBtn, UpgradablePackagesLoader.Instance }, + { InstalledNavBtn, InstalledPackagesLoader.Instance }, + } + ) { - pair.Value.FinishedLoading += (_, _) => MainApp.Dispatcher.TryEnqueue(() => pair.Key.IsLoading = false); - pair.Value.StartedLoading += (_, _) => MainApp.Dispatcher.TryEnqueue(() => pair.Key.IsLoading = true); + pair.Value.FinishedLoading += (_, _) => + MainApp.Dispatcher.TryEnqueue(() => pair.Key.IsLoading = false); + pair.Value.StartedLoading += (_, _) => + MainApp.Dispatcher.TryEnqueue(() => pair.Key.IsLoading = true); pair.Key.IsLoading = pair.Value.IsLoading; } - UpgradablePackagesLoader.Instance.PackagesChanged += (_, _) => MainApp.Dispatcher.TryEnqueue(() => - { - UpdatesBadge.Value = UpgradablePackagesLoader.Instance.Count(); - UpdatesBadge.Visibility = UpdatesBadge.Value > 0 ? Visibility.Visible : Visibility.Collapsed; - }); + UpgradablePackagesLoader.Instance.PackagesChanged += (_, _) => + MainApp.Dispatcher.TryEnqueue(() => + { + UpdatesBadge.Value = UpgradablePackagesLoader.Instance.Count(); + UpdatesBadge.Visibility = + UpdatesBadge.Value > 0 ? Visibility.Visible : Visibility.Collapsed; + }); UpdatesBadge.Value = UpgradablePackagesLoader.Instance.Count(); - UpdatesBadge.Visibility = UpdatesBadge.Value > 0 ? Visibility.Visible : Visibility.Collapsed; + UpdatesBadge.Visibility = + UpdatesBadge.Value > 0 ? Visibility.Visible : Visibility.Collapsed; - BundlesPage.UnsavedChangesStateChanged += (_, _) => MainApp.Dispatcher.TryEnqueue(() => - { - BundlesBadge.Visibility = BundlesPage.HasUnsavedChanges ? Visibility.Visible : Visibility.Collapsed; - }); - BundlesBadge.Visibility = BundlesPage.HasUnsavedChanges ? Visibility.Visible : Visibility.Collapsed; + BundlesPage.UnsavedChangesStateChanged += (_, _) => + MainApp.Dispatcher.TryEnqueue(() => + { + BundlesBadge.Visibility = BundlesPage.HasUnsavedChanges + ? Visibility.Visible + : Visibility.Collapsed; + }); + BundlesBadge.Visibility = BundlesPage.HasUnsavedChanges + ? Visibility.Visible + : Visibility.Collapsed; /* * End connecting stuff together @@ -149,11 +169,12 @@ public MainView(AutoSuggestBox mainTextBlock) if (CoreTools.IsAdministrator() && !Settings.Get(Settings.K.AlreadyWarnedAboutAdmin)) { Settings.Set(Settings.K.AlreadyWarnedAboutAdmin, true); - _= DialogHelper.WarnAboutAdminRights(); + _ = DialogHelper.WarnAboutAdminRights(); } UpdateOperationsLayout(); - MainApp.Operations._operationList.CollectionChanged += (_, _) => UpdateOperationsLayout(); + MainApp.Operations._operationList.CollectionChanged += (_, _) => + UpdateOperationsLayout(); if (!Settings.Get(Settings.K.ShownTelemetryBanner)) { @@ -175,13 +196,13 @@ public void LoadDefaultPage() "installed" => PageType.Installed, "bundles" => PageType.Bundles, "settings" => PageType.Settings, - _ => MainApp.Tooltip.AvailableUpdates > 0 ? PageType.Updates : PageType.Discover + _ => MainApp.Tooltip.AvailableUpdates > 0 ? PageType.Updates : PageType.Discover, }; NavigateTo(type); } - private Page GetPageForType(PageType type) - => type switch + private Page GetPageForType(PageType type) => + type switch { PageType.Discover => DiscoverPage, PageType.Updates => UpdatesPage, @@ -194,11 +215,11 @@ private Page GetPageForType(PageType type) PageType.OperationHistory => OperationHistoryPage ??= new OperationHistoryPage(), PageType.Help => HelpPage ??= new HelpPage(), PageType.Null => throw new InvalidCastException("Page type is Null"), - _ => throw new InvalidDataException($"Unknown page type {type}") + _ => throw new InvalidDataException($"Unknown page type {type}"), }; - private static PageType GetNextPage(PageType type) - => type switch + private static PageType GetNextPage(PageType type) => + type switch { // Default loop PageType.Discover => PageType.Updates, @@ -214,11 +235,11 @@ private static PageType GetNextPage(PageType type) PageType.ManagerLog => PageType.Discover, PageType.Help => PageType.Discover, PageType.Null => PageType.Discover, - _ => throw new InvalidDataException($"Unknown page type {type}") + _ => throw new InvalidDataException($"Unknown page type {type}"), }; - private static PageType GetPreviousPage(PageType type) - => type switch + private static PageType GetPreviousPage(PageType type) => + type switch { // Default loop PageType.Discover => PageType.Settings, @@ -234,16 +255,17 @@ private static PageType GetPreviousPage(PageType type) PageType.ManagerLog => PageType.Discover, PageType.Help => PageType.Discover, PageType.Null => PageType.Discover, - _ => throw new InvalidDataException($"Unknown page type {type}") + _ => throw new InvalidDataException($"Unknown page type {type}"), }; - private void SettingsNavButton_Click(object sender, EventArgs e) - => NavigateTo(PageType.Settings); + private void SettingsNavButton_Click(object sender, EventArgs e) => + NavigateTo(PageType.Settings); - private void ManagersNavButton_Click(object sender, EventArgs e) - => NavigateTo(PageType.Managers); + private void ManagersNavButton_Click(object sender, EventArgs e) => + NavigateTo(PageType.Managers); private bool _lastNavItemSelectionWasAuto; + private void SelectNavButtonForPage(PageType page) { _lastNavItemSelectionWasAuto = true; @@ -260,7 +282,9 @@ private void SelectNavButtonForPage(PageType page) _lastNavItemSelectionWasAuto = false; } - private void AboutNavButton_Click(object sender, RoutedEventArgs e) => _ = _aboutNavButton_Click(); + private void AboutNavButton_Click(object sender, RoutedEventArgs e) => + _ = _aboutNavButton_Click(); + private async Task _aboutNavButton_Click() { SelectNavButtonForPage(PageType.Null); @@ -282,7 +306,7 @@ public void NavigateTo(PageType NewPage_t, bool toHistory = true) CurrentPage_t = NewPage_t; (oldPage as IEnterLeaveListener)?.OnLeave(); - if(oldPage is ISearchBoxPage oldSPage) + if (oldPage is ISearchBoxPage oldSPage) { MainTextBlock.TextChanged -= oldSPage.SearchBox_TextChanged; MainTextBlock.QuerySubmitted -= oldSPage.SearchBox_QuerySubmitted; @@ -324,43 +348,47 @@ public void NavigateBack() else { NavigateTo(NavigationHistory.Last(), toHistory: false); - NavigationHistory.RemoveAt(NavigationHistory.Count-1); + NavigationHistory.RemoveAt(NavigationHistory.Count - 1); CanGoBackChanged?.Invoke( this, - NavigationHistory.Any() || ((ContentFrame.Content as IInnerNavigationPage)?.CanGoBack() ?? false)); + NavigationHistory.Any() + || ((ContentFrame.Content as IInnerNavigationPage)?.CanGoBack() ?? false) + ); } } - private void ReleaseNotesMenu_Click(object sender, RoutedEventArgs e) - => _ = DialogHelper.ShowReleaseNotes(); + private void ReleaseNotesMenu_Click(object sender, RoutedEventArgs e) => + _ = DialogHelper.ShowReleaseNotes(); - private void OperationHistoryMenu_Click(object sender, RoutedEventArgs e) - => NavigateTo(PageType.OperationHistory); + private void OperationHistoryMenu_Click(object sender, RoutedEventArgs e) => + NavigateTo(PageType.OperationHistory); - private void ManagerLogsMenu_Click(object sender, RoutedEventArgs e) - => OpenManagerLogs(); + private void ManagerLogsMenu_Click(object sender, RoutedEventArgs e) => OpenManagerLogs(); public void OpenManagerLogs(IPackageManager? manager = null) { NavigateTo(PageType.ManagerLog); - if (manager is not null) ManagerLogPage?.LoadForManager(manager); + if (manager is not null) + ManagerLogPage?.LoadForManager(manager); } + public void OpenManagerSettings(IPackageManager? manager = null) { NavigateTo(PageType.Managers); - if (manager is not null) ManagersPage?.NavigateTo(manager); + if (manager is not null) + ManagersPage?.NavigateTo(manager); } + public void OpenSettingsPage(Type page) { NavigateTo(PageType.Settings); SettingsPage?.NavigateTo(page); } - public void UniGetUILogs_Click(object sender, RoutedEventArgs e) - => NavigateTo(PageType.OwnLog); + public void UniGetUILogs_Click(object sender, RoutedEventArgs e) => + NavigateTo(PageType.OwnLog); - private void HelpMenu_Click(object sender, RoutedEventArgs e) - => ShowHelp(); + private void HelpMenu_Click(object sender, RoutedEventArgs e) => ShowHelp(); public void ShowHelp(string uriAttachment = "") { @@ -368,8 +396,8 @@ public void ShowHelp(string uriAttachment = "") HelpPage?.NavigateTo(uriAttachment); } - private void QuitUniGetUI_Click(object sender, RoutedEventArgs e) - => MainApp.Instance.DisposeAndQuit(); + private void QuitUniGetUI_Click(object sender, RoutedEventArgs e) => + MainApp.Instance.DisposeAndQuit(); private bool ResizingOPLayout; private int OpListChanges; @@ -428,7 +456,10 @@ private void OperationScrollView_SizeChanged(object sender, SizeChangedEventArgs private void OperationSplitterMenuButton_Click(object sender, RoutedEventArgs e) { - OperationListMenu.ShowAt(OperationSplitterMenuButton, new FlyoutShowOptions { ShowMode = FlyoutShowMode.Standard }); + OperationListMenu.ShowAt( + OperationSplitterMenuButton, + new FlyoutShowOptions { ShowMode = FlyoutShowMode.Standard } + ); } private void ExpandCollapseOpList_Click(object sender, RoutedEventArgs e) @@ -477,20 +508,29 @@ private void ClearSuccessfulOps_Click(object sender, RoutedEventArgs e) } } - private void NavigationView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args) + private void NavigationView_SelectionChanged( + NavigationView sender, + NavigationViewSelectionChangedEventArgs args + ) { if (_lastNavItemSelectionWasAuto) return; - if(args.SelectedItem is CustomNavViewItem item && item.Tag is not PageType.Null) + if (args.SelectedItem is CustomNavViewItem item && item.Tag is not PageType.Null) { NavigateTo(item.Tag); } } - private void MoreNavBtn_Tapped(object sender, Microsoft.UI.Xaml.Input.TappedRoutedEventArgs e) + private void MoreNavBtn_Tapped( + object sender, + Microsoft.UI.Xaml.Input.TappedRoutedEventArgs e + ) { - (VersionMenuItem as MenuFlyoutItem).Text = CoreTools.Translate("WingetUI Version {0}", CoreData.VersionName); + (VersionMenuItem as MenuFlyoutItem).Text = CoreTools.Translate( + "WingetUI Version {0}", + CoreData.VersionName + ); MoreNavButtonMenu.ShowAt(sender as FrameworkElement); } @@ -500,7 +540,12 @@ internal void LoadBundleFromFile(string param) BundlesPage?.OpenFromFile(param); } - internal void LoadBundleFromString(string payload, BundleFormatType format, string source, int loadingId) + internal void LoadBundleFromString( + string payload, + BundleFormatType format, + string source, + int loadingId + ) { NavigateTo(PageType.Bundles); BundlesPage?.OpenFromString(payload, format, source, loadingId); @@ -511,7 +556,12 @@ private void ClearAllFinished_OnClick(object sender, RoutedEventArgs e) foreach (var widget in MainApp.Operations._operationList.ToArray()) { var operation = widget.Operation; - if (operation.Status is OperationStatus.Succeeded or OperationStatus.Failed or OperationStatus.Canceled) + if ( + operation.Status + is OperationStatus.Succeeded + or OperationStatus.Failed + or OperationStatus.Canceled + ) widget.Close(); } } diff --git a/src/UniGetUI/Pages/PageInterfaces/IKeyboardShortcutListener.cs b/src/UniGetUI/Pages/PageInterfaces/IKeyboardShortcutListener.cs index d01a80480a..85eb3606fc 100644 --- a/src/UniGetUI/Pages/PageInterfaces/IKeyboardShortcutListener.cs +++ b/src/UniGetUI/Pages/PageInterfaces/IKeyboardShortcutListener.cs @@ -1,4 +1,4 @@ -namespace UniGetUI.Interface.Pages +namespace UniGetUI.Interface.Pages { /// /// Any object that can perform any of the following listed actions should diff --git a/src/UniGetUI/Pages/PageInterfaces/ISearchBoxPage.cs b/src/UniGetUI/Pages/PageInterfaces/ISearchBoxPage.cs index 95b9d4dcac..fb7f75ce00 100644 --- a/src/UniGetUI/Pages/PageInterfaces/ISearchBoxPage.cs +++ b/src/UniGetUI/Pages/PageInterfaces/ISearchBoxPage.cs @@ -3,10 +3,14 @@ using Microsoft.UI.Xaml.Input; namespace UniGetUI.Pages.PageInterfaces; + internal interface ISearchBoxPage { public string QueryBackup { get; set; } public string SearchBoxPlaceholder { get; } public void SearchBox_TextChanged(object? sender, AutoSuggestBoxTextChangedEventArgs args); - public void SearchBox_QuerySubmitted(object? sender, AutoSuggestBoxQuerySubmittedEventArgs args); + public void SearchBox_QuerySubmitted( + object? sender, + AutoSuggestBoxQuerySubmittedEventArgs args + ); } diff --git a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Administrator.xaml b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Administrator.xaml index b907dc816d..4c1162b987 100644 --- a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Administrator.xaml +++ b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Administrator.xaml @@ -1,127 +1,140 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + x:Class="UniGetUI.Pages.SettingsPages.GeneralPages.Administrator" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:converters="using:CommunityToolkit.WinUI.Converters" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="using:UniGetUI.Pages.SettingsPages.GeneralPages" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:widgets="using:UniGetUI.Interface.Widgets" + Background="Transparent" + mc:Ignorable="d" +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Administrator.xaml.cs b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Administrator.xaml.cs index 68c9ba9d53..da97560ecb 100644 --- a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Administrator.xaml.cs +++ b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Administrator.xaml.cs @@ -23,27 +23,40 @@ public Administrator() WarningTitlebar.Title = CoreTools.Translate("Warning") + "!"; WarningTitlebar.Message = - CoreTools.Translate("The following settings may pose a security risk, hence they are disabled by default.") + " " + - CoreTools.Translate("Enable the settings below if and only if you fully understand what they do, and the implications they may have.") + "\n\n" + - CoreTools.Translate("The settings will list, in their descriptions, the potential security issues they may have.") + " "; - - AllowCustomManagerPaths.StateChanged += (_, _) => RestartRequired?.Invoke(this, EventArgs.Empty); + CoreTools.Translate( + "The following settings may pose a security risk, hence they are disabled by default." + ) + + " " + + CoreTools.Translate( + "Enable the settings below if and only if you fully understand what they do, and the implications they may have." + ) + + "\n\n" + + CoreTools.Translate( + "The settings will list, in their descriptions, the potential security issues they may have." + ) + + " "; + + AllowCustomManagerPaths.StateChanged += (_, _) => + RestartRequired?.Invoke(this, EventArgs.Empty); // The following settings may pose a security risk, hence they are disabled by default. Enable them ONLY if you undertsand what you are doing. Some of those settings will show a UAC prompt before being enabled." - } public bool CanGoBack => true; - public string ShortTitle => CoreTools.Translate("Administrator rights and other dangerous settings"); + public string ShortTitle => + CoreTools.Translate("Administrator rights and other dangerous settings"); public event EventHandler? RestartRequired; - public event EventHandler? NavigationRequested { add { } remove { } } - - public void ShowRestartBanner(object sender, EventArgs e) - => RestartRequired?.Invoke(this, e); + public event EventHandler? NavigationRequested + { + add { } + remove { } + } - public void RestartCache(object sender, EventArgs e) - => _ = CoreTools.ResetUACForCurrentProcess(); + public void ShowRestartBanner(object sender, EventArgs e) => + RestartRequired?.Invoke(this, e); + public void RestartCache(object sender, EventArgs e) => + _ = CoreTools.ResetUACForCurrentProcess(); } } diff --git a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Backup.xaml b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Backup.xaml index 9b4ef9bc6b..b083ae07f9 100644 --- a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Backup.xaml +++ b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Backup.xaml @@ -1,215 +1,232 @@ - - - - - + x:Class="UniGetUI.Pages.SettingsPages.GeneralPages.Backup" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:Toolkit="using:CommunityToolkit.WinUI.Controls" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="using:UniGetUI.Pages.SettingsPages.GeneralPages" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:services="using:UniGetUI.Services" + xmlns:widgets="using:UniGetUI.Interface.Widgets" + Background="Transparent" + mc:Ignorable="d" +> + + + + + + + - - - - - - - - - - - - - + Prefix=" ● " + Text="The backup will include the complete list of the installed packages and their installation options. Ignored updates and skipped versions will also be saved." + /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + Prefix=" ● " + Text="The backup will NOT include any binary file nor any program's saved data." + /> - - - - - - - - - - - - - - - - - - + Prefix=" ● " + Text="The size of the backup is estimated to be less than 1MB." + /> - - - - - - + Prefix=" ● " + Text="The backup will be performed after login." + /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Backup.xaml.cs b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Backup.xaml.cs index 040e264701..8ab5c784f5 100644 --- a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Backup.xaml.cs +++ b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Backup.xaml.cs @@ -28,6 +28,7 @@ public sealed partial class Backup : Page, ISettingsPage private readonly GitHubBackupService _backupService; private bool _isLoggedIn; private bool _isLoading; + public Backup() { this.InitializeComponent(); @@ -40,7 +41,8 @@ public Backup() OpenBackupDirectory.Content = CoreTools.Translate("Open"); GitHubAuthService.AuthStatusChanged += (_, _) => _ = UpdateGitHubLoginStatus(); - EnablePackageBackupCheckBox_CLOUD.StateChanged += EnablePackageBackupCheckBox_CLOUD_StateChanged; + EnablePackageBackupCheckBox_CLOUD.StateChanged += + EnablePackageBackupCheckBox_CLOUD_StateChanged; _ = UpdateGitHubLoginStatus(); } @@ -49,14 +51,20 @@ public Backup() public string ShortTitle => CoreTools.Translate("Backup and Restore"); public event EventHandler? RestartRequired; - public event EventHandler? NavigationRequested { add { } remove { } } + public event EventHandler? NavigationRequested + { + add { } + remove { } + } - public void ShowRestartBanner(object? sender, EventArgs e) - => RestartRequired?.Invoke(this, e); + public void ShowRestartBanner(object? sender, EventArgs e) => + RestartRequired?.Invoke(this, e); private void ChangeBackupDirectory_Click(object sender, EventArgs e) { - ExternalLibraries.Pickers.FolderPicker openPicker = new(MainApp.Instance.MainWindow.GetWindowHandle()); + ExternalLibraries.Pickers.FolderPicker openPicker = new( + MainApp.Instance.MainWindow.GetWindowHandle() + ); string folder = openPicker.Show(); if (folder != string.Empty) { @@ -82,7 +90,9 @@ public void EnablePackageBackupUI(bool enabled) } else { - BackupDirectoryLabel.Text = Settings.GetValue(Settings.K.ChangeBackupOutputDirectory); + BackupDirectoryLabel.Text = Settings.GetValue( + Settings.K.ChangeBackupOutputDirectory + ); ResetBackupDirectory.IsEnabled = true; } } @@ -98,18 +108,24 @@ private void ResetBackupPath_Click(object sender, RoutedEventArgs e) private void OpenBackupPath_Click(object sender, RoutedEventArgs e) { string directory = Settings.GetValue(Settings.K.ChangeBackupOutputDirectory); - if (directory == "") directory = CoreData.UniGetUI_DefaultBackupDirectory; + if (directory == "") + directory = CoreData.UniGetUI_DefaultBackupDirectory; directory = directory.Replace("/", "\\"); - if (!Directory.Exists(directory)) Directory.CreateDirectory(directory); + if (!Directory.Exists(directory)) + Directory.CreateDirectory(directory); CoreTools.Launch(directory); } - private void DoBackup_LOCAL_Click(object sender, EventArgs e) => _ = _doBackup_LOCAL_Click(); + private void DoBackup_LOCAL_Click(object sender, EventArgs e) => + _ = _doBackup_LOCAL_Click(); + private static async Task _doBackup_LOCAL_Click() { - int loadingId = DialogHelper.ShowLoadingDialog(CoreTools.Translate("Performing backup, please wait...")); + int loadingId = DialogHelper.ShowLoadingDialog( + CoreTools.Translate("Performing backup, please wait...") + ); await InstalledPackagesPage.BackupPackages_LOCAL(); DialogHelper.HideLoadingDialog(loadingId); } @@ -130,7 +146,9 @@ private async Task UpdateGitHubLoginStatus() } catch (Exception ex) { - Logger.Error("An error occurred while attempting to generate settings login UI: "); + Logger.Error( + "An error occurred while attempting to generate settings login UI: " + ); Logger.Error(ex); GenerateLoginUI(); } @@ -155,14 +173,23 @@ private void GenerateLoginUI() private async Task GenerateLogoutUI(GitHubAuthService authService) { var client = authService.CreateGitHubClient(); - if (client is null) throw new AuthenticationException("How can it be authenticated and fail to create a client?"); + if (client is null) + throw new AuthenticationException( + "How can it be authenticated and fail to create a client?" + ); var user = await client.User.Current(); _isLoggedIn = true; LogInButton.Visibility = Visibility.Collapsed; LogOutButton.Visibility = Visibility.Visible; - GitHubUserTitle.Text = CoreTools.Translate("You are logged in as {0} (@{1})", user.Name, user.Login); - GitHubUserSubtitle.Text = CoreTools.Translate("Nice! Backups will be uploaded to a private gist on your account"); + GitHubUserTitle.Text = CoreTools.Translate( + "You are logged in as {0} (@{1})", + user.Name, + user.Login + ); + GitHubUserSubtitle.Text = CoreTools.Translate( + "Nice! Backups will be uploaded to a private gist on your account" + ); GitHubImage.Initials = ""; GitHubImage.ProfilePicture = new BitmapImage(new Uri(user.AvatarUrl)); } @@ -175,7 +202,9 @@ private void UpdateCloudControlsEnabled() { EnablePackageBackupCheckBox_CLOUD.IsEnabled = true; RestorePackagesFromGitHubButton.IsEnabled = true; - BackupNowButton_Cloud.IsEnabled = Settings.Get(Settings.K.EnablePackageBackup_CLOUD); + BackupNowButton_Cloud.IsEnabled = Settings.Get( + Settings.K.EnablePackageBackup_CLOUD + ); } else { @@ -185,8 +214,8 @@ private void UpdateCloudControlsEnabled() } } - private void LoginWithGitHubButton_Click(object sender, RoutedEventArgs e) - => _ = _loginWithGitHubButton_Click(); + private void LoginWithGitHubButton_Click(object sender, RoutedEventArgs e) => + _ = _loginWithGitHubButton_Click(); private async Task _loginWithGitHubButton_Click() { @@ -216,13 +245,17 @@ private void LogoutGitHubButton_Click(object sender, RoutedEventArgs e) UpdateCloudControlsEnabled(); } - private void RestoreFromGitHubButton_Click(object sender, EventArgs e) => _ = _restoreFromGitHubButton_Click(); + private void RestoreFromGitHubButton_Click(object sender, EventArgs e) => + _ = _restoreFromGitHubButton_Click(); + private async Task _restoreFromGitHubButton_Click() { RestorePackagesFromGitHubButton.IsEnabled = false; try { - int loadingId = DialogHelper.ShowLoadingDialog(CoreTools.Translate("Fetching available backups...")); + int loadingId = DialogHelper.ShowLoadingDialog( + CoreTools.Translate("Fetching available backups...") + ); var availableBackups = await _backupService.GetAvailableBackups(); DialogHelper.HideLoadingDialog(loadingId); @@ -234,21 +267,30 @@ private async Task _restoreFromGitHubButton_Click() } selectedBackup = selectedBackup.Split(' ')[0]; - loadingId = DialogHelper.ShowLoadingDialog(CoreTools.Translate("Downloading backup...")); + loadingId = DialogHelper.ShowLoadingDialog( + CoreTools.Translate("Downloading backup...") + ); var backupContents = await _backupService.GetBackupContents(selectedBackup); // DialogHelper.HideLoadingDialog(loadingId); await Task.Delay(500); // Prevent race conditions with dialogs if (backupContents is null) - throw new DataException($"The backupContents for backup {selectedBackup} returned null"); + throw new DataException( + $"The backupContents for backup {selectedBackup} returned null" + ); Logger.Info("Successfully loaded package bundle from GitHub Gist."); DialogHelper.ShowDismissableBalloon( CoreTools.Translate("Done!"), - CoreTools.Translate("The cloud backup has been loaded successfully.")); + CoreTools.Translate("The cloud backup has been loaded successfully.") + ); MainApp.Instance.MainWindow.NavigationPage.LoadBundleFromString( - backupContents, BundleFormatType.UBUNDLE, $"GitHub Gist {selectedBackup}", loadingId); + backupContents, + BundleFormatType.UBUNDLE, + $"GitHub Gist {selectedBackup}", + loadingId + ); } catch (Exception ex) { @@ -258,17 +300,22 @@ private async Task _restoreFromGitHubButton_Click() DialogHelper.HideAllLoadingDialogs(); var errorDialog = DialogHelper.DialogFactory.Create(); errorDialog.Title = CoreTools.Translate("An error occurred"); - errorDialog.Content = CoreTools.Translate("An error occurred while loading a backup: ") + ex.Message; + errorDialog.Content = + CoreTools.Translate("An error occurred while loading a backup: ") + ex.Message; errorDialog.PrimaryButtonText = CoreTools.Translate("OK"); errorDialog.DefaultButton = ContentDialogButton.Primary; await DialogHelper.ShowDialogAsync(errorDialog); } } - private void BackupToGitHubButton_Click(object sender, EventArgs e) => _ = _backupToGitHubButton_Click(); + private void BackupToGitHubButton_Click(object sender, EventArgs e) => + _ = _backupToGitHubButton_Click(); + private async Task _backupToGitHubButton_Click() { - int loadingId = DialogHelper.ShowLoadingDialog(CoreTools.Translate("Backing up packages to GitHub Gist...")); + int loadingId = DialogHelper.ShowLoadingDialog( + CoreTools.Translate("Backing up packages to GitHub Gist...") + ); var packagesContent = await InstalledPackagesPage.GenerateBackupContents(); @@ -279,7 +326,8 @@ private async Task _backupToGitHubButton_Click() Logger.Info("Successfully backed up packages to GitHub Gist."); DialogHelper.ShowDismissableBalloon( CoreTools.Translate("Backup Successful"), - CoreTools.Translate("The cloud backup completed successfully.")); + CoreTools.Translate("The cloud backup completed successfully.") + ); } catch (Exception ex) { @@ -290,7 +338,8 @@ private async Task _backupToGitHubButton_Click() var dialog = DialogHelper.DialogFactory.Create(); dialog.Title = CoreTools.Translate("Backup Failed"); - dialog.Content = CoreTools.Translate("Could not back up packages to GitHub Gist: ") + ex.Message; + dialog.Content = + CoreTools.Translate("Could not back up packages to GitHub Gist: ") + ex.Message; dialog.PrimaryButtonText = CoreTools.Translate("OK"); dialog.DefaultButton = ContentDialogButton.Primary; await DialogHelper.ShowDialogAsync(dialog); diff --git a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Experimental.xaml b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Experimental.xaml index 93f8c07ca4..6d496ab295 100644 --- a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Experimental.xaml +++ b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Experimental.xaml @@ -1,108 +1,116 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + x:Class="UniGetUI.Pages.SettingsPages.GeneralPages.Experimental" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="using:UniGetUI.Pages.SettingsPages.GeneralPages" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:widgets="using:UniGetUI.Interface.Widgets" + Background="Transparent" + mc:Ignorable="d" +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Experimental.xaml.cs b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Experimental.xaml.cs index 38799dab5a..ffa26dabcd 100644 --- a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Experimental.xaml.cs +++ b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Experimental.xaml.cs @@ -18,12 +18,17 @@ public Experimental() public bool CanGoBack => true; - public string ShortTitle => CoreTools.Translate("Experimental settings and developer options"); + public string ShortTitle => + CoreTools.Translate("Experimental settings and developer options"); public event EventHandler? RestartRequired; - public event EventHandler? NavigationRequested { add { } remove { } } + public event EventHandler? NavigationRequested + { + add { } + remove { } + } - public void ShowRestartBanner(object sender, EventArgs e) - => RestartRequired?.Invoke(this, e); + public void ShowRestartBanner(object sender, EventArgs e) => + RestartRequired?.Invoke(this, e); } } diff --git a/src/UniGetUI/Pages/SettingsPages/GeneralPages/General.xaml b/src/UniGetUI/Pages/SettingsPages/GeneralPages/General.xaml index f8f8809be4..a9176ed09c 100644 --- a/src/UniGetUI/Pages/SettingsPages/GeneralPages/General.xaml +++ b/src/UniGetUI/Pages/SettingsPages/GeneralPages/General.xaml @@ -1,51 +1,53 @@ - - - + x:Class="UniGetUI.Pages.SettingsPages.GeneralPages.General" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:Toolkit="using:CommunityToolkit.WinUI.Controls" + xmlns:controls="using:CommunityToolkit.WinUI.Controls" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="using:UniGetUI.Pages.SettingsPages.GeneralPages" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:widgets="using:UniGetUI.Interface.Widgets" + Background="Transparent" + mc:Ignorable="d" +> + + + + + + - - - - - - - - - - - - - + - - + + - + - + - - - - - + - + + + - - - - - - - - - - - + - - + + + + + + + + + + + + + diff --git a/src/UniGetUI/Pages/SettingsPages/GeneralPages/General.xaml.cs b/src/UniGetUI/Pages/SettingsPages/GeneralPages/General.xaml.cs index f4d5cc1e50..68b1c99ced 100644 --- a/src/UniGetUI/Pages/SettingsPages/GeneralPages/General.xaml.cs +++ b/src/UniGetUI/Pages/SettingsPages/GeneralPages/General.xaml.cs @@ -1,10 +1,10 @@ using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; -using UniGetUI.Core.Tools; -using UniGetUI.Pages.DialogPages; -using UniGetUI.Core.Logging; using UniGetUI.Core.Language; +using UniGetUI.Core.Logging; using UniGetUI.Core.SettingsEngine; +using UniGetUI.Core.Tools; +using UniGetUI.Pages.DialogPages; // To learn more about WinUI, the WinUI project structure, // and more about our project templates, see: http://aka.ms/winui-project-info. @@ -20,12 +20,19 @@ public General() { this.InitializeComponent(); - Dictionary lang_dict = new(LanguageData.LanguageReference.AsEnumerable()); + Dictionary lang_dict = new( + LanguageData.LanguageReference.AsEnumerable() + ); foreach (string key in lang_dict.Keys) { - if (key != "en" && - LanguageData.TranslationPercentages.TryGetValue(key, out var translationPercentage)) + if ( + key != "en" + && LanguageData.TranslationPercentages.TryGetValue( + key, + out var translationPercentage + ) + ) { lang_dict[key] = lang_dict[key] + " (" + translationPercentage + ")"; } @@ -47,27 +54,38 @@ public General() public event EventHandler? RestartRequired; public event EventHandler? NavigationRequested; - public void ShowRestartBanner(object sender, EventArgs e) - => RestartRequired?.Invoke(this, e); + public void ShowRestartBanner(object sender, EventArgs e) => + RestartRequired?.Invoke(this, e); private void ForceUpdateUniGetUI_OnClick(object sender, RoutedEventArgs e) { var mainWindow = MainApp.Instance.MainWindow; - _ = AutoUpdater.CheckAndInstallUpdates(mainWindow, mainWindow.UpdatesBanner, true, false, true); + _ = AutoUpdater.CheckAndInstallUpdates( + mainWindow, + mainWindow.UpdatesBanner, + true, + false, + true + ); } - private void ManageTelemetrySettings_Click(object sender, EventArgs e) - => _ = DialogHelper.ShowTelemetryDialog(); + private void ManageTelemetrySettings_Click(object sender, EventArgs e) => + _ = DialogHelper.ShowTelemetryDialog(); private void ImportSettings_Click(object sender, EventArgs e) => _ = _importSettings(); + private async Task _importSettings() { - ExternalLibraries.Pickers.FileOpenPicker picker = new(MainApp.Instance.MainWindow.GetWindowHandle()); + ExternalLibraries.Pickers.FileOpenPicker picker = new( + MainApp.Instance.MainWindow.GetWindowHandle() + ); string file = picker.Show(["*.json"]); if (file != string.Empty) { - int loadingId = DialogHelper.ShowLoadingDialog(CoreTools.Translate("Please wait...")); + int loadingId = DialogHelper.ShowLoadingDialog( + CoreTools.Translate("Please wait...") + ); await Task.Run(() => Settings.ImportFromFile_JSON(file)); DialogHelper.HideLoadingDialog(loadingId); ShowRestartBanner(this, new()); @@ -75,16 +93,24 @@ private async Task _importSettings() } private void ExportSettings_Click(object sender, EventArgs e) => _ = _exportSettings(); + private static async Task _exportSettings() { try { - ExternalLibraries.Pickers.FileSavePicker picker = new(MainApp.Instance.MainWindow.GetWindowHandle()); - string file = picker.Show(["*.json"], CoreTools.Translate("WingetUI Settings") + ".json"); + ExternalLibraries.Pickers.FileSavePicker picker = new( + MainApp.Instance.MainWindow.GetWindowHandle() + ); + string file = picker.Show( + ["*.json"], + CoreTools.Translate("WingetUI Settings") + ".json" + ); if (file != string.Empty) { - int loadingId = DialogHelper.ShowLoadingDialog(CoreTools.Translate("Please wait...")); + int loadingId = DialogHelper.ShowLoadingDialog( + CoreTools.Translate("Please wait...") + ); await Task.Run(() => Settings.ExportToFile_JSON(file)); DialogHelper.HideLoadingDialog(loadingId); _ = CoreTools.ShowFileOnExplorer(file); diff --git a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Interface_P.xaml b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Interface_P.xaml index 06af52c0b3..11b4999288 100644 --- a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Interface_P.xaml +++ b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Interface_P.xaml @@ -1,92 +1,91 @@ + x:Class="UniGetUI.Pages.SettingsPages.GeneralPages.Interface_P" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="using:UniGetUI.Pages.SettingsPages.GeneralPages" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:widgets="using:UniGetUI.Interface.Widgets" + Background="Transparent" + mc:Ignorable="d" +> + + + - - + + + - + + - - + + + - + + - - - - - - - - - - - - - - - + + + diff --git a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Interface_P.xaml.cs b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Interface_P.xaml.cs index 20b570227a..f4eb0ad747 100644 --- a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Interface_P.xaml.cs +++ b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Interface_P.xaml.cs @@ -1,10 +1,10 @@ +using System.Diagnostics; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Navigation; -using UniGetUI.Core.Tools; using UniGetUI.Core.Data; using UniGetUI.Core.Logging; using UniGetUI.Core.SettingsEngine; -using System.Diagnostics; +using UniGetUI.Core.Tools; // To learn more about WinUI, the WinUI project structure, // and more about our project templates, see: http://aka.ms/winui-project-info. @@ -33,11 +33,13 @@ public Interface_P() StartupPageSelector.AddItem(CoreTools.AutoTranslated("Default"), "default"); StartupPageSelector.AddItem(CoreTools.AutoTranslated("Discover Packages"), "discover"); StartupPageSelector.AddItem(CoreTools.AutoTranslated("Software Updates"), "updates"); - StartupPageSelector.AddItem(CoreTools.AutoTranslated("Installed Packages"), "installed"); + StartupPageSelector.AddItem( + CoreTools.AutoTranslated("Installed Packages"), + "installed" + ); StartupPageSelector.AddItem(CoreTools.AutoTranslated("Package Bundles"), "bundles"); StartupPageSelector.AddItem(CoreTools.AutoTranslated("Settings"), "settings"); StartupPageSelector.ShowAddedItems(); - } protected override void OnNavigatedTo(NavigationEventArgs e) @@ -51,10 +53,14 @@ protected override void OnNavigatedTo(NavigationEventArgs e) public string ShortTitle => CoreTools.Translate("User interface preferences"); public event EventHandler? RestartRequired; - public event EventHandler? NavigationRequested { add { } remove { } } + public event EventHandler? NavigationRequested + { + add { } + remove { } + } - public void ShowRestartBanner(object sender, EventArgs e) - => RestartRequired?.Invoke(this, e); + public void ShowRestartBanner(object sender, EventArgs e) => + RestartRequired?.Invoke(this, e); private void ResetIconCache_OnClick(object sender, EventArgs e) { @@ -75,22 +81,33 @@ private void ResetIconCache_OnClick(object sender, EventArgs e) private async Task LoadIconCacheSize() { - double realSize = (await Task.Run(() => - { - return Directory.GetFiles(CoreData.UniGetUICacheDirectory_Icons, "*", SearchOption.AllDirectories) - .Sum(file => new FileInfo(file).Length); - })) / 1048576d; + double realSize = + ( + await Task.Run(() => + { + return Directory + .GetFiles( + CoreData.UniGetUICacheDirectory_Icons, + "*", + SearchOption.AllDirectories + ) + .Sum(file => new FileInfo(file).Length); + }) + ) / 1048576d; double roundedSize = ((int)(realSize * 100)) / 100d; - ResetIconCache.Header = CoreTools.Translate("The local icon cache currently takes {0} MB", roundedSize); + ResetIconCache.Header = CoreTools.Translate( + "The local icon cache currently takes {0} MB", + roundedSize + ); } - private void DisableSystemTray_StateChanged(object sender, EventArgs e) - => MainApp.Instance.MainWindow.UpdateSystemTrayStatus(); + private void DisableSystemTray_StateChanged(object sender, EventArgs e) => + MainApp.Instance.MainWindow.UpdateSystemTrayStatus(); - private void ThemeSelector_ValueChanged(object sender, EventArgs e) - => MainApp.Instance.MainWindow.ApplyTheme(); + private void ThemeSelector_ValueChanged(object sender, EventArgs e) => + MainApp.Instance.MainWindow.ApplyTheme(); - private void EditAutostartSettings_Click(object sender, EventArgs e) - => CoreTools.Launch("ms-settings:startupapps"); + private void EditAutostartSettings_Click(object sender, EventArgs e) => + CoreTools.Launch("ms-settings:startupapps"); } } diff --git a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Internet.xaml b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Internet.xaml index 21e3810f6e..40eea8b1c1 100644 --- a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Internet.xaml +++ b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Internet.xaml @@ -1,176 +1,179 @@ - - - - - - - - + x:Class="UniGetUI.Pages.SettingsPages.GeneralPages.Internet" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:controls="using:CommunityToolkit.WinUI.Controls" + xmlns:converters="using:CommunityToolkit.WinUI.Converters" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="using:UniGetUI.Pages.SettingsPages.GeneralPages" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:widgets="using:UniGetUI.Interface.Widgets" + Background="Transparent" + mc:Ignorable="d" +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + Grid.Column="1" + FontWeight="Bold" + Text="Package manager" + WrappingMode="WrapWholeWords" + /> - - - - - - - + Grid.Column="2" + FontWeight="Bold" + Text="Compatible with proxy" + WrappingMode="WrapWholeWords" + /> + + + + + + + + + + + + + + diff --git a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Internet.xaml.cs b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Internet.xaml.cs index c98f787303..21cfb1e0ec 100644 --- a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Internet.xaml.cs +++ b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Internet.xaml.cs @@ -17,7 +17,6 @@ namespace UniGetUI.Pages.SettingsPages.GeneralPages /// public sealed partial class Internet : Page, ISettingsPage { - public Internet() { this.InitializeComponent(); @@ -32,9 +31,12 @@ public Internet() PasswordBox.Password = creds.Password; } - Brush SUCCESS_BG = (Brush)Application.Current.Resources["SystemFillColorSuccessBackgroundBrush"]; - Brush WARN_BG = (Brush)Application.Current.Resources["SystemFillColorCautionBackgroundBrush"]; - Brush ERROR_BG = (Brush)Application.Current.Resources["SystemFillColorCriticalBackgroundBrush"]; + Brush SUCCESS_BG = (Brush) + Application.Current.Resources["SystemFillColorSuccessBackgroundBrush"]; + Brush WARN_BG = (Brush) + Application.Current.Resources["SystemFillColorCautionBackgroundBrush"]; + Brush ERROR_BG = (Brush) + Application.Current.Resources["SystemFillColorCriticalBackgroundBrush"]; Brush BORDER_FG = (Brush)Application.Current.Resources["CardStrokeColorDefaultBrush"]; Brush TEXT_FG = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"]; @@ -44,73 +46,92 @@ public Internet() foreach (var manager in PEInterface.Managers) { - ManagersPanel.Children.Add(new TextBlock() - { - Text = manager.DisplayName, - TextAlignment = TextAlignment.Center, - Padding = new Thickness(3) - }); - - var level = manager.Capabilities.SupportsProxy; - ProxyPanel.Children.Add(new Border() - { - CornerRadius = new CornerRadius(4), - Padding = new Thickness(2), - Background = level is ProxySupport.No? ERROR_BG: (level is ProxySupport.Partially? WARN_BG: SUCCESS_BG), - BorderBrush = BORDER_FG, - BorderThickness = new Thickness(1), - Child = new TextBlock() + ManagersPanel.Children.Add( + new TextBlock() { - Text = (level is ProxySupport.No ? no : (level is ProxySupport.Partially ? part: yes)), + Text = manager.DisplayName, TextAlignment = TextAlignment.Center, - Foreground = TEXT_FG + Padding = new Thickness(3), } - }); - - AuthPanel.Children.Add(new Border() - { - CornerRadius = new CornerRadius(4), - Padding = new Thickness(2), - Background = manager.Capabilities.SupportsProxyAuth ? SUCCESS_BG : ERROR_BG, - BorderBrush = BORDER_FG, - BorderThickness = new Thickness(1), - Child = new TextBlock() + ); + + var level = manager.Capabilities.SupportsProxy; + ProxyPanel.Children.Add( + new Border() { - Text = manager.Capabilities.SupportsProxyAuth ? yes : no, - TextAlignment = TextAlignment.Center, - Foreground = TEXT_FG + CornerRadius = new CornerRadius(4), + Padding = new Thickness(2), + Background = + level is ProxySupport.No + ? ERROR_BG + : (level is ProxySupport.Partially ? WARN_BG : SUCCESS_BG), + BorderBrush = BORDER_FG, + BorderThickness = new Thickness(1), + Child = new TextBlock() + { + Text = ( + level is ProxySupport.No + ? no + : (level is ProxySupport.Partially ? part : yes) + ), + TextAlignment = TextAlignment.Center, + Foreground = TEXT_FG, + }, } - }); + ); + AuthPanel.Children.Add( + new Border() + { + CornerRadius = new CornerRadius(4), + Padding = new Thickness(2), + Background = manager.Capabilities.SupportsProxyAuth ? SUCCESS_BG : ERROR_BG, + BorderBrush = BORDER_FG, + BorderThickness = new Thickness(1), + Child = new TextBlock() + { + Text = manager.Capabilities.SupportsProxyAuth ? yes : no, + TextAlignment = TextAlignment.Center, + Foreground = TEXT_FG, + }, + } + ); } - } public bool CanGoBack => true; public string ShortTitle => CoreTools.Translate("Internet connection settings"); public event EventHandler? RestartRequired; - public event EventHandler? NavigationRequested { add { } remove { } } + public event EventHandler? NavigationRequested + { + add { } + remove { } + } + + public void ShowRestartBanner(object sender, EventArgs e) => + RestartRequired?.Invoke(this, e); - public void ShowRestartBanner(object sender, EventArgs e) - => RestartRequired?.Invoke(this, e); + private void UsernameBox_TextChanged(object sender, RoutedEventArgs e) => + _ = _usernameBox_TextChanged(); - private void UsernameBox_TextChanged(object sender, RoutedEventArgs e) => _ = _usernameBox_TextChanged(); private async Task _usernameBox_TextChanged() { SavingUserName.Opacity = 1; string oldusername = UsernameBox.Text; string oldpassword = PasswordBox.Password; await Task.Delay(500); - if (oldusername != UsernameBox.Text) return; - if (oldpassword != PasswordBox.Password) return; + if (oldusername != UsernameBox.Text) + return; + if (oldpassword != PasswordBox.Password) + return; Settings.SetProxyCredentials(UsernameBox.Text, PasswordBox.Password); MainWindow.ApplyProxyVariableToProcess(); SavingUserName.Opacity = 0; } - private void UsernameBox_TextChanged(object sender, TextChangedEventArgs e) - => UsernameBox_TextChanged(sender, new RoutedEventArgs()); + private void UsernameBox_TextChanged(object sender, TextChangedEventArgs e) => + UsernameBox_TextChanged(sender, new RoutedEventArgs()); private void EnableProxy_OnStateChanged(object? sender, EventArgs e) { diff --git a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Notifications.xaml b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Notifications.xaml index acc9feb4cb..809dfe9d6c 100644 --- a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Notifications.xaml +++ b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Notifications.xaml @@ -1,77 +1,84 @@ + x:Class="UniGetUI.Pages.SettingsPages.GeneralPages.Notifications" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="using:UniGetUI.Pages.SettingsPages.GeneralPages" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:widgets="using:UniGetUI.Interface.Widgets" + Background="Transparent" + mc:Ignorable="d" +> + + + - - + + - + - - + + - - - - - - - - - - + + + + diff --git a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Notifications.xaml.cs b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Notifications.xaml.cs index 15e7f1ced7..8e5667c162 100644 --- a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Notifications.xaml.cs +++ b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Notifications.xaml.cs @@ -1,8 +1,8 @@ using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Navigation; -using UniGetUI.Core.Tools; using UniGetUI.Core.SettingsEngine; +using UniGetUI.Core.Tools; // To learn more about WinUI, the WinUI project structure, // and more about our project templates, see: http://aka.ms/winui-project-info. @@ -45,7 +45,15 @@ protected override void OnNavigatedTo(NavigationEventArgs e) public bool CanGoBack => true; public string ShortTitle => CoreTools.Translate("Notification preferences"); - public event EventHandler? RestartRequired { add { } remove { } } - public event EventHandler? NavigationRequested { add { } remove { } } + public event EventHandler? RestartRequired + { + add { } + remove { } + } + public event EventHandler? NavigationRequested + { + add { } + remove { } + } } } diff --git a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Operations.xaml b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Operations.xaml index 7fb430aa93..6c2b4f37c1 100644 --- a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Operations.xaml +++ b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Operations.xaml @@ -1,106 +1,112 @@ + x:Class="UniGetUI.Pages.SettingsPages.GeneralPages.Operations" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:controls="using:CommunityToolkit.WinUI.Controls" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="using:UniGetUI.Pages.SettingsPages.GeneralPages" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:widgets="using:UniGetUI.Interface.Widgets" + Background="Transparent" + mc:Ignorable="d" +> + + + - - + - + - + - + - + - + + - + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + diff --git a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Operations.xaml.cs b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Operations.xaml.cs index b43233f97f..f4f5dafc78 100644 --- a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Operations.xaml.cs +++ b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Operations.xaml.cs @@ -1,8 +1,8 @@ using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using UniGetUI.Core.Tools; -using UniGetUI.Pages.DialogPages; using UniGetUI.PackageOperations; +using UniGetUI.Pages.DialogPages; // To learn more about WinUI, the WinUI project structure, // and more about our project templates, see: http://aka.ms/winui-project-info. @@ -32,10 +32,11 @@ public Operations() ParallelOperationCount.ShowAddedItems(); } - public void ShowRestartBanner(object sender, EventArgs e) - => RestartRequired?.Invoke(this, e); - private void ManageDesktopShortcutsButton_Click(object sender, RoutedEventArgs e) - => _ = DialogHelper.ManageDesktopShortcuts(); + public void ShowRestartBanner(object sender, EventArgs e) => + RestartRequired?.Invoke(this, e); + + private void ManageDesktopShortcutsButton_Click(object sender, RoutedEventArgs e) => + _ = DialogHelper.ManageDesktopShortcuts(); public bool CanGoBack => true; public string ShortTitle => CoreTools.Translate("Package operation preferences"); diff --git a/src/UniGetUI/Pages/SettingsPages/GeneralPages/SettingsHomepage.xaml b/src/UniGetUI/Pages/SettingsPages/GeneralPages/SettingsHomepage.xaml index 6a9f804a67..bd5b7ba151 100644 --- a/src/UniGetUI/Pages/SettingsPages/GeneralPages/SettingsHomepage.xaml +++ b/src/UniGetUI/Pages/SettingsPages/GeneralPages/SettingsHomepage.xaml @@ -1,126 +1,136 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + x:Class="UniGetUI.Pages.SettingsPages.SettingsHomepage" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="using:UniGetUI.Pages.SettingsPages" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:widgets="using:UniGetUI.Interface.Widgets" + Background="Transparent" + NavigationCacheMode="Required" + mc:Ignorable="d" +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/UniGetUI/Pages/SettingsPages/GeneralPages/SettingsHomepage.xaml.cs b/src/UniGetUI/Pages/SettingsPages/GeneralPages/SettingsHomepage.xaml.cs index f3c5eaa7e4..9e0840b1f6 100644 --- a/src/UniGetUI/Pages/SettingsPages/GeneralPages/SettingsHomepage.xaml.cs +++ b/src/UniGetUI/Pages/SettingsPages/GeneralPages/SettingsHomepage.xaml.cs @@ -16,7 +16,11 @@ public sealed partial class SettingsHomepage : Page, ISettingsPage public bool CanGoBack => false; public string ShortTitle => CoreTools.Translate("WingetUI Settings"); - public event EventHandler? RestartRequired { add { } remove { } } + public event EventHandler? RestartRequired + { + add { } + remove { } + } public event EventHandler? NavigationRequested; @@ -24,15 +28,35 @@ public SettingsHomepage() { this.InitializeComponent(); } - public void Administrator(object s, RoutedEventArgs e) => NavigationRequested?.Invoke(this, typeof(Administrator)); - public void Backup(object s, RoutedEventArgs e) => NavigationRequested?.Invoke(this, typeof(Backup)); - public void Experimental(object s, RoutedEventArgs e) => NavigationRequested?.Invoke(this, typeof(Experimental)); - public void General(object s, RoutedEventArgs e) => NavigationRequested?.Invoke(this, typeof(General)); - public void Interface(object s, RoutedEventArgs e) => NavigationRequested?.Invoke(this, typeof(Interface_P)); - public void Notifications(object s, RoutedEventArgs e) => NavigationRequested?.Invoke(this, typeof(Notifications)); - public void Operations(object s, RoutedEventArgs e) => NavigationRequested?.Invoke(this, typeof(Operations)); - public void Startup(object s, RoutedEventArgs e) => NavigationRequested?.Invoke(this, typeof(Updates)); - private void Internet(object sender, RoutedEventArgs e) => NavigationRequested?.Invoke(this, typeof(Internet)); - private void ManagersShortcut(object sender, RoutedEventArgs e) => NavigationRequested?.Invoke(this, typeof(ManagersHomepage)); + + public void Administrator(object s, RoutedEventArgs e) => + NavigationRequested?.Invoke(this, typeof(Administrator)); + + public void Backup(object s, RoutedEventArgs e) => + NavigationRequested?.Invoke(this, typeof(Backup)); + + public void Experimental(object s, RoutedEventArgs e) => + NavigationRequested?.Invoke(this, typeof(Experimental)); + + public void General(object s, RoutedEventArgs e) => + NavigationRequested?.Invoke(this, typeof(General)); + + public void Interface(object s, RoutedEventArgs e) => + NavigationRequested?.Invoke(this, typeof(Interface_P)); + + public void Notifications(object s, RoutedEventArgs e) => + NavigationRequested?.Invoke(this, typeof(Notifications)); + + public void Operations(object s, RoutedEventArgs e) => + NavigationRequested?.Invoke(this, typeof(Operations)); + + public void Startup(object s, RoutedEventArgs e) => + NavigationRequested?.Invoke(this, typeof(Updates)); + + private void Internet(object sender, RoutedEventArgs e) => + NavigationRequested?.Invoke(this, typeof(Internet)); + + private void ManagersShortcut(object sender, RoutedEventArgs e) => + NavigationRequested?.Invoke(this, typeof(ManagersHomepage)); } } diff --git a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Updates.xaml b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Updates.xaml index e2dd591259..ba1ae92bee 100644 --- a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Updates.xaml +++ b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Updates.xaml @@ -1,117 +1,119 @@ + x:Class="UniGetUI.Pages.SettingsPages.GeneralPages.Updates" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:controls="using:CommunityToolkit.WinUI.Controls" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="using:UniGetUI.Pages.SettingsPages.GeneralPages" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:widgets="using:UniGetUI.Interface.Widgets" + Background="Transparent" + mc:Ignorable="d" +> + + + - - - + - + - + - + - + - + - + - + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + diff --git a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Updates.xaml.cs b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Updates.xaml.cs index 4ef08b97eb..1485c465fe 100644 --- a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Updates.xaml.cs +++ b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Updates.xaml.cs @@ -1,6 +1,6 @@ +using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using UniGetUI.Core.Tools; -using Microsoft.UI.Xaml; // To learn more about WinUI, the WinUI project structure, // and more about our project templates, see: http://aka.ms/winui-project-info. @@ -17,19 +17,19 @@ public Updates() this.InitializeComponent(); Dictionary updates_dict = new() - { - { CoreTools.Translate("{0} minutes", 10), "600" }, - { CoreTools.Translate("{0} minutes", 30), "1800" }, - { CoreTools.Translate("1 hour"), "3600" }, - { CoreTools.Translate("{0} hours", 2), "7200" }, - { CoreTools.Translate("{0} hours", 4), "14400" }, - { CoreTools.Translate("{0} hours", 8), "28800" }, - { CoreTools.Translate("{0} hours", 12), "43200" }, - { CoreTools.Translate("1 day"), "86400" }, - { CoreTools.Translate("{0} days", 2), "172800" }, - { CoreTools.Translate("{0} days", 3), "259200" }, - { CoreTools.Translate("1 week"), "604800" } - }; + { + { CoreTools.Translate("{0} minutes", 10), "600" }, + { CoreTools.Translate("{0} minutes", 30), "1800" }, + { CoreTools.Translate("1 hour"), "3600" }, + { CoreTools.Translate("{0} hours", 2), "7200" }, + { CoreTools.Translate("{0} hours", 4), "14400" }, + { CoreTools.Translate("{0} hours", 8), "28800" }, + { CoreTools.Translate("{0} hours", 12), "43200" }, + { CoreTools.Translate("1 day"), "86400" }, + { CoreTools.Translate("{0} days", 2), "172800" }, + { CoreTools.Translate("{0} days", 3), "259200" }, + { CoreTools.Translate("1 week"), "604800" }, + }; foreach (KeyValuePair entry in updates_dict) { @@ -45,8 +45,8 @@ public Updates() public event EventHandler? RestartRequired; public event EventHandler? NavigationRequested; - public void ShowRestartBanner(object sender, EventArgs e) - => RestartRequired?.Invoke(this, e); + public void ShowRestartBanner(object sender, EventArgs e) => + RestartRequired?.Invoke(this, e); private void OperationsSettingsButton_Click(object sender, RoutedEventArgs e) { diff --git a/src/UniGetUI/Pages/SettingsPages/ManagersPages/ManagersHomepage.xaml b/src/UniGetUI/Pages/SettingsPages/ManagersPages/ManagersHomepage.xaml index 602cdcafff..958f83c109 100644 --- a/src/UniGetUI/Pages/SettingsPages/ManagersPages/ManagersHomepage.xaml +++ b/src/UniGetUI/Pages/SettingsPages/ManagersPages/ManagersHomepage.xaml @@ -1,23 +1,24 @@ - - - - + x:Class="UniGetUI.Pages.SettingsPages.ManagersHomepage" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="using:UniGetUI.Pages.SettingsPages" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + Background="Transparent" + NavigationCacheMode="Required" + mc:Ignorable="d" +> + + + diff --git a/src/UniGetUI/Pages/SettingsPages/ManagersPages/ManagersHomepage.xaml.cs b/src/UniGetUI/Pages/SettingsPages/ManagersPages/ManagersHomepage.xaml.cs index a23e0c47d7..faadb6e64f 100644 --- a/src/UniGetUI/Pages/SettingsPages/ManagersPages/ManagersHomepage.xaml.cs +++ b/src/UniGetUI/Pages/SettingsPages/ManagersPages/ManagersHomepage.xaml.cs @@ -1,15 +1,15 @@ -using Windows.UI.Text; +using CommunityToolkit.WinUI; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Media; using Microsoft.UI.Xaml.Navigation; +using UniGetUI.Core.SettingsEngine; using UniGetUI.Core.Tools; using UniGetUI.Interface.Widgets; -using UniGetUI.Pages.SettingsPages.GeneralPages; using UniGetUI.PackageEngine; -using UniGetUI.Core.SettingsEngine; using UniGetUI.Pages.DialogPages; -using CommunityToolkit.WinUI; +using UniGetUI.Pages.SettingsPages.GeneralPages; +using Windows.UI.Text; // To learn more about WinUI, the WinUI project structure, // and more about our project templates, see: http://aka.ms/winui-project-info. @@ -24,37 +24,51 @@ public sealed partial class ManagersHomepage : Page, ISettingsPage public bool CanGoBack => false; public string ShortTitle => CoreTools.Translate("Package manager preferences"); - public event EventHandler? RestartRequired { add { } remove { } } + public event EventHandler? RestartRequired + { + add { } + remove { } + } public event EventHandler? NavigationRequested; private readonly List managerControls = new(); private bool _isLoadingToggles; + public ManagersHomepage() { this.InitializeComponent(); bool first = true; - foreach(var manager in PEInterface.Managers) + foreach (var manager in PEInterface.Managers) { var button = new SettingsPageButton() { Text = manager.DisplayName, Description = manager.Properties.Description.Split("
")[0], HeaderIcon = new LocalIcon(manager.Properties.IconId), - Padding = new Thickness(16, 2, 16, 2) + Padding = new Thickness(16, 2, 16, 2), }; button.CornerRadius = first ? new CornerRadius(8, 8, 0, 0) : new CornerRadius(0); - button.BorderThickness = first ? new Thickness(1) : new Thickness(1,0,1,1); + button.BorderThickness = first ? new Thickness(1) : new Thickness(1, 0, 1, 1); button.Click += (_, _) => NavigationRequested?.Invoke(this, manager.GetType()); - var statusIcon = new FontIcon() { FontSize = 12, VerticalAlignment = VerticalAlignment.Center }; - var statusText = new TextBlock() { FontSize = 12, FontWeight = new FontWeight(600), VerticalAlignment = VerticalAlignment.Center }; + var statusIcon = new FontIcon() + { + FontSize = 12, + VerticalAlignment = VerticalAlignment.Center, + }; + var statusText = new TextBlock() + { + FontSize = 12, + FontWeight = new FontWeight(600), + VerticalAlignment = VerticalAlignment.Center, + }; var statusBorder = new Border() { CornerRadius = new CornerRadius(4), - Padding = new Thickness(6, 3, 6, 3) + Padding = new Thickness(6, 3, 6, 3), }; void loadStatusBadge() @@ -63,22 +77,28 @@ void loadStatusBadge() { statusText.Text = CoreTools.Translate("Disabled"); statusIcon.Glyph = "\uE814"; - statusIcon.Foreground = (Brush)Application.Current.Resources["SystemFillColorCautionBrush"]; - statusBorder.Background = (Brush)Application.Current.Resources["SystemFillColorCautionBackgroundBrush"]; + statusIcon.Foreground = (Brush) + Application.Current.Resources["SystemFillColorCautionBrush"]; + statusBorder.Background = (Brush) + Application.Current.Resources["SystemFillColorCautionBackgroundBrush"]; } else if (manager.Status.Found) { statusText.Text = CoreTools.Translate("Ready"); statusIcon.Glyph = "\uEC61"; - statusIcon.Foreground = (Brush)Application.Current.Resources["SystemFillColorSuccessBrush"]; - statusBorder.Background = (Brush)Application.Current.Resources["SystemFillColorSuccessBackgroundBrush"]; + statusIcon.Foreground = (Brush) + Application.Current.Resources["SystemFillColorSuccessBrush"]; + statusBorder.Background = (Brush) + Application.Current.Resources["SystemFillColorSuccessBackgroundBrush"]; } else { statusText.Text = CoreTools.Translate("Not found"); statusIcon.Glyph = "\uEB90"; - statusIcon.Foreground = (Brush)Application.Current.Resources["SystemFillColorCriticalBrush"]; - statusBorder.Background = (Brush)Application.Current.Resources["SystemFillColorCriticalBackgroundBrush"]; + statusIcon.Foreground = (Brush) + Application.Current.Resources["SystemFillColorCriticalBrush"]; + statusBorder.Background = (Brush) + Application.Current.Resources["SystemFillColorCriticalBackgroundBrush"]; } } @@ -93,10 +113,13 @@ void loadStatusBadge() toggle.Loaded += (_, _) => loadStatusBadge(); toggle.Toggled += async (_, _) => { - if (_isLoadingToggles) return; + if (_isLoadingToggles) + return; bool disabled = !toggle.IsOn; - int loadingId = DialogHelper.ShowLoadingDialog(CoreTools.Translate("Please wait...")); + int loadingId = DialogHelper.ShowLoadingDialog( + CoreTools.Translate("Please wait...") + ); Settings.SetDictionaryItem(Settings.K.DisabledManagers, manager.Name, disabled); await Task.Run(manager.Initialize); loadStatusBadge(); @@ -106,15 +129,16 @@ void loadStatusBadge() var status = new StackPanel() { Orientation = Orientation.Horizontal, - Spacing = 4, HorizontalAlignment = HorizontalAlignment.Center, - Children = { statusIcon, statusText } + Spacing = 4, + HorizontalAlignment = HorizontalAlignment.Center, + Children = { statusIcon, statusText }, }; statusBorder.Child = status; button.Content = new StackPanel() { Orientation = Orientation.Vertical, Spacing = 4, - Children = { toggle, statusBorder } + Children = { toggle, statusBorder }, }; first = false; @@ -128,23 +152,41 @@ void loadStatusBadge() protected override void OnNavigatedTo(NavigationEventArgs e) { _isLoadingToggles = true; - for(int i = 0; i < managerControls.Count; i++) + for (int i = 0; i < managerControls.Count; i++) { - var toggle = (ToggleSwitch)((StackPanel)managerControls[i].Content).Children.First(); - toggle.IsOn = !Settings.GetDictionaryItem(Settings.K.DisabledManagers, PEInterface.Managers[i].Name); + var toggle = (ToggleSwitch) + ((StackPanel)managerControls[i].Content).Children.First(); + toggle.IsOn = !Settings.GetDictionaryItem( + Settings.K.DisabledManagers, + PEInterface.Managers[i].Name + ); } _isLoadingToggles = false; base.OnNavigatedTo(e); } - public void Administrator(object s, RoutedEventArgs e) => NavigationRequested?.Invoke(this, typeof(Administrator)); - public void Backup(object s, RoutedEventArgs e) => NavigationRequested?.Invoke(this, typeof(Backup)); - public void Experimental(object s, RoutedEventArgs e) => NavigationRequested?.Invoke(this, typeof(Experimental)); - public void General(object s, RoutedEventArgs e) => NavigationRequested?.Invoke(this, typeof(General)); - public void Interface(object s, RoutedEventArgs e) => NavigationRequested?.Invoke(this, typeof(Interface_P)); - public void Notifications(object s, RoutedEventArgs e) => NavigationRequested?.Invoke(this, typeof(Notifications)); - public void Operations(object s, RoutedEventArgs e) => NavigationRequested?.Invoke(this, typeof(Operations)); - public void Startup(object s, RoutedEventArgs e) => NavigationRequested?.Invoke(this, typeof(Updates)); + public void Administrator(object s, RoutedEventArgs e) => + NavigationRequested?.Invoke(this, typeof(Administrator)); + + public void Backup(object s, RoutedEventArgs e) => + NavigationRequested?.Invoke(this, typeof(Backup)); + + public void Experimental(object s, RoutedEventArgs e) => + NavigationRequested?.Invoke(this, typeof(Experimental)); + + public void General(object s, RoutedEventArgs e) => + NavigationRequested?.Invoke(this, typeof(General)); + + public void Interface(object s, RoutedEventArgs e) => + NavigationRequested?.Invoke(this, typeof(Interface_P)); + + public void Notifications(object s, RoutedEventArgs e) => + NavigationRequested?.Invoke(this, typeof(Notifications)); + + public void Operations(object s, RoutedEventArgs e) => + NavigationRequested?.Invoke(this, typeof(Operations)); + public void Startup(object s, RoutedEventArgs e) => + NavigationRequested?.Invoke(this, typeof(Updates)); } } diff --git a/src/UniGetUI/Pages/SettingsPages/ManagersPages/PackageManager.xaml b/src/UniGetUI/Pages/SettingsPages/ManagersPages/PackageManager.xaml index 8533ae8743..3a79e68dfe 100644 --- a/src/UniGetUI/Pages/SettingsPages/ManagersPages/PackageManager.xaml +++ b/src/UniGetUI/Pages/SettingsPages/ManagersPages/PackageManager.xaml @@ -1,217 +1,211 @@ + x:Class="UniGetUI.Pages.SettingsPages.GeneralPages.PackageManagerPage" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:controls="using:CommunityToolkit.WinUI.Controls" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="using:UniGetUI.Pages.SettingsPages.GeneralPages" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:widgets="using:UniGetUI.Interface.Widgets" + Background="Transparent" + mc:Ignorable="d" +> + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + Grid.ColumnSpan="2" + FontSize="12" + FontWeight="SemiBold" + Opacity="0.7" + Text="Not finding the file you are looking for? Make sure it has been added to path." + /> + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - + - + - + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - - - + + + + + + diff --git a/src/UniGetUI/Pages/SettingsPages/ManagersPages/PackageManager.xaml.cs b/src/UniGetUI/Pages/SettingsPages/ManagersPages/PackageManager.xaml.cs index b0d96d4585..757e640bca 100644 --- a/src/UniGetUI/Pages/SettingsPages/ManagersPages/PackageManager.xaml.cs +++ b/src/UniGetUI/Pages/SettingsPages/ManagersPages/PackageManager.xaml.cs @@ -1,28 +1,28 @@ +using System.Diagnostics; +using CommunityToolkit.WinUI.Controls; +using ExternalLibraries.Clipboard; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Navigation; +using UniGetUI.Core.Data; +using UniGetUI.Core.SettingsEngine; +using UniGetUI.Core.SettingsEngine.SecureSettings; using UniGetUI.Core.Tools; -using UniGetUI.PackageEngine.Interfaces; -using System.Diagnostics; -using UniGetUI.PackageEngine.Managers.WingetManager; +using UniGetUI.Interface.Widgets; using UniGetUI.PackageEngine; +using UniGetUI.PackageEngine.Interfaces; +using UniGetUI.PackageEngine.Managers.CargoManager; using UniGetUI.PackageEngine.Managers.ChocolateyManager; -using UniGetUI.PackageEngine.Managers.ScoopManager; +using UniGetUI.PackageEngine.Managers.DotNetManager; using UniGetUI.PackageEngine.Managers.NpmManager; using UniGetUI.PackageEngine.Managers.PipManager; -using UniGetUI.PackageEngine.Managers.PowerShellManager; using UniGetUI.PackageEngine.Managers.PowerShell7Manager; -using UniGetUI.PackageEngine.Managers.CargoManager; +using UniGetUI.PackageEngine.Managers.PowerShellManager; +using UniGetUI.PackageEngine.Managers.ScoopManager; using UniGetUI.PackageEngine.Managers.VcpkgManager; -using UniGetUI.PackageEngine.Managers.DotNetManager; -using ExternalLibraries.Clipboard; -using CommunityToolkit.WinUI.Controls; -using UniGetUI.Interface.Widgets; -using UniGetUI.Core.Data; -using UniGetUI.Pages.DialogPages; -using UniGetUI.Core.SettingsEngine; -using UniGetUI.Core.SettingsEngine.SecureSettings; +using UniGetUI.PackageEngine.Managers.WingetManager; using UniGetUI.PackageEngine.PackageLoader; +using UniGetUI.Pages.DialogPages; // To learn more about WinUI, the WinUI project structure, // and more about our project templates, see: http://aka.ms/winui-project-info. @@ -36,10 +36,15 @@ public sealed partial class PackageManagerPage : Page, ISettingsPage { IPackageManager? Manager; public event EventHandler? RestartRequired; - public event EventHandler? NavigationRequested { add { } remove { } } + public event EventHandler? NavigationRequested + { + add { } + remove { } + } public event EventHandler? ReapplyProperties; public bool CanGoBack => true; - public string ShortTitle => Manager is null ? "" : CoreTools.Translate("{0} settings", Manager.DisplayName); + public string ShortTitle => + Manager is null ? "" : CoreTools.Translate("{0} settings", Manager.DisplayName); private bool _isLoading; public PackageManagerPage() @@ -50,44 +55,75 @@ public PackageManagerPage() protected override void OnNavigatedTo(NavigationEventArgs e) { Manager = null; - if (e.Parameter is not Type Manager_T) throw new InvalidDataException("The passed parameter was not a type"); + if (e.Parameter is not Type Manager_T) + throw new InvalidDataException("The passed parameter was not a type"); // Can't do switch with types - if (Manager_T == typeof(WinGet)) Manager = PEInterface.WinGet; - else if (Manager_T == typeof(Chocolatey)) Manager = PEInterface.Chocolatey; - else if (Manager_T == typeof(Scoop)) Manager = PEInterface.Scoop; - else if (Manager_T == typeof(Npm)) Manager = PEInterface.Npm; - else if (Manager_T == typeof(Pip)) Manager = PEInterface.Pip; - else if (Manager_T == typeof(PowerShell)) Manager = PEInterface.PowerShell; - else if (Manager_T == typeof(PowerShell7)) Manager = PEInterface.PowerShell7; - else if (Manager_T == typeof(Cargo)) Manager = PEInterface.Cargo; - else if (Manager_T == typeof(Vcpkg)) Manager = PEInterface.Vcpkg; - else if (Manager_T == typeof(DotNet)) Manager = PEInterface.DotNet; - else throw new InvalidCastException("The specified type was not a package manager!"); + if (Manager_T == typeof(WinGet)) + Manager = PEInterface.WinGet; + else if (Manager_T == typeof(Chocolatey)) + Manager = PEInterface.Chocolatey; + else if (Manager_T == typeof(Scoop)) + Manager = PEInterface.Scoop; + else if (Manager_T == typeof(Npm)) + Manager = PEInterface.Npm; + else if (Manager_T == typeof(Pip)) + Manager = PEInterface.Pip; + else if (Manager_T == typeof(PowerShell)) + Manager = PEInterface.PowerShell; + else if (Manager_T == typeof(PowerShell7)) + Manager = PEInterface.PowerShell7; + else if (Manager_T == typeof(Cargo)) + Manager = PEInterface.Cargo; + else if (Manager_T == typeof(Vcpkg)) + Manager = PEInterface.Vcpkg; + else if (Manager_T == typeof(DotNet)) + Manager = PEInterface.DotNet; + else + throw new InvalidCastException("The specified type was not a package manager!"); ReapplyProperties?.Invoke(this, new()); ApplyManagerState(); EnableManager.KeyName = Manager.Name; - EnableManager.Text = CoreTools.Translate("Enable {pm}").Replace("{pm}", Manager.DisplayName); - InstallOptionsTitle.Text = CoreTools.Translate("Default installation options for {0} packages", Manager.DisplayName); + EnableManager.Text = CoreTools + .Translate("Enable {pm}") + .Replace("{pm}", Manager.DisplayName); + InstallOptionsTitle.Text = CoreTools.Translate( + "Default installation options for {0} packages", + Manager.DisplayName + ); SettingsTitle.Text = CoreTools.Translate("{0} settings", Manager.DisplayName); StatusTitle.Text = CoreTools.Translate("{0} status", Manager.DisplayName); var DisableNotifsCard = new CheckboxCard_Dict() { - Text = CoreTools.Translate("Ignore packages from {pm} when showing a notification about updates").Replace("{pm}", Manager.DisplayName), + Text = CoreTools + .Translate( + "Ignore packages from {pm} when showing a notification about updates" + ) + .Replace("{pm}", Manager.DisplayName), DictionaryName = Settings.K.DisabledPackageManagerNotifications, ForceInversion = true, - KeyName = Manager.Name + KeyName = Manager.Name, }; ManagerLogsLabel.Text = CoreTools.Translate("View {0} logs", Manager.DisplayName); // ----------------- EXECUTABLE FILE PICKER ----------------- - ExeFileWarningText.Visibility = SecureSettings.Get(SecureSettings.K.AllowCustomManagerPaths) ? Visibility.Collapsed : Visibility.Visible; - GoToSecureSettingsBtn.Visibility = SecureSettings.Get(SecureSettings.K.AllowCustomManagerPaths) ? Visibility.Collapsed : Visibility.Visible; - ExecutableComboBox.IsEnabled = SecureSettings.Get(SecureSettings.K.AllowCustomManagerPaths); + ExeFileWarningText.Visibility = SecureSettings.Get( + SecureSettings.K.AllowCustomManagerPaths + ) + ? Visibility.Collapsed + : Visibility.Visible; + GoToSecureSettingsBtn.Visibility = SecureSettings.Get( + SecureSettings.K.AllowCustomManagerPaths + ) + ? Visibility.Collapsed + : Visibility.Visible; + ExecutableComboBox.IsEnabled = SecureSettings.Get( + SecureSettings.K.AllowCustomManagerPaths + ); InstallOptionsPanel.Description = new InstallOptions_Manager(Manager); InstallOptionsPanel.Padding = new(18, 24, 18, 24); @@ -108,12 +144,14 @@ protected override void OnNavigatedTo(NavigationEventArgs e) SourceManagerCard.Description = man; ExtraControls.Children.Add(SourceManagerCard); - ExtraControls.Children.Add(new TextBlock() - { - Margin = new(4, 24, 4, 8), - FontWeight = new Windows.UI.Text.FontWeight(600), - Text=CoreTools.Translate("Advanced options") - }); + ExtraControls.Children.Add( + new TextBlock() + { + Margin = new(4, 24, 4, 8), + FontWeight = new Windows.UI.Text.FontWeight(600), + Text = CoreTools.Translate("Advanced options"), + } + ); } // ------------------------- WINGET EXTRA SETTINGS ----------------------- @@ -126,17 +164,21 @@ protected override void OnNavigatedTo(NavigationEventArgs e) ButtonCard WinGet_ResetWindowsIPackageManager = new() { - Text = CoreTools.Translate("Reset WinGet") + - $" ({CoreTools.Translate("This may help if no packages are listed")})", + Text = + CoreTools.Translate("Reset WinGet") + + $" ({CoreTools.Translate("This may help if no packages are listed")})", ButtonText = CoreTools.AutoTranslated("Reset"), - CornerRadius = new CornerRadius(0) + CornerRadius = new CornerRadius(0), }; - WinGet_ResetWindowsIPackageManager.Click += (_, _) => _ = DialogHelper.HandleBrokenWinGet(); + WinGet_ResetWindowsIPackageManager.Click += (_, _) => + _ = DialogHelper.HandleBrokenWinGet(); ExtraControls.Children.Add(WinGet_ResetWindowsIPackageManager); CheckboxCard WinGet_ForceLocationWhenUpdating = new() { - Text = CoreTools.Translate("Force install location parameter when updating packages with custom locations"), + Text = CoreTools.Translate( + "Force install location parameter when updating packages with custom locations" + ), SettingName = Settings.K.WinGetForceLocationOnUpdate, CornerRadius = new CornerRadius(0), BorderThickness = new Thickness(1, 0, 1, 1), @@ -190,12 +232,11 @@ protected override void OnNavigatedTo(NavigationEventArgs e) }; ExtraControls.Children.Add(WinGet_HideNonApplicableUpdates);*/ } - // ---------------------------- SCOOP EXTRA SETTINGS ------------------------- else if (Manager is Scoop) { - DisableNotifsCard.CornerRadius = new CornerRadius(8,8,0,0); + DisableNotifsCard.CornerRadius = new CornerRadius(8, 8, 0, 0); DisableNotifsCard.BorderThickness = new Thickness(1, 1, 1, 0); ExtraControls.Children.Add(DisableNotifsCard); @@ -203,13 +244,19 @@ protected override void OnNavigatedTo(NavigationEventArgs e) { Text = CoreTools.AutoTranslated("Install Scoop"), ButtonText = CoreTools.AutoTranslated("Install"), - CornerRadius = new CornerRadius(0) + CornerRadius = new CornerRadius(0), }; Scoop_Install.Click += (_, _) => { _ = CoreTools.LaunchBatchFile( - Path.Join(CoreData.UniGetUIExecutableDirectory, "Assets", "Utilities", "install_scoop.cmd"), - CoreTools.Translate("Scoop Installer - WingetUI")); + Path.Join( + CoreData.UniGetUIExecutableDirectory, + "Assets", + "Utilities", + "install_scoop.cmd" + ), + CoreTools.Translate("Scoop Installer - WingetUI") + ); RestartRequired?.Invoke(this, new()); }; ExtraControls.Children.Add(Scoop_Install); @@ -219,13 +266,19 @@ protected override void OnNavigatedTo(NavigationEventArgs e) Text = CoreTools.AutoTranslated("Uninstall Scoop (and its packages)"), ButtonText = CoreTools.AutoTranslated("Uninstall"), CornerRadius = new CornerRadius(0), - BorderThickness = new Thickness(1, 0, 1, 0) + BorderThickness = new Thickness(1, 0, 1, 0), }; Scoop_Uninstall.Click += (_, _) => { _ = CoreTools.LaunchBatchFile( - Path.Join(CoreData.UniGetUIExecutableDirectory, "Assets", "Utilities", "uninstall_scoop.cmd"), - CoreTools.Translate("Scoop Uninstaller - WingetUI")); + Path.Join( + CoreData.UniGetUIExecutableDirectory, + "Assets", + "Utilities", + "uninstall_scoop.cmd" + ), + CoreTools.Translate("Scoop Uninstaller - WingetUI") + ); RestartRequired?.Invoke(this, new()); }; ExtraControls.Children.Add(Scoop_Uninstall); @@ -239,8 +292,15 @@ protected override void OnNavigatedTo(NavigationEventArgs e) Scoop_ResetAppCache.Click += (_, _) => { _ = CoreTools.LaunchBatchFile( - Path.Join(CoreData.UniGetUIExecutableDirectory, "Assets", "Utilities", "scoop_cleanup.cmd"), - CoreTools.Translate("Clearing Scoop cache - WingetUI"), RunAsAdmin: true); + Path.Join( + CoreData.UniGetUIExecutableDirectory, + "Assets", + "Utilities", + "scoop_cleanup.cmd" + ), + CoreTools.Translate("Clearing Scoop cache - WingetUI"), + RunAsAdmin: true + ); }; ExtraControls.Children.Add(Scoop_ResetAppCache); @@ -257,7 +317,7 @@ protected override void OnNavigatedTo(NavigationEventArgs e) else if (Manager is Chocolatey) { - DisableNotifsCard.CornerRadius = new CornerRadius(8,8,0,0); + DisableNotifsCard.CornerRadius = new CornerRadius(8, 8, 0, 0); DisableNotifsCard.BorderThickness = new Thickness(1, 1, 1, 0); ExtraControls.Children.Add(DisableNotifsCard); @@ -265,17 +325,16 @@ protected override void OnNavigatedTo(NavigationEventArgs e) { Text = CoreTools.AutoTranslated("Use system Chocolatey"), SettingName = Settings.K.UseSystemChocolatey, - CornerRadius = new CornerRadius(0, 0, 8, 8) + CornerRadius = new CornerRadius(0, 0, 8, 8), }; Chocolatey_SystemChoco.StateChanged += (_, _) => _ = ReloadPackageManager(); ExtraControls.Children.Add(Chocolatey_SystemChoco); } - // -------------------------------- VCPKG EXTRA SETTINGS -------------------------------------- else if (Manager is Vcpkg) { - DisableNotifsCard.CornerRadius = new CornerRadius(8,8,0,0); + DisableNotifsCard.CornerRadius = new CornerRadius(8, 8, 0, 0); DisableNotifsCard.BorderThickness = new Thickness(1, 1, 1, 0); ExtraControls.Children.Add(DisableNotifsCard); @@ -284,7 +343,7 @@ protected override void OnNavigatedTo(NavigationEventArgs e) { Text = CoreTools.Translate("Default vcpkg triplet"), SettingName = Settings.K.DefaultVcpkgTriplet, - CornerRadius = new CornerRadius(0) + CornerRadius = new CornerRadius(0), }; foreach (string triplet in Vcpkg.GetSystemTriplets()) { @@ -299,12 +358,18 @@ protected override void OnNavigatedTo(NavigationEventArgs e) Text = "Change vcpkg root location", ButtonText = "Select", CornerRadius = new CornerRadius(0, 0, 8, 8), - BorderThickness = new Thickness(1, 0, 1, 1) + BorderThickness = new Thickness(1, 0, 1, 1), }; - StackPanel p = new() { Orientation = Orientation.Horizontal, Spacing = 5, }; + StackPanel p = new() { Orientation = Orientation.Horizontal, Spacing = 5 }; var VcPkgRootLabel = new TextBlock { VerticalAlignment = VerticalAlignment.Center }; - var ResetVcPkgRootLabel = new HyperlinkButton { Content = CoreTools.Translate("Reset") }; - var OpenVcPkgRootLabel = new HyperlinkButton { Content = CoreTools.Translate("Open") }; + var ResetVcPkgRootLabel = new HyperlinkButton + { + Content = CoreTools.Translate("Reset"), + }; + var OpenVcPkgRootLabel = new HyperlinkButton + { + Content = CoreTools.Translate("Open"), + }; VcPkgRootLabel.Text = Settings.Get(Settings.K.CustomVcpkgRoot) ? Settings.GetValue(Settings.K.CustomVcpkgRoot) @@ -322,14 +387,18 @@ protected override void OnNavigatedTo(NavigationEventArgs e) OpenVcPkgRootLabel.Click += (_, _) => { - string directory = Settings.GetValue(Settings.K.CustomVcpkgRoot).Replace("/", "\\"); - if (directory.Any()) CoreTools.Launch(directory); + string directory = Settings + .GetValue(Settings.K.CustomVcpkgRoot) + .Replace("/", "\\"); + if (directory.Any()) + CoreTools.Launch(directory); }; Vcpkg_CustomVcpkgRoot.Click += (_, _) => { - ExternalLibraries.Pickers.FolderPicker openPicker = - new(MainApp.Instance.MainWindow.GetWindowHandle()); + ExternalLibraries.Pickers.FolderPicker openPicker = new( + MainApp.Instance.MainWindow.GetWindowHandle() + ); string folder = openPicker.Show(); if (folder != string.Empty) { @@ -347,7 +416,6 @@ protected override void OnNavigatedTo(NavigationEventArgs e) Vcpkg_CustomVcpkgRoot.Click += (_, _) => _ = ReloadPackageManager(); ExtraControls.Children.Add(Vcpkg_CustomVcpkgRoot); } - // -------------------------------- DEFAULT EXTRA SETTINGS -------------------------------------- else { @@ -360,7 +428,8 @@ protected override void OnNavigatedTo(NavigationEventArgs e) if (Manager is Pip) { ManagerLogs.CornerRadius = new CornerRadius(8, 8, 0, 0); - AppExecutionAliasWarningLabel.Text = "If Python cannot be found or is not listing packages but is installed on the system, you may need to disable the \"python.exe\" App Execution Alias in the settings."; + AppExecutionAliasWarningLabel.Text = + "If Python cannot be found or is not listing packages but is installed on the system, you may need to disable the \"python.exe\" App Execution Alias in the settings."; } else { @@ -370,31 +439,40 @@ protected override void OnNavigatedTo(NavigationEventArgs e) base.OnNavigatedTo(e); } - private void ShowVersionHyperlink_Click(object sender, RoutedEventArgs e) => ApplyManagerState(true); + private void ShowVersionHyperlink_Click(object sender, RoutedEventArgs e) => + ApplyManagerState(true); void ApplyManagerState(bool ShowVersion = false) { - if (Manager is null) throw new InvalidDataException(); + if (Manager is null) + throw new InvalidDataException(); // Load version and manager path ShowVersionHyperlink.Visibility = Visibility.Collapsed; LongVersionTextBlock.Visibility = Visibility.Collapsed; LongVersionTextBlock.Text = Manager.Status.Version + "\n"; - LocationLabel.Text = Manager.Status.ExecutablePath + " " + Manager.Status.ExecutableCallArgs.Trim(); - if (Manager.Status.ExecutablePath == "") LocationLabel.Text = CoreTools.Translate("The executable file for {0} was not found", Manager.DisplayName); + LocationLabel.Text = + Manager.Status.ExecutablePath + " " + Manager.Status.ExecutableCallArgs.Trim(); + if (Manager.Status.ExecutablePath == "") + LocationLabel.Text = CoreTools.Translate( + "The executable file for {0} was not found", + Manager.DisplayName + ); // Load executable selection ExecutableComboBox.SelectionChanged -= ExecutableComboBox_SelectionChanged; ExecutableComboBox.Items.Clear(); - foreach(var path in Manager.FindCandidateExecutableFiles()) + foreach (var path in Manager.FindCandidateExecutableFiles()) { ExecutableComboBox.Items.Add(path); } - string selectedValue = Settings.GetDictionaryItem(Settings.K.ManagerPaths, Manager.Name) ?? ""; + string selectedValue = + Settings.GetDictionaryItem(Settings.K.ManagerPaths, Manager.Name) + ?? ""; if (string.IsNullOrEmpty(selectedValue)) { var exe = Manager.GetExecutableFile(); - selectedValue = exe.Item1? exe.Item2: ""; + selectedValue = exe.Item1 ? exe.Item2 : ""; } ExecutableComboBox.SelectedValue = selectedValue; @@ -410,21 +488,30 @@ void ApplyManagerState(bool ShowVersion = false) else if (!Manager.IsEnabled()) { ManagerStatusBar.Severity = InfoBarSeverity.Warning; - ManagerStatusBar.Title = CoreTools.Translate("{pm} is disabled").Replace("{pm}", Manager.DisplayName); - ManagerStatusBar.Message = CoreTools.Translate("Enable it to install packages from {pm}.").Replace("{pm}", Manager.DisplayName); + ManagerStatusBar.Title = CoreTools + .Translate("{pm} is disabled") + .Replace("{pm}", Manager.DisplayName); + ManagerStatusBar.Message = CoreTools + .Translate("Enable it to install packages from {pm}.") + .Replace("{pm}", Manager.DisplayName); } else if (Manager.Status.Found) { ManagerStatusBar.Severity = InfoBarSeverity.Success; - ManagerStatusBar.Title = CoreTools.Translate("{pm} is enabled and ready to go").Replace("{pm}", Manager.DisplayName); + ManagerStatusBar.Title = CoreTools + .Translate("{pm} is enabled and ready to go") + .Replace("{pm}", Manager.DisplayName); if (!Manager.Status.Version.Contains('\n')) { - ManagerStatusBar.Message = CoreTools.Translate( - "{pm} version:").Replace("{pm}", Manager.DisplayName) + $" {Manager.Status.Version}"; + ManagerStatusBar.Message = + CoreTools.Translate("{pm} version:").Replace("{pm}", Manager.DisplayName) + + $" {Manager.Status.Version}"; } else if (ShowVersion) { - ManagerStatusBar.Message = CoreTools.Translate("{pm} version:").Replace("{pm}", Manager.DisplayName); + ManagerStatusBar.Message = CoreTools + .Translate("{pm} version:") + .Replace("{pm}", Manager.DisplayName); LongVersionTextBlock.Visibility = Visibility.Visible; } else @@ -436,13 +523,18 @@ void ApplyManagerState(bool ShowVersion = false) else // manager was not found { ManagerStatusBar.Severity = InfoBarSeverity.Error; - ManagerStatusBar.Title = CoreTools.Translate("{pm} was not found!").Replace("{pm}", Manager.DisplayName); - ManagerStatusBar.Message = CoreTools.Translate("You may need to install {pm} in order to use it with WingetUI.") + ManagerStatusBar.Title = CoreTools + .Translate("{pm} was not found!") + .Replace("{pm}", Manager.DisplayName); + ManagerStatusBar.Message = CoreTools + .Translate("You may need to install {pm} in order to use it with WingetUI.") .Replace("{pm}", Manager.DisplayName); } } - private void ManagerPath_Click(object sender, RoutedEventArgs e) => _ = _managerPath_Click(); + private void ManagerPath_Click(object sender, RoutedEventArgs e) => + _ = _managerPath_Click(); + private async Task _managerPath_Click() { WindowsClipboard.SetText(LocationLabel.Text); @@ -461,7 +553,11 @@ private void ExecutableComboBox_SelectionChanged(object sender, SelectionChanged if (string.IsNullOrEmpty(ExecutableComboBox.SelectedValue.ToString())) return; - Settings.SetDictionaryItem(Settings.K.ManagerPaths, Manager!.Name, ExecutableComboBox.SelectedValue.ToString()); + Settings.SetDictionaryItem( + Settings.K.ManagerPaths, + Manager!.Name, + ExecutableComboBox.SelectedValue.ToString() + ); _ = ReloadPackageManager(); } @@ -470,12 +566,13 @@ private void GoToSecureSettingsBtn_Click(object sender, RoutedEventArgs e) MainApp.Instance.MainWindow.NavigationPage.OpenSettingsPage(typeof(Administrator)); } - private void EnableManager_OnStateChanged(object? sender, EventArgs e) - => _ = ReloadPackageManager(); + private void EnableManager_OnStateChanged(object? sender, EventArgs e) => + _ = ReloadPackageManager(); private async Task ReloadPackageManager() { - if (Manager is null) return; + if (Manager is null) + return; int loadingId = DialogHelper.ShowLoadingDialog(CoreTools.Translate("Please wait...")); _isLoading = true; ApplyManagerState(); diff --git a/src/UniGetUI/Pages/SettingsPages/SettingsBasePage.xaml b/src/UniGetUI/Pages/SettingsPages/SettingsBasePage.xaml index 15708e7013..963fe56d94 100644 --- a/src/UniGetUI/Pages/SettingsPages/SettingsBasePage.xaml +++ b/src/UniGetUI/Pages/SettingsPages/SettingsBasePage.xaml @@ -1,89 +1,82 @@ + x:Class="UniGetUI.Pages.SettingsPages.SettingsBasePage" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:animatedvisuals="using:Microsoft.UI.Xaml.Controls.AnimatedVisuals" + xmlns:animations="using:CommunityToolkit.WinUI.Animations" + xmlns:converters="using:CommunityToolkit.WinUI.Converters" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="using:UniGetUI.Pages.SettingsPages" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:widgets="using:UniGetUI.Interface.Widgets" + Background="Transparent" + mc:Ignorable="d" +> + + + + - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + diff --git a/src/UniGetUI/Pages/SettingsPages/SettingsBasePage.xaml.cs b/src/UniGetUI/Pages/SettingsPages/SettingsBasePage.xaml.cs index 26b023a8f2..63f46a8f7a 100644 --- a/src/UniGetUI/Pages/SettingsPages/SettingsBasePage.xaml.cs +++ b/src/UniGetUI/Pages/SettingsPages/SettingsBasePage.xaml.cs @@ -1,12 +1,12 @@ using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Media.Animation; using Microsoft.UI.Xaml.Navigation; using UniGetUI.Core.Tools; -using Microsoft.UI.Xaml.Media.Animation; -using UniGetUI.PackageEngine.ManagerClasses.Manager; -using UniGetUI.Pages.SettingsPages.GeneralPages; using UniGetUI.Interface.Pages; using UniGetUI.PackageEngine.Interfaces; +using UniGetUI.PackageEngine.ManagerClasses.Manager; +using UniGetUI.Pages.SettingsPages.GeneralPages; // To learn more about WinUI, the WinUI project structure, // and more about our project templates, see: http://aka.ms/winui-project-info. @@ -19,21 +19,35 @@ namespace UniGetUI.Pages.SettingsPages public sealed partial class SettingsBasePage : Page, IEnterLeaveListener, IInnerNavigationPage { private readonly bool IsManagers; + public SettingsBasePage(bool isManagers) { IsManagers = isManagers; this.InitializeComponent(); BackButton.Click += (_, _) => { - if (MainNavigationFrame.Content is ManagersHomepage or SettingsHomepage) MainApp.Instance.MainWindow.GoBack(); - else if (MainNavigationFrame.CanGoBack) MainNavigationFrame.GoBack(); - else MainNavigationFrame.Navigate(isManagers? typeof(ManagersHomepage): typeof(SettingsHomepage), null, new DrillInNavigationTransitionInfo()); + if (MainNavigationFrame.Content is ManagersHomepage or SettingsHomepage) + MainApp.Instance.MainWindow.GoBack(); + else if (MainNavigationFrame.CanGoBack) + MainNavigationFrame.GoBack(); + else + MainNavigationFrame.Navigate( + isManagers ? typeof(ManagersHomepage) : typeof(SettingsHomepage), + null, + new DrillInNavigationTransitionInfo() + ); }; MainNavigationFrame.Navigated += MainNavigationFrame_Navigated; MainNavigationFrame.Navigating += MainNavigationFrame_Navigating; - MainNavigationFrame.Navigate(isManagers ? typeof(ManagersHomepage) : typeof(SettingsHomepage), null, new DrillInNavigationTransitionInfo()); - - RestartRequired.Message = CoreTools.Translate("Restart WingetUI to fully apply changes"); + MainNavigationFrame.Navigate( + isManagers ? typeof(ManagersHomepage) : typeof(SettingsHomepage), + null, + new DrillInNavigationTransitionInfo() + ); + + RestartRequired.Message = CoreTools.Translate( + "Restart WingetUI to fully apply changes" + ); var RestartButton = new Button { HorizontalAlignment = HorizontalAlignment.Right, @@ -41,36 +55,45 @@ public SettingsBasePage(bool isManagers) }; RestartButton.Click += (_, _) => MainApp.Instance.KillAndRestart(); RestartRequired.ActionButton = RestartButton; - } private void MainNavigationFrame_Navigating(object sender, NavigatingCancelEventArgs e) { - if (MainNavigationFrame.Content is null) return; + if (MainNavigationFrame.Content is null) + return; var page = MainNavigationFrame.Content as ISettingsPage; - if (page is null) throw new InvalidCastException("Settings page does not inherit from ISettingsPage"); + if (page is null) + throw new InvalidCastException("Settings page does not inherit from ISettingsPage"); page.NavigationRequested -= Page_NavigationRequested; page.RestartRequired -= Page_RestartRequired; - if (page is PackageManagerPage pmpage) pmpage.ReapplyProperties -= SettingsBasePage_ReapplyProperties; + if (page is PackageManagerPage pmpage) + pmpage.ReapplyProperties -= SettingsBasePage_ReapplyProperties; } private void MainNavigationFrame_Navigated(object sender, NavigationEventArgs e) { var page = e.Content as ISettingsPage; - if (page is null) throw new InvalidCastException("Settings page does not inherit from ISettingsPage"); + if (page is null) + throw new InvalidCastException("Settings page does not inherit from ISettingsPage"); BackButton.Visibility = Visibility.Visible; SettingsTitle.Text = page.ShortTitle; page.NavigationRequested += Page_NavigationRequested; page.RestartRequired += Page_RestartRequired; - if (page is PackageManagerPage pmpage) pmpage.ReapplyProperties += SettingsBasePage_ReapplyProperties; + if (page is PackageManagerPage pmpage) + pmpage.ReapplyProperties += SettingsBasePage_ReapplyProperties; } private void SettingsBasePage_ReapplyProperties(object? sender, EventArgs e) { - BackButton.Visibility = ((MainNavigationFrame.Content as ISettingsPage)?.CanGoBack ?? true) ? Visibility.Visible : Visibility.Collapsed; - SettingsTitle.Text = (MainNavigationFrame.Content as ISettingsPage)?.ShortTitle ?? "INVALID CONTENT PAGE!"; + BackButton.Visibility = + ((MainNavigationFrame.Content as ISettingsPage)?.CanGoBack ?? true) + ? Visibility.Visible + : Visibility.Collapsed; + SettingsTitle.Text = + (MainNavigationFrame.Content as ISettingsPage)?.ShortTitle + ?? "INVALID CONTENT PAGE!"; } private void Page_RestartRequired(object? sender, EventArgs e) @@ -80,17 +103,31 @@ private void Page_RestartRequired(object? sender, EventArgs e) private void Page_NavigationRequested(object? sender, Type e) { - if(e == typeof(ManagersHomepage)) + if (e == typeof(ManagersHomepage)) { MainApp.Instance.MainWindow.NavigationPage.NavigateTo(Interface.PageType.Managers); } - if(e.IsSubclassOf(typeof(PackageManager))) + if (e.IsSubclassOf(typeof(PackageManager))) { - MainNavigationFrame.Navigate(typeof(PackageManagerPage), e, new SlideNavigationTransitionInfo() { Effect = SlideNavigationTransitionEffect.FromRight} ); + MainNavigationFrame.Navigate( + typeof(PackageManagerPage), + e, + new SlideNavigationTransitionInfo() + { + Effect = SlideNavigationTransitionEffect.FromRight, + } + ); } else { - MainNavigationFrame.Navigate(e, null, new SlideNavigationTransitionInfo() { Effect = SlideNavigationTransitionEffect.FromRight} ); + MainNavigationFrame.Navigate( + e, + null, + new SlideNavigationTransitionInfo() + { + Effect = SlideNavigationTransitionEffect.FromRight, + } + ); } } @@ -104,18 +141,26 @@ public void NavigateTo(Type e) MainNavigationFrame.Navigate(e, null, new DrillInNavigationTransitionInfo()); } - public void OnEnter() - => MainNavigationFrame.Navigate(IsManagers ? typeof(ManagersHomepage) : typeof(SettingsHomepage), null, new DrillInNavigationTransitionInfo()); + public void OnEnter() => + MainNavigationFrame.Navigate( + IsManagers ? typeof(ManagersHomepage) : typeof(SettingsHomepage), + null, + new DrillInNavigationTransitionInfo() + ); public void OnLeave() { } - public bool CanGoBack() - => MainNavigationFrame.CanGoBack && MainNavigationFrame.Content is not SettingsHomepage && MainNavigationFrame.Content is not ManagersHomepage; + public bool CanGoBack() => + MainNavigationFrame.CanGoBack + && MainNavigationFrame.Content is not SettingsHomepage + && MainNavigationFrame.Content is not ManagersHomepage; public void GoBack() { - if (CanGoBack()) MainNavigationFrame.GoBack(); - else MainApp.Instance.MainWindow.GoBack(); + if (CanGoBack()) + MainNavigationFrame.GoBack(); + else + MainApp.Instance.MainWindow.GoBack(); } } } diff --git a/src/UniGetUI/Pages/SoftwarePages/AbstractPackagesPage.xaml b/src/UniGetUI/Pages/SoftwarePages/AbstractPackagesPage.xaml index 0a04e5745b..68b9b9edfd 100644 --- a/src/UniGetUI/Pages/SoftwarePages/AbstractPackagesPage.xaml +++ b/src/UniGetUI/Pages/SoftwarePages/AbstractPackagesPage.xaml @@ -1,1198 +1,1274 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + x:Class="UniGetUI.Interface.AbstractPackagesPage" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:Toolkit="using:CommunityToolkit.WinUI.Controls" + xmlns:animatedvisuals="using:Microsoft.UI.Xaml.Controls.AnimatedVisuals" + xmlns:animations="using:CommunityToolkit.WinUI.Animations" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:pkgClasses="using:UniGetUI.PackageEngine.PackageClasses" + xmlns:widgets="using:UniGetUI.Interface.Widgets" + Name="ABSTRACT_PAGE" + NavigationCacheMode="Required" + SizeChanged="ABSTRACT_PAGE_SizeChanged" + mc:Ignorable="d" +> + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - + + + + + + + + + + + - - - + RowSpacing="4" + Visibility="Collapsed" + > - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + Text="Select all" + /> + + + + + + - + + + + + + + - - - - - - - - - - - - + FontWeight="SemiBold" + Text="Filters" + /> - - - - - - - - - - - - - - - - - - - - - - - - + Checked="InstantSearchValueChanged" + Unchecked="InstantSearchValueChanged" + > + + + + + + + + + + + + + + - - - - + + + + + + + + - - + + + - + CharacterSpacing="0" + SelectionChanged="FilterOptionsChanged" + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + Padding="20,11,10,11" + x:FieldModifier="protected" + CornerRadius="8,0,0,8" + FontSize="40" + FontWeight="SemiBold" + /> + + + + + diff --git a/src/UniGetUI/Pages/SoftwarePages/AbstractPackagesPage.xaml.cs b/src/UniGetUI/Pages/SoftwarePages/AbstractPackagesPage.xaml.cs index 1fa30aab2e..e5498d5709 100644 --- a/src/UniGetUI/Pages/SoftwarePages/AbstractPackagesPage.xaml.cs +++ b/src/UniGetUI/Pages/SoftwarePages/AbstractPackagesPage.xaml.cs @@ -2,39 +2,41 @@ using System.Collections.ObjectModel; using System.Diagnostics; using System.Globalization; +using CommunityToolkit.WinUI; +using Microsoft.UI; using Microsoft.UI.Input; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Controls.Primitives; using Microsoft.UI.Xaml.Input; +using Microsoft.UI.Xaml.Media; using UniGetUI.Core.SettingsEngine; using UniGetUI.Core.Tools; +using UniGetUI.Interface.Enums; +using UniGetUI.Interface.Pages; +using UniGetUI.Interface.Telemetry; using UniGetUI.Interface.Widgets; using UniGetUI.PackageEngine.Enums; using UniGetUI.PackageEngine.Interfaces; using UniGetUI.PackageEngine.PackageClasses; using UniGetUI.PackageEngine.PackageLoader; +using UniGetUI.Pages.DialogPages; +using UniGetUI.Pages.PageInterfaces; using Windows.System; +using Windows.UI; using Windows.UI.Core; -using CommunityToolkit.WinUI; -using UniGetUI.Interface.Pages; -using UniGetUI.Interface.Telemetry; -using UniGetUI.Pages.DialogPages; using DispatcherQueuePriority = Microsoft.UI.Dispatching.DispatcherQueuePriority; -using Microsoft.UI; -using Microsoft.UI.Xaml.Media; -using Windows.UI; -using Microsoft.UI.Xaml.Controls.Primitives; -using UniGetUI.Interface.Enums; -using UniGetUI.Pages.PageInterfaces; // To learn more about WinUI, the WinUI project structure, // and more about our project templates, see: http://aka.ms/winui-project-info. namespace UniGetUI.Interface { - public abstract partial class AbstractPackagesPage : IKeyboardShortcutListener, IEnterLeaveListener, ISearchBoxPage + public abstract partial class AbstractPackagesPage + : IKeyboardShortcutListener, + IEnterLeaveListener, + ISearchBoxPage { - protected struct PackagesPageData { public bool DisableAutomaticPackageLoadOnStart; @@ -64,28 +66,37 @@ protected enum ReloadReason FirstRun, Automated, Manual, - External + External, } static class FilterHelpers { - public static string NormalizeCase(string input) - => input.ToLower(); + public static string NormalizeCase(string input) => input.ToLower(); public static string NormalizeSpecialCharacters(string input) { - input = input.Replace("-", "").Replace("_", "").Replace(" ", "").Replace("@", "").Replace("\t", "").Replace(".", "").Replace(",", "").Replace(":", ""); - foreach (KeyValuePair entry in new Dictionary - { - {'a', "àáäâ"}, - {'e', "èéëê"}, - {'i', "ìíïî"}, - {'o', "òóöô"}, - {'u', "ùúüû"}, - {'y', "ýÿ"}, - {'c', "ç"}, - {'ñ', "n"}, - }) + input = input + .Replace("-", "") + .Replace("_", "") + .Replace(" ", "") + .Replace("@", "") + .Replace("\t", "") + .Replace(".", "") + .Replace(",", "") + .Replace(":", ""); + foreach ( + KeyValuePair entry in new Dictionary + { + { 'a', "àáäâ" }, + { 'e', "èéëê" }, + { 'i', "ìíïî" }, + { 'o', "òóöô" }, + { 'u', "ùúüû" }, + { 'y', "ýÿ" }, + { 'c', "ç" }, + { 'ñ', "n" }, + } + ) { foreach (char InvalidChar in entry.Value) { @@ -95,31 +106,51 @@ public static string NormalizeSpecialCharacters(string input) return input; } - public static bool NameContains(IPackage pkg, string query, List> filters) + public static bool NameContains( + IPackage pkg, + string query, + List> filters + ) { string treatedName = pkg.Name; - foreach (var filter in filters) treatedName = filter(treatedName); + foreach (var filter in filters) + treatedName = filter(treatedName); return treatedName.Contains(query); } - public static bool IdContains(IPackage pkg, string query, List> filters) + public static bool IdContains( + IPackage pkg, + string query, + List> filters + ) { string treatedId = pkg.Id; - foreach (var filter in filters) treatedId = filter(treatedId); + foreach (var filter in filters) + treatedId = filter(treatedId); return treatedId.Contains(query); } - public static bool NameOrIdContains(IPackage pkg, string query, List> filters) - => NameContains(pkg, query, filters) || IdContains(pkg, query, filters); + public static bool NameOrIdContains( + IPackage pkg, + string query, + List> filters + ) => NameContains(pkg, query, filters) || IdContains(pkg, query, filters); - public static bool NameOrIdExactMatch(IPackage pkg, string query, List> filters) + public static bool NameOrIdExactMatch( + IPackage pkg, + string query, + List> filters + ) { string treatedId = pkg.Id; - foreach (var filter in filters) treatedId = filter(treatedId); - if (query == treatedId) return true; + foreach (var filter in filters) + treatedId = filter(treatedId); + if (query == treatedId) + return true; string treatedName = pkg.Name; - foreach (var filter in filters) treatedName = filter(treatedName); + foreach (var filter in filters) + treatedName = filter(treatedName); return query == treatedName; } } @@ -134,34 +165,42 @@ public static bool NameOrIdExactMatch(IPackage pkg, string query, List MainApp.Instance.MainWindow.GlobalSearchBox; } + protected AutoSuggestBox QueryBlock + { + get => MainApp.Instance.MainWindow.GlobalSearchBox; + } protected IPackage? SelectedItem { get { - if(CurrentPackageList.SelectedItem is PackageWrapper w) + if (CurrentPackageList.SelectedItem is PackageWrapper w) return w.Package; var fp = FilteredPackages.GetCheckedPackages(); - if (fp.Count == 1) return fp.First(); + if (fp.Count == 1) + return fp.First(); DialogHelper.ShowDismissableBalloon( CoreTools.Translate("Invalid selection"), fp.Count == 0 ? CoreTools.Translate("No package was selected") - : CoreTools.Translate("More than 1 package was selected")); + : CoreTools.Translate("More than 1 package was selected") + ); return null; } } protected ItemsView CurrentPackageList { - get => (ViewModeSelector.SelectedIndex switch - { - 1 => PackageList_Grid, - 2 => PackageList_Icons, - _ => PackageList_List - }); + get => + ( + ViewModeSelector.SelectedIndex switch + { + 1 => PackageList_Grid, + 2 => PackageList_Icons, + _ => PackageList_List, + } + ); } protected AbstractPackageLoader Loader; @@ -171,7 +210,10 @@ protected ItemsView CurrentPackageList private IEnumerable? LastQueryResult; protected List UsedManagers = []; - protected ConcurrentDictionary> UsedSourcesForManager = []; + protected ConcurrentDictionary< + IPackageManager, + List + > UsedSourcesForManager = []; protected ConcurrentDictionary RootNodeForManager = []; protected ConcurrentDictionary NodesForSources = []; private readonly TreeViewNode LocalPackagesNode = new(); @@ -194,8 +236,17 @@ protected ItemsView CurrentPackageList protected string NoPackages_SubtitleText { - get => NoPackages_SubtitleText_Base + - (SHOW_LAST_CHECKED_TIME ? " " + CoreTools.Translate("(Last checked: {0})", LastPackageLoadTime.ToString(CultureInfo.CurrentCulture)) : ""); + get => + NoPackages_SubtitleText_Base + + ( + SHOW_LAST_CHECKED_TIME + ? " " + + CoreTools.Translate( + "(Last checked: {0})", + LastPackageLoadTime.ToString(CultureInfo.CurrentCulture) + ) + : "" + ); } public string QueryBackup { get; set; } = ""; @@ -234,8 +285,12 @@ protected AbstractPackagesPage(PackagesPageData data) InitializeComponent(); // Selection of grid view mode - int viewMode = Settings.GetDictionaryItem(Settings.K.PackageListViewMode, PAGE_NAME); - if (viewMode < 0 || viewMode >= ViewModeSelector.Items.Count) viewMode = 0; + int viewMode = Settings.GetDictionaryItem( + Settings.K.PackageListViewMode, + PAGE_NAME + ); + if (viewMode < 0 || viewMode >= ViewModeSelector.Items.Count) + viewMode = 0; ViewModeSelector.SelectedIndex = viewMode; GenerateHeaderBarTitles(); @@ -300,7 +355,8 @@ protected AbstractPackagesPage(PackagesPageData data) // Handle when a source is clicked SourcesTreeView.Tapped += (_, e) => { - TreeViewNode? node = (e.OriginalSource as FrameworkElement)?.DataContext as TreeViewNode; + TreeViewNode? node = + (e.OriginalSource as FrameworkElement)?.DataContext as TreeViewNode; if (node is null) { return; @@ -321,7 +377,8 @@ protected AbstractPackagesPage(PackagesPageData data) // Handle when a source is double-clicked SourcesTreeView.RightTapped += (_, e) => { - TreeViewNode? node = (e.OriginalSource as FrameworkElement)?.DataContext as TreeViewNode; + TreeViewNode? node = + (e.OriginalSource as FrameworkElement)?.DataContext as TreeViewNode; if (node is null) { return; @@ -341,21 +398,31 @@ protected AbstractPackagesPage(PackagesPageData data) _searchPlaceholder = CoreTools.Translate("Search for packages"); MegaQueryBlock.PlaceholderText = _searchPlaceholder; - InstantSearchCheckbox.IsChecked = !Settings.GetDictionaryItem(Settings.K.DisableInstantSearch, PAGE_NAME); + InstantSearchCheckbox.IsChecked = !Settings.GetDictionaryItem( + Settings.K.DisableInstantSearch, + PAGE_NAME + ); HeaderIcon.FontWeight = new Windows.UI.Text.FontWeight(700); NameHeader.Click += (_, _) => SortPackagesBy(ObservablePackageCollection.Sorter.Name); IdHeader.Click += (_, _) => SortPackagesBy(ObservablePackageCollection.Sorter.Id); - VersionHeader.Click += (_, _) => SortPackagesBy(ObservablePackageCollection.Sorter.Version); - NewVersionHeader.Click += (_, _) => SortPackagesBy(ObservablePackageCollection.Sorter.NewVersion); - SourceHeader.Click += (_, _) => SortPackagesBy(ObservablePackageCollection.Sorter.Source); - - OrderByName_Menu.Click += (_, _) => SortPackagesBy(ObservablePackageCollection.Sorter.Name); + VersionHeader.Click += (_, _) => + SortPackagesBy(ObservablePackageCollection.Sorter.Version); + NewVersionHeader.Click += (_, _) => + SortPackagesBy(ObservablePackageCollection.Sorter.NewVersion); + SourceHeader.Click += (_, _) => + SortPackagesBy(ObservablePackageCollection.Sorter.Source); + + OrderByName_Menu.Click += (_, _) => + SortPackagesBy(ObservablePackageCollection.Sorter.Name); OrderById_Menu.Click += (_, _) => SortPackagesBy(ObservablePackageCollection.Sorter.Id); - OrderByVer_Menu.Click += (_, _) => SortPackagesBy(ObservablePackageCollection.Sorter.Version); - OrderByNewVer_Menu.Click += (_, _) => SortPackagesBy(ObservablePackageCollection.Sorter.NewVersion); - OrderBySrc_Menu.Click += (_, _) => SortPackagesBy(ObservablePackageCollection.Sorter.Source); + OrderByVer_Menu.Click += (_, _) => + SortPackagesBy(ObservablePackageCollection.Sorter.Version); + OrderByNewVer_Menu.Click += (_, _) => + SortPackagesBy(ObservablePackageCollection.Sorter.NewVersion); + OrderBySrc_Menu.Click += (_, _) => + SortPackagesBy(ObservablePackageCollection.Sorter.Source); OrderAsc_Menu.Click += (_, _) => SortPackagesBy(ascendent: true); OrderDesc_Menu.Click += (_, _) => SortPackagesBy(ascendent: false); @@ -391,12 +458,17 @@ private void GenerateHeaderBarTitles() } } - private void Loader_PackagesChanged(object? sender, PackagesChangedEvent packagesChangedEvent) + private void Loader_PackagesChanged( + object? sender, + PackagesChangedEvent packagesChangedEvent + ) { // Ensure we are in the UI thread if (Microsoft.UI.Dispatching.DispatcherQueue.GetForCurrentThread() is null) { - DispatcherQueue.TryEnqueue(() => Loader_PackagesChanged(sender, packagesChangedEvent)); + DispatcherQueue.TryEnqueue(() => + Loader_PackagesChanged(sender, packagesChangedEvent) + ); return; } @@ -430,7 +502,8 @@ private void Loader_PackagesChanged(object? sender, PackagesChangedEvent package else { // Reset internal package cache, and update from loader - foreach(var wrapper in WrappedPackages) wrapper.Dispose(); + foreach (var wrapper in WrappedPackages) + wrapper.Dispose(); WrappedPackages.Clear(); ClearSourcesList(); foreach (var package in Loader.Packages) @@ -477,7 +550,8 @@ public void SearchTriggered() public void ReloadTriggered() { - if (DISABLE_RELOAD) return; + if (DISABLE_RELOAD) + return; _ = LoadPackages(ReloadReason.Manual); } @@ -504,7 +578,13 @@ protected void AddPackageToSourcesList(IPackage package) if (!UsedManagers.Contains(source.Manager)) { UsedManagers.Add(source.Manager); - var node = new TreeViewNode { Content = source.Manager.DisplayName + " .", IsExpanded = false }; + var node = new TreeViewNode + { + Content = + source.Manager.DisplayName + + " .", + IsExpanded = false, + }; SourcesTreeView.RootNodes.Add(node); // Smart way to decide whether to check a source or not. @@ -525,10 +605,20 @@ protected void AddPackageToSourcesList(IPackage package) SourcesTreeViewGrid.Visibility = Visibility.Visible; } - if ((!UsedSourcesForManager.ContainsKey(source.Manager) || !UsedSourcesForManager[source.Manager].Contains(source)) && source.Manager.Capabilities.SupportsCustomSources) + if ( + ( + !UsedSourcesForManager.ContainsKey(source.Manager) + || !UsedSourcesForManager[source.Manager].Contains(source) + ) && source.Manager.Capabilities.SupportsCustomSources + ) { UsedSourcesForManager[source.Manager].Add(source); - TreeViewNode item = new() { Content = source.Name + " ." }; + TreeViewNode item = new() + { + Content = + source.Name + + " .", + }; NodesForSources.TryAdd(source, item); if (source.IsVirtualManager) @@ -557,14 +647,19 @@ private void FilterOptionsChanged(object sender, RoutedEventArgs e) FilterPackages(true); } - private void InstantSearchValueChanged(object sender, RoutedEventArgs e) - => Settings.SetDictionaryItem(Settings.K.DisableInstantSearch, PAGE_NAME, !InstantSearchCheckbox.IsChecked); + private void InstantSearchValueChanged(object sender, RoutedEventArgs e) => + Settings.SetDictionaryItem( + Settings.K.DisableInstantSearch, + PAGE_NAME, + !InstantSearchCheckbox.IsChecked + ); - private void SourcesTreeView_SelectionChanged(TreeView sender, TreeViewSelectionChangedEventArgs args) - => FilterPackages(); + private void SourcesTreeView_SelectionChanged( + TreeView sender, + TreeViewSelectionChangedEventArgs args + ) => FilterPackages(); - public virtual async Task LoadPackages() - => await LoadPackages(ReloadReason.External); + public virtual async Task LoadPackages() => await LoadPackages(ReloadReason.External); protected void ClearSourcesList() { @@ -582,7 +677,15 @@ protected void ClearSourcesList() ///
protected async Task LoadPackages(ReloadReason reason) { - if (!Loader.IsLoading && (!Loader.IsLoaded || reason == ReloadReason.External || reason == ReloadReason.Manual || reason == ReloadReason.Automated)) + if ( + !Loader.IsLoading + && ( + !Loader.IsLoaded + || reason == ReloadReason.External + || reason == ReloadReason.Manual + || reason == ReloadReason.Automated + ) + ) { Loader.ClearPackages(emitFinishSignal: false); await Loader.ReloadPackages(); @@ -603,7 +706,9 @@ private void SelectAndScrollTo(int index, bool focus) } else if (CurrentPackageList.Layout is UniformGridLayout gl) { - int columnCount = (int)((CurrentPackageList.ActualWidth - 8) / (gl.MinItemWidth + 8)); + int columnCount = (int)( + (CurrentPackageList.ActualWidth - 8) / (gl.MinItemWidth + 8) + ); int row = index / Math.Max(columnCount, 1); position = Math.Max(row - 1, 0) * (gl.MinItemHeight + 8); Debug.WriteLine($"pos: {position}, colCount:{columnCount}, {row}"); @@ -613,16 +718,25 @@ private void SelectAndScrollTo(int index, bool focus) throw new InvalidCastException("The layout was not recognized"); } - if (position < CurrentPackageList.ScrollView.VerticalOffset || position > - CurrentPackageList.ScrollView.VerticalOffset + CurrentPackageList.ScrollView.ActualHeight) - { - CurrentPackageList.ScrollView.ScrollTo(0, position, new ScrollingScrollOptions( - ScrollingAnimationMode.Disabled, - ScrollingSnapPointsMode.Ignore - )); + if ( + position < CurrentPackageList.ScrollView.VerticalOffset + || position + > CurrentPackageList.ScrollView.VerticalOffset + + CurrentPackageList.ScrollView.ActualHeight + ) + { + CurrentPackageList.ScrollView.ScrollTo( + 0, + position, + new ScrollingScrollOptions( + ScrollingAnimationMode.Disabled, + ScrollingSnapPointsMode.Ignore + ) + ); } - if (focus) Focus(FilteredPackages[index].Package); + if (focus) + Focus(FilteredPackages[index].Package); } private void Focus(IPackage packageToFocus, int retryCount = 0) @@ -634,7 +748,10 @@ private void Focus(IPackage packageToFocus, int retryCount = 0) DispatcherQueuePriority.Low, () => { - PackageItemContainer? containerToFocus = CurrentPackageList.FindDescendant(c => c.Package?.Equals(packageToFocus) == true); + PackageItemContainer? containerToFocus = + CurrentPackageList.FindDescendant(c => + c.Package?.Equals(packageToFocus) == true + ); if (containerToFocus == null) { Focus(packageToFocus, ++retryCount); @@ -643,7 +760,10 @@ private void Focus(IPackage packageToFocus, int retryCount = 0) if (!containerToFocus.IsSelected) { - PackageItemContainer? selectedContainer = CurrentPackageList.FindDescendant(c => c.IsSelected); + PackageItemContainer? selectedContainer = + CurrentPackageList.FindDescendant(c => + c.IsSelected + ); if (selectedContainer?.Package?.Equals(packageToFocus) == true) containerToFocus = selectedContainer; else @@ -653,15 +773,15 @@ private void Focus(IPackage packageToFocus, int retryCount = 0) } } containerToFocus.Focus(FocusState.Keyboard); - }); + } + ); } public void PackageList_CharacterReceived(object sender, CharacterReceivedRoutedEventArgs e) { char ch = Char.ToLower(e.Character); - if (('a' <= ch && ch <= 'z') - || ('0' <= ch && ch <= '9')) + if (('a' <= ch && ch <= 'z') || ('0' <= ch && ch <= '9')) { if (Environment.TickCount - LastKeyDown > QUERY_SEPARATION_TIME) { @@ -685,20 +805,32 @@ public void PackageList_CharacterReceived(object sender, CharacterReceivedRouted break; } // To avoid jumping back high up because an ID matched it (prevent typing "wi" focusing id:"WildfireGames.0AD" instead of name:"Windows") - if (IdQueryIndex == -1 && FilteredPackages[i].Package.Id.ToLower().StartsWith(TypeQuery)) + if ( + IdQueryIndex == -1 + && FilteredPackages[i].Package.Id.ToLower().StartsWith(TypeQuery) + ) { IdQueryIndex = i; } - if (NameSimilarityIndex == -1 && FilteredPackages[i].Package.Name.ToLower().Contains(TypeQuery)) + if ( + NameSimilarityIndex == -1 + && FilteredPackages[i].Package.Name.ToLower().Contains(TypeQuery) + ) { NameSimilarityIndex = i; } - if (IdSimilarityIndex == -1 && FilteredPackages[i].Package.Id.ToLower().Contains(TypeQuery)) + if ( + IdSimilarityIndex == -1 + && FilteredPackages[i].Package.Id.ToLower().Contains(TypeQuery) + ) { IdSimilarityIndex = i; } } - int QueryIndex = IdQueryIndex > -1 ? IdQueryIndex : (NameSimilarityIndex > -1 ? NameSimilarityIndex : IdSimilarityIndex); + int QueryIndex = + IdQueryIndex > -1 + ? IdQueryIndex + : (NameSimilarityIndex > -1 ? NameSimilarityIndex : IdSimilarityIndex); if (!SelectedPackage) { bool SameChars = true; @@ -722,7 +854,8 @@ public void PackageList_CharacterReceived(object sender, CharacterReceivedRouted { if (FilteredPackages[idx].Package.Name.ToLower().StartsWith(LastChar)) { - if (FirstIdx == -1) FirstIdx = idx; + if (FirstIdx == -1) + FirstIdx = idx; LastIdx = idx; } else if (FirstIdx > -1) @@ -732,7 +865,10 @@ public void PackageList_CharacterReceived(object sender, CharacterReceivedRouted } } - SelectAndScrollTo(FirstIdx + (IndexOffset % (LastIdx - FirstIdx + 1)), true); + SelectAndScrollTo( + FirstIdx + (IndexOffset % (LastIdx - FirstIdx + 1)), + true + ); } else if (QueryIndex > -1) { @@ -751,7 +887,8 @@ public void PackageList_CharacterReceived(object sender, CharacterReceivedRouted /// protected void ApplyTextAndIconsToToolbar( IDictionary Labels, - IDictionary Icons) + IDictionary Icons + ) { foreach (DependencyObject item in Labels.Keys) { @@ -770,7 +907,10 @@ protected void ApplyTextAndIconsToToolbar( { menuItem.UntranslatedText = text; } - else throw new InvalidCastException("item must be of type AppBarButton or MenuFlyoutButton"); + else + throw new InvalidCastException( + "item must be of type AppBarButton or MenuFlyoutButton" + ); } foreach (DependencyObject item in Icons.Keys) @@ -784,7 +924,10 @@ protected void ApplyTextAndIconsToToolbar( { menuItem.IconName = icon; } - else throw new InvalidCastException("item must be of type AppBarButton or MenuFlyoutButton"); + else + throw new InvalidCastException( + "item must be of type AppBarButton or MenuFlyoutButton" + ); } } @@ -809,12 +952,16 @@ public void FilterPackages(bool forceQueryUpdate = false) } else if (RootNodeForManager.Values.Contains(node)) { - IPackageManager manager = RootNodeForManager.First(x => x.Value == node).Key; + IPackageManager manager = RootNodeForManager + .First(x => x.Value == node) + .Key; visibleManagers.Add(manager); if (!manager.Capabilities.SupportsCustomSources) continue; - foreach (IManagerSource source in manager.SourcesHelper.Factory.GetAvailableSources()) + foreach ( + IManagerSource source in manager.SourcesHelper.Factory.GetAvailableSources() + ) if (!visibleSources.Contains(source)) visibleSources.Add(source); } @@ -826,26 +973,40 @@ public void FilterPackages(bool forceQueryUpdate = false) { // Load applied filters and prepare query List> appliedFilters = []; - if (UpperLowerCaseCheckbox.IsChecked is false) appliedFilters.Add(FilterHelpers.NormalizeCase); + if (UpperLowerCaseCheckbox.IsChecked is false) + appliedFilters.Add(FilterHelpers.NormalizeCase); if (IgnoreSpecialCharsCheckbox.IsChecked is true) appliedFilters.Add(FilterHelpers.NormalizeSpecialCharacters); string treatedQuery = QueryBlock.Text.Trim(); - foreach (var filter in appliedFilters) treatedQuery = filter(treatedQuery); + foreach (var filter in appliedFilters) + treatedQuery = filter(treatedQuery); // treatedQuery now has the appropiate content if (QueryIdRadio.IsChecked is true) LastQueryResult = WrappedPackages.Where(wrapper => - FilterHelpers.NameContains(wrapper.Package, treatedQuery, appliedFilters)); + FilterHelpers.NameContains(wrapper.Package, treatedQuery, appliedFilters) + ); else if (QueryNameRadio.IsChecked is true) LastQueryResult = WrappedPackages.Where(wrapper => - FilterHelpers.IdContains(wrapper.Package, treatedQuery, appliedFilters)); + FilterHelpers.IdContains(wrapper.Package, treatedQuery, appliedFilters) + ); else if (QueryBothRadio.IsChecked is true) LastQueryResult = WrappedPackages.Where(wrapper => - FilterHelpers.NameOrIdContains(wrapper.Package, treatedQuery, appliedFilters)); + FilterHelpers.NameOrIdContains( + wrapper.Package, + treatedQuery, + appliedFilters + ) + ); else if (QueryExactMatch.IsChecked == true) LastQueryResult = WrappedPackages.Where(wrapper => - FilterHelpers.NameOrIdExactMatch(wrapper.Package, treatedQuery, appliedFilters)); + FilterHelpers.NameOrIdExactMatch( + wrapper.Package, + treatedQuery, + appliedFilters + ) + ); else // QuerySimilarResultsRadio == true LastQueryResult = WrappedPackages; } @@ -854,9 +1015,13 @@ public void FilterPackages(bool forceQueryUpdate = false) foreach (var match in LastQueryResult) { - if (visibleSources.Contains(match.Package.Source) || - (!match.Package.Manager.Capabilities.SupportsCustomSources && - visibleManagers.Contains(match.Package.Manager))) + if ( + visibleSources.Contains(match.Package.Source) + || ( + !match.Package.Manager.Capabilities.SupportsCustomSources + && visibleManagers.Contains(match.Package.Manager) + ) + ) { matchingList_selectedSources.Add(match); } @@ -892,24 +1057,41 @@ public void UpdatePackageCount() { var selected = FilteredPackages.Where(p => p.IsChecked).Count(); var unSelected = FilteredPackages.Where(p => !p.IsChecked).Count(); - if (selected is 0 && unSelected is not 0) SelectAllCheckBox.IsChecked = false; - else if (selected is not 0 && unSelected is 0) SelectAllCheckBox.IsChecked = true; - else if (selected is not 0 && unSelected is not 0) SelectAllCheckBox.IsChecked = null; + if (selected is 0 && unSelected is not 0) + SelectAllCheckBox.IsChecked = false; + else if (selected is not 0 && unSelected is 0) + SelectAllCheckBox.IsChecked = true; + else if (selected is not 0 && unSelected is not 0) + SelectAllCheckBox.IsChecked = null; string GetSubtitleText() { - string r = CoreTools.Translate( - "{0} packages were found, {1} of which match the specified filters.", FilteredPackages.Count, Loader.Count()) - + " (" + CoreTools.Translate("{0} selected", selected) + ")"; - - if (SHOW_LAST_CHECKED_TIME) r += " " + CoreTools.Translate("(Last checked: {0})", LastPackageLoadTime.ToString(CultureInfo.CurrentCulture)); + string r = + CoreTools.Translate( + "{0} packages were found, {1} of which match the specified filters.", + FilteredPackages.Count, + Loader.Count() + ) + + " (" + + CoreTools.Translate("{0} selected", selected) + + ")"; + + if (SHOW_LAST_CHECKED_TIME) + r += + " " + + CoreTools.Translate( + "(Last checked: {0})", + LastPackageLoadTime.ToString(CultureInfo.CurrentCulture) + ); return r; } if (FilteredPackages.Any()) { BackgroundText.Text = NoPackages_BackgroundText; - BackgroundText.Visibility = Loader.Any() ? Visibility.Collapsed : Visibility.Visible; + BackgroundText.Visibility = Loader.Any() + ? Visibility.Collapsed + : Visibility.Visible; MainSubtitle.Text = GetSubtitleText(); } else @@ -934,9 +1116,13 @@ string GetSubtitleText() } else { - BackgroundText.Visibility = Loader.Any() ? Visibility.Collapsed : Visibility.Visible; + BackgroundText.Visibility = Loader.Any() + ? Visibility.Collapsed + : Visibility.Visible; BackgroundText.Text = MainSubtitle_StillLoading; - SourcesPlaceholderText.Visibility = Loader.Any() ? Visibility.Collapsed : Visibility.Visible; + SourcesPlaceholderText.Visibility = Loader.Any() + ? Visibility.Collapsed + : Visibility.Visible; SourcesPlaceholderText.Text = MainSubtitle_StillLoading; MainSubtitle.Text = MainSubtitle_StillLoading; } @@ -955,7 +1141,8 @@ string GetSubtitleText() /// The information with which to sort the packages public void SortPackagesBy(ObservablePackageCollection.Sorter sorter) { - if(sorter == FilteredPackages.CurrentSorter) FilteredPackages.Descending = !FilteredPackages.Descending; + if (sorter == FilteredPackages.CurrentSorter) + FilteredPackages.Descending = !FilteredPackages.Descending; FilteredPackages.SetSorter(sorter); FilteredPackages.Sort(); UpdateSortingMenu(); @@ -970,11 +1157,16 @@ public void SortPackagesBy(bool ascendent) private void UpdateSortingMenu() { - OrderByName_Menu.IsChecked = FilteredPackages.CurrentSorter is ObservablePackageCollection.Sorter.Name; - OrderById_Menu.IsChecked = FilteredPackages.CurrentSorter is ObservablePackageCollection.Sorter.Id; - OrderByVer_Menu.IsChecked = FilteredPackages.CurrentSorter is ObservablePackageCollection.Sorter.Version; - OrderByNewVer_Menu.IsChecked = FilteredPackages.CurrentSorter is ObservablePackageCollection.Sorter.NewVersion; - OrderBySrc_Menu.IsChecked = FilteredPackages.CurrentSorter is ObservablePackageCollection.Sorter.Source; + OrderByName_Menu.IsChecked = + FilteredPackages.CurrentSorter is ObservablePackageCollection.Sorter.Name; + OrderById_Menu.IsChecked = + FilteredPackages.CurrentSorter is ObservablePackageCollection.Sorter.Id; + OrderByVer_Menu.IsChecked = + FilteredPackages.CurrentSorter is ObservablePackageCollection.Sorter.Version; + OrderByNewVer_Menu.IsChecked = + FilteredPackages.CurrentSorter is ObservablePackageCollection.Sorter.NewVersion; + OrderBySrc_Menu.IsChecked = + FilteredPackages.CurrentSorter is ObservablePackageCollection.Sorter.Source; OrderAsc_Menu.IsChecked = !FilteredPackages.Descending; OrderDesc_Menu.IsChecked = FilteredPackages.Descending; @@ -986,7 +1178,7 @@ private void UpdateSortingMenu() ObservablePackageCollection.Sorter.Version => CoreTools.Translate("Version"), ObservablePackageCollection.Sorter.NewVersion => CoreTools.Translate("New version"), ObservablePackageCollection.Sorter.Source => CoreTools.Translate("Source"), - _ => throw new InvalidDataException() + _ => throw new InvalidDataException(), }; } @@ -1006,11 +1198,14 @@ protected void ShowDetailsForPackage(IPackage? package, TEL_InstallReferral refe if (package is null) return; - if(package.Source.IsVirtualManager || package is InvalidImportedPackage) + if (package.Source.IsVirtualManager || package is InvalidImportedPackage) { DialogHelper.ShowDismissableBalloon( CoreTools.Translate("Something went wrong"), - CoreTools.Translate("\"{0}\" is a local package and does not have available details", package.Name) + CoreTools.Translate( + "\"{0}\" is a local package and does not have available details", + package.Name + ) ); return; } @@ -1041,7 +1236,10 @@ protected async Task ShowInstallationOptionsForPackage(IPackage? package) { DialogHelper.ShowDismissableBalloon( CoreTools.Translate("Something went wrong"), - CoreTools.Translate("\"{0}\" is a local package and is not compatible with this feature", package.Name) + CoreTools.Translate( + "\"{0}\" is a local package and is not compatible with this feature", + package.Name + ) ); return; } @@ -1055,7 +1253,8 @@ protected async Task ShowInstallationOptionsForPackage(IPackage? package) private void SidepanelWidth_SizeChanged(object sender, SizeChangedEventArgs e) { int rawWidth = (int)e.NewSize.Width; - if (rawWidth == (int)(e.NewSize.Width / 10) || rawWidth == 25) { + if (rawWidth == (int)(e.NewSize.Width / 10) || rawWidth == 25) + { return; } @@ -1095,15 +1294,17 @@ protected void PerformMainPackageAction(IPackage? package) } } - public void FocusPackageList() - => CurrentPackageList.Focus(FocusState.Programmatic); + public void FocusPackageList() => CurrentPackageList.Focus(FocusState.Programmatic); public async Task ShowContextMenu(PackageWrapper wrapper) { CurrentPackageList.Select(wrapper.Index); await Task.Delay(20); - if(_lastContextMenuButtonTapped is not null) - (CurrentPackageList.ContextFlyout as BetterMenu)?.ShowAt(_lastContextMenuButtonTapped, new FlyoutShowOptions { Placement = FlyoutPlacementMode.RightEdgeAlignedTop }); + if (_lastContextMenuButtonTapped is not null) + (CurrentPackageList.ContextFlyout as BetterMenu)?.ShowAt( + _lastContextMenuButtonTapped, + new FlyoutShowOptions { Placement = FlyoutPlacementMode.RightEdgeAlignedTop } + ); WhenShowingContextMenu(wrapper.Package); } @@ -1125,8 +1326,10 @@ public void PackageItemContainer_DoubleTapped(object sender, DoubleTappedRoutedE container.Focus(FocusState.Keyboard); TEL_InstallReferral referral = TEL_InstallReferral.ALREADY_INSTALLED; - if (PAGE_NAME == "Bundles") referral = TEL_InstallReferral.FROM_BUNDLE; - if (PAGE_NAME == "Discover") referral = TEL_InstallReferral.DIRECT_SEARCH; + if (PAGE_NAME == "Bundles") + referral = TEL_InstallReferral.FROM_BUNDLE; + if (PAGE_NAME == "Discover") + referral = TEL_InstallReferral.DIRECT_SEARCH; ShowDetailsForPackage(container.Package, referral); } } @@ -1155,9 +1358,13 @@ private async Task ForceRedrawByScroll() private void ToggleFiltersButton_Click(object sender, RoutedEventArgs e) { - if(FilteringPanel.DisplayMode is SplitViewDisplayMode.Inline) + if (FilteringPanel.DisplayMode is SplitViewDisplayMode.Inline) { - Settings.SetDictionaryItem(Settings.K.HideToggleFilters, PAGE_NAME, !ToggleFiltersButton.IsChecked ?? false); + Settings.SetDictionaryItem( + Settings.K.HideToggleFilters, + PAGE_NAME, + !ToggleFiltersButton.IsChecked ?? false + ); } if (ToggleFiltersButton.IsChecked ?? false) @@ -1184,8 +1391,12 @@ private void ShowFilteringPane() int finalWidth = 250; try { - finalWidth = Settings.GetDictionaryItem(Settings.K.SidepanelWidths, PAGE_NAME); - if (finalWidth == 0) finalWidth = 250; + finalWidth = Settings.GetDictionaryItem( + Settings.K.SidepanelWidths, + PAGE_NAME + ); + if (finalWidth == 0) + finalWidth = 250; } catch { @@ -1207,7 +1418,7 @@ private void ShowFilteringPane() TintColor = Color.FromArgb(0, 20, 20, 20), TintOpacity = 0.4, FallbackColor = Color.FromArgb(0, 20, 20, 20), - TintLuminosityOpacity = 0.8 + TintLuminosityOpacity = 0.8, }; } else @@ -1217,10 +1428,9 @@ private void ShowFilteringPane() TintColor = Color.FromArgb(0, 250, 250, 250), TintOpacity = 0.4, FallbackColor = Color.FromArgb(0, 250, 250, 250), - TintLuminosityOpacity = 0.8 + TintLuminosityOpacity = 0.8, }; } - } FilteringPanel.IsPaneOpen = true; ToggleFiltersButton.IsChecked = true; @@ -1232,7 +1442,8 @@ private async Task LoadIconsForNewPackages() // Get the packages to be updated. foreach (var wrapper in FilteredPackages) { - if (wrapper.IconWasLoaded) continue; + if (wrapper.IconWasLoaded) + continue; wrapper.IconWasLoaded = true; PackagesWithoutIcon.Add(wrapper); } @@ -1241,7 +1452,8 @@ private async Task LoadIconsForNewPackages() foreach (var wrapper in PackagesWithoutIcon) { var icon = await Task.Run(wrapper.Package.GetIconUrlIfAny); - if (icon is not null) wrapper.PackageIcon = icon; + if (icon is not null) + wrapper.PackageIcon = icon; } } @@ -1259,8 +1471,18 @@ public void OnLeave() public void PackageItemContainer_PreviewKeyDown(object sender, KeyRoutedEventArgs e) { - if (e.Key is not (VirtualKey.Up or VirtualKey.Down or VirtualKey.Home or VirtualKey.End or VirtualKey.Enter or VirtualKey.Space) || - sender is not PackageItemContainer packageItemContainer) + if ( + e.Key + is not ( + VirtualKey.Up + or VirtualKey.Down + or VirtualKey.Home + or VirtualKey.End + or VirtualKey.Enter + or VirtualKey.Space + ) + || sender is not PackageItemContainer packageItemContainer + ) { return; } @@ -1269,13 +1491,21 @@ public void PackageItemContainer_PreviewKeyDown(object sender, KeyRoutedEventArg switch (e.Key) { case VirtualKey.Up when index > 0: - SelectAndScrollTo(index - 1, true); e.Handled = true; break; + SelectAndScrollTo(index - 1, true); + e.Handled = true; + break; case VirtualKey.Down when index < FilteredPackages.Count - 1: - SelectAndScrollTo(index + 1, true); e.Handled = true; break; + SelectAndScrollTo(index + 1, true); + e.Handled = true; + break; case VirtualKey.Home when index > 0: - SelectAndScrollTo(0, true); e.Handled = true; break; + SelectAndScrollTo(0, true); + e.Handled = true; + break; case VirtualKey.End when index < FilteredPackages.Count - 1: - SelectAndScrollTo(FilteredPackages.Count - 1, true); e.Handled = true; break; + SelectAndScrollTo(FilteredPackages.Count - 1, true); + e.Handled = true; + break; } if (e.KeyStatus.WasKeyDown) @@ -1286,10 +1516,16 @@ public void PackageItemContainer_PreviewKeyDown(object sender, KeyRoutedEventArg IPackage? package = packageItemContainer.Package; - bool IS_CONTROL_PRESSED = InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.Control).HasFlag(CoreVirtualKeyStates.Down); + bool IS_CONTROL_PRESSED = InputKeyboardSource + .GetKeyStateForCurrentThread(VirtualKey.Control) + .HasFlag(CoreVirtualKeyStates.Down); //bool IS_SHIFT_PRESSED = InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.Shift).HasFlag(CoreVirtualKeyStates.Down); - bool IS_ALT_PRESSED = InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.LeftMenu).HasFlag(CoreVirtualKeyStates.Down); - IS_ALT_PRESSED |= InputKeyboardSource.GetKeyStateForCurrentThread(VirtualKey.RightMenu).HasFlag(CoreVirtualKeyStates.Down); + bool IS_ALT_PRESSED = InputKeyboardSource + .GetKeyStateForCurrentThread(VirtualKey.LeftMenu) + .HasFlag(CoreVirtualKeyStates.Down); + IS_ALT_PRESSED |= InputKeyboardSource + .GetKeyStateForCurrentThread(VirtualKey.RightMenu) + .HasFlag(CoreVirtualKeyStates.Down); if (e.Key == VirtualKey.Enter && package is not null) { @@ -1309,8 +1545,10 @@ public void PackageItemContainer_PreviewKeyDown(object sender, KeyRoutedEventArg else { TEL_InstallReferral referral = TEL_InstallReferral.ALREADY_INSTALLED; - if (PAGE_NAME == "Bundles") referral = TEL_InstallReferral.FROM_BUNDLE; - if (PAGE_NAME == "Discover") referral = TEL_InstallReferral.DIRECT_SEARCH; + if (PAGE_NAME == "Bundles") + referral = TEL_InstallReferral.FROM_BUNDLE; + if (PAGE_NAME == "Discover") + referral = TEL_InstallReferral.DIRECT_SEARCH; ShowDetailsForPackage(package, referral); e.Handled = true; } @@ -1388,7 +1626,10 @@ private void FilteringPanel_SizeChanged(object sender, SizeChangedEventArgs e) ChangeFilteringPaneLayout(); } - private void FilteringPanel_PaneClosing(SplitView sender, SplitViewPaneClosingEventArgs args) + private void FilteringPanel_PaneClosing( + SplitView sender, + SplitViewPaneClosingEventArgs args + ) { ToggleFiltersButton.IsChecked = false; HideFilteringPane(); @@ -1396,11 +1637,16 @@ private void FilteringPanel_PaneClosing(SplitView sender, SplitViewPaneClosingEv private void ViewModeSelector_SelectionChanged(object sender, SelectionChangedEventArgs e) { - Settings.SetDictionaryItem(Settings.K.PackageListViewMode, PAGE_NAME, ViewModeSelector.SelectedIndex); + Settings.SetDictionaryItem( + Settings.K.PackageListViewMode, + PAGE_NAME, + ViewModeSelector.SelectedIndex + ); GenerateHeaderBarTitles(); } FrameworkElement _lastContextMenuButtonTapped = null!; + private void ContextMenuButton_Tapped(object sender, TappedRoutedEventArgs e) { if (sender is FrameworkElement el) @@ -1409,6 +1655,7 @@ private void ContextMenuButton_Tapped(object sender, TappedRoutedEventArgs e) private bool? _pageIsWide; private bool? _titleHidden; + private void ABSTRACT_PAGE_SizeChanged(object sender, SizeChangedEventArgs e) { if (ActualWidth < 500) @@ -1425,7 +1672,6 @@ private void ABSTRACT_PAGE_SizeChanged(object sender, SizeChangedEventArgs e) { _titleHidden = true; MainSubtitle.Visibility = Visibility.Visible; - } } @@ -1465,13 +1711,15 @@ public void SearchBox_TextChanged(object? sender, AutoSuggestBoxTextChangedEvent } } - public virtual void SearchBox_QuerySubmitted(object? sender, AutoSuggestBoxQuerySubmittedEventArgs args) + public virtual void SearchBox_QuerySubmitted( + object? sender, + AutoSuggestBoxQuerySubmittedEventArgs args + ) { // Handle Enter pressed or search button pressed MegaQueryBlockGrid.Visibility = Visibility.Collapsed; if (!DISABLE_FILTER_ON_QUERY_CHANGE) FilterPackages(true); - } } } diff --git a/src/UniGetUI/Pages/SoftwarePages/DiscoverSoftwarePage.cs b/src/UniGetUI/Pages/SoftwarePages/DiscoverSoftwarePage.cs index cd5710bf03..6a19859e7f 100644 --- a/src/UniGetUI/Pages/SoftwarePages/DiscoverSoftwarePage.cs +++ b/src/UniGetUI/Pages/SoftwarePages/DiscoverSoftwarePage.cs @@ -1,19 +1,19 @@ using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Controls.Primitives; +using Microsoft.UI.Xaml.Input; using UniGetUI.Core.Logging; using UniGetUI.Core.Tools; using UniGetUI.Interface.Enums; +using UniGetUI.Interface.Telemetry; using UniGetUI.Interface.Widgets; using UniGetUI.PackageEngine; using UniGetUI.PackageEngine.Enums; using UniGetUI.PackageEngine.Interfaces; using UniGetUI.PackageEngine.PackageLoader; +using UniGetUI.Pages.DialogPages; using Windows.System; using Windows.UI.Text; -using Microsoft.UI.Xaml.Controls.Primitives; -using UniGetUI.Interface.Telemetry; -using UniGetUI.Pages.DialogPages; -using Microsoft.UI.Xaml.Input; namespace UniGetUI.Interface.SoftwarePages { @@ -23,39 +23,55 @@ public partial class DiscoverSoftwarePage : AbstractPackagesPage private BetterMenuItem? MenuInteractive; private BetterMenuItem? MenuSkipHash; private BetterMenuItem? MenuDownloadInstaller; + public DiscoverSoftwarePage() - : base(new PackagesPageData - { - DisableAutomaticPackageLoadOnStart = true, - DisableFilterOnQueryChange = true, - MegaQueryBlockEnabled = true, - PackagesAreCheckedByDefault = false, - ShowLastLoadTime = false, - DisableReload = false, - DisableSuggestedResultsRadio = false, - PageName = "Discover", - - Loader = DiscoverablePackagesLoader.Instance, - PageRole = OperationType.Install, - - NoPackages_BackgroundText = CoreTools.Translate("No results were found matching the input criteria"), - NoPackages_SourcesText = CoreTools.Translate("No packages were found"), - NoPackages_SubtitleText_Base = CoreTools.Translate("No packages were found"), - MainSubtitle_StillLoading = CoreTools.Translate("Loading packages"), - NoMatches_BackgroundText = CoreTools.Translate("No results were found matching the input criteria"), - - PageTitle = CoreTools.Translate("Discover Packages"), - Glyph = "\uF6FA" - }) + : base( + new PackagesPageData + { + DisableAutomaticPackageLoadOnStart = true, + DisableFilterOnQueryChange = true, + MegaQueryBlockEnabled = true, + PackagesAreCheckedByDefault = false, + ShowLastLoadTime = false, + DisableReload = false, + DisableSuggestedResultsRadio = false, + PageName = "Discover", + + Loader = DiscoverablePackagesLoader.Instance, + PageRole = OperationType.Install, + + NoPackages_BackgroundText = CoreTools.Translate( + "No results were found matching the input criteria" + ), + NoPackages_SourcesText = CoreTools.Translate("No packages were found"), + NoPackages_SubtitleText_Base = CoreTools.Translate("No packages were found"), + MainSubtitle_StillLoading = CoreTools.Translate("Loading packages"), + NoMatches_BackgroundText = CoreTools.Translate( + "No results were found matching the input criteria" + ), + + PageTitle = CoreTools.Translate("Discover Packages"), + Glyph = "\uF6FA", + } + ) { InstantSearchCheckbox.IsEnabled = false; InstantSearchCheckbox.Visibility = Visibility.Collapsed; MegaFindButton.Click += Event_SearchPackages; - MegaQueryBlock.KeyUp += (s, e) => { if (e.Key == VirtualKey.Enter) { Event_SearchPackages(s, e); } }; + MegaQueryBlock.KeyUp += (s, e) => + { + if (e.Key == VirtualKey.Enter) + { + Event_SearchPackages(s, e); + } + }; } - public override void SearchBox_QuerySubmitted(object? sender, AutoSuggestBoxQuerySubmittedEventArgs args) + public override void SearchBox_QuerySubmitted( + object? sender, + AutoSuggestBoxQuerySubmittedEventArgs args + ) { base.SearchBox_QuerySubmitted(sender, args); Event_SearchPackages(sender, new()); @@ -69,7 +85,7 @@ public override BetterMenu GenerateContextMenu() { Text = CoreTools.AutoTranslated("Install"), IconName = IconType.Download, - KeyboardAcceleratorTextOverride = "Ctrl+Enter" + KeyboardAcceleratorTextOverride = "Ctrl+Enter", }; menuInstall.Click += MenuInstall_Invoked; menu.Items.Add(menuInstall); @@ -80,7 +96,7 @@ public override BetterMenu GenerateContextMenu() { Text = CoreTools.AutoTranslated("Install options"), IconName = IconType.Options, - KeyboardAcceleratorTextOverride = "Alt+Enter" + KeyboardAcceleratorTextOverride = "Alt+Enter", }; menuInstallSettings.Click += MenuInstallSettings_Invoked; menu.Items.Add(menuInstallSettings); @@ -90,7 +106,7 @@ public override BetterMenu GenerateContextMenu() MenuAsAdmin = new BetterMenuItem { Text = CoreTools.AutoTranslated("Install as administrator"), - IconName = IconType.UAC + IconName = IconType.UAC, }; MenuAsAdmin.Click += MenuAsAdmin_Invoked; menu.Items.Add(MenuAsAdmin); @@ -98,7 +114,7 @@ public override BetterMenu GenerateContextMenu() MenuInteractive = new BetterMenuItem { Text = CoreTools.AutoTranslated("Interactive installation"), - IconName = IconType.Interactive + IconName = IconType.Interactive, }; MenuInteractive.Click += MenuInteractive_Invoked; menu.Items.Add(MenuInteractive); @@ -106,7 +122,7 @@ public override BetterMenu GenerateContextMenu() MenuSkipHash = new BetterMenuItem { Text = CoreTools.AutoTranslated("Skip hash check"), - IconName = IconType.Checksum + IconName = IconType.Checksum, }; MenuSkipHash.Click += MenuSkipHash_Invoked; menu.Items.Add(MenuSkipHash); @@ -114,9 +130,13 @@ public override BetterMenu GenerateContextMenu() MenuDownloadInstaller = new BetterMenuItem { Text = CoreTools.AutoTranslated("Download installer"), - IconName = IconType.Download + IconName = IconType.Download, }; - MenuDownloadInstaller.Click += (_, _) => _ = MainApp.Operations.AskLocationAndDownload(SelectedItem, TEL_InstallReferral.DIRECT_SEARCH); + MenuDownloadInstaller.Click += (_, _) => + _ = MainApp.Operations.AskLocationAndDownload( + SelectedItem, + TEL_InstallReferral.DIRECT_SEARCH + ); menu.Items.Add(MenuDownloadInstaller); menu.Items.Add(new MenuFlyoutSeparator { Height = 5 }); @@ -124,7 +144,7 @@ public override BetterMenu GenerateContextMenu() BetterMenuItem menuShare = new() { Text = CoreTools.AutoTranslated("Share this package"), - IconName = IconType.Share + IconName = IconType.Share, }; menuShare.Click += MenuShare_Invoked; menu.Items.Add(menuShare); @@ -133,7 +153,7 @@ public override BetterMenu GenerateContextMenu() { Text = CoreTools.AutoTranslated("Package details"), IconName = IconType.Info_Round, - KeyboardAcceleratorTextOverride = "Enter" + KeyboardAcceleratorTextOverride = "Enter", }; menuDetails.Click += MenuDetails_Invoked; menu.Items.Add(menuDetails); @@ -150,14 +170,15 @@ public override void GenerateToolBar() MainToolbarButtonDropdown.Flyout = new BetterMenu() { - Items = { + Items = + { InstallAsAdmin, InstallSkipHash, InstallInteractive, new MenuFlyoutSeparator(), DownloadInstallers, - }, - Placement = FlyoutPlacementMode.Bottom + }, + Placement = FlyoutPlacementMode.Bottom, }; MainToolbarButtonIcon.Icon = IconType.Download; MainToolbarButtonText.Text = CoreTools.Translate("Install selection"); @@ -182,44 +203,69 @@ public override void GenerateToolBar() ToolBar.PrimaryCommands.Add(HelpButton); Dictionary Labels = new() - { // Entries with a trailing space are collapsed + { // Entries with a trailing space are collapsed // Their texts will be used as the tooltip - { InstallAsAdmin, CoreTools.Translate("Install as administrator") }, - { InstallSkipHash, CoreTools.Translate("Skip integrity checks") }, - { InstallInteractive, CoreTools.Translate("Interactive installation") }, - { DownloadInstallers, CoreTools.Translate("Download selected installers") }, - { InstallationSettings, CoreTools.Translate("Install options") }, - { PackageDetails, " " + CoreTools.Translate("Package details") }, - { SharePackage, " " + CoreTools.Translate("Share") }, - { ExportSelection, CoreTools.Translate("Add selection to bundle") }, - { HelpButton, CoreTools.Translate("Help") } + { InstallAsAdmin, CoreTools.Translate("Install as administrator") }, + { InstallSkipHash, CoreTools.Translate("Skip integrity checks") }, + { InstallInteractive, CoreTools.Translate("Interactive installation") }, + { DownloadInstallers, CoreTools.Translate("Download selected installers") }, + { InstallationSettings, CoreTools.Translate("Install options") }, + { PackageDetails, " " + CoreTools.Translate("Package details") }, + { SharePackage, " " + CoreTools.Translate("Share") }, + { ExportSelection, CoreTools.Translate("Add selection to bundle") }, + { HelpButton, CoreTools.Translate("Help") }, }; Dictionary Icons = new() { - { InstallAsAdmin, IconType.UAC }, - { InstallSkipHash, IconType.Checksum }, + { InstallAsAdmin, IconType.UAC }, + { InstallSkipHash, IconType.Checksum }, { InstallationSettings, IconType.Options }, - { DownloadInstallers, IconType.Download }, - { InstallInteractive, IconType.Interactive }, - { PackageDetails, IconType.Info_Round }, - { SharePackage, IconType.Share }, - { ExportSelection, IconType.AddTo }, - { HelpButton, IconType.Help } + { DownloadInstallers, IconType.Download }, + { InstallInteractive, IconType.Interactive }, + { PackageDetails, IconType.Info_Round }, + { SharePackage, IconType.Share }, + { ExportSelection, IconType.AddTo }, + { HelpButton, IconType.Help }, }; ApplyTextAndIconsToToolbar(Labels, Icons); - PackageDetails.Click += (_, _) => ShowDetailsForPackage(SelectedItem, TEL_InstallReferral.DIRECT_SEARCH); + PackageDetails.Click += (_, _) => + ShowDetailsForPackage(SelectedItem, TEL_InstallReferral.DIRECT_SEARCH); ExportSelection.Click += ExportSelection_Click; HelpButton.Click += (_, _) => MainApp.Instance.MainWindow.NavigationPage.ShowHelp(); - InstallationSettings.Click += (_, _) => _ = ShowInstallationOptionsForPackage(SelectedItem); - - MainToolbarButton.Click += (_, _) => MainApp.Operations.Install(FilteredPackages.GetCheckedPackages(), TEL_InstallReferral.DIRECT_SEARCH); - InstallAsAdmin.Click += (_, _) => MainApp.Operations.Install(FilteredPackages.GetCheckedPackages(), TEL_InstallReferral.DIRECT_SEARCH, elevated: true); - InstallSkipHash.Click += (_, _) => MainApp.Operations.Install(FilteredPackages.GetCheckedPackages(), TEL_InstallReferral.DIRECT_SEARCH, no_integrity: true); - InstallInteractive.Click += (_, _) => MainApp.Operations.Install(FilteredPackages.GetCheckedPackages(), TEL_InstallReferral.DIRECT_SEARCH, interactive: true); - DownloadInstallers.Click += (_, _) => _ = MainApp.Operations.Download(FilteredPackages.GetCheckedPackages(), TEL_InstallReferral.DIRECT_SEARCH); + InstallationSettings.Click += (_, _) => + _ = ShowInstallationOptionsForPackage(SelectedItem); + + MainToolbarButton.Click += (_, _) => + MainApp.Operations.Install( + FilteredPackages.GetCheckedPackages(), + TEL_InstallReferral.DIRECT_SEARCH + ); + InstallAsAdmin.Click += (_, _) => + MainApp.Operations.Install( + FilteredPackages.GetCheckedPackages(), + TEL_InstallReferral.DIRECT_SEARCH, + elevated: true + ); + InstallSkipHash.Click += (_, _) => + MainApp.Operations.Install( + FilteredPackages.GetCheckedPackages(), + TEL_InstallReferral.DIRECT_SEARCH, + no_integrity: true + ); + InstallInteractive.Click += (_, _) => + MainApp.Operations.Install( + FilteredPackages.GetCheckedPackages(), + TEL_InstallReferral.DIRECT_SEARCH, + interactive: true + ); + DownloadInstallers.Click += (_, _) => + _ = MainApp.Operations.Download( + FilteredPackages.GetCheckedPackages(), + TEL_InstallReferral.DIRECT_SEARCH + ); SharePackage.Click += (_, _) => DialogHelper.SharePackage(SelectedItem); } @@ -244,15 +290,18 @@ private void Event_SearchPackages(object? sender, RoutedEventArgs e) } } - protected override void WhenPackageCountUpdated() - { } + protected override void WhenPackageCountUpdated() { } - protected override void WhenPackagesLoaded(ReloadReason reason) - { } + protected override void WhenPackagesLoaded(ReloadReason reason) { } protected override void WhenShowingContextMenu(IPackage package) { - if (MenuAsAdmin is null || MenuInteractive is null || MenuSkipHash is null || MenuDownloadInstaller is null) + if ( + MenuAsAdmin is null + || MenuInteractive is null + || MenuSkipHash is null + || MenuDownloadInstaller is null + ) { Logger.Warn("MenuItems are null on DiscoverPackagesPage"); return; @@ -264,12 +313,16 @@ protected override void WhenShowingContextMenu(IPackage package) MenuDownloadInstaller.IsEnabled = package.Manager.Capabilities.CanDownloadInstaller; } - private void ExportSelection_Click(object sender, RoutedEventArgs e) => _ = _exportSelection_Click(); + private void ExportSelection_Click(object sender, RoutedEventArgs e) => + _ = _exportSelection_Click(); + private async Task _exportSelection_Click() { MainApp.Instance.MainWindow.NavigationPage.NavigateTo(PageType.Bundles); int loadingId = DialogHelper.ShowLoadingDialog(CoreTools.Translate("Please wait...")); - await PackageBundlesLoader.Instance.AddPackagesAsync(FilteredPackages.GetCheckedPackages()); + await PackageBundlesLoader.Instance.AddPackagesAsync( + FilteredPackages.GetCheckedPackages() + ); DialogHelper.HideLoadingDialog(loadingId); } @@ -286,20 +339,31 @@ private void MenuShare_Invoked(object sender, RoutedEventArgs e) DialogHelper.SharePackage(SelectedItem); } - private void MenuInstall_Invoked(object sender, RoutedEventArgs e) - => _ = MainApp.Operations.Install(SelectedItem, TEL_InstallReferral.DIRECT_SEARCH); - - private void MenuSkipHash_Invoked(object sender, RoutedEventArgs e) - => _ = MainApp.Operations.Install(SelectedItem, TEL_InstallReferral.DIRECT_SEARCH, no_integrity: true); - - private void MenuInteractive_Invoked(object sender, RoutedEventArgs e) - => _ = MainApp.Operations.Install(SelectedItem, TEL_InstallReferral.DIRECT_SEARCH, interactive: true); - - private void MenuAsAdmin_Invoked(object sender, RoutedEventArgs e) - => _ = MainApp.Operations.Install(SelectedItem, TEL_InstallReferral.DIRECT_SEARCH, elevated: true); - - private void MenuInstallSettings_Invoked(object sender, RoutedEventArgs e) - => _ = ShowInstallationOptionsForPackage(SelectedItem); - + private void MenuInstall_Invoked(object sender, RoutedEventArgs e) => + _ = MainApp.Operations.Install(SelectedItem, TEL_InstallReferral.DIRECT_SEARCH); + + private void MenuSkipHash_Invoked(object sender, RoutedEventArgs e) => + _ = MainApp.Operations.Install( + SelectedItem, + TEL_InstallReferral.DIRECT_SEARCH, + no_integrity: true + ); + + private void MenuInteractive_Invoked(object sender, RoutedEventArgs e) => + _ = MainApp.Operations.Install( + SelectedItem, + TEL_InstallReferral.DIRECT_SEARCH, + interactive: true + ); + + private void MenuAsAdmin_Invoked(object sender, RoutedEventArgs e) => + _ = MainApp.Operations.Install( + SelectedItem, + TEL_InstallReferral.DIRECT_SEARCH, + elevated: true + ); + + private void MenuInstallSettings_Invoked(object sender, RoutedEventArgs e) => + _ = ShowInstallationOptionsForPackage(SelectedItem); } } diff --git a/src/UniGetUI/Pages/SoftwarePages/InstalledPackagesPage.cs b/src/UniGetUI/Pages/SoftwarePages/InstalledPackagesPage.cs index a3df50ffd8..a4c6c2a4a4 100644 --- a/src/UniGetUI/Pages/SoftwarePages/InstalledPackagesPage.cs +++ b/src/UniGetUI/Pages/SoftwarePages/InstalledPackagesPage.cs @@ -1,4 +1,3 @@ -using Windows.UI.Text; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Controls.Primitives; @@ -16,6 +15,7 @@ using UniGetUI.PackageEngine.PackageLoader; using UniGetUI.Pages.DialogPages; using UniGetUI.Services; +using Windows.UI.Text; namespace UniGetUI.Interface.SoftwarePages { @@ -36,31 +36,36 @@ public partial class InstalledPackagesPage : AbstractPackagesPage private BetterMenuItem? MenuDownloadInstaller; public InstalledPackagesPage() - : base(new PackagesPageData - { - DisableAutomaticPackageLoadOnStart = false, - DisableFilterOnQueryChange = false, - MegaQueryBlockEnabled = false, - ShowLastLoadTime = false, - DisableReload = false, - PackagesAreCheckedByDefault = false, - DisableSuggestedResultsRadio = true, - PageName = "Installed", - - Loader = InstalledPackagesLoader.Instance, - PageRole = OperationType.Uninstall, - - NoPackages_BackgroundText = CoreTools.Translate("No results were found matching the input criteria"), - NoPackages_SourcesText = CoreTools.Translate("No packages were found"), - NoPackages_SubtitleText_Base = CoreTools.Translate("No packages were found"), - MainSubtitle_StillLoading = CoreTools.Translate("Loading packages"), - NoMatches_BackgroundText = CoreTools.Translate("No results were found matching the input criteria"), - - PageTitle = CoreTools.Translate("Installed Packages"), - Glyph = "\uE977" - }) - { - } + : base( + new PackagesPageData + { + DisableAutomaticPackageLoadOnStart = false, + DisableFilterOnQueryChange = false, + MegaQueryBlockEnabled = false, + ShowLastLoadTime = false, + DisableReload = false, + PackagesAreCheckedByDefault = false, + DisableSuggestedResultsRadio = true, + PageName = "Installed", + + Loader = InstalledPackagesLoader.Instance, + PageRole = OperationType.Uninstall, + + NoPackages_BackgroundText = CoreTools.Translate( + "No results were found matching the input criteria" + ), + NoPackages_SourcesText = CoreTools.Translate("No packages were found"), + NoPackages_SubtitleText_Base = CoreTools.Translate("No packages were found"), + MainSubtitle_StillLoading = CoreTools.Translate("Loading packages"), + NoMatches_BackgroundText = CoreTools.Translate( + "No results were found matching the input criteria" + ), + + PageTitle = CoreTools.Translate("Installed Packages"), + Glyph = "\uE977", + } + ) + { } public override BetterMenu GenerateContextMenu() { @@ -69,7 +74,7 @@ public override BetterMenu GenerateContextMenu() { Text = CoreTools.AutoTranslated("Uninstall"), IconName = IconType.Delete, - KeyboardAcceleratorTextOverride = "Ctrl+Enter" + KeyboardAcceleratorTextOverride = "Ctrl+Enter", }; menuUninstall.Click += MenuUninstall_Invoked; menu.Items.Add(menuUninstall); @@ -80,7 +85,7 @@ public override BetterMenu GenerateContextMenu() { Text = CoreTools.AutoTranslated("Uninstall options"), IconName = IconType.Options, - KeyboardAcceleratorTextOverride = "Alt+Enter" + KeyboardAcceleratorTextOverride = "Alt+Enter", }; MenuInstallationOptions.Click += MenuInstallSettings_Invoked; menu.Items.Add(MenuInstallationOptions); @@ -90,7 +95,8 @@ public override BetterMenu GenerateContextMenu() Text = CoreTools.AutoTranslated("Open install location"), IconName = IconType.Launch, }; - MenuOpenInstallLocation.Click += (_, _) => OpenPackageInstallLocation(SelectedItem);; + MenuOpenInstallLocation.Click += (_, _) => OpenPackageInstallLocation(SelectedItem); + ; menu.Items.Add(MenuOpenInstallLocation); menu.Items.Add(new MenuFlyoutSeparator()); @@ -98,7 +104,7 @@ public override BetterMenu GenerateContextMenu() MenuAsAdmin = new BetterMenuItem { Text = CoreTools.AutoTranslated("Uninstall as administrator"), - IconName = IconType.UAC + IconName = IconType.UAC, }; MenuAsAdmin.Click += MenuAsAdmin_Invoked; menu.Items.Add(MenuAsAdmin); @@ -106,7 +112,7 @@ public override BetterMenu GenerateContextMenu() MenuInteractive = new BetterMenuItem { Text = CoreTools.AutoTranslated("Interactive uninstall"), - IconName = IconType.Interactive + IconName = IconType.Interactive, }; MenuInteractive.Click += MenuInteractive_Invoked; menu.Items.Add(MenuInteractive); @@ -114,7 +120,7 @@ public override BetterMenu GenerateContextMenu() MenuRemoveData = new BetterMenuItem { Text = CoreTools.AutoTranslated("Uninstall and remove data"), - IconName = IconType.Close_Round + IconName = IconType.Close_Round, }; MenuRemoveData.Click += MenuRemoveData_Invoked; menu.Items.Add(MenuRemoveData); @@ -124,9 +130,13 @@ public override BetterMenu GenerateContextMenu() MenuDownloadInstaller = new BetterMenuItem { Text = CoreTools.AutoTranslated("Download installer"), - IconName = IconType.Download + IconName = IconType.Download, }; - MenuDownloadInstaller.Click += (_, _) => _ = MainApp.Operations.AskLocationAndDownload(SelectedItem, TEL_InstallReferral.ALREADY_INSTALLED); + MenuDownloadInstaller.Click += (_, _) => + _ = MainApp.Operations.AskLocationAndDownload( + SelectedItem, + TEL_InstallReferral.ALREADY_INSTALLED + ); menu.Items.Add(MenuDownloadInstaller); menu.Items.Add(new MenuFlyoutSeparator()); @@ -134,7 +144,7 @@ public override BetterMenu GenerateContextMenu() MenuReinstallPackage = new() { Text = CoreTools.AutoTranslated("Reinstall package"), - IconName = IconType.Download + IconName = IconType.Download, }; MenuReinstallPackage.Click += MenuReinstall_Invoked; menu.Items.Add(MenuReinstallPackage); @@ -142,7 +152,7 @@ public override BetterMenu GenerateContextMenu() MenuUninstallThenReinstall = new() { Text = CoreTools.AutoTranslated("Uninstall package, then reinstall it"), - IconName = IconType.Undelete + IconName = IconType.Undelete, }; MenuUninstallThenReinstall.Click += MenuUninstallThenReinstall_Invoked; menu.Items.Add(MenuUninstallThenReinstall); @@ -151,7 +161,7 @@ public override BetterMenu GenerateContextMenu() MenuIgnoreUpdates = new() { Text = CoreTools.AutoTranslated("Ignore updates for this package"), - IconName = IconType.Pin + IconName = IconType.Pin, }; MenuIgnoreUpdates.Click += MenuIgnorePackage_Invoked; menu.Items.Add(MenuIgnoreUpdates); @@ -161,7 +171,7 @@ public override BetterMenu GenerateContextMenu() MenuSharePackage = new() { Text = CoreTools.AutoTranslated("Share this package"), - IconName = IconType.Share + IconName = IconType.Share, }; MenuSharePackage.Click += MenuShare_Invoked; menu.Items.Add(MenuSharePackage); @@ -170,7 +180,7 @@ public override BetterMenu GenerateContextMenu() { Text = CoreTools.AutoTranslated("Package details"), IconName = IconType.Info_Round, - KeyboardAcceleratorTextOverride = "Enter" + KeyboardAcceleratorTextOverride = "Enter", }; MenuPackageDetails.Click += MenuDetails_Invoked; menu.Items.Add(MenuPackageDetails); @@ -193,7 +203,7 @@ public override void GenerateToolBar() new MenuFlyoutSeparator(), DownloadInstallers, }, - Placement = FlyoutPlacementMode.Bottom + Placement = FlyoutPlacementMode.Bottom, }; MainToolbarButtonIcon.Icon = IconType.Delete; MainToolbarButtonText.Text = CoreTools.Translate("Uninstall selection"); @@ -224,40 +234,42 @@ public override void GenerateToolBar() Dictionary Labels = new() { // Entries with a trailing space are collapsed - // Their texts will be used as the tooltip - { UninstallAsAdmin, CoreTools.Translate("Uninstall as administrator") }, + // Their texts will be used as the tooltip + { UninstallAsAdmin, CoreTools.Translate("Uninstall as administrator") }, { UninstallInteractive, CoreTools.Translate("Interactive uninstall") }, - { DownloadInstallers, CoreTools.Translate("Download selected installers") }, + { DownloadInstallers, CoreTools.Translate("Download selected installers") }, { InstallationSettings, " " + CoreTools.Translate("Uninstall options") }, - { PackageDetails, " " + CoreTools.Translate("Package details") }, - { SharePackage, " " + CoreTools.Translate("Share") }, - { IgnoreSelected, CoreTools.Translate("Ignore selected packages") }, - { ManageIgnored, CoreTools.Translate("Manage ignored updates") }, - { ExportSelection, CoreTools.Translate("Add selection to bundle") }, - { HelpButton, CoreTools.Translate("Help") } + { PackageDetails, " " + CoreTools.Translate("Package details") }, + { SharePackage, " " + CoreTools.Translate("Share") }, + { IgnoreSelected, CoreTools.Translate("Ignore selected packages") }, + { ManageIgnored, CoreTools.Translate("Manage ignored updates") }, + { ExportSelection, CoreTools.Translate("Add selection to bundle") }, + { HelpButton, CoreTools.Translate("Help") }, }; Dictionary Icons = new() { - { UninstallAsAdmin, IconType.UAC }, - { UninstallInteractive, IconType.Interactive }, - { DownloadInstallers, IconType.Download }, - { InstallationSettings, IconType.Options }, - { PackageDetails, IconType.Info_Round }, - { SharePackage, IconType.Share }, - { IgnoreSelected, IconType.Pin }, - { ManageIgnored, IconType.ClipboardList }, - { ExportSelection, IconType.AddTo }, - { HelpButton, IconType.Help } + { UninstallAsAdmin, IconType.UAC }, + { UninstallInteractive, IconType.Interactive }, + { DownloadInstallers, IconType.Download }, + { InstallationSettings, IconType.Options }, + { PackageDetails, IconType.Info_Round }, + { SharePackage, IconType.Share }, + { IgnoreSelected, IconType.Pin }, + { ManageIgnored, IconType.ClipboardList }, + { ExportSelection, IconType.AddTo }, + { HelpButton, IconType.Help }, }; ApplyTextAndIconsToToolbar(Labels, Icons); - PackageDetails.Click += (_, _) => ShowDetailsForPackage(SelectedItem, TEL_InstallReferral.ALREADY_INSTALLED); + PackageDetails.Click += (_, _) => + ShowDetailsForPackage(SelectedItem, TEL_InstallReferral.ALREADY_INSTALLED); ExportSelection.Click += ExportSelection_Click; HelpButton.Click += (_, _) => MainApp.Instance.MainWindow.NavigationPage.ShowHelp(); - InstallationSettings.Click += (_, _) => _ = ShowInstallationOptionsForPackage(SelectedItem); + InstallationSettings.Click += (_, _) => + _ = ShowInstallationOptionsForPackage(SelectedItem); ManageIgnored.Click += async (_, _) => await DialogHelper.ManageIgnoredUpdates(); IgnoreSelected.Click += async (_, _) => { @@ -271,10 +283,23 @@ public override void GenerateToolBar() } }; - MainToolbarButton.Click += (_, _) => _ = MainApp.Operations.ConfirmAndUninstall(FilteredPackages.GetCheckedPackages()); - UninstallAsAdmin.Click += (_, _) => _ = MainApp.Operations.ConfirmAndUninstall(FilteredPackages.GetCheckedPackages(), elevated: true); - UninstallInteractive.Click += (_, _) => _ = MainApp.Operations.ConfirmAndUninstall(FilteredPackages.GetCheckedPackages(), interactive: true); - DownloadInstallers.Click += (_, _) => _ = MainApp.Operations.Download(FilteredPackages.GetCheckedPackages(), TEL_InstallReferral.ALREADY_INSTALLED); + MainToolbarButton.Click += (_, _) => + _ = MainApp.Operations.ConfirmAndUninstall(FilteredPackages.GetCheckedPackages()); + UninstallAsAdmin.Click += (_, _) => + _ = MainApp.Operations.ConfirmAndUninstall( + FilteredPackages.GetCheckedPackages(), + elevated: true + ); + UninstallInteractive.Click += (_, _) => + _ = MainApp.Operations.ConfirmAndUninstall( + FilteredPackages.GetCheckedPackages(), + interactive: true + ); + DownloadInstallers.Click += (_, _) => + _ = MainApp.Operations.Download( + FilteredPackages.GetCheckedPackages(), + TEL_InstallReferral.ALREADY_INSTALLED + ); SharePackage.Click += (_, _) => DialogHelper.SharePackage(SelectedItem); } @@ -298,24 +323,29 @@ protected override void WhenPackagesLoaded(ReloadReason reason) } } - if (WinGet.NO_PACKAGES_HAVE_BEEN_LOADED/* && !Settings.Get(Settings.K.DisableWinGetMalfunctionDetector)*/) + if ( + WinGet.NO_PACKAGES_HAVE_BEEN_LOADED /* && !Settings.Get(Settings.K.DisableWinGetMalfunctionDetector)*/ + ) { var infoBar = MainApp.Instance.MainWindow.WinGetWarningBanner; infoBar.IsOpen = true; infoBar.Title = CoreTools.Translate("WinGet malfunction detected"); - infoBar.Message = CoreTools.Translate("It looks like WinGet is not working properly. Do you want to attempt to repair WinGet?"); + infoBar.Message = CoreTools.Translate( + "It looks like WinGet is not working properly. Do you want to attempt to repair WinGet?" + ); var button = new Button { Content = CoreTools.Translate("Repair WinGet") }; infoBar.ActionButton = button; button.Click += (_, _) => _ = DialogHelper.HandleBrokenWinGet(); } } - protected override void WhenShowingContextMenu(IPackage package) - => _ = _whenShowingContextMenu(package); + protected override void WhenShowingContextMenu(IPackage package) => + _ = _whenShowingContextMenu(package); private async Task _whenShowingContextMenu(IPackage package) { - if (MenuAsAdmin is null + if ( + MenuAsAdmin is null || MenuInteractive is null || MenuRemoveData is null || MenuInstallationOptions is null @@ -325,7 +355,8 @@ private async Task _whenShowingContextMenu(IPackage package) || MenuSharePackage is null || MenuPackageDetails is null || MenuOpenInstallLocation is null - || MenuDownloadInstaller is null) + || MenuDownloadInstaller is null + ) { Logger.Error("Menu items are null on InstalledPackagesTab"); return; @@ -343,14 +374,19 @@ private async Task _whenShowingContextMenu(IPackage package) MenuIgnoreUpdates.IsEnabled = false; // Will be set on the lines below; MenuSharePackage.IsEnabled = !IS_LOCAL; MenuPackageDetails.IsEnabled = !IS_LOCAL; - MenuDownloadInstaller.IsEnabled = !IS_LOCAL && package.Manager.Capabilities.CanDownloadInstaller;; + MenuDownloadInstaller.IsEnabled = + !IS_LOCAL && package.Manager.Capabilities.CanDownloadInstaller; + ; - MenuOpenInstallLocation.IsEnabled = package.Manager.DetailsHelper.GetInstallLocation(package) is not null; + MenuOpenInstallLocation.IsEnabled = + package.Manager.DetailsHelper.GetInstallLocation(package) is not null; if (!IS_LOCAL) { if (await package.HasUpdatesIgnoredAsync()) { - MenuIgnoreUpdates.Text = CoreTools.Translate("Do not ignore updates for this package anymore"); + MenuIgnoreUpdates.Text = CoreTools.Translate( + "Do not ignore updates for this package anymore" + ); MenuIgnoreUpdates.Icon = new FontIcon { Glyph = "\uE77A" }; } else @@ -362,12 +398,16 @@ private async Task _whenShowingContextMenu(IPackage package) } } - private void ExportSelection_Click(object sender, RoutedEventArgs e) => _ = _exportSelection_Click(); + private void ExportSelection_Click(object sender, RoutedEventArgs e) => + _ = _exportSelection_Click(); + private async Task _exportSelection_Click() { MainApp.Instance.MainWindow.NavigationPage.NavigateTo(PageType.Bundles); int loadingId = DialogHelper.ShowLoadingDialog(CoreTools.Translate("Please wait...")); - await PackageBundlesLoader.Instance.AddPackagesAsync(FilteredPackages.GetCheckedPackages()); + await PackageBundlesLoader.Instance.AddPackagesAsync( + FilteredPackages.GetCheckedPackages() + ); DialogHelper.HideLoadingDialog(loadingId); } @@ -420,7 +460,10 @@ public static async Task BackupPackages_LOCAL() string fileName = Settings.GetValue(Settings.K.ChangeBackupFileName); if (fileName == "") { - fileName = CoreTools.Translate("{pcName} installed packages", new Dictionary { { "pcName", Environment.MachineName } }); + fileName = CoreTools.Translate( + "{pcName} installed packages", + new Dictionary { { "pcName", Environment.MachineName } } + ); } if (Settings.Get(Settings.K.EnableBackupTimestamping)) @@ -442,29 +485,35 @@ public static async Task BackupPackages_LOCAL() } } - private void MenuUninstall_Invoked(object sender, RoutedEventArgs args) - => _ = MainApp.Operations.ConfirmAndUninstall(SelectedItem); + private void MenuUninstall_Invoked(object sender, RoutedEventArgs args) => + _ = MainApp.Operations.ConfirmAndUninstall(SelectedItem); - private void MenuAsAdmin_Invoked(object sender, RoutedEventArgs args) - => _ = MainApp.Operations.ConfirmAndUninstall(SelectedItem, elevated: true); + private void MenuAsAdmin_Invoked(object sender, RoutedEventArgs args) => + _ = MainApp.Operations.ConfirmAndUninstall(SelectedItem, elevated: true); - private void MenuInteractive_Invoked(object sender, RoutedEventArgs args) - => _ = MainApp.Operations.ConfirmAndUninstall(SelectedItem, interactive: true); + private void MenuInteractive_Invoked(object sender, RoutedEventArgs args) => + _ = MainApp.Operations.ConfirmAndUninstall(SelectedItem, interactive: true); - private void MenuRemoveData_Invoked(object sender, RoutedEventArgs args) - => _ = MainApp.Operations.ConfirmAndUninstall(SelectedItem, remove_data: true); + private void MenuRemoveData_Invoked(object sender, RoutedEventArgs args) => + _ = MainApp.Operations.ConfirmAndUninstall(SelectedItem, remove_data: true); - private void MenuReinstall_Invoked(object sender, RoutedEventArgs args) - => _ = MainApp.Operations.Install(SelectedItem, TEL_InstallReferral.ALREADY_INSTALLED); + private void MenuReinstall_Invoked(object sender, RoutedEventArgs args) => + _ = MainApp.Operations.Install(SelectedItem, TEL_InstallReferral.ALREADY_INSTALLED); - private void MenuUninstallThenReinstall_Invoked(object sender, RoutedEventArgs args) - => _ = MainApp.Operations.UninstallThenReinstall(SelectedItem, TEL_InstallReferral.ALREADY_INSTALLED); + private void MenuUninstallThenReinstall_Invoked(object sender, RoutedEventArgs args) => + _ = MainApp.Operations.UninstallThenReinstall( + SelectedItem, + TEL_InstallReferral.ALREADY_INSTALLED + ); + + private void MenuIgnorePackage_Invoked(object sender, RoutedEventArgs args) => + _ = _menuIgnorePackage_Invoked(); - private void MenuIgnorePackage_Invoked(object sender, RoutedEventArgs args) => _ = _menuIgnorePackage_Invoked(); private async Task _menuIgnorePackage_Invoked() { IPackage? package = SelectedItem; - if (package is null) return; + if (package is null) + return; if (await package.HasUpdatesIgnoredAsync()) { diff --git a/src/UniGetUI/Pages/SoftwarePages/PackageBundlesPage.cs b/src/UniGetUI/Pages/SoftwarePages/PackageBundlesPage.cs index 48e509a474..30a37bb97a 100644 --- a/src/UniGetUI/Pages/SoftwarePages/PackageBundlesPage.cs +++ b/src/UniGetUI/Pages/SoftwarePages/PackageBundlesPage.cs @@ -2,7 +2,6 @@ using System.Text.Json; using System.Text.Json.Nodes; using System.Xml.Serialization; -using Windows.UI.Text; using ExternalLibraries.Pickers; using Microsoft.UI.Text; using Microsoft.UI.Xaml; @@ -24,6 +23,7 @@ using UniGetUI.PackageEngine.PackageClasses; using UniGetUI.PackageEngine.PackageLoader; using UniGetUI.Pages.DialogPages; +using Windows.UI.Text; namespace UniGetUI.Interface.SoftwarePages { @@ -52,29 +52,37 @@ private set } public PackageBundlesPage() - : base(new PackagesPageData - { - DisableAutomaticPackageLoadOnStart = true, - DisableFilterOnQueryChange = false, - MegaQueryBlockEnabled = false, - ShowLastLoadTime = false, - DisableReload = true, - PackagesAreCheckedByDefault = false, - DisableSuggestedResultsRadio = true, - PageName = "Bundles", - - Loader = PackageBundlesLoader.Instance, - PageRole = OperationType.Install, - - NoPackages_BackgroundText = CoreTools.Translate("Add packages or open an existing package bundle"), - NoPackages_SourcesText = CoreTools.Translate("Add packages to start"), - NoPackages_SubtitleText_Base = CoreTools.Translate("The current bundle has no packages. Add some packages to get started"), - MainSubtitle_StillLoading = CoreTools.Translate("Loading packages"), - NoMatches_BackgroundText = CoreTools.Translate("No results were found matching the input criteria"), - - PageTitle = CoreTools.Translate("Package Bundles"), - Glyph = "\uF133" - }) + : base( + new PackagesPageData + { + DisableAutomaticPackageLoadOnStart = true, + DisableFilterOnQueryChange = false, + MegaQueryBlockEnabled = false, + ShowLastLoadTime = false, + DisableReload = true, + PackagesAreCheckedByDefault = false, + DisableSuggestedResultsRadio = true, + PageName = "Bundles", + + Loader = PackageBundlesLoader.Instance, + PageRole = OperationType.Install, + + NoPackages_BackgroundText = CoreTools.Translate( + "Add packages or open an existing package bundle" + ), + NoPackages_SourcesText = CoreTools.Translate("Add packages to start"), + NoPackages_SubtitleText_Base = CoreTools.Translate( + "The current bundle has no packages. Add some packages to get started" + ), + MainSubtitle_StillLoading = CoreTools.Translate("Loading packages"), + NoMatches_BackgroundText = CoreTools.Translate( + "No results were found matching the input criteria" + ), + + PageTitle = CoreTools.Translate("Package Bundles"), + Glyph = "\uF133", + } + ) { Loader.PackagesChanged += (_, _) => { @@ -89,7 +97,7 @@ public override BetterMenu GenerateContextMenu() { Text = CoreTools.AutoTranslated("Install"), IconName = IconType.Download, - KeyboardAcceleratorTextOverride = "Ctrl+Enter" + KeyboardAcceleratorTextOverride = "Ctrl+Enter", }; MenuInstall.Click += MenuInstall_Invoked; menu.Items.Add(MenuInstall); @@ -100,7 +108,7 @@ public override BetterMenu GenerateContextMenu() { Text = CoreTools.AutoTranslated("Install options"), IconName = IconType.Options, - KeyboardAcceleratorTextOverride = "Alt+Enter" + KeyboardAcceleratorTextOverride = "Alt+Enter", }; MenuInstallOptions.Click += MenuInstallSettings_Invoked; menu.Items.Add(MenuInstallOptions); @@ -110,7 +118,7 @@ public override BetterMenu GenerateContextMenu() MenuAsAdmin = new BetterMenuItem { Text = CoreTools.AutoTranslated("Install as administrator"), - IconName = IconType.UAC + IconName = IconType.UAC, }; MenuAsAdmin.Click += MenuAsAdmin_Invoked; menu.Items.Add(MenuAsAdmin); @@ -118,7 +126,7 @@ public override BetterMenu GenerateContextMenu() MenuInteractive = new BetterMenuItem { Text = CoreTools.AutoTranslated("Interactive installation"), - IconName = IconType.Interactive + IconName = IconType.Interactive, }; MenuInteractive.Click += MenuInteractive_Invoked; menu.Items.Add(MenuInteractive); @@ -126,7 +134,7 @@ public override BetterMenu GenerateContextMenu() MenuSkipHash = new BetterMenuItem { Text = CoreTools.AutoTranslated("Skip hash checks"), - IconName = IconType.Checksum + IconName = IconType.Checksum, }; MenuSkipHash.Click += MenuSkipHash_Invoked; menu.Items.Add(MenuSkipHash); @@ -134,9 +142,13 @@ public override BetterMenu GenerateContextMenu() MenuDownloadInstaller = new BetterMenuItem { Text = CoreTools.AutoTranslated("Download installer"), - IconName = IconType.Download + IconName = IconType.Download, }; - MenuDownloadInstaller.Click += (_, _) => _ = MainApp.Operations.AskLocationAndDownload(SelectedItem, TEL_InstallReferral.FROM_BUNDLE); + MenuDownloadInstaller.Click += (_, _) => + _ = MainApp.Operations.AskLocationAndDownload( + SelectedItem, + TEL_InstallReferral.FROM_BUNDLE + ); menu.Items.Add(MenuDownloadInstaller); menu.Items.Add(new MenuFlyoutSeparator()); @@ -144,7 +156,7 @@ public override BetterMenu GenerateContextMenu() BetterMenuItem menuRemoveFromList = new() { Text = CoreTools.AutoTranslated("Remove from list"), - IconName = IconType.Delete + IconName = IconType.Delete, }; menuRemoveFromList.Click += MenuRemoveFromList_Invoked; menu.Items.Add(menuRemoveFromList); @@ -153,7 +165,7 @@ public override BetterMenu GenerateContextMenu() MenuShare = new() { Text = CoreTools.AutoTranslated("Share this package"), - IconName = IconType.Share + IconName = IconType.Share, }; MenuShare.Click += MenuShare_Invoked; menu.Items.Add(MenuShare); @@ -162,7 +174,7 @@ public override BetterMenu GenerateContextMenu() { Text = CoreTools.AutoTranslated("Package details"), IconName = IconType.Info_Round, - KeyboardAcceleratorTextOverride = "Enter" + KeyboardAcceleratorTextOverride = "Enter", }; MenuDetails.Click += MenuDetails_Invoked; menu.Items.Add(MenuDetails); @@ -190,7 +202,7 @@ public override void GenerateToolBar() new MenuFlyoutSeparator(), DownloadInstallers, }, - Placement = FlyoutPlacementMode.Bottom + Placement = FlyoutPlacementMode.Bottom, }; MainToolbarButtonIcon.Icon = IconType.Download; MainToolbarButtonText.Text = CoreTools.Translate("Install selection"); @@ -220,37 +232,37 @@ public override void GenerateToolBar() Dictionary Labels = new() { // Entries with a trailing space are collapsed - // Their texts will be used as the tooltip - { NewBundle, CoreTools.Translate("New") }, - { InstallAsAdmin, CoreTools.Translate("Install as administrator") }, - { InstallInteractive, CoreTools.Translate("Interactive installation") }, - { InstallSkipHash, CoreTools.Translate("Skip integrity checks") }, - { DownloadInstallers, CoreTools.Translate("Download selected installers") }, - { OpenBundle, CoreTools.Translate("Open") }, - { ToBatchScript, CoreTools.Translate("Create .ps1 script")}, - { RemoveSelected, CoreTools.Translate("Remove selection from bundle") }, - { SaveBundle, CoreTools.Translate("Save as") }, + // Their texts will be used as the tooltip + { NewBundle, CoreTools.Translate("New") }, + { InstallAsAdmin, CoreTools.Translate("Install as administrator") }, + { InstallInteractive, CoreTools.Translate("Interactive installation") }, + { InstallSkipHash, CoreTools.Translate("Skip integrity checks") }, + { DownloadInstallers, CoreTools.Translate("Download selected installers") }, + { OpenBundle, CoreTools.Translate("Open") }, + { ToBatchScript, CoreTools.Translate("Create .ps1 script") }, + { RemoveSelected, CoreTools.Translate("Remove selection from bundle") }, + { SaveBundle, CoreTools.Translate("Save as") }, { AddPackagesToBundle, CoreTools.Translate("Add packages to bundle") }, - { PackageDetails, " " + CoreTools.Translate("Package details") }, - { SharePackage, " " + CoreTools.Translate("Share") }, - { HelpButton, CoreTools.Translate("Help") } + { PackageDetails, " " + CoreTools.Translate("Package details") }, + { SharePackage, " " + CoreTools.Translate("Share") }, + { HelpButton, CoreTools.Translate("Help") }, }; Dictionary Icons = new() { - { NewBundle, IconType.AddTo }, - { InstallAsAdmin, IconType.UAC }, - { InstallInteractive, IconType.Interactive }, - { InstallSkipHash, IconType.Checksum }, - { DownloadInstallers, IconType.Download }, - { OpenBundle, IconType.OpenFolder }, - { ToBatchScript, IconType.Console}, - { RemoveSelected, IconType.Delete}, - { SaveBundle, IconType.SaveAs }, + { NewBundle, IconType.AddTo }, + { InstallAsAdmin, IconType.UAC }, + { InstallInteractive, IconType.Interactive }, + { InstallSkipHash, IconType.Checksum }, + { DownloadInstallers, IconType.Download }, + { OpenBundle, IconType.OpenFolder }, + { ToBatchScript, IconType.Console }, + { RemoveSelected, IconType.Delete }, + { SaveBundle, IconType.SaveAs }, { AddPackagesToBundle, IconType.AddTo }, - { PackageDetails, IconType.Info_Round }, - { SharePackage, IconType.Share }, - { HelpButton, IconType.Help } + { PackageDetails, IconType.Info_Round }, + { SharePackage, IconType.Share }, + { HelpButton, IconType.Help }, }; ApplyTextAndIconsToToolbar(Labels, Icons); @@ -264,15 +276,25 @@ public override void GenerateToolBar() { DialogHelper.ShowDismissableBalloon( CoreTools.Translate("Something went wrong"), - CoreTools.Translate("\"{0}\" is a local package and can't be shared", SelectedItem.Name) + CoreTools.Translate( + "\"{0}\" is a local package and can't be shared", + SelectedItem.Name + ) ); return; } - _ = DialogHelper.ShowPackageDetails(SelectedItem, OperationType.None, TEL_InstallReferral.FROM_BUNDLE); + _ = DialogHelper.ShowPackageDetails( + SelectedItem, + OperationType.None, + TEL_InstallReferral.FROM_BUNDLE + ); }; - HelpButton.Click += (_, _) => { MainApp.Instance.MainWindow.NavigationPage.ShowHelp(); }; + HelpButton.Click += (_, _) => + { + MainApp.Instance.MainWindow.NavigationPage.ShowHelp(); + }; NewBundle.Click += async (s, e) => await AskForNewBundle(); RemoveSelected.Click += (_, _) => @@ -283,17 +305,28 @@ public override void GenerateToolBar() IReadOnlyList GetCheckedNonInstalledPackages() { - if(Settings.Get(Settings.K.InstallInstalledPackagesBundlesPage)) + if (Settings.Get(Settings.K.InstallInstalledPackagesBundlesPage)) return FilteredPackages.GetCheckedPackages().ToList(); else - return FilteredPackages.GetCheckedPackages().Where(p => p.Tag is not PackageTag.AlreadyInstalled).ToList(); + return FilteredPackages + .GetCheckedPackages() + .Where(p => p.Tag is not PackageTag.AlreadyInstalled) + .ToList(); } - MainToolbarButton.Click += async (_, _) => await ImportAndInstallPackage(GetCheckedNonInstalledPackages()); - InstallSkipHash.Click += async (_, _) => await ImportAndInstallPackage(GetCheckedNonInstalledPackages(), skiphash: true); - InstallInteractive.Click += async (_, _) => await ImportAndInstallPackage(GetCheckedNonInstalledPackages(), interactive: true); - InstallAsAdmin.Click += async (_, _) => await ImportAndInstallPackage(GetCheckedNonInstalledPackages(), elevated: true); - DownloadInstallers.Click += (_, _) => _ = MainApp.Operations.Download(FilteredPackages.GetCheckedPackages(), TEL_InstallReferral.FROM_BUNDLE); + MainToolbarButton.Click += async (_, _) => + await ImportAndInstallPackage(GetCheckedNonInstalledPackages()); + InstallSkipHash.Click += async (_, _) => + await ImportAndInstallPackage(GetCheckedNonInstalledPackages(), skiphash: true); + InstallInteractive.Click += async (_, _) => + await ImportAndInstallPackage(GetCheckedNonInstalledPackages(), interactive: true); + InstallAsAdmin.Click += async (_, _) => + await ImportAndInstallPackage(GetCheckedNonInstalledPackages(), elevated: true); + DownloadInstallers.Click += (_, _) => + _ = MainApp.Operations.Download( + FilteredPackages.GetCheckedPackages(), + TEL_InstallReferral.FROM_BUNDLE + ); OpenBundle.Click += async (_, _) => await AskOpenFromFile(); SaveBundle.Click += async (_, _) => await SaveFile(); ToBatchScript.Click += (_, _) => _ = CreateBatchScript(); @@ -301,7 +334,8 @@ IReadOnlyList GetCheckedNonInstalledPackages() SharePackage.Click += (_, _) => { IPackage? package = SelectedItem; - if (package is not null) DialogHelper.SharePackage(package); + if (package is not null) + DialogHelper.SharePackage(package); }; AddPackagesToBundle.Click += (_, _) => _ = DialogHelper.HowToAddPackagesToBundle(); @@ -309,7 +343,11 @@ IReadOnlyList GetCheckedNonInstalledPackages() public async Task AskForNewBundle() { - if (!Loader.Any() || !HasUnsavedChanges || await DialogHelper.AskLoseChangesAndCreateBundle()) + if ( + !Loader.Any() + || !HasUnsavedChanges + || await DialogHelper.AskLoseChangesAndCreateBundle() + ) { // Need to call ClearPackages, this method also clears internal caches Loader.ClearPackages(); @@ -320,43 +358,60 @@ public async Task AskForNewBundle() return false; } - public async Task ImportAndInstallPackage(IReadOnlyList packages, bool? elevated = null, bool? interactive = null, bool? skiphash = null) + public async Task ImportAndInstallPackage( + IReadOnlyList packages, + bool? elevated = null, + bool? interactive = null, + bool? skiphash = null + ) { - int loadingId = DialogHelper.ShowLoadingDialog(CoreTools.Translate("Preparing packages, please wait...")); + int loadingId = DialogHelper.ShowLoadingDialog( + CoreTools.Translate("Preparing packages, please wait...") + ); List packages_to_install = []; foreach (IPackage package in packages) { if (package is ImportedPackage imported) { - Logger.ImportantInfo($"Registering package {imported.Id} from manager {imported.Source.AsString}"); + Logger.ImportantInfo( + $"Registering package {imported.Id} from manager {imported.Source.AsString}" + ); packages_to_install.Add(await imported.RegisterAndGetPackageAsync()); } else { - Logger.Warn($"Attempted to install an invalid/incompatible package with Id={package.Id}"); + Logger.Warn( + $"Attempted to install an invalid/incompatible package with Id={package.Id}" + ); } } DialogHelper.HideLoadingDialog(loadingId); - MainApp.Operations.Install(packages_to_install, TEL_InstallReferral.FROM_BUNDLE, elevated, interactive, skiphash); + MainApp.Operations.Install( + packages_to_install, + TEL_InstallReferral.FROM_BUNDLE, + elevated, + interactive, + skiphash + ); } - protected override void WhenPackageCountUpdated() - { } + protected override void WhenPackageCountUpdated() { } - protected override void WhenPackagesLoaded(ReloadReason reason) - { } + protected override void WhenPackagesLoaded(ReloadReason reason) { } protected override void WhenShowingContextMenu(IPackage package) { - if (MenuAsAdmin is null + if ( + MenuAsAdmin is null || MenuInteractive is null || MenuSkipHash is null || MenuDetails is null || MenuShare is null || MenuInstall is null || MenuInstallOptions is null - || MenuDownloadInstaller is null) + || MenuDownloadInstaller is null + ) { Logger.Error("Menu items are null on InstalledPackagesTab"); return; @@ -365,42 +420,50 @@ protected override void WhenShowingContextMenu(IPackage package) bool IS_VALID = package as InvalidImportedPackage is null; MenuAsAdmin.IsEnabled = IS_VALID && package.Manager.Capabilities.CanRunAsAdmin; - MenuInteractive.IsEnabled = IS_VALID && package.Manager.Capabilities.CanRunInteractively; - MenuSkipHash.IsEnabled = IS_VALID && package.Manager.Capabilities.CanSkipIntegrityChecks; + MenuInteractive.IsEnabled = + IS_VALID && package.Manager.Capabilities.CanRunInteractively; + MenuSkipHash.IsEnabled = + IS_VALID && package.Manager.Capabilities.CanSkipIntegrityChecks; MenuDetails.IsEnabled = IS_VALID; MenuShare.IsEnabled = IS_VALID; MenuInstall.IsEnabled = IS_VALID; MenuInstallOptions.IsEnabled = IS_VALID; - MenuDownloadInstaller.IsEnabled = IS_VALID && package.Manager.Capabilities.CanDownloadInstaller; + MenuDownloadInstaller.IsEnabled = + IS_VALID && package.Manager.Capabilities.CanDownloadInstaller; } private void MenuInstall_Invoked(object sender, RoutedEventArgs args) { - if (SelectedItem is null) return; + if (SelectedItem is null) + return; _ = ImportAndInstallPackage([SelectedItem]); } private void MenuAsAdmin_Invoked(object sender, RoutedEventArgs args) { - if (SelectedItem is null) return; + if (SelectedItem is null) + return; _ = ImportAndInstallPackage([SelectedItem], elevated: true); } private void MenuInteractive_Invoked(object sender, RoutedEventArgs args) { - if (SelectedItem is null) return; + if (SelectedItem is null) + return; _ = ImportAndInstallPackage([SelectedItem], interactive: true); } private void MenuSkipHash_Invoked(object sender, RoutedEventArgs args) { - if (SelectedItem is null) return; + if (SelectedItem is null) + return; _ = ImportAndInstallPackage([SelectedItem], skiphash: true); } private void MenuShare_Invoked(object sender, RoutedEventArgs args) { - if (SelectedItem is null) return; + if (SelectedItem is null) + return; DialogHelper.SharePackage(SelectedItem); } @@ -422,28 +485,38 @@ private void MenuInstallSettings_Invoked(object sender, RoutedEventArgs e) private void MenuRemoveFromList_Invoked(object sender, RoutedEventArgs args) { IPackage? package = SelectedItem; - if (package is null) return; + if (package is null) + return; HasUnsavedChanges = true; Loader.Remove(package); } - public async Task OpenFromString(string payload, BundleFormatType format, string source, int? loadingId) + public async Task OpenFromString( + string payload, + BundleFormatType format, + string source, + int? loadingId + ) { if (await AskForNewBundle() is false) return; - loadingId ??= DialogHelper.ShowLoadingDialog(CoreTools.Translate("Loading packages, please wait...")); + loadingId ??= DialogHelper.ShowLoadingDialog( + CoreTools.Translate("Loading packages, please wait...") + ); var (open_version, report) = await AddFromBundle(payload, format); TelemetryHandler.ImportBundle(format); HasUnsavedChanges = false; - if ((int)(open_version*10) != (int)(SerializableBundle.ExpectedVersion*10)) - { // Check only up to first decimal digit, prevent floating point precision error. - Logger.Warn($"The loaded bundle \"{source}\" is based on schema version {open_version}, " + - $"while this UniGetUI build expects version {SerializableBundle.ExpectedVersion}." + - $"\nThis should not be a problem if packages show up, but be careful"); + if ((int)(open_version * 10) != (int)(SerializableBundle.ExpectedVersion * 10)) + { // Check only up to first decimal digit, prevent floating point precision error. + Logger.Warn( + $"The loaded bundle \"{source}\" is based on schema version {open_version}, " + + $"while this UniGetUI build expects version {SerializableBundle.ExpectedVersion}." + + $"\nThis should not be a problem if packages show up, but be careful" + ); } DialogHelper.HideLoadingDialog(loadingId.Value); @@ -455,7 +528,9 @@ public async Task OpenFromString(string payload, BundleFormatType format, string public async Task OpenFromFile(string file) { - int loadingId = DialogHelper.ShowLoadingDialog(CoreTools.Translate("Loading packages, please wait...")); + int loadingId = DialogHelper.ShowLoadingDialog( + CoreTools.Translate("Loading packages, please wait...") + ); try { BundleFormatType formatType; @@ -476,16 +551,20 @@ public async Task OpenFromFile(string file) } catch (Exception ex) { - Logger.Error("An error occurred while attempting to open a bundle"); Logger.Error(ex); var warningDialog = new ContentDialog { Title = CoreTools.Translate("The package bundle is not valid"), - Content = CoreTools.Translate("The bundle you are trying to load appears to be invalid. Please check the file and try again.") + "\n\n" + ex.Message, + Content = + CoreTools.Translate( + "The bundle you are trying to load appears to be invalid. Please check the file and try again." + ) + + "\n\n" + + ex.Message, CloseButtonText = CoreTools.Translate("Ok"), DefaultButton = ContentDialogButton.Close, - XamlRoot = MainApp.Instance.MainWindow.Content.XamlRoot // Ensure the dialog is shown in the correct context + XamlRoot = MainApp.Instance.MainWindow.Content.XamlRoot, // Ensure the dialog is shown in the correct context }; DialogHelper.HideLoadingDialog(loadingId); @@ -512,11 +591,15 @@ public async Task SaveFile() { // Get file string defaultName = CoreTools.Translate("Package bundle") + ".ubundle"; - string file = (new FileSavePicker(MainApp.Instance.MainWindow.GetWindowHandle())).Show(["*.ubundle", "*.json"], defaultName); + string file = ( + new FileSavePicker(MainApp.Instance.MainWindow.GetWindowHandle()) + ).Show(["*.ubundle", "*.json"], defaultName); if (file != String.Empty) { // Loading dialog - int loadingId = DialogHelper.ShowLoadingDialog(CoreTools.Translate("Saving packages, please wait...")); + int loadingId = DialogHelper.ShowLoadingDialog( + CoreTools.Translate("Saving packages, please wait...") + ); // Select appropriate format BundleFormatType formatType; @@ -534,13 +617,13 @@ public async Task SaveFile() DialogHelper.HideLoadingDialog(loadingId); - DialogHelper.ShowDismissableBalloon( + DialogHelper.ShowDismissableBalloon( CoreTools.Translate("Success!"), - CoreTools.Translate("The bundle was created successfully on {0}", file)); + CoreTools.Translate("The bundle was created successfully on {0}", file) + ); await CoreTools.ShowFileOnExplorer(file); HasUnsavedChanges = false; - } } catch (Exception ex) @@ -551,10 +634,15 @@ public async Task SaveFile() var warningDialog = new ContentDialog { Title = CoreTools.Translate("Could not create bundle"), - Content = CoreTools.Translate("The package bundle could not be created due to an error.") + "\n\n" + ex.Message, + Content = + CoreTools.Translate( + "The package bundle could not be created due to an error." + ) + + "\n\n" + + ex.Message, CloseButtonText = CoreTools.Translate("Ok"), DefaultButton = ContentDialogButton.Close, - XamlRoot = MainApp.Instance.MainWindow.Content.XamlRoot // Ensure the dialog is shown in the correct context + XamlRoot = MainApp.Instance.MainWindow.Content.XamlRoot, // Ensure the dialog is shown in the correct context }; DialogHelper.HideAllLoadingDialogs(); @@ -571,8 +659,10 @@ public static async Task CreateBundle(IReadOnlyList unsorted_p static int Comparison(IPackage x, IPackage y) { - if (x.Id != y.Id) return String.Compare(x.Id, y.Id, StringComparison.Ordinal); - if (x.Name != y.Name) return String.Compare(x.Name, y.Name, StringComparison.Ordinal); + if (x.Id != y.Id) + return String.Compare(x.Id, y.Id, StringComparison.Ordinal); + if (x.Name != y.Name) + return String.Compare(x.Name, y.Name, StringComparison.Ordinal); return (x.NormalizedVersion > y.NormalizedVersion) ? -1 : 1; } @@ -590,7 +680,10 @@ static int Comparison(IPackage x, IPackage y) return exportablePayload; } - public async Task<(double, BundleReport)> AddFromBundle(string content, BundleFormatType format) + public async Task<(double, BundleReport)> AddFromBundle( + string content, + BundleFormatType format + ) { // Deserialize data SerializableBundle? DeserializedData; @@ -606,12 +699,17 @@ static int Comparison(IPackage x, IPackage y) { // Dynamic convert to JSON content = await SerializationHelpers.XML_to_JSON(content); - Logger.ImportantInfo("XML payload was converted to JSON dynamically before deserialization"); + Logger.ImportantInfo( + "XML payload was converted to JSON dynamically before deserialization" + ); } DeserializedData = await Task.Run(() => { - return new SerializableBundle(JsonNode.Parse(content) ?? throw new JsonException("Could not parse JSON object")); + return new SerializableBundle( + JsonNode.Parse(content) + ?? throw new JsonException("Could not parse JSON object") + ); }); List packages = []; @@ -620,12 +718,12 @@ static int Comparison(IPackage x, IPackage y) report.IsEmpty = true; bool AllowCLIParameters = - SecureSettings.Get(SecureSettings.K.AllowCLIArguments) && - SecureSettings.Get(SecureSettings.K.AllowImportingCLIArguments); + SecureSettings.Get(SecureSettings.K.AllowCLIArguments) + && SecureSettings.Get(SecureSettings.K.AllowImportingCLIArguments); bool AllowPrePostOps = - SecureSettings.Get(SecureSettings.K.AllowPrePostOpCommand) && - SecureSettings.Get(SecureSettings.K.AllowImportPrePostOpCommands); + SecureSettings.Get(SecureSettings.K.AllowPrePostOpCommand) + && SecureSettings.Get(SecureSettings.K.AllowImportPrePostOpCommands); foreach (var pkg in DeserializedData.packages) { @@ -634,66 +732,133 @@ static int Comparison(IPackage x, IPackage y) if (opts.CustomParameters_Install.Where(x => x.Any()).Any()) { report.IsEmpty = false; - if (!report.Contents.ContainsKey(pkg.Id)) report.Contents[pkg.Id] = new(); - report.Contents[pkg.Id].Add(new($"Custom install arguments: [{string.Join(", ", opts.CustomParameters_Install)}]", AllowCLIParameters)); - if(!AllowCLIParameters) opts.CustomParameters_Install.Clear(); + if (!report.Contents.ContainsKey(pkg.Id)) + report.Contents[pkg.Id] = new(); + report + .Contents[pkg.Id] + .Add( + new( + $"Custom install arguments: [{string.Join(", ", opts.CustomParameters_Install)}]", + AllowCLIParameters + ) + ); + if (!AllowCLIParameters) + opts.CustomParameters_Install.Clear(); } if (opts.CustomParameters_Update.Where(x => x.Any()).Any()) { report.IsEmpty = false; - if (!report.Contents.ContainsKey(pkg.Id)) report.Contents[pkg.Id] = new(); - report.Contents[pkg.Id].Add(new($"Custom update arguments: [{string.Join(", ", opts.CustomParameters_Update)}]", AllowCLIParameters)); - if(!AllowCLIParameters) opts.CustomParameters_Update.Clear(); + if (!report.Contents.ContainsKey(pkg.Id)) + report.Contents[pkg.Id] = new(); + report + .Contents[pkg.Id] + .Add( + new( + $"Custom update arguments: [{string.Join(", ", opts.CustomParameters_Update)}]", + AllowCLIParameters + ) + ); + if (!AllowCLIParameters) + opts.CustomParameters_Update.Clear(); } if (opts.CustomParameters_Uninstall.Where(x => x.Any()).Any()) { report.IsEmpty = false; - if (!report.Contents.ContainsKey(pkg.Id)) report.Contents[pkg.Id] = new(); - report.Contents[pkg.Id].Add(new($"Custom uninstall arguments: [{string.Join(", ", opts.CustomParameters_Uninstall)}]", AllowCLIParameters)); - if(!AllowCLIParameters) opts.CustomParameters_Uninstall.Clear(); + if (!report.Contents.ContainsKey(pkg.Id)) + report.Contents[pkg.Id] = new(); + report + .Contents[pkg.Id] + .Add( + new( + $"Custom uninstall arguments: [{string.Join(", ", opts.CustomParameters_Uninstall)}]", + AllowCLIParameters + ) + ); + if (!AllowCLIParameters) + opts.CustomParameters_Uninstall.Clear(); } if (opts.PreInstallCommand.Any()) { report.IsEmpty = false; - if (!report.Contents.ContainsKey(pkg.Id)) report.Contents[pkg.Id] = new(); - report.Contents[pkg.Id].Add(new($"Pre-install command: {opts.PreInstallCommand}", AllowPrePostOps)); - if (!AllowPrePostOps) opts.PreInstallCommand = ""; + if (!report.Contents.ContainsKey(pkg.Id)) + report.Contents[pkg.Id] = new(); + report + .Contents[pkg.Id] + .Add( + new($"Pre-install command: {opts.PreInstallCommand}", AllowPrePostOps) + ); + if (!AllowPrePostOps) + opts.PreInstallCommand = ""; } if (opts.PostInstallCommand.Any()) { report.IsEmpty = false; - if (!report.Contents.ContainsKey(pkg.Id)) report.Contents[pkg.Id] = new(); - report.Contents[pkg.Id].Add(new($"Post-install command: {opts.PostInstallCommand}", AllowPrePostOps)); - if (!AllowPrePostOps) opts.PostInstallCommand = ""; + if (!report.Contents.ContainsKey(pkg.Id)) + report.Contents[pkg.Id] = new(); + report + .Contents[pkg.Id] + .Add( + new($"Post-install command: {opts.PostInstallCommand}", AllowPrePostOps) + ); + if (!AllowPrePostOps) + opts.PostInstallCommand = ""; } if (opts.PreUpdateCommand.Any()) { report.IsEmpty = false; - if (!report.Contents.ContainsKey(pkg.Id)) report.Contents[pkg.Id] = new(); - report.Contents[pkg.Id].Add(new($"Pre-update command: {opts.PreUpdateCommand}", AllowPrePostOps)); - if (!AllowPrePostOps) opts.PreUpdateCommand = ""; + if (!report.Contents.ContainsKey(pkg.Id)) + report.Contents[pkg.Id] = new(); + report + .Contents[pkg.Id] + .Add(new($"Pre-update command: {opts.PreUpdateCommand}", AllowPrePostOps)); + if (!AllowPrePostOps) + opts.PreUpdateCommand = ""; } if (opts.PostUpdateCommand.Any()) { report.IsEmpty = false; - if (!report.Contents.ContainsKey(pkg.Id)) report.Contents[pkg.Id] = new(); - report.Contents[pkg.Id].Add(new($"Post-update command: {opts.PostUpdateCommand}", AllowPrePostOps)); - if (!AllowPrePostOps) opts.PostUpdateCommand = ""; + if (!report.Contents.ContainsKey(pkg.Id)) + report.Contents[pkg.Id] = new(); + report + .Contents[pkg.Id] + .Add( + new($"Post-update command: {opts.PostUpdateCommand}", AllowPrePostOps) + ); + if (!AllowPrePostOps) + opts.PostUpdateCommand = ""; } if (opts.PreUninstallCommand.Any()) { report.IsEmpty = false; - if (!report.Contents.ContainsKey(pkg.Id)) report.Contents[pkg.Id] = new(); - report.Contents[pkg.Id].Add(new($"Pre-uninstall command: {opts.PreUninstallCommand}", AllowPrePostOps)); - if (!AllowPrePostOps) opts.PreUninstallCommand = ""; + if (!report.Contents.ContainsKey(pkg.Id)) + report.Contents[pkg.Id] = new(); + report + .Contents[pkg.Id] + .Add( + new( + $"Pre-uninstall command: {opts.PreUninstallCommand}", + AllowPrePostOps + ) + ); + if (!AllowPrePostOps) + opts.PreUninstallCommand = ""; } if (opts.PostUninstallCommand.Any()) { report.IsEmpty = false; - if (!report.Contents.ContainsKey(pkg.Id)) report.Contents[pkg.Id] = new(); - report.Contents[pkg.Id].Add(new($"Post-uninstall command: {opts.PostUninstallCommand}", AllowPrePostOps)); - if (!AllowPrePostOps) opts.PostUninstallCommand = ""; + if (!report.Contents.ContainsKey(pkg.Id)) + report.Contents[pkg.Id] = new(); + report + .Contents[pkg.Id] + .Add( + new( + $"Post-uninstall command: {opts.PostUninstallCommand}", + AllowPrePostOps + ) + ); + if (!AllowPrePostOps) + opts.PostUninstallCommand = ""; } pkg.InstallationOptions = opts; @@ -715,7 +880,10 @@ public static IPackage DeserializePackage(SerializablePackage raw_package) foreach (var possible_manager in PEInterface.Managers) { - if (possible_manager.Name == raw_package.ManagerName || possible_manager.DisplayName == raw_package.ManagerName) + if ( + possible_manager.Name == raw_package.ManagerName + || possible_manager.DisplayName == raw_package.ManagerName + ) { manager = possible_manager; break; @@ -735,13 +903,19 @@ public static IPackage DeserializePackage(SerializablePackage raw_package) if (manager is null || source is null) { - return DeserializeIncompatiblePackage(raw_package.GetInvalidEquivalent(), NullSource.Instance); + return DeserializeIncompatiblePackage( + raw_package.GetInvalidEquivalent(), + NullSource.Instance + ); } return new ImportedPackage(raw_package, manager, source); } - public static IPackage DeserializeIncompatiblePackage(SerializableIncompatiblePackage raw_package, IManagerSource source) + public static IPackage DeserializeIncompatiblePackage( + SerializableIncompatiblePackage raw_package, + IManagerSource source + ) { return new InvalidImportedPackage(raw_package, source); } @@ -751,10 +925,17 @@ public async Task CreateBatchScript() try { string defaultName = CoreTools.Translate("Install script") + ".ps1"; - string file = await Task.Run(() => (new FileSavePicker(MainApp.Instance.MainWindow.GetWindowHandle())).Show(["*.ps1"], defaultName)); + string file = await Task.Run(() => + (new FileSavePicker(MainApp.Instance.MainWindow.GetWindowHandle())).Show( + ["*.ps1"], + defaultName + ) + ); if (file != String.Empty) { - int loadingId = DialogHelper.ShowLoadingDialog(CoreTools.Translate("Saving packages, please wait...")); + int loadingId = DialogHelper.ShowLoadingDialog( + CoreTools.Translate("Saving packages, please wait...") + ); var packages = new List(); var commands = new List(); @@ -766,24 +947,29 @@ public async Task CreateBatchScript() { packages.Add(package.Name + " from " + package.Manager.DisplayName); - foreach (var process in package.installation_options.KillBeforeOperation) - { // Kill required processes, if any. Forcekill if the user has enable said option + foreach ( + var process in package.installation_options.KillBeforeOperation + ) + { // Kill required processes, if any. Forcekill if the user has enable said option commands.Add($"taskkill /im \"{process}\"" + (forceKill ? " /f" : "")); } if (package.installation_options.PreInstallCommand != "") - { // Add pre-operation + { // Add pre-operation commands.Add(package.installation_options.PreInstallCommand); } // Add install command var exeName = package.Manager.Properties.ExecutableFriendlyName; - var param = package.Manager.OperationHelper.GetParameters(package, - package.installation_options, OperationType.Install); - commands.Add($"{exeName} {string.Join(' ',param)}"); + var param = package.Manager.OperationHelper.GetParameters( + package, + package.installation_options, + OperationType.Install + ); + commands.Add($"{exeName} {string.Join(' ', param)}"); if (package.installation_options.PostInstallCommand != "") - { // Add post-operation + { // Add post-operation commands.Add(package.installation_options.PostInstallCommand); } } @@ -794,7 +980,8 @@ public async Task CreateBatchScript() DialogHelper.HideLoadingDialog(loadingId); DialogHelper.ShowDismissableBalloon( CoreTools.Translate("Success!"), - CoreTools.Translate("The installation script saved to {0}", file)); + CoreTools.Translate("The installation script saved to {0}", file) + ); TelemetryHandler.ExportBatch(); @@ -808,90 +995,101 @@ public async Task CreateBatchScript() Logger.Error(ex); DialogHelper.ShowDismissableBalloon( CoreTools.Translate("An error occurred"), - CoreTools.Translate("An error occurred while attempting to create an installation script:") + " " + ex.Message); + CoreTools.Translate( + "An error occurred while attempting to create an installation script:" + ) + + " " + + ex.Message + ); } } - private static string GenerateCommandString(IReadOnlyList names, IReadOnlyList commands) + private static string GenerateCommandString( + IReadOnlyList names, + IReadOnlyList commands + ) { return $$""" - Clear-Host - Write-Host "" - Write-Host "========================================================" - Write-Host "" - Write-Host " __ __ _ ______ __ __ ______" -ForegroundColor Cyan - Write-Host " / / / /___ (_) ____/__ / /_/ / / / _/" -ForegroundColor Cyan - Write-Host " / / / / __ \/ / / __/ _ \/ __/ / / // /" -ForegroundColor Cyan - Write-Host " / /_/ / / / / / /_/ / __/ /_/ /_/ // /" -ForegroundColor Cyan - Write-Host " \____/_/ /_/_/\____/\___/\__/\____/___/" -ForegroundColor Cyan - Write-Host " UniGetUI Package Installer Script" - Write-Host " Created with UniGetUI Version {{CoreData.VersionName}}" - Write-Host "" - Write-Host "========================================================" - Write-Host "" - Write-Host "NOTES:" -ForegroundColor Yellow - Write-Host " - The install process will not be as reliable as importing a bundle with UniGetUI. Expect issues and errors." -ForegroundColor Yellow - Write-Host " - Packages will be installed with the install options specified at the time of creation of this script." -ForegroundColor Yellow - Write-Host " - Error/Sucess detection may not be 100% accurate." -ForegroundColor Yellow - Write-Host " - Some of the packages may require elevation. Some of them may ask for permission, but others may fail. Consider running this script elevated." -ForegroundColor Yellow - Write-Host " - You can skip confirmation prompts by running this script with the parameter `/DisablePausePrompts` " -ForegroundColor Yellow - Write-Host "" - Write-Host "" - if ($args[0] -ne "/DisablePausePrompts") { pause } - Write-Host "" - Write-Host "This script will attempt to install the following packages:" - {{string.Join('\n', names.Select(x => $"Write-Host \" - {x}\""))}} - Write-Host "" - if ($args[0] -ne "/DisablePausePrompts") { pause } - Clear-Host - - $success_count=0 - $failure_count=0 - $commands_run=0 - $results="" - - $commands= @( - {{string.Join(",\n ", commands.Select(x => $"'cmd.exe /C {x.Replace("'", "''")}'"))}} - ) + Clear-Host + Write-Host "" + Write-Host "========================================================" + Write-Host "" + Write-Host " __ __ _ ______ __ __ ______" -ForegroundColor Cyan + Write-Host " / / / /___ (_) ____/__ / /_/ / / / _/" -ForegroundColor Cyan + Write-Host " / / / / __ \/ / / __/ _ \/ __/ / / // /" -ForegroundColor Cyan + Write-Host " / /_/ / / / / / /_/ / __/ /_/ /_/ // /" -ForegroundColor Cyan + Write-Host " \____/_/ /_/_/\____/\___/\__/\____/___/" -ForegroundColor Cyan + Write-Host " UniGetUI Package Installer Script" + Write-Host " Created with UniGetUI Version {{CoreData.VersionName}}" + Write-Host "" + Write-Host "========================================================" + Write-Host "" + Write-Host "NOTES:" -ForegroundColor Yellow + Write-Host " - The install process will not be as reliable as importing a bundle with UniGetUI. Expect issues and errors." -ForegroundColor Yellow + Write-Host " - Packages will be installed with the install options specified at the time of creation of this script." -ForegroundColor Yellow + Write-Host " - Error/Sucess detection may not be 100% accurate." -ForegroundColor Yellow + Write-Host " - Some of the packages may require elevation. Some of them may ask for permission, but others may fail. Consider running this script elevated." -ForegroundColor Yellow + Write-Host " - You can skip confirmation prompts by running this script with the parameter `/DisablePausePrompts` " -ForegroundColor Yellow + Write-Host "" + Write-Host "" + if ($args[0] -ne "/DisablePausePrompts") { pause } + Write-Host "" + Write-Host "This script will attempt to install the following packages:" + {{string.Join('\n', names.Select(x => $"Write-Host \" - {x}\""))}} + Write-Host "" + if ($args[0] -ne "/DisablePausePrompts") { pause } + Clear-Host + + $success_count=0 + $failure_count=0 + $commands_run=0 + $results="" + + $commands= @( + {{string.Join( + ",\n ", + commands.Select(x => $"'cmd.exe /C {x.Replace("'", "''")}'") + )}} + ) + + foreach ($command in $commands) { + Write-Host "Running: $command" -ForegroundColor Yellow + cmd.exe /C $command + if ($LASTEXITCODE -eq 0) { + Write-Host "[ OK ] $command" -ForegroundColor Green + $success_count++ + $results += "$([char]0x1b)[32m[ OK ] $command`n" + } + else { + Write-Host "[ FAIL ] $command" -ForegroundColor Red + $failure_count++ + $results += "$([char]0x1b)[31m[ FAIL ] $command`n" + } + $commands_run++ + Write-Host "" + } - foreach ($command in $commands) { - Write-Host "Running: $command" -ForegroundColor Yellow - cmd.exe /C $command - if ($LASTEXITCODE -eq 0) { - Write-Host "[ OK ] $command" -ForegroundColor Green - $success_count++ - $results += "$([char]0x1b)[32m[ OK ] $command`n" + Write-Host "========================================================" + Write-Host " OPERATION SUMMARY" + Write-Host "========================================================" + Write-Host "Total commands run: $commands_run" + Write-Host "Successful: $success_count" + Write-Host "Failed: $failure_count" + Write-Host "" + Write-Host "Details:" + Write-Host "$results$([char]0x1b)[37m" + Write-Host "========================================================" + + if ($failure_count -gt 0) { + Write-Host "Some commands failed. Please check the log above." -ForegroundColor Yellow } else { - Write-Host "[ FAIL ] $command" -ForegroundColor Red - $failure_count++ - $results += "$([char]0x1b)[31m[ FAIL ] $command`n" + Write-Host "All commands executed successfully!" -ForegroundColor Green } - $commands_run++ Write-Host "" - } - - Write-Host "========================================================" - Write-Host " OPERATION SUMMARY" - Write-Host "========================================================" - Write-Host "Total commands run: $commands_run" - Write-Host "Successful: $success_count" - Write-Host "Failed: $failure_count" - Write-Host "" - Write-Host "Details:" - Write-Host "$results$([char]0x1b)[37m" - Write-Host "========================================================" - - if ($failure_count -gt 0) { - Write-Host "Some commands failed. Please check the log above." -ForegroundColor Yellow - } - else { - Write-Host "All commands executed successfully!" -ForegroundColor Green - } - Write-Host "" - if ($args[0] -ne "/DisablePausePrompts") { pause } - exit $failure_count - """; + if ($args[0] -ne "/DisablePausePrompts") { pause } + exit $failure_count + """; } } } diff --git a/src/UniGetUI/Pages/SoftwarePages/SoftwareUpdatesPage.cs b/src/UniGetUI/Pages/SoftwarePages/SoftwareUpdatesPage.cs index e070610abd..d7d871c71a 100644 --- a/src/UniGetUI/Pages/SoftwarePages/SoftwareUpdatesPage.cs +++ b/src/UniGetUI/Pages/SoftwarePages/SoftwareUpdatesPage.cs @@ -1,5 +1,3 @@ -using Windows.Networking.Connectivity; -using Windows.UI.Text; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Controls.Primitives; @@ -17,9 +15,11 @@ using UniGetUI.PackageEngine.Classes.Packages.Classes; using UniGetUI.PackageEngine.Enums; using UniGetUI.PackageEngine.Interfaces; +using UniGetUI.PackageEngine.PackageClasses; using UniGetUI.PackageEngine.PackageLoader; using UniGetUI.Pages.DialogPages; -using UniGetUI.PackageEngine.PackageClasses; +using Windows.Networking.Connectivity; +using Windows.UI.Text; namespace UniGetUI.Interface.SoftwarePages { @@ -32,31 +32,36 @@ public partial class SoftwareUpdatesPage : AbstractPackagesPage private BetterMenuItem? MenuOpenInstallLocation; public SoftwareUpdatesPage() - : base(new PackagesPageData - { - DisableAutomaticPackageLoadOnStart = false, - DisableFilterOnQueryChange = false, - MegaQueryBlockEnabled = false, - ShowLastLoadTime = true, - DisableReload = false, - PackagesAreCheckedByDefault = true, - DisableSuggestedResultsRadio = true, - PageName = "Updates", - - Loader = UpgradablePackagesLoader.Instance, - PageRole = OperationType.Update, - - NoPackages_BackgroundText = CoreTools.Translate("Hooray! No updates were found."), - NoPackages_SourcesText = CoreTools.Translate("Everything is up to date"), - NoPackages_SubtitleText_Base = CoreTools.Translate("Everything is up to date"), - MainSubtitle_StillLoading = CoreTools.Translate("Loading packages"), - NoMatches_BackgroundText = CoreTools.Translate("No results were found matching the input criteria"), - - PageTitle = CoreTools.Translate("Software Updates"), - Glyph = "\uE895" - }) - { - } + : base( + new PackagesPageData + { + DisableAutomaticPackageLoadOnStart = false, + DisableFilterOnQueryChange = false, + MegaQueryBlockEnabled = false, + ShowLastLoadTime = true, + DisableReload = false, + PackagesAreCheckedByDefault = true, + DisableSuggestedResultsRadio = true, + PageName = "Updates", + + Loader = UpgradablePackagesLoader.Instance, + PageRole = OperationType.Update, + + NoPackages_BackgroundText = CoreTools.Translate( + "Hooray! No updates were found." + ), + NoPackages_SourcesText = CoreTools.Translate("Everything is up to date"), + NoPackages_SubtitleText_Base = CoreTools.Translate("Everything is up to date"), + MainSubtitle_StillLoading = CoreTools.Translate("Loading packages"), + NoMatches_BackgroundText = CoreTools.Translate( + "No results were found matching the input criteria" + ), + + PageTitle = CoreTools.Translate("Software Updates"), + Glyph = "\uE895", + } + ) + { } public override BetterMenu GenerateContextMenu() { @@ -66,7 +71,7 @@ public override BetterMenu GenerateContextMenu() { Text = CoreTools.AutoTranslated("Update"), IconName = IconType.Update, - KeyboardAcceleratorTextOverride = "Ctrl+Enter" + KeyboardAcceleratorTextOverride = "Ctrl+Enter", }; menuInstall.Click += MenuInstall_Invoked; @@ -74,9 +79,10 @@ public override BetterMenu GenerateContextMenu() { Text = CoreTools.AutoTranslated("Update options"), IconName = IconType.Options, - KeyboardAcceleratorTextOverride = "Alt+Enter" + KeyboardAcceleratorTextOverride = "Alt+Enter", }; - menuInstallSettings.Click += (_, _) => _ = ShowInstallationOptionsForPackage(SelectedItem); + menuInstallSettings.Click += (_, _) => + _ = ShowInstallationOptionsForPackage(SelectedItem); MenuOpenInstallLocation = new() { @@ -109,9 +115,13 @@ public override BetterMenu GenerateContextMenu() MenuDownloadInstaller = new BetterMenuItem { Text = CoreTools.AutoTranslated("Download installer"), - IconName = IconType.Download + IconName = IconType.Download, }; - MenuDownloadInstaller.Click += (_, _) => _ = MainApp.Operations.AskLocationAndDownload(SelectedItem, TEL_InstallReferral.ALREADY_INSTALLED); + MenuDownloadInstaller.Click += (_, _) => + _ = MainApp.Operations.AskLocationAndDownload( + SelectedItem, + TEL_InstallReferral.ALREADY_INSTALLED + ); BetterMenuItem menuUpdateAfterUninstall = new() { @@ -152,30 +162,38 @@ public override BetterMenu GenerateContextMenu() { Text = CoreTools.AutoTranslated("Package details"), IconName = IconType.Info_Round, - KeyboardAcceleratorTextOverride = "Enter" + KeyboardAcceleratorTextOverride = "Enter", }; - menuDetails.Click += (_, _) => ShowDetailsForPackage(SelectedItem, TEL_InstallReferral.ALREADY_INSTALLED); + menuDetails.Click += (_, _) => + ShowDetailsForPackage(SelectedItem, TEL_InstallReferral.ALREADY_INSTALLED); MenuFlyoutSubItem menuPause = new() { Text = CoreTools.Translate("Pause updates for"), Icon = new FontIcon { Glyph = "\uE769" }, }; - foreach (IgnoredUpdatesDatabase.PauseTime menuTime in new List{ - new() { Days = 1 }, new() { Days = 3 }, - new() { Weeks = 1 }, new() { Weeks = 2 }, new() { Weeks = 4 }, - new() { Months = 3 }, new() { Months = 6 }, new() { Months = 12 }, - }) + foreach ( + IgnoredUpdatesDatabase.PauseTime menuTime in new List + { + new() { Days = 1 }, + new() { Days = 3 }, + new() { Weeks = 1 }, + new() { Weeks = 2 }, + new() { Weeks = 4 }, + new() { Months = 3 }, + new() { Months = 6 }, + new() { Months = 12 }, + } + ) { - BetterMenuItem menuItem = new() + BetterMenuItem menuItem = new() { Text = menuTime.StringRepresentation() }; + menuItem.Click += (_, _) => { - Text = menuTime.StringRepresentation(), - }; - menuItem.Click += (_, _) => { if (SelectedItem != null) { SelectedItem.AddToIgnoredUpdatesAsync("<" + menuTime.GetDateFromNow()); - UpgradablePackagesLoader.Instance.IgnoredPackages[SelectedItem.Id] = SelectedItem; + UpgradablePackagesLoader.Instance.IgnoredPackages[SelectedItem.Id] = + SelectedItem; Loader.Remove(SelectedItem); } }; @@ -207,11 +225,13 @@ public override BetterMenu GenerateContextMenu() protected override void WhenShowingContextMenu(IPackage package) { - if (MenuAsAdmin is null + if ( + MenuAsAdmin is null || MenuInteractive is null || MenuskipHash is null || MenuDownloadInstaller is null - || MenuOpenInstallLocation is null) + || MenuOpenInstallLocation is null + ) { Logger.Error("Menu items are null on SoftwareUpdatesTab"); return; @@ -222,7 +242,8 @@ protected override void WhenShowingContextMenu(IPackage package) MenuskipHash.IsEnabled = package.Manager.Capabilities.CanSkipIntegrityChecks; MenuDownloadInstaller.IsEnabled = package.Manager.Capabilities.CanDownloadInstaller; - MenuOpenInstallLocation.IsEnabled = package.Manager.DetailsHelper.GetInstallLocation(package) is not null; + MenuOpenInstallLocation.IsEnabled = + package.Manager.DetailsHelper.GetInstallLocation(package) is not null; } public override void GenerateToolBar() @@ -235,16 +256,17 @@ public override void GenerateToolBar() MainToolbarButtonDropdown.Flyout = new BetterMenu() { - Items = { + Items = + { UpdateAsAdmin, UpdateSkipHash, UpdateInteractive, new MenuFlyoutSeparator(), DownloadInstallers, new MenuFlyoutSeparator(), - UninstallSelection + UninstallSelection, }, - Placement = FlyoutPlacementMode.Bottom + Placement = FlyoutPlacementMode.Bottom, }; MainToolbarButtonIcon.Icon = IconType.Update; MainToolbarButtonText.Text = CoreTools.Translate("Update selection"); @@ -272,40 +294,42 @@ public override void GenerateToolBar() Dictionary Labels = new() { // Entries with a leading space are collapsed - // Their texts will be used as the tooltip - { UpdateAsAdmin, CoreTools.Translate("Update as administrator") }, - { UpdateSkipHash, CoreTools.Translate("Skip integrity checks") }, - { UpdateInteractive, CoreTools.Translate("Interactive update") }, - { DownloadInstallers, CoreTools.Translate("Download selected installers") }, - { UninstallSelection, CoreTools.Translate("Uninstall selected packages") }, + // Their texts will be used as the tooltip + { UpdateAsAdmin, CoreTools.Translate("Update as administrator") }, + { UpdateSkipHash, CoreTools.Translate("Skip integrity checks") }, + { UpdateInteractive, CoreTools.Translate("Interactive update") }, + { DownloadInstallers, CoreTools.Translate("Download selected installers") }, + { UninstallSelection, CoreTools.Translate("Uninstall selected packages") }, { InstallationSettings, " " + CoreTools.Translate("Update options") }, - { PackageDetails, " " + CoreTools.Translate("Package details") }, - { SharePackage, " " + CoreTools.Translate("Share") }, - { IgnoreSelected, CoreTools.Translate("Ignore selected packages") }, - { ManageIgnored, CoreTools.Translate("Manage ignored updates") }, - { HelpButton, CoreTools.Translate("Help") } + { PackageDetails, " " + CoreTools.Translate("Package details") }, + { SharePackage, " " + CoreTools.Translate("Share") }, + { IgnoreSelected, CoreTools.Translate("Ignore selected packages") }, + { ManageIgnored, CoreTools.Translate("Manage ignored updates") }, + { HelpButton, CoreTools.Translate("Help") }, }; Dictionary Icons = new() { - { UpdateAsAdmin, IconType.UAC }, - { UpdateSkipHash, IconType.Checksum }, - { UpdateInteractive, IconType.Interactive }, + { UpdateAsAdmin, IconType.UAC }, + { UpdateSkipHash, IconType.Checksum }, + { UpdateInteractive, IconType.Interactive }, { InstallationSettings, IconType.Options }, - { DownloadInstallers, IconType.Download }, - { UninstallSelection, IconType.Delete }, - { PackageDetails, IconType.Info_Round }, - { SharePackage, IconType.Share }, - { IgnoreSelected, IconType.Pin }, - { ManageIgnored, IconType.ClipboardList }, - { HelpButton, IconType.Help } + { DownloadInstallers, IconType.Download }, + { UninstallSelection, IconType.Delete }, + { PackageDetails, IconType.Info_Round }, + { SharePackage, IconType.Share }, + { IgnoreSelected, IconType.Pin }, + { ManageIgnored, IconType.ClipboardList }, + { HelpButton, IconType.Help }, }; ApplyTextAndIconsToToolbar(Labels, Icons); - PackageDetails.Click += (_, _) => ShowDetailsForPackage(SelectedItem, TEL_InstallReferral.ALREADY_INSTALLED); + PackageDetails.Click += (_, _) => + ShowDetailsForPackage(SelectedItem, TEL_InstallReferral.ALREADY_INSTALLED); HelpButton.Click += (_, _) => MainApp.Instance.MainWindow.NavigationPage.ShowHelp(); - InstallationSettings.Click += (_, _) => _ = ShowInstallationOptionsForPackage(SelectedItem); + InstallationSettings.Click += (_, _) => + _ = ShowInstallationOptionsForPackage(SelectedItem); ManageIgnored.Click += async (_, _) => await DialogHelper.ManageIgnoredUpdates(); IgnoreSelected.Click += async (_, _) => { @@ -317,12 +341,24 @@ public override void GenerateToolBar() } }; - MainToolbarButton.Click += (_, _) => MainApp.Operations.Update(FilteredPackages.GetCheckedPackages()); - UpdateAsAdmin.Click += (_, _) => MainApp.Operations.Update(FilteredPackages.GetCheckedPackages(), elevated: true); - UpdateSkipHash.Click += (_, _) => MainApp.Operations.Update(FilteredPackages.GetCheckedPackages(), no_integrity: true); - UpdateInteractive.Click += (_, _) => MainApp.Operations.Update(FilteredPackages.GetCheckedPackages(), interactive: true); - DownloadInstallers.Click += (_, _) => _ = MainApp.Operations.Download(FilteredPackages.GetCheckedPackages(), TEL_InstallReferral.ALREADY_INSTALLED); - UninstallSelection.Click += (_, _) => _ = MainApp.Operations.ConfirmAndUninstall(FilteredPackages.GetCheckedPackages()); + MainToolbarButton.Click += (_, _) => + MainApp.Operations.Update(FilteredPackages.GetCheckedPackages()); + UpdateAsAdmin.Click += (_, _) => + MainApp.Operations.Update(FilteredPackages.GetCheckedPackages(), elevated: true); + UpdateSkipHash.Click += (_, _) => + MainApp.Operations.Update( + FilteredPackages.GetCheckedPackages(), + no_integrity: true + ); + UpdateInteractive.Click += (_, _) => + MainApp.Operations.Update(FilteredPackages.GetCheckedPackages(), interactive: true); + DownloadInstallers.Click += (_, _) => + _ = MainApp.Operations.Download( + FilteredPackages.GetCheckedPackages(), + TEL_InstallReferral.ALREADY_INSTALLED + ); + UninstallSelection.Click += (_, _) => + _ = MainApp.Operations.ConfirmAndUninstall(FilteredPackages.GetCheckedPackages()); SharePackage.Click += (_, _) => DialogHelper.SharePackage(SelectedItem); } @@ -336,29 +372,48 @@ protected override async void WhenPackagesLoaded(ReloadReason reason) try { List upgradablePackages = []; - foreach (IPackage package in Loader.Packages) - { - if (package.Tag is not PackageTag.OnQueue and not PackageTag.BeingProcessed) - upgradablePackages.Add(package); - } + foreach (IPackage package in Loader.Packages) + { + if (package.Tag is not PackageTag.OnQueue and not PackageTag.BeingProcessed) + upgradablePackages.Add(package); + } if (upgradablePackages.Count == 0) return; - if (Settings.Get(Settings.K.DisableAUPOnMeteredConnections) && - NetworkInformation.GetInternetConnectionProfile()?.GetConnectionCost().NetworkCostType is NetworkCostType.Fixed or NetworkCostType.Variable) + if ( + Settings.Get(Settings.K.DisableAUPOnMeteredConnections) + && NetworkInformation + .GetInternetConnectionProfile() + ?.GetConnectionCost() + .NetworkCostType + is NetworkCostType.Fixed + or NetworkCostType.Variable + ) { - Logger.Warn("Updates will not be installed automatically because the current internet connection is metered."); + Logger.Warn( + "Updates will not be installed automatically because the current internet connection is metered." + ); await ShowAvailableUpdatesNotification(upgradablePackages); } - else if (Settings.Get(Settings.K.DisableAUPOnBattery) && PowerManager.PowerSupplyStatus is PowerSupplyStatus.NotPresent) + else if ( + Settings.Get(Settings.K.DisableAUPOnBattery) + && PowerManager.PowerSupplyStatus is PowerSupplyStatus.NotPresent + ) { - Logger.Warn("Updates will not be installed automatically because the device is on battery."); + Logger.Warn( + "Updates will not be installed automatically because the device is on battery." + ); await ShowAvailableUpdatesNotification(upgradablePackages); } - else if (Settings.Get(Settings.K.DisableAUPOnBatterySaver) && PowerManager.EnergySaverStatus is EnergySaverStatus.On) + else if ( + Settings.Get(Settings.K.DisableAUPOnBatterySaver) + && PowerManager.EnergySaverStatus is EnergySaverStatus.On + ) { - Logger.Warn("Updates will not be installed automatically because battery saver is enabled."); + Logger.Warn( + "Updates will not be installed automatically because battery saver is enabled." + ); await ShowAvailableUpdatesNotification(upgradablePackages); } else if (Settings.Get(Settings.K.AutomaticallyUpdatePackages)) @@ -370,13 +425,19 @@ protected override async void WhenPackagesLoaded(ReloadReason reason) { _ = MainApp.Operations.UpdateAll(); await ShowUpgradingPackagesNotification(upgradablePackages); - Logger.Warn("Automatic install of updates has been enabled via Command Line (user settings have been overriden)"); + Logger.Warn( + "Automatic install of updates has been enabled via Command Line (user settings have been overriden)" + ); } else { - foreach(var package in upgradablePackages) + foreach (var package in upgradablePackages) { - if ((await InstallOptionsFactory.LoadApplicableAsync(package)).AutoUpdatePackage) + if ( + ( + await InstallOptionsFactory.LoadApplicableAsync(package) + ).AutoUpdatePackage + ) { await MainApp.Operations.Update(package); } @@ -390,7 +451,9 @@ protected override async void WhenPackagesLoaded(ReloadReason reason) } } - static async Task ShowAvailableUpdatesNotification(IReadOnlyList upgradablePackages) + static async Task ShowAvailableUpdatesNotification( + IReadOnlyList upgradablePackages + ) { if (Settings.AreUpdatesNotificationsDisabled()) return; @@ -399,7 +462,12 @@ static async Task ShowAvailableUpdatesNotification(IReadOnlyList upgra foreach (var Package in upgradablePackages) { // This allows to disable update notifications only for certain package managers - if (!Settings.GetDictionaryItem(Settings.K.DisabledPackageManagerNotifications, Package.Manager.Name)) + if ( + !Settings.GetDictionaryItem( + Settings.K.DisabledPackageManagerNotifications, + Package.Manager.Name + ) + ) { SendNotification = true; break; @@ -409,7 +477,9 @@ static async Task ShowAvailableUpdatesNotification(IReadOnlyList upgra if (!SendNotification) return; - await AppNotificationManager.Default.RemoveByTagAsync(CoreData.UpdatesAvailableNotificationTag.ToString()); + await AppNotificationManager.Default.RemoveByTagAsync( + CoreData.UpdatesAvailableNotificationTag.ToString() + ); AppNotification notification; if (upgradablePackages.Count == 1) @@ -417,19 +487,31 @@ static async Task ShowAvailableUpdatesNotification(IReadOnlyList upgra AppNotificationBuilder builder = new AppNotificationBuilder() .SetScenario(AppNotificationScenario.Default) .SetTag(CoreData.UpdatesAvailableNotificationTag.ToString()) - .AddText(CoreTools.Translate("An update was found!")) - .AddText(CoreTools.Translate("{0} can be updated to version {1}", - upgradablePackages[0].Name, upgradablePackages[0].NewVersionString)) - .SetAttributionText(CoreTools.Translate("You have currently version {0} installed", - upgradablePackages[0].VersionString)) - - .AddArgument("action", NotificationArguments.ShowOnUpdatesTab) // Believe it or not, the `'` character is broken - .AddButton(new AppNotificationButton(CoreTools.Translate("View on UniGetUI").Replace("'", "´")) - .AddArgument("action", NotificationArguments.ShowOnUpdatesTab) + .AddText( + CoreTools.Translate( + "{0} can be updated to version {1}", + upgradablePackages[0].Name, + upgradablePackages[0].NewVersionString + ) ) - .AddButton(new AppNotificationButton(CoreTools.Translate("Update")) - .AddArgument("action", NotificationArguments.UpdateAllPackages) + .SetAttributionText( + CoreTools.Translate( + "You have currently version {0} installed", + upgradablePackages[0].VersionString + ) + ) + .AddArgument("action", NotificationArguments.ShowOnUpdatesTab) // Believe it or not, the `'` character is broken + .AddButton( + new AppNotificationButton( + CoreTools.Translate("View on UniGetUI").Replace("'", "´") + ).AddArgument("action", NotificationArguments.ShowOnUpdatesTab) + ) + .AddButton( + new AppNotificationButton(CoreTools.Translate("Update")).AddArgument( + "action", + NotificationArguments.UpdateAllPackages + ) ); notification = builder.BuildNotification(); } @@ -438,7 +520,12 @@ static async Task ShowAvailableUpdatesNotification(IReadOnlyList upgra string attribution = ""; foreach (IPackage package in upgradablePackages) { - if (!Settings.GetDictionaryItem(Settings.K.DisabledPackageManagerNotifications, package.Manager.Name)) + if ( + !Settings.GetDictionaryItem( + Settings.K.DisabledPackageManagerNotifications, + package.Manager.Name + ) + ) attribution += package.Name + ", "; } @@ -447,16 +534,22 @@ static async Task ShowAvailableUpdatesNotification(IReadOnlyList upgra AppNotificationBuilder builder = new AppNotificationBuilder() .SetScenario(AppNotificationScenario.Default) .SetTag(CoreData.UpdatesAvailableNotificationTag.ToString()) - .AddText(CoreTools.Translate("Updates found!")) - .AddText(CoreTools.Translate("{0} packages can be updated", upgradablePackages.Count)) + .AddText( + CoreTools.Translate("{0} packages can be updated", upgradablePackages.Count) + ) .SetAttributionText(attribution) - // Believe it or not, the `'` character is broken - .AddButton(new AppNotificationButton(CoreTools.Translate("Open UniGetUI").Replace("'", "´")) - .AddArgument("action", NotificationArguments.ShowOnUpdatesTab) + // Believe it or not, the `'` character is broken + .AddButton( + new AppNotificationButton( + CoreTools.Translate("Open UniGetUI").Replace("'", "´") + ).AddArgument("action", NotificationArguments.ShowOnUpdatesTab) ) - .AddButton(new AppNotificationButton(CoreTools.Translate("Update all")) - .AddArgument("action", NotificationArguments.UpdateAllPackages) + .AddButton( + new AppNotificationButton(CoreTools.Translate("Update all")).AddArgument( + "action", + NotificationArguments.UpdateAllPackages + ) ) .AddArgument("action", NotificationArguments.ShowOnUpdatesTab); notification = builder.BuildNotification(); @@ -466,7 +559,9 @@ static async Task ShowAvailableUpdatesNotification(IReadOnlyList upgra AppNotificationManager.Default.Show(notification); } - static async Task ShowUpgradingPackagesNotification(IReadOnlyList upgradablePackages) + static async Task ShowUpgradingPackagesNotification( + IReadOnlyList upgradablePackages + ) { if (Settings.AreUpdatesNotificationsDisabled()) return; @@ -474,7 +569,12 @@ static async Task ShowUpgradingPackagesNotification(IReadOnlyList upgr bool SendNotification = false; foreach (var Package in upgradablePackages) { - if (!Settings.GetDictionaryItem(Settings.K.DisabledPackageManagerNotifications, Package.Manager.Name)) + if ( + !Settings.GetDictionaryItem( + Settings.K.DisabledPackageManagerNotifications, + Package.Manager.Name + ) + ) { SendNotification = true; break; @@ -484,7 +584,9 @@ static async Task ShowUpgradingPackagesNotification(IReadOnlyList upgr if (!SendNotification) return; - await AppNotificationManager.Default.RemoveByTagAsync(CoreData.UpdatesAvailableNotificationTag.ToString()); + await AppNotificationManager.Default.RemoveByTagAsync( + CoreData.UpdatesAvailableNotificationTag.ToString() + ); AppNotification notification; if (upgradablePackages.Count == 1) @@ -492,11 +594,20 @@ static async Task ShowUpgradingPackagesNotification(IReadOnlyList upgr AppNotificationBuilder builder = new AppNotificationBuilder() .SetScenario(AppNotificationScenario.Default) .SetTag(CoreData.UpdatesAvailableNotificationTag.ToString()) - .AddText(CoreTools.Translate("An update was found!")) - .AddText(CoreTools.Translate("{0} is being updated to version {1}", upgradablePackages[0].Name, upgradablePackages[0].NewVersionString)) - .SetAttributionText(CoreTools.Translate("You have currently version {0} installed", upgradablePackages[0].VersionString)) - + .AddText( + CoreTools.Translate( + "{0} is being updated to version {1}", + upgradablePackages[0].Name, + upgradablePackages[0].NewVersionString + ) + ) + .SetAttributionText( + CoreTools.Translate( + "You have currently version {0} installed", + upgradablePackages[0].VersionString + ) + ) .AddArgument("action", NotificationArguments.ShowOnUpdatesTab); notification = builder.BuildNotification(); } @@ -505,7 +616,12 @@ static async Task ShowUpgradingPackagesNotification(IReadOnlyList upgr string attribution = ""; foreach (IPackage package in upgradablePackages) { - if (!Settings.GetDictionaryItem(Settings.K.DisabledPackageManagerNotifications, package.Manager.Name)) + if ( + !Settings.GetDictionaryItem( + Settings.K.DisabledPackageManagerNotifications, + package.Manager.Name + ) + ) attribution += package.Name + ", "; } @@ -514,11 +630,14 @@ static async Task ShowUpgradingPackagesNotification(IReadOnlyList upgr AppNotificationBuilder builder = new AppNotificationBuilder() .SetScenario(AppNotificationScenario.Default) .SetTag(CoreData.UpdatesAvailableNotificationTag.ToString()) - - .AddText(CoreTools.Translate("{0} packages are being updated", upgradablePackages.Count)) + .AddText( + CoreTools.Translate( + "{0} packages are being updated", + upgradablePackages.Count + ) + ) .SetAttributionText(attribution) .AddText(CoreTools.Translate("Updates found!")) - .AddArgument("action", NotificationArguments.ShowOnUpdatesTab); notification = builder.BuildNotification(); } @@ -527,23 +646,23 @@ static async Task ShowUpgradingPackagesNotification(IReadOnlyList upgr AppNotificationManager.Default.Show(notification); } - private void MenuInstall_Invoked(object sender, RoutedEventArgs e) - => _ = MainApp.Operations.Update(SelectedItem); + private void MenuInstall_Invoked(object sender, RoutedEventArgs e) => + _ = MainApp.Operations.Update(SelectedItem); - private void MenuSkipHash_Invoked(object sender, RoutedEventArgs e) - => _ = MainApp.Operations.Update(SelectedItem, no_integrity: true); + private void MenuSkipHash_Invoked(object sender, RoutedEventArgs e) => + _ = MainApp.Operations.Update(SelectedItem, no_integrity: true); - private void MenuInteractive_Invoked(object sender, RoutedEventArgs e) - => _ = MainApp.Operations.Update(SelectedItem, interactive: true); + private void MenuInteractive_Invoked(object sender, RoutedEventArgs e) => + _ = MainApp.Operations.Update(SelectedItem, interactive: true); - private void MenuAsAdmin_Invoked(object sender, RoutedEventArgs e) - => _ = MainApp.Operations.Update(SelectedItem, elevated: true); + private void MenuAsAdmin_Invoked(object sender, RoutedEventArgs e) => + _ = MainApp.Operations.Update(SelectedItem, elevated: true); - private void MenuUpdateAfterUninstall_Invoked(object sender, RoutedEventArgs e) - => _ = MainApp.Operations.UninstallThenUpdate(SelectedItem); + private void MenuUpdateAfterUninstall_Invoked(object sender, RoutedEventArgs e) => + _ = MainApp.Operations.UninstallThenUpdate(SelectedItem); - private void MenuUninstall_Invoked(object sender, RoutedEventArgs e) - => _ = MainApp.Operations.Uninstall(SelectedItem); + private void MenuUninstall_Invoked(object sender, RoutedEventArgs e) => + _ = MainApp.Operations.Uninstall(SelectedItem); private void MenuIgnorePackage_Invoked(object sender, RoutedEventArgs e) { diff --git a/src/UniGetUI/Services/BackgroundLoginApi.cs b/src/UniGetUI/Services/BackgroundLoginApi.cs index 6c59b0ed65..590500b240 100644 --- a/src/UniGetUI/Services/BackgroundLoginApi.cs +++ b/src/UniGetUI/Services/BackgroundLoginApi.cs @@ -6,10 +6,11 @@ namespace UniGetUI.Services; -public class GHAuthApiRunner: IDisposable +public class GHAuthApiRunner : IDisposable { public event EventHandler? OnLogin; private IHost? _host; + public GHAuthApiRunner() { } public async Task Start() @@ -62,7 +63,8 @@ await context.Response.WriteAsync(

Authentication successful

You can now close this window and return to UniGetUI

- """); + """ + ); Logger.ImportantInfo($"[AUTH API] Received authentication token {code} from GitHub"); OnLogin?.Invoke(this, code.ToString()); diff --git a/src/UniGetUI/Services/GitHubAuthService.cs b/src/UniGetUI/Services/GitHubAuthService.cs index 9945a0c2e7..958192cbb8 100644 --- a/src/UniGetUI/Services/GitHubAuthService.cs +++ b/src/UniGetUI/Services/GitHubAuthService.cs @@ -5,8 +5,8 @@ using UniGetUI.Core.Logging; using UniGetUI.Core.SecureSettings; using UniGetUI.Core.SettingsEngine; -using Windows.System; using UniGetUI.Interface; +using Windows.System; namespace UniGetUI.Services { @@ -18,6 +18,7 @@ public class GitHubAuthService private readonly GitHubClient _client; public static event EventHandler? AuthStatusChanged; + public GitHubAuthService() { _client = new GitHubClient(new ProductHeaderValue("UniGetUI", CoreData.VersionName)); @@ -28,17 +29,20 @@ public GitHubAuthService() var token = SecureGHTokenManager.GetToken(); if (string.IsNullOrEmpty(token)) { - Logger.Error("GitHub access token is not available. Cannot perform Gist operation."); + Logger.Error( + "GitHub access token is not available. Cannot perform Gist operation." + ); return null; } return new GitHubClient(new ProductHeaderValue("UniGetUI", CoreData.VersionName)) { - Credentials = new Credentials(token) + Credentials = new Credentials(token), }; } private GHAuthApiRunner? loginBackend; + public async Task SignInAsync() { try @@ -48,7 +52,7 @@ public async Task SignInAsync() var request = new OauthLoginRequest(GitHubClientId) { Scopes = { "read:user", "gist" }, - RedirectUri = new Uri(RedirectUri) + RedirectUri = new Uri(RedirectUri), }; var oauthLoginUrl = _client.Oauth.GetGitHubLoginUrl(request); @@ -72,7 +76,8 @@ public async Task SignInAsync() await loginBackend.Start(); await Launcher.LaunchUriAsync(oauthLoginUrl); - while (codeFromAPI is null) await Task.Delay(100); + while (codeFromAPI is null) + await Task.Delay(100); loginBackend.OnLogin -= BackgroundApiOnOnLogin; await loginBackend.Stop(); @@ -92,6 +97,7 @@ public async Task SignInAsync() } private string? codeFromAPI; + private void BackgroundApiOnOnLogin(object? sender, string c) { codeFromAPI = c; @@ -103,7 +109,7 @@ private async Task _completeSignInAsync(string code) { var tokenRequest = new OauthTokenRequest(GitHubClientId, GitHubClientSecret, code) { - RedirectUri = new Uri(RedirectUri) // The same redirect_uri must be sent + RedirectUri = new Uri(RedirectUri), // The same redirect_uri must be sent }; var token = await _client.Oauth.CreateAccessToken(tokenRequest); @@ -119,7 +125,7 @@ private async Task _completeSignInAsync(string code) var userClient = new GitHubClient(new ProductHeaderValue("UniGetUI")) { - Credentials = new Credentials(token.AccessToken) + Credentials = new Credentials(token.AccessToken), }; var user = await userClient.User.Current(); diff --git a/src/UniGetUI/Services/GitHubBackupService.cs b/src/UniGetUI/Services/GitHubBackupService.cs index ec024322b5..adde230987 100644 --- a/src/UniGetUI/Services/GitHubBackupService.cs +++ b/src/UniGetUI/Services/GitHubBackupService.cs @@ -9,11 +9,13 @@ public class GitHubBackupService private const string GistDescription_EndingKey = "@[UNIGETUI_BACKUP_V1]"; private const string PackageBackup_StartingKey = "@[PACKAGES]"; - private const string GistDescription = $"UniGetUI package backups - DO NOT RENAME OR MODIFY {GistDescription_EndingKey}"; - private const string ReadMeContents = "" + - "This special Gist is used by UniGetUI to store your package backups. \n" + - "Please DO NOT EDIT the contents or the description of this gist, or unexpected behaviours may occur.\n" + - "Learn more about UniGetUI at https://github.com/Devolutions/UniGetUI\n"; + private const string GistDescription = + $"UniGetUI package backups - DO NOT RENAME OR MODIFY {GistDescription_EndingKey}"; + private const string ReadMeContents = + "" + + "This special Gist is used by UniGetUI to store your package backups. \n" + + "Please DO NOT EDIT the contents or the description of this gist, or unexpected behaviours may occur.\n" + + "Learn more about UniGetUI at https://github.com/Devolutions/UniGetUI\n"; private readonly GitHubAuthService _authService; @@ -22,7 +24,8 @@ public class GitHubBackupService public GitHubBackupService(GitHubAuthService authService) { _authService = authService; - string deviceUserUniqueIdentifier = $"{Environment.MachineName}\\{Environment.UserName}".Replace(" ", ""); + string deviceUserUniqueIdentifier = + $"{Environment.MachineName}\\{Environment.UserName}".Replace(" ", ""); GistFileKey = $"{PackageBackup_StartingKey} {deviceUserUniqueIdentifier}"; } @@ -38,16 +41,22 @@ public async Task UploadPackageBundle(string bundleContents) User user = await GHClient.User.Current(); var candidates = await GHClient.Gist.GetAllForUser(user.Login); - Gist? existingBackup = candidates?.FirstOrDefault(g => g?.Description?.EndsWith(GistDescription_EndingKey) ?? false); + Gist? existingBackup = candidates?.FirstOrDefault(g => + g?.Description?.EndsWith(GistDescription_EndingKey) ?? false + ); if (existingBackup is null) { - Logger.Warn($"No matching gist was found as a valid backup, a new gist will be created..."); + Logger.Warn( + $"No matching gist was found as a valid backup, a new gist will be created..." + ); existingBackup = await _createBackupGistAsync(GHClient); } await _updateBackupGistAsync(GHClient, existingBackup, bundleContents); - Logger.Info($"Cloud backup completed successfully to gist {user.Login}/{existingBackup.Id}"); + Logger.Info( + $"Cloud backup completed successfully to gist {user.Login}/{existingBackup.Id}" + ); } /// @@ -74,11 +83,7 @@ private async Task _updateBackupGistAsync(GitHubClient client, Gist gist, string /// private static Task _createBackupGistAsync(GitHubClient client) { - var newGist = new NewGist - { - Description = GistDescription, - Public = false, - }; + var newGist = new NewGist { Description = GistDescription, Public = false }; newGist.Files.Add("- UniGetUI Package Backups", ReadMeContents); return client.Gist.Create(newGist); } @@ -95,11 +100,14 @@ public async Task> GetAvailableBackups() User user = await GHClient.User.Current(); var candidates = await GHClient.Gist.GetAllForUser(user.Login); - Gist? existingBackup = candidates?.FirstOrDefault(g => g?.Description?.EndsWith(GistDescription_EndingKey) ?? false); - - return existingBackup?.Files - .Where(f => f.Key.StartsWith(PackageBackup_StartingKey)) - .Select(f => $"{f.Key.Split(' ')[^1]} ({CoreTools.FormatAsSize(f.Value.Size)})") ?? []; + Gist? existingBackup = candidates?.FirstOrDefault(g => + g?.Description?.EndsWith(GistDescription_EndingKey) ?? false + ); + + return existingBackup + ?.Files.Where(f => f.Key.StartsWith(PackageBackup_StartingKey)) + .Select(f => $"{f.Key.Split(' ')[^1]} ({CoreTools.FormatAsSize(f.Value.Size)})") + ?? []; } /// @@ -114,13 +122,19 @@ public async Task> GetAvailableBackups() User user = await GHClient.User.Current(); var candidates = await GHClient.Gist.GetAllForUser(user.Login); - Gist? existingBackup = candidates?.FirstOrDefault(g => g?.Description?.EndsWith(GistDescription_EndingKey) ?? false); + Gist? existingBackup = candidates?.FirstOrDefault(g => + g?.Description?.EndsWith(GistDescription_EndingKey) ?? false + ); if (existingBackup is null) - throw new KeyNotFoundException($"The backup {backupName} was not found, yet this name was passed by argument"); + throw new KeyNotFoundException( + $"The backup {backupName} was not found, yet this name was passed by argument" + ); existingBackup = await GHClient.Gist.Get(existingBackup.Id); - return existingBackup.Files - .FirstOrDefault(f => f.Key.StartsWith(PackageBackup_StartingKey) && f.Key.EndsWith(backupName)) + return existingBackup + .Files.FirstOrDefault(f => + f.Key.StartsWith(PackageBackup_StartingKey) && f.Key.EndsWith(backupName) + ) .Value.Content; } } diff --git a/src/UniGetUI/Services/Secrets.cs b/src/UniGetUI/Services/Secrets.cs index fa98eb1859..675ecab94e 100644 --- a/src/UniGetUI/Services/Secrets.cs +++ b/src/UniGetUI/Services/Secrets.cs @@ -8,6 +8,7 @@ internal static partial class Secrets * Seeing errors? Build the project (maybe twice) */ public static partial string GetGitHubClientId(); + public static partial string GetGitHubClientSecret(); /* ------------------------------------------------------------------------ */ } diff --git a/src/UniGetUI/Services/UserAvatar.cs b/src/UniGetUI/Services/UserAvatar.cs index 93bf49bf3e..f99edc45f8 100644 --- a/src/UniGetUI/Services/UserAvatar.cs +++ b/src/UniGetUI/Services/UserAvatar.cs @@ -1,4 +1,3 @@ -using Windows.UI; using Microsoft.UI; using Microsoft.UI.Input; using Microsoft.UI.Xaml; @@ -12,10 +11,11 @@ using UniGetUI.Interface.Widgets; using UniGetUI.Pages.DialogPages; using UniGetUI.Pages.SettingsPages.GeneralPages; +using Windows.UI; namespace UniGetUI.Services { - public partial class PointButton: Button + public partial class PointButton : Button { public PointButton() { @@ -23,7 +23,7 @@ public PointButton() } } - public partial class UserAvatar: UserControl + public partial class UserAvatar : UserControl { public UserAvatar() { @@ -53,7 +53,9 @@ public async Task RefreshStatus() } } - private void LoginButton_Click(object sender, RoutedEventArgs e) => _ = _loginButton_Click(); + private void LoginButton_Click(object sender, RoutedEventArgs e) => + _ = _loginButton_Click(); + private async Task _loginButton_Click() { SetLoading(); @@ -99,22 +101,23 @@ private void LogoutButton_Click(object sender, RoutedEventArgs e) private void SetLoading() { - this.Content = new ProgressRing() { IsIndeterminate = true, Width = 24, Height = 24 }; + this.Content = new ProgressRing() + { + IsIndeterminate = true, + Width = 24, + Height = 24, + }; } private PointButton GenerateLoginControl() { - var personPicture = new PersonPicture - { - Width = 36, - Height = 36, - }; + var personPicture = new PersonPicture { Width = 36, Height = 36 }; var translatedTextBlock = new TextBlock { Margin = new Thickness(4), TextWrapping = TextWrapping.Wrap, - Text = CoreTools.Translate("Log in with GitHub to enable cloud package backup.") + Text = CoreTools.Translate("Log in with GitHub to enable cloud package backup."), }; var hyperlinkButton = new HyperlinkButton @@ -126,14 +129,15 @@ private PointButton GenerateLoginControl() Text = CoreTools.Translate("More details"), TextWrapping = TextWrapping.Wrap, }, - FontSize = 12 + FontSize = 12, }; - hyperlinkButton.Click += (_, _) => MainApp.Instance.MainWindow.NavigationPage.ShowHelp("cloud-backup-overview/"); + hyperlinkButton.Click += (_, _) => + MainApp.Instance.MainWindow.NavigationPage.ShowHelp("cloud-backup-overview/"); var loginButton = new PointButton { HorizontalAlignment = HorizontalAlignment.Stretch, - Content = CoreTools.Translate("Log in") + Content = CoreTools.Translate("Log in"), }; loginButton.Click += LoginButton_Click; @@ -142,7 +146,7 @@ private PointButton GenerateLoginControl() MaxWidth = 200, Margin = new Thickness(-8), Orientation = Orientation.Vertical, - Spacing = 8 + Spacing = 8, }; stackPanel.Children.Add(translatedTextBlock); stackPanel.Children.Add(hyperlinkButton); @@ -152,7 +156,7 @@ private PointButton GenerateLoginControl() { LightDismissOverlayMode = LightDismissOverlayMode.Off, Placement = FlyoutPlacementMode.Bottom, - Content = stackPanel + Content = stackPanel, }; return new PointButton @@ -163,7 +167,7 @@ private PointButton GenerateLoginControl() BorderThickness = new Thickness(0), CornerRadius = new CornerRadius(100), Content = personPicture, - Flyout = flyout + Flyout = flyout, }; } @@ -194,14 +198,18 @@ private async Task GenerateLogoutControl() { Width = 36, Height = 36, - ProfilePicture = new BitmapImage(new Uri(user.AvatarUrl)) + ProfilePicture = new BitmapImage(new Uri(user.AvatarUrl)), }; var text1 = new TextBlock { Margin = new Thickness(4), TextWrapping = TextWrapping.Wrap, - Text = CoreTools.Translate("You are logged in as {0} (@{1})", user.Name, user.Login) + Text = CoreTools.Translate( + "You are logged in as {0} (@{1})", + user.Name, + user.Login + ), }; var text2 = new TextBlock @@ -210,7 +218,9 @@ private async Task GenerateLogoutControl() TextWrapping = TextWrapping.Wrap, FontSize = 12, FontWeight = new(500), - Text = CoreTools.Translate("If you have cloud backup enabled, it will be saved as a GitHub Gist on this account") + Text = CoreTools.Translate( + "If you have cloud backup enabled, it will be saved as a GitHub Gist on this account" + ), }; var hyperlinkButton = new HyperlinkButton @@ -222,9 +232,10 @@ private async Task GenerateLogoutControl() Text = CoreTools.Translate("More details"), TextWrapping = TextWrapping.Wrap, }, - FontSize = 12 + FontSize = 12, }; - hyperlinkButton.Click += (_, _) => MainApp.Instance.MainWindow.NavigationPage.ShowHelp("cloud-backup-overview/"); + hyperlinkButton.Click += (_, _) => + MainApp.Instance.MainWindow.NavigationPage.ShowHelp("cloud-backup-overview/"); var hyperlinkButton2 = new HyperlinkButton { @@ -235,16 +246,19 @@ private async Task GenerateLogoutControl() Text = CoreTools.Translate("Package backup settings"), TextWrapping = TextWrapping.Wrap, }, - FontSize = 12 + FontSize = 12, }; - hyperlinkButton2.Click += (_, _) => MainApp.Instance.MainWindow.NavigationPage.OpenSettingsPage(typeof(Backup)); + hyperlinkButton2.Click += (_, _) => + MainApp.Instance.MainWindow.NavigationPage.OpenSettingsPage(typeof(Backup)); var loginButton = new PointButton { HorizontalAlignment = HorizontalAlignment.Stretch, Content = CoreTools.Translate("Log out"), - Background = new SolidColorBrush(ActualTheme is ElementTheme.Dark? Colors.DarkRed: Colors.PaleVioletRed), - BorderThickness = new(0) + Background = new SolidColorBrush( + ActualTheme is ElementTheme.Dark ? Colors.DarkRed : Colors.PaleVioletRed + ), + BorderThickness = new(0), }; loginButton.Click += LogoutButton_Click; @@ -253,7 +267,7 @@ private async Task GenerateLogoutControl() MaxWidth = 200, Margin = new Thickness(-8), Orientation = Orientation.Vertical, - Spacing = 8 + Spacing = 8, }; stackPanel.Children.Add(text1); stackPanel.Children.Add(text2); @@ -265,7 +279,7 @@ private async Task GenerateLogoutControl() { LightDismissOverlayMode = LightDismissOverlayMode.Off, Placement = FlyoutPlacementMode.Bottom, - Content = stackPanel + Content = stackPanel, }; return new PointButton @@ -276,7 +290,7 @@ private async Task GenerateLogoutControl() BorderThickness = new Thickness(0), CornerRadius = new CornerRadius(100), Content = personPicture, - Flyout = flyout + Flyout = flyout, }; } } diff --git a/src/UniGetUI/Themes/Generic.xaml b/src/UniGetUI/Themes/Generic.xaml index 9eaeee0066..2cc18ed4e2 100644 --- a/src/UniGetUI/Themes/Generic.xaml +++ b/src/UniGetUI/Themes/Generic.xaml @@ -1,20 +1,20 @@ - - - + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:local="using:UniGetUI" + xmlns:local2="using:UniGetUI.Interface.Widgets" +> + diff --git a/src/UniGetUI/UniGetUI.csproj b/src/UniGetUI/UniGetUI.csproj index b007155f32..3b67cbbfdd 100644 --- a/src/UniGetUI/UniGetUI.csproj +++ b/src/UniGetUI/UniGetUI.csproj @@ -1,361 +1,394 @@  + + $(WindowsTargetFramework) + + WinExe + UniGetUI + app.manifest + true + true + UniGetUI.EntryPoint + False + icon.ico - - $(WindowsTargetFramework) - - WinExe - UniGetUI - app.manifest - true - true - UniGetUI.EntryPoint - False - icon.ico - - - true - None + + true + None - - true - partial - true - + + true + partial + true + - - arm64 - x64 - $(PkgDevolutions_UniGetUI_Elevator)\runtimes\win-$(ElevatorPackageArchitecture)\native\UniGetUI Elevator.exe - + + arm64 + x64 + $(PkgDevolutions_UniGetUI_Elevator)\runtimes\win-$(ElevatorPackageArchitecture)\native\UniGetUI Elevator.exe + - $(IntermediateOutputPath)\Generated Files\Secrets.Generated.cs - - + $(IntermediateOutputPath)\Generated Files\Secrets.Generated.cs + + - + - - - + + + - - - + + + - + + + + + + + + + Designer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - Designer - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - $(DefaultXamlRuntime) - Designer - - - $(DefaultXamlRuntime) - Designer - - - $(DefaultXamlRuntime) - - - $(DefaultXamlRuntime) - Designer - - - Designer - - - MSBuild:Compile - - - - - MSBuild:Compile - - - - - MSBuild:Compile - - - - - true - - - $(DefineConstants);DISABLE_XAML_GENERATED_MAIN - - - $(DefineConstants);DISABLE_XAML_GENERATED_MAIN - - - $(DefineConstants);DISABLE_XAML_GENERATED_MAIN - - - $(DefineConstants);DISABLE_XAML_GENERATED_MAIN - - - - - - - PreserveNewest - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - MSBuild:Compile - - - MSBuild:Compile - - - MSBuild:Compile - - - MSBuild:Compile - - - MSBuild:Compile - - - MSBuild:Compile - - - MSBuild:Compile - - - MSBuild:Compile - - - MSBuild:Compile - - - MSBuild:Compile - - - MSBuild:Compile - - - MSBuild:Compile - - - MSBuild:Compile - - - MSBuild:Compile - - - - - MSBuild:Compile - - - - - MSBuild:Compile - - - - - MSBuild:Compile - - - - - MSBuild:Compile - - - - - MSBuild:Compile - - - - - MSBuild:Compile - - - - - MSBuild:Compile - - - - - MSBuild:Compile - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Always - - - PreserveNewest - PreserveNewest - false - false - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - + + true + + + $(DefineConstants);DISABLE_XAML_GENERATED_MAIN + + + $(DefineConstants);DISABLE_XAML_GENERATED_MAIN + + + $(DefineConstants);DISABLE_XAML_GENERATED_MAIN + + + $(DefineConstants);DISABLE_XAML_GENERATED_MAIN + + + + + + + PreserveNewest + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + + + MSBuild:Compile + + + + + MSBuild:Compile + + + + + MSBuild:Compile + + + + + MSBuild:Compile + + + + + MSBuild:Compile + + + + + MSBuild:Compile + + + + + MSBuild:Compile + + + + + MSBuild:Compile + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Always + + + PreserveNewest + PreserveNewest + false + false + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + - - - + + + - - - + + + - - - - - + + + + + - - - + + + diff --git a/src/WindowsPackageManager.Interop/Exceptions/WinGetConfigurationException.cs b/src/WindowsPackageManager.Interop/Exceptions/WinGetConfigurationException.cs index 4d7269bc5e..f70c091cac 100644 --- a/src/WindowsPackageManager.Interop/Exceptions/WinGetConfigurationException.cs +++ b/src/WindowsPackageManager.Interop/Exceptions/WinGetConfigurationException.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. namespace WindowsPackageManager.Interop; diff --git a/src/WindowsPackageManager.Interop/ExternalLibraries.WindowsPackageManager.Interop.csproj b/src/WindowsPackageManager.Interop/ExternalLibraries.WindowsPackageManager.Interop.csproj index 0ad23b000d..dfbf549516 100644 --- a/src/WindowsPackageManager.Interop/ExternalLibraries.WindowsPackageManager.Interop.csproj +++ b/src/WindowsPackageManager.Interop/ExternalLibraries.WindowsPackageManager.Interop.csproj @@ -1,71 +1,72 @@ + + $(WindowsTargetFramework) + - - $(WindowsTargetFramework) - - - - true - WindowsPackageManager.Interop - + - - - - - $(PkgMicrosoft_Windows_SDK_Contracts)\ref\netstandard2.0 - 10.0.26100.0 - Microsoft.Management.Deployment - + + $(PkgMicrosoft_Windows_SDK_Contracts)\ref\netstandard2.0 + 10.0.26100.0 + Microsoft.Management.Deployment + $(PkgMicrosoft_WindowsPackageManager_InProcCom)\lib\Microsoft.Management.Deployment.winmd + - - - - - + + + + + - - - - true - none - - - all - runtime; build; native; contentfiles; analyzers - + + + + true + none + + + all + runtime; build; native; contentfiles; analyzers + - - - NU1701 - true - none - false - - - - NU1701 - true - none - - + + NU1701 + true + none + false + - - - - + + NU1701 + true + none + + diff --git a/src/WindowsPackageManager.Interop/WindowsPackageManager/ClassModel.cs b/src/WindowsPackageManager.Interop/WindowsPackageManager/ClassModel.cs index 8718713f4e..a37bc10e56 100644 --- a/src/WindowsPackageManager.Interop/WindowsPackageManager/ClassModel.cs +++ b/src/WindowsPackageManager.Interop/WindowsPackageManager/ClassModel.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. namespace WindowsPackageManager.Interop; @@ -30,7 +30,9 @@ public Guid GetClsid(ClsidContext context) { if (!Clsids.TryGetValue(context, out Guid clsid)) { - throw new InvalidOperationException($"{ProjectedClassType.FullName} is not implemented in context {context}"); + throw new InvalidOperationException( + $"{ProjectedClassType.FullName} is not implemented in context {context}" + ); } return clsid; diff --git a/src/WindowsPackageManager.Interop/WindowsPackageManager/ClassesDefinition.cs b/src/WindowsPackageManager.Interop/WindowsPackageManager/ClassesDefinition.cs index 7b9946f0bb..7ba76c5751 100644 --- a/src/WindowsPackageManager.Interop/WindowsPackageManager/ClassesDefinition.cs +++ b/src/WindowsPackageManager.Interop/WindowsPackageManager/ClassesDefinition.cs @@ -7,74 +7,75 @@ namespace WindowsPackageManager.Interop; internal static class ClassesDefinition { - private static Dictionary Classes { get; } = new() - { - [typeof(PackageManager)] = new() + private static Dictionary Classes { get; } = + new() { - ProjectedClassType = typeof(PackageManager), - InterfaceType = typeof(IPackageManager), - Clsids = new Dictionary + [typeof(PackageManager)] = new() { - [ClsidContext.Prod] = new Guid("C53A4F16-787E-42A4-B304-29EFFB4BF597"), - [ClsidContext.Dev] = new Guid("74CB3139-B7C5-4B9E-9388-E6616DEA288C"), + ProjectedClassType = typeof(PackageManager), + InterfaceType = typeof(IPackageManager), + Clsids = new Dictionary + { + [ClsidContext.Prod] = new Guid("C53A4F16-787E-42A4-B304-29EFFB4BF597"), + [ClsidContext.Dev] = new Guid("74CB3139-B7C5-4B9E-9388-E6616DEA288C"), + }, }, - }, - [typeof(FindPackagesOptions)] = new() - { - ProjectedClassType = typeof(FindPackagesOptions), - InterfaceType = typeof(IFindPackagesOptions), - Clsids = new Dictionary + [typeof(FindPackagesOptions)] = new() { - [ClsidContext.Prod] = new Guid("572DED96-9C60-4526-8F92-EE7D91D38C1A"), - [ClsidContext.Dev] = new Guid("1BD8FF3A-EC50-4F69-AEEE-DF4C9D3BAA96"), + ProjectedClassType = typeof(FindPackagesOptions), + InterfaceType = typeof(IFindPackagesOptions), + Clsids = new Dictionary + { + [ClsidContext.Prod] = new Guid("572DED96-9C60-4526-8F92-EE7D91D38C1A"), + [ClsidContext.Dev] = new Guid("1BD8FF3A-EC50-4F69-AEEE-DF4C9D3BAA96"), + }, }, - }, - [typeof(CreateCompositePackageCatalogOptions)] = new() - { - ProjectedClassType = typeof(CreateCompositePackageCatalogOptions), - InterfaceType = typeof(ICreateCompositePackageCatalogOptions), - Clsids = new Dictionary + [typeof(CreateCompositePackageCatalogOptions)] = new() { - [ClsidContext.Prod] = new Guid("526534B8-7E46-47C8-8416-B1685C327D37"), - [ClsidContext.Dev] = new Guid("EE160901-B317-4EA7-9CC6-5355C6D7D8A7"), + ProjectedClassType = typeof(CreateCompositePackageCatalogOptions), + InterfaceType = typeof(ICreateCompositePackageCatalogOptions), + Clsids = new Dictionary + { + [ClsidContext.Prod] = new Guid("526534B8-7E46-47C8-8416-B1685C327D37"), + [ClsidContext.Dev] = new Guid("EE160901-B317-4EA7-9CC6-5355C6D7D8A7"), + }, }, - }, - [typeof(InstallOptions)] = new() - { - ProjectedClassType = typeof(InstallOptions), - InterfaceType = typeof(IInstallOptions), - Clsids = new Dictionary + [typeof(InstallOptions)] = new() { - [ClsidContext.Prod] = new Guid("1095F097-EB96-453B-B4E6-1613637F3B14"), - [ClsidContext.Dev] = new Guid("44FE0580-62F7-44D4-9E91-AA9614AB3E86"), + ProjectedClassType = typeof(InstallOptions), + InterfaceType = typeof(IInstallOptions), + Clsids = new Dictionary + { + [ClsidContext.Prod] = new Guid("1095F097-EB96-453B-B4E6-1613637F3B14"), + [ClsidContext.Dev] = new Guid("44FE0580-62F7-44D4-9E91-AA9614AB3E86"), + }, }, - }, - [typeof(UninstallOptions)] = new() - { - ProjectedClassType = typeof(UninstallOptions), - InterfaceType = typeof(IUninstallOptions), - Clsids = new Dictionary + [typeof(UninstallOptions)] = new() { - [ClsidContext.Prod] = new Guid("E1D9A11E-9F85-4D87-9C17-2B93143ADB8D"), - [ClsidContext.Dev] = new Guid("AA2A5C04-1AD9-46C4-B74F-6B334AD7EB8C"), + ProjectedClassType = typeof(UninstallOptions), + InterfaceType = typeof(IUninstallOptions), + Clsids = new Dictionary + { + [ClsidContext.Prod] = new Guid("E1D9A11E-9F85-4D87-9C17-2B93143ADB8D"), + [ClsidContext.Dev] = new Guid("AA2A5C04-1AD9-46C4-B74F-6B334AD7EB8C"), + }, }, - }, - [typeof(PackageMatchFilter)] = new() - { - ProjectedClassType = typeof(PackageMatchFilter), - InterfaceType = typeof(IPackageMatchFilter), - Clsids = new Dictionary + [typeof(PackageMatchFilter)] = new() { - [ClsidContext.Prod] = new Guid("D02C9DAF-99DC-429C-B503-4E504E4AB000"), - [ClsidContext.Dev] = new Guid("3F85B9F4-487A-4C48-9035-2903F8A6D9E8"), + ProjectedClassType = typeof(PackageMatchFilter), + InterfaceType = typeof(IPackageMatchFilter), + Clsids = new Dictionary + { + [ClsidContext.Prod] = new Guid("D02C9DAF-99DC-429C-B503-4E504E4AB000"), + [ClsidContext.Dev] = new Guid("3F85B9F4-487A-4C48-9035-2903F8A6D9E8"), + }, }, - }, - }; + }; /// /// Get CLSID based on the provided context for the specified type @@ -109,7 +110,9 @@ private static void ValidateType() { if (!Classes.ContainsKey(typeof(TType))) { - throw new InvalidOperationException($"{typeof(TType).Name} is not a projected class type."); + throw new InvalidOperationException( + $"{typeof(TType).Name} is not a projected class type." + ); } } } diff --git a/src/WindowsPackageManager.Interop/WindowsPackageManager/ClsidContext.cs b/src/WindowsPackageManager.Interop/WindowsPackageManager/ClsidContext.cs index 93425c1f24..fab200549b 100644 --- a/src/WindowsPackageManager.Interop/WindowsPackageManager/ClsidContext.cs +++ b/src/WindowsPackageManager.Interop/WindowsPackageManager/ClsidContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. namespace WindowsPackageManager.Interop; diff --git a/src/WindowsPackageManager.Interop/WindowsPackageManager/WindowsPackageManagerFactory.cs b/src/WindowsPackageManager.Interop/WindowsPackageManager/WindowsPackageManagerFactory.cs index 8bd8f95e1d..16c54808c5 100644 --- a/src/WindowsPackageManager.Interop/WindowsPackageManager/WindowsPackageManagerFactory.cs +++ b/src/WindowsPackageManager.Interop/WindowsPackageManager/WindowsPackageManagerFactory.cs @@ -15,7 +15,10 @@ public abstract class WindowsPackageManagerFactory private readonly ClsidContext _clsidContext; protected readonly bool _allowLowerTrustRegistration; - public WindowsPackageManagerFactory(ClsidContext clsidContext, bool allowLowerTrustRegistration = false) + public WindowsPackageManagerFactory( + ClsidContext clsidContext, + bool allowLowerTrustRegistration = false + ) { _clsidContext = clsidContext; _allowLowerTrustRegistration = allowLowerTrustRegistration; @@ -35,7 +38,8 @@ public WindowsPackageManagerFactory(ClsidContext clsidContext, bool allowLowerTr public FindPackagesOptions CreateFindPackagesOptions() => CreateInstance(); - public CreateCompositePackageCatalogOptions CreateCreateCompositePackageCatalogOptions() => CreateInstance(); + public CreateCompositePackageCatalogOptions CreateCreateCompositePackageCatalogOptions() => + CreateInstance(); public InstallOptions CreateInstallOptions() => CreateInstance(); diff --git a/src/WindowsPackageManager.Interop/WindowsPackageManager/WindowsPackageManagerStandardFactory.cs b/src/WindowsPackageManager.Interop/WindowsPackageManager/WindowsPackageManagerStandardFactory.cs index 8c147e8fb3..95a223723e 100644 --- a/src/WindowsPackageManager.Interop/WindowsPackageManager/WindowsPackageManagerStandardFactory.cs +++ b/src/WindowsPackageManager.Interop/WindowsPackageManager/WindowsPackageManagerStandardFactory.cs @@ -12,10 +12,11 @@ namespace WindowsPackageManager.Interop; [SupportedOSPlatform("windows5.0")] public class WindowsPackageManagerStandardFactory : WindowsPackageManagerFactory { - public WindowsPackageManagerStandardFactory(ClsidContext clsidContext = ClsidContext.Prod, bool allowLowerTrustRegistration = false) - : base(clsidContext, allowLowerTrustRegistration) - { - } + public WindowsPackageManagerStandardFactory( + ClsidContext clsidContext = ClsidContext.Prod, + bool allowLowerTrustRegistration = false + ) + : base(clsidContext, allowLowerTrustRegistration) { } protected override T CreateInstance(Guid clsid, Guid iid) { @@ -28,7 +29,13 @@ protected override T CreateInstance(Guid clsid, Guid iid) clsctx |= CLSCTX.CLSCTX_ALLOW_LOWER_TRUST_REGISTRATION; } - Windows.Win32.Foundation.HRESULT hr = PInvoke.CoCreateInstance(clsid, null, clsctx, iid, out object result); + Windows.Win32.Foundation.HRESULT hr = PInvoke.CoCreateInstance( + clsid, + null, + clsctx, + iid, + out object result + ); // !! WARNING !! // An exception may be thrown on the line below if UniGetUI