// 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; } }