Skip to content

Commit 1a2c7af

Browse files
authored
Set runtime config values for path to executing script (#49330)
2 parents 5e1709c + 4e3b4a5 commit 1a2c7af

File tree

6 files changed

+157
-2
lines changed

6 files changed

+157
-2
lines changed

src/Cli/Microsoft.DotNet.Cli.Utils/BuiltInCommand.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,4 +181,9 @@ public ICommand SetCommandArgs(string commandArgs)
181181
{
182182
throw new NotImplementedException();
183183
}
184+
185+
public ICommand StandardOutputEncoding(Encoding encoding)
186+
{
187+
throw new NotImplementedException();
188+
}
184189
}

src/Cli/Microsoft.DotNet.Cli.Utils/Command.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,12 @@ public ICommand EnvironmentVariable(string name, string? value)
101101
return this;
102102
}
103103

104+
public ICommand StandardOutputEncoding(Encoding encoding)
105+
{
106+
_process.StartInfo.StandardOutputEncoding = encoding;
107+
return this;
108+
}
109+
104110
public ICommand CaptureStdOut()
105111
{
106112
ThrowIfRunning();

src/Cli/Microsoft.DotNet.Cli.Utils/ICommand.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ public interface ICommand
2525

2626
ICommand SetCommandArgs(string commandArgs);
2727

28+
ICommand StandardOutputEncoding(Encoding encoding);
29+
2830
string CommandName { get; }
2931

3032
string CommandArgs { get; }

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ public VirtualProjectBuildingCommand(
8787
public override int Execute()
8888
{
8989
Debug.Assert(!(NoRestore && NoBuild));
90-
9190
var consoleLogger = RunCommand.MakeTerminalLogger(Verbosity);
9291
var binaryLogger = GetBinaryLogger(BinaryLoggerArgs);
9392

@@ -620,6 +619,15 @@ public static void WriteProjectFile(
620619
621620
""");
622621

622+
var targetDirectory = Path.GetDirectoryName(targetFilePath) ?? "";
623+
writer.WriteLine($"""
624+
<ItemGroup>
625+
<RuntimeHostConfigurationOption Include="EntryPointFilePath" Value="{EscapeValue(targetFilePath)}" />
626+
<RuntimeHostConfigurationOption Include="EntryPointFileDirectoryPath" Value="{EscapeValue(targetDirectory)}" />
627+
</ItemGroup>
628+
629+
""");
630+
623631
foreach (var sdk in sdkDirectives)
624632
{
625633
WriteImport(writer, "Sdk.targets", sdk);

test/Microsoft.NET.TestFramework/Commands/TestCommand.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ public abstract class TestCommand
2626
public Action<string>? CommandOutputHandler { get; set; }
2727
public Action<Process>? ProcessStartedHandler { get; set; }
2828

29+
public Encoding? StandardOutputEncoding { get; set; }
30+
2931
protected TestCommand(ITestOutputHelper log)
3032
{
3133
Log = log;
@@ -57,6 +59,12 @@ public TestCommand WithStandardInput(string stdin)
5759
return this;
5860
}
5961

62+
public TestCommand WithStandardOutputEncoding(Encoding encoding)
63+
{
64+
StandardOutputEncoding = encoding;
65+
return this;
66+
}
67+
6068
/// <summary>
6169
/// Instructs not to escape the arguments when launching command.
6270
/// This may be used to pass ready arguments line as single string argument.
@@ -153,6 +161,11 @@ public virtual CommandResult Execute(IEnumerable<string> args)
153161
{
154162
Log.WriteLine($"❌{line}");
155163
});
164+
165+
if (StandardOutputEncoding is not null)
166+
{
167+
command.StandardOutputEncoding(StandardOutputEncoding);
168+
}
156169

157170
string fileToShow = Path.GetFileNameWithoutExtension(spec.FileName!).Equals("dotnet", StringComparison.OrdinalIgnoreCase) ?
158171
"dotnet" :

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

Lines changed: 122 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Licensed to the .NET Foundation under one or more agreements.
1+
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System.Runtime.Versioning;
@@ -1277,6 +1277,11 @@ public void Api()
12771277
<Compile Include="{programPath}" />
12781278
</ItemGroup>
12791279
1280+
<ItemGroup>
1281+
<RuntimeHostConfigurationOption Include="EntryPointFilePath" Value="{programPath}" />
1282+
<RuntimeHostConfigurationOption Include="EntryPointFileDirectoryPath" Value="{testInstance.Path}" />
1283+
</ItemGroup>
1284+
12801285
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
12811286
<Import Project="Sdk.targets" Sdk="Aspire.Hosting.Sdk" Version="9.1.0" />
12821287
@@ -1360,6 +1365,11 @@ public void Api_Diagnostic_01()
13601365
<Compile Include="{programPath}" />
13611366
</ItemGroup>
13621367
1368+
<ItemGroup>
1369+
<RuntimeHostConfigurationOption Include="EntryPointFilePath" Value="{programPath}" />
1370+
<RuntimeHostConfigurationOption Include="EntryPointFileDirectoryPath" Value="{testInstance.Path}" />
1371+
</ItemGroup>
1372+
13631373
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
13641374
13651375
<!--
@@ -1446,6 +1456,11 @@ public void Api_Diagnostic_02()
14461456
<Compile Include="{programPath}" />
14471457
</ItemGroup>
14481458
1459+
<ItemGroup>
1460+
<RuntimeHostConfigurationOption Include="EntryPointFilePath" Value="{programPath}" />
1461+
<RuntimeHostConfigurationOption Include="EntryPointFileDirectoryPath" Value="{testInstance.Path}" />
1462+
</ItemGroup>
1463+
14491464
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
14501465
14511466
<!--
@@ -1501,4 +1516,110 @@ public void Api_Error()
15011516
.And.HaveStdOutContaining("Unknown1")
15021517
.And.HaveStdOutContaining("Unknown2");
15031518
}
1519+
1520+
[Fact]
1521+
public void EntryPointFilePath()
1522+
{
1523+
var testInstance = _testAssetsManager.CreateTestDirectory();
1524+
var filePath = Path.Join(testInstance.Path, "Program.cs");
1525+
File.WriteAllText(filePath, """"
1526+
var entryPointFilePath = AppContext.GetData("EntryPointFilePath") as string;
1527+
Console.WriteLine($"""EntryPointFilePath: {entryPointFilePath}""");
1528+
"""");
1529+
1530+
new DotnetCommand(Log, "run", "Program.cs")
1531+
.WithWorkingDirectory(testInstance.Path)
1532+
.Execute()
1533+
.Should().Pass()
1534+
.And.HaveStdOut($"EntryPointFilePath: {filePath}");
1535+
}
1536+
1537+
[Fact]
1538+
public void EntryPointFileDirectoryPath()
1539+
{
1540+
var testInstance = _testAssetsManager.CreateTestDirectory();
1541+
File.WriteAllText(Path.Join(testInstance.Path, "Program.cs"), """"
1542+
var entryPointFileDirectoryPath = AppContext.GetData("EntryPointFileDirectoryPath") as string;
1543+
Console.WriteLine($"""EntryPointFileDirectoryPath: {entryPointFileDirectoryPath}""");
1544+
"""");
1545+
1546+
new DotnetCommand(Log, "run", "Program.cs")
1547+
.WithWorkingDirectory(testInstance.Path)
1548+
.Execute()
1549+
.Should().Pass()
1550+
.And.HaveStdOut($"EntryPointFileDirectoryPath: {testInstance.Path}");
1551+
}
1552+
1553+
[Fact]
1554+
public void EntryPointFilePath_WithRelativePath()
1555+
{
1556+
var testInstance = _testAssetsManager.CreateTestDirectory();
1557+
var fileName = "Program.cs";
1558+
File.WriteAllText(Path.Join(testInstance.Path, fileName), """
1559+
var entryPointFilePath = AppContext.GetData("EntryPointFilePath") as string;
1560+
Console.WriteLine($"EntryPointFilePath: {entryPointFilePath}");
1561+
""");
1562+
1563+
var relativePath = Path.GetRelativePath(Directory.GetCurrentDirectory(), Path.Join(testInstance.Path, fileName));
1564+
new DotnetCommand(Log, "run", relativePath)
1565+
.WithWorkingDirectory(Directory.GetCurrentDirectory())
1566+
.Execute()
1567+
.Should().Pass()
1568+
.And.HaveStdOut($"EntryPointFilePath: {Path.GetFullPath(relativePath)}");
1569+
}
1570+
1571+
[Fact]
1572+
public void EntryPointFilePath_WithSpacesInPath()
1573+
{
1574+
var testInstance = _testAssetsManager.CreateTestDirectory();
1575+
var dirWithSpaces = Path.Join(testInstance.Path, "dir with spaces");
1576+
Directory.CreateDirectory(dirWithSpaces);
1577+
var filePath = Path.Join(dirWithSpaces, "Program.cs");
1578+
File.WriteAllText(filePath, """
1579+
var entryPointFilePath = AppContext.GetData("EntryPointFilePath") as string;
1580+
Console.WriteLine($"EntryPointFilePath: {entryPointFilePath}");
1581+
""");
1582+
1583+
new DotnetCommand(Log, "run", filePath)
1584+
.WithWorkingDirectory(testInstance.Path)
1585+
.Execute()
1586+
.Should().Pass()
1587+
.And.HaveStdOut($"EntryPointFilePath: {filePath}");
1588+
}
1589+
1590+
[Fact]
1591+
public void EntryPointFileDirectoryPath_WithDotSlash()
1592+
{
1593+
var testInstance = _testAssetsManager.CreateTestDirectory();
1594+
var fileName = "Program.cs";
1595+
File.WriteAllText(Path.Join(testInstance.Path, fileName), """
1596+
var entryPointFileDirectoryPath = AppContext.GetData("EntryPointFileDirectoryPath") as string;
1597+
Console.WriteLine($"EntryPointFileDirectoryPath: {entryPointFileDirectoryPath}");
1598+
""");
1599+
1600+
new DotnetCommand(Log, "run", $"./{fileName}")
1601+
.WithWorkingDirectory(testInstance.Path)
1602+
.Execute()
1603+
.Should().Pass()
1604+
.And.HaveStdOut($"EntryPointFileDirectoryPath: {testInstance.Path}");
1605+
}
1606+
1607+
[Fact]
1608+
public void EntryPointFilePath_WithUnicodeCharacters()
1609+
{
1610+
var testInstance = _testAssetsManager.CreateTestDirectory();
1611+
var unicodeFileName = "Программа.cs";
1612+
var filePath = Path.Join(testInstance.Path, unicodeFileName);
1613+
File.WriteAllText(filePath, """
1614+
var entryPointFilePath = AppContext.GetData("EntryPointFilePath") as string;
1615+
Console.WriteLine($"EntryPointFilePath: {entryPointFilePath}");
1616+
""");
1617+
1618+
new DotnetCommand(Log, "run", unicodeFileName)
1619+
.WithWorkingDirectory(testInstance.Path)
1620+
.WithStandardOutputEncoding(Encoding.UTF8)
1621+
.Execute()
1622+
.Should().Pass()
1623+
.And.HaveStdOut($"EntryPointFilePath: {filePath}");
1624+
}
15041625
}

0 commit comments

Comments
 (0)