diff --git a/src/Paket.Core/BindingRedirects.fs b/src/Paket.Core/BindingRedirects.fs index 43712f3286..a5588660af 100644 --- a/src/Paket.Core/BindingRedirects.fs +++ b/src/Paket.Core/BindingRedirects.fs @@ -1,6 +1,8 @@ module Paket.BindingRedirects open System +open System.Text +open System.Xml open System.Xml.Linq open System.IO open System.Reflection @@ -13,14 +15,18 @@ type BindingRedirect = PublicKeyToken : string Culture : string option } +let private bindingNs = "urn:schemas-microsoft-com:asm.v1" + +let private ensureAssemblyBinding doc = + doc |> ensurePathExists ("/configuration/runtime/assemblyBinding!" + bindingNs) + /// Updates the supplied MSBuild document with the supplied binding redirect. let internal setRedirect (doc:XDocument) bindingRedirect = - let bindingNs = "urn:schemas-microsoft-com:asm.v1" let createElementWithNs = createElement (Some bindingNs) let tryGetElementWithNs = tryGetElement (Some bindingNs) let getElementsWithNs = getElements (Some bindingNs) - let assemblyBinding = doc |> ensurePathExists ("/configuration/runtime/assemblyBinding!" + bindingNs) + let assemblyBinding = ensureAssemblyBinding doc let dependentAssembly = assemblyBinding |> getElementsWithNs "dependentAssembly" @@ -48,6 +54,20 @@ let internal setRedirect (doc:XDocument) bindingRedirect = | None -> dependentAssembly.Add(newRedirect) doc +let internal indentAssemblyBindings config = + let assemblyBinding = ensureAssemblyBinding config + + let sb = StringBuilder() + let xmlWriterSettings = XmlWriterSettings() + xmlWriterSettings.Indent <- true + using (XmlWriter.Create(sb, xmlWriterSettings)) (fun writer -> + let tempAssemblyBindingNode = XElement.Parse(assemblyBinding.ToString()) + tempAssemblyBindingNode.WriteTo writer) + let parent = assemblyBinding.Parent + assemblyBinding.Remove() + let newAssemblyBindingNode = XElement.Parse(sb.ToString(), LoadOptions.PreserveWhitespace) + parent.Add(newAssemblyBindingNode) + /// Applies a set of binding redirects to a single configuration file. let private applyBindingRedirects bindingRedirects (configFilePath:string) = let config = @@ -57,8 +77,8 @@ let private applyBindingRedirects bindingRedirects (configFilePath:string) = | :? System.Xml.XmlException as ex -> Logging.verbosefn "Illegal xml in file: %s" configFilePath raise ex - let config = Seq.fold setRedirect config bindingRedirects + indentAssemblyBindings config config.Save configFilePath /// Applies a set of binding redirects to all .config files in a specific folder. diff --git a/tests/Paket.Tests/BindingRedirect.fs b/tests/Paket.Tests/BindingRedirect.fs index 11e77a3f0b..d153c298ab 100644 --- a/tests/Paket.Tests/BindingRedirect.fs +++ b/tests/Paket.Tests/BindingRedirect.fs @@ -24,6 +24,10 @@ let private containsSingleDescendentWithNs = containsDescendents 1 bindingNs let private createBindingRedirectXml culture assembly version publicKey = sprintf "\r\n \r\n \r\n" assembly publicKey culture version version let private xNameForNs name = XName.Get(name, bindingNs) +let sampleDocWithNoIndentation() = sprintf """ + +%s""" bindingNs (createBindingRedirectXml "cul" "asm" "v" "pKey") |> XDocument.Parse + [] let ``add missing elements to configuration file``() = let doc = sampleDoc() @@ -101,4 +105,16 @@ let ``correctly updates an existing binding redirect``() = // Assert let dependency = doc.Descendants(xNameForNs "dependentAssembly") |> Seq.head dependency.ToString() |> shouldEqual (createBindingRedirectXml "neutral" "Assembly" "2.0.0" "PUBLIC_KEY") + +[] +let ``redirects got properly indented for readability``() = + let doc = sampleDoc() + setRedirect doc defaultRedirect |> ignore + + // Act + indentAssemblyBindings doc + + // Assert + let dependency = doc.Descendants(xNameForNs "dependentAssembly") |> Seq.head + dependency.ToString() |> shouldEqual "\r\n \r\n \r\n "