Exemple #1
0
        public void ExecuteTaskCurrentDirNotEqualExecutionDir()
        {
            string theCurrentDirectory = Directory.GetCurrentDirectory();

            try
            {
                string                   executionDirectory = "C:\\";
                TaskExecutionMode        howToExecuteTask   = TaskExecutionMode.InferOutputsOnly;
                XmlDocument              doc            = new XmlDocument();
                XmlElement               taskNode       = doc.CreateElement("Foo");
                TaskExecutionStateHelper executionState = new TaskExecutionStateHelper(
                    howToExecuteTask,
                    LookupHelpers.CreateLookup(projectLevelProprtiesForInference, projectLevelItemsForInference),
                    LookupHelpers.CreateLookup(projectLevelPropertiesForExecution, projectLevelItemsForExecution),
                    taskNode,
                    hostObject,
                    projectFileOfTaskNode,
                    parentProjectFullFileName,
                    executionDirectory,
                    nodeProxyId);
                executionState.ParentModule              = taskExecutionModule;
                executionState.LoggingService            = loggingHelper;
                executionState.TargetInferenceSuccessful = true;
                executionState.ExecuteTask();
                Assert.IsTrue(string.Compare(Directory.GetCurrentDirectory(), "C:\\", StringComparison.OrdinalIgnoreCase) == 0, "Expected current directory to be c:\\ which should show up as an empty directory string");
            }
            finally
            {
                Directory.SetCurrentDirectory(theCurrentDirectory);
            }
        }
Exemple #2
0
        /// <summary>
        /// The constructor obtains the state information and the
        /// callback delegate.
        /// </summary>
        internal TaskExecutionState
        (
            TaskExecutionMode howToExecuteTask,
            Lookup lookupForInference,
            Lookup lookupForExecution,
            XmlElement taskXmlNode,
            ITaskHost hostObject,
            string projectFileOfTaskNode,
            string parentProjectFullFileName,
            string executionDirectory,
            int handleId,
            BuildEventContext buildEventContext
        )
        {
            ErrorUtilities.VerifyThrow(taskXmlNode != null, "Must have task node");

            this.howToExecuteTask = howToExecuteTask;
            this.lookupForInference = lookupForInference;
            this.lookupForExecution = lookupForExecution;
            this.hostObject = hostObject;
            this.projectFileOfTaskNode = projectFileOfTaskNode;
            this.parentProjectFullFileName = parentProjectFullFileName;
            this.executionDirectory = executionDirectory;
            this.handleId = handleId;
            this.buildEventContext = buildEventContext;
            this.taskXmlNode = taskXmlNode;
        }
        public void Execute(TaskExecutionMode mode)
        {
            if (this.CancellationToken.IsCancellationRequested)
            {
                throw new OperationCanceledException(this.CancellationToken);
            }

            try
            {
                SchemaCompareScriptGenerationResult result = this.ComparisonResult.GenerateScript(this.Parameters.TargetDatabaseName);
                File.WriteAllText(this.Parameters.ScriptFilePath, result.Script);

                if (!string.IsNullOrEmpty(result.MasterScript))
                {
                    // master script is only used if the target is Azure SQL db and the script contains all operations that must be done against the master database
                    string masterScriptPath = Path.Combine(Path.GetDirectoryName(this.Parameters.ScriptFilePath), string.Concat("master_", Path.GetFileName(this.Parameters.ScriptFilePath)));
                    File.WriteAllText(masterScriptPath, result.MasterScript);
                }
            }
            catch (Exception e)
            {
                ErrorMessage = e.Message;
                Logger.Write(TraceEventType.Error, string.Format("Schema compare generate script operation {0} failed with exception {1}", this.OperationId, e.Message));
                throw;
            }
        }
Exemple #4
0
        public void Execute(TaskExecutionMode mode)
        {
            if (this.CancellationToken.IsCancellationRequested)
            {
                throw new OperationCanceledException(this.CancellationToken);
            }

            try
            {
                this.ScriptGenerationResult = this.ComparisonResult.GenerateScript(this.Parameters.TargetDatabaseName, this.CancellationToken);

                // tests don't create a SqlTask, so only add the script when the SqlTask isn't null
                if (this.SqlTask != null)
                {
                    this.SqlTask.AddScript(SqlTaskStatus.Succeeded, this.ScriptGenerationResult.Script);
                    if (!string.IsNullOrEmpty(this.ScriptGenerationResult.MasterScript))
                    {
                        // master script is only used if the target is Azure SQL db and the script contains all operations that must be done against the master database
                        this.SqlTask.AddScript(SqlTaskStatus.Succeeded, ScriptGenerationResult.MasterScript);
                    }
                }
                if (!this.ScriptGenerationResult.Success)
                {
                    ErrorMessage = this.ScriptGenerationResult.Message;
                    throw new Exception(ErrorMessage);
                }
            }
            catch (Exception e)
            {
                ErrorMessage = e.Message;
                Logger.Write(TraceEventType.Error, string.Format("Schema compare generate script operation {0} failed with exception {1}", this.OperationId, e.Message));
                throw;
            }
        }
        /// <summary>
        /// Execute the operation for given execution mode
        /// </summary>
        /// <param name="mode"></param>
        public virtual void Execute(TaskExecutionMode mode)
        {
            var currentExecutionMode = Server.ConnectionContext.SqlExecutionModes;

            try
            {
                if (Server != null)
                {
                    Server.ConnectionContext.CapturedSql.Clear();
                    SetExecutionMode(mode);
                }

                Execute();
                GenerateScript(mode);
            }
            catch
            {
                throw;
            }
            finally
            {
                Server.ConnectionContext.CapturedSql.Clear();
                Server.ConnectionContext.SqlExecutionModes = currentExecutionMode;
            }
        }
Exemple #6
0
        /// <summary>
        /// Execute the operation for given execution mode
        /// </summary>
        /// <param name="mode"></param>
        public override void Execute(TaskExecutionMode mode)
        {
            bool hasAccessToDb = false;

            try
            {
                hasAccessToDb = GainAccessToDatabase();
                base.Execute(mode);
            }
            catch (DatabaseFullAccessException databaseFullAccessException)
            {
                Logger.Write(TraceEventType.Warning, $"Failed to gain access to database. server|database:{ServerName}|{DatabaseName}");
                throw databaseFullAccessException;
            }
            catch
            {
                throw;
            }
            finally
            {
                if (hasAccessToDb)
                {
                    ReleaseAccessToDatabase();
                }
            }
        }
Exemple #7
0
		bool Run (IBuildTask buildTask, TaskExecutionMode taskExecutionMode, out bool executeOnErrors)
		{
			executeOnErrors = false;

			// Run the task in batches
			bool retval = true;
			if (buckets.Count == 0) {
				// batched mode, but no values in the corresponding items!
				retval = Execute (buildTask, taskExecutionMode);
				if (!retval && !buildTask.ContinueOnError)
					executeOnErrors = true;

				return retval;
			}

			// batched
			foreach (Dictionary<string, BuildItemGroup> bucket in buckets) {
				project.PushBatch (bucket, commonItemsByName);
				try {
					retval = Execute (buildTask, taskExecutionMode);
					 if (!retval && !buildTask.ContinueOnError) {
						executeOnErrors = true;
						break;
					}
				} finally {
					project.PopBatch ();
				}
			}

			return retval;
		}
Exemple #8
0
        private void AddTaskToTaskGroup(TaskGroup taskGroup, ITask task, TaskExecutionMode taskExecutionMode)
        {
            CheckThatTaskWasNotExecutedAlready(task);
            if (taskGroup == null)
            {
                taskGroup = new TaskGroup()
                {
                    GroupId = Guid.NewGuid().ToString(),
                };

                taskGroup.Tasks.Add((task, taskExecutionMode));
                TasksGroups.Add(taskGroup);
            }
            else
            {
                var existingGroup = TasksGroups.FirstOrDefault(x => x.GroupId == taskGroup.GroupId);
                if (existingGroup == null)
                {
                    taskGroup.Tasks.Add((task, taskExecutionMode));
                    TasksGroups.Add(taskGroup);
                }
                else
                {
                    taskGroup.Tasks.Add((task, taskExecutionMode));
                }
            }
        }
        public void Execute(TaskExecutionMode mode)
        {
            if (this.CancellationToken.IsCancellationRequested)
            {
                throw new OperationCanceledException(this.CancellationToken);
            }

            try
            {
                SchemaComparison compare = new SchemaComparison(this.Parameters.FilePath);

                // load xml file because some parsing still needs to be done
                this.scmpInfo = XDocument.Load(this.Parameters.FilePath);

                this.Result = new SchemaCompareOpenScmpResult()
                {
                    DeploymentOptions              = new DeploymentOptions(compare.Options),
                    Success                        = true,
                    SourceEndpointInfo             = this.GetEndpointInfo(true, compare.Source),
                    TargetEndpointInfo             = this.GetEndpointInfo(false, compare.Target),
                    OriginalTargetName             = this.GetOriginalTargetName(),
                    OriginalTargetConnectionString = this.GetOriginalTargetConnectionString(),
                    ExcludedSourceElements         = this.GetExcludedElements(compare.ExcludedSourceObjects),
                    ExcludedTargetElements         = this.GetExcludedElements(compare.ExcludedTargetObjects)
                };
            }
            catch (Exception e)
            {
                ErrorMessage = e.Message;
                Logger.Write(TraceEventType.Error, string.Format("Schema compare open scmp operation failed with exception {0}", e));
                throw;
            }
        }
Exemple #10
0
        /// <summary>
        /// The constructor obtains the state information and the
        /// callback delegate.
        /// </summary>
        internal TaskExecutionState
        (
            TaskExecutionMode howToExecuteTask,
            Lookup lookupForInference,
            Lookup lookupForExecution,
            XmlElement taskXmlNode,
            ITaskHost hostObject,
            string projectFileOfTaskNode,
            string parentProjectFullFileName,
            string executionDirectory,
            int handleId,
            BuildEventContext buildEventContext
        )
        {
            ErrorUtilities.VerifyThrow(taskXmlNode != null, "Must have task node");

            this.howToExecuteTask          = howToExecuteTask;
            this.lookupForInference        = lookupForInference;
            this.lookupForExecution        = lookupForExecution;
            this.hostObject                = hostObject;
            this.projectFileOfTaskNode     = projectFileOfTaskNode;
            this.parentProjectFullFileName = parentProjectFullFileName;
            this.executionDirectory        = executionDirectory;
            this.handleId          = handleId;
            this.buildEventContext = buildEventContext;
            this.taskXmlNode       = taskXmlNode;
        }
