Skip to content

Commit

Permalink
Merge pull request #2541 from marticliment/improvements-to-package-op…
Browse files Browse the repository at this point in the history
…erations

Migration to OperationProvider
  • Loading branch information
marticliment authored Jul 30, 2024
2 parents 2645501 + e38e7fe commit bf06452
Show file tree
Hide file tree
Showing 43 changed files with 863 additions and 968 deletions.
68 changes: 3 additions & 65 deletions src/UniGetUI.PAckageEngine.Interfaces/IPackageManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace UniGetUI.PackageEngine.Interfaces
{
public interface IPackageManager : ISourceProvider, IPackageDetailsProvider
public interface IPackageManager : ISourceProvider, IPackageDetailsProvider, IOperationProvider
{
public ManagerProperties Properties { get; }
public ManagerCapabilities Capabilities { get; }
Expand All @@ -20,6 +20,7 @@ public interface IPackageManager : ISourceProvider, IPackageDetailsProvider

public ISourceProvider? SourceProvider { get; }
public IPackageDetailsProvider? PackageDetailsProvider { get; }
public IOperationProvider? OperationProvider { get; }

/// <summary>
/// Initializes the Package Manager (asynchronously). Must be run before using any other method of the manager.
Expand Down Expand Up @@ -54,76 +55,13 @@ public interface IPackageManager : ISourceProvider, IPackageDetailsProvider
/// </summary>
public Task<IPackage[]> GetInstalledPackages();

/// <summary>
/// Returns the command-line parameters to install the given package.
/// Each manager MUST implement this method.
/// </summary>
/// <param name="package">The Package going to be installed</param>
/// <param name="options">The options in which it is going to be installed</param>
/// <returns>An array of strings containing the parameters without the manager executable file</returns>
public abstract string[] GetInstallParameters(IPackage package, IInstallationOptions options);


/// <summary>
/// Returns the command-line parameters to update the given package.
/// Each manager MUST implement this method.
/// </summary>
/// <param name="package">The Package going to be updated</param>
/// <param name="options">The options in which it is going to be updated</param>
/// <returns>An array of strings containing the parameters without the manager executable file</returns>
public abstract string[] GetUpdateParameters(IPackage package, IInstallationOptions options);

/// <summary>
/// Returns the command-line parameters to uninstall the given package.
/// Each manager MUST implement this method.
/// </summary>
/// <param name="package">The Package going to be uninstalled</param>
/// <param name="options">The options in which it is going to be uninstalled</param>
/// <returns>An array of strings containing the parameters without the manager executable file</returns>
public abstract string[] GetUninstallParameters(IPackage package, IInstallationOptions options);

/// <summary>
/// Decides and returns the verdict of the install operation.
/// Each manager MUST implement this method.
/// </summary>
/// <param name="package">The package that was installed</param>
/// <param name="options">The options with which the package was installed. They may be modified if the returned value is OperationVeredict.AutoRetry</param>
/// <param name="ReturnCode">The exit code of the process</param>
/// <param name="Output">the output of the process</param>
/// <returns>An OperationVeredict value representing the result of the installation</returns>
public abstract OperationVeredict GetInstallOperationVeredict(IPackage package, IInstallationOptions options, int ReturnCode, string[] Output);


/// <summary>
/// Decides and returns the verdict of the update operation.
/// Each manager MUST implement this method.
/// </summary>
/// <param name="package">The package that was updated</param>
/// <param name="options">The options with which the package was updated. They may be modified if the returned value is OperationVeredict.AutoRetry</param>
/// <param name="ReturnCode">The exit code of the process</param>
/// <param name="Output">the output of the process</param>
/// <returns>An OperationVeredict value representing the result of the update</returns>
public abstract OperationVeredict GetUpdateOperationVeredict(IPackage package, IInstallationOptions options, int ReturnCode, string[] Output);

/// <summary>
/// Decides and returns the verdict of the uninstall operation.
/// Each manager MUST implement this method.
/// </summary>
/// <param name="package">The package that was uninstalled</param>
/// <param name="options">The options with which the package was uninstalled. They may be modified if the returned value is OperationVeredict.AutoRetry</param>
/// <param name="ReturnCode">The exit code of the process</param>
/// <param name="Output">the output of the process</param>
/// <returns>An OperationVeredict value representing the result of the uninstall</returns>
public abstract OperationVeredict GetUninstallOperationVeredict(IPackage package, IInstallationOptions options, int ReturnCode, string[] Output);

/// <summary>
/// Refreshes the Package Manager sources/indexes
/// Each manager MUST implement this method.
/// </summary>
public Task RefreshPackageIndexes();

public IManagerSource GetSourceOrDefault(string SourceName);
public IManagerSource? GetSourceIfExists(string SourceName);

public void LogOperation(Process process, string output);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using UniGetUI.PackageEngine.Enums;

namespace UniGetUI.PackageEngine.Interfaces.ManagerProviders;
public interface IOperationProvider
{
/// <summary>
/// Returns the list of arguments that need to be passed to the Package Manager executable so
/// that the requested operation is performed over the given package, with its corresponding
/// installation options.
/// </summary>
public abstract IEnumerable<string> GetOperationParameters(
IPackage package,
IInstallationOptions options,
OperationType operation
);

/// <summary>
/// Returns the veredict of the given package operation, given the package, the operation type,
/// the corresponding output and the return code.
/// </summary>
public abstract OperationVeredict GetOperationResult(
IPackage package,
IInstallationOptions options,
OperationType operation,
IEnumerable<string> processOutput,
int returnCode
);
}
1 change: 1 addition & 0 deletions src/UniGetUI.PackageEngine.Enums/Enums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public enum OperationVeredict
{
Succeeded,
Failed,
RestartRequired,
AutoRetry,
}
public enum OperationStatus
Expand Down
102 changes: 1 addition & 101 deletions src/UniGetUI.PackageEngine.Managers.Chocolatey/Chocolatey.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public Chocolatey()

SourceProvider = new ChocolateySourceProvider(this);
PackageDetailsProvider = new ChocolateyDetailsProvider(this);
OperationProvider = new ChocolateyOperationProvider(this);
}

protected override async Task<Package[]> GetAvailableUpdates_UnSafe()
Expand Down Expand Up @@ -170,107 +171,6 @@ protected override async Task<Package[]> GetInstalledPackages_UnSafe()

return Packages.ToArray();
}
public override OperationVeredict GetInstallOperationVeredict(IPackage package, IInstallationOptions options, int ReturnCode, string[] Output)
{
string output_string = string.Join("\n", Output);

if (ReturnCode is 1641 or 0)
{
return OperationVeredict.Succeeded;
}

if (ReturnCode == 3010)
{
return OperationVeredict.Succeeded; // TODO: Restart required
}

if ((output_string.Contains("Run as administrator") || output_string.Contains("The requested operation requires elevation") || output_string.Contains("ERROR: Exception calling \"CreateDirectory\" with \"1\" argument(s): \"Access to the path")) && !options.RunAsAdministrator)
{
options.RunAsAdministrator = true;
return OperationVeredict.AutoRetry;
}

return OperationVeredict.Failed;
}

