/// <summary>
        /// Creates a new task and adds it to the end of the list of tasks.
        /// </summary>
        /// <param name="taskName">The name of the task to create.</param>
        /// <param name="condition">The task's condition.</param>
        /// <param name="continueOnError">The continue on error flag.</param>
        /// <param name="msbuildRuntime">The MSBuild runtime.</param>
        /// <param name="msbuildArchitecture">The MSBuild architecture.</param>
        /// <returns>The new task instance.</returns>
        internal ProjectTaskInstance AddTask(string taskName, string condition, string continueOnError, string msbuildRuntime, string msbuildArchitecture)
        {
            ErrorUtilities.VerifyThrowInternalLength(taskName, "taskName");
            ProjectTaskInstance task = new ProjectTaskInstance(taskName, _location, condition ?? String.Empty, continueOnError ?? String.Empty, msbuildRuntime ?? String.Empty, msbuildArchitecture ?? String.Empty);

            this.AddProjectTargetInstanceChild(task);
            return(task);
        }
        /// <summary>
        /// Creates a new task and adds it to the end of the list of tasks.
        /// </summary>
        /// <param name="taskName">The name of the task to create.</param>
        /// <param name="condition">The task's condition.</param>
        /// <param name="continueOnError">The continue on error flag.</param>
        /// <returns>The new task instance.</returns>
        internal ProjectTaskInstance AddTask(string taskName, string condition, string continueOnError)
        {
            ProjectTaskInstance task = AddTask(taskName, condition, continueOnError, String.Empty, String.Empty);

            return(task);
        }
Esempio n. 3
0
		bool RunBuildTask (ProjectTargetInstance target, ProjectTaskInstance taskInstance, TargetResult targetResult, InternalBuildArguments args)
		{
			var request = submission.BuildRequest;

			var host = request.HostServices == null ? null : request.HostServices.GetHostObject (request.ProjectFullPath, target.Name, taskInstance.Name);
			
			// Create Task instance.
			var factoryIdentityParameters = new Dictionary<string,string> ();
			#if NET_4_5
			factoryIdentityParameters ["MSBuildRuntime"] = taskInstance.MSBuildRuntime;
			factoryIdentityParameters ["MSBuildArchitecture"] = taskInstance.MSBuildArchitecture;
			#endif
			var task = args.BuildTaskFactory.CreateTask (taskInstance.Name, factoryIdentityParameters, this);
			if (task == null)
				throw new InvalidOperationException (string.Format ("TaskFactory {0} returned null Task", args.BuildTaskFactory));
			LogMessageEvent (new BuildMessageEventArgs (string.Format ("Using task {0} from {1}", taskInstance.Name, task.GetType ()), null, null, MessageImportance.Low));
			task.HostObject = host;
			task.BuildEngine = this;
			
			// Prepare task parameters.
			var evaluator = new ExpressionEvaluator (project);
			var evaluatedTaskParams = taskInstance.Parameters.Select (p => new KeyValuePair<string,string> (p.Key, project.ExpandString (evaluator, p.Value)));

			var requiredProps = task.GetType ().GetProperties ()
				.Where (p => p.CanWrite && p.GetCustomAttributes (typeof (RequiredAttribute), true).Any ());
			var missings = requiredProps.Where (p => !evaluatedTaskParams.Any (tp => tp.Key.Equals (p.Name, StringComparison.OrdinalIgnoreCase)));
			if (missings.Any ())
				throw new InvalidOperationException (string.Format ("Task {0} of type {1} is used without specifying mandatory property: {2}",
					taskInstance.Name, task.GetType (), string.Join (", ", missings.Select (p => p.Name).ToArray ())));
			
			foreach (var p in evaluatedTaskParams) {
				switch (p.Key.ToLower ()) {
				case "condition":
				case "continueonerror":
					continue;
				}
				var prop = task.GetType ().GetProperty (p.Key);
				if (prop == null)
					throw new InvalidOperationException (string.Format ("Task {0} does not have property {1}", taskInstance.Name, p.Key));
				if (!prop.CanWrite)
					throw new InvalidOperationException (string.Format ("Task {0} has property {1} but it is read-only.", taskInstance.Name, p.Key));
				if (string.IsNullOrEmpty (p.Value) && !requiredProps.Contains (prop))
					continue;
				try {
					prop.SetValue (task, ConvertTo (p.Value, prop.PropertyType, evaluator), null);
				} catch (Exception ex) {
					throw new InvalidOperationException (string.Format ("Failed to convert '{0}' for property '{1}' of type {2}", p.Value, prop.Name, prop.PropertyType), ex);
				}
			}
			
			// Do execute task.
			bool taskSuccess = false;
			event_source.FireTaskStarted (this, new TaskStartedEventArgs ("Task Started", null, project.FullPath, taskInstance.FullPath, taskInstance.Name));
			try {
				taskSuccess = task.Execute ();
			
				if (!taskSuccess) {
					targetResult.Failure (null);
					if (!ContinueOnError) {
						return false;
					}
				} else {
					// Evaluate task output properties and items.
					foreach (var to in taskInstance.Outputs) {
						if (!project.EvaluateCondition (to.Condition))
							continue;
						var toItem = to as ProjectTaskOutputItemInstance;
						var toProp = to as ProjectTaskOutputPropertyInstance;
						string taskParameter = toItem != null ? toItem.TaskParameter : toProp.TaskParameter;
						var pi = task.GetType ().GetProperty (taskParameter);
						if (pi == null)
							throw new InvalidOperationException (string.Format ("Task {0} does not have property {1} specified as TaskParameter", taskInstance.Name, toItem.TaskParameter));
						if (!pi.CanRead)
							throw new InvalidOperationException (string.Format ("Task {0} has property {1} specified as TaskParameter, but it is write-only", taskInstance.Name, toItem.TaskParameter));
						var value = pi.GetValue (task, null);
						var valueString = ConvertFrom (value);
						if (toItem != null) {
							LogMessageEvent (new BuildMessageEventArgs (string.Format ("Output Item {0} from TaskParameter {1}: {2}", toItem.ItemType, toItem.TaskParameter, valueString), null, null, MessageImportance.Low));
							Action<ITaskItem> addItem = i => {
								var metadata = new ArrayList (i.MetadataNames).ToArray ().Cast<string> ().Select (n => new KeyValuePair<string,string> (n, i.GetMetadata (n)));
								args.Project.AddItem (toItem.ItemType, i.ItemSpec, metadata);
							};
							var taskItemArray = value as ITaskItem [];
							if (taskItemArray != null) {
								foreach (var ti in taskItemArray)
									addItem (ti);
							} else {
								var taskItem = value as ITaskItem;
								if (taskItem != null) 
									addItem (taskItem);
								else
									foreach (var item in valueString.Split (';'))
										args.Project.AddItem (toItem.ItemType, item);
							}
						} else {
							LogMessageEvent (new BuildMessageEventArgs (string.Format ("Output Property {0} from TaskParameter {1}: {2}", toProp.PropertyName, toProp.TaskParameter, valueString), null, null, MessageImportance.Low));
							args.Project.SetProperty (toProp.PropertyName, valueString);
						}
					}
				}
			} finally {
				event_source.FireTaskFinished (this, new TaskFinishedEventArgs ("Task Finished", null, project.FullPath, taskInstance.FullPath, taskInstance.Name, taskSuccess));
			}
			return true;
		}
