Index: project/core/tasks/FileTaskResult.cs =================================================================== --- project/core/tasks/FileTaskResult.cs (revision 4186) +++ project/core/tasks/FileTaskResult.cs (working copy) @@ -1,5 +1,6 @@ using System; using System.IO; +using ThoughtWorks.CruiseControl.Core.Util; namespace ThoughtWorks.CruiseControl.Core.Tasks { @@ -7,30 +8,56 @@ { private string data; - public FileTaskResult(string filename) : this(new FileInfo(filename)) + /// + /// Create a new task result from the contents of the specified file, converting it to XML if necessary. + /// + /// The name of the file to read. + /// True if the file is already XML, false if not. + public FileTaskResult(string filename, bool isXml) : this(new FileInfo(filename), isXml) {} - public FileTaskResult(FileInfo file) + /// + /// Create a new task result from the contents of the specified file object, converting it to XML if necessary. + /// + /// The object of the file containing the data. + /// True if the file is already XML, false if not. + public FileTaskResult(FileInfo file, bool isXml) { - ReadFileContents(file); + ReadFileContents(file, isXml); } + /// + /// The XML data of the task result. + /// public string Data { get { return data; } } + /// + /// Did the task succeed? + /// + /// True always - by definition, this type of task always succeeds. public bool Succeeded() { return true; } + /// + /// Did the task fail? + /// + /// False always - by definition, this type of task always succeeds. public bool Failed() { return false; } - private void ReadFileContents(FileInfo file) + /// + /// Read the data from the file and convert it to XML if necessary. + /// + /// The object of the file containing the data. + /// True if the file is already XML, false if not. + private void ReadFileContents(FileInfo file, bool isXml) { try { @@ -43,6 +70,8 @@ { throw new CruiseControlException("Unable to read the contents of the file: " + file.FullName, ex); } - } + if (!isXml) + data = StringUtil.MakeBuildResult(data, ""); + } } } \ No newline at end of file Index: project/core/tasks/MergeFilesTask.cs =================================================================== --- project/core/tasks/MergeFilesTask.cs (revision 4186) +++ project/core/tasks/MergeFilesTask.cs (working copy) @@ -4,20 +4,28 @@ namespace ThoughtWorks.CruiseControl.Core.Tasks { + /// + /// A task to merge disk files into the integration results. + /// [ReflectorType("merge")] public class MergeFilesTask : ITask { [ReflectorArray("files")] - public string[] MergeFiles = new string[0]; + public MergeFile[] MergeFiles = new MergeFile[0]; + /// + /// Read the configured files, converting them to XML as needed, and add them as + /// task results to the specified intergration result. + /// + /// The result for the current integration. public void Run(IIntegrationResult result) { - foreach (string mergeFile in MergeFiles) + foreach (MergeFile mergeFile in MergeFiles) { - string fullMergeFile = mergeFile; - if (!Path.IsPathRooted(mergeFile)) + string fullMergeFile = mergeFile.fileName; + if (!Path.IsPathRooted(mergeFile.fileName)) { - fullMergeFile = Path.Combine(result.WorkingDirectory, mergeFile); + fullMergeFile = Path.Combine(result.WorkingDirectory, mergeFile.fileName); } WildCardPath path = new WildCardPath(fullMergeFile); FileInfo[] files = path.GetFiles(); @@ -26,7 +34,7 @@ Log.Info("Merging file: " + fileInfo); if (fileInfo.Exists) { - result.AddTaskResult((new FileTaskResult(fileInfo))); + result.AddTaskResult((new FileTaskResult(fileInfo, mergeFile.isXml))); } else { @@ -35,5 +43,28 @@ } } } + + /// + /// An object representing a single file to be merged. + /// + [ReflectorType("file")] + public class MergeFile + { + /// + /// The pathname of the file on disk, either absolute or relative to the project working directory. + /// + [ReflectorProperty("name")] + public string fileName; + + /// + /// Is the data in XML format already? + /// + /// + /// If set to false (the default), the data will be transformed to an XML build + /// result a la . + /// + [ReflectorProperty("isXml", Required = false)] + public bool isXml = true; + } } } \ No newline at end of file Index: project/core/tasks/MsBuildTask.cs =================================================================== --- project/core/tasks/MsBuildTask.cs (revision 4186) +++ project/core/tasks/MsBuildTask.cs (working copy) @@ -53,7 +53,7 @@ string buildOutputFile = MsBuildOutputFile(result); if (File.Exists(buildOutputFile)) { - result.AddTaskResult(new FileTaskResult(buildOutputFile)); + result.AddTaskResult(new FileTaskResult(buildOutputFile, true)); } result.AddTaskResult(new ProcessTaskResult(processResult)); if (processResult.TimedOut) Index: project/core/tasks/NUnitTask.cs =================================================================== --- project/core/tasks/NUnitTask.cs (revision 4186) +++ project/core/tasks/NUnitTask.cs (working copy) @@ -47,9 +47,9 @@ ProcessResult nunitResult = processExecutor.Execute(NewProcessInfo(outputFile, result), ProcessMonitor.GetProcessMonitorByProject(result.ProjectName)); result.AddTaskResult(new ProcessTaskResult(nunitResult)); if (File.Exists(outputFile)) - { - result.AddTaskResult(new FileTaskResult(outputFile)); - } + { + result.AddTaskResult(new FileTaskResult(outputFile, false)); + } else { Log.Warning(string.Format("NUnit test output file {0} was not created", outputFile)); Index: project/examples/ccnet.config =================================================================== --- project/examples/ccnet.config (revision 4186) +++ project/examples/ccnet.config (working copy) @@ -23,9 +23,9 @@ - ..\..\..\..\build\*-results.xml - ..\..\..\..\build\fxcop\*.xml - ..\..\..\..\build\unittests\Coverage.xml + + + Index: project/examples/CVSAndNAntAndEmailPublisherCCNet.config =================================================================== --- project/examples/CVSAndNAntAndEmailPublisherCCNet.config (revision 4186) +++ project/examples/CVSAndNAntAndEmailPublisherCCNet.config (working copy) @@ -21,7 +21,7 @@ - C:\dev\ccnet\ccnet\build\ccnet.exe-results.xml + Index: project/UnitTests/Core/Tasks/FileTaskResultTest.cs =================================================================== --- project/UnitTests/Core/Tasks/FileTaskResultTest.cs (revision 4186) +++ project/UnitTests/Core/Tasks/FileTaskResultTest.cs (working copy) @@ -25,14 +25,14 @@ [Test] public void ShouldReadContentsOfTempFile() { - FileTaskResult result = new FileTaskResult(filename); + FileTaskResult result = new FileTaskResult(filename, true); Assert.AreEqual("", result.Data); } [Test, ExpectedException(typeof (CruiseControlException))] public void ShouldThrowReadableExceptionIfFileDoesNotExist() { - new FileTaskResult("unknown.file"); + new FileTaskResult("unknown.file", false); } } } \ No newline at end of file Index: project/UnitTests/Core/Tasks/MergeFileTaskTest.cs =================================================================== --- project/UnitTests/Core/Tasks/MergeFileTaskTest.cs (revision 4186) +++ project/UnitTests/Core/Tasks/MergeFileTaskTest.cs (working copy) @@ -25,18 +25,46 @@ } [Test] - public void StoreMergeFilesInIntegrationResult() + public void StoreXmlFilesInIntegrationResult() { string fileData = @""; string tempFile = TempFileUtil.CreateTempFile(TEMP_DIR, "MergeFileTask", fileData); - task.MergeFiles = new string[] {tempFile}; + MergeFilesTask.MergeFile tempMergeFile = new MergeFilesTask.MergeFile(); + tempMergeFile.fileName = tempFile; + tempMergeFile.isXml = true; + task.MergeFiles = new MergeFilesTask.MergeFile[] {tempMergeFile}; task.Run(result); - Assert.AreEqual(fileData, result.TaskOutput); + Assert.AreEqual(fileData, result.TaskOutput, "Merged data mismatch."); } - [Test] + [Test] + public void StoreNonXmlFilesInIntegrationResult() + { + string fileData = @"line 1 +line 2 + +line 4 +"; + string expectedOutput = @" + + line 1 + line 2 + line 4 + +"; + string tempFile = TempFileUtil.CreateTempFile(TEMP_DIR, "MergeFileTask", fileData); + + MergeFilesTask.MergeFile tempMergeFile = new MergeFilesTask.MergeFile(); + tempMergeFile.fileName = tempFile; + tempMergeFile.isXml = false; + task.MergeFiles = new MergeFilesTask.MergeFile[] { tempMergeFile }; + task.Run(result); + + Assert.AreEqual(expectedOutput, result.TaskOutput, "Merged data mismatch."); + } + [Test] public void ResolveWildCards() { String fileData = "bat"; @@ -45,9 +73,12 @@ TempFileUtil.CreateTempFile(TEMP_DIR, "foo.bat", "blah"); TempFileUtil.CreateTempXmlFile(TEMP_DIR + "\\sub", "foo.xml", "bat"); - task.MergeFiles = new string[] {fullPathToTempDir + @"\*.xml"}; + MergeFilesTask.MergeFile tempMergeFile = new MergeFilesTask.MergeFile(); + tempMergeFile.fileName = fullPathToTempDir + @"\*.xml"; + tempMergeFile.isXml = true; + task.MergeFiles = new MergeFilesTask.MergeFile[] { tempMergeFile }; task.Run(result); - Assert.AreEqual(fileData, result.TaskOutput); + Assert.AreEqual(fileData, result.TaskOutput, "Merged data mismatch."); } [Test] @@ -60,9 +91,12 @@ TempFileUtil.CreateTempXmlFile(TEMP_DIR + "\\sub", "foo.xml", "bat"); result.WorkingDirectory = fullPathToTempDir; - task.MergeFiles = new string[] {@"*.xml"}; + MergeFilesTask.MergeFile tempMergeFile = new MergeFilesTask.MergeFile(); + tempMergeFile.fileName = @"*.xml"; + tempMergeFile.isXml = true; + task.MergeFiles = new MergeFilesTask.MergeFile[] { tempMergeFile }; task.Run(result); - Assert.AreEqual(fileData, result.TaskOutput); + Assert.AreEqual(fileData, result.TaskOutput, "Merged data mismatch."); } [Test] @@ -77,11 +111,13 @@ TempFileUtil.CreateTempFile(TEMP_DIR, "foo.bat", fooBatFileData); TempFileUtil.CreateTempXmlFile(TEMP_DIR + @"\sub", "foo.xml", subFooXmlFileData); - task.MergeFiles = new string[] - { - fullPathToTempDir + @"\sub" + @"\*.xml", - fullPathToTempDir + @"\foo.*" - }; + MergeFilesTask.MergeFile tempMergeFile1 = new MergeFilesTask.MergeFile(); + tempMergeFile1.fileName = fullPathToTempDir + @"\sub" + @"\*.xml"; + tempMergeFile1.isXml = true; + MergeFilesTask.MergeFile tempMergeFile2 = new MergeFilesTask.MergeFile(); + tempMergeFile2.fileName = fullPathToTempDir + @"\foo.*"; + tempMergeFile2.isXml = true; + task.MergeFiles = new MergeFilesTask.MergeFile[] { tempMergeFile1, tempMergeFile2 }; task.Run(result); IList list = result.TaskResults; @@ -94,20 +130,34 @@ [Test] public void IgnoresFilesNotFound() { - task.MergeFiles = new string[] {@"c:\nonExistantFile.txt"}; + MergeFilesTask.MergeFile tempMergeFile = new MergeFilesTask.MergeFile(); + tempMergeFile.fileName = @"c:\nonExistantFile.txt"; + tempMergeFile.isXml = true; + task.MergeFiles = new MergeFilesTask.MergeFile[] { tempMergeFile }; task.Run(result); - Assert.AreEqual(string.Empty, result.TaskOutput); + Assert.AreEqual(string.Empty, result.TaskOutput, "Merged data mismatch."); } [Test] public void LoadFromConfig() { - string xml = @"foo.xmlbar.xml"; + string xml = +@" + + + + + +"; task = NetReflector.Read(xml) as MergeFilesTask; - Assert.AreEqual(2, task.MergeFiles.Length); - Assert.AreEqual("foo.xml", task.MergeFiles[0]); - Assert.AreEqual("bar.xml", task.MergeFiles[1]); - } + Assert.AreEqual(3, task.MergeFiles.Length); + Assert.AreEqual("foo.xml", task.MergeFiles[0].fileName, "File 1 name mismatch."); + Assert.IsTrue(task.MergeFiles[0].isXml, "File 1 should be XML."); + Assert.AreEqual("bar.xml", task.MergeFiles[1].fileName, "File 2 name mismatch."); + Assert.IsTrue(task.MergeFiles[1].isXml, "File 2 should be XML."); + Assert.AreEqual("baz.xml", task.MergeFiles[2].fileName, "File 3 name mismatch."); + Assert.IsFalse(task.MergeFiles[2].isXml, "File 3 should not be XML."); + } private void AssertDataContainedInList(IList list, string data) {