Exemple #11
0
 internal TaskExecutionStateHelper
 (
     TaskExecutionMode howToExecuteTask,
     Lookup lookupForInference,
     Lookup lookupForExecution,
     XmlElement taskXmlNode,
     ITaskHost hostObject,
     string projectFileOfTaskNode,
     string parentProjectFullFileName,
     string executionDirectory,
     int nodeProxyId
 )
     : base(howToExecuteTask,
            lookupForInference,
            lookupForExecution,
            taskXmlNode,
            hostObject,
            projectFileOfTaskNode,
            parentProjectFullFileName,
            executionDirectory,
            nodeProxyId,
            null
            )
 {
     // Dont need to do anything
 }
        public async Task VerifyTaskWithExecutionMode(TaskExecutionMode executionMode, bool makeTaskFail = false)
        {
            serviceHostMock.AddEventHandling(TaskStatusChangedNotification.Type, null);

            using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile())
            {
                //To make the task fail don't create the schema so create table fails
                string query = string.Empty;
                if (!makeTaskFail)
                {
                    query = $"CREATE SCHEMA [test]";
                }
                SqlTestDb testDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, query, "TaskService");

                try
                {
                    TestConnectionResult connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync(testDb.DatabaseName, queryTempFile.FilePath);

                    string          taskName    = "task name";
                    Server          server      = CreateServerObject(connectionResult.ConnectionInfo);
                    RequstParamStub requstParam = new RequstParamStub
                    {
                        TaskExecutionMode = executionMode,
                        OwnerUri          = queryTempFile.FilePath
                    };
                    SmoScriptableTaskOperationStub taskOperation = new SmoScriptableTaskOperationStub(server);
                    taskOperation.DatabaseName = testDb.DatabaseName;
                    taskOperation.TableName    = "newTable";
                    TaskMetadata taskMetadata = TaskMetadata.Create(requstParam, taskName, taskOperation, ConnectionService.Instance);
                    SqlTask      sqlTask      = service.TaskManager.CreateTask <SqlTask>(taskMetadata);
                    Task         taskToVerify = sqlTask.RunAsync().ContinueWith(task =>
                    {
                        if (!makeTaskFail)
                        {
                            if (executionMode == TaskExecutionMode.Script || executionMode == TaskExecutionMode.ExecuteAndScript)
                            {
                                serviceHostMock.Verify(x => x.SendEvent(TaskStatusChangedNotification.Type,
                                                                        It.Is <TaskProgressInfo>(t => !string.IsNullOrEmpty(t.Script))), Times.AtLeastOnce());
                            }

                            //Verify if the table created if execution mode includes execute
                            bool expected         = executionMode == TaskExecutionMode.Execute || executionMode == TaskExecutionMode.ExecuteAndScript;
                            Server serverToverfiy = CreateServerObject(connectionResult.ConnectionInfo);
                            bool actual           = serverToverfiy.Databases[testDb.DatabaseName].Tables.Contains(taskOperation.TableName, "test");
                            Assert.Equal(expected, actual);
                        }
                        else
                        {
                            serviceHostMock.Verify(x => x.SendEvent(TaskStatusChangedNotification.Type,
                                                                    It.Is <TaskProgressInfo>(t => t.Status == SqlTaskStatus.Failed)), Times.AtLeastOnce());
                        }
                    });
                    await taskToVerify;
                }
                finally
                {
                    testDb.Cleanup();
                }
            }
        }
Exemple #13
0
 public void AddExecutionMode(TaskExecutionMode mode) // Actorect to change when this class will get more formal
 {
     executionMode.Add(mode);
     if (ContainsExecutionMode(TaskExecutionMode.InstantOverrideAll) && mode == TaskExecutionMode.Chain)
     {
         executionMode.Remove(TaskExecutionMode.InstantOverrideAll);
     }
 }
 public void Add(string dependentTargetName, TaskExecutionMode taskExecMode, bool skipped = false)
 {
     Add(new TargetDependency
     {
         TargetName        = dependentTargetName,
         TaskExecutionMode = taskExecMode,
         Skipped           = skipped
     });
 }
        /// <summary>
        /// Execute the operation for given execution mode
        /// </summary>
        /// <param name="mode"></param>
        public virtual void Execute(TaskExecutionMode mode)
        {
            var currentExecutionMode = Server.ConnectionContext.SqlExecutionModes;

            try
            {
                if (Server != null)
                {
                    Server.ConnectionContext.CapturedSql.Clear();
                    switch (mode)
                    {
                    case TaskExecutionMode.Execute:
                    {
                        Server.ConnectionContext.SqlExecutionModes = SqlExecutionModes.ExecuteSql;
                        break;
                    }

                    case TaskExecutionMode.ExecuteAndScript:
                    {
                        Server.ConnectionContext.SqlExecutionModes = SqlExecutionModes.ExecuteAndCaptureSql;
                        break;
                    }

                    case TaskExecutionMode.Script:
                    {
                        Server.ConnectionContext.SqlExecutionModes = SqlExecutionModes.CaptureSql;
                        break;
                    }
                    }
                }

                Execute();
                if (mode == TaskExecutionMode.Script || mode == TaskExecutionMode.ExecuteAndScript)
                {
                    this.ScriptContent = GetScriptContent();
                    if (SqlTask != null)
                    {
                        OnScriptAdded(new TaskScript
                        {
                            Status = SqlTaskStatus.Succeeded,
                            Script = this.ScriptContent
                        });
                    }
                }
            }
            catch
            {
                throw;
            }
            finally
            {
                Server.ConnectionContext.CapturedSql.Clear();
                Server.ConnectionContext.SqlExecutionModes = currentExecutionMode;
            }
        }
 public static RunType asRunType(TaskExecutionMode taskExecutionMode)
 {
     if (taskExecutionMode == TaskExecutionMode.Script)
     {
         return(RunType.ScriptToWindow);
     }
     else
     {
         return(RunType.RunNow);
     }
 }
Exemple #17
0
 /// <summary>
 /// Since we could not derrive from TaskEngine and have no Interface, we need to overide the method in here and
 /// replace the calls when testing the class because of the calls to TaskEngine. If at a future time we get a mock task
 /// engine, Interface or a non sealed TaskEngine these methods can disappear.
 /// </summary>
 /// <returns></returns>
 virtual internal bool TaskEngineExecuteTask(
     TaskEngine taskEngine,
     TaskExecutionMode howTaskShouldBeExecuted,
     Lookup lookup
     )
 {
     return(taskEngine.ExecuteTask
            (
                howTaskShouldBeExecuted,
                lookup
            ));
 }
Exemple #18
0
        public void Execute(TaskExecutionMode mode)
        {
            if (this.CancellationToken.IsCancellationRequested)
            {
                throw new OperationCanceledException(this.CancellationToken);
            }

            try
            {
                SchemaCompareEndpoint sourceEndpoint = SchemaCompareUtils.CreateSchemaCompareEndpoint(this.Parameters.SourceEndpointInfo, this.SourceConnectionInfo);
                SchemaCompareEndpoint targetEndpoint = SchemaCompareUtils.CreateSchemaCompareEndpoint(this.Parameters.TargetEndpointInfo, this.TargetConnectionInfo);

                SchemaComparison comparison = new SchemaComparison(sourceEndpoint, targetEndpoint);

                if (this.Parameters.DeploymentOptions != null)
                {
                    comparison.Options = SchemaCompareUtils.CreateSchemaCompareOptions(this.Parameters.DeploymentOptions);
                }

                // for testing
                schemaCompareStarted?.Invoke(this, new EventArgs());

                this.ComparisonResult = comparison.Compare(this.CancellationToken);

                // try one more time if it didn't work the first time
                if (!this.ComparisonResult.IsValid)
                {
                    this.ComparisonResult = comparison.Compare(this.CancellationToken);
                }

                // Since DacFx does not throw on schema comparison cancellation, throwing here explicitly to ensure consistency of behavior
                if (!this.ComparisonResult.IsValid && this.CancellationToken.IsCancellationRequested)
                {
                    throw new OperationCanceledException(this.CancellationToken);
                }

                this.Differences = new List <DiffEntry>();
                if (this.ComparisonResult.Differences != null)
                {
                    foreach (SchemaDifference difference in this.ComparisonResult.Differences)
                    {
                        DiffEntry diffEntry = SchemaCompareUtils.CreateDiffEntry(difference, null);
                        this.Differences.Add(diffEntry);
                    }
                }
            }
            catch (Exception e)
            {
                ErrorMessage = e.Message;
                Logger.Write(TraceEventType.Error, string.Format("Schema compare operation {0} failed with exception {1}", this.OperationId, e.Message));
                throw;
            }
        }
