Tyrrrz / CliWrap

Library for running command-line processes
MIT License
4.32k stars 264 forks source link

Ripgrep returns exit code 1 with no stdout or stderr, can't work out why #190

Closed dracan closed 1 year ago

dracan commented 1 year ago

Version

3.6.0

Details

I'm trying to use this to run Ripgrep, but it always returned errorcode 1 with nothing in the stdout. Not sure why.

Steps to reproduce

Here's an example...

image

On the left, I'm trying to run rg rabbit, and it fails with no reason. On the right, if I use rg --help, this does work.

Running this natively on the command line...

image

So I think that's proving that rg rabbit is writing to the stdout stream. But I can't see why it would fail when running the same command through CliWrap.

Code from screenshot is here:

var result = await Cli.Wrap("rg")
    .WithArguments(new[] {
        "rabbit",
    }, false)
    .WithWorkingDirectory(@"C:\Dump\GrepTest\")
    .WithValidation(CommandResultValidation.None)
    .ExecuteBufferedAsync();

result.Dump()

Ps. just want to also say thank you for the awesome project! I can't believe it's so difficult to do this kind of stuff in .NET natively! Very grateful of you spending the time to make this easier! 🙏🏼

Tyrrrz commented 1 year ago

Hi Dan.

This appears to be happening because rg notices that the standard input stream is redirected and assumes you're passing data to it. This causes it to switch to an alternative behavior, where it searches inside the stdin data, instead of the working directory.

image

You can reproduce this behavior in the terminal like so:

c:\Users\Tyrrr\Downloads\1>echo "foo rabbit bar" | rg rabbit
"foo rabbit bar"

CliWrap always redirects all standard streams and handles piping at a separate layer, so that's why the stdin is redirected even though you didn't pipe anything there. If the stdin is empty (which is the default), rg errors out with exit code 1. It's rather unfortunate that the tool doesn't provide more info in the stderr though.

Anyway, to fix this, you need to override rg's behavior by explicitly telling it to search in the current working directory. You can do that by passing . as the second argument:

var result = await Cli.Wrap("rg")
    .WithArguments(new[] {
        "rabbit",
        "."
    }, false)
    .WithWorkingDirectory(@"C:\Dump\GrepTest\")
    .WithValidation(CommandResultValidation.None)
    .ExecuteBufferedAsync();

result.Dump()

image

dracan commented 1 year ago

HI @Tyrrrz. Thank you so much for looking into that, and for your very detailed reply! Especially as it involved a different tool that you're not involved in 🙏🏼 Good to know for future reference that CliWrap is always redirecting input streams though - as I guess Ripgrep probably isn't going to be the only tool that does similar (I know of a few that act differently when being piped to). Thanks again for the awesome library 🙂

Tyrrrz commented 1 year ago

HI @Tyrrrz. Thank you so much for looking into that, and for your very detailed reply! Especially as it involved a different tool that you're not involved in 🙏🏼 Good to know for future reference that CliWrap is always redirecting input streams though - as I guess Ripgrep probably isn't going to be the only tool that does similar (I know of a few that act differently when being piped to). Thanks again for the awesome library 🙂

You're welcome!