Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migration to OperationProvider #2541

Merged
merged 6 commits into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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