// 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 // // Jay Turpin (jayturpin@hotmail.com) // Gerry Shaw (gerry_shaw@yahoo.com) using System; using System.IO; using System.Globalization; using NAnt.Core.Attributes; using NAnt.Core.Types; using NAnt.Core.Util; namespace NAnt.Core.Tasks { /// /// Touches a file or set of files -- corresponds to the Unix touch command. /// /// /// /// If the file specified does not exist, the task will create it. /// /// /// /// Touch the Main.cs file. The current time is used. /// /// /// ]]> /// /// /// /// /// Touch all executable files in the project base directory and its /// subdirectories. /// /// /// /// /// /// /// /// /// ]]> /// /// [TaskName("touch")] public class TouchTask : Task { #region Private Instance Fields private FileInfo _file; private long _millis; private DateTime _datetime; private FileSet _fileset = new FileSet(); #endregion Private Instance Fields #region Public Instance Properties /// /// The file to touch. /// [TaskAttribute("file")] public FileInfo File { get { return _file; } set { _file = value; } } /// /// Specifies the new modification time of the file(s) in milliseconds /// since midnight Jan 1 1970. /// [TaskAttribute("millis")] public long Millis { get { return _millis; } set { _millis = value; } } /// /// Specifies the new modification time of the file in the format /// MM/DD/YYYY HH:MM:SS. /// [TaskAttribute("datetime")] [DateTimeValidator()] public DateTime Datetime { get { return _datetime; } set { _datetime = value; } } /// /// Used to select files that should be touched. /// [BuildElement("fileset")] public FileSet TouchFileSet { get { return _fileset; } set { _fileset = value; } } #endregion Public Instance Properties #region Override implementation of Task /// /// Ensures the supplied attributes are valid. /// /// Xml node used to define this task instance. protected override void InitializeTask(System.Xml.XmlNode taskNode) { // limit task to either millis or a date string if (Millis != 0 && Datetime != DateTime.MinValue) { throw new BuildException("Cannot specify 'millis' and 'datetime'" + " in the same task.", Location); } // limit task to touching either a file or fileset if (File != null && TouchFileSet.Includes.Count != 0) { throw new BuildException("Cannot specify both 'file' attribute" + " and use in the same task.", Location); } } protected override void ExecuteTask() { DateTime touchDateTime = DateTime.Now; // ensure base directory is set, even if fileset was not initialized // from XML if (TouchFileSet.BaseDirectory == null) { TouchFileSet.BaseDirectory = new DirectoryInfo(Project.BaseDirectory); } if (Millis != 0) { touchDateTime = GetDateTime(Millis); } else if (Datetime != DateTime.MinValue) { touchDateTime = Datetime; } // try to touch specified file if (File != null) { // touch file TouchFile(File.FullName, touchDateTime); } else { // touch files in fileset // only use the file set if file attribute has NOT been set foreach (string path in TouchFileSet.FileNames) { TouchFile(path, touchDateTime); } } } #endregion Override implementation of Task #region Private Instance Methods private void TouchFile(string path, DateTime touchDateTime) { try { if (System.IO.File.Exists(path)) { Log(Level.Verbose, "Touching file '{0}' with '{1}'.", path, touchDateTime.ToString(CultureInfo.InvariantCulture)); } else { Log(Level.Verbose, "Creating file '{0}' with '{1}'.", path, touchDateTime.ToString(CultureInfo.InvariantCulture)); // create the file (and ensure stream is closed) using (FileStream fs = System.IO.File.Create(path)) { } } System.IO.File.SetLastWriteTime(path, touchDateTime); } catch (Exception ex) { string msg = string.Format(CultureInfo.InvariantCulture, ResourceUtils.GetString("NA1152"), path); if (FailOnError) { throw new BuildException(msg, Location, ex); } // swallow any errors and move on Log(Level.Verbose, msg + " " + ex.Message); } } private DateTime GetDateTime(long milliSeconds) { DateTime touchDateTime = DateTime.Parse("01/01/1970 00:00:00", CultureInfo.InvariantCulture); return touchDateTime.Add(TimeSpan.FromMilliseconds(milliSeconds)); } #endregion Private Instance Methods } }