Search code examples
nant

Writing a custom NAnt task able to use filters


I'm trying to write a custom NAnt task that does some file-based operations. One of the things that would be incredibly useful would be the ability to run the <expandproperties> filter on one of the input files.

In the interest of keeping the task suitably generic, I simply want to enable support for the <filterchain> element (similar to how the <copy> task works).

I've been using the source for the <copy> task to guide me, however I keep on running into methods that are internal when it comes to writing the tasks. I know I can use reflection to break encapsulation, but I'm reluctant to do this.

Does anyone know of any useful articles, or have any experience with this?


Solution

  • I started going down the road of creating a private Filter subclass that took a TextReader (basically re-creating the PhysicalTextReader inside the NAnt source). However I realised that, actually, there was a much easier way of reading a file through a filter chain:

    [TaskName("mytask")]
    public class MyTask : Task
    {
        /// <summary>
        /// Chain of filters used to alter the input file's content as it is read.
        /// </summary>
        [BuildElement("filterchain")]
        public FilterChain Filters { get; set; }
    
        /// <summary>
        /// The input file.
        /// </summary>
        [TaskAttribute("input")]
        public FileInfo InputFile { get; set; }
    
        protected override void ExecuteTask()
        {
            Log(FileUtils.ReadFile(InputFile.FullName, Filters, null));
        }
    }
    

    Then you can use this exactly as you would expect:

    <mytask input="foo.txt">
        <filterchain>
            <expandproperties />
        </filterchain>
    </mytask>