public override OperationVeredict GetUpdateOperationVeredict(IPackage package, IInstallationOptions options, int ReturnCode, string[] Output)
{
return GetInstallOperationVeredict(package, options, ReturnCode, Output);
}

public override OperationVeredict GetUninstallOperationVeredict(IPackage package, IInstallationOptions options, int ReturnCode, string[] Output)
{
string output_string = string.Join("\n", Output);

if (ReturnCode is 1641 or 1614 or 1605 or 0)
{
return OperationVeredict.Succeeded;
}

if (ReturnCode == 3010)
{
return OperationVeredict.Succeeded; // TODO: Restart required
}

if ((output_string.Contains("Run as administrator") || output_string.Contains("The requested operation requires elevation")) && !options.RunAsAdministrator)
{
options.RunAsAdministrator = true;
return OperationVeredict.AutoRetry;
}

return OperationVeredict.Failed;
}
public override string[] GetInstallParameters(IPackage package, IInstallationOptions options)
{
List<string> parameters = GetUninstallParameters(package, options).ToList();
parameters[0] = Properties.InstallVerb;
parameters.Add("--no-progress");

if (options.Architecture == Architecture.X86)
{
parameters.Add("--forcex86");
}

if (options.PreRelease)
{
parameters.Add("--prerelease");
}

if (options.SkipHashCheck)
{
parameters.AddRange(["--ignore-checksums", "--force"]);
}

if (options.Version != "")
{
parameters.AddRange([$"--version={options.Version}", "--allow-downgrade"]);
}

return parameters.ToArray();
}
public override string[] GetUpdateParameters(IPackage package, IInstallationOptions options)
{
string[] parameters = GetInstallParameters(package, options);
parameters[0] = Properties.UpdateVerb;
return parameters;
}

