Skip to content

Commit

Permalink
More command and configuration/settings refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
daveaglick committed Oct 18, 2019
1 parent 07fbdbf commit b94d0dc
Show file tree
Hide file tree
Showing 32 changed files with 395 additions and 290 deletions.
5 changes: 4 additions & 1 deletion RELEASE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# 1.0.0-alpha.9

- Removed `CustomBuildCommand` and replaced with fluent `IBootstrapper.AddCommand()` overloads.
- Added `IBootstrapper.AddDelegateCommand()` fluent methods to configure delegate-based commands.
- Added `IBootstrapper.AddBuildCommand()` fluent methods to configure simple commands that build specified pipelines.
- Refactored the base commands to allow consumers to derive from `EngineCommand`.
- Added a new `IEngineManager` interface to expose the engine manager to commands that derive from `EngineCommand`.
- Refactored `IEngine.Settings` and `IExecutionContext.Settings` to use a `IConfiguration` as the backing store and present it as metadata.
- Lazily creates type-based pipelines using the DI container so they can have injected services (#59).
- Adds `INamedPipeline` to allow pipeline instances to provide names.
Expand Down
6 changes: 3 additions & 3 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
version: '2.x'
- task: UseDotNet@2
inputs:
version: '3.x'
version: '3.0.x'
- script: build -target BuildServer
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
Expand All @@ -23,7 +23,7 @@ jobs:
version: '2.x'
- task: UseDotNet@2
inputs:
version: '3.x'
version: '3.0.x'
includePreviewVersions: true
- script: pwsh ./build.ps1 -target BuildServer
env:
Expand All @@ -37,7 +37,7 @@ jobs:
version: '2.x'
- task: UseDotNet@2
inputs:
version: '3.x'
version: '3.0.x'
includePreviewVersions: true
- script: pwsh ./build.ps1 -target BuildServer
env:
Expand Down
4 changes: 2 additions & 2 deletions src/core/Statiq.App/Bootstrapper/Bootstrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public async Task<int> RunAsync()
Configurators.Configure<IBootstrapper>(this);

// Get our initial settings for configuration
SettingsConfigurationProvider settingsProvider = new SettingsConfigurationProvider();
EngineSettingsConfigurationProvider settingsProvider = new EngineSettingsConfigurationProvider();
ConfigurableSettings configurableSettings = new ConfigurableSettings(settingsProvider);
Configurators.Configure(configurableSettings);

Expand All @@ -85,7 +85,7 @@ public async Task<int> RunAsync()

// Create the stand-alone command line service container and register a few types needed for the CLI
CommandServiceTypeRegistrar registrar = new CommandServiceTypeRegistrar();
registrar.RegisterInstance(typeof(SettingsConfigurationProvider), settingsProvider);
registrar.RegisterInstance(typeof(IEngineSettingsDictionary), settingsProvider);
registrar.RegisterInstance(typeof(IConfigurationRoot), configurationRoot);
registrar.RegisterInstance(typeof(IServiceCollection), serviceCollection);
registrar.RegisterInstance(typeof(IBootstrapper), this);
Expand Down
53 changes: 43 additions & 10 deletions src/core/Statiq.App/Bootstrapper/IBootstrapper.CommandDefaults.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,28 +38,61 @@ public IBootstrapper AddCommand(Type commandType, string name)
return this;
}

public IBootstrapper AddCommand(string name, EngineCommandSettings commandSettings)
{
_ = name ?? throw new ArgumentNullException(nameof(name));
_ = commandSettings ?? throw new ArgumentNullException(nameof(commandSettings));
return ConfigureCommands(x => x.AddCommand<CustomBuildCommand>(name).WithData(commandSettings));
}
public IBootstrapper AddBuildCommand(
string name,
params string[] pipelines) =>
AddBuildCommand(name, null, false, pipelines);