Exemple #19
0
        public void Execute(TaskExecutionMode mode = TaskExecutionMode.Execute)
        {
            if (this.CancellationToken.IsCancellationRequested)
            {
                throw new OperationCanceledException(this.CancellationToken);
            }

            try
            {
                SchemaCompareEndpoint sourceEndpoint = SchemaCompareUtils.CreateSchemaCompareEndpoint(this.Parameters.SourceEndpointInfo, this.SourceConnectionString);
                SchemaCompareEndpoint targetEndpoint = SchemaCompareUtils.CreateSchemaCompareEndpoint(this.Parameters.TargetEndpointInfo, this.TargetConnectionString);

                SchemaComparison comparison = new SchemaComparison(sourceEndpoint, targetEndpoint);

                if (Parameters.ExcludedSourceObjects != null)
                {
                    foreach (var sourceObj in this.Parameters.ExcludedSourceObjects)
                    {
                        SchemaComparisonExcludedObjectId excludedObjId = SchemaCompareUtils.CreateExcludedObject(sourceObj);
                        if (excludedObjId != null)
                        {
                            comparison.ExcludedSourceObjects.Add(excludedObjId);
                        }
                    }
                }

                if (Parameters.ExcludedTargetObjects != null)
                {
                    foreach (var targetObj in this.Parameters.ExcludedTargetObjects)
                    {
                        SchemaComparisonExcludedObjectId excludedObjId = SchemaCompareUtils.CreateExcludedObject(targetObj);
                        if (excludedObjId != null)
                        {
                            comparison.ExcludedTargetObjects.Add(excludedObjId);
                        }
                    }
                }

                if (this.Parameters.DeploymentOptions != null)
                {
                    comparison.Options = SchemaCompareUtils.CreateSchemaCompareOptions(this.Parameters.DeploymentOptions);
                }

                comparison.SaveToFile(this.Parameters.ScmpFilePath, true);
            }
            catch (Exception e)
            {
                ErrorMessage = e.Message;
                Logger.Write(TraceEventType.Error, string.Format("Schema compare save settings operation {0} failed with exception {1}", this.OperationId, e));
                throw;
            }
        }
 protected void GenerateScript(TaskExecutionMode mode)
 {
     if (mode == TaskExecutionMode.Script || mode == TaskExecutionMode.ExecuteAndScript)
     {
         this.ScriptContent = GetScriptContent();
         if (SqlTask != null)
         {
             OnScriptAdded(new TaskScript
             {
                 Status = SqlTaskStatus.Succeeded,
                 Script = this.ScriptContent
             });
         }
     }
 }
Exemple #21
0
        public void Execute(TaskExecutionMode mode)
        {
            if (this.CancellationToken.IsCancellationRequested)
            {
                throw new OperationCanceledException(this.CancellationToken);
            }

            try
            {
                this.PublishResult = this.ComparisonResult.PublishChangesToTarget();
            }
            catch (Exception e)
            {
                ErrorMessage = e.Message;
                Logger.Write(TraceEventType.Error, string.Format("Schema compare publish changes operation {0} failed with exception {1}", this.OperationId, e.Message));
                throw;
            }
        }
        public void Execute(TaskExecutionMode mode)
        {
            if (this.CancellationToken.IsCancellationRequested)
            {
                throw new OperationCanceledException(this.CancellationToken);
            }

            try
            {
                this.DacServices = new DacServices(this.SqlConnection.ConnectionString);
                Execute();
            }
            catch (Exception e)
            {
                Logger.Write(TraceEventType.Error, string.Format("DacFx import operation {0} failed with exception {1}", this.OperationId, e));
                throw;
            }
        }
        /// <summary>
        /// Exclude will return false if included dependencies are found. Include will also include dependencies that need to be included.
        /// This is the same behavior as SSDT
        /// </summary>
        /// <param name="mode"></param>
        public void Execute(TaskExecutionMode mode)
        {
            this.CancellationToken.ThrowIfCancellationRequested();

            try
            {
                SchemaDifference node = this.FindDifference(this.ComparisonResult.Differences, this.Parameters.DiffEntry);
                if (node == null)
                {
                    throw new InvalidOperationException(SR.SchemaCompareExcludeIncludeNodeNotFound);
                }

                this.Success = this.Parameters.IncludeRequest ? this.ComparisonResult.Include(node) : this.ComparisonResult.Exclude(node);

                // if include request (pass or fail), send dependencies that might have been affected by this request, given by GetIncludeDependencies()
                if (this.Parameters.IncludeRequest)
                {
                    IEnumerable <SchemaDifference> affectedDependencies = this.ComparisonResult.GetIncludeDependencies(node);
                    this.AffectedDependencies = affectedDependencies.Select(difference => SchemaCompareUtils.CreateDiffEntry(difference: difference, parent: null)).ToList();
                }
                else
                {   // if exclude was successful, the possible affected dependencies are given by GetIncludedDependencies()
                    if (this.Success)
                    {
                        IEnumerable <SchemaDifference> affectedDependencies = this.ComparisonResult.GetIncludeDependencies(node);
                        this.AffectedDependencies = affectedDependencies.Select(difference => SchemaCompareUtils.CreateDiffEntry(difference: difference, parent: null)).ToList();
                    }
                    // if not successful, send back the exclude dependencies that caused it to fail
                    else
                    {
                        IEnumerable <SchemaDifference> blockingDependencies = this.ComparisonResult.GetExcludeDependencies(node);
                        blockingDependencies      = blockingDependencies.Where(difference => difference.Included == node.Included);
                        this.BlockingDependencies = blockingDependencies.Select(difference => SchemaCompareUtils.CreateDiffEntry(difference: difference, parent: null)).ToList();
                    }
                }
            }
            catch (Exception e)
            {
                ErrorMessage = e.Message;
                Logger.Write(TraceEventType.Error, string.Format("Schema compare publish changes operation {0} failed with exception {1}", this.OperationId, e.Message));
                throw;
            }
        }
        bool Execute(IBuildTask buildTask, TaskExecutionMode taskExecutionMode)
        {
            if (ConditionParser.ParseAndEvaluate(buildTask.Condition, project))
            {
                switch (taskExecutionMode)
                {
                case TaskExecutionMode.Complete:
                    return(buildTask.Execute());

                case TaskExecutionMode.SkipAndSetOutput:
                    return(buildTask.ResolveOutputItems());

                default:
                    throw new NotImplementedException();
                }
            }

            return(true);
        }
        public void Execute(TaskExecutionMode mode)
        {
            if (this.CancellationToken.IsCancellationRequested)
            {
                throw new OperationCanceledException(this.CancellationToken);
            }

            try
            {
                // Pass in Azure authentication token if needed
                this.DacServices = this.ConnInfo.ConnectionDetails.AzureAccountToken != null ? new DacServices(this.ConnectionString, new AccessTokenProvider(this.ConnInfo.ConnectionDetails.AzureAccountToken)) : new DacServices(this.ConnectionString);
                Execute();
            }
            catch (Exception e)
            {
                Logger.Write(TraceEventType.Error, string.Format("DacFx import operation {0} failed with exception {1}", this.OperationId, e));
                throw;
            }
        }
        public void Execute(TaskExecutionMode mode)
        {
            if (this.CancellationToken.IsCancellationRequested)
            {
                throw new OperationCanceledException(this.CancellationToken);
            }

            try
            {
                SchemaCompareEndpoint sourceEndpoint = CreateSchemaCompareEndpoint(this.Parameters.SourceEndpointInfo, this.SourceConnectionString);
                SchemaCompareEndpoint targetEndpoint = CreateSchemaCompareEndpoint(this.Parameters.TargetEndpointInfo, this.TargetConnectionString);

                SchemaComparison comparison = new SchemaComparison(sourceEndpoint, targetEndpoint);

                if (this.Parameters.DeploymentOptions != null)
                {
                    comparison.Options = this.CreateSchemaCompareOptions(this.Parameters.DeploymentOptions);
                }

                this.ComparisonResult = comparison.Compare();

                // try one more time if it didn't work the first time
                if (!this.ComparisonResult.IsValid)
                {
                    this.ComparisonResult = comparison.Compare();
                }

                this.Differences = new List <DiffEntry>();
                foreach (SchemaDifference difference in this.ComparisonResult.Differences)
                {
                    DiffEntry diffEntry = CreateDiffEntry(difference, null);
                    this.Differences.Add(diffEntry);
                }
            }
            catch (Exception e)
            {
                ErrorMessage = e.Message;
                Logger.Write(TraceEventType.Error, string.Format("Schema compare operation {0} failed with exception {1}", this.OperationId, e.Message));
                throw;
            }
        }
Exemple #27
0
        public void Execute(TaskExecutionMode mode)
        {
            this.CancellationToken.ThrowIfCancellationRequested();

            try
            {
                SchemaDifference node = this.FindDifference(this.ComparisonResult.Differences, this.Parameters.DiffEntry);
                if (node == null)
                {
                    throw new InvalidOperationException(SR.SchemaCompareExcludeIncludeNodeNotFound);
                }

                this.Success = this.Parameters.IncludeRequest ? this.ComparisonResult.Include(node) : this.ComparisonResult.Exclude(node);
            }
            catch (Exception e)
            {
                ErrorMessage = e.Message;
                Logger.Write(TraceEventType.Error, string.Format("Schema compare publish changes operation {0} failed with exception {1}", this.OperationId, e.Message));
                throw;
            }
        }
        /// <summary>
        /// Execute a task
        /// </summary>
        /// <param name="mode">Task execution mode (e.g. script or execute)</param>
        /// <exception cref="InvalidOperationException">
        /// The method has been called twice in parallel for the same instance.
        /// </exception>
        public void Execute(TaskExecutionMode mode)
        {
            try
            {
                var scriptText = GenerateScript(Parameters, cancellation.Token);
                if (scriptText != null)
                {
                    SqlTask?.AddScript(SqlTaskStatus.Succeeded, scriptText);
                }
            }
            catch (Exception e)
            {
                ErrorMessage = e.Message;
                Logger.Write(TraceEventType.Error, string.Format(
                                 CultureInfo.InvariantCulture,
                                 "SQL Assessment: generate script operation failed with exception {0}",
                                 e.Message));

                throw;
            }
        }
Exemple #29
0
        public void TaskExecutionStateTestProperties()
        {
            TaskExecutionMode        howToExecuteTask = TaskExecutionMode.ExecuteTaskAndGatherOutputs;
            XmlDocument              doc            = new XmlDocument();
            XmlElement               taskNode       = doc.CreateElement("Foo");
            TaskExecutionStateHelper executionState = new TaskExecutionStateHelper(
                howToExecuteTask,
                LookupHelpers.CreateLookup(projectLevelProprtiesForInference, projectLevelItemsForInference),
                LookupHelpers.CreateLookup(projectLevelPropertiesForExecution, projectLevelItemsForExecution),
                taskNode,
                hostObject,
                projectFileOfTaskNode,
                parentProjectFullFileName,
                executionDirectory,
                nodeProxyId);

            executionState.HandleId = 1;
            Assert.AreEqual(1, executionState.HandleId, "Expected NodeProxyId to be equal to 1");

            executionState.LoggingService = loggingHelper;
            Assert.AreEqual(loggingHelper, executionState.LoggingService, "Expected LoggingService to be equal to the loggingService set in the LoggingService property setter");
        }
        protected void SetExecutionMode(TaskExecutionMode mode)
        {
            switch (mode)
            {
            case TaskExecutionMode.Execute:
            {
                Server.ConnectionContext.SqlExecutionModes = SqlExecutionModes.ExecuteSql;
                break;
            }

            case TaskExecutionMode.ExecuteAndScript:
            {
                Server.ConnectionContext.SqlExecutionModes = SqlExecutionModes.ExecuteAndCaptureSql;
                break;
            }

            case TaskExecutionMode.Script:
            {
                Server.ConnectionContext.SqlExecutionModes = SqlExecutionModes.CaptureSql;
                break;
            }
            }
        }
Exemple #31
0
		public bool Build (IBuildTask buildTask, TaskExecutionMode taskExecutionMode, out bool executeOnErrors)
		{
			executeOnErrors = false;
			try {
				Init ();

				// populate list of referenced items and metadata
				ParseTaskAttributes (buildTask);
				if (consumedMetadataReferences.Count == 0) {
					return Execute (buildTask, taskExecutionMode);
				}

				BatchAndPrepareBuckets ();
				return Run (buildTask, taskExecutionMode, out executeOnErrors);
			} finally {
				consumedItemsByName = null;
				consumedMetadataReferences = null;
				consumedQMetadataReferences = null;
				consumedUQMetadataReferences = null;
				batchedItemsByName = null;
				commonItemsByName = null;
			}
		}
        bool Run(IBuildTask buildTask, TaskExecutionMode taskExecutionMode, out bool executeOnErrors)
        {
            executeOnErrors = false;

            // Run the task in batches
            bool retval = true;

            if (buckets.Count == 0)
            {
                // batched mode, but no values in the corresponding items!
                retval = Execute(buildTask, taskExecutionMode);
                if (!retval && !buildTask.ContinueOnError)
                {
                    executeOnErrors = true;
                }

                return(retval);
            }

            // batched
            foreach (Dictionary <string, BuildItemGroup> bucket in buckets)
            {
                project.PushBatch(bucket, commonItemsByName);
                try {
                    retval = Execute(buildTask, taskExecutionMode);
                    if (!retval && !buildTask.ContinueOnError)
                    {
                        executeOnErrors = true;
                        break;
                    }
                } finally {
                    project.PopBatch();
                }
            }

            return(retval);
        }
Exemple #33
0
        public void Execute(TaskExecutionMode mode)
        {
            if (this.CancellationToken.IsCancellationRequested)
            {
                throw new OperationCanceledException(this.CancellationToken);
            }

            try
            {
                this.PublishResult = this.ComparisonResult.PublishChangesToTarget(this.CancellationToken);
                if (!this.PublishResult.Success)
                {
                    // Sending only errors and warnings - because overall message might be too big for task view
                    ErrorMessage = string.Join(Environment.NewLine, this.PublishResult.Errors.Where(x => x.MessageType == SqlServer.Dac.DacMessageType.Error || x.MessageType == SqlServer.Dac.DacMessageType.Warning));
                    throw new Exception(ErrorMessage);
                }
            }
            catch (Exception e)
            {
                ErrorMessage = e.Message;
                Logger.Write(TraceEventType.Error, string.Format("Schema compare publish changes operation {0} failed with exception {1}", this.OperationId, e.Message));
                throw;
            }
        }
Exemple #34
0
        /// <summary>
        /// Gathers task outputs in two ways:
        /// 1) Given an instantiated task that has finished executing, it extracts the outputs using .NET reflection.
        /// 2) Otherwise, it parses the task's output specifications and (statically) infers the outputs.
        /// </summary>
        /// <param name="howToExecuteTask"></param>
        /// <param name="task"></param>
        /// <param name="bucket"></param>
        /// <returns>true, if successful</returns>
        private bool GatherTaskOutputs(TaskExecutionMode howToExecuteTask, ITask task, ItemBucket bucket)
        {
            bool gatheredTaskOutputsSuccessfully = true;

            foreach (TaskOutput taskOutputSpecification in
                        GetTaskOutputSpecifications(true))
            {
                // if the task's outputs are supposed to be gathered
                if (
                        (taskOutputSpecification.ConditionAttribute == null)
                        ||
                        Utilities.EvaluateCondition(taskOutputSpecification.ConditionAttribute.Value,
                            taskOutputSpecification.ConditionAttribute,
                            bucket.Expander, null, ParserOptions.AllowAll, loggingServices, buildEventContext)
                    )
                {
                    ErrorUtilities.VerifyThrow(taskOutputSpecification.TaskParameterAttribute != null,
                        "Invalid task output specification -- this should have been caught when the <Output> XML was parsed.");
                    ErrorUtilities.VerifyThrow(taskOutputSpecification.TaskParameterAttribute.Value.Length > 0,
                        "Invalid task output specification -- this should have been caught when the <Output> XML was parsed.");

                    // expand all embedded properties, item metadata and item vectors in the task parameter name
                    string taskParameterName = bucket.Expander.ExpandAllIntoString(taskOutputSpecification.TaskParameterAttribute);

                    ProjectErrorUtilities.VerifyThrowInvalidProject(taskParameterName.Length > 0, taskOutputSpecification.TaskParameterAttribute,
                        "InvalidEvaluatedAttributeValue", taskParameterName, taskOutputSpecification.TaskParameterAttribute.Value, XMakeAttributes.taskParameter, XMakeElements.output);

                    string itemName = null;
                    string propertyName = null;

                    // check where the outputs are going -- into a vector, or a property?
                    if (taskOutputSpecification.IsItemVector)
                    {
                        ErrorUtilities.VerifyThrow(taskOutputSpecification.ItemNameAttribute != null,
                            "How can it be an output item if the item name is null?  This should have been caught when the <Output> XML was parsed.");

                        ErrorUtilities.VerifyThrow(taskOutputSpecification.ItemNameAttribute.Value.Length > 0,
                            "Invalid task output specification -- this should have been caught when the <Output> XML was parsed.");

                        // expand all embedded properties, item metadata and item vectors in the item type name
                        itemName = bucket.Expander.ExpandAllIntoString(taskOutputSpecification.ItemNameAttribute);

                        ProjectErrorUtilities.VerifyThrowInvalidProject(itemName.Length > 0, taskOutputSpecification.ItemNameAttribute,
                            "InvalidEvaluatedAttributeValue", itemName, taskOutputSpecification.ItemNameAttribute.Value, XMakeAttributes.itemName, XMakeElements.output);
                    }
                    else
                    {
                        ErrorUtilities.VerifyThrow(taskOutputSpecification.IsProperty,
                            "Invalid task output specification -- this should have been caught when the <Output> XML was parsed.");

                        ErrorUtilities.VerifyThrow(taskOutputSpecification.PropertyNameAttribute != null,
                            "How can it be an output property if the property name is null?  This should have been caught when the <Output> XML was parsed.");

                        ErrorUtilities.VerifyThrow(taskOutputSpecification.PropertyNameAttribute.Value.Length > 0,
                            "Invalid task output specification -- this should have been caught when the <Output> XML was parsed.");

                        // expand all embedded properties, item metadata and item vectors in the property name
                        propertyName = bucket.Expander.ExpandAllIntoString(taskOutputSpecification.PropertyNameAttribute);

                        ProjectErrorUtilities.VerifyThrowInvalidProject(propertyName.Length > 0, taskOutputSpecification.PropertyNameAttribute,
                            "InvalidEvaluatedAttributeValue", propertyName, taskOutputSpecification.PropertyNameAttribute.Value, XMakeAttributes.propertyName, XMakeElements.output);
                    }

                    // if we're gathering outputs by .NET reflection
                    if (howToExecuteTask == TaskExecutionMode.ExecuteTaskAndGatherOutputs)
                    {
                        gatheredTaskOutputsSuccessfully = GatherGeneratedTaskOutputs(bucket.Lookup, taskOutputSpecification, taskParameterName, itemName, propertyName, task);
                    }
                    // if we're inferring outputs based on information in the task and <Output> tags
                    else
                    {
                        Debug.Assert(howToExecuteTask == TaskExecutionMode.InferOutputsOnly);

                        InferTaskOutputs(bucket.Lookup, taskOutputSpecification, taskParameterName, itemName, propertyName, bucket);
                    }
                }

                if (!gatheredTaskOutputsSuccessfully)
                {
                    break;
                }
            }

            return gatheredTaskOutputsSuccessfully;
        }
Exemple #35
0
        /// <summary>
        /// Execute a task object for a given bucket.
        /// </summary>
        /// <param name="engineProxy"></param>
        /// <param name="bucket"></param>
        /// <param name="howToExecuteTask"></param>
        /// <param name="task"></param>
        /// <param name="taskResult">Whether the task returned true from Execute</param>
        /// <returns>true if task executed successfully (possibly failed but continueOnError=true)</returns>
        private bool ExecuteInstantiatedTask(EngineProxy engineProxy, ItemBucket bucket, TaskExecutionMode howToExecuteTask, ITask task, out bool taskResult)
        {
            UpdateContinueOnError(bucket, engineProxy);

            taskResult = false;
            bool taskExecutedSuccessfully = true;

            if (!InitializeTask(task, bucket, engineProxy))
            {
                // The task cannot be initialized.
                ProjectErrorUtilities.VerifyThrowInvalidProject(false, taskNode, "TaskParametersError", TaskName, String.Empty);
            }
            else
            {
                bool taskReturned = false;

                try
                {
                    taskResult = task.Execute();
                    taskReturned = true;
                }
                // if a logger has failed, abort immediately
                catch (LoggerException)
                {
                    // Polite logger failure
                    throw;
                }
                catch (InternalLoggerException)
                {
                    // Logger threw arbitrary exception
                    throw;
                }
                // handle any exception thrown by the task during execution
                // NOTE: We catch ALL exceptions here, to attempt to completely isolate the Engine
                // from failures in the task. Probably we should try to avoid catching truly fatal exceptions,
                // e.g., StackOverflowException
                catch (Exception e)
                {
                    if (continueOnError)
                    {
                        loggingServices.LogTaskWarningFromException(buildEventContext, e,
                            // Don't try and log the line/column number for this error if
                            // ContinueOnError=true, because it's too expensive to do so, 
                            // and this error may be fairly common and expected.
                            new BuildEventFileInfo(projectFileOfTaskNode), TaskName);

                        // Log a message explaining why we converted the previous error into a warning.
                        loggingServices.LogComment(buildEventContext, MessageImportance.Normal, "ErrorConvertedIntoWarning");
                    }
                    else
                    {
                        loggingServices.LogFatalTaskError(buildEventContext, e,
                            CreateBuildEventFileInfoForTask(),
                            TaskName);
                    }
                }

                // If the task returned attempt to gather its outputs.  If gathering outputs fails set the taskResults
                // to false
                if (taskReturned)
                {
                    taskResult = GatherTaskOutputs(howToExecuteTask, task, bucket) && taskResult;
                }

                // If the taskResults are false look at ContinueOnError.  If ContinueOnError=false (default)
                // mark the taskExecutedSuccessfully=false.  Otherwise let the task succeed but log a normal
                // pri message that says this task is continuing because ContinueOnError=true
                if (!taskResult)
                {
                    if (!continueOnError)
                    {
                        taskExecutedSuccessfully = false;
                    }
                    else
                    {
                        loggingServices.LogComment(buildEventContext, MessageImportance.Normal,
                            "TaskContinuedDueToContinueOnError",
                             "ContinueOnError", TaskName, "true");
                    }
                }
            }

            return taskExecutedSuccessfully;
        }
Exemple #36
0
        /// <summary>
        /// Executes the task.
        /// </summary>
        public Task<WorkUnitResult> ExecuteTask(TargetLoggingContext targetLoggingContext, BuildRequestEntry requestEntry, ITargetBuilderCallback targetBuilderCallback, ProjectTargetInstanceChild task, TaskExecutionMode mode, Lookup lookupForInference, Lookup lookupForExecution, CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return Task<WorkUnitResult>.FromResult(new WorkUnitResult(WorkUnitResultCode.Canceled, WorkUnitActionCode.Stop, null));
            }

            ProjectOnErrorInstance errorTask = task as ProjectOnErrorInstance;
            if (null != errorTask)
            {
                ErrorTasks.Add(errorTask);
            }
            else
            {
                ProjectTaskInstance taskInstance = task as ProjectTaskInstance;
                ExecutedTasks.Add(taskInstance);

                if ((mode & TaskExecutionMode.InferOutputsOnly) == TaskExecutionMode.InferOutputsOnly)
                {
                    lookupForInference.AddNewItem(new ProjectItemInstance(requestEntry.RequestConfiguration.Project, taskInstance.Name + "_Item", "Item", task.Location.File));
                }
                else if ((mode & TaskExecutionMode.ExecuteTaskAndGatherOutputs) == TaskExecutionMode.ExecuteTaskAndGatherOutputs)
                {
                    lookupForExecution.AddNewItem(new ProjectItemInstance(requestEntry.RequestConfiguration.Project, taskInstance.Name + "_Item", "Item", task.Location.File));
                }

                if (String.Equals(taskInstance.Name, "CallTarget", StringComparison.OrdinalIgnoreCase))
                {
                    taskInstance.GetParameter("Targets");
                    char[] splitter = new char[] { ';' };
                    targetBuilderCallback.LegacyCallTarget(taskInstance.GetParameter("Targets").Split(splitter), false, taskInstance.Location);
                }

                _taskNumber++;
                if (FailTaskNumber == _taskNumber)
                {
                    if (taskInstance.ContinueOnError == "True")
                    {
                        return Task<WorkUnitResult>.FromResult(new WorkUnitResult(WorkUnitResultCode.Failed, WorkUnitActionCode.Continue, null));
                    }

                    return Task<WorkUnitResult>.FromResult(new WorkUnitResult(WorkUnitResultCode.Failed, WorkUnitActionCode.Stop, null));
                }
            }

            return Task<WorkUnitResult>.FromResult(new WorkUnitResult(WorkUnitResultCode.Success, WorkUnitActionCode.Continue, null));
        }
Exemple #37
0
		bool Execute (IBuildTask buildTask, TaskExecutionMode taskExecutionMode)
		{
			if (ConditionParser.ParseAndEvaluate (buildTask.Condition, project)) {
				switch (taskExecutionMode) {
				case TaskExecutionMode.Complete:
					return buildTask.Execute ();
				case TaskExecutionMode.SkipAndSetOutput:
					return buildTask.ResolveOutputItems ();
				default:
					throw new NotImplementedException ();
				}
			}

			return true;
		}
 /// <summary>
 /// Mock out and override the method inside of TaskExecutionState which makes the calls to the task engine.
 /// </summary>
 internal override bool TaskEngineExecuteTask(TaskEngine taskEngine, TaskExecutionMode howToExecuteTask, Lookup lookup)
 {
     return targetInferenceSuccessful;
 }
Exemple #39
0
        /// <summary>
        /// Initializes and executes the task.
        /// </summary>
        private async Task<WorkUnitResult> InitializeAndExecuteTask(TaskLoggingContext taskLoggingContext, ItemBucket bucket, IDictionary<string, string> taskIdentityParameters, TaskHost taskHost, TaskExecutionMode howToExecuteTask)
        {
            if (!_taskExecutionHost.InitializeForBatch(taskLoggingContext, bucket, taskIdentityParameters))
            {
                ProjectErrorUtilities.ThrowInvalidProject(_targetChildInstance.Location, "TaskDeclarationOrUsageError", _taskNode.Name);
            }

            try
            {
                // UNDONE: Move this and the task host.
                taskHost.LoggingContext = taskLoggingContext;
                WorkUnitResult executionResult = await ExecuteInstantiatedTask(_taskExecutionHost, taskLoggingContext, taskHost, bucket, howToExecuteTask);

                ErrorUtilities.VerifyThrow(executionResult != null, "Unexpected null execution result");

                return executionResult;
            }
            finally
            {
                _taskExecutionHost.CleanupForBatch();
            }
        }
Exemple #40
0
        /// <summary>
        /// Called to execute a task within a target. This method instantiates the task, sets its parameters, and executes it. 
        /// </summary>
        /// <returns>true, if successful</returns>
        internal bool ExecuteTask(TaskExecutionMode howToExecuteTask, Lookup lookup)
        {
            ErrorUtilities.VerifyThrow(lookup != null, "Need to specify items available to task.");

            bool taskExecutedSuccessfully = false;
            EngineProxy engineProxy = null;

            ArrayList buckets = null;

            try
            {
                engineProxy = new EngineProxy(parentModule, handleId, parentProjectFullFileName, projectFileOfTaskNode, loggingServices, buildEventContext);
                List<string> taskParameterValues = CreateListOfParameterValues();
                buckets = BatchingEngine.PrepareBatchingBuckets(taskNode, taskParameterValues, lookup);

                lookupHash = null;
                // Only create a hash table if there are more than one bucket as this is the only time a property can be overridden
                if (buckets.Count > 1)
                {
                    lookupHash = Utilities.CreateTableIfNecessary((Hashtable)null);
                }
		
		// Loop through each of the batch buckets and execute them one at a time
                for (int i=0; i < buckets.Count; i++)
                {
                    // Execute the batch bucket, pass in which bucket we are executing so that we know when to get a new taskId for the bucket.
                    taskExecutedSuccessfully = ExecuteBucket(engineProxy, (ItemBucket)buckets[i], i, howToExecuteTask);
                    if (!taskExecutedSuccessfully)
                    {
                        break;
                    }
                }
            }
            finally
            {
                // Remove the AssemblyResolve handler in the default AppDomain, we are done with the task.
                if (resolver != null)
                {
                    resolver.RemoveHandler();
                }

                if (engineProxy != null)
                {
                    engineProxy.MarkAsInActive();
                }

                // Now all task batches are done, apply all item adds to the outer 
                // target batch; we do this even if the task wasn't found (in that case,
                // no items or properties will have been added to the scope)
                if (buckets != null)
                {
                    foreach (ItemBucket bucket in buckets)
                    {
                        bucket.Lookup.LeaveScope();
                    }
                }
            }

            return taskExecutedSuccessfully;
        }
Exemple #41
0
        /// <summary>
        /// Logs a task skipped message if necessary.
        /// </summary>
        private void LogSkippedTask(ItemBucket bucket, TaskExecutionMode howToExecuteTask)
        {
            // If this is an Intrinsic task, it does not log skips.
            if (_taskNode != null)
            {
                if (howToExecuteTask == TaskExecutionMode.ExecuteTaskAndGatherOutputs)
                {
                    if (!_targetLoggingContext.LoggingService.OnlyLogCriticalEvents)
                    {
                        // Expand the expression for the Log.
                        string expanded = bucket.Expander.ExpandIntoStringAndUnescape(_targetChildInstance.Condition, ExpanderOptions.ExpandAll, _targetChildInstance.ConditionLocation);

                        // Whilst we are within the processing of the task, we haven't actually started executing it, so
                        // our skip task message needs to be in the context of the target. However any errors should be reported
                        // at the point where the task appears in the project.
                        _targetLoggingContext.LogComment
                            (
                            MessageImportance.Low,
                            "TaskSkippedFalseCondition",
                            _taskNode.Name,
                            _targetChildInstance.Condition,
                            expanded
                            );
                    }
                }
            }
        }
Exemple #42
0
        /// <summary>
        /// Execute a task object for a given bucket.
        /// </summary>
        /// <param name="taskExecutionHost">The host used to execute the task.</param>
        /// <param name="taskLoggingContext">The logging context.</param>
        /// <param name="taskHost">The task host for the task.</param>
        /// <param name="bucket">The batching bucket</param>
        /// <param name="howToExecuteTask">The task execution mode</param>
        /// <returns>The result of running the task.</returns>
        private async Task<WorkUnitResult> ExecuteInstantiatedTask(ITaskExecutionHost taskExecutionHost, TaskLoggingContext taskLoggingContext, TaskHost taskHost, ItemBucket bucket, TaskExecutionMode howToExecuteTask)
        {
            UpdateContinueOnError(bucket, taskHost);

            bool taskResult = false;

            WorkUnitResultCode resultCode = WorkUnitResultCode.Success;
            WorkUnitActionCode actionCode = WorkUnitActionCode.Continue;

            if (!taskExecutionHost.SetTaskParameters(_taskNode.ParametersForBuild))
            {
                // The task cannot be initialized.
                ProjectErrorUtilities.VerifyThrowInvalidProject(false, _targetChildInstance.Location, "TaskParametersError", _taskNode.Name, String.Empty);
            }
            else
            {
                bool taskReturned = false;
                Exception taskException = null;

                // If this is the MSBuild task, we need to execute it's special internal method.
                TaskExecutionHost host = taskExecutionHost as TaskExecutionHost;
                Type taskType = host.TaskInstance.GetType();

                try
                {
                    if (taskType == typeof(MSBuild))
                    {
                        MSBuild msbuildTask = host.TaskInstance as MSBuild;
                        ErrorUtilities.VerifyThrow(msbuildTask != null, "Unexpected MSBuild internal task.");
                        _targetBuilderCallback.EnterMSBuildCallbackState();

                        try
                        {
                            taskResult = await msbuildTask.ExecuteInternal();
                        }
                        finally
                        {
                            _targetBuilderCallback.ExitMSBuildCallbackState();
                        }
                    }
                    else if (taskType == typeof(CallTarget))
                    {
                        CallTarget callTargetTask = host.TaskInstance as CallTarget;
                        taskResult = await callTargetTask.ExecuteInternal();
                    }
                    else
                    {
                        using (FullTracking.Track(taskLoggingContext.TargetLoggingContext.Target.Name, _taskNode.Name, _buildRequestEntry.ProjectRootDirectory, _buildRequestEntry.RequestConfiguration.Project.PropertiesToBuildWith))
                        {
                            taskResult = taskExecutionHost.Execute();
                        }
                    }
                }
                catch (Exception ex)
                {
                    if (ExceptionHandling.IsCriticalException(ex) || (Environment.GetEnvironmentVariable("MSBUILDDONOTCATCHTASKEXCEPTIONS") == "1"))
                    {
                        throw;
                    }

                    taskException = ex;
                }

                if (taskException == null)
                {
                    taskReturned = true;

                    // Set the property "MSBuildLastTaskResult" to reflect whether the task succeeded or not.
                    // The main use of this is if ContinueOnError is true -- so that the next task can consult the result.
                    // So we want it to be "false" even if ContinueOnError is true. 
                    // The constants "true" and "false" should NOT be localized. They become property values.
                    bucket.Lookup.SetProperty(ProjectPropertyInstance.Create(ReservedPropertyNames.lastTaskResult, taskResult ? "true" : "false", true/* may be reserved */, _buildRequestEntry.RequestConfiguration.Project.IsImmutable));
                }
                else
                {
                    Type type = taskException.GetType();

                    if (type == typeof(LoggerException))
                    {
                        // if a logger has failed, abort immediately
                        // Polite logger failure
                        _continueOnError = ContinueOnError.ErrorAndStop;

                        // Rethrow wrapped in order to avoid losing the callstack
                        throw new LoggerException(taskException.Message, taskException);
                    }
                    else if (type == typeof(InternalLoggerException))
                    {
                        // Logger threw arbitrary exception
                        _continueOnError = ContinueOnError.ErrorAndStop;
                        InternalLoggerException ex = taskException as InternalLoggerException;

                        // Rethrow wrapped in order to avoid losing the callstack
                        throw new InternalLoggerException(taskException.Message, taskException, ex.BuildEventArgs, ex.ErrorCode, ex.HelpKeyword, ex.InitializationException);
                    }
                    else if (type == typeof(ThreadAbortException))
                    {
                        Thread.ResetAbort();
                        _continueOnError = ContinueOnError.ErrorAndStop;

                        // Cannot rethrow wrapped as ThreadAbortException is sealed and has no appropriate constructor
                        // Stack will be lost
                        throw taskException;
                    }
                    else if (type == typeof(BuildAbortedException))
                    {
                        _continueOnError = ContinueOnError.ErrorAndStop;

                        // Rethrow wrapped in order to avoid losing the callstack
                        throw new BuildAbortedException(taskException.Message, ((BuildAbortedException)taskException));
                    }
                    else if (type == typeof(CircularDependencyException))
                    {
                        _continueOnError = ContinueOnError.ErrorAndStop;
                        ProjectErrorUtilities.ThrowInvalidProject(taskLoggingContext.Task.Location, "CircularDependency", taskLoggingContext.TargetLoggingContext.Target.Name);
                    }
                    else if (type == typeof(InvalidProjectFileException))
                    {
                        // Just in case this came out of a task, make sure it's not
                        // marked as having been logged.
                        InvalidProjectFileException ipex = (InvalidProjectFileException)taskException;
                        ipex.HasBeenLogged = false;

                        if (_continueOnError != ContinueOnError.ErrorAndStop)
                        {
                            taskLoggingContext.LogInvalidProjectFileError(ipex);
                            taskLoggingContext.LogComment(MessageImportance.Normal, "ErrorConvertedIntoWarning");
                        }
                        else
                        {
                            // Rethrow wrapped in order to avoid losing the callstack
                            throw new InvalidProjectFileException(ipex.Message, ipex);
                        }
                    }
                    else if (type == typeof(Exception) || type.IsSubclassOf(typeof(Exception)))
                    {
                        // Occasionally, when debugging a very uncommon task exception, it is useful to loop the build with 
                        // a debugger attached to break on 2nd chance exceptions.
                        // That requires that there needs to be a way to not catch here, by setting an environment variable.
                        if (ExceptionHandling.IsCriticalException(taskException) || (Environment.GetEnvironmentVariable("MSBUILDDONOTCATCHTASKEXCEPTIONS") == "1"))
                        {
                            // Wrapping in an Exception will unfortunately mean that this exception would fly through any IsCriticalException above.
                            // However, we should not have any, also we should not have stashed such an exception anyway.
                            throw new Exception(taskException.Message, taskException);
                        }

                        Exception exceptionToLog = taskException;

                        if (exceptionToLog is TargetInvocationException)
                        {
                            exceptionToLog = exceptionToLog.InnerException;
                        }

                        // handle any exception thrown by the task during execution
                        // NOTE: We catch ALL exceptions here, to attempt to completely isolate the Engine
                        // from failures in the task.
                        if (_continueOnError == ContinueOnError.WarnAndContinue)
                        {
                            taskLoggingContext.LogTaskWarningFromException
                            (
                                new BuildEventFileInfo(_targetChildInstance.Location),
                                exceptionToLog,
                                _taskNode.Name
                            );

                            // Log a message explaining why we converted the previous error into a warning.
                            taskLoggingContext.LogComment(MessageImportance.Normal, "ErrorConvertedIntoWarning");
                        }
                        else
                        {
                            taskLoggingContext.LogFatalTaskError
                            (
                                new BuildEventFileInfo(_targetChildInstance.Location),
                                exceptionToLog,
                                _taskNode.Name
                            );
                        }
                    }
                    else
                    {
                        ErrorUtilities.ThrowInternalErrorUnreachable();
                    }
                }

                // If the task returned attempt to gather its outputs.  If gathering outputs fails set the taskResults
                // to false
                if (taskReturned)
                {
                    taskResult = GatherTaskOutputs(taskExecutionHost, howToExecuteTask, bucket) && taskResult;
                }

                // If the taskResults are false look at ContinueOnError.  If ContinueOnError=false (default)
                // mark the taskExecutedSuccessfully=false.  Otherwise let the task succeed but log a normal
                // pri message that says this task is continuing because ContinueOnError=true
                resultCode = taskResult ? WorkUnitResultCode.Success : WorkUnitResultCode.Failed;
                actionCode = WorkUnitActionCode.Continue;
                if (resultCode == WorkUnitResultCode.Failed)
                {
                    if (_continueOnError == ContinueOnError.ErrorAndStop)
                    {
                        actionCode = WorkUnitActionCode.Stop;
                    }
                    else
                    {
                        // This is the ErrorAndContinue or WarnAndContinue case...
                        string settingString = "true";
                        if (_taskNode.ContinueOnErrorLocation != null)
                        {
                            settingString = bucket.Expander.ExpandIntoStringAndUnescape(_taskNode.ContinueOnError, ExpanderOptions.ExpandAll, _taskNode.ContinueOnErrorLocation); // expand embedded item vectors after expanding properties and item metadata
                        }

                        taskLoggingContext.LogComment
                        (
                            MessageImportance.Normal,
                            "TaskContinuedDueToContinueOnError",
                            "ContinueOnError",
                            _taskNode.Name,
                            settingString
                        );

                        actionCode = WorkUnitActionCode.Continue;
                    }
                }
            }

            WorkUnitResult result = new WorkUnitResult(resultCode, actionCode, null);

            return result;
        }
Exemple #43
0
        /// <summary>
        /// Called to execute a task within a target. This method instantiates the task, sets its parameters, and executes it. 
        /// </summary>
        /// <returns>true, if successful</returns>
        private async Task<WorkUnitResult> ExecuteTask(TaskExecutionMode mode, Lookup lookup)
        {
            ErrorUtilities.VerifyThrowArgumentNull(lookup, "lookup");

            WorkUnitResult taskResult = new WorkUnitResult(WorkUnitResultCode.Failed, WorkUnitActionCode.Stop, null);
            TaskHost taskHost = null;

            List<ItemBucket> buckets = null;

            try
            {
                if (_taskNode != null)
                {
                    taskHost = new TaskHost(_componentHost, _buildRequestEntry, _targetChildInstance.Location, _targetBuilderCallback);
                    _taskExecutionHost.InitializeForTask(taskHost, _targetLoggingContext, _buildRequestEntry.RequestConfiguration.Project, _taskNode.Name, _taskNode.Location, _taskHostObject, _continueOnError != ContinueOnError.ErrorAndStop, taskHost.AppDomainSetup, taskHost.IsOutOfProc, _cancellationToken);
                }

                List<string> taskParameterValues = CreateListOfParameterValues();
                buckets = BatchingEngine.PrepareBatchingBuckets(taskParameterValues, lookup, _targetChildInstance.Location);

                Dictionary<string, string> lookupHash = null;

                // Only create a hash table if there are more than one bucket as this is the only time a property can be overridden
                if (buckets.Count > 1)
                {
                    lookupHash = new Dictionary<string, string>(MSBuildNameIgnoreCaseComparer.Default);
                }

                WorkUnitResult aggregateResult = new WorkUnitResult();

                // Loop through each of the batch buckets and execute them one at a time
                for (int i = 0; i < buckets.Count; i++)
                {
                    // Execute the batch bucket, pass in which bucket we are executing so that we know when to get a new taskId for the bucket.
                    taskResult = await ExecuteBucket(taskHost, (ItemBucket)buckets[i], mode, lookupHash);

                    aggregateResult = aggregateResult.AggregateResult(taskResult);

                    if (aggregateResult.ActionCode == WorkUnitActionCode.Stop)
                    {
                        break;
                    }
                }

                taskResult = aggregateResult;
            }
            finally
            {
                _taskExecutionHost.CleanupForTask();

                if (taskHost != null)
                {
                    taskHost.MarkAsInactive();
                }

                // Now all task batches are done, apply all item adds to the outer 
                // target batch; we do this even if the task wasn't found (in that case,
                // no items or properties will have been added to the scope)
                if (buckets != null)
                {
                    foreach (ItemBucket bucket in buckets)
                    {
                        bucket.LeaveScope();
                    }
                }
            }

            return taskResult;
        }
Exemple #44
0
        /// <summary>
        /// Gathers task outputs in two ways:
        /// 1) Given an instantiated task that has finished executing, it extracts the outputs using .NET reflection.
        /// 2) Otherwise, it parses the task's output specifications and (statically) infers the outputs.
        /// </summary>
        /// <param name="taskExecutionHost">The task execution host.</param>
        /// <param name="howToExecuteTask">The task execution mode</param>
        /// <param name="bucket">The bucket to which the task execution belongs.</param>
        /// <returns>true, if successful</returns>
        private bool GatherTaskOutputs(ITaskExecutionHost taskExecutionHost, TaskExecutionMode howToExecuteTask, ItemBucket bucket)
        {
            bool gatheredTaskOutputsSuccessfully = true;

            foreach (ProjectTaskInstanceChild taskOutputSpecification in _taskNode.Outputs)
            {
                // if the task's outputs are supposed to be gathered
                bool condition = ConditionEvaluator.EvaluateCondition
                    (
                    taskOutputSpecification.Condition,
                    ParserOptions.AllowAll,
                    bucket.Expander,
                    ExpanderOptions.ExpandAll,
                    _buildRequestEntry.ProjectRootDirectory,
                    taskOutputSpecification.ConditionLocation,
                    _targetLoggingContext.LoggingService,
                    _targetLoggingContext.BuildEventContext
                    );

                if (condition)
                {
                    string taskParameterName = null;
                    bool outputTargetIsItem = false;
                    string outputTargetName = null;

                    // check where the outputs are going -- into a vector, or a property?
                    ProjectTaskOutputItemInstance taskOutputItemInstance = taskOutputSpecification as ProjectTaskOutputItemInstance;

                    if (taskOutputItemInstance != null)
                    {
                        // expand all embedded properties, item metadata and item vectors in the item type name
                        outputTargetIsItem = true;
                        outputTargetName = bucket.Expander.ExpandIntoStringAndUnescape(taskOutputItemInstance.ItemType, ExpanderOptions.ExpandAll, taskOutputItemInstance.ItemTypeLocation);
                        taskParameterName = taskOutputItemInstance.TaskParameter;

                        ProjectErrorUtilities.VerifyThrowInvalidProject
                        (
                            outputTargetName.Length > 0,
                            taskOutputItemInstance.ItemTypeLocation,
                            "InvalidEvaluatedAttributeValue",
                            outputTargetName,
                            taskOutputItemInstance.ItemType,
                            XMakeAttributes.itemName,
                            XMakeElements.output
                        );
                    }
                    else
                    {
                        ProjectTaskOutputPropertyInstance taskOutputPropertyInstance = taskOutputSpecification as ProjectTaskOutputPropertyInstance;
                        outputTargetIsItem = false;

                        // expand all embedded properties, item metadata and item vectors in the property name
                        outputTargetName = bucket.Expander.ExpandIntoStringAndUnescape(taskOutputPropertyInstance.PropertyName, ExpanderOptions.ExpandAll, taskOutputPropertyInstance.PropertyNameLocation);
                        taskParameterName = taskOutputPropertyInstance.TaskParameter;

                        ProjectErrorUtilities.VerifyThrowInvalidProject
                        (
                            outputTargetName.Length > 0,
                            taskOutputPropertyInstance.PropertyNameLocation,
                            "InvalidEvaluatedAttributeValue",
                            outputTargetName,
                            taskOutputPropertyInstance.PropertyName,
                            XMakeAttributes.propertyName,
                            XMakeElements.output
                        );
                    }

                    string unexpandedTaskParameterName = taskParameterName;
                    taskParameterName = bucket.Expander.ExpandIntoStringAndUnescape(taskParameterName, ExpanderOptions.ExpandAll, taskOutputSpecification.TaskParameterLocation);

                    ProjectErrorUtilities.VerifyThrowInvalidProject
                    (
                        taskParameterName.Length > 0,
                        taskOutputSpecification.TaskParameterLocation,
                        "InvalidEvaluatedAttributeValue",
                        taskParameterName,
                        unexpandedTaskParameterName,
                        XMakeAttributes.taskParameter,
                        XMakeElements.output
                    );

                    // if we're gathering outputs by .NET reflection
                    if (howToExecuteTask == TaskExecutionMode.ExecuteTaskAndGatherOutputs)
                    {
                        gatheredTaskOutputsSuccessfully = taskExecutionHost.GatherTaskOutputs(taskParameterName, taskOutputSpecification.Location, outputTargetIsItem, outputTargetName);
                    }
                    else
                    {
                        // If we're inferring outputs based on information in the task and <Output> tags
                        ErrorUtilities.VerifyThrow(howToExecuteTask == TaskExecutionMode.InferOutputsOnly, "should be inferring");

                        // UNDONE: Refactor this method to use the same flag/string paradigm we use above, rather than two strings and the task output spec.
                        InferTaskOutputs(bucket.Lookup, taskOutputSpecification, taskParameterName, outputTargetName, outputTargetName, bucket);
                    }
                }

                if (!gatheredTaskOutputsSuccessfully)
                {
                    break;
                }
            }

            return gatheredTaskOutputsSuccessfully;
        }
Exemple #45
0
 /// <summary>
 /// Since we could not derrive from TaskEngine and have no Interface, we need to overide the method in here and 
 /// replace the calls when testing the class because of the calls to TaskEngine. If at a future time we get a mock task 
 /// engine, Interface or a non sealed TaskEngine these methods can disappear.
 /// </summary>
 /// <returns></returns>
 virtual internal bool TaskEngineExecuteTask(
     TaskEngine taskEngine,
     TaskExecutionMode howTaskShouldBeExecuted,
     Lookup lookup
 )
 {
     return taskEngine.ExecuteTask
          (
              howTaskShouldBeExecuted,
              lookup
          );
 }
Exemple #46
0
        /// <summary>
        /// Execute a single bucket
        /// </summary>
        /// <returns>true if execution succeeded</returns>        
        private async Task<WorkUnitResult> ExecuteBucket(TaskHost taskHost, ItemBucket bucket, TaskExecutionMode howToExecuteTask, Dictionary<string, string> lookupHash)
        {
            // On Intrinsic tasks, we do not allow batchable params, therefore metadata is excluded.
            ParserOptions parserOptions = (_taskNode == null) ? ParserOptions.AllowPropertiesAndItemLists : ParserOptions.AllowAll;
            WorkUnitResult taskResult = new WorkUnitResult(WorkUnitResultCode.Failed, WorkUnitActionCode.Stop, null);

            bool condition = ConditionEvaluator.EvaluateCondition
                (
                _targetChildInstance.Condition,
                parserOptions,
                bucket.Expander,
                ExpanderOptions.ExpandAll,
                _buildRequestEntry.ProjectRootDirectory,
                _targetChildInstance.ConditionLocation,
                _targetLoggingContext.LoggingService,
                _targetLoggingContext.BuildEventContext
                );

            if (!condition)
            {
                LogSkippedTask(bucket, howToExecuteTask);
                taskResult = new WorkUnitResult(WorkUnitResultCode.Skipped, WorkUnitActionCode.Continue, null);

                return taskResult;
            }

            // If this is an Intrinsic task, it gets handled in a special fashion.
            if (_taskNode == null)
            {
                ExecuteIntrinsicTask(bucket);
                taskResult = new WorkUnitResult(WorkUnitResultCode.Success, WorkUnitActionCode.Continue, null);
            }
            else
            {
                if (_componentHost.BuildParameters.SaveOperatingEnvironment)
                {
                    // Change to the project root directory.
                    // If that directory does not exist, do nothing. (Do not check first as it is almost always there and it is slow)
                    // This is because if the project has not been saved, this directory may not exist, yet it is often useful to still be able to build the project. 
                    // No errors are masked by doing this: errors loading the project from disk are reported at load time, if necessary.
                    NativeMethodsShared.SetCurrentDirectory(_buildRequestEntry.ProjectRootDirectory);
                }

                if (howToExecuteTask == TaskExecutionMode.ExecuteTaskAndGatherOutputs)
                {
                    // We need to find the task before logging the task started event so that the using task statement comes before the task started event 
                    IDictionary<string, string> taskIdentityParameters = GatherTaskIdentityParameters(bucket.Expander);
                    TaskRequirements? requirements = _taskExecutionHost.FindTask(taskIdentityParameters);
                    if (requirements != null)
                    {
                        TaskLoggingContext taskLoggingContext = _targetLoggingContext.LogTaskBatchStarted(_projectFullPath, _targetChildInstance);
                        try
                        {
                            if (
                                ((requirements.Value & TaskRequirements.RequireSTAThread) == TaskRequirements.RequireSTAThread) &&
                                (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA)
                                )
                            {
                                taskResult = ExecuteTaskInSTAThread(bucket, taskLoggingContext, taskIdentityParameters, taskHost, howToExecuteTask);
                            }
                            else
                            {
                                taskResult = await InitializeAndExecuteTask(taskLoggingContext, bucket, taskIdentityParameters, taskHost, howToExecuteTask);
                            }

                            if (lookupHash != null)
                            {
                                List<string> overrideMessages = bucket.Lookup.GetPropertyOverrideMessages(lookupHash);
                                if (overrideMessages != null)
                                {
                                    foreach (string s in overrideMessages)
                                    {
                                        taskLoggingContext.LogCommentFromText(MessageImportance.Low, s);
                                    }
                                }
                            }
                        }
                        catch (InvalidProjectFileException e)
                        {
                            // Make sure the Invalid Project error gets logged *before* TaskFinished.  Otherwise,
                            // the log is confusing.
                            taskLoggingContext.LogInvalidProjectFileError(e);
                            _continueOnError = ContinueOnError.ErrorAndStop;
                        }
                        finally
                        {
                            // Flag the completion of the task.
                            taskLoggingContext.LogTaskBatchFinished(_projectFullPath, taskResult.ResultCode == WorkUnitResultCode.Success || taskResult.ResultCode == WorkUnitResultCode.Skipped);

                            if (taskResult.ResultCode == WorkUnitResultCode.Failed && _continueOnError == ContinueOnError.WarnAndContinue)
                            {
                                // We coerce the failing result to a successful result.
                                taskResult = new WorkUnitResult(WorkUnitResultCode.Success, taskResult.ActionCode, taskResult.Exception);
                            }
                        }
                    }
                }
                else
                {
                    ErrorUtilities.VerifyThrow(howToExecuteTask == TaskExecutionMode.InferOutputsOnly, "should be inferring");

                    ErrorUtilities.VerifyThrow
                        (
                        GatherTaskOutputs(null, howToExecuteTask, bucket),
                        "The method GatherTaskOutputs() should never fail when inferring task outputs."
                        );

                    if (lookupHash != null)
                    {
                        List<string> overrideMessages = bucket.Lookup.GetPropertyOverrideMessages(lookupHash);
                        if (overrideMessages != null)
                        {
                            foreach (string s in overrideMessages)
                            {
                                _targetLoggingContext.LogCommentFromText(MessageImportance.Low, s);
                            }
                        }
                    }

                    taskResult = new WorkUnitResult(WorkUnitResultCode.Success, WorkUnitActionCode.Continue, null);
                }
            }

            return taskResult;
        }