public override string[] GetUninstallParameters(IPackage package, IInstallationOptions options)
{
List<string> parameters = [Properties.UninstallVerb, package.Id, "-y"];

if (options.CustomParameters is not null)
{
parameters.AddRange(options.CustomParameters);
}

if (options.InteractiveInstallation)
{
parameters.Add("--notsilent");
}

return parameters.ToArray();
}

protected override async Task<ManagerStatus> LoadManager()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using UniGetUI.PackageEngine.Classes.Manager.BaseProviders;
using UniGetUI.PackageEngine.Enums;
using UniGetUI.PackageEngine.Interfaces;
using UniGetUI.PackageEngine.Managers.ChocolateyManager;
using UniGetUI.PackageEngine.PackageClasses;

namespace UniGetUI.PackageEngine.Managers.ChocolateyManager;
internal sealed class ChocolateyOperationProvider : BaseOperationProvider<Chocolatey>
{
public ChocolateyOperationProvider(Chocolatey manager) : base(manager) { }

public override IEnumerable<string> GetOperationParameters(
IPackage package,
IInstallationOptions options,
OperationType operation)
{
List<string> 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.CustomParameters is not null)
parameters.AddRange(options.CustomParameters);

if (options.InteractiveInstallation)
parameters.Add("--notsilent");

if(operation is OperationType.Install or OperationType.Update)
{
parameters.Add("--no-progress");

if (options.Architecture == Architecture.X86)
parameters.Add("--forcex86");

if (options.PreRelease)
parameters.Add("--prerelease");

if (options.SkipHashCheck)
parameters.AddRange(["--ignore-checksums", "--force"]);

if (options.Version != "")
parameters.AddRange([$"--version={options.Version}", "--allow-downgrade"]);
}

return parameters;
}

public override OperationVeredict GetOperationResult(
IPackage package,
IInstallationOptions options,
OperationType operation,
IEnumerable<string> processOutput,
int returnCode)
{
if(returnCode is 3010)
{
return OperationVeredict.RestartRequired;
}

if (returnCode is 1641 or 1614 or 1605 or 0)
{
return OperationVeredict.Succeeded;
}


string output_string = string.Join("\n", processOutput);
if (!options.RunAsAdministrator &&
(output_string.Contains("Run as administrator")
|| output_string.Contains("The requested operation requires elevation")
|| output_string.Contains("ERROR: Exception calling \"CreateDirectory\" with \"1\" argument(s): \"Access to the path")) )
{
options.RunAsAdministrator = true;
return OperationVeredict.AutoRetry;
}

return OperationVeredict.Failed;
}
}
Loading

0 comments on commit bf06452

Please sign in to comment.