Skip to content

Commit dfe8030

Browse files
authored
File-based apps: consider args in simple csc optimization (#50779)
1 parent b7b9812 commit dfe8030

File tree

2 files changed

+72
-5
lines changed

2 files changed

+72
-5
lines changed

src/Cli/dotnet/Commands/Run/RunCommand.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ internal ICommand GetTargetCommand(Func<ProjectCollection, ProjectInstance>? pro
397397
// So we can skip project evaluation to continue the optimized path.
398398
Debug.Assert(EntryPointFileFullPath is not null);
399399
Reporter.Verbose.WriteLine("Getting target command: for csc-built program.");
400-
return CreateCommandForCscBuiltProgram(EntryPointFileFullPath);
400+
return CreateCommandForCscBuiltProgram(EntryPointFileFullPath, ApplicationArgs);
401401
}
402402

403403
Reporter.Verbose.WriteLine("Getting target command: evaluating project.");
@@ -463,11 +463,11 @@ static void SetRootVariableName(ICommand command, string runtimeIdentifier, stri
463463
}
464464
}
465465

466-
static ICommand CreateCommandForCscBuiltProgram(string entryPointFileFullPath)
466+
static ICommand CreateCommandForCscBuiltProgram(string entryPointFileFullPath, string[] args)
467467
{
468468
var artifactsPath = VirtualProjectBuildingCommand.GetArtifactsPath(entryPointFileFullPath);
469469
var exePath = Path.Join(artifactsPath, "bin", "debug", Path.GetFileNameWithoutExtension(entryPointFileFullPath) + FileNameSuffixes.CurrentPlatform.Exe);
470-
var commandSpec = new CommandSpec(path: exePath, args: null);
470+
var commandSpec = new CommandSpec(path: exePath, args: ArgumentEscaper.EscapeAndConcatenateArgArrayForProcessStart(args));
471471
var command = CommandFactoryUsingResolver.Create(commandSpec)
472472
.WorkingDirectory(Path.GetDirectoryName(entryPointFileFullPath));
473473

test/dotnet.Tests/CommandTests/Run/RunFileTests.cs

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3034,6 +3034,27 @@ public void CscOnly_SpacesInPath()
30343034
Build(testInstance, BuildLevel.Csc, expectedOutput: "v1", programFileName: programFileName);
30353035
}
30363036

3037+
[Fact] // https://github.com/dotnet/sdk/issues/50778
3038+
public void CscOnly_Args()
3039+
{
3040+
var testInstance = _testAssetsManager.CreateTestDirectory(baseDirectory: OutOfTreeBaseDirectory);
3041+
var programPath = Path.Join(testInstance.Path, "Program.cs");
3042+
File.WriteAllText(programPath, s_program);
3043+
3044+
// Remove artifacts from possible previous runs of this test.
3045+
var artifactsDir = VirtualProjectBuildingCommand.GetArtifactsPath(programPath);
3046+
if (Directory.Exists(artifactsDir)) Directory.Delete(artifactsDir, recursive: true);
3047+
3048+
Build(testInstance, BuildLevel.Csc, args: ["test", "args"], expectedOutput: """
3049+
echo args:test;args
3050+
Hello from Program
3051+
""");
3052+
}
3053+
3054+
/// <summary>
3055+
/// Tests an optimization which remembers CSC args from prior MSBuild runs and can skip subsequent MSBuild invocations and call CSC directly.
3056+
/// This optimization kicks in when the file has some <c>#:</c> directives (then the simpler "hard-coded CSC args" optimization cannot be used).
3057+
/// </summary>
30373058
[Fact]
30383059
public void CscOnly_AfterMSBuild()
30393060
{
@@ -3089,6 +3110,9 @@ public void CscOnly_AfterMSBuild()
30893110
Build(testInstance, BuildLevel.All, expectedOutput: "v4 ");
30903111
}
30913112

3113+
/// <summary>
3114+
/// See <see cref="CscOnly_AfterMSBuild"/>.
3115+
/// </summary>
30923116
[Fact]
30933117
public void CscOnly_AfterMSBuild_SpacesInPath()
30943118
{
@@ -3119,6 +3143,46 @@ public void CscOnly_AfterMSBuild_SpacesInPath()
31193143
Build(testInstance, BuildLevel.Csc, expectedOutput: "v2 Release", programFileName: programFileName);
31203144
}
31213145

3146+
/// <summary>
3147+
/// See <see cref="CscOnly_AfterMSBuild"/>.
3148+
/// </summary>
3149+
[Fact]
3150+
public void CscOnly_AfterMSBuild_Args()
3151+
{
3152+
var testInstance = _testAssetsManager.CreateTestDirectory(baseDirectory: OutOfTreeBaseDirectory);
3153+
var programPath = Path.Join(testInstance.Path, "Program.cs");
3154+
3155+
var code = $"""
3156+
#:property Configuration=Release
3157+
{s_program}
3158+
""";
3159+
3160+
File.WriteAllText(programPath, code);
3161+
3162+
// Remove artifacts from possible previous runs of this test.
3163+
var artifactsDir = VirtualProjectBuildingCommand.GetArtifactsPath(programPath);
3164+
if (Directory.Exists(artifactsDir)) Directory.Delete(artifactsDir, recursive: true);
3165+
3166+
Build(testInstance, BuildLevel.All, args: ["test", "args"], expectedOutput: """
3167+
echo args:test;args
3168+
Hello from Program
3169+
Release config
3170+
""");
3171+
3172+
code = code.Replace("Hello", "Hi");
3173+
File.WriteAllText(programPath, code);
3174+
3175+
Build(testInstance, BuildLevel.Csc, ["test", "args"], expectedOutput: """
3176+
echo args:test;args
3177+
Hi from Program
3178+
Release config
3179+
""");
3180+
}
3181+
3182+
/// <summary>
3183+
/// See <see cref="CscOnly_AfterMSBuild"/>.
3184+
/// This optimization currently does not support <c>#:project</c> references and hence is disabled if those are present.
3185+
/// </summary>
31223186
[Fact]
31233187
public void CscOnly_AfterMSBuild_ProjectReferences()
31243188
{
@@ -3175,8 +3239,8 @@ public class LibClass
31753239
}
31763240

31773241
/// <summary>
3178-
/// If users have more complex build customizations, they can opt out of the optimization which
3179-
/// reuses CSC arguments and skips subsequent MSBuild invocations.
3242+
/// See <see cref="CscOnly_AfterMSBuild"/>.
3243+
/// If users have more complex build customizations, they can opt out of the optimization.
31803244
/// </summary>
31813245
[Theory, CombinatorialData]
31823246
public void CscOnly_AfterMSBuild_OptOut(bool canSkipMSBuild, bool inDirectoryBuildProps)
@@ -3220,6 +3284,9 @@ public void CscOnly_AfterMSBuild_OptOut(bool canSkipMSBuild, bool inDirectoryBui
32203284
Build(testInstance, canSkipMSBuild ? BuildLevel.Csc : BuildLevel.All, expectedOutput: "v2 Release");
32213285
}
32223286

3287+
/// <summary>
3288+
/// See <see cref="CscOnly_AfterMSBuild"/>.
3289+
/// </summary>
32233290
[Fact]
32243291
public void CscOnly_AfterMSBuild_AuxiliaryFilesNotReused()
32253292
{

0 commit comments

Comments
 (0)