From 2c93189d8dfbf8f1e4dc5d1ffe755a8dcc5dd3d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojciech=20Nag=C3=B3rski?= Date: Wed, 23 Jan 2019 14:32:57 +0100 Subject: [PATCH] Support attribute of array of FileInfo or DirectoryInfo --- .../ParsingValidationTests.cs | 127 ++++++++++++++++++ .../Builder/ArgumentExtensions.cs | 20 +++ 2 files changed, 147 insertions(+) diff --git a/src/System.CommandLine.Tests/ParsingValidationTests.cs b/src/System.CommandLine.Tests/ParsingValidationTests.cs index 03f53e13fd..df7b676a6a 100644 --- a/src/System.CommandLine.Tests/ParsingValidationTests.cs +++ b/src/System.CommandLine.Tests/ParsingValidationTests.cs @@ -5,6 +5,7 @@ using System.CommandLine.Invocation; using System.IO; using System.Linq; +using System.Reflection; using FluentAssertions; using Xunit; using Xunit.Abstractions; @@ -192,6 +193,66 @@ public void An_argument_can_be_invalid_based_on_file_existence() e.Message == $"File does not exist: {guid}"); } + [Fact] + public void An_argument_with_multiple_file_info_can_be_invalid_based_on_first_file_existence() + { + var command = new Command( + "move", + argument: new Argument + { + Arity = ArgumentArity.ZeroOrMore + }.ExistingOnly()); + command.AddOption( + new Option( + "--to", + argument: new Argument + { + Arity = ArgumentArity.ExactlyOne + })); + + Guid guid1 = Guid.NewGuid(); + Guid guid2 = Guid.NewGuid(); + var result = + command.Parse( + $@"move ""{guid1}"" ""{guid2}"" --to ""{Path.Combine(Directory.GetCurrentDirectory(), ".trash")}"""); + + result.Errors + .Should() + .HaveCount(1) + .And + .Contain(e => e.SymbolResult.Name == "move" && e.Message == $"File does not exist: {guid1}"); + } + + [Fact] + public void An_argument_with_multiple_file_info_can_be_invalid_based_on_second_file_existence() + { + var command = new Command( + "move", + argument: new Argument + { + Arity = ArgumentArity.ZeroOrMore + }.ExistingOnly()); + command.AddOption( + new Option( + "--to", + argument: new Argument + { + Arity = ArgumentArity.ExactlyOne + })); + + var executingAssemblyLocation = Assembly.GetExecutingAssembly().Location; + var guid = Guid.NewGuid(); + var result = + command.Parse( + $@"move ""{executingAssemblyLocation}"" ""{guid}"" --to ""{Path.Combine(Directory.GetCurrentDirectory(), ".trash")}"""); + + result.Errors + .Should() + .HaveCount(1) + .And + .Contain(e => e.SymbolResult.Name == "move" && e.Message == $"File does not exist: {guid}"); + } + [Fact] public void An_argument_can_be_invalid_based_on_directory_existence() { @@ -223,6 +284,72 @@ public void An_argument_can_be_invalid_based_on_directory_existence() e.Message == $"Directory does not exist: {trash}"); } + [Fact] + public void An_argument_with_multiple_directory_info_can_be_invalid_based_on_first_directory_existence() + { + var command = new Command( + "move", + argument: new Argument + { + Arity = ArgumentArity.ExactlyOne + }); + command.AddOption( + new Option("--to", + argument: new Argument + { + Arity = ArgumentArity.ZeroOrMore + }.ExistingOnly())); + + var currentDirectory = Directory.GetCurrentDirectory(); + var trash1 = Path.Combine(currentDirectory, ".trash1"); + var trash2 = Path.Combine(currentDirectory, ".trash2"); + + var commandLine = $@"move ""{currentDirectory}"" --to ""{trash1}"" ""{trash2}"""; + + var result = command.Parse(commandLine); + + _output.WriteLine(result.Diagram()); + + result.Errors + .Should() + .HaveCount(1) + .And + .Contain(e => e.SymbolResult.Name == "to" && e.Message == $"Directory does not exist: {trash1}"); + } + + [Fact] + public void An_argument_with_multiple_directory_info_can_be_invalid_based_on_second_directory_existence() + { + var command = new Command( + "move", + argument: new Argument + { + Arity = ArgumentArity.ExactlyOne + }); + command.AddOption( + new Option("--to", + argument: new Argument + { + Arity = ArgumentArity.ZeroOrMore + }.ExistingOnly())); + + var currentDirectory = Directory.GetCurrentDirectory(); + var executionAssemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + var trash = Path.Combine(currentDirectory, ".trash2"); + + var commandLine = $@"move ""{currentDirectory}"" --to ""{executionAssemblyPath}"" ""{trash}"""; + + var result = command.Parse(commandLine); + + _output.WriteLine(result.Diagram()); + + result.Errors + .Should() + .HaveCount(1) + .And + .Contain(e => e.SymbolResult.Name == "to" && e.Message == $"Directory does not exist: {trash}"); + } + [Fact] public void A_command_with_subcommands_is_invalid_to_invoke_if_it_has_no_handler() { diff --git a/src/System.CommandLine/Builder/ArgumentExtensions.cs b/src/System.CommandLine/Builder/ArgumentExtensions.cs index 34eba9613e..359d651dd8 100644 --- a/src/System.CommandLine/Builder/ArgumentExtensions.cs +++ b/src/System.CommandLine/Builder/ArgumentExtensions.cs @@ -59,6 +59,26 @@ public static Argument ExistingOnly(this Argument return argument; } + public static Argument ExistingOnly(this Argument argument) + { + argument.AddValidator(symbol => + symbol.Arguments + .Where(filePath => !File.Exists(filePath)) + .Select(symbol.ValidationMessages.FileDoesNotExist) + .FirstOrDefault()); + return argument; + } + + public static Argument ExistingOnly(this Argument argument) + { + argument.AddValidator(symbol => + symbol.Arguments + .Where(filePath => !Directory.Exists(filePath)) + .Select(symbol.ValidationMessages.DirectoryDoesNotExist) + .FirstOrDefault()); + return argument; + } + public static TArgument LegalFilePathsOnly( this TArgument argument) where TArgument : Argument