Skip to content

Commit b9dde48

Browse files
KathleenDollardmhutch
authored andcommitted
Add subsystem implementing response file handling
1 parent 71cfaed commit b9dde48

File tree

5 files changed

+138
-0
lines changed

5 files changed

+138
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright (c) .NET Foundation and contributors. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using FluentAssertions;
5+
using System.CommandLine.Directives;
6+
using System.CommandLine.Parsing;
7+
using Xunit;
8+
9+
namespace System.CommandLine.Subsystems.Tests;
10+
11+
public class ResponseSubsystemTests
12+
{
13+
14+
[Fact]
15+
// TODO: Not sure why these tests are passing
16+
public void Simple_response_file_contributes_to_parsing()
17+
{
18+
var option = new CliOption<string>("--hello");
19+
var rootCommand = new CliRootCommand { option };
20+
var configuration = new CliConfiguration(rootCommand);
21+
var subsystem = new ResponseSubsystem();
22+
string[] args = ["@Response_1.rsp"];
23+
24+
Subsystem.Initialize(subsystem, configuration, args);
25+
26+
var parseResult = CliParser.Parse(rootCommand, args, configuration);
27+
var value = parseResult.GetValue(option);
28+
29+
value.Should().Be("world");
30+
}
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--hello world

src/System.CommandLine.Subsystems.Tests/System.CommandLine.Subsystems.Tests.csproj

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
<ItemGroup>
1717
<Content Include="TestApps/**/*.csproj" CopyToOutputDirectory="PreserveNewest" />
1818
<Content Include="TestApps/**/*.cs" CopyToOutputDirectory="PreserveNewest" />
19+
<Content Include="Response_1.rsp" CopyToOutputDirectory="PreserveNewest" />
1920
</ItemGroup>
2021

2122
<ItemGroup>
@@ -31,6 +32,7 @@
3132
-->
3233
<Compile Include="AlternateSubsystems.cs" />
3334
<Compile Include="Constants.cs" />
35+
<Compile Include="ResponseSubsystemTests.cs" />
3436
<Compile Include="DirectiveSubsystemTests.cs" />
3537
<Compile Include="DiagramSubsystemTests.cs" />
3638
<Compile Include="PipelineTests.cs" />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// Copyright (c) .NET Foundation and contributors. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using System.CommandLine.Parsing;
5+
using System.CommandLine.Subsystems;
6+
7+
namespace System.CommandLine.Directives;
8+
9+
public class ResponseSubsystem()
10+
: CliSubsystem("Response", SubsystemKind.Response, null)
11+
{
12+
protected internal override CliConfiguration Initialize(InitializationContext context)
13+
{
14+
context.Configuration.ResponseFileTokenReplacer = Replacer;
15+
return context.Configuration;
16+
}
17+
18+
public static (List<string>? tokens, List<string>? errors) Replacer(string responseSourceName)
19+
{
20+
try
21+
{
22+
// TODO: Include checks from previous system.
23+
var contents = File.ReadAllText(responseSourceName);
24+
return (CliParser.SplitCommandLine(contents).ToList(), null);
25+
}
26+
catch
27+
{
28+
// TODO: Switch to proper errors
29+
return (null,
30+
errors:
31+
[
32+
$"Failed to open response file {responseSourceName}"
33+
]);
34+
}
35+
}
36+
37+
// TODO: File handling from previous system - ensure these checks are done (note: no tests caught these oversights
38+
/* internal static bool TryReadResponseFile(
39+
string filePath,
40+
out IReadOnlyList<string>? newTokens,
41+
out string? error)
42+
{
43+
try
44+
{
45+
newTokens = ExpandResponseFile(filePath).ToArray();
46+
error = null;
47+
return true;
48+
}
49+
catch (FileNotFoundException)
50+
{
51+
error = LocalizationResources.ResponseFileNotFound(filePath);
52+
}
53+
catch (IOException e)
54+
{
55+
error = LocalizationResources.ErrorReadingResponseFile(filePath, e);
56+
}
57+
58+
newTokens = null;
59+
return false;
60+
61+
static IEnumerable<string> ExpandResponseFile(string filePath)
62+
{
63+
var lines = File.ReadAllLines(filePath);
64+
65+
for (var i = 0; i < lines.Length; i++)
66+
{
67+
var line = lines[i];
68+
69+
foreach (var p in SplitLine(line))
70+
{
71+
if (GetReplaceableTokenValue(p) is { } path)
72+
{
73+
foreach (var q in ExpandResponseFile(path))
74+
{
75+
yield return q;
76+
}
77+
}
78+
else
79+
{
80+
yield return p;
81+
}
82+
}
83+
}
84+
}
85+
86+
static IEnumerable<string> SplitLine(string line)
87+
{
88+
var arg = line.Trim();
89+
90+
if (arg.Length == 0 || arg[0] == '#')
91+
{
92+
yield break;
93+
}
94+
95+
foreach (var word in CliParser.SplitCommandLine(arg))
96+
{
97+
yield return word;
98+
}
99+
}
100+
}
101+
*/
102+
103+
}

src/System.CommandLine.Subsystems/Subsystems/SubsystemKind.cs

+1
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ public enum SubsystemKind
1111
ErrorReporting,
1212
Completion,
1313
Diagram,
14+
Response,
1415
}

0 commit comments

Comments
 (0)