Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ArgumentExtensions.ExistingOnly, but allow "-" for reading standard input #1782

Open
KalleOlaviNiemitalo opened this issue Jun 30, 2022 · 3 comments

Comments

@KalleOlaviNiemitalo
Copy link

In a command-line app, I'd like to define a mandatory argument whose value is either a file path to read that file, or "-" to read standard input. What is the best practice for defining such an argument so that it works properly with completion and validation?

ArgumentExtensions.ExistingOnly can be used to add validation that an Argument<FileInfo> names an existing file, but this of course does not support "-". In 2.0.0-beta4.22272.1, neither ExistingOnly nor the FileInfo type affects completion, but I imagine they could do so in the future.

If I use Argument<FileInfo>, then the problem is how to recognize that the value is "-", rather than e.g. "./-". FileInfo.Name and FileSystemInfo.FullName are not suitable. FileInfo.ToString() could be suitable but the documentation advises against using it, and in Reference Source, there seems to be some logic that might cause ToString() not to return the entire string that was passed to the constructor.

After my app has recognized "-", it can use either Console.In or Console.OpenStandardInput(), depending on whether it needs to read text or binary data. It can also check IStandardIn.IsInputRedirected and refuse to read binary data from standard input unless redirected. #275 does not seem useful to me because it does not cover binary input. I don't care about cancellation #1073.

So then, is the best practice like this:

  • Define the argument as Argument<string>, to avoid any shenanigans from FileInfo.ToString().
  • Add validation similar to ArgumentExtensions.ExistingOnly, but using string rather than FileInfo, and allowing "-".
  • Don't do anything about completion for now. Reconsider after ICompletionSource for file paths? #1697 has been implemented.
@jonsequitur
Copy link
Contributor

jonsequitur commented Jul 2, 2022

My first impression here is that this might be a different type from either string or FileInfo, and perhaps be a new option type we include in the library. Would something like this make sense?

public class StreamInputOption : Option<TextReader>
{
    public StreamInputOption() : base("-")  // 👈Option name is fixed by convention
    { 
        Arity = ArgumentArity.Zero
    }
}

The completions would behave like the planned completions for FileInfo.

@KalleOlaviNiemitalo
Copy link
Author

Not Option<TextReader>, because I need binary input too. I currently have binary input in one command and text input in another, but I am planning to merge them to one command and have an option for the input format (a three-value enum where one of the formats is binary and two are text).

@KalleOlaviNiemitalo
Copy link
Author

If it were an option type, then it would be difficult to implement cat prefix - suffix, where the command reads first one file, then stdin, and finally another file. An Argument<PathOrStdio[]> is a better fit here. Also, cat -- - should still read standard input rather than a "-" file, if I remember correctly. It's not an option even though it starts with -.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants