diff --git a/src/c#/GeneralUpdate.Drivelution/Core/Pipeline/IPipelineStep.cs b/src/c#/GeneralUpdate.Drivelution/Core/Pipeline/IPipelineStep.cs new file mode 100644 index 00000000..572d0ba5 --- /dev/null +++ b/src/c#/GeneralUpdate.Drivelution/Core/Pipeline/IPipelineStep.cs @@ -0,0 +1,31 @@ +using GeneralUpdate.Drivelution.Abstractions.Models; + +namespace GeneralUpdate.Drivelution.Core.Pipeline; + +/// +/// Defines a single step in the driver update pipeline. +/// Each step encapsulates one stage of the update process (validate, backup, install, verify, etc.). +/// +public interface IPipelineStep +{ + /// + /// Human-readable name of this step, used for logging and progress reporting. + /// + string StepName { get; } + + /// + /// Determines whether this step should be executed given the current context. + /// Allows steps to conditionally skip based on strategy (e.g., backup step skipped when RequireBackup is false). + /// + /// Current pipeline context. + /// true if the step should run; otherwise false. + bool ShouldExecute(PipelineContext context); + + /// + /// Executes the pipeline step asynchronously. + /// + /// Mutable pipeline context carrying driver info, strategy, and result. + /// Cancellation token. + /// A indicating success or failure. + Task ExecuteAsync(PipelineContext context, CancellationToken cancellationToken); +} diff --git a/src/c#/GeneralUpdate.Drivelution/Core/Pipeline/PipelineContext.cs b/src/c#/GeneralUpdate.Drivelution/Core/Pipeline/PipelineContext.cs new file mode 100644 index 00000000..a4a2ea29 --- /dev/null +++ b/src/c#/GeneralUpdate.Drivelution/Core/Pipeline/PipelineContext.cs @@ -0,0 +1,44 @@ +using GeneralUpdate.Drivelution.Abstractions.Models; + +namespace GeneralUpdate.Drivelution.Core.Pipeline; + +/// +/// Mutable context object that flows through the driver update pipeline. +/// Carries driver information, strategy configuration, and the accumulating result. +/// +public class PipelineContext +{ + /// + /// Initializes a new pipeline context. + /// + /// Driver information for the update. + /// Update strategy configuration. + /// Accumulating update result (mutated by each step). + public PipelineContext(DriverInfo driverInfo, UpdateStrategy strategy, UpdateResult result) + { + DriverInfo = driverInfo ?? throw new ArgumentNullException(nameof(driverInfo)); + Strategy = strategy ?? throw new ArgumentNullException(nameof(strategy)); + Result = result ?? throw new ArgumentNullException(nameof(result)); + } + + /// + /// Driver information for the update. + /// + public DriverInfo DriverInfo { get; } + + /// + /// Update strategy configuration. + /// + public UpdateStrategy Strategy { get; } + + /// + /// Accumulating update result (mutated by each pipeline step). + /// + public UpdateResult Result { get; } + + /// + /// A mutable bag of key-value pairs for steps to share intermediate data. + /// Example: the backup step stores the backup path here, the rollback step reads it. + /// + public Dictionary Bag { get; } = new(); +} diff --git a/src/c#/GeneralUpdate.Drivelution/Core/Pipeline/PipelineResult.cs b/src/c#/GeneralUpdate.Drivelution/Core/Pipeline/PipelineResult.cs new file mode 100644 index 00000000..53a21c8f --- /dev/null +++ b/src/c#/GeneralUpdate.Drivelution/Core/Pipeline/PipelineResult.cs @@ -0,0 +1,39 @@ +namespace GeneralUpdate.Drivelution.Core.Pipeline; + +/// +/// Represents the outcome of a single pipeline step execution. +/// +public class PipelineResult +{ + /// + /// Whether the step executed successfully. + /// + public bool Success { get; init; } + + /// + /// Error message if the step failed (null when successful). + /// + public string? ErrorMessage { get; init; } + + /// + /// Optional exception captured during step execution. + /// + public Exception? Exception { get; init; } + + /// + /// Creates a successful result. + /// + public static PipelineResult Ok() => new() { Success = true }; + + /// + /// Creates a failed result with an error message. + /// + /// Description of the failure. + /// Optional exception that caused the failure. + public static PipelineResult Fail(string errorMessage, Exception? exception = null) => new() + { + Success = false, + ErrorMessage = errorMessage, + Exception = exception + }; +}