Exemple #47
0
        /// <summary>
        /// Execute a single bucket
        /// </summary>
        /// <returns>true if execution succeeded</returns>
        private bool ExecuteBucket(EngineProxy engineProxy, ItemBucket bucket, int bucketNumber, TaskExecutionMode howToExecuteTask)
        {
            if (
                    (this.conditionAttribute != null)
                    &&
                    !Utilities.EvaluateCondition(this.conditionAttribute.Value, this.conditionAttribute,
                        bucket.Expander, null, ParserOptions.AllowAll, loggingServices, buildEventContext)
                )
            {
                // Condition is false
                if (howToExecuteTask == TaskExecutionMode.ExecuteTaskAndGatherOutputs)
                {
                    if (!loggingServices.OnlyLogCriticalEvents)
                    {
                        // Expand the expression for the Log.
                        string expanded = bucket.Expander.ExpandAllIntoString(this.conditionAttribute);
                        // Whilst we are within the processing of the task, we haven't actually started executing it, so
                        // our skip task message needs to be in the context of the target. However any errors should be reported
                        // at the point where the task appears in the project.
                        BuildEventContext skipTaskContext = new BuildEventContext(buildEventContext.NodeId, buildEventContext.TargetId, buildEventContext.ProjectContextId, BuildEventContext.InvalidTaskId);
                        loggingServices.LogComment(skipTaskContext,
                                        "TaskSkippedFalseCondition",
                                         TaskName, this.conditionAttribute.Value, expanded);
                    }
                }

                return true;
            }

            bool taskExecutedSuccessfully = true;

            // Condition is true
            if (howToExecuteTask == TaskExecutionMode.ExecuteTaskAndGatherOutputs)
            {
                // Now that we know we will need to execute the task,
                // Ensure the TaskEngine is initialized with the task class
                // This does the work of task discovery, if it 
                // hasn't already been done.
                bool taskClassWasFound = FindTask();

                if (!taskClassWasFound)
                {
                    // Task wasn't discovered, we cannot continue
                    return false;
                }

                // Now instantiate, initialize, and execute the task
                ITask task;

                // If this is the first bucket use the task context originally given to it, for the remaining buckets get a unique id for them
                if (bucketNumber != 0)
                {
		    // Ask the parent engine the next Id which should be used for the taskId.
                    buildEventContext = new BuildEventContext(buildEventContext.NodeId, buildEventContext.TargetId, buildEventContext.ProjectContextId, parentModule.GetNextTaskId());

		    // For each batch the engineProxy needs to have the correct buildEventContext as all messages comming from a task will have the buildEventContext of the EngineProxy.
                    engineProxy.BuildEventContext = buildEventContext;
                }

                loggingServices.LogTaskStarted(buildEventContext, TaskName, parentProjectFullFileName, projectFileOfTaskNode);

                AppDomain taskAppDomain = PrepareAppDomain();

                bool taskResult = false;

                try
                {
                    task = InstantiateTask(taskAppDomain);

                    // If task cannot be instantiated, we consider its declaration/usage to be invalid.
                    ProjectErrorUtilities.VerifyThrowInvalidProject(task != null, taskNode, "TaskDeclarationOrUsageError", TaskName);
                    taskExecutedSuccessfully = ExecuteInstantiatedTask(engineProxy, bucket, howToExecuteTask, task, out taskResult);
                    if (lookupHash != null)
                    {
                        List<string> overrideMessages = bucket.Lookup.GetPropertyOverrideMessages(lookupHash);
                        if (overrideMessages != null)
                        {
                            foreach (string s in overrideMessages)
                            {
                                loggingServices.LogCommentFromText(buildEventContext, MessageImportance.Low, s);
                            }
                        }
                    }
                }
                catch (InvalidProjectFileException e)
                {
                    // Make sure the Invalid Project error gets logged *before* TaskFinished.  Otherwise,
                    // the log is confusing.
                    loggingServices.LogInvalidProjectFileError(buildEventContext, e);
                    throw;
                }
                finally
                {
                    // Flag the completion of the task.
                    loggingServices.LogTaskFinished(
                        buildEventContext,
                        TaskName,
                        parentProjectFullFileName,
                        projectFileOfTaskNode,
                        taskResult);

                    task = null;

                    if (taskAppDomain != null)
                    {
                        AppDomain.Unload(taskAppDomain);
                        taskAppDomain = null;
                    }
                }
            }
            else
            {
                Debug.Assert(howToExecuteTask == TaskExecutionMode.InferOutputsOnly);

                ErrorUtilities.VerifyThrow(GatherTaskOutputs(howToExecuteTask, null, bucket),
                    "The method GatherTaskOutputs() should never fail when inferring task outputs.");
                if (lookupHash != null)
                {
                    List<string> overrideMessages = bucket.Lookup.GetPropertyOverrideMessages(lookupHash);
                    if (overrideMessages != null)
                    {
                        foreach (string s in overrideMessages)
                        {
                            loggingServices.LogCommentFromText(buildEventContext, MessageImportance.Low, s);
                        }
                    }
                }
            }

            return taskExecutedSuccessfully;
        }
 internal TaskExecutionStateHelper
     (
        TaskExecutionMode howToExecuteTask,
        Lookup lookupForInference,
        Lookup lookupForExecution,
        XmlElement taskXmlNode,
        ITaskHost hostObject,
        string projectFileOfTaskNode,
        string parentProjectFullFileName,
        string executionDirectory,
        int nodeProxyId
     )
     : base(howToExecuteTask,
         lookupForInference,
         lookupForExecution, 
         taskXmlNode,
         hostObject,
         projectFileOfTaskNode,
         parentProjectFullFileName,
         executionDirectory,
         nodeProxyId,
     null
     )
 {
     // Dont need to do anything
 }
Exemple #49
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;
        }
Exemple #50
0
        private WorkUnitResult ExecuteTaskInSTAThread(ItemBucket bucket, TaskLoggingContext taskLoggingContext, IDictionary<string, string> taskIdentityParameters, TaskHost taskHost, TaskExecutionMode howToExecuteTask)
        {
            WorkUnitResult taskResult = new WorkUnitResult(WorkUnitResultCode.Failed, WorkUnitActionCode.Stop, null);
            Thread staThread = null;
            Exception exceptionFromExecution = null;
            ManualResetEvent taskRunnerFinished = new ManualResetEvent(false);
            try
            {
                ThreadStart taskRunnerDelegate = delegate ()
                {
                    Lookup.Scope scope = bucket.Lookup.EnterScope("STA Thread for Task");
                    try
                    {
                        taskResult = InitializeAndExecuteTask(taskLoggingContext, bucket, taskIdentityParameters, taskHost, howToExecuteTask).Result;
                    }
                    catch (Exception e)
                    {
                        if (ExceptionHandling.IsCriticalException(e))
                        {
                            throw;
                        }

                        exceptionFromExecution = e;
                    }
                    finally
                    {
                        scope.LeaveScope();
                        taskRunnerFinished.Set();
                    }
                };

                staThread = new Thread(taskRunnerDelegate);
                staThread.SetApartmentState(ApartmentState.STA);
                staThread.Name = "MSBuild STA task runner thread";
                staThread.CurrentCulture = _componentHost.BuildParameters.Culture;
                staThread.CurrentUICulture = _componentHost.BuildParameters.UICulture;
                staThread.Start();

                // TODO: Why not just Join on the thread???
                taskRunnerFinished.WaitOne();
            }
            finally
            {
                taskRunnerFinished.Close();
                taskRunnerFinished = null;
            }

            if (exceptionFromExecution != null)
            {
                // Unfortunately this will reset the callstack
                throw exceptionFromExecution;
            }

            return taskResult;
        }