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

[Feature Request] Pass arguments to --pre command #2046

Closed
toonn opened this issue Oct 29, 2021 · 12 comments
Closed

[Feature Request] Pass arguments to --pre command #2046

toonn opened this issue Oct 29, 2021 · 12 comments
Labels
doc An issue with or an improvement to documentation. rollup A PR that has been merged with many others in a rollup.

Comments

@toonn
Copy link

toonn commented Oct 29, 2021

Describe your feature request

I'm writing a Git pre-commit hook that should prevent me from committing certain sections I have marked DO NOT COMMIT.

I would like to do something like the following because I only want to grep the parts of files that have been staged:

rg -Fl --pre 'git diff --cached -- $1'  'DO NOT COMMIT'

However, the --pre argument only supports either commands found on the PATH or an absolute path to a file. Right now I'm working around this by using an absolute path to a script, ~/src/repo/.git/hooks/git-diff-cached.sh, but this is a very inelegant approach. It requires me to hardcode the repo's path in the hook. If I want to use this hook in multiple repos I have to either update that path every time or put the script in one central location.

I've attempted to use process substitution, rg -Fl --pre <(printf 'git diff --cached -- $1') 'DO NOT COMMIT' but named pipes are created without execute permission.

Hence, my feature request. Would it be possible to add a flag specifying arguments to be passed to the preprocessing command or having a separate --pre-script flag we can pass a string to rather than a file?

@BurntSushi
Copy link
Owner

I'm not quite following here. Why not do something like git diff ... | rg ... in your hook? The pre flag should really only be relevant when you need to apply a transformation on the content in order to get it from a non-UTF-8 encoding (like a PDF) to a UTF-8 encoding.

@toonn
Copy link
Author

toonn commented Oct 30, 2021

That's because I want to output the filename of the files containing the erroneously committed sections. If there's a match I already know the contents and -l would give me <stdin>, which is useless.

@BurntSushi
Copy link
Owner

Ah I see. Yeah, this isn't really how the --pre flag is intended to be used. This is also a good example of the XY problem: you have a problem, came up with a solution and that solution doesn't quite fit. Which turns into a feature request to tweak that solution, but without actually discussing the full scope of the original problem you're trying to solve. So in that vein, I think the problem you're trying to solve is something like this: I want to write a pre-commit hook that detects if a substring exists in the diffs of any staged files, and if such a substring exists, print the name of the file.

So I think I would solve that problem like so:

for f in $(git diff --cached --name-only); do
 if git diff --cached -- "$f" | rg -qF "TESTING"; then
   echo $f
 fi
done

As for your actual request, the reason why I won't add it is because it complicates things quite a bit. There's a categorical difference between "execute a path" and "execute a path with some arguments." At the OS level, those arguments need to be specified individually, which means ripgrep has to split those arguments somehow. Or accept the arguments in a way where they are already split.

It requires me to hardcode the repo's path in the hook.

Also, I don't think this is true. You should be able to put a script in a repo and then call that script from a git hook. It's not clear to me why you think you need to hard code an absolute path to do this. In particular, from man githooks:

Before Git invokes a hook, it changes its working directory to either $GIT_DIR in a bare repository or the root of the working tree in a non-bare repository.

So just pass a relative path to the --pre flag? Should work fine.

However, the --pre argument only supports either commands found on the PATH or an absolute path to a file.

What gives you that idea?

$ tree
.
├── foo
└── tester

0 directories, 2 files

$ cat foo
abc
def
hij
klm
nop

$ cat tester
#!/bin/sh

exec tac "$@"

$ rg '^\w' foo
1:abc
2:def
3:hij
4:klm
5:nop

$ rg '^\w' foo --pre tac
1:nop
2:klm
3:hij
4:def
5:abc

$ rg '^\w' foo --pre ./tester
1:nop
2:klm
3:hij
4:def
5:abc

@toonn
Copy link
Author

toonn commented Oct 30, 2021

This could indeed be solved with nested for loops. But I hope you can see how it would be a lot more convenient if I could pass a simple command in-line.

The reason I didn't think relative paths would work is I tried it (used a path relative to the hook though, seems like the reason it didn't work, my bad) and the documentation:

This option expects the COMMAND program to either be an absolute path or to be available in your PATH.

