Hi Scott,

As agreed, I implemented an Available task that allows you to check for the
available of a file or directory resource.

I currently have two possible resource checks :

- File
- Directory

eg. <available type="File" resource="myfile.txt" property="myfile.present"
/>

I used "resource" instead of "file" (or "directory") for the attribute name,
so we can add more resource checks (for registry key, registry value, .NET
runtime, ....) later without having to add a attribute for each type of
check.

I would prefer to be able to use lower case values in the buildfiles, but
enum members should use Pascal casing and Nant uses a case-sensitive enum
parsing so you have to specify the values in pascal casing too in the
buildfile (should we change the behaviour to use a case-insensitive lookup
for enum members) ?

However, I don't know how the task should behave when a file or directory is
not found : should I set the specified property to false or should it not
set the property at all (this is how ant works) ?  If I don't set the
property to a value, then I don't think you can use it in the "if" and
"unless" attributes and stuff, because NAnt doesn't handle this very well
yet.

I already proposed to Ian a while ago, to consider a property, that has not
been set to a value, to have the value "false".  I know he changed this
behaviour locally, but I don't know if he committed this change already or
if he's planning to commit it anyway.

Right now, I set the specified property to true or false depending on
whether the resource is available or not.

I included the source for the AvailableTask and the test class, but let me
know if you want me to change the behaviour.

Thanks,

Gert
// NAnt - A .NET build tool
// Copyright (C) 2002 Scott Hernandez ([EMAIL PROTECTED])
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// Gert Driesen ([EMAIL PROTECTED])

using System;
using System.IO;
using System.Globalization;

using NUnit.Framework;
using SourceForge.NAnt.Tasks;
//using SourceForge.NAnt.Attributes;

namespace SourceForge.NAnt.Tests {
    /// <summary>
    /// Tests available Task.
    /// </summary>
    [TestFixture]
    public class AvailableTest : BuildTestBase {

        [SetUp]
        protected override void SetUp() {
            base.SetUp();
            tempFile = CreateTempFile("a.b");
            tempDir = CreateTempDir("foo");

            // create a temporary file
            notExistingTempFile = CreateTempFile("b.c");
            // delete it to make sure it definitely not exists
            if (notExistingTempFile != null && File.Exists(notExistingTempFile)) {
                File.Delete(notExistingTempFile);
            }

            // create a temporary directory
            notExistingTempDir = CreateTempDir("test");
            // delete it to make sure it definitely not exists
            if (notExistingTempDir != null && Directory.Exists(notExistingTempDir)) {
                Directory.Delete(notExistingTempDir);
            }
        }

        [TearDown]
        protected override void TearDown() {
            base.TearDown();

            if (tempFile != null && File.Exists(tempFile)) {
                File.Delete(tempFile);
            }

            if (tempDir != null && Directory.Exists(tempDir)) {
                Directory.Delete(tempDir);
            }

            if (notExistingTempFile != null && File.Exists(notExistingTempFile)) {
                File.Delete(notExistingTempFile);
            }

            if (notExistingTempDir != null && Directory.Exists(notExistingTempDir)) {
                Directory.Delete(notExistingTempDir);
            }
        }

        [Test]
        public void Test_ExistingFile() {
            string _xml= @"
            <project>
                <available type='{0}' resource='{1}' property='file.exists'/>
                <echo message='file.exists={2}'/>
            </project>";
            
            string result = RunBuild(String.Format(CultureInfo.InvariantCulture, _xml, 
AvailableTask.ResourceType.File.ToString(CultureInfo.InvariantCulture), tempFile, 
"${file.exists}"));
            
            Assertion.Assert("File resource should have existed:" + result, 
result.ToLower().IndexOf("file.exists=true") != -1);
        }

        [Test]
        public void Test_NotExistingFile() {
            string _xml= @"
            <project>
                <available type='{0}' resource='{1}' property='file.exists'/>
                <echo message='file.exists={2}'/>
            </project>";
            
            string result = RunBuild(String.Format(CultureInfo.InvariantCulture, _xml, 
AvailableTask.ResourceType.File.ToString(CultureInfo.InvariantCulture), 
notExistingTempFile, "${file.exists}"));
            
            Assertion.Assert("File resource not should have existed:" + result, 
result.ToLower().IndexOf("file.exists=false") != -1);
        }

        [Test]
        public void Test_InvalidFile() {
            string _xml= @"
            <project>
                <available type='{0}' resource='{1}' property='file.exists'/>
                <echo message='file.exists={2}'/>
            </project>";
            
            string result = RunBuild(String.Format(CultureInfo.InvariantCulture, _xml, 
AvailableTask.ResourceType.Directory.ToString(CultureInfo.InvariantCulture), 
@"\\#(){/}.dddd", "${file.exists}"));
            
            Assertion.Assert("File resource not should have existed:" + result, 
result.ToLower().IndexOf("file.exists=false") != -1);
        }

        [Test]
        public void Test_ExistingDirectory() {
            string _xml= @"
            <project>
                <available type='{0}' resource='{1}' property='dir.exists'/>
                <echo message='dir.exists={2}'/>
            </project>";
            
            string result = RunBuild(String.Format(CultureInfo.InvariantCulture, _xml, 
AvailableTask.ResourceType.Directory.ToString(CultureInfo.InvariantCulture), tempDir, 
"${dir.exists}"));
            
            Assertion.Assert("Directtory resource should have existed:" + result, 
result.ToLower().IndexOf("dir.exists=true") != -1);
        }

        [Test]
        public void Test_NotExistingDirectory() {
            string _xml= @"
            <project>
                <available type='{0}' resource='{1}' property='dir.exists'/>
                <echo message='dir.exists={2}'/>
            </project>";
            
            string result = RunBuild(String.Format(CultureInfo.InvariantCulture, _xml, 
AvailableTask.ResourceType.Directory.ToString(CultureInfo.InvariantCulture), 
notExistingTempDir, "${dir.exists}"));
            
            Assertion.Assert("Directory resource not should have existed:" + result, 
result.ToLower().IndexOf("dir.exists=false") != -1);
        }

        [Test]
        public void Test_InvalidDirectory() {
            string _xml= @"
            <project>
                <available type='{0}' resource='{1}' property='dir.exists'/>
                <echo message='dir.exists={2}'/>
            </project>";
            
            string result = RunBuild(String.Format(CultureInfo.InvariantCulture, _xml, 
AvailableTask.ResourceType.Directory.ToString(CultureInfo.InvariantCulture), "#(){/}", 
"${dir.exists}"));
            
            Assertion.Assert("Directory resource not should have existed:" + result, 
result.ToLower().IndexOf("dir.exists=false") != -1);
        }

        [Test]
        [ExpectedException(typeof(BuildException))]
        public void Test_InvalidResourceType() {
            string _xml= @"
            <project>
                <available type='{0}' resource='{1}' property='file.exists'/>
                <echo message='file.exists={2}'/>
            </project>";
            
            string result = RunBuild(String.Format(CultureInfo.InvariantCulture, _xml, 
"InvalidResourceType", @"\\#(){/}.dddd", "${file.exists}"));

            Assertion.Fail("A buildexception should have been thrown because of the 
invalid resource type:" + result);
        }

        #region Private Instance Fields

        string tempFile;
        string tempDir;
        string notExistingTempFile;
        string notExistingTempDir;

        #endregion Private Instance Fields
    }
}
// NAnt - A .NET build tool
// Copyright (C) 2001-2002 Gerry Shaw
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// Gerry Shaw ([EMAIL PROTECTED])
// Gert Driesen ([EMAIL PROTECTED])

using System;
using System.IO;
using System.Globalization;

using SourceForge.NAnt.Attributes;

namespace SourceForge.NAnt.Tasks {

