From: Slide Date: Tue, 6 Dec 2011 17:00:38 +0000 (-0700) Subject: [xbuild] Add 'OverrideReadOnlyFiles' property to Copy task. X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=f2c44f81a35de87a00c5eca3c31baaf7b63363f0;p=mono.git [xbuild] Add 'OverrideReadOnlyFiles' property to Copy task. Also, fixed Bugzilla 2239 where the copy task does not behave the same as msbuild when a file being copied is ReadOnly. msbuild resets the attributes of the file to Normal in this case. --- 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 a090e4716d4..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 () { @@ -164,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 { @@ -189,9 +201,18 @@ namespace Microsoft.Build.Tasks { { 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) @@ -203,7 +224,7 @@ namespace Microsoft.Build.Tasks { FileInfo destinationInfo = new FileInfo (dest); return !(sourceInfo.Length == destinationInfo.Length && - File.GetLastWriteTime(source) <= File.GetLastWriteTime (dest)); + File.GetLastWriteTime (source) <= File.GetLastWriteTime (dest)); } } diff --git a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CopyTest.cs b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CopyTest.cs index e3cd166b9f9..63c3ea9456c 100644 --- a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CopyTest.cs +++ b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CopyTest.cs @@ -57,7 +57,7 @@ namespace MonoTests.Microsoft.Build.Tasks { { Engine engine; Project project; - string file_path = Path.Combine(source_path, "copy.txt"); + string file_path = Path.Combine (source_path, "copy.txt"); string target_file = Path.Combine (target_path, "copy.txt"); using (File.CreateText (file_path)) { } @@ -243,6 +243,143 @@ namespace MonoTests.Microsoft.Build.Tasks { } } + [Test] + public void TestCopy_ReadOnlyUpdate () + { + Engine engine; + Project project; + string file_path = Path.Combine (source_path, "copyro.txt"); + string target_file = Path.Combine (target_path, "copyro.txt"); + + using (File.CreateText (file_path)) { } + + string documentString = @" + + " + target_file + @" + + 1 + 2 + + + + + + + + + + "; + + engine = new Engine (Consts.BinPath); + project = engine.CreateNewProject (); + + TestMessageLogger testLogger = new TestMessageLogger (); + engine.RegisterLogger (testLogger); + + project.LoadXml (documentString); + + if (!project.Build ("1")) { + testLogger.DumpMessages (); + Assert.Fail ("Build failed"); + } + Assert.IsTrue (File.Exists (target_file), "A2"); + Assert.AreEqual (FileAttributes.Normal, File.GetAttributes (target_file), "A3"); + } + +#if NET_3_5 || NET_4_0 + [Test] + public void TestCopy_OverwriteReadOnlyTrue () + { + Engine engine; + Project project; + string file_path = Path.Combine (source_path, "copyro1.txt"); + string target_file = Path.Combine (target_path, "copyro1.txt"); + + using (File.CreateText (file_path)) { } + using (File.CreateText (target_file)) { } + + File.SetAttributes (target_file, FileAttributes.ReadOnly); + Assert.AreEqual (FileAttributes.ReadOnly, File.GetAttributes (target_file), "A1"); + + string documentString = @" + + " + target_file + @" + + 1 + 2 + + + + + + + + + + "; + + engine = new Engine (Consts.BinPath); + project = engine.CreateNewProject (); + + TestMessageLogger testLogger = new TestMessageLogger (); + engine.RegisterLogger (testLogger); + + project.LoadXml (documentString); + + if (!project.Build ("1")) { + testLogger.DumpMessages (); + Assert.Fail ("Build failed"); + } + Assert.IsTrue (File.Exists (target_file), "A2"); + Assert.AreEqual (FileAttributes.Normal, File.GetAttributes (target_file), "A3"); + } + + [Test] + public void TestCopy_OverwriteReadOnlyFalse () + { + Engine engine; + Project project; + string file_path = Path.Combine (source_path, "copyro2.txt"); + string target_file = Path.Combine (target_path, "copyro2.txt"); + + using (File.CreateText (file_path)) { } + using (File.CreateText (target_file)) { } + + File.SetAttributes (target_file, FileAttributes.ReadOnly); + Assert.AreEqual (FileAttributes.ReadOnly, File.GetAttributes (target_file), "A1"); + + string documentString = @" + + " + target_file + @" + + 1 + 2 + + + + + + + + + + "; + + engine = new Engine (Consts.BinPath); + project = engine.CreateNewProject (); + + TestMessageLogger testLogger = new TestMessageLogger (); + engine.RegisterLogger (testLogger); + + project.LoadXml (documentString); + + // build should fail because of the readonly target file + Assert.IsFalse (project.Build ("1")); + + File.SetAttributes (target_file, FileAttributes.Normal); + } +#endif + void CheckCopyBuildItems (Project project, string [] source_files, string destination_folder, string prefix) { int num = source_files.Length;