From 186077546281ea2865e4d7ae3fdbeeb1bbf60b1d Mon Sep 17 00:00:00 2001 From: Rami Date: Sun, 3 Nov 2024 22:59:09 -0800 Subject: [PATCH] Preserve line ending characters --- CHANGELOG.md | 1 + .../ProjectConverter.cs | 29 ++++++++++++++- ...VersionElementsToAttributesCommandTests.cs | 10 ++--- .../ProgramCommand.cs | 2 +- .../HelpTests.cs | 37 +++++++++++++++++++ .../InputTests.cs | 7 ++-- .../Usage.txt | 2 +- 7 files changed, 76 insertions(+), 12 deletions(-) create mode 100644 src/PackageReferenceVersionToAttributeToolTests/HelpTests.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cfde8f..a666c95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## TBD - Added support for converting projects within sln files on the command line +- Preserve line ending characters ## v1.0.1104.33 (November 4th, 2024) diff --git a/src/PackageReferenceVersionToAttribute/ProjectConverter.cs b/src/PackageReferenceVersionToAttribute/ProjectConverter.cs index bb7fe98..a47db8a 100644 --- a/src/PackageReferenceVersionToAttribute/ProjectConverter.cs +++ b/src/PackageReferenceVersionToAttribute/ProjectConverter.cs @@ -146,11 +146,14 @@ private async Task ConvertAsync(string projectFilePath) this.fileService.RemoveReadOnlyAttribute(projectFilePath); } + string detectedLineEnding = DetectLineEnding(projectFilePath); + var settings = new XmlWriterSettings { OmitXmlDeclaration = document.Declaration == null, // Preserve the XML declaration if it exists. - Indent = false, // Prevents adding any extra indentation - NewLineHandling = NewLineHandling.Replace, + Indent = false, // Prevents adding any extra indentation. + NewLineHandling = NewLineHandling.Replace, // Preserve the same line endings. + NewLineChars = detectedLineEnding, // Preserve the same line endings. }; if (this.options.DryRun) @@ -169,5 +172,27 @@ private async Task ConvertAsync(string projectFilePath) document.Save(writer); // Preserves original formatting, avoids extra lines } } + + public static string DetectLineEnding(string filePath) + { + using var reader = new StreamReader(filePath); + int ch; + char previousChar = '\0'; + + while ((ch = reader.Read()) != -1) + { + char currentChar = (char)ch; + + if (currentChar == '\n') + { + return previousChar == '\r' ? "\r\n" : "\n"; + } + + previousChar = currentChar; + } + + // Default to system line ending if no line ending found + return Environment.NewLine; + } } } diff --git a/src/PackageReferenceVersionToAttributeExtensionTests/ConvertPackageReferenceVersionElementsToAttributesCommandTests.cs b/src/PackageReferenceVersionToAttributeExtensionTests/ConvertPackageReferenceVersionElementsToAttributesCommandTests.cs index 841703a..53e8368 100644 --- a/src/PackageReferenceVersionToAttributeExtensionTests/ConvertPackageReferenceVersionElementsToAttributesCommandTests.cs +++ b/src/PackageReferenceVersionToAttributeExtensionTests/ConvertPackageReferenceVersionElementsToAttributesCommandTests.cs @@ -161,8 +161,7 @@ public async Task ExecuteAsync_WithOneSelectedProject_SucceedsAsync() this.command.Invoke(null); // Assert - Assert.AreEqual( - """ + string expectedContents = """ net8.0 @@ -171,12 +170,13 @@ public async Task ExecuteAsync_WithOneSelectedProject_SucceedsAsync() - """, - project.Contents); + """; + Assert.AreEqual(expectedContents, project.Contents); string backupFilePath = $"{project.Path}.bak"; Assert.IsTrue(File.Exists(backupFilePath)); - Assert.AreEqual(Contents, File.ReadAllText(backupFilePath)); + string actualContents = File.ReadAllText(backupFilePath); + Assert.AreEqual(Contents, actualContents); } /// diff --git a/src/PackageReferenceVersionToAttributeTool/ProgramCommand.cs b/src/PackageReferenceVersionToAttributeTool/ProgramCommand.cs index 92fe7ed..a12f8b5 100644 --- a/src/PackageReferenceVersionToAttributeTool/ProgramCommand.cs +++ b/src/PackageReferenceVersionToAttributeTool/ProgramCommand.cs @@ -20,7 +20,7 @@ public ProgramCommand() { var inputsArgument = new Argument( name: "inputs", - description: "The project files or wildcard patterns to convert.") + description: "The file paths and patterns which match solution and project files to convert.") { Arity = ArgumentArity.OneOrMore, }; diff --git a/src/PackageReferenceVersionToAttributeToolTests/HelpTests.cs b/src/PackageReferenceVersionToAttributeToolTests/HelpTests.cs new file mode 100644 index 0000000..c302ff4 --- /dev/null +++ b/src/PackageReferenceVersionToAttributeToolTests/HelpTests.cs @@ -0,0 +1,37 @@ +// +// Copyright (c) Rami Abughazaleh. All rights reserved. +// + +namespace PackageReferenceVersionToAttributeToolTests +{ + using System.IO; + using Microsoft.VisualStudio.TestTools.UnitTesting; + using PackageReferenceVersionToAttributeTool; + using static PackageReferenceVersionToAttributeToolTests.ToolRunner.ToolRunner; + + /// + /// Contains unit tests for verifying the expected behavior for the `--help` parameter of the tool. + /// + [TestClass] + public class HelpTests + { + /// + /// Verifies that a call to + /// with the `--help` parameter, + /// returns a successful exit code and displays the command line usage on the console. + /// + /// A representing the asynchronous unit test. + [TestMethod] + public async Task Run_WithHelpParameter_DisplaysUsage() + { + // Act + var result = await RunToolAsync("--help"); + + // Assert + Assert.AreEqual(0, result.ExitCode, result.OutputAndError); + + var expectedOutput = await File.ReadAllTextAsync("Usage.txt"); + Assert.AreEqual(expectedOutput, result.Output.Trim(), result.OutputAndError); + } + } +} \ No newline at end of file diff --git a/src/PackageReferenceVersionToAttributeToolTests/InputTests.cs b/src/PackageReferenceVersionToAttributeToolTests/InputTests.cs index 01059fc..dbda076 100644 --- a/src/PackageReferenceVersionToAttributeToolTests/InputTests.cs +++ b/src/PackageReferenceVersionToAttributeToolTests/InputTests.cs @@ -86,7 +86,7 @@ Converting PackageReference Version child elements to attributes in the project result.OutputAndError); Assert.AreEqual(string.Empty, result.Error.Trim()); - Assert.AreEqual( + string expectedContents = """ @@ -96,8 +96,9 @@ Converting PackageReference Version child elements to attributes in the project - """, - projectA.ReadAllText()); + """; + string actualContents = projectA.ReadAllText(); + Assert.AreEqual(expectedContents, actualContents); } /// diff --git a/src/PackageReferenceVersionToAttributeToolTests/Usage.txt b/src/PackageReferenceVersionToAttributeToolTests/Usage.txt index 1f73609..7721e5c 100644 --- a/src/PackageReferenceVersionToAttributeToolTests/Usage.txt +++ b/src/PackageReferenceVersionToAttributeToolTests/Usage.txt @@ -5,7 +5,7 @@ Usage: PackageReferenceVersionToAttributeTool ... [options] Arguments: - The project files or wildcard patterns to convert. + The file paths and patterns which match solution and project files to convert. Options: -b, --backup Create a backup of the project files.