From 8fbcc33ff3f8940429a89fc0882723e221408546 Mon Sep 17 00:00:00 2001 From: kapsiR Date: Wed, 13 May 2020 15:28:26 +0200 Subject: [PATCH 1/2] Fix unparsing FileInfo and DirectoryInfo This treats FileInfo and DirectoryInfo as special as e.g. DateTime. Unparsing a FileInfo or DirectoryInfo works now with a path that contains spaces. Fixes #626 --- src/CommandLine/UnParserExtensions.cs | 3 ++- .../Fakes/Options_With_FileDirectoryInfo.cs | 18 ++++++++++++++++++ .../Unit/UnParserExtensionsTests.cs | 19 +++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 tests/CommandLine.Tests/Fakes/Options_With_FileDirectoryInfo.cs diff --git a/src/CommandLine/UnParserExtensions.cs b/src/CommandLine/UnParserExtensions.cs index 63921e22..76757138 100644 --- a/src/CommandLine/UnParserExtensions.cs +++ b/src/CommandLine/UnParserExtensions.cs @@ -2,6 +2,7 @@ using System; using System.Collections; +using System.IO; using System.Linq; using System.Text; using CommandLine.Core; @@ -204,7 +205,7 @@ private static string FormatValue(Specification spec, object value) private static object FormatWithQuotesIfString(object value) { - if (value is DateTime || value is DateTimeOffset) return $"\"{value}\""; + if (value is DateTime || value is DateTimeOffset || value is FileInfo || value is DirectoryInfo) return $"\"{value}\""; Func doubQt = v => v.Contains("\"") ? v.Replace("\"", "\\\"") : v; diff --git a/tests/CommandLine.Tests/Fakes/Options_With_FileDirectoryInfo.cs b/tests/CommandLine.Tests/Fakes/Options_With_FileDirectoryInfo.cs new file mode 100644 index 00000000..0d05afbf --- /dev/null +++ b/tests/CommandLine.Tests/Fakes/Options_With_FileDirectoryInfo.cs @@ -0,0 +1,18 @@ +// Copyright 2005-2015 Giacomo Stelluti Scala & Contributors. All rights reserved. See License.md in the project root for license information. + +using System.IO; + +namespace CommandLine.Tests.Fakes +{ + public class Options_With_FileDirectoryInfo + { + [Option('s', "stringPath")] + public string StringPath { get; set; } + + [Option('f', "filePath")] + public FileInfo FilePath { get; set; } + + [Option('d', "directoryPath")] + public DirectoryInfo DirectoryPath { get; set; } + } +} diff --git a/tests/CommandLine.Tests/Unit/UnParserExtensionsTests.cs b/tests/CommandLine.Tests/Unit/UnParserExtensionsTests.cs index 1c295642..d25c99e1 100644 --- a/tests/CommandLine.Tests/Unit/UnParserExtensionsTests.cs +++ b/tests/CommandLine.Tests/Unit/UnParserExtensionsTests.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using Xunit; using FluentAssertions; @@ -23,6 +24,15 @@ public static void UnParsing_instance_returns_command_line(Simple_Options option .Should().BeEquivalentTo(result); } + [Theory] + [MemberData(nameof(UnParseFileDirectoryData))] + public static void UnParsing_instance_returns_command_line_for_file_directory_paths(Options_With_FileDirectoryInfo options, string result) + { + new Parser() + .FormatCommandLine(options) + .Should().BeEquivalentTo(result); + } + [Theory] [MemberData(nameof(UnParseDataVerbs))] public static void UnParsing_instance_returns_command_line_for_verbs(Add_Verb verb, string result) @@ -298,6 +308,15 @@ public static IEnumerable UnParseData } } + public static IEnumerable UnParseFileDirectoryData + { + get + { + yield return new object[] { new Options_With_FileDirectoryInfo(), "" }; + yield return new object[] { new Options_With_FileDirectoryInfo { FilePath = new FileInfo(@"C:\my path\with spaces\file with spaces.txt"), DirectoryPath = new DirectoryInfo(@"C:\my path\with spaces\"), StringPath = @"C:\my path\with spaces\file with spaces.txt" }, @"--directoryPath ""C:\my path\with spaces\"" --filePath ""C:\my path\with spaces\file with spaces.txt"" --stringPath ""C:\my path\with spaces\file with spaces.txt""" }; + } + } + public static IEnumerable UnParseDataVerbs { From eeb3ee40336b904e1daf269b91c1a6bc0eb8d500 Mon Sep 17 00:00:00 2001 From: kapsiR Date: Mon, 15 Jun 2020 23:45:32 +0200 Subject: [PATCH 2/2] Change FormatWithQuotesIfString to accept any string with spaces (PR feedback) Feedback via issue comment: https://github.com/commandlineparser/commandline/issues/626#issuecomment-644399305 --- src/CommandLine/UnParserExtensions.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/CommandLine/UnParserExtensions.cs b/src/CommandLine/UnParserExtensions.cs index 76757138..8e726ca5 100644 --- a/src/CommandLine/UnParserExtensions.cs +++ b/src/CommandLine/UnParserExtensions.cs @@ -2,7 +2,6 @@ using System; using System.Collections; -using System.IO; using System.Linq; using System.Text; using CommandLine.Core; @@ -205,14 +204,16 @@ private static string FormatValue(Specification spec, object value) private static object FormatWithQuotesIfString(object value) { - if (value is DateTime || value is DateTimeOffset || value is FileInfo || value is DirectoryInfo) return $"\"{value}\""; + string s = value.ToString(); + if (!string.IsNullOrEmpty(s) && !s.Contains("\"") && s.Contains(" ")) + return $"\"{s}\""; + Func doubQt = v => v.Contains("\"") ? v.Replace("\"", "\\\"") : v; - return (value as string) - .ToMaybe() - .MapValueOrDefault(v => v.Contains(' ') || v.Contains("\"") - ? "\"".JoinTo(doubQt(v), "\"") : v, value); + return s.ToMaybe() + .MapValueOrDefault(v => v.Contains(' ') || v.Contains("\"") + ? "\"".JoinTo(doubQt(v), "\"") : v, value); } private static char SeperatorOrSpace(this Specification spec)