// NAnt - A .NET build tool // Copyright (C) 2002-2003 Scott Hernandez // // 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 // // Scott Hernandez (ScottHernandez@hotmail.com) // Jaroslaw Kowalski (jkowalski@users.sourceforge.net) using System; using System.Globalization; using System.IO; using NAnt.Core.Attributes; using NAnt.Core.Functions; using NAnt.Core.Types; using NAnt.Core.Util; namespace NAnt.Core.Tasks { /// /// Checks the conditional attributes and executes the children if /// . /// /// /// /// If no conditions are checked, all child tasks are executed. /// /// /// If more than one attribute is used, they are &&'d. The first /// to fail stops the check. /// /// /// The order of condition evaluation is, , /// , , /// . /// /// /// instead of using the deprecated attributes, we advise you to use the /// following functions in combination with the /// attribute: /// /// /// /// Function /// Description /// /// /// /// Checks whether the specified property exists. /// /// /// /// Checks whether the specified target exists. /// /// /// /// /// Tests the value of a property using expressions. /// /// /// Build release configuration /// /// ]]> /// /// /// /// Tests the the output of a function. /// /// /// /// /// ]]> /// /// /// /// (Deprecated) Check that a target exists. /// /// /// /// /// /// ]]> /// /// /// /// (Deprecated) Check existence of a property. /// /// /// /// /// ]]> /// /// /// /// (Deprecated) Check that a property value is true. /// /// /// /// /// ]]> /// /// /// /// /// (Deprecated) Check that a property exists and is /// (uses multiple conditions). /// /// /// /// /// /// ]]> /// /// which is the same as /// /// /// /// /// /// /// ]]> /// /// /// /// /// (Deprecated) Check file dates. If myfile.dll is uptodate, /// then do stuff. /// /// /// /// /// /// ]]> /// /// or /// /// /// /// /// /// /// /// ]]> /// /// or /// /// /// /// /// /// /// /// /// /// /// ]]> /// /// [TaskName("if")] public class IfTask : TaskContainer { #region Private Instance Fields private string _propNameTrue; private string _propNameExists; private string _targetName; private string _test; private FileSet _compareFiles; private FileSet _uptodateFiles; #endregion Private Instance Fields #region Public Instance Properties /// /// The file to compare if uptodate. /// [TaskAttribute("uptodatefile")] [System.Obsolete("Use instead.", false)] public string UpToDateFile { set { if (_uptodateFiles == null) { _uptodateFiles = new FileSet(); _uptodateFiles.Parent = this; _uptodateFiles.Project = Project; _uptodateFiles.NamespaceManager = NamespaceManager; } _uptodateFiles.Includes.Add(value); } } /// /// The file to check against for the uptodate file. /// [TaskAttribute("comparefile")] [System.Obsolete("Use instead.", false)] public string CompareFile { set { if (_compareFiles == null) { _compareFiles = new FileSet(); _compareFiles.Parent = this; _compareFiles.Project = Project; _compareFiles.NamespaceManager = NamespaceManager; } _compareFiles.Includes.Add(value); } } /// /// The that contains the comparison files for /// the (s) check. /// [BuildElement("comparefiles")] [System.Obsolete("Use task instead.", false)] public FileSet CompareFiles { get { return _compareFiles; } set { _compareFiles = value; } } /// /// The that contains the uptodate files for /// the (s) check. /// [BuildElement("uptodatefiles")] [System.Obsolete("Use task instead.", false)] public FileSet UpToDateFiles { get { return _uptodateFiles; } set { _uptodateFiles = value; } } /// /// Used to test whether a property is true. /// [TaskAttribute("propertytrue")] [System.Obsolete("Use instead.", false)] public string PropertyNameTrue { get { return _propNameTrue; } set { _propNameTrue = StringUtils.ConvertEmptyToNull(value); } } /// /// Used to test whether a property exists. /// [TaskAttribute("propertyexists")] [System.Obsolete("Use instead.", false)] public string PropertyNameExists { get { return _propNameExists;} set { _propNameExists = StringUtils.ConvertEmptyToNull(value); } } /// /// Used to test whether a target exists. /// [TaskAttribute("targetexists")] [System.Obsolete("Use instead.", false)] public string TargetNameExists { get { return _targetName; } set { _targetName = StringUtils.ConvertEmptyToNull(value); } } /// /// Used to test arbitrary boolean expression. /// [TaskAttribute("test")] [BooleanValidator()] public string Test { get { return _test; } set { _test = StringUtils.ConvertEmptyToNull(value); } } #endregion Public Instance Properties #region Protected Instance Properties protected virtual bool ConditionsTrue { get { bool ret = true; if (Test != null) { if (!Convert.ToBoolean(Test, CultureInfo.InvariantCulture)) { return false; } } // check if target exists if (TargetNameExists != null) { ret = ret && (Project.Targets.Find(TargetNameExists) != null); if (!ret) { return false; } } // check if property exists if (PropertyNameExists != null) { ret = ret && Properties.Contains(PropertyNameExists); if (!ret) { return false; } } // check if value of property is boolean true if (PropertyNameTrue != null) { try { ret = ret && bool.Parse(Properties[PropertyNameTrue]); if (!ret) { return false; } } catch (Exception ex) { throw new BuildException(string.Format(CultureInfo.InvariantCulture, ResourceUtils.GetString("NA1126"), PropertyNameTrue), Location, ex); } } // check if file is up-to-date if (UpToDateFiles != null) { FileInfo primaryFile = UpToDateFiles.MostRecentLastWriteTimeFile; if (primaryFile == null || !primaryFile.Exists) { ret = false; Log(Level.Verbose, "Uptodatefile(s) do(es) not exist."); } else { string newerFile = FileSet.FindMoreRecentLastWriteTime(_compareFiles.FileNames, primaryFile.LastWriteTime); bool needsAnUpdate = (newerFile != null); if (needsAnUpdate) { Log(Level.Verbose, "{0} is newer than {1}.", newerFile, primaryFile.Name); } ret = ret && !needsAnUpdate; } if (!ret) { return false; } } return ret; } } #endregion Protected Instance Properties #region Override implementation of TaskContainer protected override void ExecuteTask() { if (ConditionsTrue) { base.ExecuteTask(); } } #endregion Override implementation of TaskContainer #region Override implementation of Task protected override void InitializeTask(System.Xml.XmlNode taskNode) { base.InitializeTask (taskNode); //check that we have something to do. if ((UpToDateFiles == null || CompareFiles == null) && Test == null && PropertyNameExists == null && PropertyNameTrue == null && TargetNameExists == null) { throw new BuildException("At least one if condition" + " must be set (test, propertytrue, targetexists, etc...):", Location); } } #endregion Override implementation of Task } /// /// The opposite of the if task. /// /// /// Check that a property does not exist. /// /// /// /// /// ]]> /// /// Check that a property value is not true. /// /// /// /// /// ]]> /// /// /// /// Check that a target does not exist. /// /// /// /// /// ]]> /// /// [TaskName("ifnot")] [Obsolete("Use the task instead.", false)] public class IfNotTask : IfTask { #region Override implementation of IfTask protected override bool ConditionsTrue { get { return !base.ConditionsTrue; } } #endregion Override implementation of IfTask } }