Skip to content

Commit

Permalink
Adds dotnet component input (#105)
Browse files Browse the repository at this point in the history
Closes #99
  • Loading branch information
PascalSenn authored Jul 13, 2023
1 parent 4e9dfec commit 3ad821c
Show file tree
Hide file tree
Showing 44 changed files with 1,380 additions and 85 deletions.
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="7.0.0" />
<PackageVersion Include="Spectre.Console" Version="0.46.0" />
<PackageVersion Include="Spectre.Console.Json" Version="0.46.0" />
<PackageVersion Include="Spectre.Console.Testing" Version="0.47.0" />
<PackageVersion Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
</ItemGroup>
<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using System.Collections;
using Confix.Extensions;
using Confix.Tool.Abstractions;
using Confix.Tool.Abstractions.Configuration;

namespace Confix.Tool.Middlewares;

public sealed class ConfigurationFileCollection
: IConfigurationFileCollection
{
private readonly IReadOnlyList<JsonFile> _collection;

public ConfigurationFileCollection(
RuntimeConfiguration? configuration,
SolutionConfiguration? solutionConfiguration,
ProjectConfiguration? projectConfiguration,
ComponentConfiguration? componentConfiguration,
IReadOnlyList<JsonFile> collection)
{
RuntimeConfiguration = configuration;
Solution = solutionConfiguration;
Project = projectConfiguration;
Component = componentConfiguration;
_collection = collection;
}

public RuntimeConfiguration? RuntimeConfiguration { get; }

public SolutionConfiguration? Solution { get; }

public ProjectConfiguration? Project { get; }

public ComponentConfiguration? Component { get; }

/// <inheritdoc />
public IEnumerator<JsonFile> GetEnumerator()
=> _collection.GetEnumerator();

/// <inheritdoc />
IEnumerator IEnumerable.GetEnumerator()
=> GetEnumerator();

/// <inheritdoc />
public int Count => _collection.Count;

/// <inheritdoc />
public JsonFile this[int index] => _collection[index];
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Confix.Extensions;
using ConfiX.Extensions;
using Confix.Tool.Abstractions;
using Confix.Tool.Abstractions.Configuration;
Expand Down
8 changes: 7 additions & 1 deletion src/Confix.Tool/src/Confix.Tool/Common/Logging/App.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,11 @@ namespace Confix.Tool.Commands.Logging;

public static class App
{
public static IConsoleLogger Log { get; internal set; } = ConsoleLogger.NullLogger;
private static readonly AsyncLocal<IConsoleLogger> _log = new();

public static IConsoleLogger Log
{
get => _log.Value ?? ConsoleLogger.NullLogger;
set => _log.Value = value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,19 @@ public static class VerbosityCommandLineBuilderExtensions
{
public static CommandLineBuilder UseVerbosity(this CommandLineBuilder builder)
{
var verbosity = Verbosity.Normal;
builder.AddSingleton<IConsoleLogger>(sp =>
{
var console = sp.GetRequiredService<IAnsiConsole>();

return new ConsoleLogger(console, verbosity);
});
builder.AddMiddleware((context, next) =>
{
var verbosity =
verbosity =
context.ParseResult.GetValueForOption(VerbosityOption.Instance);

var console = context.BindingContext.GetRequiredService<IAnsiConsole>();

var logger = new ConsoleLogger(console, verbosity);

context.BindingContext.AddService(typeof(IConsoleLogger), _ => logger);

App.Log = logger;
App.Log = context.BindingContext.GetRequiredService<IConsoleLogger>();

return next(context);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ async Task<int> Execute(StatusContext ctx)
Parameter = ParameterCollection.From(_parameter),
Console = _services.GetRequiredService<IAnsiConsole>(),
Logger = _services.GetRequiredService<IConsoleLogger>(),
Execution = ExecutionContext.Create(),
Execution = _services.GetRequiredService<IExecutionContext>(),
Status = new SpectreStatusContext(ctx),
Services = _services
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using Confix.Tool.Schema;
using Confix.Utilities.Json;

namespace ConfiX.Extensions;
namespace Confix.Extensions;

public sealed class RuntimeConfiguration
{
Expand Down Expand Up @@ -60,9 +60,10 @@ public static RuntimeConfiguration Parse(JsonNode? node, IReadOnlyList<JsonFile>
? ProjectConfiguration.Parse(projectNode.ExpectObject())
: null;

var encryption = obj.TryGetNonNullPropertyValue(FieldNames.Encryption, out var encryptionNode)
? EncryptionConfiguration.Parse(encryptionNode.ExpectObject())
: null;
var encryption =
obj.TryGetNonNullPropertyValue(FieldNames.Encryption, out var encryptionNode)
? EncryptionConfiguration.Parse(encryptionNode.ExpectObject())
: null;

return new RuntimeConfiguration(
isRoot,
Expand Down Expand Up @@ -112,4 +113,4 @@ public static RuntimeConfiguration LoadFromFiles(IEnumerable<JsonFile> files)

return config;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public IReadOnlyList<ConfigurationFile> GetConfigurationFiles(IConfigurationFile
AppSettingsConfigurationFileProviderConfiguration.Parse(context.Definition.Value);

var input = context.Project.Directory!.FindInPath(FileNames.AppSettings, false);

if (input is null)
{
return Array.Empty<ConfigurationFile>();
Expand All @@ -31,18 +31,18 @@ public IReadOnlyList<ConfigurationFile> GetConfigurationFiles(IConfigurationFile

if (configuration.UseUserSecrets is true)
{
App.Log.UseUserSecrets();
context.Logger.UseUserSecrets();
var csproj = DotnetHelpers.FindProjectFileInPath(context.Project.Directory!);
if (csproj is not null)
{
var userSecretsId = DotnetHelpers.EnsureUserSecretsId(csproj);
var userSecretsFolder = GetUserSecretPath(userSecretsId);
output = new FileInfo(Path.Combine(userSecretsFolder.FullName, FileNames.Secrets));
App.Log.UseUserSecretsConfigurationFile(output);
context.Logger.UseUserSecretsConfigurationFile(output);
}
}

App.Log.FoundAAppSettingsConfigurationFile(input);
context.Logger.FoundAAppSettingsConfigurationFile(input);

files.Add(new ConfigurationFile { InputFile = input, OutputFile = output });

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public IReadOnlyList<ConfigurationFile> GetConfigurationFiles(IConfigurationFile

foreach (var file in context.Project.Directory!.FindAllInPath(path, false))
{
App.Log.FoundAInlineConfigurationFile(file);
context.Logger.FoundAInlineConfigurationFile(file);

files.Add(new ConfigurationFile { InputFile = file, OutputFile = file });
}
Expand Down
5 changes: 4 additions & 1 deletion src/Confix.Tool/src/Confix.Tool/ConfixCommandLine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
using ConfiX.Entities.Schema.Extensions;
using Confix.Tool.Abstractions;
using Confix.Tool.Commands.Logging;
using Confix.Tool.Common.Pipelines;
using Confix.Tool.Middlewares;
using ExecutionContext = Confix.Tool.Common.Pipelines.ExecutionContext;

namespace Confix.Tool;

internal sealed class ConfixCommandLine : CommandLineBuilder
public sealed class ConfixCommandLine : CommandLineBuilder
{
public ConfixCommandLine() : base(new ConfixRootCommand())
{
Expand All @@ -17,6 +19,7 @@ public ConfixCommandLine() : base(new ConfixRootCommand())
.RegisterMiddlewares()
.AddSingleton(DefaultConsole.Create())
.AddSingleton<IServiceProvider>(sp => sp)
.AddSingleton<IExecutionContext>(_ => ExecutionContext.Create())
.UseDefaults()
.UseVerbosity()
.AddExceptionHandler();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public static CommandLineBuilder RegisterComponentInputs(this CommandLineBuilder
sp.GetRequiredService<IComponentInputFactory>()));

builder.AddComponentInput<GraphQlComponentInput>();
builder.AddComponentInput<DotnetComponentInput>();

return builder;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using Confix.Tool.Commands.Logging;
using Confix.Tool.Commands.Temp;
using Confix.Tool.Common.Pipelines;
using Confix.Tool.Middlewares;
using Confix.Tool.Schema;
using Confix.Utilities.FileSystem;

namespace Confix.Tool.Entities.Components;

public sealed class DotnetComponentInput : IComponentInput
{
private const string _embeddedResourcePath =
$"$(MSBuildProjectDirectory)/{FolderNames.Components}/**/*.*";

public static string Type => "dotnet";

/// <inheritdoc />
public async Task ExecuteAsync(IMiddlewareContext context)
{
var configuration = context.Features.Get<ConfigurationFeature>();

if (configuration.Scope is not ConfigurationScope.Component ||
configuration.ConfigurationFiles.Component is null)
{
throw new ExitException("Component input has to be executed in a component directory");
}

if (configuration.Project?.Directory is not { } projectDirectory)
{
context.Logger.DotnetComponentProviderNeedsToBeRunInsideAConfixProject();
return;
}

var csproj = DotnetHelpers.FindProjectFileInPath(projectDirectory);

if (csproj is null)
{
context.Logger.ProjectNotFoundInDirectory(projectDirectory);
context.Logger.DotnetProjectWasNotDetected();
return;
}

context.Logger.FoundDotnetProject(csproj);

try
{
DotnetHelpers.EnsureEmbeddedResource(csproj, _embeddedResourcePath);
}
catch
{
context.Logger.CouldNotParseProjectFile(csproj);
}
}
}

file static class Log
{
public static void DotnetComponentProviderNeedsToBeRunInsideAConfixProject(
this IConsoleLogger console)
{
console.Error(
"Dotnet component provider needs to be run inside a confix project. No project was found");
}

public static void ProjectNotFoundInDirectory(
this IConsoleLogger logger,
DirectoryInfo directory)
{
logger.Debug($"Could not find project in directory: {directory}");
}

public static void DotnetProjectWasNotDetected(this IConsoleLogger logger)
{
logger.Information("Dotnet project was not detected. Skipping dotnet component input");
}

public static void FoundDotnetProject(this IConsoleLogger logger, FileSystemInfo csproj)
{
logger.Information($"Found .NET project:{csproj.ToLink()} [dim]{csproj.FullName}[/]");
}

public static void CouldNotParseProjectFile(this IConsoleLogger logger, FileSystemInfo csproj)
{
logger.Error($"Could not parse project file: {csproj.ToLink()} [dim]{csproj.FullName}[/]");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public async Task ExecuteAsync(IMiddlewareContext context)

if (schemaJsonFile.Exists)
{
context.Logger.ReplacingExistingSchemaJsonFile(schemaJsonFile);
schemaJsonFile.Delete();
}

Expand Down Expand Up @@ -99,4 +100,13 @@ public static void GeneratedSchemaBasedOnGraphQL(
schemaFile.ToLink(),
schemaFile.FullName);
}

public static void ReplacingExistingSchemaJsonFile(
this IConsoleLogger console,
FileSystemInfo schemaFile)
{
console.Debug("Replacing existing schema.json file: {0} [dim]{1}[/]",
schemaFile.ToLink(),
schemaFile.FullName);
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
namespace Confix.Tool.Abstractions;

public record EncryptionDefinition(
EncryptionProviderDefinition Provider
)
public record EncryptionDefinition(EncryptionProviderDefinition Provider)
{
public static EncryptionDefinition From(EncryptionConfiguration configuration)
{
if (configuration.Provider is null)
{
throw new ValidationException("Encryption configuration is invalid.")
{
Errors = new[]{"Provider is required."}
Errors = new[] { "Provider is required." }
};
}

var provider = EncryptionProviderDefinition.From(configuration.Provider!);

return new EncryptionDefinition(provider);
}
};
};
Loading

0 comments on commit 3ad821c

Please sign in to comment.