    /// <summary>
    /// Sets the given property to <c>true</c> if the requested resource is available 
    /// at runtime, and <c>false</c> if the resource is not available.</summary>
    /// <example>
    ///   <para>
    ///   Sets the <c>myfile.present</c> property to <c>true</c> if the file is 
    ///   available on the filesystem and <c>false</c> if the file is not available.
    ///   </para>
    ///   <code>
    ///     <![CDATA[
    /// <available type="File" resource="myfile.txt" property="myfile.present" />
    ///     ]]>
    ///   </code>
    ///   <para>
    ///   Sets the <c>build.dir.present</c> property to <c>true</c> if the directory 
    ///   is available on the filesystem and <c>false</c> if the directory is not
    ///   available..
    ///   </para>
    ///   <code>
    ///     <![CDATA[
    /// <available type="Directory" resource="build" property="build.dir.present" />
    ///     ]]>
    ///   </code>
    /// </example>
    [TaskName("available")]
    public class AvailableTask : Task {

        public enum ResourceType : int {
            File = 1,
            Directory = 2
        }

        #region Public Instance Properties

        /// <summary>The resource which must be available.</summary>
        [TaskAttribute("resource", Required=true)]
        public string Resource          { get { return _resource; } set {_resource = 
value; } }

        /// <summary>The type of resource which must be present - either <c>File</c> 
or <c>Directory</c>.</summary>
        [TaskAttribute("type", Required=true)]
        public ResourceType Type { 
            get { return _resourceType; }
            set {
                if (!Enum.IsDefined(typeof(ResourceType), value)) {
                    throw new 
ArgumentException(string.Format(CultureInfo.InvariantCulture, "An invalid type {0} was 
specified.", value)); 
                } else {
                    this._resourceType = value;
                }
            } 
        }

        /// <summary>The property that must be set if the resource is 
available.</summary>
        [TaskAttribute("property", Required=true)]
        public string PropertyName      { get { return _propertyName; } set 
{_propertyName = value; } }

        #endregion Public Instance Properties

        #region Override implementation of Task

        /// <summary>
        /// Executes the Available task.
        /// </summary>
        /// <remarks>
        /// Sets the property identifier by <see cref="PropertyName" /> to <c>true</c>
        /// when the resource exists and to <c>false</c> when the resource doesn't 
exist.
        /// </remarks>
        /// <exception cref="BuildException">The availability of the resource could 
not be evaluated.</exception>
        protected override void ExecuteTask() {
            Project.Properties[PropertyName] = 
Evaluate().ToString(CultureInfo.InvariantCulture);
        }

        #endregion Override implementation of Task

        #region Protected Instance Methods

        /// <summary>
        /// Evaluates the availability of a resource.
        /// </summary>
        /// <returns><c>true</c> if the resource is available, <c>false</c> 
otrherwise</returns>
        /// <exception cref="BuildException">The availability of the resource could 
not be evaluated.</exception>
        protected virtual bool Evaluate() {
            bool resourceAvailable = false;

            try {
                if (Type == ResourceType.File) {
                    // check if specified file is available on filesystem
                    FileInfo fileInfo = new FileInfo(Project.GetFullPath(Resource));
                    if (fileInfo.Exists) {
                        resourceAvailable = true;
                    } else {
                        Log.WriteIf(Verbose, "Unable to find " + Type + " " + 
Resource);
                        resourceAvailable = false;
                    }
                } else if (Type == ResourceType.Directory) {
                    // check if specified directory is available on filesystem
                    DirectoryInfo dirInfo = new 
DirectoryInfo(Project.GetFullPath(Resource));
                    if (dirInfo.Exists) {
                        resourceAvailable = true;
                    } else {
                        Log.WriteIf(Verbose, "Unable to find " + Type + " " + 
Resource);
                        resourceAvailable = false;
                    }
                }
                return resourceAvailable;
            } catch (Exception e) {
                string message = string.Format(CultureInfo.InvariantCulture, "Unable 
to check if {0} resource {1} is available.", Type, Resource);
                throw new BuildException(message, Location, e);
            }
        }

        #endregion Protected Instance Methods

        #region Private Instance Fields

        ResourceType _resourceType;
        string _resource = null;
        string _propertyName = null;

        #endregion
    }
}

Reply via email to