Skip to content

Commit

Permalink
Make config writer use XmlWriter for disk write
Browse files Browse the repository at this point in the history
... instead of doing XmlWriter -> string -> disk.
- This guarantees that the file encoding and the XML declaration are
  properly in sync.
- Adds a `saveNormalizedXml` function to Utils to facilitate this.
- Adds a test to UtilsSpecs for the new function.
- Updates ConfigFile.saveConfigNode to use the new function.
- Should fix #2003 permanently.
- Removes the previous fix in commit d1d06b7
  • Loading branch information
Jonathan Page committed Jan 17, 2017
1 parent e274db0 commit 243adb2
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 9 deletions.
9 changes: 1 addition & 8 deletions src/Paket.Core/ConfigFile.fs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,6 @@ let private rootElement = "configuration"
let private getConfigNode (nodeName : string) =
let rootNode =
let doc = XmlDocument ()

let xmldecl = doc.CreateXmlDeclaration("1.0",null,null)
xmldecl.Encoding <- "UTF-8"
xmldecl.Standalone <- "yes"

doc.InsertBefore(xmldecl, doc.DocumentElement) |> ignore

if File.Exists Constants.PaketConfigFile then
try
use f = File.OpenRead(Constants.PaketConfigFile)
Expand All @@ -49,7 +42,7 @@ let private getConfigNode (nodeName : string) =
let private saveConfigNode (node : XmlNode) =
trial {
do! createDir Constants.PaketConfigFolder
do! saveFile Constants.PaketConfigFile (normalizeXml node.OwnerDocument)
do! saveNormalizedXml Constants.PaketConfigFile node.OwnerDocument
}


Expand Down
13 changes: 13 additions & 0 deletions src/Paket.Core/Utils.fs
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,19 @@ let inline normalizeXml (doc:XmlDocument) =
xmlTextWriter.Flush()
stringWriter.GetStringBuilder() |> string

let saveNormalizedXml (fileName:string) (doc:XmlDocument) =
// combination of saveFile and normalizeXml which ensures that the
// file encoding matches the one listed in the XML itself.
tracefn "Saving xml %s" fileName
let settings = XmlWriterSettings (Indent=true)

try
use fstream = File.Create(fileName)
use xmlTextWriter = XmlWriter.Create(fstream, settings)
doc.WriteTo(xmlTextWriter) |> ok
with _ ->
FileSaveError fileName |> fail

let normalizeFeedUrl (source:string) =
match source.TrimEnd([|'/'|]) with
| "https://api.nuget.org/v3/index.json" -> Constants.DefaultNuGetV3Stream
Expand Down
20 changes: 19 additions & 1 deletion tests/Paket.Tests/UtilsSpecs.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ open NUnit.Framework
open FsUnit
open System
open System.Net
open Chessie.ErrorHandling
open System.Xml

[<Test>]
let ``createRelativePath should handle spaces``() =
Expand Down Expand Up @@ -252,4 +254,20 @@ let ``should simplify path``() =
System.IO.Path.IsPathRooted p2 |> shouldEqual true
System.IO.Path.IsPathRooted p3 |> shouldEqual false
System.IO.Path.GetFullPath p1 |> shouldEqual (System.IO.Path.GetFullPath p2)
System.IO.Path.Combine(normalizePath p0,normalizePath p3) |> Path.GetFullPath |> shouldEqual (System.IO.Path.GetFullPath p2)
System.IO.Path.Combine(normalizePath p0,normalizePath p3) |> Path.GetFullPath |> shouldEqual (System.IO.Path.GetFullPath p2)

[<Test>]
let ``saving new XML file should produce valid XML``() =
let tempFile = Path.GetTempFileName ()
try
let doc = XmlDocument ()
doc.AppendChild(doc.CreateElement("configuration")) |> ignore
saveNormalizedXml tempFile doc |> shouldEqual (ok ())
let newDoc = XmlDocument ()
use f = File.OpenRead(tempFile)
newDoc.Load f
if not (newDoc.FirstChild :? XmlDeclaration) then
failwith "Generated XML should contain a declaration"
finally
if File.Exists(tempFile) then
File.Delete(tempFile)

0 comments on commit 243adb2

Please sign in to comment.