Skip to content

Commit 0494802

Browse files
adamsitnikeerhardt
andauthored
Add NativeAOT test (#1656)
* move TrimmingTestApp to TestApps folder * add NativeAOT test * make sure detailed log output is produced * don't use reflection for creating an array of objects * Empty is misleading as the capacity can be > 0 * improve the test * suppress the single warning we get so far * remove unused type * use OS-specific rid * Add link to the issue * Apply suggestions from code review Co-authored-by: Eric Erhardt <[email protected]> * avoid code duplication * use hardcoded version Co-authored-by: Eric Erhardt <[email protected]>
1 parent b55482a commit 0494802

File tree

10 files changed

+91
-45
lines changed

10 files changed

+91
-45
lines changed

NuGet.config

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
<add key="dotnet-eng" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json" />
1010
<add key="dotnet-tools" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json" />
1111
<add key="dotnet-libraries" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-libraries/nuget/v3/index.json" />
12+
<!-- required by NativeAOT -->
13+
<add key="dotnet7" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet7/nuget/v3/index.json" />
1214
</packageSources>
1315
<disabledPackageSources />
1416
</configuration>

src/System.CommandLine.Tests/TrimmingTests.cs renamed to src/System.CommandLine.Tests/CompilationTests.cs

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,18 @@
88
using System.IO;
99
using System.Text;
1010
using FluentAssertions;
11+
using Microsoft.DotNet.PlatformAbstractions;
1112
using Xunit;
1213
using Xunit.Abstractions;
1314

1415
namespace System.CommandLine.Tests;
1516

16-
public class TrimmingTests
17+
public class CompilationTests
1718
{
1819
private readonly ITestOutputHelper _output;
1920
private readonly string _systemCommandLineDllPath;
2021

21-
public TrimmingTests(ITestOutputHelper output)
22+
public CompilationTests(ITestOutputHelper output)
2223
{
2324
_output = output;
2425

@@ -29,25 +30,35 @@ public TrimmingTests(ITestOutputHelper output)
2930
[InlineData("")]
3031
[InlineData("-p:PublishSingleFile=true")]
3132
public void App_referencing_system_commandline_can_be_trimmed(string additionalArgs)
33+
=> PublishAndValidate("Trimming", "warning IL", additionalArgs);
34+
35+
[ReleaseBuildOnlyFact]
36+
public void App_referencing_system_commandline_can_be_compiled_ahead_of_time()
37+
=> PublishAndValidate("NativeAOT", "AOT analysis warning");
38+
39+
private void PublishAndValidate(string appName, string warningText, string additionalArgs = null)
3240
{
3341
var stdOut = new StringBuilder();
3442
var stdErr = new StringBuilder();
3543

36-
var workingDirectory = Path.Combine(Directory.GetCurrentDirectory(), "TrimmingTestApp");
37-
44+
var workingDirectory = Path.Combine(Directory.GetCurrentDirectory(), "TestApps", appName);
45+
46+
string rId = GetPortableRuntimeIdentifier();
47+
3848
Process.RunToCompletion(
3949
DotnetMuxer.Path.FullName,
40-
"clean -c Release -r win-x64",
50+
$"clean -c Release -r {rId}",
4151
workingDirectory: workingDirectory);
4252

43-
var commandLine = string.Format(
44-
"publish -c Release -r win-x64 --self-contained -p:SystemCommandLineDllPath=\"{0}\" -p:TreatWarningsAsErrors=true -p:PublishTrimmed=true {1}",
53+
string publishCommand = string.Format(
54+
"publish -c Release -r {0} --self-contained -p:SystemCommandLineDllPath=\"{1}\" -p:TreatWarningsAsErrors=true {2}",
55+
rId,
4556
_systemCommandLineDllPath,
4657
additionalArgs);
4758

4859
var exitCode = Process.RunToCompletion(
4960
DotnetMuxer.Path.FullName,
50-
commandLine,
61+
publishCommand,
5162
s =>
5263
{
5364
_output.WriteLine(s);
@@ -60,10 +71,16 @@ public void App_referencing_system_commandline_can_be_trimmed(string additionalA
6071
},
6172
workingDirectory);
6273

63-
stdOut.ToString().Should().NotContain("warning IL");
74+
stdOut.ToString().Should().NotContain(warningText);
6475
stdErr.ToString().Should().BeEmpty();
6576
exitCode.Should().Be(0);
6677
}
78+
79+
private static string GetPortableRuntimeIdentifier()
80+
{
81+
string osPart = OperatingSystem.IsWindows() ? "win" : (OperatingSystem.IsMacOS() ? "osx" : "linux");
82+
return $"{osPart}-{RuntimeEnvironment.RuntimeArchitecture}";
83+
}
6784
}
6885

6986
#endif

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

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,15 @@
1414
<EmbeddedResource Remove="TestResults\**" />
1515
<None Remove="TestResults\**" />
1616

17-
<Compile Remove="TrimmingTestApp/**" />
18-
<Content Remove="TrimmingTestApp/**" />
19-
<EmbeddedResource Remove="TrimmingTestApp/**" />
20-
<None Remove="TrimmingTestApp/**" />
17+
<Compile Remove="TestApps/**" />
18+
<Content Remove="TestApps/**" />
19+
<EmbeddedResource Remove="TestApps/**" />
20+
<None Remove="TestApps/**" />
2121

22-
23-
<Content Include="TrimmingTestApp/TrimmingTestApp.csproj">
22+
<Content Include="TestApps/**/*.csproj">
2423
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
2524
</Content>
26-
<Content Include="TrimmingTestApp/Program.cs">
25+
<Content Include="TestApps/**/*.cs">
2726
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
2827
</Content>
2928

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net6.0</TargetFramework>
6+
<!-- producing more detailed log output -->
7+
<TrimmerSingleWarn>false</TrimmerSingleWarn>
8+
</PropertyGroup>
9+
10+
<PropertyGroup>
11+
<SystemCommandLineDllPath Condition="'$(SystemCommandLineDllPath)'==''">..\..\..\System.CommandLine\bin\Release\net6.0\System.CommandLine.dll</SystemCommandLineDllPath>
12+
</PropertyGroup>
13+
14+
<ItemGroup>
15+
<Reference Include="SystemCommandLineDll">
16+
<HintPath>$(SystemCommandLineDllPath)</HintPath>
17+
</Reference>
18+
<PackageReference Include="Microsoft.DotNet.ILCompiler" Version="7.0.0-preview.3.22123.2" />
19+
</ItemGroup>
20+
21+
</Project>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using System;
2+
using System.CommandLine;
3+
using System.CommandLine.Builder;
4+
using System.CommandLine.Parsing;
5+
6+
public class Program
7+
{
8+
static void Run(bool boolean, string text)
9+
{
10+
Console.WriteLine($"Bool option: {text}");
11+
Console.WriteLine($"String option: {boolean}");
12+
}
13+
14+
private static int Main(string[] args)
15+
{
16+
Option<bool> boolOption = new Option<bool>(new[] { "--bool", "-b" }, "Bool option");
17+
Option<string> stringOption = new Option<string>(new[] { "--string", "-s" }, "String option");
18+
19+
RootCommand command = new RootCommand
20+
{
21+
boolOption,
22+
stringOption
23+
};
24+
25+
command.SetHandler<bool, string>(Run, boolOption, stringOption);
26+
27+
return new CommandLineBuilder(command).Build().Invoke(args);
28+
}
29+
}

src/System.CommandLine.Tests/TrimmingTestApp/TrimmingTestApp.csproj renamed to src/System.CommandLine.Tests/TestApps/Trimming/Trimming.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
</PropertyGroup>
1111

1212
<PropertyGroup>
13-
<SystemCommandLineDllPath Condition="'$(SystemCommandLineDllPath)'==''">..\..\System.CommandLine\bin\Release\net6.0\System.CommandLine.dll</SystemCommandLineDllPath>
13+
<SystemCommandLineDllPath Condition="'$(SystemCommandLineDllPath)'==''">..\..\..\System.CommandLine\bin\Release\net6.0\System.CommandLine.dll</SystemCommandLineDllPath>
1414
</PropertyGroup>
1515

1616
<ItemGroup>

src/System.CommandLine/Binding/ArgumentConverter.DefaultValues.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ internal static partial class ArgumentConverter
1515
private static ConstructorInfo? _listCtor;
1616
#endif
1717

18-
private static Array CreateEmptyArray(Type itemType, int capacity = 0)
18+
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL3050", Justification = "https://github.com/dotnet/command-line-api/issues/1638")]
19+
private static Array CreateArray(Type itemType, int capacity)
1920
=> Array.CreateInstance(itemType, capacity);
2021

2122
private static IList CreateEmptyList(Type listType)
@@ -40,18 +41,18 @@ private static IList CreateEnumerable(Type type, Type itemType, int capacity = 0
4041
{
4142
if (type.IsArray)
4243
{
43-
return CreateEmptyArray(itemType, capacity);
44+
return CreateArray(itemType, capacity);
4445
}
4546

4647
if (type.IsGenericType)
4748
{
4849
var x = type.GetGenericTypeDefinition() switch
4950
{
5051
{ } enumerable when typeof(IEnumerable<>).IsAssignableFrom(enumerable) =>
51-
CreateEmptyArray(itemType, capacity),
52+
CreateArray(itemType, capacity),
5253
{ } array when typeof(IList<>).IsAssignableFrom(array) ||
5354
typeof(ICollection<>).IsAssignableFrom(array) =>
54-
CreateEmptyArray(itemType, capacity),
55+
CreateArray(itemType, capacity),
5556
{ } list when list == typeof(List<>) =>
5657
CreateEmptyList(type),
5758
_ => null

src/System.CommandLine/Binding/ArgumentConverter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ public static bool TryConvertArgument(ArgumentResult argumentResult, out object?
276276
when nonGeneric == typeof(IList) ||
277277
nonGeneric == typeof(ICollection) ||
278278
nonGeneric == typeof(IEnumerable)
279-
=> CreateEmptyArray(typeof(object)),
279+
=> Array.Empty<object>(),
280280
_ when type.IsValueType => CreateDefaultValueType(type),
281281
_ => null
282282
};

src/System.CommandLine/Binding/TypeDefaultValueSource.cs

Lines changed: 0 additions & 23 deletions
This file was deleted.

0 commit comments

Comments
 (0)