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

.MapResultAsync not working #809

Closed
asterictnl-lvdw opened this issue Mar 28, 2022 · 4 comments
Closed

.MapResultAsync not working #809

asterictnl-lvdw opened this issue Mar 28, 2022 · 4 comments

Comments

@asterictnl-lvdw
Copy link

Using the Pull from #390 I get an error when trying to use .MapResultAsync it does not exist in version 2.9.0preview1???

Changing it to MapResult makes the code work. But is Async not implemented correctly?

using CommandLine;
using CommandLine.Text;
using System;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    [Verb("add", HelpText = "Add file contents to the index.")]
    class AddOptions
    {
        //normal options here
    }

    [Verb("commit", HelpText = "Record changes to the repository.")]
    class CommitOptions
    {
        //normal options here
    }

    [Verb("clone", HelpText = "Clone a repository into a new directory.")]
    class CloneOptions
    {
        //normal options here
    }

    class Program
    {
        static async Task<int> Main(string[] args)
        {
            var parserResult = new Parser(c => c.HelpWriter = null);
            return await parserResult.ParseArguments<AddOptions, CommitOptions, CloneOptions>(args)
              .MapResult(
                (AddOptions opts) => RunAddAndReturnExitCodeAsync(opts),
                (CommitOptions opts) => RunCommitAndReturnExitCodeAsync(opts),
                (CloneOptions opts) => RunCloneAndReturnExitCodeAsync(opts),
                errs => Console.WriteLine(DisplayHelp()));
        }

        static Task<int> RunAddAndReturnExitCodeAsync(AddOptions opts)
        {
            throw new NotImplementedException();
        }

        private static Task<int> RunCommitAndReturnExitCodeAsync(CommitOptions opts)
        {
            throw new NotImplementedException();
        }

        private static Task<int> RunCloneAndReturnExitCodeAsync(CloneOptions opts)
        {
            throw new NotImplementedException();
        }

        private static async Task<int> DisplayHelp<T>(ParserResult<T> result)
        {
            var helpText = HelpText.AutoBuild(result, h =>
            {
                h.AdditionalNewLineAfterOption = false;
                h.Heading = "Myapp 2.0.0-beta"; //change header
                h.Copyright = "Copyright (c) 2019 Global.com"; //change copyright text
                return h;
            },
            e => e,
            verbsIndex: true);  //set verbsIndex to display verb help summary.
            Console.WriteLine(helpText);
            return -1;
        }
    }
}

Furthermore, I want to implement the custom help screen into the mapped results. I do need to change the Parser.Default for this. I have looked at the examples, but I couldn't get it to work.

Question: What do I need to change at errs => Console.WriteLine(DisplayHelp())); in order to make it work?

@elgonzo
Copy link

elgonzo commented Mar 28, 2022

I get an error when trying to use .MapResultAsync it does not exist in version 2.9.0preview1???

Nope, it does not (unless you somehow find some hidden or abandoned source code file that declares this method ¯\(ツ)/¯ ).
If interested, you might read the discussion and follow the commits about MapResultAsync in the PR you linked to...

Question: What do I need to change at errs => Console.WriteLine(DisplayHelp())); in order to make it work?

Do you mean you want to pass the ParserResult produced by parserResult.ParseArguments<AddOptions, CommitOptions, CloneOptions>(args) to your DisplayHelp() method? If so, that should be simple to realize. Try something similar like this (untested!):

    var parser = new Parser(c => c.HelpWriter = null);
    var parseResult = parser.ParseArguments<AddOptions, CommitOptions, CloneOptions>(args);
    parseResult.MapResult(
        (AddOptions opts) => RunAddAndReturnExitCodeAsync(opts),
        (CommitOptions opts) => RunCommitAndReturnExitCodeAsync(opts),
        (CloneOptions opts) => RunCloneAndReturnExitCodeAsync(opts),
        errs => Console.WriteLine(DisplayHelp(parseResult))
    );

(P.S.: Your variable name is utterly confusing and misplaced here: var parserResult = new Parser(c => c.HelpWriter = null);. A parser is a parser. A parser is not a parser result. I changed that silly variable name in my code snippet.)

@asterictnl-lvdw
Copy link
Author

@elgonzo
I have tried the last line, but that didnt work. Let me explain what is the matter:
The Main Task is asynchronous.

Program.DisplayHelp needs to have a (ParserResult).
If I add then I get the error cannot convert from CommandLine.Parser to CommandLine.ParserResult<System.Threating.Tasks.Task>. This is because of Main being a Task and DisplayHelp being an Task as well.

I will look at the code with a professional C# Coder as well so he can help me if possible if I do not get the answer from here.

@elgonzo
Copy link

elgonzo commented Mar 29, 2022

Program.DisplayHelp needs to have a (ParserResult).
If I add then I get the error cannot convert from CommandLine.Parser to CommandLine.ParserResult<System.Threating.Tasks.Task>.

If DisplayHelp needs a ParserResult<T> instance, don't pass a Parser instance to it -- pass the ParserResult to it. Pay attention to the P.S. in my last post underneath my code example. In my code example i did change the variable name regarding the parser to make the code less confusing.

This is because of Main being a Task and DisplayHelp being an Task as well.

How did you come to that conclusion? How could Main and DisplayHelp being async possibly explain why your code is passing a Parser instead of a ParserResult<T> instance? That doesn't make any sense.

@asterictnl-lvdw
Copy link
Author

@elgonzo

Solved it by modifying the implementation of #633 This looks like a working example without any return value instead.

Thanks for trying to help me out. :)

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