From f1d4fcf4d18cd2b21e31ede858cf2c80654f0428 Mon Sep 17 00:00:00 2001 From: just-seba <46223600+just-seba@users.noreply.github.com> Date: Sat, 2 Mar 2024 13:14:47 +0100 Subject: [PATCH 01/10] refactor: `PaddingCleaner` uses `GeneratedRegexAttribute`. --- .../Padding/PaddingCleaner.cs | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/CodeButler/CodeButler.Console/Padding/PaddingCleaner.cs b/src/CodeButler/CodeButler.Console/Padding/PaddingCleaner.cs index 3f357ac..da4a49b 100644 --- a/src/CodeButler/CodeButler.Console/Padding/PaddingCleaner.cs +++ b/src/CodeButler/CodeButler.Console/Padding/PaddingCleaner.cs @@ -1,18 +1,22 @@ -using System.Linq; -using System.Text.RegularExpressions; +using System.Text.RegularExpressions; -namespace CodeButler.Padding +namespace CodeButler.Padding; + +public partial class PaddingCleaner { - public class PaddingCleaner - { - private static readonly Regex _dirtyNewLine = new Regex(@"[\t ]+(\r\n|\n)", RegexOptions.Multiline); - private static readonly Regex _multiEmptyLine = new Regex(@"^(\r\n|\n)+", RegexOptions.Multiline); + private static readonly Regex _dirtyNewLine = GenerateDirtyNewLineRegex(); + private static readonly Regex _multiEmptyLine = GenerateMultiEmptyLineRegex(); - public string Clean(string input) - { - string output = _dirtyNewLine.Replace(input, match => match.Groups.Values.Last().Value); - output = _multiEmptyLine.Replace(output, match => match.Groups.Values.Last().Value); - return output; - } + public virtual string Clean(string input) + { + string output = _dirtyNewLine.Replace(input, match => match.Groups[^1].Value); + output = _multiEmptyLine.Replace(output, match => match.Groups[^1].Value); + return output; } -} \ No newline at end of file + + [GeneratedRegex(@"[\t ]+(\r\n|\n)", RegexOptions.Multiline)] + private static partial Regex GenerateDirtyNewLineRegex(); + + [GeneratedRegex(@"^(\r\n|\n)+", RegexOptions.Multiline)] + private static partial Regex GenerateMultiEmptyLineRegex(); +} From 095e7be3df14ef7e726849f50b467a8326592719 Mon Sep 17 00:00:00 2001 From: just-seba <46223600+just-seba@users.noreply.github.com> Date: Sat, 2 Mar 2024 13:19:26 +0100 Subject: [PATCH 02/10] feat: Command line flag `--no-sort-member-by-alphabet` to disable sorting members by alphabet. --- src/CodeButler/.editorconfig | 9 + .../CodeButler.Console.csproj | 3 +- src/CodeButler/CodeButler.Console/Mode.cs | 13 +- src/CodeButler/CodeButler.Console/Program.cs | 100 +++------ .../Properties/launchSettings.json | 1 - .../Reorganizing/MemberInfo.cs | 51 +++++ .../Reorganizing/MemberInfoComparer.cs | 82 ++++++++ .../MemberInfoSortConfiguration.cs | 6 + .../Reorganizing/MemberOrderInfo.cs | 110 ---------- .../Reorganizing/UsingOrderInfo.cs | 9 +- .../CodeButler.Console/RootCommand.cs | 95 +++++++++ .../RootCommandConfiguration.cs | 12 ++ .../RootCommandConfigurationBinder.cs | 48 +++++ .../Syntax/MemberInfoFactory.cs | 165 +++++++++++++++ .../Syntax/MemberOrderInfoExtensions.cs | 160 -------------- .../Syntax/MembersOrganizerExtensions.cs | 20 +- .../Syntax/SyntaxListExtensions.cs | 9 +- .../Syntax/SyntaxReorganizerRewriter.cs | 25 ++- .../Syntax/UsingOrderInfoExtensions.cs | 5 +- .../CodeButler.IntegrationTests.csproj | 2 +- .../IntegrationTests.cs | 51 +++-- .../CodeButler.UnitTests.csproj | 3 +- .../Reorganizing/MemberInfoComparerTest.cs | 196 ++++++++++++++++++ .../Reorganizing/MemberOrderInfoTest.cs | 134 ------------ 24 files changed, 779 insertions(+), 530 deletions(-) create mode 100644 src/CodeButler/CodeButler.Console/Reorganizing/MemberInfo.cs create mode 100644 src/CodeButler/CodeButler.Console/Reorganizing/MemberInfoComparer.cs create mode 100644 src/CodeButler/CodeButler.Console/Reorganizing/MemberInfoSortConfiguration.cs delete mode 100644 src/CodeButler/CodeButler.Console/Reorganizing/MemberOrderInfo.cs create mode 100644 src/CodeButler/CodeButler.Console/RootCommand.cs create mode 100644 src/CodeButler/CodeButler.Console/RootCommandConfiguration.cs create mode 100644 src/CodeButler/CodeButler.Console/RootCommandConfigurationBinder.cs create mode 100644 src/CodeButler/CodeButler.Console/Syntax/MemberInfoFactory.cs delete mode 100644 src/CodeButler/CodeButler.Console/Syntax/MemberOrderInfoExtensions.cs create mode 100644 src/CodeButler/tests/CodeButler.UnitTests/Reorganizing/MemberInfoComparerTest.cs delete mode 100644 src/CodeButler/tests/CodeButler.UnitTests/Reorganizing/MemberOrderInfoTest.cs diff --git a/src/CodeButler/.editorconfig b/src/CodeButler/.editorconfig index 94b46a3..d6255c2 100644 --- a/src/CodeButler/.editorconfig +++ b/src/CodeButler/.editorconfig @@ -29,9 +29,18 @@ dotnet_diagnostic.IDE0072.severity = suggestion # SA0001: XML comment analysis is disabled due to project configuration dotnet_diagnostic.SA0001.severity = none +# SA1000: The keyword 'new' should be followed by a space +dotnet_diagnostic.SA1000.severity = none + +# SA1009: Closing parenthesis must be spaced correctly +dotnet_diagnostic.SA1009.severity = silent + # SA1101: Prefix local calls with this dotnet_diagnostic.SA1101.severity = none +# SA1111: Closing parenthesis must be on line of last parameter +dotnet_diagnostic.SA1111.severity = silent + # SA1123: Region should not be located within a code element dotnet_diagnostic.SA1123.severity = suggestion diff --git a/src/CodeButler/CodeButler.Console/CodeButler.Console.csproj b/src/CodeButler/CodeButler.Console/CodeButler.Console.csproj index 8e8cd6f..160f7d3 100644 --- a/src/CodeButler/CodeButler.Console/CodeButler.Console.csproj +++ b/src/CodeButler/CodeButler.Console/CodeButler.Console.csproj @@ -2,7 +2,7 @@ Exe - net6.0 + net8.0 CodeButler enable true @@ -16,5 +16,6 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + \ No newline at end of file diff --git a/src/CodeButler/CodeButler.Console/Mode.cs b/src/CodeButler/CodeButler.Console/Mode.cs index b4122dd..5d651cb 100644 --- a/src/CodeButler/CodeButler.Console/Mode.cs +++ b/src/CodeButler/CodeButler.Console/Mode.cs @@ -1,8 +1,7 @@ -namespace CodeButler +namespace CodeButler; + +public enum Mode { - internal enum Mode - { - Console, - File, - } -} \ No newline at end of file + Console, + File, +} diff --git a/src/CodeButler/CodeButler.Console/Program.cs b/src/CodeButler/CodeButler.Console/Program.cs index c872e3f..7249864 100644 --- a/src/CodeButler/CodeButler.Console/Program.cs +++ b/src/CodeButler/CodeButler.Console/Program.cs @@ -1,11 +1,7 @@ using System; +using System.CommandLine; using System.IO; using System.Threading.Tasks; -using CodeButler.Padding; -using CodeButler.Syntax; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; namespace CodeButler { @@ -13,76 +9,36 @@ public class Program { public static async Task Main(string[] args) { - Mode mode; - if (Console.IsInputRedirected) + var rootCommand = new RootCommand( + "Reorganises, sorts and cleans up the provided C# file." + ); + + var noSortMemberByAlphabetOption = new Option( + name: "--no-sort-member-by-alphabet", + description: "Disables sorting members by alphabet.", + getDefaultValue: () => false + ); + + var inputFileArg = Console.IsInputRedirected + ? null + : new Argument( + name: "Input", + description: "Path to input file or piped input." + ); + + rootCommand.AddOption(noSortMemberByAlphabetOption); + if (inputFileArg is not null) { - mode = Mode.Console; + rootCommand.AddArgument(inputFileArg); } - else if (args.Length > 0) - { - mode = Mode.File; - } - else - { - Console.Error.WriteLine("No input provided."); - return -1; - } - - string input = await GetInput(mode, args).ConfigureAwait(false); - CompilationUnitSyntax root = Parse(input); - var organizedRoot = Reorganize(root); - - await SetOutput(organizedRoot, mode, args).ConfigureAwait(false); - return 0; - } - - public static CompilationUnitSyntax Parse(string input) - { - var paddingCleaner = new PaddingCleaner(); - string cleanInput = paddingCleaner.Clean(input); - SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(cleanInput); - CompilationUnitSyntax root = syntaxTree.GetCompilationUnitRoot(); - return root; - } - - public static CompilationUnitSyntax Reorganize(CompilationUnitSyntax compilationUnit) - { - return compilationUnit.Reorganize(); - } - - private static async Task GetInput(Mode mode, string[] args) - { - switch (mode) - { - case Mode.Console: - using (var reader = new StreamReader(Console.OpenStandardInput(), Console.InputEncoding)) - { - return await reader.ReadToEndAsync().ConfigureAwait(false); - } - - case Mode.File: - return await File.ReadAllTextAsync(args[0]).ConfigureAwait(false); - - default: - throw new NotImplementedException($"Mode \"{mode}\" not implemented."); - } - } - - private static async Task SetOutput(CompilationUnitSyntax compilationUnit, Mode mode, string[] args) - { - switch (mode) - { - case Mode.Console: - Console.Write(compilationUnit.ToFullString()); - break; - case Mode.File: - await File.WriteAllTextAsync(args[0], compilationUnit.ToFullString()).ConfigureAwait(false); - break; + rootCommand.SetHandler( + RootCommandHandler.Handle, + new RootCommandConfigurationBinder(noSortMemberByAlphabetOption, inputFileArg) + ); - default: - throw new NotImplementedException($"Mode \"{mode}\" not implemented."); - } + var exitCode = await rootCommand.InvokeAsync(args); + return exitCode; } } -} \ No newline at end of file +} diff --git a/src/CodeButler/CodeButler.Console/Properties/launchSettings.json b/src/CodeButler/CodeButler.Console/Properties/launchSettings.json index cbbe867..6fa6939 100644 --- a/src/CodeButler/CodeButler.Console/Properties/launchSettings.json +++ b/src/CodeButler/CodeButler.Console/Properties/launchSettings.json @@ -2,7 +2,6 @@ "profiles": { "CodeButler.Console": { "commandName": "Project", - "commandLineArgs": "TypeDefaultOrder.cs" } } } \ No newline at end of file diff --git a/src/CodeButler/CodeButler.Console/Reorganizing/MemberInfo.cs b/src/CodeButler/CodeButler.Console/Reorganizing/MemberInfo.cs new file mode 100644 index 0000000..7c2e1fa --- /dev/null +++ b/src/CodeButler/CodeButler.Console/Reorganizing/MemberInfo.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; + +namespace CodeButler.Reorganizing; + +public class MemberInfo : IEquatable +{ + public MemberInfo() + { + AccessModifier = MemberAccessModifier.None; + AdditionalModifier = MemberAdditionalModifier.None; + MemberType = MemberType.None; + } + + public MemberAccessModifier AccessModifier { get; init; } + + public MemberAdditionalModifier AdditionalModifier { get; init; } + + public string? Identifier { get; init; } + + public MemberType MemberType { get; init; } + + public static bool operator !=(MemberInfo? left, MemberInfo? right) + { + return !(left == right); + } + + public static bool operator ==(MemberInfo? left, MemberInfo? right) + { + return EqualityComparer.Default.Equals(left, right); + } + + public override bool Equals(object? obj) + { + return Equals(obj as MemberInfo); + } + + public bool Equals(MemberInfo? other) + { + return other != null + && MemberType == other.MemberType + && Identifier == other.Identifier + && AccessModifier == other.AccessModifier + && AdditionalModifier == other.AdditionalModifier; + } + + public override int GetHashCode() + { + return HashCode.Combine(MemberType, Identifier, AccessModifier, AdditionalModifier); + } +} diff --git a/src/CodeButler/CodeButler.Console/Reorganizing/MemberInfoComparer.cs b/src/CodeButler/CodeButler.Console/Reorganizing/MemberInfoComparer.cs new file mode 100644 index 0000000..a4807c7 --- /dev/null +++ b/src/CodeButler/CodeButler.Console/Reorganizing/MemberInfoComparer.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace CodeButler.Reorganizing; + +public class MemberInfoComparer : IComparer +{ + private readonly MemberSortConfiguration _configuration; + private readonly Func[] _compareMethods; + + public MemberInfoComparer(MemberSortConfiguration configuration) + { + _configuration = configuration; + _compareMethods = + [ + CompareByMemberType, + CompareByAccessModifier, + CompareByAdditionalModifier, + CompareByIdentifier, + ]; + } + + public static MemberInfoComparer Default { get; } = + new MemberInfoComparer(new MemberSortConfiguration()); + + public int Compare(MemberInfo? x, MemberInfo? y) + { + return _compareMethods + .Select(compareMethod => compareMethod(x, y)) + .FirstOrDefault(result => result != 0); + } + + private int CompareByAccessModifier(MemberInfo? x, MemberInfo? y) + { + return (x, y) switch + { + (null, null) => 0, + (null, _) => -1, + (_, null) => 1, + _ => x.AccessModifier - y.AccessModifier, + }; + } + + private int CompareByAdditionalModifier(MemberInfo? x, MemberInfo? y) + { + return (x, y) switch + { + (null, null) => 0, + (null, _) => -1, + (_, null) => 1, + _ => x.AdditionalModifier - y.AdditionalModifier, + }; + } + + private int CompareByIdentifier(MemberInfo? x, MemberInfo? y) + { + if (!_configuration.SortByAlphabet) + { + return 0; + } + + return (x, y) switch + { + (null, null) => 0, + (null, _) => -1, + (_, null) => 1, + _ => string.Compare(x.Identifier, y.Identifier, StringComparison.Ordinal), + }; + } + + private int CompareByMemberType(MemberInfo? x, MemberInfo? y) + { + return (x, y) switch + { + (null, null) => 0, + (null, _) => -1, + (_, null) => 1, + _ => x.MemberType - y.MemberType, + }; + } +} diff --git a/src/CodeButler/CodeButler.Console/Reorganizing/MemberInfoSortConfiguration.cs b/src/CodeButler/CodeButler.Console/Reorganizing/MemberInfoSortConfiguration.cs new file mode 100644 index 0000000..c3818ec --- /dev/null +++ b/src/CodeButler/CodeButler.Console/Reorganizing/MemberInfoSortConfiguration.cs @@ -0,0 +1,6 @@ +namespace CodeButler.Reorganizing; + +public class MemberSortConfiguration +{ + public bool SortByAlphabet { get; init; } = true; +} diff --git a/src/CodeButler/CodeButler.Console/Reorganizing/MemberOrderInfo.cs b/src/CodeButler/CodeButler.Console/Reorganizing/MemberOrderInfo.cs deleted file mode 100644 index 43ee449..0000000 --- a/src/CodeButler/CodeButler.Console/Reorganizing/MemberOrderInfo.cs +++ /dev/null @@ -1,110 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace CodeButler.Reorganizing -{ - public class MemberOrderInfo : IComparable, IEquatable - { - private readonly Func[] _compareMethods; - - public MemberOrderInfo() - { - AccessModifier = MemberAccessModifier.None; - AdditionalModifier = MemberAdditionalModifier.None; - MemberType = MemberType.None; - - _compareMethods = new Func[] - { - CompareByMemberType, - CompareByAccessModifier, - CompareByAdditionalModifier, - CompareByIdentifier, - }; - } - - public MemberAccessModifier AccessModifier { get; set; } - - public MemberAdditionalModifier AdditionalModifier { get; set; } - - public string? Identifier { get; set; } - - public MemberType MemberType { get; set; } - - public static bool operator !=(MemberOrderInfo? left, MemberOrderInfo? right) - { - return !(left == right); - } - - public static bool operator <(MemberOrderInfo left, MemberOrderInfo right) - { - return left is null ? right is not null : left.CompareTo(right) < 0; - } - - public static bool operator <=(MemberOrderInfo left, MemberOrderInfo right) - { - return left is null || left.CompareTo(right) <= 0; - } - - public static bool operator ==(MemberOrderInfo? left, MemberOrderInfo? right) - { - return EqualityComparer.Default.Equals(left, right); - } - - public static bool operator >(MemberOrderInfo left, MemberOrderInfo right) - { - return left is not null && left.CompareTo(right) > 0; - } - - public static bool operator >=(MemberOrderInfo left, MemberOrderInfo right) - { - return left is null ? right is null : left.CompareTo(right) >= 0; - } - - public int CompareByAccessModifier(MemberOrderInfo? other) - { - return other is null ? -1 : AccessModifier - other.AccessModifier; - } - - public int CompareByAdditionalModifier(MemberOrderInfo? other) - { - return other is null ? -1 : AdditionalModifier - other.AdditionalModifier; - } - - public int CompareByIdentifier(MemberOrderInfo? other) - { - return (other is null) ? -1 : string.Compare(Identifier, other.Identifier, StringComparison.Ordinal); - } - - public int CompareByMemberType(MemberOrderInfo? other) - { - return other is null ? -1 : MemberType - other.MemberType; - } - - public int CompareTo(MemberOrderInfo? other) - { - return _compareMethods - .Select(compareMethod => compareMethod(other)) - .FirstOrDefault(result => result != 0); - } - - public override bool Equals(object? obj) - { - return Equals(obj as MemberOrderInfo); - } - - public bool Equals(MemberOrderInfo? other) - { - return other != null && - MemberType == other.MemberType && - Identifier == other.Identifier && - AccessModifier == other.AccessModifier && - AdditionalModifier == other.AdditionalModifier; - } - - public override int GetHashCode() - { - return HashCode.Combine(MemberType, Identifier, AccessModifier, AdditionalModifier); - } - } -} \ No newline at end of file diff --git a/src/CodeButler/CodeButler.Console/Reorganizing/UsingOrderInfo.cs b/src/CodeButler/CodeButler.Console/Reorganizing/UsingOrderInfo.cs index 76bb41d..a44df61 100644 --- a/src/CodeButler/CodeButler.Console/Reorganizing/UsingOrderInfo.cs +++ b/src/CodeButler/CodeButler.Console/Reorganizing/UsingOrderInfo.cs @@ -118,8 +118,8 @@ public int CompareByName(UsingOrderInfo? other) public int CompareTo(UsingOrderInfo? other) { return _compareMethods - .Select(compareMethod => compareMethod(other)) - .FirstOrDefault(result => result != 0); + .Select(compareMethod => compareMethod(other)) + .FirstOrDefault(result => result != 0); } public override bool Equals(object? obj) @@ -129,8 +129,7 @@ public override bool Equals(object? obj) public bool Equals(UsingOrderInfo? other) { - return other != null && - Name == other.Name; + return other != null && Name == other.Name; } public override int GetHashCode() @@ -169,4 +168,4 @@ private static bool IsSystemUsing(UsingOrderInfo usingOrderInfo) return usingOrderInfo.Name.StartsWith(_systemUsing, StringComparison.Ordinal); } } -} \ No newline at end of file +} diff --git a/src/CodeButler/CodeButler.Console/RootCommand.cs b/src/CodeButler/CodeButler.Console/RootCommand.cs new file mode 100644 index 0000000..f353b16 --- /dev/null +++ b/src/CodeButler/CodeButler.Console/RootCommand.cs @@ -0,0 +1,95 @@ +using System; +using System.CommandLine; +using System.IO; +using System.Threading.Tasks; +using CodeButler.Padding; +using CodeButler.Reorganizing; +using CodeButler.Syntax; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; + +namespace CodeButler; + +public class RootCommandHandler +{ + public static async Task Handle(RootCommandConfiguration configuration) + { + var input = await GetInput(configuration).ConfigureAwait(false); + CompilationUnitSyntax root = Parse(input); + var organizedRoot = Reorganize( + root, + new MemberSortConfiguration { SortByAlphabet = configuration.SortMemberByAlphabet } + ); + + await SetOutput(organizedRoot, configuration).ConfigureAwait(false); + } + + public static CompilationUnitSyntax Parse(string input) + { + var paddingCleaner = new PaddingCleaner(); + var cleanInput = paddingCleaner.Clean(input); + var syntaxTree = CSharpSyntaxTree.ParseText(cleanInput); + var root = syntaxTree.GetCompilationUnitRoot(); + return root; + } + + public static CompilationUnitSyntax Reorganize( + CompilationUnitSyntax compilationUnit, + MemberSortConfiguration memberSortConfiguration + ) + { + return compilationUnit.Reorganize(memberSortConfiguration); + } + + private static async Task GetInput(RootCommandConfiguration configuration) + { + switch (configuration.Mode) + { + case Mode.Console: + using ( + var reader = new StreamReader( + Console.OpenStandardInput(), + Console.InputEncoding + ) + ) + { + return await reader.ReadToEndAsync().ConfigureAwait(false); + } + + case Mode.File: + return await File.ReadAllTextAsync(configuration.File!.FullName) + .ConfigureAwait(false); + + default: + throw new NotImplementedException( + $"Mode \"{configuration.Mode}\" not implemented." + ); + } + } + + private static async Task SetOutput( + CompilationUnitSyntax compilationUnit, + RootCommandConfiguration configuration + ) + { + switch (configuration.Mode) + { + case Mode.Console: + configuration.Console.Write(compilationUnit.ToFullString()); + break; + + case Mode.File: + await File.WriteAllTextAsync( + configuration.File!.FullName, + compilationUnit.ToFullString() + ) + .ConfigureAwait(false); + break; + + default: + throw new NotImplementedException( + $"Mode \"{configuration.Mode}\" not implemented." + ); + } + } +} diff --git a/src/CodeButler/CodeButler.Console/RootCommandConfiguration.cs b/src/CodeButler/CodeButler.Console/RootCommandConfiguration.cs new file mode 100644 index 0000000..8f17b04 --- /dev/null +++ b/src/CodeButler/CodeButler.Console/RootCommandConfiguration.cs @@ -0,0 +1,12 @@ +using System.CommandLine; +using System.IO; + +namespace CodeButler; + +public class RootCommandConfiguration +{ + public bool SortMemberByAlphabet { get; init; } + public Mode Mode { get; init; } + public FileInfo? File { get; init; } + public IConsole Console { get; init; } = null!; +} diff --git a/src/CodeButler/CodeButler.Console/RootCommandConfigurationBinder.cs b/src/CodeButler/CodeButler.Console/RootCommandConfigurationBinder.cs new file mode 100644 index 0000000..3b46639 --- /dev/null +++ b/src/CodeButler/CodeButler.Console/RootCommandConfigurationBinder.cs @@ -0,0 +1,48 @@ +using System.CommandLine; +using System.CommandLine.Binding; +using System.IO; + +namespace CodeButler; + +public class RootCommandConfigurationBinder : BinderBase +{ + private readonly Option _noSortMemberByAlphabet; + private readonly Argument? _file; + + public RootCommandConfigurationBinder( + Option noSortMemberByAlphabet, + Argument? file + ) + { + _noSortMemberByAlphabet = noSortMemberByAlphabet; + _file = file; + } + + protected override RootCommandConfiguration GetBoundValue(BindingContext bindingContext) + { + var parseResult = bindingContext.ParseResult; + + Mode mode; + FileInfo? file; + if (_file is null) + { + mode = Mode.Console; + file = null; + } + else + { + mode = Mode.File; + file = parseResult.GetValueForArgument(_file); + } + + return new RootCommandConfiguration + { + SortMemberByAlphabet = !bindingContext.ParseResult.GetValueForOption( + _noSortMemberByAlphabet + ), + Mode = mode, + File = file, + Console = bindingContext.Console, + }; + } +} diff --git a/src/CodeButler/CodeButler.Console/Syntax/MemberInfoFactory.cs b/src/CodeButler/CodeButler.Console/Syntax/MemberInfoFactory.cs new file mode 100644 index 0000000..5c59ce1 --- /dev/null +++ b/src/CodeButler/CodeButler.Console/Syntax/MemberInfoFactory.cs @@ -0,0 +1,165 @@ +using System; +using System.Linq; +using CodeButler.Reorganizing; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; + +namespace CodeButler.Syntax; + +public static class MemberInfoFactory +{ + public static MemberInfo GetMemberInfo(this MemberDeclarationSyntax memberDeclaration) + { + ArgumentNullException.ThrowIfNull(memberDeclaration); + + return new MemberInfo() + { + Identifier = GetMemberName(memberDeclaration), + AccessModifier = GetMemberAccessModifier(memberDeclaration), + AdditionalModifier = GetMemberAdditionalModifier(memberDeclaration), + MemberType = GetMemberType(memberDeclaration), + }; + } + + private static string GetMemberName(MemberDeclarationSyntax memberDeclaration) + { + var name = memberDeclaration switch + { + NamespaceDeclarationSyntax declaration => declaration.Name.ToString(), + FieldDeclarationSyntax declaration + => string.Join( + ", ", + declaration.Declaration.Variables.Select(variableDeclaration => + variableDeclaration.Identifier + ) + ), + DelegateDeclarationSyntax declaration => declaration.Identifier.ToString(), + EventDeclarationSyntax declaration => declaration.Identifier.ToString(), + EnumDeclarationSyntax declaration => declaration.Identifier.ToString(), + InterfaceDeclarationSyntax declaration => declaration.Identifier.ToString(), + PropertyDeclarationSyntax declaration => declaration.Identifier.ToString(), + MethodDeclarationSyntax declaration => declaration.Identifier.ToString(), + StructDeclarationSyntax declaration => declaration.Identifier.ToString(), + ClassDeclarationSyntax declaration => declaration.Identifier.ToString(), + _ => string.Empty, + }; + + return name; + } + + private static MemberType GetMemberType(MemberDeclarationSyntax memberDeclaration) + { + SyntaxKind kind = memberDeclaration.Kind(); + return kind switch + { + SyntaxKind.FieldDeclaration => MemberType.Field, + SyntaxKind.ConstructorDeclaration => MemberType.Constructor, + SyntaxKind.DestructorDeclaration => MemberType.Destructor, + SyntaxKind.DelegateDeclaration => MemberType.Delegate, + SyntaxKind.EventDeclaration => MemberType.Event, + SyntaxKind.EventFieldDeclaration => MemberType.Event, + SyntaxKind.EnumDeclaration => MemberType.Enum, + SyntaxKind.InterfaceDeclaration => MemberType.Interface, + SyntaxKind.PropertyDeclaration => MemberType.Property, + SyntaxKind.IndexerDeclaration => MemberType.Indexer, + SyntaxKind.OperatorDeclaration => MemberType.Indexer, + SyntaxKind.MethodDeclaration => MemberType.Method, + SyntaxKind.StructDeclaration => MemberType.Struct, + SyntaxKind.ClassDeclaration => MemberType.Class, + _ => MemberType.None, + }; + } + + private static MemberAccessModifier GetMemberAccessModifier( + MemberDeclarationSyntax memberDeclaration + ) + { + var modifierKinds = memberDeclaration.Modifiers.Select(token => token.Kind()).ToHashSet(); + + if (modifierKinds.Count == 0) + { + return MemberAccessModifier.None; + } + else if (modifierKinds.Contains(SyntaxKind.PublicKeyword)) + { + // public + return MemberAccessModifier.Public; + } + else if (modifierKinds.Contains(SyntaxKind.InternalKeyword)) + { + // (?) internal + if (modifierKinds.Contains(SyntaxKind.ProtectedKeyword)) + { + // protected internal + return MemberAccessModifier.ProtectedInternal; + } + else + { + // internal + return MemberAccessModifier.Internal; + } + } + else if (modifierKinds.Contains(SyntaxKind.ProtectedKeyword)) + { + // (?) protected (?) + if (modifierKinds.Contains(SyntaxKind.InternalKeyword)) + { + // protected internal + return MemberAccessModifier.ProtectedInternal; + } + else if (modifierKinds.Contains(SyntaxKind.PrivateKeyword)) + { + // private protected + return MemberAccessModifier.PrivateProtected; + } + else + { + // protected + return MemberAccessModifier.Protected; + } + } + else if (modifierKinds.Contains(SyntaxKind.PrivateKeyword)) + { + return MemberAccessModifier.Private; + } + else + { + return MemberAccessModifier.None; + } + } + + private static MemberAdditionalModifier GetMemberAdditionalModifier( + MemberDeclarationSyntax memberDeclaration + ) + { + var modifierKinds = memberDeclaration.Modifiers.Select(token => token.Kind()).ToHashSet(); + + if (modifierKinds.Count == 0) + { + return MemberAdditionalModifier.None; + } + else if (modifierKinds.Contains(SyntaxKind.ConstKeyword)) + { + return MemberAdditionalModifier.Const; + } + else if ( + modifierKinds.Contains(SyntaxKind.StaticKeyword) + && modifierKinds.Contains(SyntaxKind.ReadOnlyKeyword) + ) + { + return MemberAdditionalModifier.StaticReadonly; + } + else if (modifierKinds.Contains(SyntaxKind.ReadOnlyKeyword)) + { + return MemberAdditionalModifier.Readonly; + } + else if (modifierKinds.Contains(SyntaxKind.StaticKeyword)) + { + return MemberAdditionalModifier.Static; + } + else + { + return MemberAdditionalModifier.None; + } + } +} diff --git a/src/CodeButler/CodeButler.Console/Syntax/MemberOrderInfoExtensions.cs b/src/CodeButler/CodeButler.Console/Syntax/MemberOrderInfoExtensions.cs deleted file mode 100644 index 664a0dc..0000000 --- a/src/CodeButler/CodeButler.Console/Syntax/MemberOrderInfoExtensions.cs +++ /dev/null @@ -1,160 +0,0 @@ -using System; -using System.Linq; -using CodeButler.Reorganizing; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; - -namespace CodeButler.Syntax -{ - public static class MemberOrderInfoExtensions - { - public static MemberOrderInfo GetMemberOrderInfo(this MemberDeclarationSyntax memberDeclaration) - { - if (memberDeclaration is null) - { - throw new ArgumentNullException(nameof(memberDeclaration)); - } - - return new MemberOrderInfo() - { - Identifier = GetMemberName(memberDeclaration), - AccessModifier = GetMemberAccessModifier(memberDeclaration), - AdditionalModifier = GetMemberAdditionalModifier(memberDeclaration), - MemberType = GetMemberType(memberDeclaration), - }; - } - - private static string GetMemberName(MemberDeclarationSyntax memberDeclaration) - { - var name = memberDeclaration switch - { - NamespaceDeclarationSyntax declaration => declaration.Name.ToString(), - FieldDeclarationSyntax declaration => string.Join(", ", declaration.Declaration.Variables.Select(variableDeclaration => variableDeclaration.Identifier)), - DelegateDeclarationSyntax declaration => declaration.Identifier.ToString(), - EventDeclarationSyntax declaration => declaration.Identifier.ToString(), - EnumDeclarationSyntax declaration => declaration.Identifier.ToString(), - InterfaceDeclarationSyntax declaration => declaration.Identifier.ToString(), - PropertyDeclarationSyntax declaration => declaration.Identifier.ToString(), - MethodDeclarationSyntax declaration => declaration.Identifier.ToString(), - StructDeclarationSyntax declaration => declaration.Identifier.ToString(), - ClassDeclarationSyntax declaration => declaration.Identifier.ToString(), - _ => string.Empty, - }; - - return name; - } - - private static MemberType GetMemberType(MemberDeclarationSyntax memberDeclaration) - { - SyntaxKind kind = memberDeclaration.Kind(); - return kind switch - { - SyntaxKind.FieldDeclaration => MemberType.Field, - SyntaxKind.ConstructorDeclaration => MemberType.Constructor, - SyntaxKind.DestructorDeclaration => MemberType.Destructor, - SyntaxKind.DelegateDeclaration => MemberType.Delegate, - SyntaxKind.EventDeclaration => MemberType.Event, - SyntaxKind.EventFieldDeclaration => MemberType.Event, - SyntaxKind.EnumDeclaration => MemberType.Enum, - SyntaxKind.InterfaceDeclaration => MemberType.Interface, - SyntaxKind.PropertyDeclaration => MemberType.Property, - SyntaxKind.IndexerDeclaration => MemberType.Indexer, - SyntaxKind.OperatorDeclaration => MemberType.Indexer, - SyntaxKind.MethodDeclaration => MemberType.Method, - SyntaxKind.StructDeclaration => MemberType.Struct, - SyntaxKind.ClassDeclaration => MemberType.Class, - _ => MemberType.None, - }; - } - - private static MemberAccessModifier GetMemberAccessModifier(MemberDeclarationSyntax memberDeclaration) - { - var modifierKinds = memberDeclaration.Modifiers - .Select(token => token.Kind()) - .ToHashSet(); - - if (modifierKinds.Count == 0) - { - return MemberAccessModifier.None; - } - else if (modifierKinds.Contains(SyntaxKind.PublicKeyword)) - { - // public - return MemberAccessModifier.Public; - } - else if (modifierKinds.Contains(SyntaxKind.InternalKeyword)) - { - // (?) internal - if (modifierKinds.Contains(SyntaxKind.ProtectedKeyword)) - { - // protected internal - return MemberAccessModifier.ProtectedInternal; - } - else - { - // internal - return MemberAccessModifier.Internal; - } - } - else if (modifierKinds.Contains(SyntaxKind.ProtectedKeyword)) - { - // (?) protected (?) - if (modifierKinds.Contains(SyntaxKind.InternalKeyword)) - { - // protected internal - return MemberAccessModifier.ProtectedInternal; - } - else if (modifierKinds.Contains(SyntaxKind.PrivateKeyword)) - { - // private protected - return MemberAccessModifier.PrivateProtected; - } - else - { - // protected - return MemberAccessModifier.Protected; - } - } - else if (modifierKinds.Contains(SyntaxKind.PrivateKeyword)) - { - return MemberAccessModifier.Private; - } - else - { - return MemberAccessModifier.None; - } - } - - private static MemberAdditionalModifier GetMemberAdditionalModifier(MemberDeclarationSyntax memberDeclaration) - { - var modifierKinds = memberDeclaration.Modifiers - .Select(token => token.Kind()) - .ToHashSet(); - - if (modifierKinds.Count == 0) - { - return MemberAdditionalModifier.None; - } - else if (modifierKinds.Contains(SyntaxKind.ConstKeyword)) - { - return MemberAdditionalModifier.Const; - } - else if (modifierKinds.Contains(SyntaxKind.StaticKeyword) && modifierKinds.Contains(SyntaxKind.ReadOnlyKeyword)) - { - return MemberAdditionalModifier.StaticReadonly; - } - else if (modifierKinds.Contains(SyntaxKind.ReadOnlyKeyword)) - { - return MemberAdditionalModifier.Readonly; - } - else if (modifierKinds.Contains(SyntaxKind.StaticKeyword)) - { - return MemberAdditionalModifier.Static; - } - else - { - return MemberAdditionalModifier.None; - } - } - } -} \ No newline at end of file diff --git a/src/CodeButler/CodeButler.Console/Syntax/MembersOrganizerExtensions.cs b/src/CodeButler/CodeButler.Console/Syntax/MembersOrganizerExtensions.cs index d7ec7bc..316a4d0 100644 --- a/src/CodeButler/CodeButler.Console/Syntax/MembersOrganizerExtensions.cs +++ b/src/CodeButler/CodeButler.Console/Syntax/MembersOrganizerExtensions.cs @@ -1,15 +1,21 @@ -using Microsoft.CodeAnalysis.CSharp.Syntax; +using System; +using CodeButler.Reorganizing; +using Microsoft.CodeAnalysis.CSharp.Syntax; namespace CodeButler.Syntax { public static class MembersOrganizerExtensions { - public static CompilationUnitSyntax Reorganize(this CompilationUnitSyntax root) + public static CompilationUnitSyntax Reorganize( + this CompilationUnitSyntax root, + MemberSortConfiguration memberSortConfiguration + ) { - var organizer = new SyntaxReorganizerRewriter(); - return root.Accept(organizer) is CompilationUnitSyntax reorganizedRoot - ? reorganizedRoot - : throw new System.Exception("Reorganized root is null or not of type CompilationUnitSyntax."); + var organizer = new SyntaxReorganizerRewriter(memberSortConfiguration); + return root.Accept(organizer) as CompilationUnitSyntax + ?? throw new Exception( + $"Reorganized root is null or not of type {typeof(CompilationUnitSyntax)}." + ); } } -} \ No newline at end of file +} diff --git a/src/CodeButler/CodeButler.Console/Syntax/SyntaxListExtensions.cs b/src/CodeButler/CodeButler.Console/Syntax/SyntaxListExtensions.cs index 3e192db..12a5cea 100644 --- a/src/CodeButler/CodeButler.Console/Syntax/SyntaxListExtensions.cs +++ b/src/CodeButler/CodeButler.Console/Syntax/SyntaxListExtensions.cs @@ -1,10 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using CodeButler.Reorganizing; +using System.Collections.Generic; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp.Syntax; namespace CodeButler.Syntax { @@ -16,4 +11,4 @@ public static SyntaxList ToSyntaxList(this IEnumerable node return new SyntaxList(nodes); } } -} \ No newline at end of file +} diff --git a/src/CodeButler/CodeButler.Console/Syntax/SyntaxReorganizerRewriter.cs b/src/CodeButler/CodeButler.Console/Syntax/SyntaxReorganizerRewriter.cs index a9a281f..4ab2e33 100644 --- a/src/CodeButler/CodeButler.Console/Syntax/SyntaxReorganizerRewriter.cs +++ b/src/CodeButler/CodeButler.Console/Syntax/SyntaxReorganizerRewriter.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using CodeButler.Reorganizing; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; @@ -8,6 +9,13 @@ namespace CodeButler.Syntax { public class SyntaxReorganizerRewriter : CSharpSyntaxRewriter { + private MemberInfoComparer _memberInfoComparer; + + public SyntaxReorganizerRewriter(MemberSortConfiguration memberSortConfiguration) + { + _memberInfoComparer = new(memberSortConfiguration); + } + public override SyntaxNode? VisitClassDeclaration(ClassDeclarationSyntax node) { var members = OrganizeMembers(node.Members); @@ -40,20 +48,25 @@ public class SyntaxReorganizerRewriter : CSharpSyntaxRewriter return node.WithMembers(members); } - private static SyntaxList OrganizeUsings(IEnumerable usingDirectives) + private static SyntaxList OrganizeUsings( + IEnumerable usingDirectives + ) { - var sorted = usingDirectives.OrderBy(UsingOrderInfoExtensions.GetUsingOrderInfo) - .ToSyntaxList(); + var sorted = usingDirectives + .OrderBy(UsingOrderInfoExtensions.GetUsingOrderInfo) + .ToSyntaxList(); return sorted; } - private SyntaxList OrganizeMembers(IEnumerable memberDeclarations) + private SyntaxList OrganizeMembers( + IEnumerable memberDeclarations + ) { return memberDeclarations .Select(member => member.Accept(this)) .OfType() - .OrderBy(MemberOrderInfoExtensions.GetMemberOrderInfo) + .OrderBy(MemberInfoFactory.GetMemberInfo, _memberInfoComparer) .ToSyntaxList(); } } -} \ No newline at end of file +} diff --git a/src/CodeButler/CodeButler.Console/Syntax/UsingOrderInfoExtensions.cs b/src/CodeButler/CodeButler.Console/Syntax/UsingOrderInfoExtensions.cs index 40a8f98..51f18d1 100644 --- a/src/CodeButler/CodeButler.Console/Syntax/UsingOrderInfoExtensions.cs +++ b/src/CodeButler/CodeButler.Console/Syntax/UsingOrderInfoExtensions.cs @@ -1,5 +1,4 @@ -using System; -using CodeButler.Reorganizing; +using CodeButler.Reorganizing; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace CodeButler.Syntax @@ -16,4 +15,4 @@ public static UsingOrderInfo GetUsingOrderInfo(this UsingDirectiveSyntax usingDi }; } } -} \ No newline at end of file +} diff --git a/src/CodeButler/tests/CodeButler.IntegrationTests/CodeButler.IntegrationTests.csproj b/src/CodeButler/tests/CodeButler.IntegrationTests/CodeButler.IntegrationTests.csproj index 9f6a6cd..ce4aec2 100644 --- a/src/CodeButler/tests/CodeButler.IntegrationTests/CodeButler.IntegrationTests.csproj +++ b/src/CodeButler/tests/CodeButler.IntegrationTests/CodeButler.IntegrationTests.csproj @@ -1,6 +1,6 @@ - net6.0 + net8.0 diff --git a/src/CodeButler/tests/CodeButler.IntegrationTests/IntegrationTests.cs b/src/CodeButler/tests/CodeButler.IntegrationTests/IntegrationTests.cs index efc8e1d..7caaddc 100644 --- a/src/CodeButler/tests/CodeButler.IntegrationTests/IntegrationTests.cs +++ b/src/CodeButler/tests/CodeButler.IntegrationTests/IntegrationTests.cs @@ -1,6 +1,7 @@ -using System.Collections.Generic; +using System; using System.IO; using System.Linq; +using System.Threading.Tasks; using FluentAssertions; using Xunit; @@ -8,25 +9,47 @@ namespace CodeButler.IntegrationTests { public class IntegrationTests { - public static IEnumerable TestCases => - Directory.EnumerateDirectories("TestCases") - .Select(dir => dir.Split(Path.DirectorySeparatorChar)[^1]) - .Select(dirname => new[] { dirname }); + private const string _testCasesDir = "TestCases"; + + public static TheoryData TestCases() + { + var testCases = Directory + .EnumerateDirectories(_testCasesDir) + .Select(dir => dir.Split(Path.DirectorySeparatorChar)[^1]); + + var data = new TheoryData(); + foreach (var testCase in testCases) + { + data.Add(testCase); + } + + return data; + } [Theory] [MemberData(nameof(TestCases))] - public void DirectUseOfProgramClass(string folder) + public async Task DirectUseOfProgramClass(string folder) { - string originalPath = Path.Combine("TestCases", folder, "original.cs.test"); - string cleanPath = Path.Combine("TestCases", folder, "clean.cs.test"); + // Arrange + var originalPath = Path.Combine(_testCasesDir, folder, "original.cs.test"); + var cleanPath = Path.Combine(_testCasesDir, folder, "clean.cs.test"); - string original = File.ReadAllText(originalPath); - string clean = File.ReadAllText(cleanPath); + var testPath = Path.Combine( + _testCasesDir, + folder, + $"{Guid.NewGuid().ToString()[..7]}.cs" + ); - var parsedOriginal = Program.Parse(original); - string reorganized = Program.Reorganize(parsedOriginal).ToFullString(); + // Act + File.Copy(originalPath, testPath); + var exitCode = await Program.Main([testPath]); + var result = await File.ReadAllTextAsync(testPath); + File.Delete(testPath); - _ = reorganized.Should().Be(clean); + // Assert + var clean = await File.ReadAllTextAsync(cleanPath); + exitCode.Should().Be(0); + result.Should().Be(clean); } } -} \ No newline at end of file +} diff --git a/src/CodeButler/tests/CodeButler.UnitTests/CodeButler.UnitTests.csproj b/src/CodeButler/tests/CodeButler.UnitTests/CodeButler.UnitTests.csproj index f06aa1b..6e2e12c 100644 --- a/src/CodeButler/tests/CodeButler.UnitTests/CodeButler.UnitTests.csproj +++ b/src/CodeButler/tests/CodeButler.UnitTests/CodeButler.UnitTests.csproj @@ -1,8 +1,7 @@  - net6.0 - 10 + net8.0 false diff --git a/src/CodeButler/tests/CodeButler.UnitTests/Reorganizing/MemberInfoComparerTest.cs b/src/CodeButler/tests/CodeButler.UnitTests/Reorganizing/MemberInfoComparerTest.cs new file mode 100644 index 0000000..51f16e0 --- /dev/null +++ b/src/CodeButler/tests/CodeButler.UnitTests/Reorganizing/MemberInfoComparerTest.cs @@ -0,0 +1,196 @@ +using System; +using CodeButler.Reorganizing; +using FluentAssertions; +using Xunit; + +namespace CodeButler.Test.Reorganizing +{ + public class MemberInfoComparerTest + { + [Theory] + [InlineData("A", "A", 0)] + [InlineData("a", "a", 0)] + [InlineData("A", "B", -1)] + [InlineData("C", "B", 1)] + [InlineData("a", "A", 1)] + [InlineData("A", "a", -1)] + [InlineData("a", "aa", -1)] + [InlineData("aA", "Aa", 1)] + public void OrderByIdentifier(string left, string right, int expected) + { + var leftMemberInfo = new MemberInfo() { Identifier = left }; + var rightMemberInfo = new MemberInfo() { Identifier = right }; + + var result = MemberInfoComparer.Default.Compare(leftMemberInfo, rightMemberInfo); + + AssertCompare(expected, result); + } + + [Theory] + [InlineData( + MemberType.Field, + MemberAccessModifier.Private, + MemberType.Property, + MemberAccessModifier.Public, + -1 + )] + public void OrderByMemberTypeThenByAccessModifier( + MemberType leftType, + MemberAccessModifier leftAccess, + MemberType rightType, + MemberAccessModifier rightAccess, + int expected + ) + { + var leftMemberInfo = new MemberInfo() + { + MemberType = leftType, + AccessModifier = leftAccess + }; + var rightMemberInfo = new MemberInfo() + { + MemberType = rightType, + AccessModifier = rightAccess + }; + + var result = MemberInfoComparer.Default.Compare(leftMemberInfo, rightMemberInfo); + + AssertCompare(expected, result); + } + + [Theory] + [InlineData( + MemberAccessModifier.Private, + MemberAdditionalModifier.Const, + MemberAccessModifier.Public, + MemberAdditionalModifier.Static, + 1 + )] + public void OrderByAccessModifierThenByAdditionalModifier( + MemberAccessModifier leftAccess, + MemberAdditionalModifier leftAdditional, + MemberAccessModifier rightAccess, + MemberAdditionalModifier rightAdditional, + int expected + ) + { + var leftMemberInfo = new MemberInfo() + { + AccessModifier = leftAccess, + AdditionalModifier = leftAdditional + }; + var rightMemberInfo = new MemberInfo() + { + AccessModifier = rightAccess, + AdditionalModifier = rightAdditional + }; + + var result = MemberInfoComparer.Default.Compare(leftMemberInfo, rightMemberInfo); + + AssertCompare(expected, result); + } + + [Theory] + [InlineData(MemberAdditionalModifier.Const, "B", MemberAdditionalModifier.Static, "A", -1)] + public void OrderByAdditionalModifierThenByIdentifier( + MemberAdditionalModifier leftAdditional, + string leftIdentifier, + MemberAdditionalModifier rightAdditional, + string rightIdentifier, + int expected + ) + { + var leftMemberInfo = new MemberInfo() + { + AdditionalModifier = leftAdditional, + Identifier = leftIdentifier + }; + var rightMemberInfo = new MemberInfo() + { + AdditionalModifier = rightAdditional, + Identifier = rightIdentifier + }; + + var result = MemberInfoComparer.Default.Compare(leftMemberInfo, rightMemberInfo); + + AssertCompare(expected, result); + } + + [Theory] + [InlineData(MemberAdditionalModifier.None, MemberAdditionalModifier.None, 0)] + [InlineData(MemberAdditionalModifier.Const, MemberAdditionalModifier.Readonly, -1)] + [InlineData(MemberAdditionalModifier.Readonly, MemberAdditionalModifier.StaticReadonly, 1)] + [InlineData(MemberAdditionalModifier.None, MemberAdditionalModifier.Const, 1)] + public void OrderByAdditionalModifier( + MemberAdditionalModifier left, + MemberAdditionalModifier right, + int expected + ) + { + var leftMemberInfo = new MemberInfo() { AdditionalModifier = left }; + var rightMemberInfo = new MemberInfo() { AdditionalModifier = right }; + + var result = MemberInfoComparer.Default.Compare(leftMemberInfo, rightMemberInfo); + + AssertCompare(expected, result); + } + + [Theory] + [InlineData(MemberAccessModifier.None, MemberAccessModifier.None, 0)] + [InlineData(MemberAccessModifier.Private, MemberAccessModifier.Private, 0)] + [InlineData(MemberAccessModifier.Public, MemberAccessModifier.Protected, -1)] + [InlineData(MemberAccessModifier.Internal, MemberAccessModifier.ProtectedInternal, -1)] + [InlineData(MemberAccessModifier.Protected, MemberAccessModifier.None, -1)] + [InlineData(MemberAccessModifier.PrivateProtected, MemberAccessModifier.Public, 1)] + public void OrderByAccessModifier( + MemberAccessModifier left, + MemberAccessModifier right, + int expected + ) + { + var leftMemberInfo = new MemberInfo() { AccessModifier = left }; + var rightMemberInfo = new MemberInfo() { AccessModifier = right }; + + var result = MemberInfoComparer.Default.Compare(leftMemberInfo, rightMemberInfo); + + AssertCompare(expected, result); + } + + [Theory] + [InlineData(MemberType.None, MemberType.None, 0)] + [InlineData(MemberType.Field, MemberType.Field, 0)] + [InlineData(MemberType.Constructor, MemberType.Destructor, -1)] + [InlineData(MemberType.Interface, MemberType.Method, -1)] + [InlineData(MemberType.Event, MemberType.Delegate, 1)] + [InlineData(MemberType.Property, MemberType.Enum, 1)] + public void OrderByType(MemberType left, MemberType right, int expected) + { + var leftMemberInfo = new MemberInfo() { MemberType = left }; + var rightMemberInfo = new MemberInfo() { MemberType = right }; + + var result = MemberInfoComparer.Default.Compare(leftMemberInfo, rightMemberInfo); + + AssertCompare(expected, result); + } + + private static void AssertCompare(int expected, int result) + { + if (expected == 0) + { + result.Should().Be(0); + } + else if (expected < 0) + { + result.Should().BeNegative(); + } + else if (expected > 0) + { + result.Should().BePositive(); + } + else + { + throw new Exception("CompareAssert badly implemented."); + } + } + } +} diff --git a/src/CodeButler/tests/CodeButler.UnitTests/Reorganizing/MemberOrderInfoTest.cs b/src/CodeButler/tests/CodeButler.UnitTests/Reorganizing/MemberOrderInfoTest.cs deleted file mode 100644 index 7222cc0..0000000 --- a/src/CodeButler/tests/CodeButler.UnitTests/Reorganizing/MemberOrderInfoTest.cs +++ /dev/null @@ -1,134 +0,0 @@ -using System; -using CodeButler.Reorganizing; -using FluentAssertions; -using Xunit; - -namespace CodeButler.Test.Reorganizing -{ - public class MemberOrderInfoTest - { - [Theory] - [InlineData("A", "A", 0)] - [InlineData("a", "a", 0)] - [InlineData("A", "B", -1)] - [InlineData("C", "B", 1)] - [InlineData("a", "A", 1)] - [InlineData("A", "a", -1)] - [InlineData("a", "aa", -1)] - [InlineData("aA", "Aa", 1)] - public void OrderByIdentifier(string left, string right, int expected) - { - var leftOrderInfo = new MemberOrderInfo() { Identifier = left }; - var rightOrderInfo = new MemberOrderInfo() { Identifier = right }; - - int result = leftOrderInfo.CompareTo(rightOrderInfo); - - AssertCompare(expected, result); - } - - [Theory] - [InlineData(MemberType.Field, MemberAccessModifier.Private, MemberType.Property, MemberAccessModifier.Public, -1)] - public void OrderByMemberTypeThenByAccessModifier(MemberType leftType, MemberAccessModifier leftAccess, MemberType rightType, MemberAccessModifier rightAccess, int expected) - { - var leftOrderInfo = new MemberOrderInfo() { MemberType = leftType, AccessModifier = leftAccess }; - var rightOrderInfo = new MemberOrderInfo() { MemberType = rightType, AccessModifier = rightAccess }; - - int result = leftOrderInfo.CompareTo(rightOrderInfo); - - AssertCompare(expected, result); - } - - [Theory] - [InlineData(MemberAccessModifier.Private, MemberAdditionalModifier.Const, MemberAccessModifier.Public, MemberAdditionalModifier.Static, 1)] - public void OrderByAccessModifierThenByAdditionalModifier(MemberAccessModifier leftAccess, MemberAdditionalModifier leftAdditional, MemberAccessModifier rightAccess, MemberAdditionalModifier rightAdditional, int expected) - { - var leftOrderInfo = new MemberOrderInfo() { AccessModifier = leftAccess, AdditionalModifier = leftAdditional }; - var rightOrderInfo = new MemberOrderInfo() { AccessModifier = rightAccess, AdditionalModifier = rightAdditional }; - - int result = leftOrderInfo.CompareTo(rightOrderInfo); - - AssertCompare(expected, result); - } - - [Theory] - [InlineData(MemberAdditionalModifier.Const, "B", MemberAdditionalModifier.Static, "A", -1)] - public void OrderByAdditionalModifierThenByIdentifier(MemberAdditionalModifier leftAdditional, string leftIdentifier, MemberAdditionalModifier rightAdditional, string rightIdentifier, int expected) - { - var leftOrderInfo = new MemberOrderInfo() { AdditionalModifier = leftAdditional, Identifier = leftIdentifier }; - var rightOrderInfo = new MemberOrderInfo() { AdditionalModifier = rightAdditional, Identifier = rightIdentifier }; - - int result = leftOrderInfo.CompareTo(rightOrderInfo); - - AssertCompare(expected, result); - } - - [Theory] - [InlineData(MemberAdditionalModifier.None, MemberAdditionalModifier.None, 0)] - [InlineData(MemberAdditionalModifier.Const, MemberAdditionalModifier.Readonly, -1)] - [InlineData(MemberAdditionalModifier.Readonly, MemberAdditionalModifier.StaticReadonly, 1)] - [InlineData(MemberAdditionalModifier.None, MemberAdditionalModifier.Const, 1)] - public void OrderByAdditionalModifier(MemberAdditionalModifier left, MemberAdditionalModifier right, int expected) - { - var leftOrderInfo = new MemberOrderInfo() { AdditionalModifier = left }; - var rightOrderInfo = new MemberOrderInfo() { AdditionalModifier = right }; - - int result = leftOrderInfo.CompareTo(rightOrderInfo); - - AssertCompare(expected, result); - } - - [Theory] - [InlineData(MemberAccessModifier.None, MemberAccessModifier.None, 0)] - [InlineData(MemberAccessModifier.Private, MemberAccessModifier.Private, 0)] - [InlineData(MemberAccessModifier.Public, MemberAccessModifier.Protected, -1)] - [InlineData(MemberAccessModifier.Internal, MemberAccessModifier.ProtectedInternal, -1)] - [InlineData(MemberAccessModifier.Protected, MemberAccessModifier.None, -1)] - [InlineData(MemberAccessModifier.PrivateProtected, MemberAccessModifier.Public, 1)] - public void OrderByAccessModifier(MemberAccessModifier left, MemberAccessModifier right, int expected) - { - var leftOrderInfo = new MemberOrderInfo() { AccessModifier = left }; - var rightOrderInfo = new MemberOrderInfo() { AccessModifier = right }; - - int result = leftOrderInfo.CompareTo(rightOrderInfo); - - AssertCompare(expected, result); - } - - [Theory] - [InlineData(MemberType.None, MemberType.None, 0)] - [InlineData(MemberType.Field, MemberType.Field, 0)] - [InlineData(MemberType.Constructor, MemberType.Destructor, -1)] - [InlineData(MemberType.Interface, MemberType.Method, -1)] - [InlineData(MemberType.Event, MemberType.Delegate, 1)] - [InlineData(MemberType.Property, MemberType.Enum, 1)] - public void OrderByType(MemberType left, MemberType right, int expected) - { - var leftOrderInfo = new MemberOrderInfo() { MemberType = left }; - var rightOrderInfo = new MemberOrderInfo() { MemberType = right }; - - int result = leftOrderInfo.CompareTo(rightOrderInfo); - - AssertCompare(expected, result); - } - - private static void AssertCompare(int expected, int result) - { - if (expected == 0) - { - result.Should().Be(0); - } - else if (expected < 0) - { - result.Should().BeNegative(); - } - else if (expected > 0) - { - result.Should().BePositive(); - } - else - { - throw new Exception("CompareAssert badly implemented."); - } - } - } -} \ No newline at end of file From 9b5bc8c10b9ad0559686e3481bf6277247479859 Mon Sep 17 00:00:00 2001 From: just-seba <46223600+just-seba@users.noreply.github.com> Date: Sat, 2 Mar 2024 13:42:09 +0100 Subject: [PATCH 03/10] refactors: Clean up code. - Uses file scoped namespaces - Removes some extension methods --- src/CodeButler/.editorconfig | 10 +- .../{Mode.cs => InputOutputMode.cs} | 2 +- src/CodeButler/CodeButler.Console/Program.cs | 57 ++- .../Reorganizing/MemberAccessModifier.cs | 23 +- .../Reorganizing/MemberAdditionalModifier.cs | 19 +- .../Reorganizing/MemberType.cs | 37 +- .../Reorganizing/UsingInfo.cs | 170 +++++++++ .../Reorganizing/UsingOrderInfo.cs | 171 --------- .../CodeButler.Console/RootCommand.cs | 36 +- .../RootCommandConfiguration.cs | 2 +- .../RootCommandConfigurationBinder.cs | 6 +- .../Syntax/MembersOrganizerExtensions.cs | 21 -- .../Syntax/SyntaxListExtensions.cs | 13 +- .../Syntax/SyntaxReorganizerRewriter.cs | 105 +++--- .../Syntax/UsingInfoFactory.cs | 17 + .../Syntax/UsingOrderInfoExtensions.cs | 18 - .../IntegrationTests.cs | 75 ++-- .../Padding/PaddingCleanerTests.cs | 41 ++- .../Reorganizing/MemberInfoComparerTest.cs | 333 +++++++++--------- .../Reorganizing/UsingOrderInfoTest.cs | 269 +++++++------- .../Syntax/UsingDirectiveSyntaxTest.cs | 54 +-- 21 files changed, 742 insertions(+), 737 deletions(-) rename src/CodeButler/CodeButler.Console/{Mode.cs => InputOutputMode.cs} (64%) create mode 100644 src/CodeButler/CodeButler.Console/Reorganizing/UsingInfo.cs delete mode 100644 src/CodeButler/CodeButler.Console/Reorganizing/UsingOrderInfo.cs delete mode 100644 src/CodeButler/CodeButler.Console/Syntax/MembersOrganizerExtensions.cs create mode 100644 src/CodeButler/CodeButler.Console/Syntax/UsingInfoFactory.cs delete mode 100644 src/CodeButler/CodeButler.Console/Syntax/UsingOrderInfoExtensions.cs diff --git a/src/CodeButler/.editorconfig b/src/CodeButler/.editorconfig index d6255c2..47af26e 100644 --- a/src/CodeButler/.editorconfig +++ b/src/CodeButler/.editorconfig @@ -102,18 +102,22 @@ dotnet_naming_symbols.private_constant.required_modifiers = const dotnet_naming_style.underscore_camel_case.required_prefix = _ dotnet_naming_style.underscore_camel_case.capitalization = camel_case -#upper_case +# upper_case dotnet_naming_style.upper_case.capitalization = all_upper dotnet_naming_style.upper_case.word_separator = _ #.NET naming rule: -#private_fields_underscore_camelcase +# private_fields_underscore_camelcase dotnet_naming_rule.private_fields_underscore_camelcase.symbols = private_field dotnet_naming_rule.private_fields_underscore_camelcase.style = underscore_camel_case dotnet_naming_rule.private_fields_underscore_camelcase.severity = suggestion -#private_constants_upper_case +# private_constants_upper_case dotnet_naming_rule.private_constants_upper_case.symbols = private_field dotnet_naming_rule.private_constants_upper_case.style = underscore_camel_case dotnet_naming_rule.private_constants_upper_case.severity = suggestion +# Enforce file-scoped namespace +csharp_style_namespace_declarations = file_scoped:error +dotnet_diagnostic.IDE0161.severity = error + diff --git a/src/CodeButler/CodeButler.Console/Mode.cs b/src/CodeButler/CodeButler.Console/InputOutputMode.cs similarity index 64% rename from src/CodeButler/CodeButler.Console/Mode.cs rename to src/CodeButler/CodeButler.Console/InputOutputMode.cs index 5d651cb..31e806d 100644 --- a/src/CodeButler/CodeButler.Console/Mode.cs +++ b/src/CodeButler/CodeButler.Console/InputOutputMode.cs @@ -1,6 +1,6 @@ namespace CodeButler; -public enum Mode +public enum InputOutputMode { Console, File, diff --git a/src/CodeButler/CodeButler.Console/Program.cs b/src/CodeButler/CodeButler.Console/Program.cs index 7249864..dd0f13a 100644 --- a/src/CodeButler/CodeButler.Console/Program.cs +++ b/src/CodeButler/CodeButler.Console/Program.cs @@ -3,42 +3,39 @@ using System.IO; using System.Threading.Tasks; -namespace CodeButler +namespace CodeButler; + +public class Program { - public class Program + public static async Task Main(string[] args) { - public static async Task Main(string[] args) - { - var rootCommand = new RootCommand( - "Reorganises, sorts and cleans up the provided C# file." - ); - - var noSortMemberByAlphabetOption = new Option( - name: "--no-sort-member-by-alphabet", - description: "Disables sorting members by alphabet.", - getDefaultValue: () => false - ); + var rootCommand = new RootCommand("Reorganises, sorts and cleans up the provided C# file."); - var inputFileArg = Console.IsInputRedirected - ? null - : new Argument( - name: "Input", - description: "Path to input file or piped input." - ); + var noSortMemberByAlphabetOption = new Option( + name: "--no-sort-member-by-alphabet", + description: "Disables sorting members by alphabet.", + getDefaultValue: () => false + ); - rootCommand.AddOption(noSortMemberByAlphabetOption); - if (inputFileArg is not null) - { - rootCommand.AddArgument(inputFileArg); - } - - rootCommand.SetHandler( - RootCommandHandler.Handle, - new RootCommandConfigurationBinder(noSortMemberByAlphabetOption, inputFileArg) + var inputFileArg = Console.IsInputRedirected + ? null + : new Argument( + name: "Input", + description: "Path to input file or piped input." ); - var exitCode = await rootCommand.InvokeAsync(args); - return exitCode; + rootCommand.AddOption(noSortMemberByAlphabetOption); + if (inputFileArg is not null) + { + rootCommand.AddArgument(inputFileArg); } + + rootCommand.SetHandler( + RootCommandHandler.Handle, + new RootCommandConfigurationBinder(noSortMemberByAlphabetOption, inputFileArg) + ); + + var exitCode = await rootCommand.InvokeAsync(args); + return exitCode; } } diff --git a/src/CodeButler/CodeButler.Console/Reorganizing/MemberAccessModifier.cs b/src/CodeButler/CodeButler.Console/Reorganizing/MemberAccessModifier.cs index a0ae775..7555cbb 100644 --- a/src/CodeButler/CodeButler.Console/Reorganizing/MemberAccessModifier.cs +++ b/src/CodeButler/CodeButler.Console/Reorganizing/MemberAccessModifier.cs @@ -1,13 +1,12 @@ -namespace CodeButler.Reorganizing +namespace CodeButler.Reorganizing; + +public enum MemberAccessModifier { - public enum MemberAccessModifier - { - Public, - Internal, - Protected, - ProtectedInternal, - PrivateProtected, - Private, - None, - } -} \ No newline at end of file + Public, + Internal, + Protected, + ProtectedInternal, + PrivateProtected, + Private, + None, +} diff --git a/src/CodeButler/CodeButler.Console/Reorganizing/MemberAdditionalModifier.cs b/src/CodeButler/CodeButler.Console/Reorganizing/MemberAdditionalModifier.cs index 337677a..9d8a250 100644 --- a/src/CodeButler/CodeButler.Console/Reorganizing/MemberAdditionalModifier.cs +++ b/src/CodeButler/CodeButler.Console/Reorganizing/MemberAdditionalModifier.cs @@ -1,11 +1,10 @@ -namespace CodeButler.Reorganizing +namespace CodeButler.Reorganizing; + +public enum MemberAdditionalModifier { - public enum MemberAdditionalModifier - { - Const, - StaticReadonly, - Static, - Readonly, - None, - } -} \ No newline at end of file + Const, + StaticReadonly, + Static, + Readonly, + None, +} diff --git a/src/CodeButler/CodeButler.Console/Reorganizing/MemberType.cs b/src/CodeButler/CodeButler.Console/Reorganizing/MemberType.cs index 105021c..a24e323 100644 --- a/src/CodeButler/CodeButler.Console/Reorganizing/MemberType.cs +++ b/src/CodeButler/CodeButler.Console/Reorganizing/MemberType.cs @@ -1,20 +1,19 @@ -namespace CodeButler.Reorganizing +namespace CodeButler.Reorganizing; + +public enum MemberType { - public enum MemberType - { - Field, - Constructor, - Destructor, - Delegate, - Event, - Enum, - Interface, - Property, - Indexer, - Operator, - Method, - Struct, - Class, - None, - } -} \ No newline at end of file + Field, + Constructor, + Destructor, + Delegate, + Event, + Enum, + Interface, + Property, + Indexer, + Operator, + Method, + Struct, + Class, + None, +} diff --git a/src/CodeButler/CodeButler.Console/Reorganizing/UsingInfo.cs b/src/CodeButler/CodeButler.Console/Reorganizing/UsingInfo.cs new file mode 100644 index 0000000..75ec23d --- /dev/null +++ b/src/CodeButler/CodeButler.Console/Reorganizing/UsingInfo.cs @@ -0,0 +1,170 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace CodeButler.Reorganizing; + +public sealed class UsingInfo : IEquatable, IComparable +{ + private const string _systemUsing = "System"; + + private readonly Func[] _compareMethods; + + public UsingInfo(string name) + { + Name = name ?? throw new ArgumentNullException(nameof(name)); + _compareMethods = new Func[] + { + CompareByIsGlobal, + CompareByIsStatic, + CompareByAlias, + CompareByName, + }; + } + + public string? Alias { get; set; } + + public bool IsStatic { get; set; } + public bool IsGlobal { get; set; } + + public string Name { get; } + + public static bool operator !=(UsingInfo? left, UsingInfo? right) + { + return !(left == right); + } + + public static bool operator <(UsingInfo left, UsingInfo right) + { + return left is null ? right is not null : left.CompareTo(right) < 0; + } + + public static bool operator <=(UsingInfo left, UsingInfo right) + { + return left is null || left.CompareTo(right) <= 0; + } + + public static bool operator ==(UsingInfo? left, UsingInfo? right) + { + return EqualityComparer.Default.Equals(left, right); + } + + public static bool operator >(UsingInfo left, UsingInfo right) + { + return left is not null && left.CompareTo(right) > 0; + } + + public static bool operator >=(UsingInfo left, UsingInfo right) + { + return left is null ? right is null : left.CompareTo(right) >= 0; + } + + public int CompareByAlias(UsingInfo? other) + { + if (other is null) + { + return -1; + } + + return string.Compare(Alias, other.Alias, StringComparison.Ordinal); + } + + public int CompareByIsStatic(UsingInfo? other) + { + if (other is null) + { + return -1; + } + + return (IsStatic, other.IsStatic) switch + { + (false, true) => -1, + (true, false) => 1, + (_, _) => 0, + }; + } + + public int CompareByIsGlobal(UsingInfo? other) + { + if (other is null) + { + return -1; + } + + return (IsGlobal, other.IsGlobal) switch + { + (true, false) => -1, + (false, true) => 1, + (_, _) => 0, + }; + } + + public int CompareByName(UsingInfo? other) + { + if (other is null) + { + return -1; + } + + return (IsSystemUsing(this), IsSystemUsing(other)) switch + { + (true, false) => -1, + (false, true) => 1, + (_, _) => string.Compare(Name, other.Name, StringComparison.Ordinal), + }; + } + + public int CompareTo(UsingInfo? other) + { + return _compareMethods + .Select(compareMethod => compareMethod(other)) + .FirstOrDefault(result => result != 0); + } + + public override bool Equals(object? obj) + { + return Equals(obj as UsingInfo); + } + + public bool Equals(UsingInfo? other) + { + return other != null && Name == other.Name; + } + + public override int GetHashCode() + { + return HashCode.Combine(Name); + } + + public override string ToString() + { + var sb = new StringBuilder(); + + if (IsGlobal) + { + sb.Append("global "); + } + + sb.Append("using"); + + if (!string.IsNullOrEmpty(Alias)) + { + sb.Append($" {Alias} ="); + } + + if (IsStatic) + { + sb.Append(" static"); + } + + sb.Append($" {Name};"); + + return sb.ToString(); + } + + private static bool IsSystemUsing(UsingInfo usingOrderInfo) + { + return usingOrderInfo.Name.StartsWith(_systemUsing, StringComparison.Ordinal); + } +} diff --git a/src/CodeButler/CodeButler.Console/Reorganizing/UsingOrderInfo.cs b/src/CodeButler/CodeButler.Console/Reorganizing/UsingOrderInfo.cs deleted file mode 100644 index a44df61..0000000 --- a/src/CodeButler/CodeButler.Console/Reorganizing/UsingOrderInfo.cs +++ /dev/null @@ -1,171 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace CodeButler.Reorganizing -{ - public sealed class UsingOrderInfo : IEquatable, IComparable - { - private const string _systemUsing = "System"; - - private readonly Func[] _compareMethods; - - public UsingOrderInfo(string name) - { - Name = name ?? throw new ArgumentNullException(nameof(name)); - _compareMethods = new Func[] - { - CompareByIsGlobal, - CompareByIsStatic, - CompareByAlias, - CompareByName, - }; - } - - public string? Alias { get; set; } - - public bool IsStatic { get; set; } - public bool IsGlobal { get; set; } - - public string Name { get; } - - public static bool operator !=(UsingOrderInfo? left, UsingOrderInfo? right) - { - return !(left == right); - } - - public static bool operator <(UsingOrderInfo left, UsingOrderInfo right) - { - return left is null ? right is not null : left.CompareTo(right) < 0; - } - - public static bool operator <=(UsingOrderInfo left, UsingOrderInfo right) - { - return left is null || left.CompareTo(right) <= 0; - } - - public static bool operator ==(UsingOrderInfo? left, UsingOrderInfo? right) - { - return EqualityComparer.Default.Equals(left, right); - } - - public static bool operator >(UsingOrderInfo left, UsingOrderInfo right) - { - return left is not null && left.CompareTo(right) > 0; - } - - public static bool operator >=(UsingOrderInfo left, UsingOrderInfo right) - { - return left is null ? right is null : left.CompareTo(right) >= 0; - } - - public int CompareByAlias(UsingOrderInfo? other) - { - if (other is null) - { - return -1; - } - - return string.Compare(Alias, other.Alias, StringComparison.Ordinal); - } - - public int CompareByIsStatic(UsingOrderInfo? other) - { - if (other is null) - { - return -1; - } - - return (IsStatic, other.IsStatic) switch - { - (false, true) => -1, - (true, false) => 1, - (_, _) => 0, - }; - } - - public int CompareByIsGlobal(UsingOrderInfo? other) - { - if (other is null) - { - return -1; - } - - return (IsGlobal, other.IsGlobal) switch - { - (true, false) => -1, - (false, true) => 1, - (_, _) => 0, - }; - } - - public int CompareByName(UsingOrderInfo? other) - { - if (other is null) - { - return -1; - } - - return (IsSystemUsing(this), IsSystemUsing(other)) switch - { - (true, false) => -1, - (false, true) => 1, - (_, _) => string.Compare(Name, other.Name, StringComparison.Ordinal), - }; - } - - public int CompareTo(UsingOrderInfo? other) - { - return _compareMethods - .Select(compareMethod => compareMethod(other)) - .FirstOrDefault(result => result != 0); - } - - public override bool Equals(object? obj) - { - return Equals(obj as UsingOrderInfo); - } - - public bool Equals(UsingOrderInfo? other) - { - return other != null && Name == other.Name; - } - - public override int GetHashCode() - { - return HashCode.Combine(Name); - } - - public override string ToString() - { - var sb = new StringBuilder(); - - if (IsGlobal) - { - sb.Append("global "); - } - - sb.Append("using"); - - if (!string.IsNullOrEmpty(Alias)) - { - sb.Append($" {Alias} ="); - } - - if (IsStatic) - { - sb.Append(" static"); - } - - sb.Append($" {Name};"); - - return sb.ToString(); - } - - private static bool IsSystemUsing(UsingOrderInfo usingOrderInfo) - { - return usingOrderInfo.Name.StartsWith(_systemUsing, StringComparison.Ordinal); - } - } -} diff --git a/src/CodeButler/CodeButler.Console/RootCommand.cs b/src/CodeButler/CodeButler.Console/RootCommand.cs index f353b16..ce11e5d 100644 --- a/src/CodeButler/CodeButler.Console/RootCommand.cs +++ b/src/CodeButler/CodeButler.Console/RootCommand.cs @@ -14,17 +14,25 @@ public class RootCommandHandler { public static async Task Handle(RootCommandConfiguration configuration) { - var input = await GetInput(configuration).ConfigureAwait(false); - CompilationUnitSyntax root = Parse(input); + var input = await ReadInput(configuration).ConfigureAwait(false); + + var clean = Clean(input); + var root = Parse(clean); var organizedRoot = Reorganize( root, new MemberSortConfiguration { SortByAlphabet = configuration.SortMemberByAlphabet } ); - await SetOutput(organizedRoot, configuration).ConfigureAwait(false); + await WriteOutput(organizedRoot, configuration).ConfigureAwait(false); + } + + private static string Clean(string input) + { + var paddingCleaner = new PaddingCleaner(); + return paddingCleaner.Clean(input); } - public static CompilationUnitSyntax Parse(string input) + private static CompilationUnitSyntax Parse(string input) { var paddingCleaner = new PaddingCleaner(); var cleanInput = paddingCleaner.Clean(input); @@ -33,19 +41,23 @@ public static CompilationUnitSyntax Parse(string input) return root; } - public static CompilationUnitSyntax Reorganize( + private static CompilationUnitSyntax Reorganize( CompilationUnitSyntax compilationUnit, MemberSortConfiguration memberSortConfiguration ) { - return compilationUnit.Reorganize(memberSortConfiguration); + var organizer = new SyntaxReorganizerRewriter(memberSortConfiguration); + return compilationUnit.Accept(organizer) as CompilationUnitSyntax + ?? throw new Exception( + $"Reorganized root is null or not of type {typeof(CompilationUnitSyntax)}." + ); } - private static async Task GetInput(RootCommandConfiguration configuration) + private static async Task ReadInput(RootCommandConfiguration configuration) { switch (configuration.Mode) { - case Mode.Console: + case InputOutputMode.Console: using ( var reader = new StreamReader( Console.OpenStandardInput(), @@ -56,7 +68,7 @@ private static async Task GetInput(RootCommandConfiguration configuratio return await reader.ReadToEndAsync().ConfigureAwait(false); } - case Mode.File: + case InputOutputMode.File: return await File.ReadAllTextAsync(configuration.File!.FullName) .ConfigureAwait(false); @@ -67,18 +79,18 @@ private static async Task GetInput(RootCommandConfiguration configuratio } } - private static async Task SetOutput( + private static async Task WriteOutput( CompilationUnitSyntax compilationUnit, RootCommandConfiguration configuration ) { switch (configuration.Mode) { - case Mode.Console: + case InputOutputMode.Console: configuration.Console.Write(compilationUnit.ToFullString()); break; - case Mode.File: + case InputOutputMode.File: await File.WriteAllTextAsync( configuration.File!.FullName, compilationUnit.ToFullString() diff --git a/src/CodeButler/CodeButler.Console/RootCommandConfiguration.cs b/src/CodeButler/CodeButler.Console/RootCommandConfiguration.cs index 8f17b04..509e234 100644 --- a/src/CodeButler/CodeButler.Console/RootCommandConfiguration.cs +++ b/src/CodeButler/CodeButler.Console/RootCommandConfiguration.cs @@ -6,7 +6,7 @@ namespace CodeButler; public class RootCommandConfiguration { public bool SortMemberByAlphabet { get; init; } - public Mode Mode { get; init; } + public InputOutputMode Mode { get; init; } public FileInfo? File { get; init; } public IConsole Console { get; init; } = null!; } diff --git a/src/CodeButler/CodeButler.Console/RootCommandConfigurationBinder.cs b/src/CodeButler/CodeButler.Console/RootCommandConfigurationBinder.cs index 3b46639..ff5d10a 100644 --- a/src/CodeButler/CodeButler.Console/RootCommandConfigurationBinder.cs +++ b/src/CodeButler/CodeButler.Console/RootCommandConfigurationBinder.cs @@ -22,16 +22,16 @@ protected override RootCommandConfiguration GetBoundValue(BindingContext binding { var parseResult = bindingContext.ParseResult; - Mode mode; + InputOutputMode mode; FileInfo? file; if (_file is null) { - mode = Mode.Console; + mode = InputOutputMode.Console; file = null; } else { - mode = Mode.File; + mode = InputOutputMode.File; file = parseResult.GetValueForArgument(_file); } diff --git a/src/CodeButler/CodeButler.Console/Syntax/MembersOrganizerExtensions.cs b/src/CodeButler/CodeButler.Console/Syntax/MembersOrganizerExtensions.cs deleted file mode 100644 index 316a4d0..0000000 --- a/src/CodeButler/CodeButler.Console/Syntax/MembersOrganizerExtensions.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using CodeButler.Reorganizing; -using Microsoft.CodeAnalysis.CSharp.Syntax; - -namespace CodeButler.Syntax -{ - public static class MembersOrganizerExtensions - { - public static CompilationUnitSyntax Reorganize( - this CompilationUnitSyntax root, - MemberSortConfiguration memberSortConfiguration - ) - { - var organizer = new SyntaxReorganizerRewriter(memberSortConfiguration); - return root.Accept(organizer) as CompilationUnitSyntax - ?? throw new Exception( - $"Reorganized root is null or not of type {typeof(CompilationUnitSyntax)}." - ); - } - } -} diff --git a/src/CodeButler/CodeButler.Console/Syntax/SyntaxListExtensions.cs b/src/CodeButler/CodeButler.Console/Syntax/SyntaxListExtensions.cs index 12a5cea..8590054 100644 --- a/src/CodeButler/CodeButler.Console/Syntax/SyntaxListExtensions.cs +++ b/src/CodeButler/CodeButler.Console/Syntax/SyntaxListExtensions.cs @@ -1,14 +1,13 @@ using System.Collections.Generic; using Microsoft.CodeAnalysis; -namespace CodeButler.Syntax +namespace CodeButler.Syntax; + +public static class SyntaxListExtensions { - public static class SyntaxListExtensions + public static SyntaxList ToSyntaxList(this IEnumerable nodes) + where TNode : SyntaxNode { - public static SyntaxList ToSyntaxList(this IEnumerable nodes) - where TNode : SyntaxNode - { - return new SyntaxList(nodes); - } + return new SyntaxList(nodes); } } diff --git a/src/CodeButler/CodeButler.Console/Syntax/SyntaxReorganizerRewriter.cs b/src/CodeButler/CodeButler.Console/Syntax/SyntaxReorganizerRewriter.cs index 4ab2e33..a8ecb45 100644 --- a/src/CodeButler/CodeButler.Console/Syntax/SyntaxReorganizerRewriter.cs +++ b/src/CodeButler/CodeButler.Console/Syntax/SyntaxReorganizerRewriter.cs @@ -5,68 +5,65 @@ using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; -namespace CodeButler.Syntax +namespace CodeButler.Syntax; + +public class SyntaxReorganizerRewriter : CSharpSyntaxRewriter { - public class SyntaxReorganizerRewriter : CSharpSyntaxRewriter - { - private MemberInfoComparer _memberInfoComparer; + private MemberInfoComparer _memberInfoComparer; - public SyntaxReorganizerRewriter(MemberSortConfiguration memberSortConfiguration) - { - _memberInfoComparer = new(memberSortConfiguration); - } + public SyntaxReorganizerRewriter(MemberSortConfiguration memberSortConfiguration) + { + _memberInfoComparer = new(memberSortConfiguration); + } - public override SyntaxNode? VisitClassDeclaration(ClassDeclarationSyntax node) - { - var members = OrganizeMembers(node.Members); - return node.WithMembers(members); - } + public override SyntaxNode? VisitClassDeclaration(ClassDeclarationSyntax node) + { + var members = OrganizeMembers(node.Members); + return node.WithMembers(members); + } - public override SyntaxNode? VisitCompilationUnit(CompilationUnitSyntax node) - { - var usings = OrganizeUsings(node.Usings); - var members = OrganizeMembers(node.Members); - return node.WithUsings(usings).WithMembers(members); - } + public override SyntaxNode? VisitCompilationUnit(CompilationUnitSyntax node) + { + var usings = OrganizeUsings(node.Usings); + var members = OrganizeMembers(node.Members); + return node.WithUsings(usings).WithMembers(members); + } - public override SyntaxNode? VisitInterfaceDeclaration(InterfaceDeclarationSyntax node) - { - var members = OrganizeMembers(node.Members); - return node.WithMembers(members); - } + public override SyntaxNode? VisitInterfaceDeclaration(InterfaceDeclarationSyntax node) + { + var members = OrganizeMembers(node.Members); + return node.WithMembers(members); + } - public override SyntaxNode? VisitNamespaceDeclaration(NamespaceDeclarationSyntax node) - { - var usings = OrganizeUsings(node.Usings); - var members = OrganizeMembers(node.Members); - return node.WithUsings(usings).WithMembers(members); - } + public override SyntaxNode? VisitNamespaceDeclaration(NamespaceDeclarationSyntax node) + { + var usings = OrganizeUsings(node.Usings); + var members = OrganizeMembers(node.Members); + return node.WithUsings(usings).WithMembers(members); + } - public override SyntaxNode? VisitStructDeclaration(StructDeclarationSyntax node) - { - var members = OrganizeMembers(node.Members); - return node.WithMembers(members); - } + public override SyntaxNode? VisitStructDeclaration(StructDeclarationSyntax node) + { + var members = OrganizeMembers(node.Members); + return node.WithMembers(members); + } - private static SyntaxList OrganizeUsings( - IEnumerable usingDirectives - ) - { - var sorted = usingDirectives - .OrderBy(UsingOrderInfoExtensions.GetUsingOrderInfo) - .ToSyntaxList(); - return sorted; - } + private static SyntaxList OrganizeUsings( + IEnumerable usingDirectives + ) + { + var sorted = usingDirectives.OrderBy(UsingInfoFactory.GetUsingInfo).ToSyntaxList(); + return sorted; + } - private SyntaxList OrganizeMembers( - IEnumerable memberDeclarations - ) - { - return memberDeclarations - .Select(member => member.Accept(this)) - .OfType() - .OrderBy(MemberInfoFactory.GetMemberInfo, _memberInfoComparer) - .ToSyntaxList(); - } + private SyntaxList OrganizeMembers( + IEnumerable memberDeclarations + ) + { + return memberDeclarations + .Select(member => member.Accept(this)) + .OfType() + .OrderBy(MemberInfoFactory.GetMemberInfo, _memberInfoComparer) + .ToSyntaxList(); } } diff --git a/src/CodeButler/CodeButler.Console/Syntax/UsingInfoFactory.cs b/src/CodeButler/CodeButler.Console/Syntax/UsingInfoFactory.cs new file mode 100644 index 0000000..e8ba936 --- /dev/null +++ b/src/CodeButler/CodeButler.Console/Syntax/UsingInfoFactory.cs @@ -0,0 +1,17 @@ +using CodeButler.Reorganizing; +using Microsoft.CodeAnalysis.CSharp.Syntax; + +namespace CodeButler.Syntax; + +public static class UsingInfoFactory +{ + public static UsingInfo GetUsingInfo(this UsingDirectiveSyntax usingDirective) + { + return new UsingInfo(usingDirective.Name.ToString()) + { + Alias = usingDirective.Alias?.Name.ToString(), + IsStatic = usingDirective.StaticKeyword != default, + IsGlobal = usingDirective.GlobalKeyword != default, + }; + } +} diff --git a/src/CodeButler/CodeButler.Console/Syntax/UsingOrderInfoExtensions.cs b/src/CodeButler/CodeButler.Console/Syntax/UsingOrderInfoExtensions.cs deleted file mode 100644 index 51f18d1..0000000 --- a/src/CodeButler/CodeButler.Console/Syntax/UsingOrderInfoExtensions.cs +++ /dev/null @@ -1,18 +0,0 @@ -using CodeButler.Reorganizing; -using Microsoft.CodeAnalysis.CSharp.Syntax; - -namespace CodeButler.Syntax -{ - public static class UsingOrderInfoExtensions - { - public static UsingOrderInfo GetUsingOrderInfo(this UsingDirectiveSyntax usingDirective) - { - return new UsingOrderInfo(usingDirective.Name.ToString()) - { - Alias = usingDirective.Alias?.Name.ToString(), - IsStatic = usingDirective.StaticKeyword != default, - IsGlobal = usingDirective.GlobalKeyword != default, - }; - } - } -} diff --git a/src/CodeButler/tests/CodeButler.IntegrationTests/IntegrationTests.cs b/src/CodeButler/tests/CodeButler.IntegrationTests/IntegrationTests.cs index 7caaddc..c554302 100644 --- a/src/CodeButler/tests/CodeButler.IntegrationTests/IntegrationTests.cs +++ b/src/CodeButler/tests/CodeButler.IntegrationTests/IntegrationTests.cs @@ -5,51 +5,46 @@ using FluentAssertions; using Xunit; -namespace CodeButler.IntegrationTests +namespace CodeButler.IntegrationTests; + +public class IntegrationTests { - public class IntegrationTests + private const string _testCasesDir = "TestCases"; + + public static TheoryData TestCases() { - private const string _testCasesDir = "TestCases"; + var testCases = Directory + .EnumerateDirectories(_testCasesDir) + .Select(dir => dir.Split(Path.DirectorySeparatorChar)[^1]); - public static TheoryData TestCases() + var data = new TheoryData(); + foreach (var testCase in testCases) { - var testCases = Directory - .EnumerateDirectories(_testCasesDir) - .Select(dir => dir.Split(Path.DirectorySeparatorChar)[^1]); - - var data = new TheoryData(); - foreach (var testCase in testCases) - { - data.Add(testCase); - } - - return data; + data.Add(testCase); } - [Theory] - [MemberData(nameof(TestCases))] - public async Task DirectUseOfProgramClass(string folder) - { - // Arrange - var originalPath = Path.Combine(_testCasesDir, folder, "original.cs.test"); - var cleanPath = Path.Combine(_testCasesDir, folder, "clean.cs.test"); - - var testPath = Path.Combine( - _testCasesDir, - folder, - $"{Guid.NewGuid().ToString()[..7]}.cs" - ); - - // Act - File.Copy(originalPath, testPath); - var exitCode = await Program.Main([testPath]); - var result = await File.ReadAllTextAsync(testPath); - File.Delete(testPath); - - // Assert - var clean = await File.ReadAllTextAsync(cleanPath); - exitCode.Should().Be(0); - result.Should().Be(clean); - } + return data; + } + + [Theory] + [MemberData(nameof(TestCases))] + public async Task DirectUseOfProgramClass(string folder) + { + // Arrange + var originalPath = Path.Combine(_testCasesDir, folder, "original.cs.test"); + var cleanPath = Path.Combine(_testCasesDir, folder, "clean.cs.test"); + + var testPath = Path.Combine(_testCasesDir, folder, $"{Guid.NewGuid().ToString()[..7]}.cs"); + + // Act + File.Copy(originalPath, testPath); + var exitCode = await Program.Main([testPath]); + var result = await File.ReadAllTextAsync(testPath); + File.Delete(testPath); + + // Assert + var clean = await File.ReadAllTextAsync(cleanPath); + exitCode.Should().Be(0); + result.Should().Be(clean); } } diff --git a/src/CodeButler/tests/CodeButler.UnitTests/Padding/PaddingCleanerTests.cs b/src/CodeButler/tests/CodeButler.UnitTests/Padding/PaddingCleanerTests.cs index 6dfa3c5..3e775f1 100644 --- a/src/CodeButler/tests/CodeButler.UnitTests/Padding/PaddingCleanerTests.cs +++ b/src/CodeButler/tests/CodeButler.UnitTests/Padding/PaddingCleanerTests.cs @@ -2,25 +2,30 @@ using FluentAssertions; using Xunit; -namespace CodeButler.UnitTests.Padding +namespace CodeButler.UnitTests.Padding; + +public class PaddingCleanerTests { - public class PaddingCleanerTests + [Theory] + [InlineData(" \n", "\n")] + [InlineData(" \n \n", "\n")] + [InlineData(" \r\n \r\n", "\r\n")] + [InlineData("\n\n\n", "\n")] + [InlineData("\r\n\r\n\r\n", "\r\n")] + [InlineData(" // Comment\n\n public void ...", " // Comment\n\n public void ...")] + [InlineData( + " // Comment\r\n\r\n public void ...", + " // Comment\r\n\r\n public void ..." + )] + [InlineData( + " // Comment\n \n \n public void ...", + " // Comment\n\n public void ..." + )] + public void InputShouldBeCleaned(string input, string expected) { - [Theory] - [InlineData(" \n", "\n")] - [InlineData(" \n \n", "\n")] - [InlineData(" \r\n \r\n", "\r\n")] - [InlineData("\n\n\n", "\n")] - [InlineData("\r\n\r\n\r\n", "\r\n")] - [InlineData(" // Comment\n\n public void ...", " // Comment\n\n public void ...")] - [InlineData(" // Comment\r\n\r\n public void ...", " // Comment\r\n\r\n public void ...")] - [InlineData(" // Comment\n \n \n public void ...", " // Comment\n\n public void ...")] - public void InputShouldBeCleaned(string input, string expected) - { - var paddingCleaner = new PaddingCleaner(); - string output = paddingCleaner.Clean(input); + var paddingCleaner = new PaddingCleaner(); + string output = paddingCleaner.Clean(input); - output.Should().Be(expected); - } + output.Should().Be(expected); } -} \ No newline at end of file +} diff --git a/src/CodeButler/tests/CodeButler.UnitTests/Reorganizing/MemberInfoComparerTest.cs b/src/CodeButler/tests/CodeButler.UnitTests/Reorganizing/MemberInfoComparerTest.cs index 51f16e0..aeecdca 100644 --- a/src/CodeButler/tests/CodeButler.UnitTests/Reorganizing/MemberInfoComparerTest.cs +++ b/src/CodeButler/tests/CodeButler.UnitTests/Reorganizing/MemberInfoComparerTest.cs @@ -3,194 +3,193 @@ using FluentAssertions; using Xunit; -namespace CodeButler.Test.Reorganizing +namespace CodeButler.UnitTests.Reorganizing; + +public class MemberInfoComparerTest { - public class MemberInfoComparerTest + [Theory] + [InlineData("A", "A", 0)] + [InlineData("a", "a", 0)] + [InlineData("A", "B", -1)] + [InlineData("C", "B", 1)] + [InlineData("a", "A", 1)] + [InlineData("A", "a", -1)] + [InlineData("a", "aa", -1)] + [InlineData("aA", "Aa", 1)] + public void OrderByIdentifier(string left, string right, int expected) { - [Theory] - [InlineData("A", "A", 0)] - [InlineData("a", "a", 0)] - [InlineData("A", "B", -1)] - [InlineData("C", "B", 1)] - [InlineData("a", "A", 1)] - [InlineData("A", "a", -1)] - [InlineData("a", "aa", -1)] - [InlineData("aA", "Aa", 1)] - public void OrderByIdentifier(string left, string right, int expected) - { - var leftMemberInfo = new MemberInfo() { Identifier = left }; - var rightMemberInfo = new MemberInfo() { Identifier = right }; + var leftMemberInfo = new MemberInfo() { Identifier = left }; + var rightMemberInfo = new MemberInfo() { Identifier = right }; - var result = MemberInfoComparer.Default.Compare(leftMemberInfo, rightMemberInfo); + var result = MemberInfoComparer.Default.Compare(leftMemberInfo, rightMemberInfo); - AssertCompare(expected, result); - } + AssertCompare(expected, result); + } - [Theory] - [InlineData( - MemberType.Field, - MemberAccessModifier.Private, - MemberType.Property, - MemberAccessModifier.Public, - -1 - )] - public void OrderByMemberTypeThenByAccessModifier( - MemberType leftType, - MemberAccessModifier leftAccess, - MemberType rightType, - MemberAccessModifier rightAccess, - int expected - ) + [Theory] + [InlineData( + MemberType.Field, + MemberAccessModifier.Private, + MemberType.Property, + MemberAccessModifier.Public, + -1 + )] + public void OrderByMemberTypeThenByAccessModifier( + MemberType leftType, + MemberAccessModifier leftAccess, + MemberType rightType, + MemberAccessModifier rightAccess, + int expected + ) + { + var leftMemberInfo = new MemberInfo() { - var leftMemberInfo = new MemberInfo() - { - MemberType = leftType, - AccessModifier = leftAccess - }; - var rightMemberInfo = new MemberInfo() - { - MemberType = rightType, - AccessModifier = rightAccess - }; - - var result = MemberInfoComparer.Default.Compare(leftMemberInfo, rightMemberInfo); - - AssertCompare(expected, result); - } - - [Theory] - [InlineData( - MemberAccessModifier.Private, - MemberAdditionalModifier.Const, - MemberAccessModifier.Public, - MemberAdditionalModifier.Static, - 1 - )] - public void OrderByAccessModifierThenByAdditionalModifier( - MemberAccessModifier leftAccess, - MemberAdditionalModifier leftAdditional, - MemberAccessModifier rightAccess, - MemberAdditionalModifier rightAdditional, - int expected - ) + MemberType = leftType, + AccessModifier = leftAccess + }; + var rightMemberInfo = new MemberInfo() { - var leftMemberInfo = new MemberInfo() - { - AccessModifier = leftAccess, - AdditionalModifier = leftAdditional - }; - var rightMemberInfo = new MemberInfo() - { - AccessModifier = rightAccess, - AdditionalModifier = rightAdditional - }; - - var result = MemberInfoComparer.Default.Compare(leftMemberInfo, rightMemberInfo); - - AssertCompare(expected, result); - } + MemberType = rightType, + AccessModifier = rightAccess + }; - [Theory] - [InlineData(MemberAdditionalModifier.Const, "B", MemberAdditionalModifier.Static, "A", -1)] - public void OrderByAdditionalModifierThenByIdentifier( - MemberAdditionalModifier leftAdditional, - string leftIdentifier, - MemberAdditionalModifier rightAdditional, - string rightIdentifier, - int expected - ) - { - var leftMemberInfo = new MemberInfo() - { - AdditionalModifier = leftAdditional, - Identifier = leftIdentifier - }; - var rightMemberInfo = new MemberInfo() - { - AdditionalModifier = rightAdditional, - Identifier = rightIdentifier - }; - - var result = MemberInfoComparer.Default.Compare(leftMemberInfo, rightMemberInfo); - - AssertCompare(expected, result); - } + var result = MemberInfoComparer.Default.Compare(leftMemberInfo, rightMemberInfo); - [Theory] - [InlineData(MemberAdditionalModifier.None, MemberAdditionalModifier.None, 0)] - [InlineData(MemberAdditionalModifier.Const, MemberAdditionalModifier.Readonly, -1)] - [InlineData(MemberAdditionalModifier.Readonly, MemberAdditionalModifier.StaticReadonly, 1)] - [InlineData(MemberAdditionalModifier.None, MemberAdditionalModifier.Const, 1)] - public void OrderByAdditionalModifier( - MemberAdditionalModifier left, - MemberAdditionalModifier right, - int expected - ) + AssertCompare(expected, result); + } + + [Theory] + [InlineData( + MemberAccessModifier.Private, + MemberAdditionalModifier.Const, + MemberAccessModifier.Public, + MemberAdditionalModifier.Static, + 1 + )] + public void OrderByAccessModifierThenByAdditionalModifier( + MemberAccessModifier leftAccess, + MemberAdditionalModifier leftAdditional, + MemberAccessModifier rightAccess, + MemberAdditionalModifier rightAdditional, + int expected + ) + { + var leftMemberInfo = new MemberInfo() + { + AccessModifier = leftAccess, + AdditionalModifier = leftAdditional + }; + var rightMemberInfo = new MemberInfo() { - var leftMemberInfo = new MemberInfo() { AdditionalModifier = left }; - var rightMemberInfo = new MemberInfo() { AdditionalModifier = right }; + AccessModifier = rightAccess, + AdditionalModifier = rightAdditional + }; - var result = MemberInfoComparer.Default.Compare(leftMemberInfo, rightMemberInfo); + var result = MemberInfoComparer.Default.Compare(leftMemberInfo, rightMemberInfo); - AssertCompare(expected, result); - } + AssertCompare(expected, result); + } - [Theory] - [InlineData(MemberAccessModifier.None, MemberAccessModifier.None, 0)] - [InlineData(MemberAccessModifier.Private, MemberAccessModifier.Private, 0)] - [InlineData(MemberAccessModifier.Public, MemberAccessModifier.Protected, -1)] - [InlineData(MemberAccessModifier.Internal, MemberAccessModifier.ProtectedInternal, -1)] - [InlineData(MemberAccessModifier.Protected, MemberAccessModifier.None, -1)] - [InlineData(MemberAccessModifier.PrivateProtected, MemberAccessModifier.Public, 1)] - public void OrderByAccessModifier( - MemberAccessModifier left, - MemberAccessModifier right, - int expected - ) + [Theory] + [InlineData(MemberAdditionalModifier.Const, "B", MemberAdditionalModifier.Static, "A", -1)] + public void OrderByAdditionalModifierThenByIdentifier( + MemberAdditionalModifier leftAdditional, + string leftIdentifier, + MemberAdditionalModifier rightAdditional, + string rightIdentifier, + int expected + ) + { + var leftMemberInfo = new MemberInfo() + { + AdditionalModifier = leftAdditional, + Identifier = leftIdentifier + }; + var rightMemberInfo = new MemberInfo() { - var leftMemberInfo = new MemberInfo() { AccessModifier = left }; - var rightMemberInfo = new MemberInfo() { AccessModifier = right }; + AdditionalModifier = rightAdditional, + Identifier = rightIdentifier + }; - var result = MemberInfoComparer.Default.Compare(leftMemberInfo, rightMemberInfo); + var result = MemberInfoComparer.Default.Compare(leftMemberInfo, rightMemberInfo); - AssertCompare(expected, result); - } + AssertCompare(expected, result); + } - [Theory] - [InlineData(MemberType.None, MemberType.None, 0)] - [InlineData(MemberType.Field, MemberType.Field, 0)] - [InlineData(MemberType.Constructor, MemberType.Destructor, -1)] - [InlineData(MemberType.Interface, MemberType.Method, -1)] - [InlineData(MemberType.Event, MemberType.Delegate, 1)] - [InlineData(MemberType.Property, MemberType.Enum, 1)] - public void OrderByType(MemberType left, MemberType right, int expected) - { - var leftMemberInfo = new MemberInfo() { MemberType = left }; - var rightMemberInfo = new MemberInfo() { MemberType = right }; + [Theory] + [InlineData(MemberAdditionalModifier.None, MemberAdditionalModifier.None, 0)] + [InlineData(MemberAdditionalModifier.Const, MemberAdditionalModifier.Readonly, -1)] + [InlineData(MemberAdditionalModifier.Readonly, MemberAdditionalModifier.StaticReadonly, 1)] + [InlineData(MemberAdditionalModifier.None, MemberAdditionalModifier.Const, 1)] + public void OrderByAdditionalModifier( + MemberAdditionalModifier left, + MemberAdditionalModifier right, + int expected + ) + { + var leftMemberInfo = new MemberInfo() { AdditionalModifier = left }; + var rightMemberInfo = new MemberInfo() { AdditionalModifier = right }; - var result = MemberInfoComparer.Default.Compare(leftMemberInfo, rightMemberInfo); + var result = MemberInfoComparer.Default.Compare(leftMemberInfo, rightMemberInfo); - AssertCompare(expected, result); - } + AssertCompare(expected, result); + } + + [Theory] + [InlineData(MemberAccessModifier.None, MemberAccessModifier.None, 0)] + [InlineData(MemberAccessModifier.Private, MemberAccessModifier.Private, 0)] + [InlineData(MemberAccessModifier.Public, MemberAccessModifier.Protected, -1)] + [InlineData(MemberAccessModifier.Internal, MemberAccessModifier.ProtectedInternal, -1)] + [InlineData(MemberAccessModifier.Protected, MemberAccessModifier.None, -1)] + [InlineData(MemberAccessModifier.PrivateProtected, MemberAccessModifier.Public, 1)] + public void OrderByAccessModifier( + MemberAccessModifier left, + MemberAccessModifier right, + int expected + ) + { + var leftMemberInfo = new MemberInfo() { AccessModifier = left }; + var rightMemberInfo = new MemberInfo() { AccessModifier = right }; + + var result = MemberInfoComparer.Default.Compare(leftMemberInfo, rightMemberInfo); + + AssertCompare(expected, result); + } + + [Theory] + [InlineData(MemberType.None, MemberType.None, 0)] + [InlineData(MemberType.Field, MemberType.Field, 0)] + [InlineData(MemberType.Constructor, MemberType.Destructor, -1)] + [InlineData(MemberType.Interface, MemberType.Method, -1)] + [InlineData(MemberType.Event, MemberType.Delegate, 1)] + [InlineData(MemberType.Property, MemberType.Enum, 1)] + public void OrderByType(MemberType left, MemberType right, int expected) + { + var leftMemberInfo = new MemberInfo() { MemberType = left }; + var rightMemberInfo = new MemberInfo() { MemberType = right }; - private static void AssertCompare(int expected, int result) + var result = MemberInfoComparer.Default.Compare(leftMemberInfo, rightMemberInfo); + + AssertCompare(expected, result); + } + + private static void AssertCompare(int expected, int result) + { + if (expected == 0) + { + result.Should().Be(0); + } + else if (expected < 0) + { + result.Should().BeNegative(); + } + else if (expected > 0) + { + result.Should().BePositive(); + } + else { - if (expected == 0) - { - result.Should().Be(0); - } - else if (expected < 0) - { - result.Should().BeNegative(); - } - else if (expected > 0) - { - result.Should().BePositive(); - } - else - { - throw new Exception("CompareAssert badly implemented."); - } + throw new Exception("CompareAssert badly implemented."); } } } diff --git a/src/CodeButler/tests/CodeButler.UnitTests/Reorganizing/UsingOrderInfoTest.cs b/src/CodeButler/tests/CodeButler.UnitTests/Reorganizing/UsingOrderInfoTest.cs index 652cdaf..185819c 100644 --- a/src/CodeButler/tests/CodeButler.UnitTests/Reorganizing/UsingOrderInfoTest.cs +++ b/src/CodeButler/tests/CodeButler.UnitTests/Reorganizing/UsingOrderInfoTest.cs @@ -4,155 +4,174 @@ using FluentAssertions; using Xunit; -namespace CodeButler.Test.Reorganizing +namespace CodeButler.UnitTests.Reorganizing; + +public class UsingInfoTest { - public class UsingOrderInfoTest + [Theory] + [InlineData("System", "System", 0)] + [InlineData("System.Test", "System", 1)] + [InlineData("System", "System.Test", -1)] + [InlineData("System", "Xunit", -1)] + [InlineData("Xunit", "System", 1)] + [InlineData("System", "FluentAssertions", 1)] + [InlineData("Xunit", "FluentAssertions", 1)] + [InlineData(null, "A", -1)] + [InlineData(null, null, 0)] + [InlineData("A", null, 1)] + public void OrderByAlias(string left, string right, int expected) { - [Theory] - [InlineData("System", "System", 0)] - [InlineData("System.Test", "System", 1)] - [InlineData("System", "System.Test", -1)] - [InlineData("System", "Xunit", -1)] - [InlineData("Xunit", "System", 1)] - [InlineData("System", "FluentAssertions", 1)] - [InlineData("Xunit", "FluentAssertions", 1)] - [InlineData(null, "A", -1)] - [InlineData(null, null, 0)] - [InlineData("A", null, 1)] - public void OrderByAlias(string left, string right, int expected) - { - var leftUsingInfo = new UsingOrderInfo(string.Empty) { Alias = left }; - var rightUsingInfo = new UsingOrderInfo(string.Empty) { Alias = right }; + var leftUsingInfo = new UsingInfo(string.Empty) { Alias = left }; + var rightUsingInfo = new UsingInfo(string.Empty) { Alias = right }; - int result = leftUsingInfo.CompareByAlias(rightUsingInfo); + int result = leftUsingInfo.CompareByAlias(rightUsingInfo); - AssertCompare(expected, result); - } + AssertCompare(expected, result); + } - [Theory] - [InlineData("Alias-A", "Name-B", "Alias-B", "Name-A", -1)] - [InlineData("Alias-B", "Name-B", "Alias-A", "Name-A", 1)] - [InlineData("Alias", "Name-B", "Alias", "Name-A", 1)] - [InlineData("Alias", "Name-A", "Alias", "Name-B", -1)] - [InlineData(null, "Name-A", null, "Name-B", -1)] - [InlineData(null, "Name-A", null, "Name-A", 0)] - public void OrderByAliasThenByName(string leftAlias, string leftName, string rightAlias, string rightName, int expected) - { - var leftUsingInfo = new UsingOrderInfo(leftName) { Alias = leftAlias }; - var rightUsingInfo = new UsingOrderInfo(rightName) { Alias = rightAlias }; + [Theory] + [InlineData("Alias-A", "Name-B", "Alias-B", "Name-A", -1)] + [InlineData("Alias-B", "Name-B", "Alias-A", "Name-A", 1)] + [InlineData("Alias", "Name-B", "Alias", "Name-A", 1)] + [InlineData("Alias", "Name-A", "Alias", "Name-B", -1)] + [InlineData(null, "Name-A", null, "Name-B", -1)] + [InlineData(null, "Name-A", null, "Name-A", 0)] + public void OrderByAliasThenByName( + string leftAlias, + string leftName, + string rightAlias, + string rightName, + int expected + ) + { + var leftUsingInfo = new UsingInfo(leftName) { Alias = leftAlias }; + var rightUsingInfo = new UsingInfo(rightName) { Alias = rightAlias }; - int result = leftUsingInfo.CompareTo(rightUsingInfo); + int result = leftUsingInfo.CompareTo(rightUsingInfo); - AssertCompare(expected, result); - } + AssertCompare(expected, result); + } - [Theory] - [InlineData(false, "B", true, "A", -1)] - [InlineData(true, "A", false, "B", 1)] - [InlineData(false, "A", false, "B", -1)] - [InlineData(true, "A", true, "B", -1)] - [InlineData(true, "B", true, "A", 1)] - [InlineData(false, "A", false, "A", 0)] - [InlineData(true, null, true, null, 0)] - public void OrderByIsStaticThenByAlias(bool leftIsStatic, string leftAlias, bool rightIsStatic, string rightAlias, int expected) + [Theory] + [InlineData(false, "B", true, "A", -1)] + [InlineData(true, "A", false, "B", 1)] + [InlineData(false, "A", false, "B", -1)] + [InlineData(true, "A", true, "B", -1)] + [InlineData(true, "B", true, "A", 1)] + [InlineData(false, "A", false, "A", 0)] + [InlineData(true, null, true, null, 0)] + public void OrderByIsStaticThenByAlias( + bool leftIsStatic, + string leftAlias, + bool rightIsStatic, + string rightAlias, + int expected + ) + { + var leftUsingInfo = new UsingInfo(string.Empty) { - var leftUsingInfo = new UsingOrderInfo(string.Empty) { IsStatic = leftIsStatic, Alias = leftAlias }; - var rightUsingInfo = new UsingOrderInfo(string.Empty) { IsStatic = rightIsStatic, Alias = rightAlias }; + IsStatic = leftIsStatic, + Alias = leftAlias + }; + var rightUsingInfo = new UsingInfo(string.Empty) + { + IsStatic = rightIsStatic, + Alias = rightAlias + }; - int result = leftUsingInfo.CompareTo(rightUsingInfo); + int result = leftUsingInfo.CompareTo(rightUsingInfo); - AssertCompare(expected, result); - } + AssertCompare(expected, result); + } - [Theory] - [InlineData("System", "System", 0)] - [InlineData("System.Test", "System", 1)] - [InlineData("System", "System.Test", -1)] - [InlineData("System", "Xunit", -1)] - [InlineData("Xunit", "System", 1)] - [InlineData("System", "FluentAssertions", -1)] - [InlineData("Xunit", "FluentAssertions", 1)] - public void OrderByName(string left, string right, int expected) - { - var leftUsingInfo = new UsingOrderInfo(left); - var rightUsingInfo = new UsingOrderInfo(right); + [Theory] + [InlineData("System", "System", 0)] + [InlineData("System.Test", "System", 1)] + [InlineData("System", "System.Test", -1)] + [InlineData("System", "Xunit", -1)] + [InlineData("Xunit", "System", 1)] + [InlineData("System", "FluentAssertions", -1)] + [InlineData("Xunit", "FluentAssertions", 1)] + public void OrderByName(string left, string right, int expected) + { + var leftUsingInfo = new UsingInfo(left); + var rightUsingInfo = new UsingInfo(right); - int result = leftUsingInfo.CompareByName(rightUsingInfo); + int result = leftUsingInfo.CompareByName(rightUsingInfo); - AssertCompare(expected, result); - } + AssertCompare(expected, result); + } - [Theory] - [InlineData(false, false, 0)] - [InlineData(false, true, -1)] - [InlineData(true, false, 1)] - [InlineData(true, true, 0)] - public void OrderByStatic(bool left, bool right, int expected) - { - var leftUsingInfo = new UsingOrderInfo(string.Empty) { IsStatic = left }; - var rightUsingInfo = new UsingOrderInfo(string.Empty) { IsStatic = right }; + [Theory] + [InlineData(false, false, 0)] + [InlineData(false, true, -1)] + [InlineData(true, false, 1)] + [InlineData(true, true, 0)] + public void OrderByStatic(bool left, bool right, int expected) + { + var leftUsingInfo = new UsingInfo(string.Empty) { IsStatic = left }; + var rightUsingInfo = new UsingInfo(string.Empty) { IsStatic = right }; - int result = leftUsingInfo.CompareByIsStatic(rightUsingInfo); + int result = leftUsingInfo.CompareByIsStatic(rightUsingInfo); - AssertCompare(expected, result); - } + AssertCompare(expected, result); + } - [Theory] - [InlineData(true, false, -1)] - [InlineData(false, true, 1)] - [InlineData(false, false, 0)] - [InlineData(true, true, 0)] - public void OrderByGlobal(bool left, bool right, int expected) - { - var leftUsingInfo = new UsingOrderInfo(string.Empty) { IsGlobal = left }; - var rightUsingInfo = new UsingOrderInfo(string.Empty) { IsGlobal = right }; + [Theory] + [InlineData(true, false, -1)] + [InlineData(false, true, 1)] + [InlineData(false, false, 0)] + [InlineData(true, true, 0)] + public void OrderByGlobal(bool left, bool right, int expected) + { + var leftUsingInfo = new UsingInfo(string.Empty) { IsGlobal = left }; + var rightUsingInfo = new UsingInfo(string.Empty) { IsGlobal = right }; - int result = leftUsingInfo.CompareByIsGlobal(rightUsingInfo); + int result = leftUsingInfo.CompareByIsGlobal(rightUsingInfo); - AssertCompare(expected, result); - } + AssertCompare(expected, result); + } - [Fact] - public void Order_Should_Be_As_Expected() + [Fact] + public void Order_Should_Be_As_Expected() + { + var expected = new UsingInfo[] + { + new("System.Linq") { IsGlobal = true }, + new("System"), + new("System.Text"), + new("Xunit"), + new("Xunit.Fact") { Alias = "FakeNews" }, + new("System.Math") { IsStatic = true }, + }; + + var rnd = new Random(); + var input = expected.OrderBy(_ => rnd.Next()).ToArray(); + var sorted = input.OrderBy(x => x).ToArray(); + + for (int i = 0; i < expected.Length; i++) { - var expected = new UsingOrderInfo[] - { - new("System.Linq") { IsGlobal = true }, - new("System"), - new("System.Text"), - new("Xunit"), - new("Xunit.Fact") { Alias = "FakeNews" }, - new("System.Math") { IsStatic = true }, - }; - - var rnd = new Random(); - var input = expected.OrderBy(_ => rnd.Next()).ToArray(); - var sorted = input.OrderBy(x => x).ToArray(); - - for (int i = 0; i < expected.Length; i++) - { - sorted[i].Should().BeSameAs(expected[i]); - } + sorted[i].Should().BeSameAs(expected[i]); } + } - private static void AssertCompare(int expected, int result) + private static void AssertCompare(int expected, int result) + { + if (expected == 0) + { + result.Should().Be(0); + } + else if (expected < 0) + { + result.Should().BeNegative(); + } + else if (expected > 0) + { + result.Should().BePositive(); + } + else { - if (expected == 0) - { - result.Should().Be(0); - } - else if (expected < 0) - { - result.Should().BeNegative(); - } - else if (expected > 0) - { - result.Should().BePositive(); - } - else - { - throw new Exception("CompareAssert badly implemented."); - } + throw new Exception("CompareAssert badly implemented."); } } -} \ No newline at end of file +} diff --git a/src/CodeButler/tests/CodeButler.UnitTests/Syntax/UsingDirectiveSyntaxTest.cs b/src/CodeButler/tests/CodeButler.UnitTests/Syntax/UsingDirectiveSyntaxTest.cs index 85729f0..8481463 100644 --- a/src/CodeButler/tests/CodeButler.UnitTests/Syntax/UsingDirectiveSyntaxTest.cs +++ b/src/CodeButler/tests/CodeButler.UnitTests/Syntax/UsingDirectiveSyntaxTest.cs @@ -3,32 +3,36 @@ using Microsoft.CodeAnalysis.CSharp; using Xunit; -namespace CodeButler.Test.Syntax +namespace CodeButler.UnitTests.Syntax; + +public class UsingDirectiveSyntaxTest { - public class UsingDirectiveSyntaxTest + [Theory] + [InlineData("System", null, false, false)] + [InlineData("System", null, false, true)] + [InlineData("System.Math", null, true, false)] + [InlineData("System.Math", null, true, true)] + [InlineData("System.Test", "Test", false, false)] + [InlineData("System.Test", "Test", true, false)] + public void GetUsingOrderInfoTest(string name, string alias, bool isStatic, bool isGlobal) { - [Theory] - [InlineData("System", null, false, false)] - [InlineData("System", null, false, true)] - [InlineData("System.Math", null, true, false)] - [InlineData("System.Math", null, true, true)] - [InlineData("System.Test", "Test", false, false)] - [InlineData("System.Test", "Test", true, false)] - public void GetUsingOrderInfoTest(string name, string alias, bool isStatic, bool isGlobal) - { - var usingDirective = SyntaxFactory.UsingDirective( - globalKeyword: SyntaxFactory.Token(isGlobal ? SyntaxKind.GlobalKeyword : SyntaxKind.None), - usingKeyword: SyntaxFactory.Token(SyntaxKind.UsingKeyword), - staticKeyword: SyntaxFactory.Token(isStatic ? SyntaxKind.StaticKeyword : SyntaxKind.None), - alias: alias is null ? null : SyntaxFactory.NameEquals(alias), - name: SyntaxFactory.ParseName(name), - semicolonToken: SyntaxFactory.Token(SyntaxKind.SemicolonToken)); + var usingDirective = SyntaxFactory.UsingDirective( + globalKeyword: SyntaxFactory.Token( + isGlobal ? SyntaxKind.GlobalKeyword : SyntaxKind.None + ), + usingKeyword: SyntaxFactory.Token(SyntaxKind.UsingKeyword), + staticKeyword: SyntaxFactory.Token( + isStatic ? SyntaxKind.StaticKeyword : SyntaxKind.None + ), + alias: alias is null ? null : SyntaxFactory.NameEquals(alias), + name: SyntaxFactory.ParseName(name), + semicolonToken: SyntaxFactory.Token(SyntaxKind.SemicolonToken) + ); - var usingOrderInfo = usingDirective.GetUsingOrderInfo(); - usingOrderInfo.Name.Should().Be(name); - usingOrderInfo.Alias.Should().Be(alias); - usingOrderInfo.IsStatic.Should().Be(isStatic); - usingOrderInfo.IsGlobal.Should().Be(isGlobal); - } + var usingOrderInfo = usingDirective.GetUsingInfo(); + usingOrderInfo.Name.Should().Be(name); + usingOrderInfo.Alias.Should().Be(alias); + usingOrderInfo.IsStatic.Should().Be(isStatic); + usingOrderInfo.IsGlobal.Should().Be(isGlobal); } -} \ No newline at end of file +} From 4ae4ad39038c36b76f4bbb3e90ed6176feb7751e Mon Sep 17 00:00:00 2001 From: just-seba <46223600+just-seba@users.noreply.github.com> Date: Sat, 2 Mar 2024 13:49:24 +0100 Subject: [PATCH 04/10] chore: Update NuGet packages, fixes new warnings. --- src/CodeButler/CodeButler.Console/CodeButler.Console.csproj | 6 +++--- ...rInfoSortConfiguration.cs => MemberSortConfiguration.cs} | 0 .../{RootCommand.cs => RootCommandHandler.cs} | 2 +- .../CodeButler.Console/Syntax/UsingInfoFactory.cs | 2 +- .../CodeButler.IntegrationTests.csproj | 4 ++++ .../tests/CodeButler.UnitTests/CodeButler.UnitTests.csproj | 4 ++++ .../{UsingOrderInfoTest.cs => UsingInfoTest.cs} | 2 +- 7 files changed, 14 insertions(+), 6 deletions(-) rename src/CodeButler/CodeButler.Console/Reorganizing/{MemberInfoSortConfiguration.cs => MemberSortConfiguration.cs} (100%) rename src/CodeButler/CodeButler.Console/{RootCommand.cs => RootCommandHandler.cs} (99%) rename src/CodeButler/tests/CodeButler.UnitTests/Reorganizing/{UsingOrderInfoTest.cs => UsingInfoTest.cs} (99%) diff --git a/src/CodeButler/CodeButler.Console/CodeButler.Console.csproj b/src/CodeButler/CodeButler.Console/CodeButler.Console.csproj index 160f7d3..21f1375 100644 --- a/src/CodeButler/CodeButler.Console/CodeButler.Console.csproj +++ b/src/CodeButler/CodeButler.Console/CodeButler.Console.csproj @@ -10,9 +10,9 @@ - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/CodeButler/CodeButler.Console/Reorganizing/MemberInfoSortConfiguration.cs b/src/CodeButler/CodeButler.Console/Reorganizing/MemberSortConfiguration.cs similarity index 100% rename from src/CodeButler/CodeButler.Console/Reorganizing/MemberInfoSortConfiguration.cs rename to src/CodeButler/CodeButler.Console/Reorganizing/MemberSortConfiguration.cs diff --git a/src/CodeButler/CodeButler.Console/RootCommand.cs b/src/CodeButler/CodeButler.Console/RootCommandHandler.cs similarity index 99% rename from src/CodeButler/CodeButler.Console/RootCommand.cs rename to src/CodeButler/CodeButler.Console/RootCommandHandler.cs index ce11e5d..c8be960 100644 --- a/src/CodeButler/CodeButler.Console/RootCommand.cs +++ b/src/CodeButler/CodeButler.Console/RootCommandHandler.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.CommandLine; using System.IO; using System.Threading.Tasks; diff --git a/src/CodeButler/CodeButler.Console/Syntax/UsingInfoFactory.cs b/src/CodeButler/CodeButler.Console/Syntax/UsingInfoFactory.cs index e8ba936..642fa4d 100644 --- a/src/CodeButler/CodeButler.Console/Syntax/UsingInfoFactory.cs +++ b/src/CodeButler/CodeButler.Console/Syntax/UsingInfoFactory.cs @@ -7,7 +7,7 @@ public static class UsingInfoFactory { public static UsingInfo GetUsingInfo(this UsingDirectiveSyntax usingDirective) { - return new UsingInfo(usingDirective.Name.ToString()) + return new UsingInfo(usingDirective.Name?.ToString() ?? string.Empty) { Alias = usingDirective.Alias?.Name.ToString(), IsStatic = usingDirective.StaticKeyword != default, diff --git a/src/CodeButler/tests/CodeButler.IntegrationTests/CodeButler.IntegrationTests.csproj b/src/CodeButler/tests/CodeButler.IntegrationTests/CodeButler.IntegrationTests.csproj index ce4aec2..2aa9753 100644 --- a/src/CodeButler/tests/CodeButler.IntegrationTests/CodeButler.IntegrationTests.csproj +++ b/src/CodeButler/tests/CodeButler.IntegrationTests/CodeButler.IntegrationTests.csproj @@ -14,6 +14,10 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + all diff --git a/src/CodeButler/tests/CodeButler.UnitTests/CodeButler.UnitTests.csproj b/src/CodeButler/tests/CodeButler.UnitTests/CodeButler.UnitTests.csproj index 6e2e12c..a1d2882 100644 --- a/src/CodeButler/tests/CodeButler.UnitTests/CodeButler.UnitTests.csproj +++ b/src/CodeButler/tests/CodeButler.UnitTests/CodeButler.UnitTests.csproj @@ -8,6 +8,10 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/CodeButler/tests/CodeButler.UnitTests/Reorganizing/UsingOrderInfoTest.cs b/src/CodeButler/tests/CodeButler.UnitTests/Reorganizing/UsingInfoTest.cs similarity index 99% rename from src/CodeButler/tests/CodeButler.UnitTests/Reorganizing/UsingOrderInfoTest.cs rename to src/CodeButler/tests/CodeButler.UnitTests/Reorganizing/UsingInfoTest.cs index 185819c..60dfc1f 100644 --- a/src/CodeButler/tests/CodeButler.UnitTests/Reorganizing/UsingOrderInfoTest.cs +++ b/src/CodeButler/tests/CodeButler.UnitTests/Reorganizing/UsingInfoTest.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq; using CodeButler.Reorganizing; using FluentAssertions; From ffe21ba3094fa022f1ae27e69c0f54bf863fd4f3 Mon Sep 17 00:00:00 2001 From: just-seba <46223600+just-seba@users.noreply.github.com> Date: Sat, 2 Mar 2024 14:16:41 +0100 Subject: [PATCH 05/10] feat: Support for `using`statements below file-scoped `namespace`declaration. --- .../CodeButler.Console/RootCommandHandler.cs | 13 +++++---- .../Syntax/SyntaxReorganizerRewriter.cs | 29 ++++++++++++------- .../IntegrationTests.cs | 5 ++++ .../file-scoped-namespace/clean.cs.test | 12 ++++++++ .../file-scoped-namespace/original.cs.test | 15 ++++++++++ 5 files changed, 58 insertions(+), 16 deletions(-) create mode 100644 src/CodeButler/tests/CodeButler.IntegrationTests/TestCases/file-scoped-namespace/clean.cs.test create mode 100644 src/CodeButler/tests/CodeButler.IntegrationTests/TestCases/file-scoped-namespace/original.cs.test diff --git a/src/CodeButler/CodeButler.Console/RootCommandHandler.cs b/src/CodeButler/CodeButler.Console/RootCommandHandler.cs index c8be960..3681ae9 100644 --- a/src/CodeButler/CodeButler.Console/RootCommandHandler.cs +++ b/src/CodeButler/CodeButler.Console/RootCommandHandler.cs @@ -18,10 +18,7 @@ public static async Task Handle(RootCommandConfiguration configuration) var clean = Clean(input); var root = Parse(clean); - var organizedRoot = Reorganize( - root, - new MemberSortConfiguration { SortByAlphabet = configuration.SortMemberByAlphabet } - ); + var organizedRoot = Reorganize(root, configuration); await WriteOutput(organizedRoot, configuration).ConfigureAwait(false); } @@ -43,10 +40,14 @@ private static CompilationUnitSyntax Parse(string input) private static CompilationUnitSyntax Reorganize( CompilationUnitSyntax compilationUnit, - MemberSortConfiguration memberSortConfiguration + RootCommandConfiguration configuration ) { - var organizer = new SyntaxReorganizerRewriter(memberSortConfiguration); + var comparer = new MemberInfoComparer( + new MemberSortConfiguration { SortByAlphabet = configuration.SortMemberByAlphabet } + ); + + var organizer = new SyntaxReorganizerRewriter(comparer); return compilationUnit.Accept(organizer) as CompilationUnitSyntax ?? throw new Exception( $"Reorganized root is null or not of type {typeof(CompilationUnitSyntax)}." diff --git a/src/CodeButler/CodeButler.Console/Syntax/SyntaxReorganizerRewriter.cs b/src/CodeButler/CodeButler.Console/Syntax/SyntaxReorganizerRewriter.cs index a8ecb45..f16d0e6 100644 --- a/src/CodeButler/CodeButler.Console/Syntax/SyntaxReorganizerRewriter.cs +++ b/src/CodeButler/CodeButler.Console/Syntax/SyntaxReorganizerRewriter.cs @@ -9,37 +9,46 @@ namespace CodeButler.Syntax; public class SyntaxReorganizerRewriter : CSharpSyntaxRewriter { - private MemberInfoComparer _memberInfoComparer; + private readonly IComparer _memberInfoComparer; - public SyntaxReorganizerRewriter(MemberSortConfiguration memberSortConfiguration) + public SyntaxReorganizerRewriter(IComparer memberInfoComparer) { - _memberInfoComparer = new(memberSortConfiguration); + _memberInfoComparer = memberInfoComparer; } - public override SyntaxNode? VisitClassDeclaration(ClassDeclarationSyntax node) + public override SyntaxNode? VisitCompilationUnit(CompilationUnitSyntax node) { + var usings = OrganizeUsings(node.Usings); var members = OrganizeMembers(node.Members); - return node.WithMembers(members); + return node.WithUsings(usings).WithMembers(members); } - public override SyntaxNode? VisitCompilationUnit(CompilationUnitSyntax node) + public override SyntaxNode? VisitNamespaceDeclaration(NamespaceDeclarationSyntax node) { var usings = OrganizeUsings(node.Usings); var members = OrganizeMembers(node.Members); return node.WithUsings(usings).WithMembers(members); } - public override SyntaxNode? VisitInterfaceDeclaration(InterfaceDeclarationSyntax node) + public override SyntaxNode? VisitFileScopedNamespaceDeclaration( + FileScopedNamespaceDeclarationSyntax node + ) + { + var usings = OrganizeUsings(node.Usings); + var members = OrganizeMembers(node.Members); + return node.WithUsings(usings).WithMembers(members); + } + + public override SyntaxNode? VisitClassDeclaration(ClassDeclarationSyntax node) { var members = OrganizeMembers(node.Members); return node.WithMembers(members); } - public override SyntaxNode? VisitNamespaceDeclaration(NamespaceDeclarationSyntax node) + public override SyntaxNode? VisitInterfaceDeclaration(InterfaceDeclarationSyntax node) { - var usings = OrganizeUsings(node.Usings); var members = OrganizeMembers(node.Members); - return node.WithUsings(usings).WithMembers(members); + return node.WithMembers(members); } public override SyntaxNode? VisitStructDeclaration(StructDeclarationSyntax node) diff --git a/src/CodeButler/tests/CodeButler.IntegrationTests/IntegrationTests.cs b/src/CodeButler/tests/CodeButler.IntegrationTests/IntegrationTests.cs index c554302..de361dd 100644 --- a/src/CodeButler/tests/CodeButler.IntegrationTests/IntegrationTests.cs +++ b/src/CodeButler/tests/CodeButler.IntegrationTests/IntegrationTests.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Threading.Tasks; using FluentAssertions; +using Microsoft.CodeAnalysis.CSharp; using Xunit; namespace CodeButler.IntegrationTests; @@ -36,6 +37,10 @@ public async Task DirectUseOfProgramClass(string folder) var testPath = Path.Combine(_testCasesDir, folder, $"{Guid.NewGuid().ToString()[..7]}.cs"); + // Debug + var syntaxTree = CSharpSyntaxTree.ParseText(await File.ReadAllTextAsync(cleanPath)); + var root = syntaxTree.GetCompilationUnitRoot(); + // Act File.Copy(originalPath, testPath); var exitCode = await Program.Main([testPath]); diff --git a/src/CodeButler/tests/CodeButler.IntegrationTests/TestCases/file-scoped-namespace/clean.cs.test b/src/CodeButler/tests/CodeButler.IntegrationTests/TestCases/file-scoped-namespace/clean.cs.test new file mode 100644 index 0000000..b1cda25 --- /dev/null +++ b/src/CodeButler/tests/CodeButler.IntegrationTests/TestCases/file-scoped-namespace/clean.cs.test @@ -0,0 +1,12 @@ +using System; +using System.Text; +using Xunit; + +namespace TestCases.FileScopedNamespace; +using System; +using System.Linq; + +public interface ITest +{ + Task Test(); +} diff --git a/src/CodeButler/tests/CodeButler.IntegrationTests/TestCases/file-scoped-namespace/original.cs.test b/src/CodeButler/tests/CodeButler.IntegrationTests/TestCases/file-scoped-namespace/original.cs.test new file mode 100644 index 0000000..282fa37 --- /dev/null +++ b/src/CodeButler/tests/CodeButler.IntegrationTests/TestCases/file-scoped-namespace/original.cs.test @@ -0,0 +1,15 @@ +using Xunit; +using System; +using System.Text; + +namespace TestCases.FileScopedNamespace; +using System.Linq; +using System; + + + + +public interface ITest +{ + Task Test(); +} From 17bf171df4ec2d0475c9df3cf758812b2d7f73d9 Mon Sep 17 00:00:00 2001 From: just-seba <46223600+just-seba@users.noreply.github.com> Date: Sat, 2 Mar 2024 14:22:58 +0100 Subject: [PATCH 06/10] ci: Adds dependabot. --- .github/dependabot.yml | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..744a6af --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,33 @@ +version: 2 +updates: + - package-ecosystem: "nuget" + directory: "/" + schedule: + interval: "weekly" + labels: + - "dependencies" + commit-message: + prefix: "build" + include: "scope" + groups: + xunit: + patterns: + - "xunit*" + - package-ecosystem: "npm" + directory: "src/projektanker.code-butler" + schedule: + interval: "weekly" + labels: + - "dependencies" + commit-message: + prefix: "build" + include: "scope" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + labels: + - "dependencies" + commit-message: + prefix: "build" + include: "scope" From a0fa076822f56ece07a5423b1b9046bad09ff828 Mon Sep 17 00:00:00 2001 From: just-seba <46223600+just-seba@users.noreply.github.com> Date: Sat, 2 Mar 2024 14:26:08 +0100 Subject: [PATCH 07/10] ci: fixes dotnet version in pipeline. --- .github/workflows/ci-cd.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index bd089e1..e4a36ef 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -22,10 +22,13 @@ jobs: - name: 🟣 Setup .NET uses: actions/setup-dotnet@v3 with: - dotnet-version: 6.0.x + dotnet-version: 8.0.x + + - name: 🛠️ Build + run: dotnet build - name: ✔ Test - run: dotnet test --verbosity normal + run: dotnet test --no-build --verbosity normal - name: 📯 Publish run: dotnet publish ./CodeButler.Console/CodeButler.Console.csproj --output ./publish From f9e1beee13040236be1f6a1d1310129144f84809 Mon Sep 17 00:00:00 2001 From: just-seba <46223600+just-seba@users.noreply.github.com> Date: Sat, 2 Mar 2024 14:30:14 +0100 Subject: [PATCH 08/10] ci: Sets .NET version by global.json --- .github/workflows/ci-cd.yml | 18 +++++------------- global.json | 6 ++++++ 2 files changed, 11 insertions(+), 13 deletions(-) create mode 100644 global.json diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index e4a36ef..5fafa21 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -20,10 +20,8 @@ jobs: uses: actions/checkout@v3 - name: 🟣 Setup .NET - uses: actions/setup-dotnet@v3 - with: - dotnet-version: 8.0.x - + uses: actions/setup-dotnet@v4 + - name: 🛠️ Build run: dotnet build @@ -53,9 +51,7 @@ jobs: uses: actions/setup-node@v3 - name: 🟣 Setup .NET - uses: actions/setup-dotnet@v3 - with: - dotnet-version: 6.0.x + uses: actions/setup-dotnet@v4 - name: 🛠 Install NPM packages run: npm ci @@ -86,9 +82,7 @@ jobs: uses: actions/setup-node@v3 - name: 🟣 Setup .NET - uses: actions/setup-dotnet@v3 - with: - dotnet-version: 6.0.x + uses: actions/setup-dotnet@v4 - name: 🛠 Install NPM packages run: npm ci @@ -113,9 +107,7 @@ jobs: uses: actions/setup-node@v3 - name: 🟣 Setup .NET - uses: actions/setup-dotnet@v3 - with: - dotnet-version: 6.0.x + uses: actions/setup-dotnet@v4 - name: 🛠 Install NPM packages run: npm ci diff --git a/global.json b/global.json new file mode 100644 index 0000000..3b1d787 --- /dev/null +++ b/global.json @@ -0,0 +1,6 @@ +{ + "sdk": { + "version": "8.0.0", + "rollForward": "latestFeature" + } +} \ No newline at end of file From 42af1932af2ce3a847447174aef7230a466d62f5 Mon Sep 17 00:00:00 2001 From: just-seba <46223600+just-seba@users.noreply.github.com> Date: Sat, 2 Mar 2024 14:50:31 +0100 Subject: [PATCH 09/10] feat: Use file input over pipe input. --- src/CodeButler/CodeButler.Console/Program.cs | 23 ++++++++++++------- .../RootCommandConfigurationBinder.cs | 18 ++++----------- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/src/CodeButler/CodeButler.Console/Program.cs b/src/CodeButler/CodeButler.Console/Program.cs index dd0f13a..2265370 100644 --- a/src/CodeButler/CodeButler.Console/Program.cs +++ b/src/CodeButler/CodeButler.Console/Program.cs @@ -17,18 +17,25 @@ public static async Task Main(string[] args) getDefaultValue: () => false ); + var inputFileArgMeta = new + { + Name = "input", + Description = "Path to input file or piped input." + }; + var inputFileArg = Console.IsInputRedirected - ? null - : new Argument( - name: "Input", - description: "Path to input file or piped input." + ? new Argument( + name: inputFileArgMeta.Name, + description: inputFileArgMeta.Description, + getDefaultValue: () => null + ) + : new Argument( + name: inputFileArgMeta.Name, + description: inputFileArgMeta.Description ); rootCommand.AddOption(noSortMemberByAlphabetOption); - if (inputFileArg is not null) - { - rootCommand.AddArgument(inputFileArg); - } + rootCommand.AddArgument(inputFileArg); rootCommand.SetHandler( RootCommandHandler.Handle, diff --git a/src/CodeButler/CodeButler.Console/RootCommandConfigurationBinder.cs b/src/CodeButler/CodeButler.Console/RootCommandConfigurationBinder.cs index ff5d10a..1434825 100644 --- a/src/CodeButler/CodeButler.Console/RootCommandConfigurationBinder.cs +++ b/src/CodeButler/CodeButler.Console/RootCommandConfigurationBinder.cs @@ -7,11 +7,11 @@ namespace CodeButler; public class RootCommandConfigurationBinder : BinderBase { private readonly Option _noSortMemberByAlphabet; - private readonly Argument? _file; + private readonly Argument _file; public RootCommandConfigurationBinder( Option noSortMemberByAlphabet, - Argument? file + Argument file ) { _noSortMemberByAlphabet = noSortMemberByAlphabet; @@ -22,18 +22,8 @@ protected override RootCommandConfiguration GetBoundValue(BindingContext binding { var parseResult = bindingContext.ParseResult; - InputOutputMode mode; - FileInfo? file; - if (_file is null) - { - mode = InputOutputMode.Console; - file = null; - } - else - { - mode = InputOutputMode.File; - file = parseResult.GetValueForArgument(_file); - } + var file = parseResult.GetValueForArgument(_file); + var mode = file is null ? InputOutputMode.Console : InputOutputMode.File; return new RootCommandConfiguration { From 86d18641642c71d48c8d2b2235b433eb1de6ef14 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 2 Mar 2024 13:55:39 +0000 Subject: [PATCH 10/10] build(deps-dev): bump vsce in /src/projektanker.code-butler Bumps [vsce](https://github.com/Microsoft/vsce) from 1.100.1 to 2.15.0. - [Release notes](https://github.com/Microsoft/vsce/releases) - [Commits](https://github.com/Microsoft/vsce/compare/v1.100.1...v2.15.0) --- updated-dependencies: - dependency-name: vsce dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .../package-lock.json | 785 ++++++++++++------ src/projektanker.code-butler/package.json | 2 +- 2 files changed, 525 insertions(+), 262 deletions(-) diff --git a/src/projektanker.code-butler/package-lock.json b/src/projektanker.code-butler/package-lock.json index 985222b..f692a20 100644 --- a/src/projektanker.code-butler/package-lock.json +++ b/src/projektanker.code-butler/package-lock.json @@ -1,6 +1,6 @@ { "name": "code-butler", - "version": "1.4.0", + "version": "2.2.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -290,9 +290,9 @@ "dev": true }, "azure-devops-node-api": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-11.0.1.tgz", - "integrity": "sha512-YMdjAw9l5p/6leiyIloxj3k7VIvYThKjvqgiQn88r3nhT93ENwsoDS3A83CyJ4uTWzCZ5f5jCi6c27rTU5Pz+A==", + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-11.2.0.tgz", + "integrity": "sha512-XdiGPhrpaT5J8wdERRKs5g8E0Zy1pvOYTli7z9E8nmOn3YGp4FhtjhrOyFmX/8veWCwdI69mCHKJw6l+4J/bHA==", "dev": true, "requires": { "tunnel": "0.0.6", @@ -305,10 +305,35 @@ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true + }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + } + } + }, "boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", "dev": true }, "brace-expansion": { @@ -330,20 +355,33 @@ "fill-range": "^7.0.1" } }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, "buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", "dev": true }, "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dev": true, "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" } }, "callsites": { @@ -364,45 +402,38 @@ } }, "cheerio": { - "version": "1.0.0-rc.10", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz", - "integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==", - "dev": true, - "requires": { - "cheerio-select": "^1.5.0", - "dom-serializer": "^1.3.2", - "domhandler": "^4.2.0", - "htmlparser2": "^6.1.0", - "parse5": "^6.0.1", - "parse5-htmlparser2-tree-adapter": "^6.0.1", - "tslib": "^2.2.0" - }, - "dependencies": { - "tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", - "dev": true - } + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "dev": true, + "requires": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" } }, "cheerio-select": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.5.0.tgz", - "integrity": "sha512-qocaHPv5ypefh6YNxvnbABM07KMxExbtbfuJoIie3iZXX1ERwYmJcIiRrr9H05ucQP1k28dav8rpdDgjQd8drg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", "dev": true, "requires": { - "css-select": "^4.1.3", - "css-what": "^5.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0", - "domutils": "^2.7.0" + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" } }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", "dev": true }, "color-convert": { @@ -444,22 +475,22 @@ } }, "css-select": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.1.3.tgz", - "integrity": "sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", "dev": true, "requires": { "boolbase": "^1.0.0", - "css-what": "^5.0.0", - "domhandler": "^4.2.0", - "domutils": "^2.6.0", - "nth-check": "^2.0.0" + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" } }, "css-what": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.0.1.tgz", - "integrity": "sha512-FYDTSHb/7KXsWICVsxdmiExPjCfRC4qRFBdVwv7Ax9hMnvMmEjP9RfxTEZ3qPZGmADDn2vAKSo9UcN1jKVYscg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", "dev": true }, "debug": { @@ -471,16 +502,42 @@ "ms": "2.1.2" } }, + "decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "requires": { + "mimic-response": "^3.1.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, "deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, - "denodeify": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/denodeify/-/denodeify-1.2.1.tgz", - "integrity": "sha1-OjYof1A05pnnV3kBBSwubJQlFjE=", + "define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + } + }, + "detect-libc": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", + "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", "dev": true }, "dir-glob": { @@ -502,40 +559,40 @@ } }, "dom-serializer": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", - "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "dev": true, "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" } }, "domelementtype": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", - "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", "dev": true }, "domhandler": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.2.tgz", - "integrity": "sha512-PzE9aBMsdZO8TK4BnuJwH0QT41wgMbRzuZrHUcpYncEjmQazq8QEaBWgLG7ZyC/DAZKEgglpIA6j4Qn/HmxS3w==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dev": true, "requires": { - "domelementtype": "^2.2.0" + "domelementtype": "^2.3.0" } }, "domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", "dev": true, "requires": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" } }, "emoji-regex": { @@ -544,6 +601,15 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, "enquirer": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", @@ -554,9 +620,24 @@ } }, "entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true + }, + "es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.2.4" + } + }, + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "dev": true }, "escape-string-regexp": { @@ -783,6 +864,12 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, + "expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "dev": true + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -826,7 +913,7 @@ "fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", "dev": true, "requires": { "pend": "~1.2.0" @@ -866,10 +953,10 @@ "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", "dev": true }, - "follow-redirects": { - "version": "1.14.4", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.4.tgz", - "integrity": "sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==", + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", "dev": true }, "fs.realpath": { @@ -879,9 +966,9 @@ "dev": true }, "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true }, "functional-red-black-tree": { @@ -891,16 +978,24 @@ "dev": true }, "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" } }, + "github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "dev": true + }, "glob": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", @@ -955,13 +1050,13 @@ } } }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dev": true, "requires": { - "function-bind": "^1.1.1" + "get-intrinsic": "^1.1.3" } }, "has-flag": { @@ -970,33 +1065,63 @@ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, - "has-symbols": { + "has-property-descriptors": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "requires": { + "es-define-property": "^1.0.0" + } + }, + "has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true }, + "hasown": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", + "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", + "dev": true, + "requires": { + "function-bind": "^1.1.2" + } + }, "hosted-git-info": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", - "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", "dev": true, "requires": { "lru-cache": "^6.0.0" } }, "htmlparser2": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", "dev": true, "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" } }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true + }, "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", @@ -1035,14 +1160,11 @@ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, - "requires": { - "ci-info": "^2.0.0" - } + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true }, "is-extglob": { "version": "2.1.1", @@ -1105,6 +1227,16 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, + "keytar": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz", + "integrity": "sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==", + "dev": true, + "requires": { + "node-addon-api": "^4.3.0", + "prebuild-install": "^7.0.1" + } + }, "leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -1122,20 +1254,14 @@ } }, "linkify-it": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", - "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", "dev": true, "requires": { "uc.micro": "^1.0.1" } }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, "lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", @@ -1164,22 +1290,28 @@ } }, "markdown-it": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", - "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", + "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", "dev": true, "requires": { - "argparse": "^1.0.7", - "entities": "~2.0.0", - "linkify-it": "^2.0.0", + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", "mdurl": "^1.0.1", "uc.micro": "^1.0.5" }, "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "entities": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", - "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", "dev": true } } @@ -1187,7 +1319,7 @@ "mdurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", "dev": true }, "merge2": { @@ -1212,6 +1344,12 @@ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true }, + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -1221,6 +1359,18 @@ "brace-expansion": "^1.1.7" } }, + "minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true + }, + "mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -1233,25 +1383,57 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, + "napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", + "dev": true + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "node-abi": { + "version": "3.56.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.56.0.tgz", + "integrity": "sha512-fZjdhDOeRcaS+rcpve7XuwHBmktS1nS1gzgghwKUQQ8nTy2FdSDr6ZT8k6YhvlJeHmmQMYiT/IH9hfco5zeW2Q==", + "dev": true, + "requires": { + "semver": "^7.3.5" + }, + "dependencies": { + "semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "node-addon-api": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==", + "dev": true + }, "nth-check": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz", - "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "dev": true, "requires": { "boolbase": "^1.0.0" } }, "object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true }, "once": { @@ -1277,72 +1459,6 @@ "word-wrap": "^1.2.3" } }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "ovsx": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/ovsx/-/ovsx-0.2.1.tgz", - "integrity": "sha512-STCpZrGq5YW4TiR+IFRqnTeKm6SBAYewHbgD75NYh9Zzy0/G72Y3zScvLiCRMGkhu+4HfP41X8sB83RUBmO0XA==", - "dev": true, - "requires": { - "commander": "^6.1.0", - "follow-redirects": "^1.13.2", - "is-ci": "^2.0.0", - "leven": "^3.1.0", - "tmp": "^0.2.1", - "vsce": "~1.97.0" - }, - "dependencies": { - "vsce": { - "version": "1.97.0", - "resolved": "https://registry.npmjs.org/vsce/-/vsce-1.97.0.tgz", - "integrity": "sha512-5Rxj6qO0dN4FnzVS9G94osstx8R3r1OQP39G7WYERpoO9X+OSodVVkRhFDapPNjekfUNo+d5Qn7W1EtNQVoLCg==", - "dev": true, - "requires": { - "azure-devops-node-api": "^11.0.1", - "chalk": "^2.4.2", - "cheerio": "^1.0.0-rc.9", - "commander": "^6.1.0", - "denodeify": "^1.2.1", - "glob": "^7.0.6", - "leven": "^3.1.0", - "lodash": "^4.17.15", - "markdown-it": "^10.0.0", - "mime": "^1.3.4", - "minimatch": "^3.0.3", - "osenv": "^0.1.3", - "parse-semver": "^1.1.1", - "read": "^1.0.7", - "semver": "^5.1.0", - "tmp": "^0.2.1", - "typed-rest-client": "^1.8.4", - "url-join": "^1.1.0", - "yauzl": "^2.3.1", - "yazl": "^2.2.2" - } - } - } - }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -1355,25 +1471,29 @@ "parse-semver": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz", - "integrity": "sha1-mkr9bfBj3Egm+T+6SpnPIj9mbLg=", + "integrity": "sha512-Eg1OuNntBMH0ojvEKSrvDSnwLmvVuUOSdylH/pSCPNMIspLlweJyIWXCE+k/5hm3cj/EBUYwmWkjhBALNP4LXQ==", "dev": true, "requires": { "semver": "^5.1.0" } }, "parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dev": true, + "requires": { + "entities": "^4.4.0" + } }, "parse5-htmlparser2-tree-adapter": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", - "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", + "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", "dev": true, "requires": { - "parse5": "^6.0.1" + "domhandler": "^5.0.2", + "parse5": "^7.0.0" } }, "path-is-absolute": { @@ -1397,7 +1517,7 @@ "pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", "dev": true }, "picomatch": { @@ -1406,6 +1526,26 @@ "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "dev": true }, + "prebuild-install": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", + "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", + "dev": true, + "requires": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + } + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -1418,6 +1558,16 @@ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -1425,9 +1575,9 @@ "dev": true }, "qs": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", - "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", "dev": true, "requires": { "side-channel": "^1.0.4" @@ -1439,15 +1589,46 @@ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true + } + } + }, "read": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", - "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", + "integrity": "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==", "dev": true, "requires": { "mute-stream": "~0.0.4" } }, + "readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, "regexpp": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", @@ -1490,18 +1671,38 @@ "queue-microtask": "^1.2.2" } }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", + "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==", "dev": true }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true }, + "set-function-length": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", + "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", + "dev": true, + "requires": { + "define-data-property": "^1.1.2", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.1" + } + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -1518,14 +1719,32 @@ "dev": true }, "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + } + }, + "simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true + }, + "simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", "dev": true, "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" } }, "slash": { @@ -1588,6 +1807,15 @@ "strip-ansi": "^6.0.0" } }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", @@ -1646,6 +1874,31 @@ } } }, + "tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -1653,13 +1906,10 @@ "dev": true }, "tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "requires": { - "rimraf": "^3.0.0" - } + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "dev": true }, "to-regex-range": { "version": "5.0.1", @@ -1691,6 +1941,15 @@ "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", "dev": true }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -1707,9 +1966,9 @@ "dev": true }, "typed-rest-client": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.6.tgz", - "integrity": "sha512-xcQpTEAJw2DP7GqVNECh4dD+riS+C1qndXLfBCJ3xk0kqprtGN491P5KlmrDbKdtuW8NEcP/5ChxiJI3S9WYTA==", + "version": "1.8.11", + "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.11.tgz", + "integrity": "sha512-5UvfMpd1oelmUPRbbaVnq+rHP7ng2cE4qoQkQeAqxRL6PklkxsM0g32/HL0yfvruK6ojQ5x8EE+HF4YV6DtuCA==", "dev": true, "requires": { "qs": "^6.9.1", @@ -1730,9 +1989,9 @@ "dev": true }, "underscore": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz", - "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==", + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", "dev": true }, "uri-js": { @@ -1745,9 +2004,15 @@ } }, "url-join": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-1.1.0.tgz", - "integrity": "sha1-dBxsL0WWxIMNZxhGCSDQySIC3Hg=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, "v8-compile-cache": { @@ -1757,30 +2022,28 @@ "dev": true }, "vsce": { - "version": "1.100.1", - "resolved": "https://registry.npmjs.org/vsce/-/vsce-1.100.1.tgz", - "integrity": "sha512-1VjLyse5g6e2eQ6jUpslu7IDq44velwF8Jy8s7ePdwGNuG8EzfmaOfVyig3ZSMJ0l8DiJmZllx5bRAB4RMdnHg==", + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/vsce/-/vsce-2.15.0.tgz", + "integrity": "sha512-P8E9LAZvBCQnoGoizw65JfGvyMqNGlHdlUXD1VAuxtvYAaHBKLBdKPnpy60XKVDAkQCfmMu53g+gq9FM+ydepw==", "dev": true, "requires": { "azure-devops-node-api": "^11.0.1", "chalk": "^2.4.2", "cheerio": "^1.0.0-rc.9", "commander": "^6.1.0", - "denodeify": "^1.2.1", "glob": "^7.0.6", "hosted-git-info": "^4.0.2", + "keytar": "^7.7.0", "leven": "^3.1.0", - "lodash": "^4.17.15", - "markdown-it": "^10.0.0", + "markdown-it": "^12.3.2", "mime": "^1.3.4", "minimatch": "^3.0.3", - "osenv": "^0.1.3", "parse-semver": "^1.1.1", "read": "^1.0.7", "semver": "^5.1.0", "tmp": "^0.2.1", "typed-rest-client": "^1.8.4", - "url-join": "^1.1.0", + "url-join": "^4.0.1", "xml2js": "^0.4.23", "yauzl": "^2.3.1", "yazl": "^2.2.2" @@ -1832,7 +2095,7 @@ "yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", "dev": true, "requires": { "buffer-crc32": "~0.2.3", diff --git a/src/projektanker.code-butler/package.json b/src/projektanker.code-butler/package.json index 49de244..4c2cab4 100644 --- a/src/projektanker.code-butler/package.json +++ b/src/projektanker.code-butler/package.json @@ -83,6 +83,6 @@ "@typescript-eslint/parser": "^4.31.1", "eslint": "^7.1.0", "typescript": "^4.0.2", - "vsce": "^1.100.1" + "vsce": "^2.15.0" } }