internal static void UpdateProjectWithBuilder(Project p, TaskBuilder tb) { // add a true property for each task (use in build to test for task existence). // add a property for each task with the assembly location. p.Properties.AddReadOnly("nant.tasks." + tb.TaskName, Boolean.TrueString); p.Properties.AddReadOnly("nant.tasks." + tb.TaskName + ".location", tb.AssemblyFileName); }
/// <summary> /// Scans a given <see cref="Type" /> for tasks. /// </summary> /// <param name="extensionAssembly">The <see cref="ExtensionAssembly" /> containing the <see cref="Type" /> to scan.</param> /// <param name="type">The <see cref="Type" /> to scan.</param> /// <param name="task">The <see cref="Task" /> which will be used to output messages to the build log.</param> /// <returns> /// <see langword="true" /> if <paramref name="type" /> represents a /// <see cref="Task" />; otherwise, <see langword="false" />. /// </returns> private static bool ScanTypeForTasks(ExtensionAssembly extensionAssembly, Type type, Task task) { try { TaskNameAttribute taskNameAttribute = (TaskNameAttribute) Attribute.GetCustomAttribute(type, typeof(TaskNameAttribute)); if (type.IsSubclassOf(typeof(Task)) && !type.IsAbstract && taskNameAttribute != null) { task.Log(Level.Debug, string.Format(CultureInfo.InvariantCulture, ResourceUtils.GetString("String_CreatingTaskBuilder"), type.Name)); TaskBuilder tb = new TaskBuilder(extensionAssembly, type.FullName); if (TaskBuilders[tb.TaskName] == null) { task.Log(Level.Debug, string.Format(CultureInfo.InvariantCulture, ResourceUtils.GetString("String_AddingTask"), tb.TaskName, GetAssemblyLocation(tb.Assembly), tb.ClassName)); TaskBuilders.Add(tb); } // specified type represents a task return true; } else { // specified type does not represent valid task return false; } } catch { task.Log(Level.Error, "Failure scanning \"{0}\" for tasks.", type.AssemblyQualifiedName); throw; } }
// In here, we're defining a class, foo_Task, derived from our DefinedTask class. This allows us to write the bulk of the code // in real C#, rather than attempting to build it here. // This means that we have Task <- DefinedTask <- foo_Task. // We also need a module and an assembly to hold the class, so we do that, too. protected override void ExecuteTask() { AssemblyName assemblyName = new AssemblyName(); assemblyName.Name = _taskName + "_Assembly"; AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(_taskName + "_Module"); // Now we've got an assembly and a module for the task to live in, we can define the actual task class. TypeBuilder typeBuilder = moduleBuilder.DefineType(_taskName + "_Task", TypeAttributes.Public); typeBuilder.SetParent(typeof(DefinedTask)); // It needs a [TaskName] attribute. ConstructorInfo taskNameAttributeConstructor = typeof(TaskNameAttribute).GetConstructor(new Type[] { typeof(string) }); CustomAttributeBuilder taskNameAttributeBuilder = new CustomAttributeBuilder(taskNameAttributeConstructor, new object[] { _taskName }); typeBuilder.SetCustomAttribute(taskNameAttributeBuilder); // We're done. Create it. Type taskType = typeBuilder.CreateType(); // Stash the XML in our static. We'll need it in DefinedTask later. DefinedTaskDefinitions.Add(_taskName, XmlNode); // Hook that up into NAnt. TaskBuilder taskBuilder = new TaskBuilder(taskType.Assembly, taskType.FullName); TypeFactory.TaskBuilders.Add(taskBuilder); }
/// <summary> /// Creates a new <see cref="Task" /> instance for the given XML and /// <see cref="Project" />. /// </summary> /// <param name="taskNode">The XML to initialize the task with.</param> /// <param name="proj">The <see cref="Project" /> that the <see cref="Task" /> belongs to.</param> /// <param name="targetCallStack">The current target call stack. Needed for accessing thread and target properties.</param> /// <returns> /// The new <see cref="Task" /> instance. /// </returns> public static Task CreateTask(XmlNode taskNode, Project proj, TargetCallStack targetCallStack) { if (taskNode == null) { throw new ArgumentNullException("taskNode"); } if (proj == null) { throw new ArgumentNullException("proj"); } string taskName = taskNode.Name; TaskBuilder builder = TaskBuilders[taskName]; if (builder == null) { Location location = proj.LocationMap.GetLocation(taskNode); throw new BuildException(string.Format(CultureInfo.InvariantCulture, ResourceUtils.GetString("NA1083"), taskName), location); } Task task = builder.CreateTask(); task.Project = proj; task.CallStack = targetCallStack; task.NamespaceManager = proj.NamespaceManager; // check whether the task (or its base class) is deprecated ObsoleteAttribute obsoleteAttribute = (ObsoleteAttribute) Attribute.GetCustomAttribute(task.GetType(), typeof(ObsoleteAttribute), true); if (obsoleteAttribute != null) { Location location = proj.LocationMap.GetLocation(taskNode); string obsoleteMessage = string.Format(CultureInfo.InvariantCulture, ResourceUtils.GetString("NA1086"), taskName, obsoleteAttribute.Message); if (obsoleteAttribute.IsError) { throw new BuildException(obsoleteMessage, location); } else { if (targetCallStack.CurrentFrame != null && targetCallStack.CurrentFrame.TaskCallStack.CurrentFrame != null) { targetCallStack.CurrentFrame.TaskCallStack.CurrentFrame.Task.Log(Level.Warning, "{0} {1}", location, obsoleteMessage); } else { (proj as ITargetLogger).Log(Level.Warning, "{0} {1}", location, obsoleteMessage); } } } return(task); }
internal static void UpdateProjectWithBuilder(Project p, TaskBuilder tb) { // add a true property for each task (use in build to test for task existence). // add a property for each task with the assembly location. p.Properties.AddReadOnly("nant.tasks." + tb.TaskName, Boolean.TrueString); try { p.Properties.AddReadOnly("nant.tasks." + tb.TaskName + ".location", tb.Assembly.Location); } catch (NotSupportedException) { // Assembly.Location is not supported in dynamic assemblies } }
/// <summary> /// Scans a given <see cref="Type" /> for tasks. /// </summary> /// <param name="type">The <see cref="Type" /> to scan.</param> /// <param name="task">The <see cref="Task" /> which will be used to output messages to the build log.</param> /// <returns> /// <see langword="true" /> if <paramref name="type" /> represents a /// <see cref="Task" />; otherwise, <see langword="false" />. /// </returns> private static bool ScanTypeForTasks(Type type, Task task) { try { TaskNameAttribute taskNameAttribute = (TaskNameAttribute) Attribute.GetCustomAttribute(type, typeof(TaskNameAttribute)); if (type.IsSubclassOf(typeof(Task)) && !type.IsAbstract && taskNameAttribute != null) { task.Log(Level.Debug, string.Format(CultureInfo.InvariantCulture, ResourceUtils.GetString("String_CreatingTaskBuilder"), type.Name)); TaskBuilder tb = new TaskBuilder(type.Assembly, type.FullName); if (TaskBuilders[tb.TaskName] == null) { task.Log(Level.Debug, string.Format(CultureInfo.InvariantCulture, ResourceUtils.GetString("String_AddingTask"), tb.TaskName, GetAssemblyLocation(tb.Assembly), tb.ClassName)); TaskBuilders.Add(tb); foreach (WeakReference wr in _projects) { if (!wr.IsAlive) { task.Log(Level.Debug, "WeakReference for project is dead."); continue; } Project p = wr.Target as Project; if (p == null) { task.Log(Level.Debug, "WeakReference is not a" + " project! This should not be possible."); continue; } UpdateProjectWithBuilder(p, tb); } } // specified type represents a task return(true); } else { // specified type does not represent valid task return(false); } } catch { task.Log(Level.Error, "Failure scanning \"{0}\" for tasks.", type.AssemblyQualifiedName); throw; } }
/// <summary> /// Removes a member from the collection. /// </summary> /// <param name="item">The <see cref="TaskBuilder"/> to remove from the collection.</param> public void Remove(TaskBuilder item) { base.List.Remove(item); }
/// <summary> /// Inserts a <see cref="TaskBuilder"/> into the collection at the specified index. /// </summary> /// <param name="index">The zero-based index at which <paramref name="item"/> should be inserted.</param> /// <param name="item">The <see cref="TaskBuilder"/> to insert.</param> public void Insert(int index, TaskBuilder item) { base.List.Insert(index, item); }
/// <summary> /// Retrieves the index of a specified <see cref="TaskBuilder"/> object in the collection. /// </summary> /// <param name="item">The <see cref="TaskBuilder"/> object for which the index is returned.</param> /// <returns> /// The index of the specified <see cref="TaskBuilder"/>. If the <see cref="TaskBuilder"/> is not currently a member of the collection, it returns -1. /// </returns> public int IndexOf(TaskBuilder item) { return(base.List.IndexOf(item)); }
/// <summary> /// Determines whether a <see cref="TaskBuilder"/> is in the collection. /// </summary> /// <param name="item">The <see cref="TaskBuilder"/> to locate in the collection.</param> /// <returns> /// <see langword="true" /> if <paramref name="item"/> is found in the /// collection; otherwise, <see langword="false" />. /// </returns> public bool Contains(TaskBuilder item) { return(base.List.Contains(item)); }
/// <summary> /// Adds a <see cref="TaskBuilder"/> to the end of the collection. /// </summary> /// <param name="item">The <see cref="TaskBuilder"/> to be added to the end of the collection.</param> /// <returns>The position into which the new element was inserted.</returns> public int Add(TaskBuilder item) { return(base.List.Add(item)); }
/// <summary> /// Scans a given <see cref="Type" /> for tasks. /// </summary> /// <param name="type">The <see cref="Type" /> to scan.</param> /// <param name="task">The <see cref="Task" /> which will be used to output messages to the build log.</param> /// <returns> /// <see langword="true" /> if <paramref name="type" /> represents a /// <see cref="Task" />; otherwise, <see langword="false" />. /// </returns> private static bool ScanTypeForTasks(Type type, Task task) { try { TaskNameAttribute taskNameAttribute = (TaskNameAttribute) Attribute.GetCustomAttribute(type, typeof(TaskNameAttribute)); if (type.IsSubclassOf(typeof(Task)) && !type.IsAbstract && taskNameAttribute != null) { task.Log(Level.Debug, "Creating TaskBuilder for \"{0}\".", type.Name); TaskBuilder tb = new TaskBuilder(type.FullName, type.Assembly.Location); if (TaskBuilders[tb.TaskName] == null) { task.Log(Level.Debug, "Adding \"{0}\" from {1}:{2}.", tb.TaskName, tb.AssemblyFileName, tb.ClassName); TaskBuilders.Add(tb); foreach(WeakReference wr in _projects) { if (!wr.IsAlive) { task.Log(Level.Debug, "WeakReference for project is dead."); continue; } Project p = wr.Target as Project; if (p == null) { task.Log(Level.Debug, "WeakReference is not a" + " project! This should not be possible."); continue; } UpdateProjectWithBuilder(p, tb); } } // specified type represents a task return true; } else { // specified type does not represent valid task return false; } } catch { task.Log(Level.Error, "Failure scanning \"{0}\" for tasks.", type.AssemblyQualifiedName); throw; } }
/// <summary> /// Retrieves the index of a specified <see cref="TaskBuilder"/> object in the collection. /// </summary> /// <param name="item">The <see cref="TaskBuilder"/> object for which the index is returned.</param> /// <returns> /// The index of the specified <see cref="TaskBuilder"/>. If the <see cref="TaskBuilder"/> is not currently a member of the collection, it returns -1. /// </returns> public int IndexOf(TaskBuilder item) { return base.List.IndexOf(item); }
/// <summary> /// Copies the entire collection to a compatible one-dimensional array, starting at the specified index of the target array. /// </summary> /// <param name="array">The one-dimensional array that is the destination of the elements copied from the collection. The array must have zero-based indexing.</param> /// <param name="index">The zero-based index in <paramref name="array"/> at which copying begins.</param> public void CopyTo(TaskBuilder[] array, int index) { base.List.CopyTo(array, index); }
/// <summary> /// Determines whether a <see cref="TaskBuilder"/> is in the collection. /// </summary> /// <param name="item">The <see cref="TaskBuilder"/> to locate in the collection.</param> /// <returns> /// <see langword="true" /> if <paramref name="item"/> is found in the /// collection; otherwise, <see langword="false" />. /// </returns> public bool Contains(TaskBuilder item) { return base.List.Contains(item); }
/// <summary> /// Adds the elements of a <see cref="TaskBuilder"/> array to the end of the collection. /// </summary> /// <param name="items">The array of <see cref="TaskBuilder"/> elements to be added to the end of the collection.</param> public void AddRange(TaskBuilder[] items) { for (int i = 0; (i < items.Length); i = (i + 1)) { Add(items[i]); } }
/// <summary> /// Adds a <see cref="TaskBuilder"/> to the end of the collection. /// </summary> /// <param name="item">The <see cref="TaskBuilder"/> to be added to the end of the collection.</param> /// <returns>The position into which the new element was inserted.</returns> public int Add(TaskBuilder item) { return base.List.Add(item); }
/// <summary> /// Initializes a new instance of the <see cref="TaskBuilderCollection"/> class /// with the specified array of <see cref="TaskBuilder"/> instances. /// </summary> public TaskBuilderCollection(TaskBuilder[] value) { AddRange(value); }