I think the feature request does fit the existing option very well but I understand there can be implementation issues that would make a new option necessary. Being able to write a single-line preprocessor is incredibly useful, it could even subsume the current behavior because you could run exec ./my-script or similar. I saw there were a lot of issues about compression levels, this would be easily addressed by being able to pass arguments.

Doesn't ripgrep already need to deal with argument splitting or is that taken care of by the shell? If it is, couldn't the feature just rely on invoking a shell, something like bash -c 'user command'?

@BurntSushi
Copy link
Owner

This could indeed be solved with nested for loops. But I hope you can see how it would be a lot more convenient if I could pass a simple command in-line.

Of course. But the win here is very small and the costs required to achieve that win are pretty high. It's not like the shell I wrote for you is terribly complicated here. And this isn't even something you need to run by hand a lot. You're looking to shove this into a pre-commit hook script and then forget about it. It doesn't make sense to optimize for convenience in those sorts of scenarios IMO.

saw there were a lot of issues about compression levels, this would be easily addressed by being able to pass arguments.

It's also easily solved with a wrapper script.

Doesn't ripgrep already need to deal with argument splitting or is that taken care of by the shell?

The shell.

If it is, couldn't the feature just rely on invoking a shell, something like bash -c 'user command'?

That's a non-starter because it relies on executing a shell. Doesn't work if bash isn't installed.

I think the bottom line here is that the existing facilities are flexible enough to make pretty much anything work, with a simple implementation and obvious behavior, even if it isn't always the most convenient.

It looks like the docs should be updated, but otherwise this is wontfix. Sorry.

@BurntSushi BurntSushi added the doc An issue with or an improvement to documentation. label Oct 30, 2021
@toonn
Copy link
Author

toonn commented Oct 30, 2021

Would a patch that implements a new flag or expands on the behavior of --pre have a chance of being accepted?

@BurntSushi
Copy link
Owner

In order to answer that, I have to know what new behavior it implements... If you're talking about this feature request, then no, it wouldn't, for reasons I already described.

@florianpircher
Copy link

I would love an arguments parameter for --pre as well. For me, a command that I work with validates the file if run as COMMAND FILE and pretty-prints its otherwise binary contents with COMMAND -p FILE (and there are other output forms that are sometimes desired like COMMAND -convert json FILE or COMMAND -convert xml FILE). Sure, I could create a custom script for each output format and specify that script as the command, but allowing for arguments to the command would simplify the process:

rg --pre COMMAND --pre-args '-p' FILE

@BurntSushi
Copy link
Owner

@florianpircher Yes, the intended path here would indeed be to create a custom script for each thing you need.

@florianpircher
Copy link

OK, understandable. I guess this issue can be closed then.

@BurntSushi BurntSushi closed this as not planned Won't fix, can't repro, duplicate, stale Nov 24, 2023
@BurntSushi BurntSushi added wontfix A feature or bug that is unlikely to be implemented or fixed. and removed doc An issue with or an improvement to documentation. labels Nov 24, 2023
@toonn
Copy link
Author

toonn commented Nov 25, 2023

@BurntSushi, you said earlier up the thread that the docs should be updated to properly reflect that --pre works with paths relative to the current working directory. Could this issue be reopened until that is addressed? It doesn't seem to be changed in the man page for 13.0.0 that I have locally.

@BurntSushi BurntSushi reopened this Nov 25, 2023
@BurntSushi BurntSushi added doc An issue with or an improvement to documentation. rollup A PR that has been merged with many others in a rollup. and removed wontfix A feature or bug that is unlikely to be implemented or fixed. labels Nov 25, 2023
@toonn
Copy link
Author

toonn commented Nov 25, 2023

Thank you! ❤️

I still wish the feature would be considered but clearer docs always help.

netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this issue Nov 28, 2023
14.0.2 (2023-11-27)
===================
This is a patch release with a few small bug fixes.

Bug fixes:

* [BUG #2654](BurntSushi/ripgrep#2654):
  Fix `deb` release sha256 sum file.
* [BUG #2658](BurntSushi/ripgrep#2658):
  Fix partial regression in the behavior of `--null-data --line-regexp`.
* [BUG #2659](BurntSushi/ripgrep#2659):
  Fix Fish shell completions.
* [BUG #2662](BurntSushi/ripgrep#2662):
  Fix typo in documentation for `-i/--ignore-case`.


14.0.1 (2023-11-26)
===================
This a patch release meant to fix `cargo install ripgrep` on Windows.

Bug fixes:

* [BUG #2653](BurntSushi/ripgrep#2653):
  Include `pkg/windows/Manifest.xml` in crate package.


14.0.0 (2023-11-26)
===================
ripgrep 14 is a new major version release of ripgrep that has some new
features, performance improvements and a lot of bug fixes.

The headlining feature in this release is hyperlink support. In this release,
they are an opt-in feature but may change to an opt-out feature in the future.
To enable them, try passing `--hyperlink-format default`. If you use [VS Code],
then try passing `--hyperlink-format vscode`. Please [report your experience
with hyperlinks][report-hyperlinks], positive or negative.

[VS Code]: https://code.visualstudio.com/
[report-hyperlinks]: BurntSushi/ripgrep#2611

Another headlining development in this release is that it contains a rewrite
of its regex engine. You generally shouldn't notice any changes, except for
some searches may get faster. You can read more about the [regex engine rewrite
on my blog][regex-internals]. Please [report your performance improvements or
regressions that you notice][report-perf].

[report-perf]: BurntSushi/ripgrep#2652

Finally, ripgrep switched the library it uses for argument parsing. Users
should not notice a difference in most cases (error messages have changed
somewhat), but flag overrides should generally be more consistent. For example,
things like `--no-ignore --ignore-vcs` work as one would expect (disables all
filtering related to ignore rules except for rules found in version control
systems such as `git`).

[regex-internals]: https://blog.burntsushi.net/regex-internals/

**BREAKING CHANGES**:

* `rg -C1 -A2` used to be equivalent to `rg -A2`, but now it is equivalent to
  `rg -B1 -A2`. That is, `-A` and `-B` no longer completely override `-C`.
  Instead, they only partially override `-C`.

Build process changes:

* ripgrep's shell completions and man page are now created by running ripgrep
with a new `--generate` flag. For example, `rg --generate man` will write a
man page in `roff` format on stdout. The release archives have not changed.
* The optional build dependency on `asciidoc` or `asciidoctor` has been
dropped. Previously, it was used to produce ripgrep's man page. ripgrep now
owns this process itself by writing `roff` directly.

Performance improvements:

* [PERF #1746](BurntSushi/ripgrep#1746):
  Make some cases with inner literals faster.
* [PERF #1760](BurntSushi/ripgrep#1760):
  Make most searches with `\b` look-arounds (among others) much faster.
* [PERF #2591](BurntSushi/ripgrep#2591):
  Parallel directory traversal now uses work stealing for faster searches.
* [PERF #2642](BurntSushi/ripgrep#2642):
  Parallel directory traversal has some contention reduced.

Feature enhancements:

* Added or improved file type filtering for Ada, DITA, Elixir, Fuchsia, Gentoo,
  Gradle, GraphQL, Markdown, Prolog, Raku, TypeScript, USD, V
* [FEATURE #665](BurntSushi/ripgrep#665):
  Add a new `--hyperlink-format` flag that turns file paths into hyperlinks.
* [FEATURE #1709](BurntSushi/ripgrep#1709):
  Improve documentation of ripgrep's behavior when stdout is a tty.
* [FEATURE #1737](BurntSushi/ripgrep#1737):
  Provide binaries for Apple silicon.
* [FEATURE #1790](BurntSushi/ripgrep#1790):
  Add new `--stop-on-nonmatch` flag.
* [FEATURE #1814](BurntSushi/ripgrep#1814):
  Flags are now categorized in `-h/--help` output and ripgrep's man page.
* [FEATURE #1838](BurntSushi/ripgrep#1838):
  An error is shown when searching for NUL bytes with binary detection enabled.
* [FEATURE #2195](BurntSushi/ripgrep#2195):
  When `extra-verbose` mode is enabled in zsh, show extra file type info.
* [FEATURE #2298](BurntSushi/ripgrep#2298):
  Add instructions for installing ripgrep using `cargo binstall`.
* [FEATURE #2409](BurntSushi/ripgrep#2409):
  Added installation instructions for `winget`.
* [FEATURE #2425](BurntSushi/ripgrep#2425):
  Shell completions (and man page) can be created via `rg --generate`.
* [FEATURE #2524](BurntSushi/ripgrep#2524):
  The `--debug` flag now indicates whether stdin or `./` is being searched.
* [FEATURE #2643](BurntSushi/ripgrep#2643):
  Make `-d` a short flag for `--max-depth`.
* [FEATURE #2645](BurntSushi/ripgrep#2645):
  The `--version` output will now also contain PCRE2 availability information.

Bug fixes:

* [BUG #884](BurntSushi/ripgrep#884):
  Don't error when `-v/--invert-match` is used multiple times.
* [BUG #1275](BurntSushi/ripgrep#1275):
  Fix bug with `\b` assertion in the regex engine.
* [BUG #1376](BurntSushi/ripgrep#1376):
  Using `--no-ignore --ignore-vcs` now works as one would expect.
* [BUG #1622](BurntSushi/ripgrep#1622):
  Add note about error messages to `-z/--search-zip` documentation.
* [BUG #1648](BurntSushi/ripgrep#1648):
  Fix bug where sometimes short flags with values, e.g., `-M 900`, would fail.
* [BUG #1701](BurntSushi/ripgrep#1701):
  Fix bug where some flags could not be repeated.
* [BUG #1757](BurntSushi/ripgrep#1757):
  Fix bug when searching a sub-directory didn't have ignores applied correctly.
* [BUG #1891](BurntSushi/ripgrep#1891):
  Fix bug when using `-w` with a regex that can match the empty string.
* [BUG #1911](BurntSushi/ripgrep#1911):
  Disable mmap searching in all non-64-bit environments.
* [BUG #1966](BurntSushi/ripgrep#1966):
  Fix bug where ripgrep can panic when printing to stderr.
* [BUG #2046](BurntSushi/ripgrep#2046):
  Clarify that `--pre` can accept any kind of path in the documentation.
* [BUG #2108](BurntSushi/ripgrep#2108):
  Improve docs for `-r/--replace` syntax.
* [BUG #2198](BurntSushi/ripgrep#2198):
  Fix bug where `--no-ignore-dot` would not ignore `.rgignore`.
* [BUG #2201](BurntSushi/ripgrep#2201):
  Improve docs for `-r/--replace` flag.
* [BUG #2288](BurntSushi/ripgrep#2288):
  `-A` and `-B` now only each partially override `-C`.
* [BUG #2236](BurntSushi/ripgrep#2236):
  Fix gitignore parsing bug where a trailing `\/` resulted in an error.
* [BUG #2243](BurntSushi/ripgrep#2243):
  Fix `--sort` flag for values other than `path`.
* [BUG #2246](BurntSushi/ripgrep#2246):
  Add note in `--debug` logs when binary files are ignored.
* [BUG #2337](BurntSushi/ripgrep#2337):
  Improve docs to mention that `--stats` is always implied by `--json`.
* [BUG #2381](BurntSushi/ripgrep#2381):
  Make `-p/--pretty` override flags like `--no-line-number`.
* [BUG #2392](BurntSushi/ripgrep#2392):
  Improve global git config parsing of the `excludesFile` field.
* [BUG #2418](BurntSushi/ripgrep#2418):
  Clarify sorting semantics of `--sort=path`.
* [BUG #2458](BurntSushi/ripgrep#2458):
  Make `--trim` run before `-M/--max-columns` takes effect.
* [BUG #2479](BurntSushi/ripgrep#2479):
  Add documentation about `.ignore`/`.rgignore` files in parent directories.
* [BUG #2480](BurntSushi/ripgrep#2480):
  Fix bug when using inline regex flags with `-e/--regexp`.
* [BUG #2505](BurntSushi/ripgrep#2505):
  Improve docs for `--vimgrep` by mentioning footguns and some work-arounds.
* [BUG #2519](BurntSushi/ripgrep#2519):
  Fix incorrect default value in documentation for `--field-match-separator`.
* [BUG #2523](BurntSushi/ripgrep#2523):
  Make executable searching take `.com` into account on Windows.
* [BUG #2574](BurntSushi/ripgrep#2574):
  Fix bug in `-w/--word-regexp` that would result in incorrect match offsets.
* [BUG #2623](BurntSushi/ripgrep#2623):
  Fix a number of bugs with the `-w/--word-regexp` flag.
* [BUG #2636](BurntSushi/ripgrep#2636):
  Strip release binaries for macOS.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
doc An issue with or an improvement to documentation. rollup A PR that has been merged with many others in a rollup.
Projects
None yet
Development

No branches or pull requests

3 participants