Esempio n. 4
0
		// FIXME: Exception should be caught at caller site.
		bool DoBuildTarget (ProjectTargetInstance target, TargetResult targetResult, InternalBuildArguments args)
		{
			var request = submission.BuildRequest;
	
			// Here we check cancellation (only after TargetStarted event).
			if (args.CheckCancel ()) {
				targetResult.Failure (new BuildAbortedException ("Build has canceled"));
				return false;
			}
			
			try {
				foreach (var child in target.Children) {
					// Evaluate additional target properties
					var tp = child as ProjectPropertyGroupTaskInstance;
					if (tp != null) {
						if (!args.Project.EvaluateCondition (tp.Condition))
							continue;
						foreach (var p in tp.Properties) {
							if (!args.Project.EvaluateCondition (p.Condition))
								continue;
							var value = args.Project.ExpandString (p.Value);
							project.SetProperty (p.Name, value);
						}
						continue;
					}

					var ii = child as ProjectItemGroupTaskInstance;
					if (ii != null) {
						if (!args.Project.EvaluateCondition (ii.Condition))
							continue;
						foreach (var item in ii.Items) {
							if (!args.Project.EvaluateCondition (item.Condition))
								continue;
							project.AddItem (item.ItemType, project.ExpandString (item.Include));
						}
						continue;
					}
					
					var task = child as ProjectTaskInstance;
					if (task != null) {
						current_task = task;
						if (!args.Project.EvaluateCondition (task.Condition)) {
							LogMessageEvent (new BuildMessageEventArgs (string.Format ("Task '{0}' was skipped because condition '{1}' wasn't met.", task.Name, task.Condition), null, null, MessageImportance.Low));
							continue;
						}
						if (!RunBuildTask (target, task, targetResult, args))
							return false;
						continue;
					}

					var onError = child as ProjectOnErrorInstance;
					if (onError != null)
						continue; // evaluated under catch clause.

					throw new NotSupportedException (string.Format ("Unexpected Target element children \"{0}\"", child.GetType ()));
				}
			} catch (Exception ex) {
				// fallback task specified by OnError element
				foreach (var c in target.Children.OfType<ProjectOnErrorInstance> ()) {
					if (!args.Project.EvaluateCondition (c.Condition))
						continue;
					foreach (var fallbackTarget in project.ExpandString (c.ExecuteTargets).Split (';'))
						BuildTargetByName (fallbackTarget, args);
				}
				int line = target.Location != null ? target.Location.Line : 0;
				int col = target.Location != null ? target.Location.Column : 0;
				LogErrorEvent (new BuildErrorEventArgs (null, null, target.FullPath, line, col, 0, 0, ex.Message, null, null));
				targetResult.Failure (ex);
				return false;
			}
			return true;
		}
Esempio n. 5
0
        /// <summary>
        /// Builds the task specified by the XML.
        /// </summary>
        /// <param name="loggingContext">The logging context of the target</param>
        /// <param name="requestEntry">The build request entry being built</param>
        /// <param name="targetBuilderCallback">The target builder callback.</param>
        /// <param name="taskInstance">The task instance.</param>
        /// <param name="mode">The mode in which to execute tasks.</param>
        /// <param name="inferLookup">The lookup to be used for inference.</param>
        /// <param name="executeLookup">The lookup to be used during execution.</param>
        /// <returns>The result of running the task batch.</returns>
        /// <remarks>
        /// The ExecuteTask method takes a task as specified by XML and executes it.  This procedure is comprised 
        /// of the following steps:
        /// 1. Loading the Task from its containing assembly by looking it up in the task registry
        /// 2. Determining if the task is batched.  If it is, create the batches and execute each as if it were a non-batched task
        /// 3. If the task is not batched, execute it.
        /// 4. If the task was batched, hold on to its Lookup until all of the natches are done, then merge them.
        /// </remarks>
        public async Task<WorkUnitResult> ExecuteTask(TargetLoggingContext loggingContext, BuildRequestEntry requestEntry, ITargetBuilderCallback targetBuilderCallback, ProjectTargetInstanceChild taskInstance, TaskExecutionMode mode, Lookup inferLookup, Lookup executeLookup, CancellationToken cancellationToken)
        {
            ErrorUtilities.VerifyThrow(taskInstance != null, "Need to specify the task instance.");

            _buildRequestEntry = requestEntry;
            _targetBuilderCallback = targetBuilderCallback;
            _cancellationToken = cancellationToken;
            _targetChildInstance = taskInstance;

            // In the case of Intrinsic tasks, taskNode will end up null.  Currently this is how we distinguish
            // intrinsic from extrinsic tasks.
            _taskNode = taskInstance as ProjectTaskInstance;

            if (_taskNode != null && requestEntry.Request.HostServices != null)
            {
                _taskHostObject = requestEntry.Request.HostServices.GetHostObject(requestEntry.RequestConfiguration.Project.FullPath, loggingContext.Target.Name, _taskNode.Name);
            }

            _projectFullPath = requestEntry.RequestConfiguration.Project.FullPath;

            // this.handleId = handleId; No handles
            // this.parentModule = parentModule; No task execution module
            _continueOnError = ContinueOnError.ErrorAndStop;

            _targetLoggingContext = loggingContext;

            WorkUnitResult taskResult = new WorkUnitResult(WorkUnitResultCode.Failed, WorkUnitActionCode.Stop, null);
            if ((mode & TaskExecutionMode.InferOutputsOnly) == TaskExecutionMode.InferOutputsOnly)
            {
                taskResult = await ExecuteTask(TaskExecutionMode.InferOutputsOnly, inferLookup);
            }

            if ((mode & TaskExecutionMode.ExecuteTaskAndGatherOutputs) == TaskExecutionMode.ExecuteTaskAndGatherOutputs)
            {
                taskResult = await ExecuteTask(TaskExecutionMode.ExecuteTaskAndGatherOutputs, executeLookup);
            }

            return taskResult;
        }
