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

Replace .editorconfig with DotnetConfig in code base #127

Merged
merged 2 commits into from
May 19, 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
67 changes: 37 additions & 30 deletions Sources/Kysect.Configuin.CodeStyleDoc/CodeStyleGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using Kysect.CommonLib.Collections.Extensions;
using Kysect.CommonLib.BaseTypes.Extensions;
using Kysect.CommonLib.Collections.Extensions;
using Kysect.Configuin.CodeStyleDoc.Models;
using Kysect.Configuin.Common;
using Kysect.Configuin.EditorConfig;
using Kysect.Configuin.EditorConfig.Settings;
using Kysect.Configuin.DotnetConfig.Syntax;
using Kysect.Configuin.DotnetConfig.Syntax.Nodes;
using Kysect.Configuin.RoslynModels;
using Microsoft.Extensions.Logging;
using System.Collections.Immutable;

namespace Kysect.Configuin.CodeStyleDoc;

Expand All @@ -17,34 +19,34 @@ public CodeStyleGenerator(ILogger logger)
_logger = logger;
}

public CodeStyle Generate(DotnetConfigSettings dotnetConfigSettings, RoslynRules roslynRules)
public CodeStyle Generate(DotnetConfigDocument dotnetConfigDocument, RoslynRules roslynRules)
{
ArgumentNullException.ThrowIfNull(dotnetConfigSettings);
ArgumentNullException.ThrowIfNull(roslynRules);
dotnetConfigDocument.ThrowIfNull();
roslynRules.ThrowIfNull();

_logger.LogInformation("Start code style generating.");

IReadOnlyCollection<RoslynStyleRuleOption> roslynRuleOptions = roslynRules.GetOptions();
IReadOnlyCollection<IEditorConfigSetting> notProcessedSettings = dotnetConfigSettings.Settings;
IReadOnlyCollection<IDotnetConfigSyntaxNode> notProcessedSettings = dotnetConfigDocument.DescendantNodes();

_logger.LogInformation("Try parse {count} settings", notProcessedSettings.Count);
notProcessedSettings = notProcessedSettings.Where(IsSupported).ToList();
notProcessedSettings = notProcessedSettings.Where(IsSupported).ToImmutableList();

IReadOnlyCollection<CodeStyleRoslynOptionConfiguration> optionConfigurations = notProcessedSettings
.OfType<RoslynOptionEditorConfigSetting>()
.OfType<DotnetConfigRuleOptionNode>()
.Select(o => ParseOptionSettings(o, roslynRuleOptions))
.ToList();
_logger.LogInformation("Parsed {count} option configurations", optionConfigurations.Count);

notProcessedSettings = notProcessedSettings.Where(r => r is not RoslynOptionEditorConfigSetting).ToList();
notProcessedSettings = notProcessedSettings.Where(r => r is not DotnetConfigRuleOptionNode).ToImmutableList();

IReadOnlyCollection<ICodeStyleElement> ruleConfiguration = notProcessedSettings
.OfType<RoslynSeverityEditorConfigSetting>()
.OfType<DotnetConfigRuleSeverityNode>()
.Select(severitySetting => ParseRuleSettings(severitySetting, optionConfigurations, roslynRules))
.ToList();
_logger.LogInformation("Parsed {count} rule severity", ruleConfiguration.Count);

notProcessedSettings = notProcessedSettings.Where(r => r is not RoslynSeverityEditorConfigSetting).ToList();
notProcessedSettings = notProcessedSettings.Where(r => r is not DotnetConfigRuleSeverityNode).ToImmutableList();

if (notProcessedSettings.Any())
{
Expand All @@ -59,69 +61,74 @@ public CodeStyle Generate(DotnetConfigSettings dotnetConfigSettings, RoslynRules
return new CodeStyle(ruleConfiguration);
}

private bool IsSupported(IEditorConfigSetting setting)
private bool IsSupported(IDotnetConfigSyntaxNode setting)
{
if (setting is not IDotnetConfigPropertySyntaxNode)
{
return false;
}

// TODO: #35 support parsing for this rule
if (setting is RoslynSeverityEditorConfigSetting severityEditorConfigRule
if (setting is DotnetConfigRuleSeverityNode severityEditorConfigRule
&& severityEditorConfigRule.RuleId.Equals(RoslynRuleId.Parse("IDE1006")))
{
_logger.LogWarning("Rule IDE0055 is not supported and will be skipped.");
_logger.LogWarning("Rule IDE1006 is not supported and will be skipped.");
return false;
}

// TODO: #35 Probably, most of this rules related to IDE1006
if (setting is CompositeRoslynOptionEditorConfigSetting compositeSetting)
if (setting is DotnetConfigRuleCompositeOptionNode compositeSetting)
{
_logger.LogWarning("{setting} is not supported and will be skipped.", compositeSetting.ToDisplayString());
_logger.LogWarning("{setting} is not supported and will be skipped.", compositeSetting.ToFullString());
return false;
}

// TODO: Maybe we need to support it in some way
if (setting is GeneralEditorConfigSetting generalSetting)
if (setting is DotnetConfigGeneralOptionNode generalSetting)
{
_logger.LogWarning("{option} is not supported and will be skipped.", generalSetting.ToDisplayString());
_logger.LogWarning("{option} is not supported and will be skipped.", generalSetting.ToFullString());
return false;
}

return true;
}

private CodeStyleRoslynOptionConfiguration ParseOptionSettings(RoslynOptionEditorConfigSetting optionEditorConfigSetting, IReadOnlyCollection<RoslynStyleRuleOption> styleRuleOptions)
private CodeStyleRoslynOptionConfiguration ParseOptionSettings(DotnetConfigRuleOptionNode optionDotnetConfigSetting, IReadOnlyCollection<RoslynStyleRuleOption> styleRuleOptions)
{
RoslynStyleRuleOption? roslynStyleRuleOption = styleRuleOptions.SingleOrDefault(o => o.Name == optionEditorConfigSetting.Key);
RoslynStyleRuleOption? roslynStyleRuleOption = styleRuleOptions.SingleOrDefault(o => o.Name == optionDotnetConfigSetting.Key);

if (roslynStyleRuleOption is null)
throw new ConfiguinException($"Option {optionEditorConfigSetting.Key} was not found in documentation");
throw new ConfiguinException($"Option {optionDotnetConfigSetting.Key} was not found in documentation");

return new CodeStyleRoslynOptionConfiguration(roslynStyleRuleOption, optionEditorConfigSetting.Value);
return new CodeStyleRoslynOptionConfiguration(roslynStyleRuleOption, optionDotnetConfigSetting.Value);
}

private ICodeStyleElement ParseRuleSettings(
RoslynSeverityEditorConfigSetting severityEditorConfigSetting,
DotnetConfigRuleSeverityNode severityDotnetConfigSetting,
IReadOnlyCollection<CodeStyleRoslynOptionConfiguration> optionConfigurations,
RoslynRules roslynRules)
{
RoslynStyleRuleGroup? ruleGroup = roslynRules.StyleRuleGroups.SingleOrDefault(g => g.Rules.Any(r => r.RuleId.Equals(severityEditorConfigSetting.RuleId)));
RoslynStyleRuleGroup? ruleGroup = roslynRules.StyleRuleGroups.SingleOrDefault(g => g.Rules.Any(r => r.RuleId.Equals(severityDotnetConfigSetting.RuleId)));

if (ruleGroup is not null)
{
RoslynStyleRule rule = ruleGroup.Rules.Single(r => r.RuleId.Equals(severityEditorConfigSetting.RuleId));
RoslynStyleRule rule = ruleGroup.Rules.Single(r => r.RuleId.Equals(severityDotnetConfigSetting.RuleId));
var options = ruleGroup
.Options
.Select(o => FindOptionConfiguration(optionConfigurations, o.Name))
.WhereNotNull()
.ToList();

return new CodeStyleRoslynStyleRuleConfiguration(rule, severityEditorConfigSetting.Severity, options, ruleGroup.Overview, ruleGroup.Example);
return new CodeStyleRoslynStyleRuleConfiguration(rule, severityDotnetConfigSetting.ParseSeverity(), options, ruleGroup.Overview, ruleGroup.Example);
}

RoslynQualityRule? roslynQualityRule = roslynRules.QualityRules.FirstOrDefault(q => q.RuleId.Equals(severityEditorConfigSetting.RuleId));
RoslynQualityRule? roslynQualityRule = roslynRules.QualityRules.FirstOrDefault(q => q.RuleId.Equals(severityDotnetConfigSetting.RuleId));
if (roslynQualityRule is not null)
{
return new CodeStyleRoslynQualityRuleConfiguration(roslynQualityRule, severityEditorConfigSetting.Severity);
return new CodeStyleRoslynQualityRuleConfiguration(roslynQualityRule, severityDotnetConfigSetting.ParseSeverity());
}

throw new ConfiguinException($"Rule with id {severityEditorConfigSetting.RuleId} was not found");
throw new ConfiguinException($"Rule with id {severityDotnetConfigSetting.RuleId} was not found");
}

private CodeStyleRoslynOptionConfiguration? FindOptionConfiguration(
Expand Down
4 changes: 2 additions & 2 deletions Sources/Kysect.Configuin.CodeStyleDoc/ICodeStyleGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
using Kysect.Configuin.CodeStyleDoc.Models;
using Kysect.Configuin.EditorConfig;
using Kysect.Configuin.DotnetConfig.Syntax.Nodes;
using Kysect.Configuin.RoslynModels;

namespace Kysect.Configuin.CodeStyleDoc;

public interface ICodeStyleGenerator
{
CodeStyle Generate(DotnetConfigSettings dotnetConfigSettings, RoslynRules roslynRules);
CodeStyle Generate(DotnetConfigDocument dotnetConfigDocument, RoslynRules roslynRules);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\Kysect.Configuin.EditorConfig\Kysect.Configuin.EditorConfig.csproj" />
<ProjectReference Include="..\Kysect.Configuin.DotnetConfig\Kysect.Configuin.DotnetConfig.csproj" />
<ProjectReference Include="..\Kysect.Configuin.RoslynModels\Kysect.Configuin.RoslynModels.csproj" />
</ItemGroup>
</Project>
14 changes: 6 additions & 8 deletions Sources/Kysect.Configuin.ConfigurationRoot/DependencyBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
using Kysect.Configuin.CodeStyleDoc;
using Kysect.Configuin.CodeStyleDoc.Markdown;
using Kysect.Configuin.DotnetConfig.Formatter;
using Kysect.Configuin.DotnetConfig.Syntax;
using Kysect.Configuin.DotnetConfig.Template;
using Kysect.Configuin.DotnetFormatIntegration;
using Kysect.Configuin.DotnetFormatIntegration.Abstractions;
using Kysect.Configuin.DotnetFormatIntegration.Cli;
using Kysect.Configuin.DotnetFormatIntegration.FileSystem;
using Kysect.Configuin.EditorConfig;
using Kysect.Configuin.EditorConfig.DocumentModel;
using Kysect.Configuin.EditorConfig.Formatter;
using Kysect.Configuin.EditorConfig.Template;
using Kysect.Configuin.Learn;
using Kysect.Configuin.Learn.Abstraction;
using Kysect.Configuin.Markdown.TextExtractor;
Expand All @@ -34,7 +33,6 @@ public static IServiceCollection InitializeServiceProvider()

serviceCollection.AddSingleton<IDotnetFormatPreviewGenerator, DotnetFormatPreviewGenerator>();

serviceCollection.AddSingleton<IDotnetConfigSettingsParser, DotnetConfigSettingsParser>();
serviceCollection.AddSingleton<IRoslynRuleDocumentationParser, LearnDocumentationParser>();
serviceCollection.AddSingleton<IMarkdownTextExtractor>(PlainTextExtractor.Create());
serviceCollection.AddSingleton<ICodeStyleGenerator, CodeStyleGenerator>();
Expand All @@ -44,9 +42,9 @@ public static IServiceCollection InitializeServiceProvider()
serviceCollection.AddSingleton<TemporaryFileMover>();
serviceCollection.AddSingleton<DotnetFormatReportComparator>();
serviceCollection.AddSingleton<DotnetFormatPreviewGenerator>();
serviceCollection.AddSingleton<EditorConfigTemplateGenerator>();
serviceCollection.AddSingleton<EditorConfigDocumentParser>();
serviceCollection.AddSingleton<EditorConfigFormatter>();
serviceCollection.AddSingleton<DotnetConfigDocumentTemplateGenerator>();
serviceCollection.AddSingleton<DotnetConfigDocumentParser>();
serviceCollection.AddSingleton<DotnetConfigDocumentFormatter>();

return serviceCollection;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
<ProjectReference Include="..\Kysect.Configuin.CodeStyleDoc\Kysect.Configuin.CodeStyleDoc.csproj" />
<ProjectReference Include="..\Kysect.Configuin.Common\Kysect.Configuin.Common.csproj" />
<ProjectReference Include="..\Kysect.Configuin.DotnetFormatIntegration\Kysect.Configuin.DotnetFormatIntegration.csproj" />
<ProjectReference Include="..\Kysect.Configuin.EditorConfig\Kysect.Configuin.EditorConfig.csproj" />
<ProjectReference Include="..\Kysect.Configuin.Learn\Kysect.Configuin.Learn.csproj" />
<ProjectReference Include="..\Kysect.Configuin.Markdown\Kysect.Configuin.Markdown.csproj" />
<ProjectReference Include="..\Kysect.Configuin.RoslynModels\Kysect.Configuin.RoslynModels.csproj" />
Expand Down
8 changes: 4 additions & 4 deletions Sources/Kysect.Configuin.Console/CommandAppInitializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ public static CommandApp Initialize(IServiceCollection services)
app.Configure(config =>
{
config.AddCommand<GenerateCodeStyleDocCommand>("generate-styledoc");
config.AddCommand<EditorConfigApplyPreviewCommand>("preview");
config.AddCommand<AnalyzeEditorConfigCommand>("analyze");
config.AddCommand<GenerateEditorConfigTemplateTemplate>("template");
config.AddCommand<FormatEditorconfigCommand>("format");
config.AddCommand<PreviewDotnetConfigChangesCommand>("preview");
config.AddCommand<AnalyzeDotnetConfigCommand>("analyze");
config.AddCommand<GenerateDotnetConfigTemplateCommand>("template");
config.AddCommand<FormatDotnetConfigCommand>("format");
config.AddCommand<GenerateRoslynRuleDocumentationFile>("generate-roslyn-documentation");
});

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using Kysect.CommonLib.BaseTypes.Extensions;
using Kysect.Configuin.DotnetConfig.Analyzing;
using Kysect.Configuin.DotnetConfig.Syntax;
using Kysect.Configuin.DotnetConfig.Syntax.Nodes;
using Kysect.Configuin.Learn.Abstraction;
using Kysect.Configuin.RoslynModels;
using Microsoft.Extensions.Logging;
using Spectre.Console.Cli;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;

namespace Kysect.Configuin.Console.Commands;

internal sealed class AnalyzeDotnetConfigCommand(
IRoslynRuleDocumentationParser roslynRuleDocumentationParser,
DotnetConfigDocumentParser dotnetConfigDocumentParser,
ILogger logger
) : Command<AnalyzeDotnetConfigCommand.Settings>
{
public sealed class Settings : CommandSettings
{
[Description("Path to dotnet config file.")]
[CommandArgument(0, "[dotnet config path]")]
public string? DotnetConfigPath { get; init; }

[Description("Path to cloned MS Learn repository.")]
[CommandOption("-d|--documentation")]
public string? MsLearnRepositoryPath { get; init; }
}

public override int Execute([NotNull] CommandContext context, [NotNull] Settings settings)
{
settings.DotnetConfigPath.ThrowIfNull();

DotnetConfigDocumentAnalyzer dotnetConfigDocumentAnalyzer = new DotnetConfigDocumentAnalyzer();
IDotnetConfigAnalyzeReporter reporter = new DotnetConfigAnalyzeLogReporter(logger);

RoslynRules roslynRules = settings.MsLearnRepositoryPath is null
? RoslynRuleDocumentationCache.ReadFromCache()
: roslynRuleDocumentationParser.Parse(settings.MsLearnRepositoryPath);

string editorConfigContent = File.ReadAllText(settings.DotnetConfigPath);
DotnetConfigDocument dotnetConfigDocument = dotnetConfigDocumentParser.Parse(editorConfigContent);

DotnetConfigMissedConfiguration dotnetConfigMissedConfiguration = dotnetConfigDocumentAnalyzer.GetMissedConfigurations(dotnetConfigDocument, roslynRules);
IReadOnlyCollection<DotnetConfigInvalidOptionValue> incorrectOptionValues = dotnetConfigDocumentAnalyzer.GetIncorrectOptionValues(dotnetConfigDocument, roslynRules);
IReadOnlyCollection<RoslynRuleId> incorrectOptionSeverity = dotnetConfigDocumentAnalyzer.GetIncorrectOptionSeverity(dotnetConfigDocument, roslynRules);

reporter.ReportMissedConfigurations(dotnetConfigMissedConfiguration);
reporter.ReportIncorrectOptionValues(incorrectOptionValues);
reporter.ReportIncorrectOptionSeverity(incorrectOptionSeverity);

return 0;
}
}

This file was deleted.

Loading