diff --git a/src/app/FakeLib/MSBuild/ProjectSystem.fs b/src/app/FakeLib/MSBuild/ProjectSystem.fs index f282bc79a39..8a5c48207ef 100644 --- a/src/app/FakeLib/MSBuild/ProjectSystem.fs +++ b/src/app/FakeLib/MSBuild/ProjectSystem.fs @@ -6,19 +6,36 @@ open System.Xml open System.Xml.Linq /// A small abstraction over MSBuild project files. -type ProjectSystem(projectFileName : string) = - let document = - ReadFileAsString projectFileName - |> XMLHelper.XMLDoc +type ProjectFile(projectFileName:string,documentContent : string) = + let document = XMLHelper.XMLDoc documentContent let nsmgr = let nsmgr = new XmlNamespaceManager(document.NameTable) nsmgr.AddNamespace("default", document.DocumentElement.NamespaceURI) nsmgr - let files = - let xpath = "/default:Project/default:ItemGroup/default:Compile/@Include" - [for node in document.SelectNodes(xpath,nsmgr) -> node.InnerText] + let compileNodesXPath = "/default:Project/default:ItemGroup/default:Compile" + let getCompileNodes (document:XmlDocument) = + [for node in document.SelectNodes(compileNodesXPath,nsmgr) -> node] + + let getFileAttributes (document:XmlDocument) = + let xpath = compileNodesXPath + "/@Include" + [for attr in document.SelectNodes(xpath,nsmgr) -> attr] + + let files = getFileAttributes document |> List.map (fun attr -> attr.InnerText) + + /// Read a Project from a FileName + static member FromFile(projectFileName) = new ProjectFile(projectFileName,ReadFileAsString projectFileName) + + /// Add a file to the Compile nodes + member x.AddFile fileName = + let document = XMLHelper.XMLDoc documentContent // we create a copy and work immutable + let node = getCompileNodes document |> Seq.last + let newNode = node.CloneNode(false) :?> XmlElement + newNode.SetAttribute("Include",fileName) + + node.ParentNode.AppendChild(newNode) |> ignore + new ProjectFile(projectFileName,document.OuterXml) /// All files which are in "Compile" sections member x.Files = files @@ -40,11 +57,11 @@ type ProjectComparison = let findMissingFiles templateProject projects = let isFSharpProject file = file |> endsWith ".fsproj" - let templateFiles = (ProjectSystem templateProject).Files + let templateFiles = (ProjectFile.FromFile templateProject).Files let templateFilesSet = Set.ofSeq templateFiles projects - |> Seq.map (fun fileName -> ProjectSystem fileName) + |> Seq.map (fun fileName -> ProjectFile.FromFile fileName) |> Seq.map (fun ps -> let missingFiles = Set.difference templateFilesSet (Set.ofSeq ps.Files) let unorderedFiles = diff --git a/src/test/Test.FAKECore/ProjectSystemSpecs.cs b/src/test/Test.FAKECore/ProjectSystemSpecs.cs index 2c82d4ccc9e..1b833de1f13 100644 --- a/src/test/Test.FAKECore/ProjectSystemSpecs.cs +++ b/src/test/Test.FAKECore/ProjectSystemSpecs.cs @@ -5,8 +5,8 @@ namespace Test.FAKECore { public class when_checking_for_files { - static ProjectSystem.ProjectSystem _project; - Because of = () => _project = new ProjectSystem.ProjectSystem("ProjectTestFiles/FakeLib.fsproj"); + static ProjectSystem.ProjectFile _project; + Because of = () => _project = ProjectSystem.ProjectFile.FromFile("ProjectTestFiles/FakeLib.fsproj"); It should_find_the_SpecsRemovement_helper_in_the_MSBuild_folder = () => _project.Files.ShouldContain("MSBuild\\SpecsRemovement.fs"); @@ -23,4 +23,17 @@ public class when_checking_for_files It should_not_find_the_badadadum_helper = () => _project.Files.ShouldNotContain("badadadumHelper.fs"); } + + public class when_adding_files + { + static ProjectSystem.ProjectFile _project; + Establish context = () => _project = ProjectSystem.ProjectFile.FromFile("ProjectTestFiles/FakeLib.fsproj"); + Because of = () => _project = _project.AddFile("badadadumHelper.fs"); + + It should_find_the_SpecsRemovement_helper_in_the_MSBuild_folder = () => + _project.Files.ShouldContain("MSBuild\\SpecsRemovement.fs"); + + It should_find_the_badadadum_helper = () => + _project.Files.ShouldContain("badadadumHelper.fs"); + } } \ No newline at end of file