Update NuGet packages

This commit is contained in:
Tyrrrz
2023-11-12 19:08:54 +02:00
parent ff06b8896f
commit b41e9b4929
33 changed files with 149 additions and 112 deletions

View File

@@ -9,15 +9,15 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Basic.Reference.Assemblies.Net70" Version="1.4.2" /> <PackageReference Include="Basic.Reference.Assemblies.Net70" Version="1.4.5" />
<PackageReference Include="coverlet.collector" Version="6.0.0" PrivateAssets="all" /> <PackageReference Include="coverlet.collector" Version="6.0.0" PrivateAssets="all" />
<PackageReference Include="CSharpier.MsBuild" Version="0.25.0" PrivateAssets="all" /> <PackageReference Include="CSharpier.MsBuild" Version="0.26.1" PrivateAssets="all" />
<PackageReference Include="GitHubActionsTestLogger" Version="2.3.2" PrivateAssets="all" /> <PackageReference Include="GitHubActionsTestLogger" Version="2.3.3" PrivateAssets="all" />
<PackageReference Include="FluentAssertions" Version="6.11.0" /> <PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.6.0" /> <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.7.0" />
<PackageReference Include="xunit" Version="2.5.0" /> <PackageReference Include="xunit" Version="2.6.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.0" PrivateAssets="all" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" PrivateAssets="all" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -12,7 +12,8 @@ public class GeneralSpecs
public void All_analyzers_have_unique_diagnostic_IDs() public void All_analyzers_have_unique_diagnostic_IDs()
{ {
// Arrange // Arrange
var analyzers = typeof(AnalyzerBase).Assembly var analyzers = typeof(AnalyzerBase)
.Assembly
.GetTypes() .GetTypes()
.Where(t => !t.IsAbstract && t.IsAssignableTo(typeof(DiagnosticAnalyzer))) .Where(t => !t.IsAbstract && t.IsAssignableTo(typeof(DiagnosticAnalyzer)))
.Select(t => (DiagnosticAnalyzer)Activator.CreateInstance(t)!) .Select(t => (DiagnosticAnalyzer)Activator.CreateInstance(t)!)

View File

@@ -31,7 +31,8 @@ internal class AnalyzerAssertions : ReferenceTypeAssertions<DiagnosticAnalyzer,
}; };
// Get default CliFx namespaces // Get default CliFx namespaces
var defaultCliFxNamespaces = typeof(ICommand).Assembly var defaultCliFxNamespaces = typeof(ICommand)
.Assembly
.GetTypes() .GetTypes()
.Where(t => t.IsPublic) .Where(t => t.IsPublic)
.Select(t => t.Namespace) .Select(t => t.Namespace)
@@ -55,9 +56,10 @@ internal class AnalyzerAssertions : ReferenceTypeAssertions<DiagnosticAnalyzer,
var compilation = CSharpCompilation.Create( var compilation = CSharpCompilation.Create(
"CliFxTests_DynamicAssembly_" + Guid.NewGuid(), "CliFxTests_DynamicAssembly_" + Guid.NewGuid(),
new[] { ast }, new[] { ast },
Net70.References.All.Append( Net70
MetadataReference.CreateFromFile(typeof(ICommand).Assembly.Location) .References
), .All
.Append(MetadataReference.CreateFromFile(typeof(ICommand).Assembly.Location)),
// DLL to avoid having to define the Main() method // DLL to avoid having to define the Main() method
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary) new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
); );
@@ -104,7 +106,8 @@ internal class AnalyzerAssertions : ReferenceTypeAssertions<DiagnosticAnalyzer,
expectedDiagnosticIds.Intersect(producedDiagnosticIds).Count() expectedDiagnosticIds.Intersect(producedDiagnosticIds).Count()
== expectedDiagnosticIds.Length; == expectedDiagnosticIds.Length;
Execute.Assertion Execute
.Assertion
.ForCondition(isSuccessfulAssertion) .ForCondition(isSuccessfulAssertion)
.FailWith(() => .FailWith(() =>
{ {
@@ -148,7 +151,8 @@ internal class AnalyzerAssertions : ReferenceTypeAssertions<DiagnosticAnalyzer,
var producedDiagnostics = GetProducedDiagnostics(sourceCode); var producedDiagnostics = GetProducedDiagnostics(sourceCode);
var isSuccessfulAssertion = !producedDiagnostics.Any(); var isSuccessfulAssertion = !producedDiagnostics.Any();
Execute.Assertion Execute
.Assertion
.ForCondition(isSuccessfulAssertion) .ForCondition(isSuccessfulAssertion)
.FailWith(() => .FailWith(() =>
{ {

View File

@@ -17,11 +17,11 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="CSharpier.MsBuild" Version="0.25.0" PrivateAssets="all" /> <PackageReference Include="CSharpier.MsBuild" Version="0.26.1" PrivateAssets="all" />
<!-- Make sure to target the lowest possible version of the compiler for wider support --> <!-- Make sure to target the lowest possible version of the compiler for wider support -->
<PackageReference Include="Microsoft.CodeAnalysis" Version="3.0.0" PrivateAssets="all" /> <PackageReference Include="Microsoft.CodeAnalysis" Version="3.0.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.0.0" PrivateAssets="all" /> <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.0.0" PrivateAssets="all" />
<PackageReference Include="PolyShim" Version="1.7.0" PrivateAssets="all" /> <PackageReference Include="PolyShim" Version="1.8.0" PrivateAssets="all" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -55,30 +55,35 @@ internal partial class CommandOptionSymbol
return null; return null;
var name = var name =
attribute.ConstructorArguments attribute
.ConstructorArguments
.Where(a => a.Type?.SpecialType == SpecialType.System_String) .Where(a => a.Type?.SpecialType == SpecialType.System_String)
.Select(a => a.Value) .Select(a => a.Value)
.FirstOrDefault() as string; .FirstOrDefault() as string;
var shortName = var shortName =
attribute.ConstructorArguments attribute
.ConstructorArguments
.Where(a => a.Type?.SpecialType == SpecialType.System_Char) .Where(a => a.Type?.SpecialType == SpecialType.System_Char)
.Select(a => a.Value) .Select(a => a.Value)
.FirstOrDefault() as char?; .FirstOrDefault() as char?;
var isRequired = var isRequired =
attribute.NamedArguments attribute
.NamedArguments
.Where(a => a.Key == "IsRequired") .Where(a => a.Key == "IsRequired")
.Select(a => a.Value.Value) .Select(a => a.Value.Value)
.FirstOrDefault() as bool?; .FirstOrDefault() as bool?;
var converter = attribute.NamedArguments var converter = attribute
.NamedArguments
.Where(a => a.Key == "Converter") .Where(a => a.Key == "Converter")
.Select(a => a.Value.Value) .Select(a => a.Value.Value)
.Cast<ITypeSymbol?>() .Cast<ITypeSymbol?>()
.FirstOrDefault(); .FirstOrDefault();
var validators = attribute.NamedArguments var validators = attribute
.NamedArguments
.Where(a => a.Key == "Validators") .Where(a => a.Key == "Validators")
.SelectMany(a => a.Value.Values) .SelectMany(a => a.Value.Values)
.Select(c => c.Value) .Select(c => c.Value)

View File

@@ -57,24 +57,28 @@ internal partial class CommandParameterSymbol
var order = (int)attribute.ConstructorArguments.Select(a => a.Value).First()!; var order = (int)attribute.ConstructorArguments.Select(a => a.Value).First()!;
var name = var name =
attribute.NamedArguments attribute
.NamedArguments
.Where(a => a.Key == "Name") .Where(a => a.Key == "Name")
.Select(a => a.Value.Value) .Select(a => a.Value.Value)
.FirstOrDefault() as string; .FirstOrDefault() as string;
var isRequired = var isRequired =
attribute.NamedArguments attribute
.NamedArguments
.Where(a => a.Key == "IsRequired") .Where(a => a.Key == "IsRequired")
.Select(a => a.Value.Value) .Select(a => a.Value.Value)
.FirstOrDefault() as bool?; .FirstOrDefault() as bool?;
var converter = attribute.NamedArguments var converter = attribute
.NamedArguments
.Where(a => a.Key == "Converter") .Where(a => a.Key == "Converter")
.Select(a => a.Value.Value) .Select(a => a.Value.Value)
.Cast<ITypeSymbol?>() .Cast<ITypeSymbol?>()
.FirstOrDefault(); .FirstOrDefault();
var validators = attribute.NamedArguments var validators = attribute
.NamedArguments
.Where(a => a.Key == "Validators") .Where(a => a.Key == "Validators")
.SelectMany(a => a.Value.Values) .SelectMany(a => a.Value.Values)
.Select(c => c.Value) .Select(c => c.Value)

View File

@@ -31,9 +31,10 @@ public class OptionMustBeInsideCommandAnalyzer : AnalyzerBase
if (!CommandOptionSymbol.IsOptionProperty(property)) if (!CommandOptionSymbol.IsOptionProperty(property))
return; return;
var isInsideCommand = property.ContainingType.AllInterfaces.Any( var isInsideCommand = property
i => i.DisplayNameMatches(SymbolNames.CliFxCommandInterface) .ContainingType
); .AllInterfaces
.Any(i => i.DisplayNameMatches(SymbolNames.CliFxCommandInterface));
if (!isInsideCommand) if (!isInsideCommand)
{ {

View File

@@ -35,7 +35,8 @@ public class OptionMustHaveUniqueNameAnalyzer : AnalyzerBase
if (string.IsNullOrWhiteSpace(option.Name)) if (string.IsNullOrWhiteSpace(option.Name))
return; return;
var otherProperties = property.ContainingType var otherProperties = property
.ContainingType
.GetMembers() .GetMembers()
.OfType<IPropertySymbol>() .OfType<IPropertySymbol>()
.Where(m => !m.Equals(property)) .Where(m => !m.Equals(property))

View File

@@ -34,7 +34,8 @@ public class OptionMustHaveUniqueShortNameAnalyzer : AnalyzerBase
if (option.ShortName is null) if (option.ShortName is null)
return; return;
var otherProperties = property.ContainingType var otherProperties = property
.ContainingType
.GetMembers() .GetMembers()
.OfType<IPropertySymbol>() .OfType<IPropertySymbol>()
.Where(m => !m.Equals(property)) .Where(m => !m.Equals(property))

View File

@@ -29,12 +29,14 @@ public class OptionMustHaveValidConverterAnalyzer : AnalyzerBase
if (option.ConverterType is null) if (option.ConverterType is null)
return; return;
var converterValueType = option.ConverterType var converterValueType = option
.ConverterType
.GetBaseTypes() .GetBaseTypes()
.FirstOrDefault( .FirstOrDefault(
t => t.ConstructedFrom.DisplayNameMatches(SymbolNames.CliFxBindingConverterClass) t => t.ConstructedFrom.DisplayNameMatches(SymbolNames.CliFxBindingConverterClass)
) )
?.TypeArguments.FirstOrDefault(); ?.TypeArguments
.FirstOrDefault();
// Value returned by the converter must be assignable to the property type // Value returned by the converter must be assignable to the property type
var isCompatible = var isCompatible =
@@ -45,10 +47,9 @@ public class OptionMustHaveValidConverterAnalyzer : AnalyzerBase
? context.Compilation.IsAssignable(converterValueType, property.Type) ? context.Compilation.IsAssignable(converterValueType, property.Type)
// Non-scalar (assume we can handle all IEnumerable types for simplicity) // Non-scalar (assume we can handle all IEnumerable types for simplicity)
: property.Type.TryGetEnumerableUnderlyingType() is { } enumerableUnderlyingType : property.Type.TryGetEnumerableUnderlyingType() is { } enumerableUnderlyingType
&& context.Compilation.IsAssignable( && context
converterValueType, .Compilation
enumerableUnderlyingType .IsAssignable(converterValueType, enumerableUnderlyingType)
)
); );
if (!isCompatible) if (!isCompatible)

View File

@@ -34,7 +34,8 @@ public class OptionMustHaveValidValidatorsAnalyzer : AnalyzerBase
t => t =>
t.ConstructedFrom.DisplayNameMatches(SymbolNames.CliFxBindingValidatorClass) t.ConstructedFrom.DisplayNameMatches(SymbolNames.CliFxBindingValidatorClass)
) )
?.TypeArguments.FirstOrDefault(); ?.TypeArguments
.FirstOrDefault();
// Value passed to the validator must be assignable from the property type // Value passed to the validator must be assignable from the property type
var isCompatible = var isCompatible =

View File

@@ -31,9 +31,10 @@ public class ParameterMustBeInsideCommandAnalyzer : AnalyzerBase
if (!CommandParameterSymbol.IsParameterProperty(property)) if (!CommandParameterSymbol.IsParameterProperty(property))
return; return;
var isInsideCommand = property.ContainingType.AllInterfaces.Any( var isInsideCommand = property
i => i.DisplayNameMatches(SymbolNames.CliFxCommandInterface) .ContainingType
); .AllInterfaces
.Any(i => i.DisplayNameMatches(SymbolNames.CliFxCommandInterface));
if (!isInsideCommand) if (!isInsideCommand)
{ {

View File

@@ -33,7 +33,8 @@ public class ParameterMustBeLastIfNonRequiredAnalyzer : AnalyzerBase
if (parameter.IsRequired != false) if (parameter.IsRequired != false)
return; return;
var otherProperties = property.ContainingType var otherProperties = property
.ContainingType
.GetMembers() .GetMembers()
.OfType<IPropertySymbol>() .OfType<IPropertySymbol>()
.Where(m => !m.Equals(property)) .Where(m => !m.Equals(property))

View File

@@ -33,7 +33,8 @@ public class ParameterMustBeLastIfNonScalarAnalyzer : AnalyzerBase
if (parameter.IsScalar()) if (parameter.IsScalar())
return; return;
var otherProperties = property.ContainingType var otherProperties = property
.ContainingType
.GetMembers() .GetMembers()
.OfType<IPropertySymbol>() .OfType<IPropertySymbol>()
.Where(m => !m.Equals(property)) .Where(m => !m.Equals(property))

View File

@@ -33,7 +33,8 @@ public class ParameterMustBeSingleIfNonRequiredAnalyzer : AnalyzerBase
if (parameter.IsRequired != false) if (parameter.IsRequired != false)
return; return;
var otherProperties = property.ContainingType var otherProperties = property
.ContainingType
.GetMembers() .GetMembers()
.OfType<IPropertySymbol>() .OfType<IPropertySymbol>()
.Where(m => !m.Equals(property)) .Where(m => !m.Equals(property))

View File

@@ -33,7 +33,8 @@ public class ParameterMustBeSingleIfNonScalarAnalyzer : AnalyzerBase
if (parameter.IsScalar()) if (parameter.IsScalar())
return; return;
var otherProperties = property.ContainingType var otherProperties = property
.ContainingType
.GetMembers() .GetMembers()
.OfType<IPropertySymbol>() .OfType<IPropertySymbol>()
.Where(m => !m.Equals(property)) .Where(m => !m.Equals(property))

View File

@@ -35,7 +35,8 @@ public class ParameterMustHaveUniqueNameAnalyzer : AnalyzerBase
if (string.IsNullOrWhiteSpace(parameter.Name)) if (string.IsNullOrWhiteSpace(parameter.Name))
return; return;
var otherProperties = property.ContainingType var otherProperties = property
.ContainingType
.GetMembers() .GetMembers()
.OfType<IPropertySymbol>() .OfType<IPropertySymbol>()
.Where(m => !m.Equals(property)) .Where(m => !m.Equals(property))

View File

@@ -31,7 +31,8 @@ public class ParameterMustHaveUniqueOrderAnalyzer : AnalyzerBase
if (parameter is null) if (parameter is null)
return; return;
var otherProperties = property.ContainingType var otherProperties = property
.ContainingType
.GetMembers() .GetMembers()
.OfType<IPropertySymbol>() .OfType<IPropertySymbol>()
.Where(m => !m.Equals(property)) .Where(m => !m.Equals(property))

View File

@@ -29,12 +29,14 @@ public class ParameterMustHaveValidConverterAnalyzer : AnalyzerBase
if (parameter.ConverterType is null) if (parameter.ConverterType is null)
return; return;
var converterValueType = parameter.ConverterType var converterValueType = parameter
.ConverterType
.GetBaseTypes() .GetBaseTypes()
.FirstOrDefault( .FirstOrDefault(
t => t.ConstructedFrom.DisplayNameMatches(SymbolNames.CliFxBindingConverterClass) t => t.ConstructedFrom.DisplayNameMatches(SymbolNames.CliFxBindingConverterClass)
) )
?.TypeArguments.FirstOrDefault(); ?.TypeArguments
.FirstOrDefault();
// Value returned by the converter must be assignable to the property type // Value returned by the converter must be assignable to the property type
var isCompatible = var isCompatible =
@@ -45,10 +47,9 @@ public class ParameterMustHaveValidConverterAnalyzer : AnalyzerBase
? context.Compilation.IsAssignable(converterValueType, property.Type) ? context.Compilation.IsAssignable(converterValueType, property.Type)
// Non-scalar (assume we can handle all IEnumerable types for simplicity) // Non-scalar (assume we can handle all IEnumerable types for simplicity)
: property.Type.TryGetEnumerableUnderlyingType() is { } enumerableUnderlyingType : property.Type.TryGetEnumerableUnderlyingType() is { } enumerableUnderlyingType
&& context.Compilation.IsAssignable( && context
converterValueType, .Compilation
enumerableUnderlyingType .IsAssignable(converterValueType, enumerableUnderlyingType)
)
); );
if (!isCompatible) if (!isCompatible)

View File

@@ -34,7 +34,8 @@ public class ParameterMustHaveValidValidatorsAnalyzer : AnalyzerBase
t => t =>
t.ConstructedFrom.DisplayNameMatches(SymbolNames.CliFxBindingValidatorClass) t.ConstructedFrom.DisplayNameMatches(SymbolNames.CliFxBindingValidatorClass)
) )
?.TypeArguments.FirstOrDefault(); ?.TypeArguments
.FirstOrDefault();
// Value passed to the validator must be assignable from the property type // Value passed to the validator must be assignable from the property type
var isCompatible = var isCompatible =

View File

@@ -53,7 +53,8 @@ public class SystemConsoleShouldBeAvoidedAnalyzer : AnalyzerBase
return; return;
// Check if IConsole is available in scope as an alternative to System.Console // Check if IConsole is available in scope as an alternative to System.Console
var isConsoleInterfaceAvailable = context.Node var isConsoleInterfaceAvailable = context
.Node
.Ancestors() .Ancestors()
.OfType<MethodDeclarationSyntax>() .OfType<MethodDeclarationSyntax>()
.SelectMany(m => m.ParameterList.Parameters) .SelectMany(m => m.ParameterList.Parameters)

View File

@@ -42,9 +42,9 @@ internal static class RoslynExtensions
// on higher versions of the C# compiler. // on higher versions of the C# compiler.
public static bool IsRequired(this IPropertySymbol property) => public static bool IsRequired(this IPropertySymbol property) =>
property property
// Can't rely on the RequiredMemberAttribute because it's generated by the compiler, not added by the user, // Can't rely on the RequiredMemberAttribute because it's generated by the compiler, not added by the user,
// so we have to check for the presence of the `required` modifier in the syntax tree instead. // so we have to check for the presence of the `required` modifier in the syntax tree instead.
.DeclaringSyntaxReferences .DeclaringSyntaxReferences
.Select(r => r.GetSyntax()) .Select(r => r.GetSyntax())
.OfType<PropertyDeclarationSyntax>() .OfType<PropertyDeclarationSyntax>()
.SelectMany(p => p.Modifiers) .SelectMany(p => p.Modifiers)

View File

@@ -6,13 +6,13 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.7" /> <PackageReference Include="BenchmarkDotNet" Version="0.13.10" />
<PackageReference Include="clipr" Version="1.6.1" /> <PackageReference Include="clipr" Version="1.6.1" />
<PackageReference Include="Cocona" Version="2.2.0" /> <PackageReference Include="Cocona" Version="2.2.0" />
<PackageReference Include="CommandLineParser" Version="2.9.1" /> <PackageReference Include="CommandLineParser" Version="2.9.1" />
<PackageReference Include="CSharpier.MsBuild" Version="0.25.0" PrivateAssets="all" /> <PackageReference Include="CSharpier.MsBuild" Version="0.26.1" PrivateAssets="all" />
<PackageReference Include="McMaster.Extensions.CommandLineUtils" Version="4.0.2" /> <PackageReference Include="McMaster.Extensions.CommandLineUtils" Version="4.1.0" />
<PackageReference Include="PowerArgs" Version="4.0.2" /> <PackageReference Include="PowerArgs" Version="4.0.3" />
<PackageReference Include="System.CommandLine" Version="2.0.0-beta1.20574.7" /> <PackageReference Include="System.CommandLine" Version="2.0.0-beta1.20574.7" />
</ItemGroup> </ItemGroup>

View File

@@ -7,7 +7,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="CSharpier.MsBuild" Version="0.25.0" PrivateAssets="all" /> <PackageReference Include="CSharpier.MsBuild" Version="0.26.1" PrivateAssets="all" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
</ItemGroup> </ItemGroup>

View File

@@ -7,7 +7,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="CSharpier.MsBuild" Version="0.25.0" PrivateAssets="all" /> <PackageReference Include="CSharpier.MsBuild" Version="0.26.1" PrivateAssets="all" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -9,18 +9,18 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Basic.Reference.Assemblies.Net70" Version="1.4.2" /> <PackageReference Include="Basic.Reference.Assemblies.Net70" Version="1.4.5" />
<PackageReference Include="CliWrap" Version="3.6.4" /> <PackageReference Include="CliWrap" Version="3.6.4" />
<PackageReference Include="coverlet.collector" Version="6.0.0" PrivateAssets="all" /> <PackageReference Include="coverlet.collector" Version="6.0.0" PrivateAssets="all" />
<PackageReference Include="CSharpier.MsBuild" Version="0.25.0" PrivateAssets="all" /> <PackageReference Include="CSharpier.MsBuild" Version="0.26.1" PrivateAssets="all" />
<PackageReference Include="FluentAssertions" Version="6.11.0" /> <PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="GitHubActionsTestLogger" Version="2.3.2" PrivateAssets="all" /> <PackageReference Include="GitHubActionsTestLogger" Version="2.3.3" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.6.0" /> <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.7.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="PolyShim" Version="1.7.0" PrivateAssets="all" /> <PackageReference Include="PolyShim" Version="1.8.0" PrivateAssets="all" />
<PackageReference Include="xunit" Version="2.5.0" /> <PackageReference Include="xunit" Version="2.6.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.0" PrivateAssets="all" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" PrivateAssets="all" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -31,7 +31,8 @@ internal static class DynamicCommandBuilder
}; };
// Get default CliFx namespaces // Get default CliFx namespaces
var defaultCliFxNamespaces = typeof(ICommand).Assembly var defaultCliFxNamespaces = typeof(ICommand)
.Assembly
.GetTypes() .GetTypes()
.Where(t => t.IsPublic) .Where(t => t.IsPublic)
.Select(t => t.Namespace) .Select(t => t.Namespace)
@@ -55,7 +56,9 @@ internal static class DynamicCommandBuilder
var compilation = CSharpCompilation.Create( var compilation = CSharpCompilation.Create(
"CliFxTests_DynamicAssembly_" + Guid.NewGuid(), "CliFxTests_DynamicAssembly_" + Guid.NewGuid(),
new[] { ast }, new[] { ast },
Net70.References.All Net70
.References
.All
.Append(MetadataReference.CreateFromFile(typeof(ICommand).Assembly.Location)) .Append(MetadataReference.CreateFromFile(typeof(ICommand).Assembly.Location))
.Append( .Append(
MetadataReference.CreateFromFile( MetadataReference.CreateFromFile(

View File

@@ -8,14 +8,10 @@ namespace CliFx.Tests.Utils.Extensions;
internal static class AssertionExtensions internal static class AssertionExtensions
{ {
public static void ConsistOfLines(this StringAssertions assertions, IEnumerable<string> lines) public static void ConsistOfLines(this StringAssertions assertions, IEnumerable<string> lines) =>
{ assertions
var actualLines = assertions.Subject.Split( .Subject
new[] { '\n', '\r' }, .Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries).Should().Equal(lines);
StringSplitOptions.RemoveEmptyEntries
);
actualLines.Should().Equal(lines);
}
public static void ConsistOfLines(this StringAssertions assertions, params string[] lines) => public static void ConsistOfLines(this StringAssertions assertions, params string[] lines) =>
assertions.ConsistOfLines((IEnumerable<string>)lines); assertions.ConsistOfLines((IEnumerable<string>)lines);
@@ -33,9 +29,11 @@ internal static class AssertionExtensions
if (index < 0) if (index < 0)
{ {
Execute.Assertion.FailWith( Execute
$"Expected string '{assertions.Subject}' to contain '{value}' after position {lastIndex}." .Assertion
); .FailWith(
$"Expected string '{assertions.Subject}' to contain '{value}' after position {lastIndex}."
);
} }
lastIndex = index; lastIndex = index;

View File

@@ -72,11 +72,9 @@ public class CliApplication
{ {
using (_console.WithForegroundColor(ConsoleColor.Green)) using (_console.WithForegroundColor(ConsoleColor.Green))
{ {
var processId = ProcessEx.GetCurrentProcessId(); _console
.Output
_console.Output.WriteLine( .WriteLine($"Attach the debugger to process with ID {ProcessEx.GetCurrentProcessId()} to continue.");
$"Attach the debugger to process with ID {processId} to continue."
);
} }
// Try to also launch the debugger ourselves (only works with Visual Studio) // Try to also launch the debugger ourselves (only works with Visual Studio)

View File

@@ -21,9 +21,9 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="CSharpier.MsBuild" Version="0.25.0" PrivateAssets="all" /> <PackageReference Include="CSharpier.MsBuild" Version="0.26.1" PrivateAssets="all" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="all" /> <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="all" />
<PackageReference Include="PolyShim" Version="1.7.0" PrivateAssets="all" /> <PackageReference Include="PolyShim" Version="1.8.0" PrivateAssets="all" />
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" Condition="'$(TargetFramework)' == 'netstandard2.0'" /> <PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" Condition="'$(TargetFramework)' == 'netstandard2.0'" />
</ItemGroup> </ItemGroup>

View File

@@ -152,10 +152,14 @@ internal class CommandBinder
try try
{ {
// Non-scalar // Non-scalar
var enumerableUnderlyingType = var enumerableUnderlyingType = memberSchema
memberSchema.Property.Type.TryGetEnumerableUnderlyingType(); .Property
.Type
.TryGetEnumerableUnderlyingType();
if ( if (
enumerableUnderlyingType is not null && memberSchema.Property.Type != typeof(string) enumerableUnderlyingType is not null
&& memberSchema.Property.Type != typeof(string)
) )
{ {
return ConvertMultiple( return ConvertMultiple(
@@ -248,7 +252,8 @@ internal class CommandBinder
{ {
// Ensure there are no unexpected parameters and that all parameters are provided // Ensure there are no unexpected parameters and that all parameters are provided
var remainingParameterInputs = commandInput.Parameters.ToList(); var remainingParameterInputs = commandInput.Parameters.ToList();
var remainingRequiredParameterSchemas = commandSchema.Parameters var remainingRequiredParameterSchemas = commandSchema
.Parameters
.Where(p => p.IsRequired) .Where(p => p.IsRequired)
.ToList(); .ToList();
@@ -317,19 +322,21 @@ internal class CommandBinder
{ {
// Ensure there are no unrecognized options and that all required options are set // Ensure there are no unrecognized options and that all required options are set
var remainingOptionInputs = commandInput.Options.ToList(); var remainingOptionInputs = commandInput.Options.ToList();
var remainingRequiredOptionSchemas = commandSchema.Options var remainingRequiredOptionSchemas = commandSchema
.Options
.Where(o => o.IsRequired) .Where(o => o.IsRequired)
.ToList(); .ToList();
foreach (var optionSchema in commandSchema.Options) foreach (var optionSchema in commandSchema.Options)
{ {
var optionInputs = commandInput.Options var optionInputs = commandInput
.Options
.Where(o => optionSchema.MatchesIdentifier(o.Identifier)) .Where(o => optionSchema.MatchesIdentifier(o.Identifier))
.ToArray(); .ToArray();
var environmentVariableInput = commandInput.EnvironmentVariables.FirstOrDefault( var environmentVariableInput = commandInput
e => optionSchema.MatchesEnvironmentVariable(e.Name) .EnvironmentVariables
); .FirstOrDefault(e => optionSchema.MatchesEnvironmentVariable(e.Name));
// Direct input // Direct input
if (optionInputs.Any()) if (optionInputs.Any())

View File

@@ -106,9 +106,9 @@ internal class HelpConsoleFormatter : ConsoleFormatter
} }
// Child command usage // Child command usage
var childCommandSchemas = _context.ApplicationSchema.GetChildCommands( var childCommandSchemas = _context
_context.CommandSchema.Name .ApplicationSchema
); .GetChildCommands(_context.CommandSchema.Name);
if (childCommandSchemas.Any()) if (childCommandSchemas.Any())
{ {
@@ -365,7 +365,8 @@ internal class HelpConsoleFormatter : ConsoleFormatter
private void WriteCommandChildren() private void WriteCommandChildren()
{ {
var childCommandSchemas = _context.ApplicationSchema var childCommandSchemas = _context
.ApplicationSchema
.GetChildCommands(_context.CommandSchema.Name) .GetChildCommands(_context.CommandSchema.Name)
.OrderBy(a => a.Name, StringComparer.Ordinal) .OrderBy(a => a.Name, StringComparer.Ordinal)
.ToArray(); .ToArray();
@@ -398,7 +399,8 @@ internal class HelpConsoleFormatter : ConsoleFormatter
} }
// Child commands of child command // Child commands of child command
var grandChildCommandSchemas = _context.ApplicationSchema var grandChildCommandSchemas = _context
.ApplicationSchema
.GetChildCommands(childCommandSchema.Name) .GetChildCommands(childCommandSchema.Name)
.OrderBy(c => c.Name, StringComparer.Ordinal) .OrderBy(c => c.Name, StringComparer.Ordinal)
.ToArray(); .ToArray();
@@ -422,7 +424,8 @@ internal class HelpConsoleFormatter : ConsoleFormatter
Write( Write(
ConsoleColor.Cyan, ConsoleColor.Cyan,
// Relative to current command (not the parent) // Relative to current command (not the parent)
grandChildCommandSchema.Name grandChildCommandSchema
.Name
?.Substring(_context.CommandSchema.Name?.Length ?? 0) ?.Substring(_context.CommandSchema.Name?.Length ?? 0)
.Trim() .Trim()
); );

View File

@@ -44,10 +44,9 @@ internal partial class ApplicationSchema
string.IsNullOrWhiteSpace(parentCommandName) string.IsNullOrWhiteSpace(parentCommandName)
|| ||
// Otherwise a command is a descendant if it starts with the same name segments // Otherwise a command is a descendant if it starts with the same name segments
potentialParentCommandSchema.Name.StartsWith( potentialParentCommandSchema
parentCommandName + ' ', .Name
StringComparison.OrdinalIgnoreCase .StartsWith(parentCommandName + ' ', StringComparison.OrdinalIgnoreCase);
);
if (isDescendant) if (isDescendant)
result.Add(potentialParentCommandSchema); result.Add(potentialParentCommandSchema);