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

Support positional arguments that "correspond" to the configured parameters #121

Open
astrohart opened this issue Jan 23, 2024 · 0 comments

Comments

@astrohart
Copy link

For example, I am writing a console app that renames folders (after retrying 60 times; you know how sometimes, when you go to rename a folder, you cannot because another process is using it).

I wish to configure my console app to be called thus:

C:\>FolderRenamder "C:\Path\To\Current\Folder" "C:\New\Folder\Path"

(I know, I know, there is a move command, but again...I want to have a "retry.")

I've coded up my command-line parser thus:

public static ICommandLineInfo CommandLine(string[] args)
{
    ICommandLineInfo result = default;

    try
    {
        // Dump the collection args to the log
        DebugUtils.WriteLine(
            DebugLevel.Debug,
            $"Parse.CommandLine: args = '{args.ToSetString()}'"
        );

        var p = new FluentCommandLineParser<CommandLineInfo>();

        p.Setup(arg => arg.OldPathname)
         .As('o', "old-pathname")
         .Required();

        p.Setup(arg => arg.NewPathname)
         .As('n', "new-pathname")
         .Required();

        p.Setup(arg => arg.MaxRetries)
         .As('m', "max-retries")
         .SetDefault(60);

        p.SetupHelp("?", "--help")
         .Callback(PrintHelpMessage);

        if (args.Length == 0)
        {
            DebugUtils.WriteLine(
                DebugLevel.Error,
                "*** ERROR *** Zero command line argument(s) were passed.  The old and new folder paths must be passed, at least.  Showing Help message and quitting..."
            );

            p.HelpOption.ShowHelp(p.Options);
            return result;
        }

        var parseResults = p.Parse(args);

        if (parseResults.HasErrors ||
            !CommandLineInfoValidator.IsValid(p.Object)) return result;

        result = p.Object;
    }
    catch (Exception ex)
    {
        // dump all the exception info to the log
        DebugUtils.LogException(ex);

        result = default;
    }

    return result;
}

Assume that the method is in some static class and that all interfaces and properties are defined and imported as you might expect.  The issue I am having is, when I run the app with the _positional command-line arguments_ as shown above, I get that `parseResults.HasErrors` is `true`.  The `CommandLineParserResult.ErrorText` property is equal to `"Option 'o:old-pathname' parse error. option is required but was not specified.\r\nOption 'n:new-pathname' parse error. option is required but was not specified.\r\n"` (I just copied the value straight out of the debugger visualizer btw).

It would be nice to have a fluent method to call on my `Setup()` lines to tell `fclp` to just assume that the first element of `args` is indeed the value of the `OldFilename` and that the second value of the `args` is the `NewFilename`. 

That is, it would be cool if `fclp` supported _positional_ command-line arguments, where it could keep track of _in what order_ command-line options are configured, so that if I then simply pass stuff in in that same order, it will be assumed to be matched with whatever `Setup()` method was called when before `Parse()` is called.
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

1 participant