コード例 #1
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);
        }
コード例 #2
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);
        }