Skip to content

Commit 317afeb

Browse files
authored
Fix working directory of simple file-based apps (#51828)
1 parent 22c641b commit 317afeb

File tree

2 files changed

+122
-5
lines changed

2 files changed

+122
-5
lines changed

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -537,8 +537,7 @@ static ICommand CreateCommandForCscBuiltProgram(string entryPointFileFullPath, s
537537
var artifactsPath = VirtualProjectBuildingCommand.GetArtifactsPath(entryPointFileFullPath);
538538
var exePath = Path.Join(artifactsPath, "bin", "debug", Path.GetFileNameWithoutExtension(entryPointFileFullPath) + FileNameSuffixes.CurrentPlatform.Exe);
539539
var commandSpec = new CommandSpec(path: exePath, args: ArgumentEscaper.EscapeAndConcatenateArgArrayForProcessStart(args));
540-
var command = CommandFactoryUsingResolver.Create(commandSpec)
541-
.WorkingDirectory(Path.GetDirectoryName(entryPointFileFullPath));
540+
var command = CommandFactoryUsingResolver.Create(commandSpec);
542541

543542
SetRootVariableName(
544543
command,

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

Lines changed: 121 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -880,6 +880,124 @@ public void EmptyFile()
880880
.And.HaveStdOutContaining("error CS5001:"); // Program does not contain a static 'Main' method suitable for an entry point
881881
}
882882

883+
/// <summary>
884+
/// See <see href="https://github.com/dotnet/sdk/issues/51778"/>.
885+
/// </summary>
886+
[Theory, CombinatorialData]
887+
public void WorkingDirectory(bool cscOnly)
888+
{
889+
var testInstance = _testAssetsManager.CreateTestDirectory(baseDirectory: cscOnly ? OutOfTreeBaseDirectory : null);
890+
var programPath = Path.Join(testInstance.Path, "Program.cs");
891+
892+
var code = """
893+
Console.WriteLine("v1");
894+
Console.WriteLine(Environment.CurrentDirectory);
895+
Console.WriteLine(Directory.GetCurrentDirectory());
896+
Console.WriteLine(new DirectoryInfo(".").FullName);
897+
Console.WriteLine(AppContext.GetData("EntryPointFileDirectoryPath"));
898+
""";
899+
900+
File.WriteAllText(programPath, code);
901+
902+
var workDir = TestPathUtility.ResolveTempPrefixLink(Path.GetTempPath()).TrimEnd(Path.DirectorySeparatorChar);
903+
904+
var artifactsDir = VirtualProjectBuildingCommand.GetArtifactsPath(programPath);
905+
if (Directory.Exists(artifactsDir)) Directory.Delete(artifactsDir, recursive: true);
906+
907+
Build(testInstance,
908+
expectedLevel: cscOnly ? BuildLevel.Csc : BuildLevel.All,
909+
programFileName: programPath,
910+
workDir: workDir,
911+
expectedOutput: GetExpectedOutput("v1", workDir));
912+
913+
code = code.Replace("v1", "v2");
914+
File.WriteAllText(programPath, code);
915+
916+
Build(testInstance,
917+
expectedLevel: BuildLevel.Csc,
918+
programFileName: programPath,
919+
workDir: workDir,
920+
expectedOutput: GetExpectedOutput("v2", workDir));
921+
922+
string GetExpectedOutput(string version, string workDir) => $"""
923+
{version}
924+
{workDir}
925+
{workDir}
926+
{workDir}
927+
{Path.GetDirectoryName(programPath)}
928+
""";
929+
}
930+
931+
/// <summary>
932+
/// Combination of <see cref="WorkingDirectory"/> and <see cref="CscOnly_AfterMSBuild"/>.
933+
/// </summary>
934+
[Fact]
935+
public void WorkingDirectory_CscOnly_AfterMSBuild()
936+
{
937+
var testInstance = _testAssetsManager.CreateTestDirectory(baseDirectory: OutOfTreeBaseDirectory);
938+
var programPath = Path.Join(testInstance.Path, "Program.cs");
939+
940+
var code = """
941+
#:property Configuration=Release
942+
Console.WriteLine("v1");
943+
Console.WriteLine(Environment.CurrentDirectory);
944+
Console.WriteLine(Directory.GetCurrentDirectory());
945+
Console.WriteLine(new DirectoryInfo(".").FullName);
946+
Console.WriteLine(AppContext.GetData("EntryPointFileDirectoryPath"));
947+
""";
948+
949+
File.WriteAllText(programPath, code);
950+
951+
var workDir = TestPathUtility.ResolveTempPrefixLink(Path.GetTempPath()).TrimEnd(Path.DirectorySeparatorChar);
952+
953+
var artifactsDir = VirtualProjectBuildingCommand.GetArtifactsPath(programPath);
954+
if (Directory.Exists(artifactsDir)) Directory.Delete(artifactsDir, recursive: true);
955+
956+
Build(testInstance,
957+
expectedLevel: BuildLevel.All,
958+
programFileName: programPath,
959+
workDir: workDir,
960+
expectedOutput: GetExpectedOutput("v1", workDir));
961+
962+
Build(testInstance,
963+
expectedLevel: BuildLevel.None,
964+
programFileName: programPath,
965+
workDir: workDir,
966+
expectedOutput: GetExpectedOutput("v1", workDir));
967+
968+
code = code.Replace("v1", "v2");
969+
File.WriteAllText(programPath, code);
970+
971+
Build(testInstance,
972+
expectedLevel: BuildLevel.Csc,
973+
programFileName: programPath,
974+
workDir: workDir,
975+
expectedOutput: GetExpectedOutput("v2", workDir));
976+
977+
// Can be overridden with a #:property.
978+
var workDir2 = Path.Join(testInstance.Path, "dir2");
979+
Directory.CreateDirectory(workDir2);
980+
code = $"""
981+
#:property RunWorkingDirectory={workDir2}
982+
{code}
983+
""";
984+
File.WriteAllText(programPath, code);
985+
986+
Build(testInstance,
987+
expectedLevel: BuildLevel.All,
988+
programFileName: programPath,
989+
workDir: workDir,
990+
expectedOutput: GetExpectedOutput("v2", workDir2));
991+
992+
string GetExpectedOutput(string version, string workDir) => $"""
993+
{version}
994+
{workDir}
995+
{workDir}
996+
{workDir}
997+
{Path.GetDirectoryName(programPath)}
998+
""";
999+
}
1000+
8831001
/// <summary>
8841002
/// Implicit build files have an effect.
8851003
/// </summary>
@@ -3238,7 +3356,7 @@ Release config
32383356
Build(testInstance, BuildLevel.Csc);
32393357
}
32403358

3241-
private void Build(TestDirectory testInstance, BuildLevel expectedLevel, ReadOnlySpan<string> args = default, string expectedOutput = "Hello from Program", string programFileName = "Program.cs")
3359+
private void Build(TestDirectory testInstance, BuildLevel expectedLevel, ReadOnlySpan<string> args = default, string expectedOutput = "Hello from Program", string programFileName = "Program.cs", string? workDir = null)
32423360
{
32433361
string prefix = expectedLevel switch
32443362
{
@@ -3249,12 +3367,12 @@ private void Build(TestDirectory testInstance, BuildLevel expectedLevel, ReadOnl
32493367
};
32503368

32513369
new DotnetCommand(Log, ["run", programFileName, "-bl", .. args])
3252-
.WithWorkingDirectory(testInstance.Path)
3370+
.WithWorkingDirectory(workDir ?? testInstance.Path)
32533371
.Execute()
32543372
.Should().Pass()
32553373
.And.HaveStdOut(prefix + expectedOutput);
32563374

3257-
var binlogs = new DirectoryInfo(testInstance.Path)
3375+
var binlogs = new DirectoryInfo(workDir ?? testInstance.Path)
32583376
.EnumerateFiles("*.binlog", SearchOption.TopDirectoryOnly);
32593377

32603378
binlogs.Select(f => f.Name)

0 commit comments

Comments
 (0)