diff --git a/src/System.CommandLine/ArgumentValidation.cs b/src/System.CommandLine/ArgumentValidation.cs index a4cc6cc3d1..00988ed1f9 100644 --- a/src/System.CommandLine/ArgumentValidation.cs +++ b/src/System.CommandLine/ArgumentValidation.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Collections.Generic; +using System.CommandLine.Parsing; using System.IO; namespace System.CommandLine @@ -18,7 +19,7 @@ public static class ArgumentValidation /// The configured argument. public static Argument AcceptExistingOnly(this Argument argument) { - argument.Validators.Add(Validate.FileExists); + argument.Validators.Add(FileOrDirectoryExists); return argument; } @@ -29,7 +30,7 @@ public static Argument AcceptExistingOnly(this Argument argu /// The configured argument. public static Argument AcceptExistingOnly(this Argument argument) { - argument.Validators.Add(Validate.DirectoryExists); + argument.Validators.Add(FileOrDirectoryExists); return argument; } @@ -40,7 +41,7 @@ public static Argument AcceptExistingOnly(this ArgumentThe configured argument. public static Argument AcceptExistingOnly(this Argument argument) { - argument.Validators.Add(Validate.FileOrDirectoryExists); + argument.Validators.Add(FileOrDirectoryExists); return argument; } @@ -54,18 +55,51 @@ public static Argument AcceptExistingOnly(this Argument argument) { if (typeof(IEnumerable).IsAssignableFrom(typeof(T))) { - argument.Validators.Add(Validate.FileExists); + argument.Validators.Add(FileOrDirectoryExists); } else if (typeof(IEnumerable).IsAssignableFrom(typeof(T))) { - argument.Validators.Add(Validate.DirectoryExists); + argument.Validators.Add(FileOrDirectoryExists); } else { - argument.Validators.Add(Validate.FileOrDirectoryExists); + argument.Validators.Add(FileOrDirectoryExists); } return argument; } + + private static void FileOrDirectoryExists(ArgumentResult result) + where T : FileSystemInfo + { + // both FileInfo and DirectoryInfo are sealed so following checks are enough + bool checkFile = typeof(T) != typeof(DirectoryInfo); + bool checkDirectory = typeof(T) != typeof(FileInfo); + + for (var i = 0; i < result.Tokens.Count; i++) + { + var token = result.Tokens[i]; + + if (checkFile && checkDirectory) + { +#if NET7_0_OR_GREATER + if (!Path.Exists(token.Value)) +#else + if (!Directory.Exists(token.Value) && !File.Exists(token.Value)) +#endif + { + result.AddError(LocalizationResources.FileOrDirectoryDoesNotExist(token.Value)); + } + } + else if (checkDirectory && !Directory.Exists(token.Value)) + { + result.AddError(LocalizationResources.DirectoryDoesNotExist(token.Value)); + } + else if (checkFile && !Directory.Exists(token.Value) && !File.Exists(token.Value)) + { + result.AddError(LocalizationResources.FileDoesNotExist(token.Value)); + } + } + } } } diff --git a/src/System.CommandLine/OptionValidation.cs b/src/System.CommandLine/OptionValidation.cs index c0305ec9fa..647908ee88 100644 --- a/src/System.CommandLine/OptionValidation.cs +++ b/src/System.CommandLine/OptionValidation.cs @@ -18,7 +18,8 @@ public static class OptionValidation /// The option being extended. public static Option AcceptExistingOnly(this Option option) { - option.Argument.Validators.Add(Validate.FileExists); + option._argument.AcceptExistingOnly(); + return option; } @@ -29,7 +30,7 @@ public static Option AcceptExistingOnly(this Option option) /// The option being extended. public static Option AcceptExistingOnly(this Option option) { - option.Argument.Validators.Add(Validate.DirectoryExists); + option._argument.AcceptExistingOnly(); return option; } @@ -40,7 +41,7 @@ public static Option AcceptExistingOnly(this OptionThe option being extended. public static Option AcceptExistingOnly(this Option option) { - option.Argument.Validators.Add(Validate.FileOrDirectoryExists); + option._argument.AcceptExistingOnly(); return option; } @@ -52,10 +53,7 @@ public static Option AcceptExistingOnly(this Option AcceptExistingOnly(this Option option) where T : IEnumerable { - if (option.Argument is Argument arg) - { - arg.AcceptExistingOnly(); - } + option._argument.AcceptExistingOnly(); return option; } diff --git a/src/System.CommandLine/Option{T}.cs b/src/System.CommandLine/Option{T}.cs index fcd623484c..619d1a5be2 100644 --- a/src/System.CommandLine/Option{T}.cs +++ b/src/System.CommandLine/Option{T}.cs @@ -10,7 +10,7 @@ namespace System.CommandLine /// The that the option's arguments are expected to be parsed as. public class Option : Option, IValueDescriptor { - private readonly Argument _argument; + internal readonly Argument _argument; /// public Option( diff --git a/src/System.CommandLine/Validate.cs b/src/System.CommandLine/Validate.cs deleted file mode 100644 index cb0ae6f578..0000000000 --- a/src/System.CommandLine/Validate.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System.CommandLine.Parsing; -using System.IO; - -namespace System.CommandLine; - -internal static class Validate -{ - internal static void FileExists(ArgumentResult result) - { - for (var i = 0; i < result.Tokens.Count; i++) - { - var token = result.Tokens[i]; - - if (!File.Exists(token.Value)) - { - result.AddError(LocalizationResources.FileDoesNotExist(token.Value)); - } - } - } - - internal static void DirectoryExists(ArgumentResult result) - { - for (var i = 0; i < result.Tokens.Count; i++) - { - var token = result.Tokens[i]; - - if (!Directory.Exists(token.Value)) - { - result.AddError(LocalizationResources.DirectoryDoesNotExist(token.Value)); - } - } - } - - internal static void FileOrDirectoryExists(ArgumentResult result) - { - for (var i = 0; i < result.Tokens.Count; i++) - { - var token = result.Tokens[i]; - - if (!Directory.Exists(token.Value) && !File.Exists(token.Value)) - { - result.AddError(LocalizationResources.FileOrDirectoryDoesNotExist(token.Value)); - } - } - } -} \ No newline at end of file