Ejemplo n.º 1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="FileExpressionBase"/> class.
        /// </summary>
        /// <param name="rawExpression">An unprocessed string for a single expression.</param>
        /// <param name="project">The project where the expression exists.</param>
        /// <param name="task">The task where the expression exists.</param>
        protected FileExpressionBase(string rawExpression, ProjectInstance project, ProjectTaskInstance task = null)
        {
            string trimmedExpression = rawExpression.Trim();

            if (task != null)
            {
                string copyTaskFilePath = task.Location.File;

                // Process MsBuildThis* macros
                // ignore copy tasks within the proj - evaluation will just work.
                if (!copyTaskFilePath.Equals(project.FullPath, StringComparison.OrdinalIgnoreCase))
                {
                    // We leave off the trailing ')' to allow for macro operations. This could allow us to misdetect macros
                    // (e.g. $(MsBuildThisFileButNotReally), but should be rare and should still function correctly even if we
                    // do.
                    if (trimmedExpression.IndexOf("$(MSBuildThisFile", StringComparison.OrdinalIgnoreCase) >= 0)
                    {
#pragma warning disable CA1308 // Normalize strings to uppercase
                        trimmedExpression = trimmedExpression.ToLowerInvariant();
#pragma warning restore CA1308 // Normalize strings to uppercase
                        trimmedExpression = trimmedExpression.Replace("$(msbuildthisfiledirectory)", Path.GetDirectoryName(copyTaskFilePath) + "\\");
                        trimmedExpression = trimmedExpression.Replace("$(msbuildthisfile)", Path.GetFileName(copyTaskFilePath));
                        trimmedExpression = trimmedExpression.Replace("$(msbuildthisfileextension)", Path.GetExtension(copyTaskFilePath));
                        trimmedExpression = trimmedExpression.Replace("$(msbuildthisfilefullpath)", copyTaskFilePath);
                        trimmedExpression = trimmedExpression.Replace("$(msbuildthisfilename)", Path.GetFileNameWithoutExtension(copyTaskFilePath));
                    }
                }
            }

            ProcessedExpression = trimmedExpression;
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="FileExpressionList"/> class.
        /// </summary>
        /// <param name="rawFileListString">The unprocessed list of file expressions.</param>
        /// <param name="project">The project where the expression list exists.</param>
        /// <param name="task">The task where the expression list exists.</param>
        public FileExpressionList(string rawFileListString, ProjectInstance project, ProjectTaskInstance task)
        {
            IList <string> expressions = rawFileListString.SplitStringList();
            var            seenFiles   = new HashSet <string>(PathComparer.Instance);

            foreach (string expression in expressions)
            {
                FileExpressionBase parsedExpression = FileExpressionFactory.ParseExpression(expression, project, task);
                Expressions.Add(parsedExpression);

                foreach (string file in parsedExpression.EvaluatedFiles)
                {
                    if (string.IsNullOrWhiteSpace(file))
                    {
                        continue;
                    }

                    if (seenFiles.Add(file))
                    {
                        DedupedFiles.Add(file);
                    }

                    AllFiles.Add(file);
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="FileExpressionLiteral"/> class.
        /// </summary>
        /// <param name="rawExpression">An unprocessed string for a single expression.</param>
        /// <param name="project">The project where the expression exists.</param>
        /// <param name="task">The task where the expression exists.</param>
        public FileExpressionLiteral(string rawExpression, ProjectInstance project, ProjectTaskInstance task = null)
            : base(rawExpression, project, task)
        {
            string expandedFileListString = project.ExpandString(ProcessedExpression);

            EvaluatedFiles = expandedFileListString.SplitStringList();
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="FileExpressionList"/> class.
        /// </summary>
        /// <param name="rawFileListString">The unprocessed list of file expressions.</param>
        /// <param name="project">The project where the expression list exists.</param>
        /// <param name="task">The task where the expression list exists.</param>
        public FileExpressionList(string rawFileListString, ProjectInstance project, ProjectTaskInstance task)
        {
            List <string> expressions = rawFileListString.SplitStringList();

            NumExpressions = expressions.Count;

            var seenFiles = new HashSet <string>(PathComparer.Instance);

            foreach (string expression in expressions)
            {
                List <string> evaluatedFiles = FileExpression.EvaluateExpression(expression, project, task, out bool isBatched);
                if (isBatched)
                {
                    NumBatchExpressions++;
                }

                foreach (string file in evaluatedFiles)
                {
                    if (string.IsNullOrWhiteSpace(file))
                    {
                        continue;
                    }

                    if (seenFiles.Add(file))
                    {
                        DedupedFiles.Add(file);
                    }

                    AllFiles.Add(file);
                }
            }
        }
        /// <summary>
        /// Evaluates file expressions, which are MSBuild expressions that
        /// evaluate to a list of files (e.g. @(Compile -> '%(filename)') or %(None.filename)).
        /// <param name="expression">An unprocessed string for a single expression.</param>
        /// <param name="project">The project where the expression exists.</param>
        /// <param name="task">The task where the expression exists.</param>
        /// <returns>the set of all files in the evaluated expression.</returns>
        public static List <string> EvaluateExpression(
            string expression,
            ProjectInstance project,
            ProjectTaskInstance task,
            out bool isBatched)
        {
            expression = expression.Trim();

            isBatched = !expression.StartsWith("@(", StringComparison.Ordinal) && // This would make it a transform expression instead of a batched expression
                        expression.IndexOf("%(", StringComparison.Ordinal) >= 0;
            return(isBatched
                ? EvaluateBatchedExpression(expression, project, task)
                : EvaluateLiteralExpression(expression, project, task));
        }
Ejemplo n.º 6
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)));
        }
Ejemplo n.º 7
0
        private static ProjectTaskInstance GetTaskInstance(string taskXmlString)
        {
            string content = @"
                    <Project>
                        <Target Name='t'>
                            " + taskXmlString + @"
                        </Target>
                    </Project>
                ";

            ProjectRootElement  xml      = ProjectRootElement.Create(XmlReader.Create(new StringReader(content)));
            Project             project  = new Project(xml);
            ProjectInstance     instance = project.CreateProjectInstance();
            ProjectTaskInstance task     = (ProjectTaskInstance)(instance.Targets["t"].Children[0]);

            return(task);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Return a task instance representing the task XML string passed in
        /// </summary>
        private static ProjectTaskInstance GetTaskInstance(string taskXmlString)
        {
            string content = @"
                    <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' >
                        <Target Name='t'>
                            " + taskXmlString + @"
                        </Target>
                    </Project>
                ";

            ProjectRootElement  xml      = ProjectRootElement.Create(XmlReader.Create(new StringReader(content)));
            Project             project  = new Project(xml);
            ProjectInstance     instance = project.CreateProjectInstance();
            ProjectTaskInstance task     = (ProjectTaskInstance)(instance.Targets["t"].Children[0]);

            return(task);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Constructs a task logging context from a parent target context and a task node.
        /// </summary>
        internal TaskLoggingContext(TargetLoggingContext targetLoggingContext, string projectFullPath, ProjectTargetInstanceChild task)
            : base(targetLoggingContext)
        {
            _targetLoggingContext = targetLoggingContext;
            _task = task;

            ProjectTaskInstance taskInstance = task as ProjectTaskInstance;

            if (taskInstance != null)
            {
                _taskName = taskInstance.Name;
            }
            else
            {
                ProjectPropertyGroupTaskInstance propertyGroupInstance = task as ProjectPropertyGroupTaskInstance;
                if (propertyGroupInstance != null)
                {
                    _taskName = "PropertyGroup";
                }
                else
                {
                    ProjectItemGroupTaskInstance itemGroupInstance = task as ProjectItemGroupTaskInstance;
                    if (itemGroupInstance != null)
                    {
                        _taskName = "ItemGroup";
                    }
                    else
                    {
                        _taskName = "Unknown";
                    }
                }
            }

            this.BuildEventContext = LoggingService.LogTaskStarted2
                                     (
                targetLoggingContext.BuildEventContext,
                _taskName,
                projectFullPath,
                task.Location.File,
                task.Location.Line,
                task.Location.Column
                                     );
            this.IsValid = true;
        }
Ejemplo n.º 10
0
        public void ProjectTaskInstanceCanSerializeViaTranslator(
            IDictionary <string, Tuple <string, MockElementLocation> > parameters,
            List <ProjectTaskInstanceChild> outputs)
        {
            parameters = parameters ?? new Dictionary <string, Tuple <string, MockElementLocation> >();

            var parametersCopy = new Dictionary <string, Tuple <string, ElementLocation> >(parameters.Count);

            foreach (var param in parameters)
            {
                parametersCopy[param.Key] = Tuple.Create(param.Value.Item1, (ElementLocation)param.Value.Item2);
            }

            var original = CreateTargetTask(null, parametersCopy, outputs);

            ((INodePacketTranslatable)original).Translate(TranslationHelpers.GetWriteTranslator());
            var copy = ProjectTaskInstance.FactoryForDeserialization(TranslationHelpers.GetReadTranslator());

            Assert.Equal(original, copy, new TargetTaskComparer());
        }
        private static ProjectTaskOutputPropertyInstance GetSampleTaskOutputInstance()
        {
            string content = @"
                    <Project>
                       <Target Name='t'>
                            <t1>
                                <Output TaskParameter='p' Condition='c' PropertyName='p1'/>
                            </t1>
                        </Target>
                    </Project>
                ";

            ProjectRootElement  xml                  = ProjectRootElement.Create(XmlReader.Create(new StringReader(content)));
            Project             project              = new Project(xml);
            ProjectInstance     instance             = project.CreateProjectInstance();
            ProjectTaskInstance task                 = (ProjectTaskInstance)instance.Targets["t"].Children[0];
            ProjectTaskOutputPropertyInstance output = (ProjectTaskOutputPropertyInstance)task.Outputs[0];

            return(output);
        }
        /// <summary>
        /// Create a TaskInstance with some parameters
        /// </summary>
        private static ProjectTaskOutputItemInstance GetSampleTaskOutputInstance()
        {
            string content = @"
                    <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' >
                       <Target Name='t'>
                            <t1>
                                <Output TaskParameter='p' Condition='c' ItemName='i'/>
                            </t1>
                        </Target>
                    </Project>
                ";

            ProjectRootElement            xml      = ProjectRootElement.Create(XmlReader.Create(new StringReader(content)));
            Project                       project  = new Project(xml);
            ProjectInstance               instance = project.CreateProjectInstance();
            ProjectTaskInstance           task     = (ProjectTaskInstance)instance.Targets["t"].Children[0];
            ProjectTaskOutputItemInstance output   = (ProjectTaskOutputItemInstance)task.Outputs[0];

            return(output);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Simulates executing a task. Execution time simulation is rounded to the closes numeric value. If this value is less than 1000 than nothing happens.
        /// </summary>
        public Task <WorkUnitResult> ExecuteTask(TargetLoggingContext targetLoggingContext, BuildRequestEntry requestEntry, ITargetBuilderCallback targetBuilderCallback, ProjectTargetInstanceChild task, TaskExecutionMode mode, Lookup lookupForInference, Lookup lookupForExecution, CancellationToken cancellationToken)
        {
            bool cancelled = false;
            RequestDefinition   testDefinition   = _testDataProvider[requestEntry.Request.ConfigurationId];
            TargetDefinition    targetDefinition = testDefinition.ProjectDefinition.TargetsCollection[targetLoggingContext.Target.Name];
            ProjectTaskInstance taskInstance     = (ProjectTaskInstance)task as ProjectTaskInstance;
            TaskDefinition      taskDefinition   = targetDefinition.TasksCollection[taskInstance.Name];

            taskDefinition.SignalTaskStarted();

            if (testDefinition.ExecutionTime > 1000)
            {
                DateTime startTime = DateTime.Now;
                long     executionTimeInSeconds = testDefinition.ExecutionTime / 1000;

                while (executionTimeInSeconds > 0)
                {
                    if (cancellationToken.WaitHandle.WaitOne(1, false) == true)
                    {
                        cancelled = true;
                        break;
                    }

                    Thread.Sleep(1000);
                    executionTimeInSeconds -= 1;
                }
            }

            if (!cancelled)
            {
                _result = taskDefinition.ExpectedResult;
            }
            else
            {
                _result = new WorkUnitResult(WorkUnitResultCode.Canceled, WorkUnitActionCode.Stop, new MockTaskBuilderException());
            }

            taskDefinition.SignalTaskCompleted();
            _taskDone.Set();
            return(Task <BuildResult> .FromResult(_result));
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Initializes a new instance of the <see cref="FileExpressionBatched"/> class.
        /// </summary>
        /// <param name="rawExpression">An unprocessed string for a single expression.</param>
        /// <param name="project">The project where the expression exists.</param>
        /// <param name="task">The task where the expression exists.</param>
        public FileExpressionBatched(string rawExpression, ProjectInstance project, ProjectTaskInstance task = null)
            : base(rawExpression, project, task)
        {
            // Copy task has batching in it. Get the batched items if possible, then parse inputs.
            Match regexMatch = BatchedItemRegex.Match(ProcessedExpression);

            if (regexMatch.Success)
            {
                // If the user didn't specify a metadata item, then we default to Identity
                string transformItem =
                    string.IsNullOrEmpty(regexMatch.Groups[2].Value) ?
                    BatchedItemRegex.Replace(ProcessedExpression, @"%(Identity)") :
                    BatchedItemRegex.Replace(ProcessedExpression, @"%($2)");

                // Convert the batch into a transform. If this is an item -> metadata based transition then it will do the replacements for you.
                string expandedString = project.ExpandString(
                    $"@({regexMatch.Groups["ItemType"].Value}-> '{transformItem}')");
                EvaluatedFiles = expandedString.SplitStringList();
            }
            else
            {
                throw new InvalidOperationException();
            }
        }
Ejemplo n.º 15
0
 /// <summary>
 /// Initializes a new instance of the <see cref="FileExpressionTransform"/> class.
 /// </summary>
 /// <param name="rawExpression">An unprocessed string for a single expression.</param>
 /// <param name="project">The project where the expression exists.</param>
 /// <param name="task">The task where the expression exists.</param>
 public FileExpressionTransform(string rawExpression, ProjectInstance project, ProjectTaskInstance task = null)
     : base(rawExpression, project, task)
 {
 }
 /// <summary>
 /// Evaluates a literal expression, e.g. '$(Outdir)\foo.dll'.
 /// </summary>
 /// <param name="expression">An unprocessed string for a single expression.</param>
 /// <param name="project">The project where the expression exists.</param>
 /// <param name="task">The task where the expression exists.</param>
 /// <returns>The set of all files in the evaluated expression.</returns>
 private static List <string> EvaluateLiteralExpression(string expression, ProjectInstance project, ProjectTaskInstance task)
 {
     expression = ProcessExpression(expression, project, task);
     expression = project.ExpandString(expression);
     return(expression.SplitStringList());
 }
Ejemplo n.º 17
0
        /// <summary>
        /// Factory method that parses an unprocessed Expression string and returns an Expression
        /// of the appropriate type.
        /// </summary>
        /// <param name="rawExpression">An unprocessed string for a single expression.</param>
        /// <param name="project">The project where the expression exists.</param>
        /// <param name="task">The task where the expression exists.</param>
        /// <returns>A file expression class.</returns>
        public static FileExpressionBase ParseExpression(string rawExpression, ProjectInstance project, ProjectTaskInstance task)
        {
            string trimmedExpression = rawExpression.Trim();

            if (FileExpressionBatched.IsExpression(trimmedExpression))
            {
                return(new FileExpressionBatched(rawExpression, project, task));
            }

            if (FileExpressionTransform.IsExpression(rawExpression))
            {
                return(new FileExpressionTransform(trimmedExpression, project, task));
            }

            return(new FileExpressionLiteral(rawExpression, project, task));
        }
Ejemplo n.º 18
0
        // FIXME: Exception should be caught at caller site.
        bool DoBuildTarget(ProjectTargetInstance target, TargetResult targetResult, InternalBuildArguments args)
        {
            var request = submission.BuildRequest;

            // Here we check cancellation (only after TargetStarted event).
            if (args.CheckCancel())
            {
                targetResult.Failure(new BuildAbortedException("Build has canceled"));
                return(false);
            }

            try {
                foreach (var child in target.Children)
                {
                    // Evaluate additional target properties
                    var tp = child as ProjectPropertyGroupTaskInstance;
                    if (tp != null)
                    {
                        if (!args.Project.EvaluateCondition(tp.Condition))
                        {
                            continue;
                        }
                        foreach (var p in tp.Properties)
                        {
                            if (!args.Project.EvaluateCondition(p.Condition))
                            {
                                continue;
                            }
                            var value = args.Project.ExpandString(p.Value);
                            project.SetProperty(p.Name, value);
                        }
                        continue;
                    }

                    var ii = child as ProjectItemGroupTaskInstance;
                    if (ii != null)
                    {
                        if (!args.Project.EvaluateCondition(ii.Condition))
                        {
                            continue;
                        }
                        foreach (var item in ii.Items)
                        {
                            if (!args.Project.EvaluateCondition(item.Condition))
                            {
                                continue;
                            }
                            project.AddItem(item.ItemType, project.ExpandString(item.Include));
                        }
                        continue;
                    }

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

                    var onError = child as ProjectOnErrorInstance;
                    if (onError != null)
                    {
                        continue;                         // evaluated under catch clause.
                    }
                    throw new NotSupportedException(string.Format("Unexpected Target element children \"{0}\"", child.GetType()));
                }
            } catch (Exception ex) {
                // fallback task specified by OnError element
                foreach (var c in target.Children.OfType <ProjectOnErrorInstance> ())
                {
                    if (!args.Project.EvaluateCondition(c.Condition))
                    {
                        continue;
                    }
                    foreach (var fallbackTarget in project.ExpandString(c.ExecuteTargets).Split(';'))
                    {
                        BuildTargetByName(fallbackTarget, args);
                    }
                }
                int line = target.Location != null ? target.Location.Line : 0;
                int col  = target.Location != null ? target.Location.Column : 0;
                LogErrorEvent(new BuildErrorEventArgs(null, null, target.FullPath, line, col, 0, 0, ex.Message, null, null));
                targetResult.Failure(ex);
                return(false);
            }
            return(true);
        }
Ejemplo n.º 19
0
        bool RunBuildTask(ProjectTargetInstance target, ProjectTaskInstance taskInstance, TargetResult targetResult, InternalBuildArguments args)
        {
            var request = submission.BuildRequest;

            var host = request.HostServices == null ? null : request.HostServices.GetHostObject(request.ProjectFullPath, target.Name, taskInstance.Name);

            // Create Task instance.
            var factoryIdentityParameters = new Dictionary <string, string> ();

            factoryIdentityParameters ["MSBuildRuntime"]      = taskInstance.MSBuildRuntime;
            factoryIdentityParameters ["MSBuildArchitecture"] = taskInstance.MSBuildArchitecture;
            var task = args.BuildTaskFactory.CreateTask(taskInstance.Name, factoryIdentityParameters, this);

            if (task == null)
            {
                throw new InvalidOperationException(string.Format("TaskFactory {0} returned null Task", args.BuildTaskFactory));
            }
            LogMessageEvent(new BuildMessageEventArgs(string.Format("Using task {0} from {1}", taskInstance.Name, task.GetType()), null, null, MessageImportance.Low));
            task.HostObject  = host;
            task.BuildEngine = this;

            // Prepare task parameters.
            var evaluator           = new ExpressionEvaluator(project);
            var evaluatedTaskParams = taskInstance.Parameters.Select(p => new KeyValuePair <string, string> (p.Key, project.ExpandString(evaluator, p.Value)));

            var requiredProps = task.GetType().GetProperties()
                                .Where(p => p.CanWrite && p.GetCustomAttributes(typeof(RequiredAttribute), true).Any());
            var missings = requiredProps.Where(p => !evaluatedTaskParams.Any(tp => tp.Key.Equals(p.Name, StringComparison.OrdinalIgnoreCase)));

            if (missings.Any())
            {
                throw new InvalidOperationException(string.Format("Task {0} of type {1} is used without specifying mandatory property: {2}",
                                                                  taskInstance.Name, task.GetType(), string.Join(", ", missings.Select(p => p.Name).ToArray())));
            }

            foreach (var p in evaluatedTaskParams)
            {
                switch (p.Key.ToLower())
                {
                case "condition":
                case "continueonerror":
                    continue;
                }
                var prop = task.GetType().GetProperty(p.Key);
                if (prop == null)
                {
                    throw new InvalidOperationException(string.Format("Task {0} does not have property {1}", taskInstance.Name, p.Key));
                }
                if (!prop.CanWrite)
                {
                    throw new InvalidOperationException(string.Format("Task {0} has property {1} but it is read-only.", taskInstance.Name, p.Key));
                }
                if (string.IsNullOrEmpty(p.Value) && !requiredProps.Contains(prop))
                {
                    continue;
                }
                try {
                    prop.SetValue(task, ConvertTo(p.Value, prop.PropertyType, evaluator), null);
                } catch (Exception ex) {
                    throw new InvalidOperationException(string.Format("Failed to convert '{0}' for property '{1}' of type {2}", p.Value, prop.Name, prop.PropertyType), ex);
                }
            }

            // Do execute task.
            bool taskSuccess = false;

            event_source.FireTaskStarted(this, new TaskStartedEventArgs("Task Started", null, project.FullPath, taskInstance.FullPath, taskInstance.Name));
            try {
                taskSuccess = task.Execute();

                if (!taskSuccess)
                {
                    targetResult.Failure(null);
                    if (!ContinueOnError)
                    {
                        return(false);
                    }
                }
                else
                {
                    // Evaluate task output properties and items.
                    foreach (var to in taskInstance.Outputs)
                    {
                        if (!project.EvaluateCondition(to.Condition))
                        {
                            continue;
                        }
                        var    toItem        = to as ProjectTaskOutputItemInstance;
                        var    toProp        = to as ProjectTaskOutputPropertyInstance;
                        string taskParameter = toItem != null ? toItem.TaskParameter : toProp.TaskParameter;
                        var    pi            = task.GetType().GetProperty(taskParameter);
                        if (pi == null)
                        {
                            throw new InvalidOperationException(string.Format("Task {0} does not have property {1} specified as TaskParameter", taskInstance.Name, toItem.TaskParameter));
                        }
                        if (!pi.CanRead)
                        {
                            throw new InvalidOperationException(string.Format("Task {0} has property {1} specified as TaskParameter, but it is write-only", taskInstance.Name, toItem.TaskParameter));
                        }
                        var value       = pi.GetValue(task, null);
                        var valueString = ConvertFrom(value);
                        if (toItem != null)
                        {
                            LogMessageEvent(new BuildMessageEventArgs(string.Format("Output Item {0} from TaskParameter {1}: {2}", toItem.ItemType, toItem.TaskParameter, valueString), null, null, MessageImportance.Low));
                            Action <ITaskItem> addItem = i => {
                                var metadata = new ArrayList(i.MetadataNames).ToArray().Cast <string> ().Select(n => new KeyValuePair <string, string> (n, i.GetMetadata(n)));
                                args.Project.AddItem(toItem.ItemType, i.ItemSpec, metadata);
                            };
                            var taskItemArray = value as ITaskItem [];
                            if (taskItemArray != null)
                            {
                                foreach (var ti in taskItemArray)
                                {
                                    addItem(ti);
                                }
                            }
                            else
                            {
                                var taskItem = value as ITaskItem;
                                if (taskItem != null)
                                {
                                    addItem(taskItem);
                                }
                                else
                                {
                                    foreach (var item in valueString.Split(';'))
                                    {
                                        args.Project.AddItem(toItem.ItemType, item);
                                    }
                                }
                            }
                        }
                        else
                        {
                            LogMessageEvent(new BuildMessageEventArgs(string.Format("Output Property {0} from TaskParameter {1}: {2}", toProp.PropertyName, toProp.TaskParameter, valueString), null, null, MessageImportance.Low));
                            args.Project.SetProperty(toProp.PropertyName, valueString);
                        }
                    }
                }
            } finally {
                event_source.FireTaskFinished(this, new TaskFinishedEventArgs("Task Finished", null, project.FullPath, taskInstance.FullPath, taskInstance.Name, taskSuccess));
            }
            return(true);
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Create a TaskInstance with some parameters
        /// </summary>
        private static ProjectTaskInstance GetSampleTaskInstance()
        {
            ProjectTaskInstance task = GetTaskInstance(@"<t1 a='a1' b='b1' ContinueOnError='coe' Condition='c'/>");

            return(task);
        }