Skip to content

Commit 21d74fd

Browse files
committed
Allow PowerShell7 updates to clear up older versions of modules, if the user enables so (fix #3123)
1 parent 013dbca commit 21d74fd

8 files changed

Lines changed: 45 additions & 4 deletions

File tree

src/UniGetUI.PackageEngine.Enums/ManagerCapabilities.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public struct ManagerCapabilities
2424
public bool CanRunInteractively = false;
2525
public bool CanRemoveDataOnUninstall = false;
2626
public bool CanDownloadInstaller = false;
27+
public bool CanUninstallPreviousVersionsAfterUpdate = false;
2728
public bool SupportsCustomVersions = false;
2829
public bool SupportsCustomArchitectures = false;
2930
public string[] SupportedCustomArchitectures = [];

src/UniGetUI.PackageEngine.Managers.PowerShell7/PowerShell7.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public PowerShell7()
2727
SupportsPreRelease = true,
2828
CanDownloadInstaller = true,
2929
SupportsCustomPackageIcons = true,
30+
CanUninstallPreviousVersionsAfterUpdate = true,
3031
Sources = new SourceCapabilities
3132
{
3233
KnowsPackageCount = false,

src/UniGetUI.PackageEngine.Operations/PackageOperations.cs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using UniGetUI.Core.Classes;
22
using UniGetUI.Core.Data;
3+
using UniGetUI.Core.Logging;
34
using UniGetUI.Core.SettingsEngine;
45
using UniGetUI.Core.Tools;
56
using UniGetUI.Interface.Enums;
@@ -31,7 +32,7 @@ public PackageOperation(
3132
OperationType role,
3233
bool IgnoreParallelInstalls = false,
3334
AbstractOperation? req = null)
34-
: base(!IgnoreParallelInstalls, _getPreInstallOps(options, role, req), _getPostInstallOps(options, role))
35+
: base(!IgnoreParallelInstalls, _getPreInstallOps(options, role, package, req), _getPostInstallOps(options, role, package))
3536
{
3637
Package = package;
3738
Options = options;
@@ -129,7 +130,7 @@ public override Task<Uri> GetOperationIcon()
129130
return TaskRecycler<Uri>.RunOrAttachAsync(Package.GetIconUrl);
130131
}
131132

132-
private static IReadOnlyList<InnerOperation> _getPreInstallOps(InstallOptions opts, OperationType role, AbstractOperation? preReq = null)
133+
private static IReadOnlyList<InnerOperation> _getPreInstallOps(InstallOptions opts, OperationType role, IPackage package, AbstractOperation? preReq = null)
133134
{
134135
List<InnerOperation> l = new();
135136
if(preReq is not null) l.Add(new(preReq, true));
@@ -149,7 +150,7 @@ private static IReadOnlyList<InnerOperation> _getPreInstallOps(InstallOptions op
149150
return l;
150151
}
151152

152-
private static IReadOnlyList<InnerOperation> _getPostInstallOps(InstallOptions opts, OperationType role)
153+
private static IReadOnlyList<InnerOperation> _getPostInstallOps(InstallOptions opts, OperationType role, IPackage package)
153154
{
154155
List<InnerOperation> l = new();
155156

@@ -160,6 +161,17 @@ private static IReadOnlyList<InnerOperation> _getPostInstallOps(InstallOptions o
160161
else if (role is OperationType.Uninstall && opts.PostUninstallCommand.Any())
161162
l.Add(new(new PrePostOperation(opts.PostUninstallCommand), false));
162163

164+
if (role is OperationType.Update && opts.UninstallPreviousVersionsOnUpdate)
165+
{
166+
var matches = InstalledPackagesLoader.Instance.Packages.Where(
167+
p => p.IsEquivalentTo(package) && p.NormalizedVersion < package.NormalizedNewVersion);
168+
foreach (var match in matches)
169+
{
170+
Logger.Info($"Queuing {match} version {match.VersionString} for automatic uninstall after update...");
171+
l.Add(new(new UninstallPackageOperation(match, opts.Copy()), false));
172+
}
173+
}
174+
163175
return l;
164176
}
165177
}

src/UniGetUI.PackageEngine.Serializable/InstallOptions.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public class InstallOptions: SerializableComponent<InstallOptions>
1919
public bool SkipMinorUpdates { get; set; }
2020
public bool OverridesNextLevelOpts { get; set; }
2121
public bool RemoveDataOnUninstall { get; set; }
22+
public bool UninstallPreviousVersionsOnUpdate { get; set; }
2223
public List<string> KillBeforeOperation { get; set; } = [];
2324

2425
public string PreInstallCommand { get; set; } = "";
@@ -59,7 +60,8 @@ public override InstallOptions Copy()
5960
PostUninstallCommand = PostUninstallCommand,
6061
AbortOnPreInstallFail = AbortOnPreInstallFail,
6162
AbortOnPreUpdateFail = AbortOnPreUpdateFail,
62-
AbortOnPreUninstallFail = AbortOnPreUninstallFail
63+
AbortOnPreUninstallFail = AbortOnPreUninstallFail,
64+
UninstallPreviousVersionsOnUpdate = UninstallPreviousVersionsOnUpdate,
6365
};
6466
}
6567

@@ -92,6 +94,7 @@ this.CustomParameters_Uninstall.Count is 0 &&
9294
this.CustomInstallLocation = data[nameof(CustomInstallLocation)]?.GetVal<string>() ?? "";
9395
this.Version = data[nameof(Version)]?.GetVal<string>() ?? "";
9496
this.SkipMinorUpdates = data[nameof(SkipMinorUpdates)]?.GetVal<bool>() ?? false;
97+
this.UninstallPreviousVersionsOnUpdate = data[nameof(UninstallPreviousVersionsOnUpdate)]?.GetVal<bool>() ?? false;
9598

9699
this.PreInstallCommand = data[nameof(PreInstallCommand)]?.GetVal<string>() ?? "";
97100
this.PreUpdateCommand = data[nameof(PreUpdateCommand)]?.GetVal<string>() ?? "";
@@ -143,6 +146,7 @@ AbortOnPreInstallFail is not true ||
143146
AbortOnPreUpdateFail is not true ||
144147
PreUninstallCommand.Any() ||
145148
PostUninstallCommand.Any() ||
149+
UninstallPreviousVersionsOnUpdate is not false ||
146150
AbortOnPreUninstallFail is not true;
147151
// OverridesNextLevelOpts does not need to be checked here, since
148152
// this method is invoked before this property has been set
@@ -179,6 +183,7 @@ public override string ToString()
179183
$"AbortOnPreUpdateFail={AbortOnPreUpdateFail};" +
180184
$"PreUninstallCommand={PreUninstallCommand};" +
181185
$"PostUninstallCommand={PostUninstallCommand};" +
186+
$"UninstallPreviousVersionsOnUpdate={UninstallPreviousVersionsOnUpdate}" +
182187
$"AbortOnPreUninstallFail={AbortOnPreUninstallFail};" +
183188
$"PreRelease={PreRelease}>";
184189
}

