// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Generic;
using Microsoft.Build.Collections;
using Microsoft.Build.Experimental.BuildCheck;
using Microsoft.Build.Framework;
namespace Microsoft.Build.Execution
{
///
/// BuildRequestData encapsulates all the data needed to submit a build request.
///
public class BuildRequestData : BuildRequestData
{
///
/// Constructs a BuildRequestData for build requests based on project instances.
///
/// The instance to build.
/// The targets to build.
public BuildRequestData(ProjectInstance projectInstance, string[] targetsToBuild)
: this(projectInstance, targetsToBuild, null, BuildRequestDataFlags.None)
{
}
///
/// Constructs a BuildRequestData for build requests based on project instances.
///
/// The instance to build.
/// The targets to build.
/// The host services to use, if any. May be null.
public BuildRequestData(ProjectInstance projectInstance, string[] targetsToBuild, HostServices hostServices)
: this(projectInstance, targetsToBuild, hostServices, BuildRequestDataFlags.None)
{
}
///
/// Constructs a BuildRequestData for build requests based on project instances.
///
/// The instance to build.
/// The targets to build.
/// The host services to use, if any. May be null.
/// Flags controlling this build request.
public BuildRequestData(ProjectInstance projectInstance, string[] targetsToBuild, HostServices? hostServices, BuildRequestDataFlags flags)
: this(projectInstance, targetsToBuild, hostServices, flags, null)
{
}
///
/// Constructs a BuildRequestData for build requests based on project instances.
///
/// The instance to build.
/// The targets to build.
/// The host services to use, if any. May be null.
/// Flags controlling this build request.
/// The list of properties whose values should be transferred from the project to any out-of-proc node.
public BuildRequestData(ProjectInstance projectInstance, string[] targetsToBuild, HostServices? hostServices, BuildRequestDataFlags flags, IEnumerable? propertiesToTransfer)
: this(targetsToBuild, hostServices, flags, projectInstance.FullPath)
{
ArgumentNullException.ThrowIfNull(projectInstance);
if (projectInstance.EvaluationStage != Evaluation.ProjectEvaluationStage.Full)
{
Shared.ErrorUtilities.ThrowInvalidOperation("OM_PartialEvaluationCannotBuild", projectInstance.EvaluationStage);
}
foreach (string targetName in targetsToBuild)
{
ArgumentNullException.ThrowIfNull(targetName, "target");
}
ProjectInstance = projectInstance;
GlobalPropertiesDictionary = projectInstance.GlobalPropertiesDictionary;
ExplicitlySpecifiedToolsVersion = projectInstance.ExplicitToolsVersion;
if (propertiesToTransfer != null)
{
PropertiesToTransfer = new List(propertiesToTransfer);
}
}
///
/// Constructs a BuildRequestData for build requests based on project instances.
///
/// The instance to build.
/// The targets to build.
/// The host services to use, if any. May be null.
/// Flags controlling this build request.
/// The list of properties whose values should be transferred from the project to any out-of-proc node.
/// A describing properties, items, and metadata that should be returned. Requires setting .
public BuildRequestData(ProjectInstance projectInstance, string[] targetsToBuild, HostServices? hostServices, BuildRequestDataFlags flags, IEnumerable? propertiesToTransfer, RequestedProjectState requestedProjectState)
: this(projectInstance, targetsToBuild, hostServices, flags, propertiesToTransfer)
{
ArgumentNullException.ThrowIfNull(requestedProjectState);
RequestedProjectState = requestedProjectState;
}
///
/// Constructs a BuildRequestData for build requests based on project files.
///
/// The full path to the project file.
/// The global properties which should be used during evaluation of the project. Cannot be null.
/// The tools version to use for the build. May be null.
/// The targets to build.
/// The host services to use. May be null.
public BuildRequestData(string projectFullPath, IDictionary globalProperties, string? toolsVersion, string[] targetsToBuild, HostServices? hostServices)
: this(projectFullPath, globalProperties, toolsVersion, targetsToBuild, hostServices, BuildRequestDataFlags.None)
{
}
///
/// Constructs a BuildRequestData for build requests based on project files.
///
/// The full path to the project file.
/// The global properties which should be used during evaluation of the project. Cannot be null.
/// The tools version to use for the build. May be null.
/// The targets to build.
/// The host services to use. May be null.
/// The to use.
/// A describing properties, items, and metadata that should be returned. Requires setting .
public BuildRequestData(string projectFullPath, IDictionary globalProperties,
string? toolsVersion, string[] targetsToBuild, HostServices? hostServices, BuildRequestDataFlags flags,
RequestedProjectState requestedProjectState)
: this(projectFullPath, globalProperties, toolsVersion, targetsToBuild, hostServices, flags)
{
ArgumentNullException.ThrowIfNull(requestedProjectState);
RequestedProjectState = requestedProjectState;
}
///
/// Constructs a BuildRequestData for build requests based on project files.
///
/// The full path to the project file.
/// The global properties which should be used during evaluation of the project. Cannot be null.
/// The tools version to use for the build. May be null.
/// The targets to build.
/// The host services to use. May be null.
/// The to use.
public BuildRequestData(string projectFullPath, IDictionary globalProperties, string? toolsVersion, string[] targetsToBuild, HostServices? hostServices, BuildRequestDataFlags flags)
: this(targetsToBuild, hostServices, flags, FileUtilities.NormalizePath(projectFullPath)!)
{
ArgumentException.ThrowIfNullOrEmpty(projectFullPath);
ArgumentNullException.ThrowIfNull(globalProperties);
GlobalPropertiesDictionary = new PropertyDictionary(globalProperties.Count);
foreach (KeyValuePair propertyPair in globalProperties)
{
GlobalPropertiesDictionary.Set(ProjectPropertyInstance.Create(propertyPair.Key, propertyPair.Value));
}
ExplicitlySpecifiedToolsVersion = toolsVersion;
}
///
/// Common constructor.
///
private BuildRequestData(string[] targetsToBuild, HostServices? hostServices, BuildRequestDataFlags flags, string projectFullPath)
: base(targetsToBuild, flags, hostServices)
{
ProjectFullPath = projectFullPath;
}
///
/// The actual project, in the case where the project doesn't come from disk.
/// May be null.
///
/// The project instance.
public ProjectInstance? ProjectInstance
{
get;
}
/// The project file.
/// The project file to be built.
public string ProjectFullPath { get; internal set; }
internal override BuildSubmissionBase CreateSubmission(BuildManager buildManager,
int submissionId, BuildRequestData requestData,
bool legacyThreadingSemantics) =>
new BuildSubmission(buildManager, submissionId, requestData, legacyThreadingSemantics);
public override IEnumerable EntryProjectsFullPath => ProjectFullPath.AsSingleItemEnumerable();
///
/// The global properties to use.
///
/// The set of global properties to be used to build this request.
public ICollection GlobalProperties => (GlobalPropertiesDictionary == null) ?
(ICollection)ReadOnlyEmptyCollection.Instance :
new ReadOnlyCollection(GlobalPropertiesDictionary);
public override bool IsGraphRequest => false;
///
/// The explicitly requested tools version to use.
///
public string? ExplicitlySpecifiedToolsVersion { get; }
///
/// Returns a list of properties to transfer out of proc for the build.
///
public IEnumerable? PropertiesToTransfer { get; }
///
/// Returns the properties, items, and metadata that will be returned
/// by this build.
///
public RequestedProjectState? RequestedProjectState { get; }
///
/// Whether the tools version used originated from an explicit specification,
/// for example from an MSBuild task or /tv switch.
///
internal bool ExplicitToolsVersionSpecified => ExplicitlySpecifiedToolsVersion != null;
///
/// Returns the global properties as a dictionary.
///
internal PropertyDictionary? GlobalPropertiesDictionary { get; }
private IReadOnlyDictionary? _globalPropertiesLookup;
///
public override IReadOnlyDictionary GlobalPropertiesLookup => _globalPropertiesLookup ??=
Execution.GlobalPropertiesLookup.ToGlobalPropertiesLookup(GlobalPropertiesDictionary);
// WARNING!: Do not remove the below proxy properties.
// They are required to make the OM forward compatible
// (code built against this OM should run against binaries with previous version of OM).
///
public new ICollection TargetNames => base.TargetNames;
///
public new BuildRequestDataFlags Flags => base.Flags;
///
public new HostServices? HostServices => base.HostServices;
}
}