1 // NAnt - A .NET build tool
\r
2 // Copyright (C) 2001 Gerry Shaw
\r
4 // This program is free software; you can redistribute it and/or modify
\r
5 // it under the terms of the GNU General Public License as published by
\r
6 // the Free Software Foundation; either version 2 of the License, or
\r
7 // (at your option) any later version.
\r
9 // This program is distributed in the hope that it will be useful,
\r
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
12 // GNU General Public License for more details.
\r
14 // You should have received a copy of the GNU General Public License
\r
15 // along with this program; if not, write to the Free Software
\r
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\r
18 // Gerry Shaw (gerry_shaw@yahoo.com)
\r
19 // Ian MacLean (ian_maclean@another.com)
\r
21 namespace SourceForge.NAnt {
\r
27 using System.Collections;
\r
28 using System.Collections.Specialized;
\r
31 public class CopyTask : Task {
\r
33 [TaskAttribute("file")]
\r
34 string _sourceFile = null;
\r
36 [TaskAttribute("tofile")]
\r
37 string _toFile = null;
\r
39 [TaskAttribute("todir")]
\r
40 string _toDirectory = null;
\r
42 [TaskAttribute("filtering")]
\r
43 [BooleanValidator()]
\r
44 string _filtering = Boolean.FalseString;
\r
46 [TaskAttribute("flatten")]
\r
47 [BooleanValidator()]
\r
48 string _flatten = Boolean.FalseString;
\r
50 [TaskAttribute("includeEmptyDirs")]
\r
51 [BooleanValidator()]
\r
52 string _includeEmptyDirs = Boolean.FalseString;
\r
54 [TaskFileSet("fileset")]
\r
55 FileSet _fileset = new FileSet(true); // include all by default
\r
57 [TaskAttribute("overwrite")]
\r
58 [BooleanValidator()]
\r
59 string _overwrite = Boolean.FalseString;
\r
61 [TaskAttribute("verbose")]
\r
62 [BooleanValidator()]
\r
63 string _verbose = Boolean.FalseString;
\r
65 [TaskAttribute("preserveLastModified")]
\r
66 [BooleanValidator()]
\r
67 string _preserveLastModified = Boolean.FalseString;
\r
69 Hashtable _fileCopyMap = new Hashtable();
\r
71 public string SourceFile { get { return _sourceFile; } }
\r
72 public string ToFile { get { return _toFile; } }
\r
73 public string ToDirectory { get { return _toDirectory; } }
\r
74 public bool Filtering { get { return Convert.ToBoolean(_filtering); } }
\r
75 public bool Flatten { get { return Convert.ToBoolean(_flatten); } }
\r
76 public bool IncludeEmptyDirs { get { return Convert.ToBoolean(_includeEmptyDirs); } }
\r
77 public bool Overwrite { get { return Convert.ToBoolean(_overwrite); } }
\r
78 public bool PreserveLastModified{ get { return Convert.ToBoolean(_preserveLastModified); } }
\r
79 public FileSet CopyFileSet { get { return _fileset; } }
\r
81 public bool Verbose {
\r
83 return (Project.Verbose || Convert.ToBoolean(_verbose));
\r
87 protected Hashtable FileCopyMap {
\r
88 get { return _fileCopyMap; }
\r
92 /// Actually does the file (and possibly empty directory) copies.
\r
94 protected virtual void DoFileOperations() {
\r
95 int fileCount = FileCopyMap.Keys.Count;
\r
96 if (fileCount > 0) {
\r
97 if (ToDirectory != null) {
\r
98 Log.WriteLine(LogPrefix + "Copying {0} files to {1}", fileCount, Project.GetFullPath(ToDirectory));
\r
100 Log.WriteLine(LogPrefix + "Copying {0} files", fileCount);
\r
103 // loop thru our file list
\r
104 foreach (string sourcePath in FileCopyMap.Keys) {
\r
105 string dstPath = (string)FileCopyMap[sourcePath];
\r
106 if (sourcePath == dstPath) {
\r
108 Log.WriteLine(LogPrefix + "Skipping self-copy of {0}" + sourcePath);
\r
115 Log.WriteLine(LogPrefix + "Copying {0} to {1}", sourcePath, dstPath);
\r
118 // create directory if not present
\r
119 string dstDirectory = Path.GetDirectoryName(dstPath);
\r
120 if (!Directory.Exists(dstDirectory)) {
\r
121 Directory.CreateDirectory(dstDirectory);
\r
123 Log.WriteLine(LogPrefix + "Created directory {0}", dstDirectory);
\r
127 File.Copy(sourcePath, dstPath, true);
\r
128 } catch (IOException ioe) {
\r
129 string msg = String.Format("Cannot copy {0} to {1}", sourcePath, dstPath);
\r
130 throw new BuildException(msg, Location, ioe);
\r
135 // TODO: handle empty directories in the fileset, refer to includeEmptyDirs attribute at
\r
136 // http://jakarta.apache.org/ant/manual/CoreTasks/copy.html
\r
139 protected override void ExecuteTask() {
\r
141 string dstDirectoryPath = Project.GetFullPath(ToDirectory);
\r
142 string srcFilePath = Project.GetFullPath(SourceFile);
\r
143 FileInfo srcInfo = new FileInfo(srcFilePath);
\r
145 string dstFilePath;
\r
146 if (ToFile == null) {
\r
147 dstFilePath = dstDirectoryPath + Path.DirectorySeparatorChar + srcInfo.Name;
\r
149 dstFilePath = Project.GetFullPath(ToFile);
\r
152 FileInfo dstInfo = new FileInfo(dstFilePath);
\r
153 if (SourceFile != null) {
\r
154 if (srcInfo.Exists) {
\r
155 // do the outdated check
\r
156 bool outdated = (!dstInfo.Exists) || (srcInfo.LastWriteTime > dstInfo.LastWriteTime);
\r
158 if (Overwrite || outdated) {
\r
159 // add to a copy map of absolute verified paths
\r
160 FileCopyMap.Add(srcFilePath, dstFilePath);
\r
163 Log.WriteLine(LogPrefix + "Could not find file {0} to copy.", srcFilePath);
\r
166 // get the complete path of the base directory of the fileset, ie, c:\work\nant\src
\r
167 string srcBasePath = Project.GetFullPath(CopyFileSet.BaseDirectory);
\r
168 string dstBasePath = Project.GetFullPath(ToDirectory);
\r
170 // if source file not specified use fileset
\r
171 foreach (string pathname in CopyFileSet.FileNames) {
\r
172 // replace the fileset path with the destination path
\r
173 // NOTE: big problems could occur if the file set base dir is rooted on a different drive
\r
174 string dstPath = pathname.Replace(srcBasePath, dstBasePath);
\r
176 srcInfo = new FileInfo(pathname);
\r
177 dstInfo = new FileInfo(dstPath);
\r
179 if (srcInfo.Exists) {
\r
180 // do the outdated check
\r
181 bool outdated = (!dstInfo.Exists) || (srcInfo.LastWriteTime > dstInfo.LastWriteTime);
\r
183 if (Overwrite || outdated) {
\r
184 FileCopyMap.Add(pathname, dstPath);
\r
187 Log.WriteLine(LogPrefix + "Could not find file {0} to copy.", srcFilePath);
\r
192 // do all the actual copy operations now...
\r
193 DoFileOperations();
\r