src/UniGetUI/Pages/DialogPages/InstallOptions_Manager.xaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
<CheckBox Name="InteractiveCheckBox" Click="InteractiveCheckBox_Click" />
6868
<CheckBox Name="HashCheckBox" Click="HashCheckbox_Click" />
6969
<CheckBox Name="PreReleaseCheckBox" Click="PreReleaseCheckBox_Click" />
70+
<CheckBox Name="UninstallPreviousVerOnUpdate" Click="ClearPreviousOnUpdate_OnClick" />
7071

7172
</controls:WrapPanel>
7273
<!-- ARCHITECTURE COMBOBOX -->

src/UniGetUI/Pages/DialogPages/InstallOptions_Manager.xaml.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Microsoft.UI.Xaml;
22
using Microsoft.UI.Xaml.Controls;
33
using UniGetUI.Core.Language;
4+
using UniGetUI.Core.SettingsEngine;
45
using UniGetUI.Core.SettingsEngine.SecureSettings;
56
using UniGetUI.Core.Tools;
67
using UniGetUI.PackageEngine.Enums;
@@ -26,6 +27,7 @@ public InstallOptions_Manager(IPackageManager manager)
2627
AdminCheckBox.Content = CoreTools.Translate("Run as admin");
2728
InteractiveCheckBox.Content = CoreTools.Translate("Interactive installation");
2829
HashCheckBox.Content = CoreTools.Translate("Skip hash check");
30+
UninstallPreviousVerOnUpdate.Content = CoreTools.Translate("Uninstall previous versions when updated");
2931
PreReleaseCheckBox.Content = CoreTools.Translate("Allow pre-release versions");
3032
ArchLabel.Text = CoreTools.Translate("Architecture to install:");
3133
ScopeLabel.Text = CoreTools.Translate("Installation scope:");
@@ -149,6 +151,9 @@ private async Task LoadOptions()
149151
CustomParameters2.Text = string.Join(' ', options.CustomParameters_Update);
150152
CustomParameters3.Text = string.Join(' ', options.CustomParameters_Uninstall);
151153

