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
29 changes: 29 additions & 0 deletions src/Build.UnitTests/BackEnd/BuildRequestConfiguration_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,35 @@ public void TestTranslation()
BuildRequestConfiguration deserializedConfig = packet as BuildRequestConfiguration;

Assert.Equal(config, deserializedConfig);
Comment thread
ViktorHofer marked this conversation as resolved.
Resolved

// RequestedTargets is excluded from InternalEquals, so assert the empty-list round-trip explicitly.
deserializedConfig.RequestedTargets.ShouldBeEmpty();
}

/// <summary>
/// Regression test for the solution metaproject bug where building a solution with a
/// non-standard target (e.g. "Pack") in a multi-node/parallel build fails with MSB4057.
/// The requested targets must round-trip through translation; otherwise a configuration
/// that crosses a node boundary loses them and the generated solution metaproject omits
/// the user-requested targets.
/// </summary>
[Fact]
public void TestTranslationPreservesRequestedTargets()
{
PropertyDictionary<ProjectPropertyInstance> properties = new PropertyDictionary<ProjectPropertyInstance>();
properties.Set(ProjectPropertyInstance.Create("this", "that"));

BuildRequestData data = new BuildRequestData("file", properties.ToDictionary(), "4.0", ["Build", "Pack"], null);
BuildRequestConfiguration config = new BuildRequestConfiguration(data, "2.0");

config.RequestedTargets.ShouldBe(["Build", "Pack"]);

((ITranslatable)config).Translate(TranslationHelpers.GetWriteTranslator());
INodePacket packet = BuildRequestConfiguration.FactoryForDeserialization(TranslationHelpers.GetReadTranslator());

BuildRequestConfiguration deserializedConfig = packet as BuildRequestConfiguration;

deserializedConfig.RequestedTargets.ShouldBe(["Build", "Pack"]);
}

[Fact]
Expand Down
15 changes: 12 additions & 3 deletions src/Build/BackEnd/Shared/BuildRequestConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,18 @@ internal class BuildRequestConfiguration : IEquatable<BuildRequestConfiguration>

#endregion

/// <summary>
/// The target names that were requested to execute. Backed by a field so that it can be
/// serialized across nodes; without this, a configuration that crosses a node boundary
/// would lose its requested targets, which is needed (for example) to generate the correct
/// set of targets in a solution metaproject.
/// </summary>
private List<string> _requestedTargets = [];
Comment thread
ViktorHofer marked this conversation as resolved.
Resolved

/// <summary>
/// The target names that were requested to execute.
/// </summary>
internal IReadOnlyCollection<string> RequestedTargets { get; }
internal IReadOnlyCollection<string> RequestedTargets => _requestedTargets;

/// <summary>
/// Initializes a configuration from a BuildRequestData structure. Used by the BuildManager.
Expand Down Expand Up @@ -182,7 +190,7 @@ internal BuildRequestConfiguration(int configId, BuildRequestData data, string d
_explicitToolsVersionSpecified = data.ExplicitToolsVersionSpecified;
_toolsVersion = ResolveToolsVersion(data, defaultToolsVersion);
_globalProperties = data.GlobalPropertiesDictionary;
RequestedTargets = new List<string>(data.TargetNames);
_requestedTargets = new List<string>(data.TargetNames);

// The following information only exists when the request is populated with an existing project.
if (data.ProjectInstance != null)
Expand Down Expand Up @@ -253,7 +261,7 @@ private BuildRequestConfiguration(int configId, BuildRequestConfiguration other)
_globalProperties = other._globalProperties;
IsCacheable = other.IsCacheable;
_configId = configId;
RequestedTargets = other.RequestedTargets;
_requestedTargets = other._requestedTargets;
_projectEvaluationId = other._projectEvaluationId;
}

Expand Down Expand Up @@ -956,6 +964,7 @@ public void Translate(ITranslator translator)
translator.Translate(ref _savedCurrentDirectory);
translator.TranslateDictionary(ref _savedEnvironmentVariables, CommunicationsUtilities.EnvironmentVariableComparer);
translator.Translate(ref _projectEvaluationId);
translator.Translate(ref _requestedTargets);

// if the entire state is translated, then the transferred state represents the full evaluation data
if (translator.Mode == TranslationDirection.ReadFromStream && _transferredState?.TranslateEntireState == true)
Expand Down
Loading