Esempio n. 6
0
		bool DoBuildTarget (ProjectTargetInstance target, TargetResult targetResult, InternalBuildArguments args)
		{
			var request = submission.BuildRequest;
	
			// Here we check cancellation (only after TargetStarted event).
			if (args.CheckCancel ()) {
				targetResult.Failure (new BuildAbortedException ("Build has canceled"));
				return false;
			}
			
			var propsToRestore = new Dictionary<string,string> ();
			var itemsToRemove = new List<ProjectItemInstance> ();
			try {
				// Evaluate additional target properties
				foreach (var c in target.Children.OfType<ProjectPropertyGroupTaskInstance> ()) {
					if (!args.Project.EvaluateCondition (c.Condition))
						continue;
					foreach (var p in c.Properties) {
						if (!args.Project.EvaluateCondition (p.Condition))
							continue;
						var value = args.Project.ExpandString (p.Value);
						propsToRestore.Add (p.Name, project.GetPropertyValue (value));
						project.SetProperty (p.Name, value);
					}
				}
				
				// Evaluate additional target items
				foreach (var c in target.Children.OfType<ProjectItemGroupTaskInstance> ()) {
					if (!args.Project.EvaluateCondition (c.Condition))
						continue;
					foreach (var item in c.Items) {
						if (!args.Project.EvaluateCondition (item.Condition))
							continue;
						Func<string,ProjectItemInstance> creator = i => new ProjectItemInstance (project, item.ItemType, item.Metadata.Select (m => new KeyValuePair<string,string> (m.Name, m.Value)), i);
						foreach (var ti in project.GetAllItems (item.Include, item.Exclude, creator, creator, s => s == item.ItemType, (ti, s) => ti.SetMetadata ("RecurseDir", s)))
							itemsToRemove.Add (ti);
					}
				}
				
				foreach (var c in target.Children.OfType<ProjectOnErrorInstance> ()) {
					if (!args.Project.EvaluateCondition (c.Condition))
						continue;
					throw new NotImplementedException ();
				}
				
				// run tasks
				foreach (var ti in target.Children.OfType<ProjectTaskInstance> ()) {
					current_task = ti;
					if (!args.Project.EvaluateCondition (ti.Condition)) {
						LogMessageEvent (new BuildMessageEventArgs (string.Format ("Task '{0}' was skipped because condition '{1}' wasn't met.", ti.Name, ti.Condition), null, null, MessageImportance.Low));
						continue;
					}
					if (!RunBuildTask (target, ti, targetResult, args))
						return false;
				}
			} finally {
				// restore temporary property state to the original state.
				foreach (var p in propsToRestore) {
					if (p.Value == string.Empty)
						project.RemoveProperty (p.Key);
					else
						project.SetProperty (p.Key, p.Value);
				}
				foreach (var item in itemsToRemove)
					project.RemoveItem (item);
			}
			return true;
		}
Esempio n. 7
0
 /// <summary>
 /// Creates a new task and adds it to the end of the list of tasks.
 /// </summary>
 /// <param name="taskName">The name of the task to create.</param>
 /// <param name="condition">The task's condition.</param>
 /// <param name="continueOnError">The continue on error flag.</param>
 /// <returns>The new task instance.</returns>
 internal ProjectTaskInstance AddTask(string taskName, string condition, string continueOnError, string msbuildRuntime, string msbuildArchitecture)
 {
     ErrorUtilities.VerifyThrowInternalLength(taskName, "taskName");
     ProjectTaskInstance task = new ProjectTaskInstance(taskName, _location, condition ?? String.Empty, continueOnError ?? String.Empty, msbuildRuntime ?? String.Empty, msbuildArchitecture ?? String.Empty);
     this.AddProjectTargetInstanceChild(task);
     return task;
 }