X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FMicrosoft.Build.Tasks%2FMicrosoft.Build.Tasks%2FCopy.cs;h=8c28c2ae27b5a9c8a8dcfec93da8975974c9b151;hb=f2c44f81a35de87a00c5eca3c31baaf7b63363f0;hp=9d8b4b9f4b49a61ffb3e0f48714c1c0247a36616;hpb=1c14f1ee6d701510c15499d71fc2b324151a8629;p=mono.git diff --git a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Copy.cs b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Copy.cs index 9d8b4b9f4b4..8c28c2ae27b 100644 --- a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Copy.cs +++ b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Copy.cs @@ -42,6 +42,7 @@ namespace Microsoft.Build.Tasks { ITaskItem destinationFolder; bool skipUnchangedFiles; ITaskItem[] sourceFiles; + bool overwriteReadOnlyFiles; public Copy () { @@ -49,63 +50,74 @@ namespace Microsoft.Build.Tasks { public override bool Execute () { + if (sourceFiles.Length == 0) + // nothing to copy! + return true; + try { List temporaryCopiedFiles = new List (); - if (sourceFiles.Length != destinationFiles.Length) - throw new Exception ("Number of source files is different than number of destination files."); - if (destinationFiles != null && destinationFolder != null) - throw new Exception ("You must specify only one attribute from DestinationFiles and DestinationFolder"); - if (destinationFiles != null) { - IEnumerator source, destination; - source = ((IEnumerable ) sourceFiles).GetEnumerator (); - destination = ((IEnumerable ) destinationFiles).GetEnumerator (); - while (source.MoveNext ()) { - destination.MoveNext (); - ITaskItem sourceItem = source.Current; - ITaskItem destinationItem = destination.Current; + if (sourceFiles != null && destinationFiles != null && + sourceFiles.Length != destinationFiles.Length) { + Log.LogError ("Number of source files is different than number of destination files."); + return false; + } + + if (destinationFiles != null && destinationFolder != null) { + Log.LogError ("You must specify only one attribute from DestinationFiles and DestinationFolder"); + return false; + } + + if (destinationFiles != null && destinationFiles.Length > 0) { + for (int i = 0; i < sourceFiles.Length; i ++) { + ITaskItem sourceItem = sourceFiles [i]; + ITaskItem destinationItem = destinationFiles [i]; string sourceFile = sourceItem.GetMetadata ("FullPath"); string destinationFile = destinationItem.GetMetadata ("FullPath"); - if (skipUnchangedFiles == true) { - FileInfo sourceInfo = new FileInfo (sourceFile); - FileInfo destinationInfo = new FileInfo (destinationFile); - if (sourceInfo.Length == destinationInfo.Length && File.GetLastWriteTime(sourceFile) <= - File.GetLastWriteTime (destinationFile)) - continue; + if (!File.Exists (sourceFile)) { + Log.LogError ("Cannot copy {0} to {1}, as the source file doesn't exist.", sourceFile, destinationFile); + continue; } - File.Copy (sourceFile, destinationFile); - temporaryCopiedFiles.Add (source.Current); + + if (!skipUnchangedFiles || HasFileChanged (sourceFile, destinationFile)) + CopyFile (sourceFile, destinationFile, true); + + sourceItem.CopyMetadataTo (destinationItem); + temporaryCopiedFiles.Add (destinationItem); } } else if (destinationFolder != null) { - bool directoryCreated = false; + List temporaryDestinationFiles = new List (); string destinationDirectory = destinationFolder.GetMetadata ("FullPath"); - if (Directory.Exists (destinationDirectory) == false) { - Directory.CreateDirectory (destinationDirectory); - directoryCreated = true; - } + bool directoryCreated = CreateDirectoryIfRequired (destinationDirectory); - IEnumerator source; - source = (IEnumerator ) sourceFiles.GetEnumerator (); - while (source.MoveNext ()) { - ITaskItem sourceItem = source.Current; + foreach (ITaskItem sourceItem in sourceFiles) { string sourceFile = sourceItem.GetMetadata ("FullPath"); string filename = sourceItem.GetMetadata ("Filename") + sourceItem.GetMetadata ("Extension"); string destinationFile = Path.Combine (destinationDirectory,filename); - if (skipUnchangedFiles == true && directoryCreated == false) { - FileInfo sourceInfo = new FileInfo (sourceFile); - FileInfo destinationInfo = new FileInfo (destinationFile); - if (sourceInfo.Length == destinationInfo.Length && File.GetLastWriteTime(sourceFile) <= - File.GetLastWriteTime (destinationFile)) - continue; + if (!File.Exists (sourceFile)) { + Log.LogError ("Cannot copy {0} to {1}, as the source file doesn't exist.", sourceFile, destinationFile); + continue; } - File.Copy (sourceFile, destinationFile); - temporaryCopiedFiles.Add (source.Current); + + if (!skipUnchangedFiles || directoryCreated || + HasFileChanged (sourceFile, destinationFile)) + CopyFile (sourceFile, destinationFile, false); + + temporaryCopiedFiles.Add (new TaskItem ( + Path.Combine (destinationFolder.GetMetadata ("Identity"), filename), + sourceItem.CloneCustomMetadata ())); + + temporaryDestinationFiles.Add (new TaskItem ( + Path.Combine (destinationFolder.GetMetadata ("Identity"), filename), + sourceItem.CloneCustomMetadata ())); } + destinationFiles = temporaryDestinationFiles.ToArray (); } else { - throw new Exception ("You must specify DestinationFolder or DestinationFiles attribute."); + Log.LogError ("You must specify DestinationFolder or DestinationFiles attribute."); + return false; } copiedFiles = temporaryCopiedFiles.ToArray (); @@ -153,6 +165,17 @@ namespace Microsoft.Build.Tasks { } } +#if NET_3_5 || NET_4_0 + public bool OverwriteReadOnlyFiles { + get { + return overwriteReadOnlyFiles; + } + set { + overwriteReadOnlyFiles = value; + } + } +#endif + [Required] public ITaskItem[] SourceFiles { get { @@ -162,7 +185,49 @@ namespace Microsoft.Build.Tasks { sourceFiles = value; } } + + // returns whether directory was created or not + bool CreateDirectoryIfRequired (string name) + { + if (Directory.Exists (name)) + return false; + + Log.LogMessage ("Creating directory '{0}'", name); + Directory.CreateDirectory (name); + return true; + } + + void CopyFile (string source, string dest, bool create_dir) + { + if (create_dir) + CreateDirectoryIfRequired (Path.GetDirectoryName (dest)); + if (overwriteReadOnlyFiles) + ClearReadOnlyAttribute (dest); + Log.LogMessage ("Copying file from '{0}' to '{1}'", source, dest); + if (String.Compare (source, dest) != 0) + File.Copy (source, dest, true); + ClearReadOnlyAttribute (dest); + } + + void ClearReadOnlyAttribute (string name) + { + if (File.Exists (name) && ((File.GetAttributes (name) & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)) + File.SetAttributes (name, FileAttributes.Normal); + } + + bool HasFileChanged (string source, string dest) + { + if (!File.Exists (dest)) + return true; + + FileInfo sourceInfo = new FileInfo (source); + FileInfo destinationInfo = new FileInfo (dest); + + return !(sourceInfo.Length == destinationInfo.Length && + File.GetLastWriteTime (source) <= File.GetLastWriteTime (dest)); + } + } } -#endif \ No newline at end of file +#endif