Skip to content

Commit

Permalink
Implement scope override and scope detection from installer URL (#367)
Browse files Browse the repository at this point in the history
  • Loading branch information
ryfu-msft authored May 5, 2023
1 parent c415f84 commit 735abc1
Show file tree
Hide file tree
Showing 12 changed files with 343 additions and 127 deletions.
3 changes: 3 additions & 0 deletions doc/update.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ Override the architecture of an installer:

`wingetcreate.exe update --urls <InstallerUrl1>|<InstallerArchitecture> --version <Version> <PackageIdentifier>`

Override the scope of an installer:
`wingetcreate.exe update --urls <InstallerUrl1>|<InstallerScope> --version <Version> <PackageIdentifier>`

Update an existing manifest and submit PR to GitHub:

`wingetcreate.exe update --submit --token <GitHubPersonalAccessToken> --urls <InstallerUrl1> <InstallerUrl2> --version <Version> <PackageIdentifier>`
Expand Down
4 changes: 2 additions & 2 deletions src/WingetCreateCLI/Commands/BaseCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -224,9 +224,9 @@ protected static void DisplayArchitectureWarnings(List<InstallerMetadata> instal
i.UrlArchitecture != i.BinaryArchitecture);

if (mismatchedArchInstallers.Any())
{
Logger.WarnLocalized(nameof(Resources.DetectedArchMismatch_Message));
{
Console.WriteLine();
Logger.WarnLocalized(nameof(Resources.DetectedArchMismatch_Message));
foreach (var mismatch in mismatchedArchInstallers)
{
Logger.WarnLocalized(nameof(Resources.InstallerBinaryMismatch_Message), mismatch.UrlArchitecture, mismatch.BinaryArchitecture);
Expand Down
75 changes: 56 additions & 19 deletions src/WingetCreateCLI/Commands/UpdateCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public static IEnumerable<Example> Examples
yield return new Example(Resources.Example_UpdateCommand_SearchAndUpdateVersionAndInstallerURL, new UpdateCommand { Id = "<PackageIdentifier>", InstallerUrls = new string[] { "<InstallerUrl1>", "<InstallerUrl2>" }, Version = "<Version>" });
yield return new Example(Resources.Example_UpdateCommand_SaveAndPublish, new UpdateCommand { Id = "<PackageIdentifier>", Version = "<Version>", OutputDir = "<OutputDirectory>", GitHubToken = "<GitHubPersonalAccessToken>" });
yield return new Example(Resources.Example_UpdateCommand_OverrideArchitecture, new UpdateCommand { Id = "<PackageIdentifier>", InstallerUrls = new string[] { "<InstallerUrl1>|<InstallerArchitecture>" }, Version = "<Version>" });
yield return new Example(Resources.Example_UpdateCommand_OverrideScope, new UpdateCommand { Id = "<PackageIdentifier>", InstallerUrls = new string[] { "<InstallerUrl1>|<InstallerScope>" }, Version = "<Version>" });
yield return new Example(Resources.Example_UpdateCommand_SubmitToGitHub, new UpdateCommand { Id = "<PackageIdentifier>", Version = "<Version>", InstallerUrls = new string[] { "<InstallerUrl1>", "<InstallerUrl2>" }, SubmitToGitHub = true, GitHubToken = "<GitHubPersonalAccessToken>" });
}
}
Expand Down Expand Up @@ -231,16 +232,16 @@ public async Task<Manifests> UpdateManifestsAutonomously(Manifests manifests)
this.InstallerUrls = installerManifest.Installers.Select(i => i.InstallerUrl).Distinct().ToArray();
}

// Generate list of InstallerUpdate objects and parse out any specified architecture overrides.
List<InstallerMetadata> installerMetadataList = this.ParseInstallerUrlsForArchOverride(this.InstallerUrls.Select(i => i.Trim()).ToList());
// Generate list of InstallerUpdate objects and parse out any specified architecture or scope overrides.
List<InstallerMetadata> installerMetadataList = this.ParseInstallerUrlsForOverrides(this.InstallerUrls.Select(i => i.Trim()).ToList());

// If the installer update list is null there was an issue when parsing for architecture override.
// If the installer update list is null there was an issue when parsing for architecture or scope override.
if (installerMetadataList == null)
{
return null;
}

// Reassign list with parsed installer URLs without architecture overrides.
// Reassign list with parsed installer URLs without architecture or scope overrides.
this.InstallerUrls = installerMetadataList.Select(x => x.InstallerUrl).ToList();

foreach (var installerUpdate in installerMetadataList)
Expand All @@ -249,6 +250,11 @@ public async Task<Manifests> UpdateManifestsAutonomously(Manifests manifests)
{
Logger.WarnLocalized(nameof(Resources.OverridingArchitecture_Warning), installerUpdate.InstallerUrl, installerUpdate.OverrideArchitecture);
}

if (installerUpdate.OverrideScope.HasValue)
{
Logger.WarnLocalized(nameof(Resources.OverridingScope_Warning), installerUpdate.InstallerUrl, installerUpdate.OverrideScope);
}
}

