Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/Build.UnitTests/Utilities_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,17 @@ public void CommentsInPreprocessing()

env.SetEnvironmentVariable("MSBUILDLOADALLFILESASWRITEABLE", "1");

#if FEATURE_GET_COMMANDLINE
MSBuildApp.Execute(@"c:\bin\msbuild.exe """ + inputFile.Path +
(NativeMethodsShared.IsUnixLike ? @""" -pp:""" : @""" /pp:""") + outputFile.Path + @"""")
.ShouldBe(MSBuildApp.ExitType.Success);
#else
Assert.Equal(
MSBuildApp.ExitType.Success,
MSBuildApp.Execute(
new[] { @"c:\bin\msbuild.exe", '"' + inputFile.Path + '"',
'"' + (NativeMethodsShared.IsUnixLike ? "-pp:" : "/pp:") + outputFile.Path + '"'}));
#endif

bool foundDoNotModify = false;
foreach (string line in File.ReadLines(outputFile.Path))
Expand Down
19 changes: 17 additions & 2 deletions src/Build/BackEnd/Client/MSBuildClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,11 @@ public sealed class MSBuildClient
/// The command line to process.
/// The first argument on the command line is assumed to be the name/path of the executable, and is ignored.
/// </summary>
#if FEATURE_GET_COMMANDLINE
private readonly string _commandLine;
#else
private readonly string[] _commandLine;
#endif

/// <summary>
/// The MSBuild client execution result.
Expand Down Expand Up @@ -108,7 +112,13 @@ public sealed class MSBuildClient
/// on the command line is assumed to be the name/path of the executable, and is ignored</param>
/// <param name="msbuildLocation"> Full path to current MSBuild.exe if executable is MSBuild.exe,
/// or to version of MSBuild.dll found to be associated with the current process.</param>
public MSBuildClient(string commandLine, string msbuildLocation)
public MSBuildClient(
#if FEATURE_GET_COMMANDLINE
string commandLine,
#else
string[] commandLine,
#endif
string msbuildLocation)
{
_serverEnvironmentVariables = new();
_exitResult = new();
Expand Down Expand Up @@ -152,7 +162,12 @@ private void CreateNodePipeStream()
public MSBuildClientExitResult Execute(CancellationToken cancellationToken)
{
// Command line in one string used only in human readable content.
string descriptiveCommandLine = _commandLine;
string descriptiveCommandLine =
#if FEATURE_GET_COMMANDLINE
_commandLine;
#else
string.Join(" ", _commandLine);
#endif

CommunicationsUtilities.Trace("Executing build with command line '{0}'", descriptiveCommandLine);

Expand Down
7 changes: 6 additions & 1 deletion src/Build/BackEnd/Node/OutOfProcServerNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@ public sealed class OutOfProcServerNode : INode, INodePacketFactory, INodePacket
/// <summary>
/// A callback used to execute command line build.
/// </summary>
public delegate (int exitCode, string exitType) BuildCallback(string commandLine);
public delegate (int exitCode, string exitType) BuildCallback(
#if FEATURE_GET_COMMANDLINE
string commandLine);
#else
string[] commandLine);
#endif

private readonly BuildCallback _buildFunction;

Expand Down
12 changes: 12 additions & 0 deletions src/Build/BackEnd/Node/ServerNodeBuildCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ namespace Microsoft.Build.BackEnd
/// </summary>
internal sealed class ServerNodeBuildCommand : INodePacket
{
#if FEATURE_GET_COMMANDLINE
private string _commandLine = default!;
#else
private string[] _commandLine = default!;
#endif
private string _startupDirectory = default!;
private Dictionary<string, string> _buildProcessEnvironment = default!;
private CultureInfo _culture = default!;
Expand All @@ -30,7 +34,11 @@ internal sealed class ServerNodeBuildCommand : INodePacket
/// <summary>
/// Command line including arguments
/// </summary>
#if FEATURE_GET_COMMANDLINE
public string CommandLine => _commandLine;
#else
public string[] CommandLine => _commandLine;
#endif

/// <summary>
/// The startup directory
Expand Down Expand Up @@ -71,7 +79,11 @@ private ServerNodeBuildCommand()
}

public ServerNodeBuildCommand(
#if FEATURE_GET_COMMANDLINE
string commandLine,
#else
string[] commandLine,
#endif
string startupDirectory,
Dictionary<string, string> buildProcessEnvironment,
CultureInfo culture, CultureInfo uiCulture,
Expand Down
47 changes: 1 addition & 46 deletions src/Build/CompatibilitySuppressions.xml
Original file line number Diff line number Diff line change
@@ -1,48 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://learn.microsoft.com/dotnet/fundamentals/package-validation/diagnostic-ids -->
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!-- MSBuildClient is in experimental namespace and not used outside the MSBuild -->
<!-- OutOfProcServerNode.BuildCallback is in experimental namespace and not used outside the MSBuild -->
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Build.Experimental.MSBuildClient.#ctor(System.String[],System.String)</Target>
<Left>lib/net10.0/Microsoft.Build.dll</Left>
<Right>lib/net10.0/Microsoft.Build.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Build.Experimental.OutOfProcServerNode.BuildCallback.BeginInvoke(System.String[],System.AsyncCallback,System.Object)</Target>
<Left>lib/net10.0/Microsoft.Build.dll</Left>
<Right>lib/net10.0/Microsoft.Build.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Build.Experimental.OutOfProcServerNode.BuildCallback.Invoke(System.String[])</Target>
<Left>lib/net10.0/Microsoft.Build.dll</Left>
<Right>lib/net10.0/Microsoft.Build.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Build.Experimental.MSBuildClient.#ctor(System.String[],System.String)</Target>
<Left>ref/net10.0/Microsoft.Build.dll</Left>
<Right>ref/net10.0/Microsoft.Build.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Build.Experimental.OutOfProcServerNode.BuildCallback.BeginInvoke(System.String[],System.AsyncCallback,System.Object)</Target>
<Left>ref/net10.0/Microsoft.Build.dll</Left>
<Right>ref/net10.0/Microsoft.Build.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Build.Experimental.OutOfProcServerNode.BuildCallback.Invoke(System.String[])</Target>
<Left>ref/net10.0/Microsoft.Build.dll</Left>
<Right>ref/net10.0/Microsoft.Build.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
</Suppressions>
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
1 change: 1 addition & 0 deletions src/Directory.BeforeCommon.targets
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
<DefineConstants>$(DefineConstants);FEATURE_ENVIRONMENT_SYSTEMDIRECTORY</DefineConstants>
<DefineConstants>$(DefineConstants);FEATURE_FILE_TRACKER</DefineConstants>
<DefineConstants Condition="'$(MachineIndependentBuild)' != 'true'">$(DefineConstants);FEATURE_GAC</DefineConstants>
<DefineConstants>$(DefineConstants);FEATURE_GET_COMMANDLINE</DefineConstants>
<DefineConstants>$(DefineConstants);FEATURE_HANDLEPROCESSCORRUPTEDSTATEEXCEPTIONS</DefineConstants>
<DefineConstants>$(DefineConstants);FEATURE_HTTP_LISTENER</DefineConstants>
<DefineConstants Condition="'$(MachineIndependentBuild)' != 'true'">$(DefineConstants);FEATURE_INSTALLED_MSBUILD</DefineConstants>
Expand Down
55 changes: 21 additions & 34 deletions src/MSBuild.UnitTests/CommandLineSwitches_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -622,8 +622,7 @@ public void FeatureAvailibilitySwitchIdentificationTest(string switchName)
public void TargetsSwitchParameter()
{
CommandLineSwitches switches = new CommandLineSwitches();
CommandLineParser parser = new CommandLineParser();
parser.GatherCommandLineSwitches(new List<string>() { "/targets:targets.txt" }, switches);
MSBuildApp.GatherCommandLineSwitches(new List<string>() { "/targets:targets.txt" }, switches);

switches.HaveErrors().ShouldBeFalse();
switches[CommandLineSwitches.ParameterizedSwitch.Targets].ShouldBe(new[] { "targets.txt" });
Expand All @@ -633,8 +632,7 @@ public void TargetsSwitchParameter()
public void TargetsSwitchDoesNotSupportMultipleOccurrences()
{
CommandLineSwitches switches = new CommandLineSwitches();
CommandLineParser parser = new CommandLineParser();
parser.GatherCommandLineSwitches(new List<string>() { "/targets /targets" }, switches);
MSBuildApp.GatherCommandLineSwitches(new List<string>() { "/targets /targets" }, switches);

switches.HaveErrors().ShouldBeTrue();
}
Expand Down Expand Up @@ -711,9 +709,8 @@ public void LowPrioritySwitchIdentificationTests(string lowpriority)
public void GraphBuildSwitchCanHaveParameters()
{
CommandLineSwitches switches = new CommandLineSwitches();
CommandLineParser parser = new CommandLineParser();

parser.GatherCommandLineSwitches(new List<string> { "/graph", "/graph:true; NoBuild ;; ;", "/graph:foo" }, switches);
MSBuildApp.GatherCommandLineSwitches(new List<string> { "/graph", "/graph:true; NoBuild ;; ;", "/graph:foo" }, switches);

switches[CommandLineSwitches.ParameterizedSwitch.GraphBuild].ShouldBe(new[] { "true", " NoBuild ", " ", "foo" });

Expand All @@ -724,9 +721,8 @@ public void GraphBuildSwitchCanHaveParameters()
public void GraphBuildSwitchCanBeParameterless()
{
CommandLineSwitches switches = new CommandLineSwitches();
CommandLineParser parser = new CommandLineParser();

parser.GatherCommandLineSwitches(new List<string> { "/graph" }, switches);
MSBuildApp.GatherCommandLineSwitches(new List<string> { "/graph" }, switches);

switches[CommandLineSwitches.ParameterizedSwitch.GraphBuild].ShouldBe(Array.Empty<string>());

Expand All @@ -737,9 +733,8 @@ public void GraphBuildSwitchCanBeParameterless()
public void InputResultsCachesSupportsMultipleOccurrence()
{
CommandLineSwitches switches = new CommandLineSwitches();
CommandLineParser parser = new CommandLineParser();

parser.GatherCommandLineSwitches(new List<string>() { "/irc", "/irc:a;b", "/irc:c;d" }, switches);
MSBuildApp.GatherCommandLineSwitches(new List<string>() { "/irc", "/irc:a;b", "/irc:c;d" }, switches);

switches[CommandLineSwitches.ParameterizedSwitch.InputResultsCaches].ShouldBe(new[] { null, "a", "b", "c", "d" });

Expand All @@ -750,9 +745,8 @@ public void InputResultsCachesSupportsMultipleOccurrence()
public void OutputResultsCache()
{
CommandLineSwitches switches = new CommandLineSwitches();
CommandLineParser parser = new CommandLineParser();

parser.GatherCommandLineSwitches(new List<string>() { "/orc:a" }, switches);
MSBuildApp.GatherCommandLineSwitches(new List<string>() { "/orc:a" }, switches);

switches[CommandLineSwitches.ParameterizedSwitch.OutputResultsCache].ShouldBe(new[] { "a" });

Expand All @@ -763,9 +757,8 @@ public void OutputResultsCache()
public void OutputResultsCachesDoesNotSupportMultipleOccurrences()
{
CommandLineSwitches switches = new CommandLineSwitches();
CommandLineParser parser = new CommandLineParser();

parser.GatherCommandLineSwitches(new List<string>() { "/orc:a", "/orc:b" }, switches);
MSBuildApp.GatherCommandLineSwitches(new List<string>() { "/orc:a", "/orc:b" }, switches);

switches.HaveErrors().ShouldBeTrue();
}
Expand Down Expand Up @@ -1295,9 +1288,8 @@ public void ExtractAnyLoggerParameterPickLast()
public void ProcessWarnAsErrorSwitchNotSpecified()
{
CommandLineSwitches commandLineSwitches = new CommandLineSwitches();
CommandLineParser parser = new CommandLineParser();

parser.GatherCommandLineSwitches(new List<string>(new[] { "" }), commandLineSwitches);
MSBuildApp.GatherCommandLineSwitches(new List<string>(new[] { "" }), commandLineSwitches);

Assert.Null(MSBuildApp.ProcessWarnAsErrorSwitch(commandLineSwitches));
}
Expand All @@ -1311,9 +1303,8 @@ public void ProcessWarnAsErrorSwitchWithCodes()
ISet<string> expectedWarningsAsErrors = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "a", "B", "c", "D", "e" };

CommandLineSwitches commandLineSwitches = new CommandLineSwitches();
CommandLineParser parser = new CommandLineParser();

parser.GatherCommandLineSwitches(new List<string>(new[]
MSBuildApp.GatherCommandLineSwitches(new List<string>(new[]
{
"\"/warnaserror: a,B ; c \"", // Leading, trailing, leading and trailing whitespace
"/warnaserror:A,b,C", // Repeats of different case
Expand All @@ -1337,9 +1328,8 @@ public void ProcessWarnAsErrorSwitchWithCodes()
public void ProcessWarnAsErrorSwitchEmptySwitchClearsSet()
{
CommandLineSwitches commandLineSwitches = new CommandLineSwitches();
CommandLineParser parser = new CommandLineParser();

parser.GatherCommandLineSwitches(new List<string>(new[]
MSBuildApp.GatherCommandLineSwitches(new List<string>(new[]
{
"/warnaserror:a;b;c",
"/warnaserror",
Expand All @@ -1361,9 +1351,8 @@ public void ProcessWarnAsErrorSwitchValuesAfterEmptyAddOn()
ISet<string> expectedWarningsAsErors = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "e", "f", "g" };

CommandLineSwitches commandLineSwitches = new CommandLineSwitches();
CommandLineParser parser = new CommandLineParser();

parser.GatherCommandLineSwitches(new List<string>(new[]
MSBuildApp.GatherCommandLineSwitches(new List<string>(new[]
{
"/warnaserror:a;b;c",
"/warnaserror",
Expand All @@ -1384,9 +1373,8 @@ public void ProcessWarnAsErrorSwitchValuesAfterEmptyAddOn()
public void ProcessWarnAsErrorSwitchEmpty()
{
CommandLineSwitches commandLineSwitches = new CommandLineSwitches();
CommandLineParser parser = new CommandLineParser();

parser.GatherCommandLineSwitches(new List<string>(new[] { "/warnaserror" }), commandLineSwitches);
MSBuildApp.GatherCommandLineSwitches(new List<string>(new[] { "/warnaserror" }), commandLineSwitches);

ISet<string> actualWarningsAsErrors = MSBuildApp.ProcessWarnAsErrorSwitch(commandLineSwitches);

Expand All @@ -1402,11 +1390,10 @@ public void ProcessWarnAsErrorSwitchEmpty()
public void ProcessWarnAsMessageSwitchEmpty()
{
CommandLineSwitches commandLineSwitches = new CommandLineSwitches();
CommandLineParser parser = new CommandLineParser();

// Set "expanded" content to match the placeholder so the verify can use the exact resource string as "expected."
string command = "{0}";
parser.GatherCommandLineSwitches(new List<string>(new[] { "/warnasmessage" }), commandLineSwitches, command);
MSBuildApp.GatherCommandLineSwitches(new List<string>(new[] { "/warnasmessage" }), commandLineSwitches, command);

VerifySwitchError(commandLineSwitches, "/warnasmessage", AssemblyResources.GetString("MissingWarnAsMessageParameterError"));
}
Expand All @@ -1423,15 +1410,13 @@ public void ProcessEnvironmentVariableSwitch()
env.SetEnvironmentVariable("ENVIRONMENTVARIABLE", string.Empty);

CommandLineSwitches commandLineSwitches = new();
CommandLineParser parser = new CommandLineParser();

string fullCommandLine = "msbuild validProject.csproj %ENVIRONMENTVARIABLE%";
parser.GatherCommandLineSwitches(new List<string>() { "validProject.csproj", "%ENVIRONMENTVARIABLE%" }, commandLineSwitches, fullCommandLine);
MSBuildApp.GatherCommandLineSwitches(new List<string>() { "validProject.csproj", "%ENVIRONMENTVARIABLE%" }, commandLineSwitches, fullCommandLine);
VerifySwitchError(commandLineSwitches, "%ENVIRONMENTVARIABLE%", String.Format(AssemblyResources.GetString("EnvironmentVariableAsSwitch"), fullCommandLine));

commandLineSwitches = new();
fullCommandLine = "msbuild %ENVIRONMENTVARIABLE% validProject.csproj";
parser.GatherCommandLineSwitches(new List<string>() { "%ENVIRONMENTVARIABLE%", "validProject.csproj" }, commandLineSwitches, fullCommandLine);
MSBuildApp.GatherCommandLineSwitches(new List<string>() { "%ENVIRONMENTVARIABLE%", "validProject.csproj" }, commandLineSwitches, fullCommandLine);
VerifySwitchError(commandLineSwitches, "%ENVIRONMENTVARIABLE%", String.Format(AssemblyResources.GetString("EnvironmentVariableAsSwitch"), fullCommandLine));
}
}
Expand All @@ -1445,9 +1430,8 @@ public void ProcessWarnAsMessageSwitchWithCodes()
ISet<string> expectedWarningsAsMessages = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "a", "B", "c", "D", "e" };

CommandLineSwitches commandLineSwitches = new CommandLineSwitches();
CommandLineParser parser = new CommandLineParser();

parser.GatherCommandLineSwitches(new List<string>(new[]
MSBuildApp.GatherCommandLineSwitches(new List<string>(new[]
{
"\"/warnasmessage: a,B ; c \"", // Leading, trailing, leading and trailing whitespace
"/warnasmessage:A,b,C", // Repeats of different case
Expand All @@ -1471,9 +1455,8 @@ public void ProcessWarnAsMessageSwitchWithCodes()
public void ProcessProfileEvaluationEmpty()
{
CommandLineSwitches commandLineSwitches = new CommandLineSwitches();
CommandLineParser parser = new CommandLineParser();

parser.GatherCommandLineSwitches(new List<string>(new[] { "/profileevaluation" }), commandLineSwitches);
MSBuildApp.GatherCommandLineSwitches(new List<string>(new[] { "/profileevaluation" }), commandLineSwitches);
commandLineSwitches[CommandLineSwitches.ParameterizedSwitch.ProfileEvaluation][0].ShouldBe("no-file");
}

Expand Down Expand Up @@ -1565,7 +1548,11 @@ public void ProcessInvalidTargetSwitch()
using TestEnvironment testEnvironment = TestEnvironment.Create();
string project = testEnvironment.CreateTestProjectWithFiles("project.proj", projectContent).ProjectFile;

#if FEATURE_GET_COMMANDLINE
MSBuildApp.Execute(@"msbuild.exe " + project + " /t:foo.bar").ShouldBe(MSBuildApp.ExitType.SwitchError);
#else
MSBuildApp.Execute(new[] { @"msbuild.exe", project, "/t:foo.bar" }).ShouldBe(MSBuildApp.ExitType.SwitchError);
#endif
}

/// <summary>
Expand Down
Loading
Loading