154+
UninstallPreviousVerOnUpdate.IsEnabled = Manager.Capabilities.CanUninstallPreviousVersionsAfterUpdate;
155+
UninstallPreviousVerOnUpdate.IsChecked = options.UninstallPreviousVersionsOnUpdate;
156+
152157
ResetButton.IsEnabled = true;
153158
ApplyButton.IsEnabled = true;
154159
ApplyButton.Style = (Style)Application.Current.Resources["DefaultButtonStyle"];
@@ -167,6 +172,7 @@ private async Task SaveOptions()
167172
options.SkipHashCheck = HashCheckBox.IsChecked ?? false;
168173
options.InteractiveInstallation = InteractiveCheckBox.IsChecked ?? false;
169174
options.PreRelease = PreReleaseCheckBox.IsChecked ?? false;
175+
options.UninstallPreviousVersionsOnUpdate = UninstallPreviousVerOnUpdate.IsChecked ?? false;
170176

171177
// Administrator
172178
options.Architecture = "";
@@ -216,6 +222,7 @@ private void DisableAllInput()
216222
InteractiveCheckBox.IsEnabled = false;
217223
HashCheckBox.IsEnabled = false;
218224
ArchitectureCombo.IsEnabled = false;
225+
UninstallPreviousVerOnUpdate.IsEnabled = false;
219226
ScopeCombo.IsEnabled = false;
220227
SelectDir.IsEnabled = false;
221228
ResetDir.IsEnabled = false;
@@ -294,4 +301,9 @@ private void GoToSecureSettings_Click(object sender, RoutedEventArgs e)
294301
{
295302
MainApp.Instance.MainWindow.NavigationPage.OpenSettingsPage(typeof(Administrator));
296303
}
304+
305+
private void ClearPreviousOnUpdate_OnClick(object sender, RoutedEventArgs e)
306+
{
307+
ApplyButton.Style = (Style)Application.Current.Resources["AccentButtonStyle"];
308+
}
297309
}

src/UniGetUI/Pages/DialogPages/InstallOptions_Package.xaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,9 @@
200200
<CheckBox Name="HashCheckbox" Click="HashCheckbox_Click">
201201
<widgets:TranslatedTextBlock HorizontalAlignment="Stretch" Text="Skip hash check" />
202202
</CheckBox>
203+
<CheckBox Name="UninstallPreviousOnUpdate">
204+
<widgets:TranslatedTextBlock HorizontalAlignment="Stretch" Text="Uninstall previous versions when updated" />
205+
</CheckBox>
203206
</controls:WrapPanel>
204207
<Grid
205208
Padding="4,8"

src/UniGetUI/Pages/DialogPages/InstallOptions_Package.xaml.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ async Task LoadImage()
9797
AdminCheckBox.IsChecked = Options.RunAsAdministrator;
9898
InteractiveCheckBox.IsChecked = Options.InteractiveInstallation;
9999
HashCheckbox.IsChecked = Options.SkipHashCheck;
100+
UninstallPreviousOnUpdate.IsChecked = Options.UninstallPreviousVersionsOnUpdate;
100101

101102
ArchitectureComboBox.Items.Add(CoreTools.Translate("Default"));
102103
ArchitectureComboBox.SelectedIndex = 0;
@@ -226,6 +227,9 @@ private void EnableDisableControls(OperationType operation)
226227
operation is not OperationType.Uninstall
227228
&& Package.Manager.Capabilities.CanSkipIntegrityChecks;
228229

230+
UninstallPreviousOnUpdate.IsEnabled = Package.Manager.Capabilities.CanUninstallPreviousVersionsAfterUpdate;
231+
UninstallPreviousOnUpdate.Visibility = Package.Manager.Capabilities.CanUninstallPreviousVersionsAfterUpdate? Visibility.Visible: Visibility.Collapsed;
232+
229233
ArchitectureComboBox.IsEnabled =
230234
operation is not OperationType.Uninstall
231235
&& Package.Manager.Capabilities.SupportsCustomArchitectures;
@@ -302,6 +306,7 @@ public async Task<InstallOptions> GetUpdatedOptions(bool updateDetachedOptions =
302306
Options.RunAsAdministrator = AdminCheckBox?.IsChecked ?? false;
303307
Options.InteractiveInstallation = InteractiveCheckBox?.IsChecked ?? false;
304308
Options.SkipHashCheck = HashCheckbox?.IsChecked ?? false;
309+
Options.UninstallPreviousVersionsOnUpdate = UninstallPreviousOnUpdate?.IsChecked ?? false;
305310
Options.OverridesNextLevelOpts = !FollowGlobalOptionsSwitch.IsOn;
306311

307312
Options.Architecture = "";
@@ -471,6 +476,7 @@ private void SettingsTabBar_SelectionChanged(object sender, SelectionChangedEven
471476
{
472477
CommandLineViewBox.Visibility = SettingsTabBar.SelectedIndex < 3 ? Visibility.Visible : Visibility.Collapsed;
473478
}
479+
474480
}
475481

476482
public class IOP_Proc

0 commit comments

Comments
 (0)