// We only support updates with same number of installer URLs
Expand Down Expand Up @@ -561,11 +567,11 @@ private static void DisplayManifestsAsMenuSelection(Manifests manifests)
}

/// <summary>
/// Parse out architecture overrides included in the installer URLs and returns the parsed list of installer URLs.
/// Parses the installer urls for any architecture or scope overrides.
/// </summary>
/// <param name="installerUrlsToBeParsed">List of installer URLs to be parsed for architecture overrides.</param>
/// <returns>List of <see cref="InstallerMetadata"/> helper objects used for updating the installers.</returns>
private List<InstallerMetadata> ParseInstallerUrlsForArchOverride(List<string> installerUrlsToBeParsed)
private List<InstallerMetadata> ParseInstallerUrlsForOverrides(List<string> installerUrlsToBeParsed)
{
List<InstallerMetadata> installerMetadataList = new List<InstallerMetadata>();
foreach (string item in installerUrlsToBeParsed)
Expand All @@ -577,24 +583,55 @@ private List<InstallerMetadata> ParseInstallerUrlsForArchOverride(List<string> i
// '|' character indicates that an architecture override can be parsed from the installer.
string[] installerUrlOverride = item.Split('|');

if (installerUrlOverride.Length > 2)
// There can be at most 3 elements at one time (installerUrl|archOverride|scopeOverride)
if (installerUrlOverride.Length > 3)
{
Logger.ErrorLocalized(nameof(Resources.MultipleArchitectureOverride_Error));
Logger.ErrorLocalized(nameof(Resources.OverrideLimitExceeded_Error), item);
return null;
}

string installerUrl = installerUrlOverride[0];
string overrideArchString = installerUrlOverride[1];
Architecture? overrideArch = overrideArchString.ToEnumOrDefault<Architecture>();
if (overrideArch.HasValue)
{
installerMetadata.InstallerUrl = installerUrl;
installerMetadata.OverrideArchitecture = overrideArch.Value;
}
else
installerMetadata.InstallerUrl = installerUrlOverride[0];

bool archOverridePresent = false;
bool scopeOverridePresent = false;

for (int i = 1; i < installerUrlOverride.Length; i++)
{
Logger.ErrorLocalized(nameof(Resources.UnableToParseArchOverride_Error), overrideArchString);
return null;
string overrideString = installerUrlOverride[i];
Architecture? overrideArch = overrideString.ToEnumOrDefault<Architecture>();
Scope? overrideScope = overrideString.ToEnumOrDefault<Scope>();

if (overrideArch.HasValue)
{
if (archOverridePresent)
{
Logger.ErrorLocalized(nameof(Resources.MultipleArchitectureOverride_Error));
return null;
}
else
{
archOverridePresent = true;
installerMetadata.OverrideArchitecture = overrideArch.Value;
}
}
else if (overrideScope.HasValue)
{
if (scopeOverridePresent)
{
Logger.ErrorLocalized(nameof(Resources.MultipleScopeOverride_Error));
return null;
}
else
{
scopeOverridePresent = true;
installerMetadata.OverrideScope = overrideScope.Value;
}
}
else
{
Logger.ErrorLocalized(nameof(Resources.UnableToParseOverride_Error), overrideString);
return null;
}
}
}
else
Expand Down
78 changes: 55 additions & 23 deletions src/WingetCreateCLI/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 735abc1

Please sign in to comment.