Allow versioning in downloaded installer file names - #5319
Conversation
There was a problem hiding this comment.
Pull request overview
Adds configurable installer filename schemes and integrates them into download workflows.
Changes:
- Adds filename generation, sanitization, extension handling, and tests.
- Adds settings UI and search indexing.
- Adds manager metadata for version-dependent installer URLs.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
Package.cs |
Generates installer filenames with resolved versions. |
PackageManager.cs |
Adds default URL-version behavior. |
NullPackageManager.cs |
Implements the new interface property. |
BaseNuGet.cs |
Marks NuGet URLs as version-specific. |
Cargo.cs |
Marks Cargo URLs as version-specific. |
IPackageManager.cs |
Exposes URL-version behavior. |
InstallerFileNaming.cs |
Implements filename schemes and sanitization. |
InstallerFileNamingTests.cs |
Tests naming behavior and edge cases. |
SettingsEngine_Names.cs |
Registers the filename setting. |
Operations.axaml.cs |
Populates naming options. |
Operations.axaml |
Adds the settings UI. |
PackageDetailsWindow.axaml.cs |
Uses the application download workflow. |
SettingsSearchIndex.cs |
Indexes the new setting. |
AvaloniaPackageOperationHelper.cs |
Improves extension extraction for save dialogs. |
Suppressed comments (1)
src/UniGetUI.Core.Tools/InstallerFileNaming.cs:110
- A raw substring check can suppress the requested version even when only a different token contains it—for example, version
2.0is considered present intool-12.0, and single-digit versions match almost any stem. Check for the version as a delimiter-bounded filename token instead, while retaining the intendedjre-8u451-...case.
if (stem.Contains(version, StringComparison.OrdinalIgnoreCase))
return stem;
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
src/UniGetUI.Core.Tools.Tests/InstallerFileNamingTests.cs:11
- These tests write directly to
CoreData.UniGetUIUserConfigurationDirectory, and teardown deletes the user's existing installer-name preference instead of restoring it. Running the suite locally can therefore modify real application settings. Isolate the test withTEST_DataDirectoryOverride, as the other settings-backed Core.Tools tests do.
public void Dispose()
{
Settings.SetValue(Settings.K.InstallerFileNameScheme, "");
GC.SuppressFinalize(this);
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 20 out of 20 changed files in this pull request and generated 1 comment.
Suppressed comments (2)
Previously missed (2) — in code that hasn't changed since the last review.
src/UniGetUI.Core.Tools/InstallerFileNaming.cs:40
- Cargo details use installer type
Sourceand a/crates/{id}/{version}/downloadURL with no extension, but this map has nosourcefallback. Every versioned scheme therefore produces an extensionless Cargo artifact, and the single-file picker subsequently falls back to an.exefilter even though the payload is a.cratearchive. Add the Cargo fallback extension (or expose and map a Cargo-specific installer type).
["nupkg"] = ".nupkg",
src/UniGetUI.Core.Tools.Tests/InstallerFileNamingTests.cs:162
- This test is platform-dependent because
Sanitizedelegates toPath.GetInvalidFileNameChars()::is invalid on Windows but valid on Linux and macOS, so the supported cross-platform test project producesFoo: Bar Baz_1.0.exethere. Use only a universally invalid character such as/in this assertion.
"Foo: Bar / Baz",
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 23 out of 23 changed files in this pull request and generated no new comments.
Suppressed comments (2)
Previously missed (1) — in code that hasn't changed since the last review.
src/UniGetUI.Avalonia/ViewModels/DialogPages/OperationViewModel.cs:302
- This role-based fallback still loses the originating referral for install operations. A bundle install (
PackageBundlesPage.cs:277) and a reinstall launched from Installed Packages (InstalledPackagesPage.cs:381) are both plainInstallPackageOperations, so opening their details from the operation list reports subsequent installs/downloads asDIRECT_SEARCHinstead ofFROM_BUNDLEorALREADY_INSTALLED. Preserve the referral on the operation and pass it through here rather than inferring it fromRole.
var referral = packageOp.Role is OperationType.Update or OperationType.Uninstall
? TEL_InstallReferral.ALREADY_INSTALLED
: TEL_InstallReferral.DIRECT_SEARCH;
src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Package.cs:350
- For managers whose installer URL always resolves to the latest release, this fallback can label the payload with an unrelated installed version. For example, Pip loads its URL from the unversioned
/pypi/{id}/jsonendpoint, so an installed 1.0 package with no equivalent currently loaded can download 2.0 as..._1.0.whl; the newListedVersionIsUsedWhenNoEquivalentIsLoadedtest codifies this mismatch. When the latest version cannot be resolved, omit it or obtain it from manager metadata rather than falling back toVersionString.
return VersionString;
There was a problem hiding this comment.
🤖 Pull request was approved automatically: the AI review is complete and all its review threads are resolved. 🎉
Integration Details
{
"deliveryId": "39371e70-9ffa-11f1-9b6e-381295aeb7a4",
"headSha": "65b21fd9cba416fd8f18adef0be4e200115bccc5",
"reviewer": "copilot-pull-request-reviewer[bot]"
}
This pull request introduces a user-configurable setting for naming downloaded installer files, allowing users to choose between several naming schemes (e.g., including version or package ID in the file name). It also implements the logic for building installer file names according to the selected scheme, updates the UI and settings infrastructure to support this option, and adds comprehensive tests for the new functionality. Additionally, it introduces a new property to package managers to indicate if the installer URL follows the package version.
Installer file naming customization:
InstallerFileNamingutility with logic to build installer file names according to a user-selected scheme (publisher name, package name and version, package ID and version, or publisher name and version), including extension handling and sanitization.InstallerFileNameSchemeto the settings engine, exposed in the UI as a combobox in the Operations settings page, and indexed for search.Installer download flow improvements:
Testing and reliability:
InstallerFileNaming, covering all naming schemes, extension extraction, version normalization, and edge cases.Package manager interface update:
InstallerUrlFollowsPackageVersionproperty toIPackageManagerand implemented it in relevant package managers, allowing for future logic that depends on whether the installer URL changes with the package version.