public IBootstrapper AddCommand(
public IBootstrapper AddBuildCommand(
string name,
string description,
params string[] pipelines) =>
AddBuildCommand(name, description, false, pipelines);

public IBootstrapper AddBuildCommand(
string name,
bool defaultPipelines,
params string[] pipelines) =>
AddCommand(name, false, pipelines);
AddBuildCommand(name, null, defaultPipelines, pipelines);

public IBootstrapper AddCommand(
public IBootstrapper AddBuildCommand(
string name,
string description,
bool defaultPipelines,
params string[] pipelines) =>
AddCommand(name, new EngineCommandSettings
AddBuildCommand(name, description, new EngineCommandSettings
{
Pipelines = pipelines,
DefaultPipelines = defaultPipelines
});

public IBootstrapper AddBuildCommand(string name, EngineCommandSettings commandSettings) =>
AddBuildCommand(name, null, commandSettings);

public IBootstrapper AddBuildCommand(string name, string description, EngineCommandSettings commandSettings)
{
_ = name ?? throw new ArgumentNullException(nameof(name));
_ = commandSettings ?? throw new ArgumentNullException(nameof(commandSettings));
return ConfigureCommands(x => x
.AddCommand<BuildCommand<BaseCommandSettings>>(name)
.WithData(commandSettings)
.WithDescription(description));
}

public IBootstrapper AddDelegateCommand(string name, Func<CommandContext, int> func) =>
AddDelegateCommand<EmptyCommandSettings>(name, null, (c, _) => func(c));

public IBootstrapper AddDelegateCommand(string name, string description, Func<CommandContext, int> func) =>
AddDelegateCommand<EmptyCommandSettings>(name, description, (c, _) => func(c));

public IBootstrapper AddDelegateCommand<TSettings>(string name, Func<CommandContext, TSettings, int> func)
where TSettings : CommandSettings =>
AddDelegateCommand(name, null, func);

public IBootstrapper AddDelegateCommand<TSettings>(string name, string description, Func<CommandContext, TSettings, int> func)
where TSettings : CommandSettings =>
ConfigureCommands(x => x.AddDelegate(name, func).WithDescription(description));

public IBootstrapper AddCommands(Assembly assembly)
{
_ = assembly ?? throw new ArgumentNullException(nameof(assembly));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ public IBootstrapper AddDefaultConfiguration() =>

public IBootstrapper AddDefaultCommands()
{
SetDefaultCommand<BuildCommand>();
AddCommand<BuildCommand>();
SetDefaultCommand<BuildCommand<EngineCommandSettings>>();
AddCommand<BuildCommand<EngineCommandSettings>>();
AddCommand<PreviewCommand>();
AddCommands();
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public IBootstrapper AddPipelines(
ConfigureEngine(x => action(x.Pipelines));

public IBootstrapper AddPipelines(
Action<ISettings, IPipelineCollection> action) =>
Action<IEngineSettings, IPipelineCollection> action) =>
ConfigureEngine(x => action(x.Settings, x.Pipelines));

// By type
Expand All @@ -27,10 +27,10 @@ public IBootstrapper AddPipeline(string name, IPipeline pipeline) =>
public IBootstrapper AddPipeline(IPipeline pipeline) =>
ConfigureEngine(x => x.Pipelines.Add(pipeline));

public IBootstrapper AddPipeline(string name, Func<ISettings, IPipeline> pipelineFunc) =>
public IBootstrapper AddPipeline(string name, Func<IEngineSettings, IPipeline> pipelineFunc) =>
ConfigureEngine(x => x.Pipelines.Add(name, pipelineFunc(x.Settings)));

public IBootstrapper AddPipeline(Func<ISettings, IPipeline> pipelineFunc) =>
public IBootstrapper AddPipeline(Func<IEngineSettings, IPipeline> pipelineFunc) =>
ConfigureEngine(x => x.Pipelines.Add(pipelineFunc(x.Settings)));

public IBootstrapper AddPipeline(Type pipelineType)
Expand Down
27 changes: 16 additions & 11 deletions src/core/Statiq.App/Commands/BuildCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,29 @@

namespace Statiq.App
{
[Description("Runs the pipelines.")]
internal class BuildCommand : EngineCommand<EngineCommandSettings>
[Description("Executes the pipelines.")]
internal class BuildCommand<TSettings> : EngineCommand<TSettings>
where TSettings : BaseCommandSettings
{
public BuildCommand(SettingsConfigurationProvider settingsProvider, IConfigurationRoot configurationRoot, IServiceCollection serviceCollection, IBootstrapper bootstrapper)
: base(settingsProvider, configurationRoot, serviceCollection, bootstrapper)
public BuildCommand(
IEngineSettingsDictionary engineSettings,
IConfigurationRoot configurationRoot,
IServiceCollection serviceCollection,
IBootstrapper bootstrapper)
: base(engineSettings, configurationRoot, serviceCollection, bootstrapper)
{
}

public override async Task<int> ExecuteCommandAsync(CommandContext context, EngineCommandSettings settings)
protected override async Task<int> ExecuteEngineAsync(
CommandContext commandContext,
TSettings commandSettings,
IEngineManager engineManager)
{
using (CancellationTokenSource cancellationTokenSource = new CancellationTokenSource())
{
using (EngineManager engineManager = new EngineManager(context, this, settings))
{
return await engineManager.ExecuteAsync(cancellationTokenSource)
? (int)ExitCode.Normal
: (int)ExitCode.ExecutionError;
}
return await engineManager.ExecuteAsync(cancellationTokenSource)
? (int)ExitCode.Normal
: (int)ExitCode.ExecutionError;
}
}
}
Expand Down
39 changes: 0 additions & 39 deletions src/core/Statiq.App/Commands/CustomBuildCommand.cs

This file was deleted.

20 changes: 0 additions & 20 deletions src/core/Statiq.App/Commands/EngineCommandData.cs

This file was deleted.

52 changes: 38 additions & 14 deletions src/core/Statiq.App/Commands/EngineCommand{TSettings}.cs
Original file line number Diff line number Diff line change
@@ -1,37 +1,61 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using NetEscapades.Extensions.Logging.RollingFile;
using Spectre.Cli;
using Statiq.Common;
using Statiq.Core;

namespace Statiq.App
{
internal abstract class EngineCommand<TSettings> : BaseCommand<TSettings>, IEngineCommand
public abstract class EngineCommand<TSettings> : BaseCommand<TSettings>
where TSettings : BaseCommandSettings
{
protected EngineCommand(SettingsConfigurationProvider settingsProvider, IConfigurationRoot configurationRoot, IServiceCollection serviceCollection, IBootstrapper bootstrapper)
protected EngineCommand(
IEngineSettingsDictionary engineSettings,
IConfigurationRoot configurationRoot,
IServiceCollection serviceCollection,
IBootstrapper bootstrapper)
: base(serviceCollection)
{
SettingsProvider = settingsProvider;
EngineSettings = engineSettings;
ConfigurationRoot = configurationRoot;
ServiceCollection = serviceCollection;
Bootstrapper = bootstrapper;
}

public SettingsConfigurationProvider SettingsProvider { get; }
public IEngineSettingsDictionary EngineSettings { get; }

public IConfigurationRoot ConfigurationRoot { get; }

public IServiceCollection ServiceCollection { get; }

public IBootstrapper Bootstrapper { get; }

public override sealed async Task<int> ExecuteCommandAsync(CommandContext commandContext, TSettings commandSettings)
{
// We need to get the engine command settings to pass to the engine manager
// First try the actual command settings
if (!(commandSettings is EngineCommandSettings engineCommandSettings))
{
// Then try the command data or create one and either way copy over the base command settings
engineCommandSettings = commandContext.Data as EngineCommandSettings ?? new EngineCommandSettings();
engineCommandSettings.LogLevel = commandSettings.LogLevel;
engineCommandSettings.Attach = commandSettings.Attach;
engineCommandSettings.LogFile = commandSettings.LogFile;
}

// Execute the engine manager and dispose it when done
using (EngineManager engineManager =
new EngineManager(
commandContext,
engineCommandSettings,
EngineSettings,
ConfigurationRoot,
ServiceCollection,
Bootstrapper))
{
return await ExecuteEngineAsync(commandContext, commandSettings, engineManager);
}
}

protected abstract Task<int> ExecuteEngineAsync(CommandContext commandContext, TSettings commandSettings, IEngineManager engineManager);
}
}
Loading

0 comments on commit b94d0dc

Please sign in to comment.