Skip to content

Commit

Permalink
Merge pull request #769 from Stift/IndentAssemblyBindingRedirects
Browse files Browse the repository at this point in the history
Improve config file formatting with indented binding redirects
  • Loading branch information
forki committed Apr 12, 2015
2 parents 05b0ad3 + edfaaf1 commit 0e40547
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 3 deletions.
26 changes: 23 additions & 3 deletions src/Paket.Core/BindingRedirects.fs
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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"
Expand Down Expand Up @@ -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 =
Expand All @@ -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.
Expand Down
16 changes: 16 additions & 0 deletions tests/Paket.Tests/BindingRedirect.fs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ let private containsSingleDescendentWithNs = containsDescendents 1 bindingNs
let private createBindingRedirectXml culture assembly version publicKey = sprintf "<dependentAssembly xmlns=\"urn:schemas-microsoft-com:asm.v1\">\r\n <assemblyIdentity name=\"%s\" publicKeyToken=\"%s\" culture=\"%s\" />\r\n <bindingRedirect oldVersion=\"0.0.0.0-%s\" newVersion=\"%s\" />\r\n</dependentAssembly>" assembly publicKey culture version version
let private xNameForNs name = XName.Get(name, bindingNs)

let sampleDocWithNoIndentation() = sprintf """<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime><assemblyBinding xmlns="%s">%s</assemblyBinding></runtime></configuration>""" bindingNs (createBindingRedirectXml "cul" "asm" "v" "pKey") |> XDocument.Parse

[<Test>]
let ``add missing elements to configuration file``() =
let doc = sampleDoc()
Expand Down Expand Up @@ -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")

[<Test>]
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 "<dependentAssembly xmlns=\"urn:schemas-microsoft-com:asm.v1\">\r\n <assemblyIdentity name=\"Assembly\" publicKeyToken=\"PUBLIC_KEY\" culture=\"neutral\" />\r\n <bindingRedirect oldVersion=\"0.0.0.0-1.0.0\" newVersion=\"1.0.0\" />\r\n </dependentAssembly>"

0 comments on commit 0e40547

Please sign in to comment.