diff --git a/CliFx.Analyzers/CommandSchemaAnalyzer.cs b/CliFx.Analyzers/CommandSchemaAnalyzer.cs index 52b62eb..f299279 100644 --- a/CliFx.Analyzers/CommandSchemaAnalyzer.cs +++ b/CliFx.Analyzers/CommandSchemaAnalyzer.cs @@ -206,7 +206,7 @@ namespace CliFx.Analyzers // Duplicate environment variable name var duplicateEnvironmentVariableNameOptions = options .Where(p => !string.IsNullOrWhiteSpace(p.EnvironmentVariableName)) - .GroupBy(p => p.EnvironmentVariableName, StringComparer.OrdinalIgnoreCase) + .GroupBy(p => p.EnvironmentVariableName, StringComparer.Ordinal) .Where(g => g.Count() > 1) .SelectMany(g => g.AsEnumerable()) .ToArray(); diff --git a/CliFx.Tests/EnvironmentVariablesSpecs.cs b/CliFx.Tests/EnvironmentVariablesSpecs.cs index 67b4014..f8d1b52 100644 --- a/CliFx.Tests/EnvironmentVariablesSpecs.cs +++ b/CliFx.Tests/EnvironmentVariablesSpecs.cs @@ -89,5 +89,27 @@ namespace CliFx.Tests Option = $"foo{Path.PathSeparator}bar" }); } + + [Fact] + public void Option_can_use_a_specific_environment_variable_as_fallback_while_respecting_case() + { + // Arrange + const string expected = "foobar"; + var input = CommandInput.Empty; + var envVars = new Dictionary + { + ["ENV_OPT"] = expected, + ["env_opt"] = "2" + }; + + // Act + var instance = CommandHelper.ResolveCommand(input, envVars); + + // Assert + instance.Should().BeEquivalentTo(new EnvironmentVariableCommand + { + Option = expected + }); + } } -} \ No newline at end of file +} diff --git a/CliFx/CliApplication.cs b/CliFx/CliApplication.cs index 228ab5b..593ed93 100644 --- a/CliFx/CliApplication.cs +++ b/CliFx/CliApplication.cs @@ -218,9 +218,10 @@ namespace CliFx /// public async ValueTask RunAsync(IReadOnlyList commandLineArguments) { + // Environment variable names are case-insensitive on Windows but are case-sensitive on Linux and macOS var environmentVariables = Environment.GetEnvironmentVariables() .Cast() - .ToDictionary(e => (string) e.Key, e => (string) e.Value, StringComparer.OrdinalIgnoreCase); + .ToDictionary(e => (string) e.Key, e => (string) e.Value, StringComparer.Ordinal); return await RunAsync(commandLineArguments, environmentVariables); } @@ -264,4 +265,4 @@ namespace CliFx public ValueTask ExecuteAsync(IConsole console) => default; } } -} \ No newline at end of file +} diff --git a/CliFx/Domain/CommandOptionSchema.cs b/CliFx/Domain/CommandOptionSchema.cs index e4b95fa..bc79f57 100644 --- a/CliFx/Domain/CommandOptionSchema.cs +++ b/CliFx/Domain/CommandOptionSchema.cs @@ -45,7 +45,7 @@ namespace CliFx.Domain public bool MatchesEnvironmentVariableName(string environmentVariableName) => !string.IsNullOrWhiteSpace(EnvironmentVariableName) && - string.Equals(EnvironmentVariableName, environmentVariableName, StringComparison.OrdinalIgnoreCase); + string.Equals(EnvironmentVariableName, environmentVariableName, StringComparison.Ordinal); public string GetUserFacingDisplayString() {