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

Document the unusual behaviour of ** in glob option #941

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

jamiecobbett
Copy link

@jamiecobbett jamiecobbett commented Jan 30, 2025

⚡ Summary

I had assumed that glob patterns work like they do with the *nix ls command, or in tools like lint-staged. I can imagine people expecting it to behave the same.

It seems that ** is interpreted as a single asterisk, ie meaning "1+ directories deep", rather than "0 or more directories deep".

Whilst there is a link to the Go glob library used, and that README mentions double asterisks, I was mainly left confused by it:

Syntax is inspired by standard wildcards, except that ** is aka super-asterisk, that do not sensitive for separators.

I don't think this covers the difference I'm bringing up. I also don't know what is meant by "super-asterisk" here - I'd love to know!

More details, including an example are in the commit message.

Thanks for making such an awesome tool!

I had assumed that glob patterns work like they do with the *nix `ls` command,
or in tools like lint-staged.

It seems that ** is interpreted as a single asterisk for 1+ directories, rather than "0 or more directories deep" as in `ls`.

Whilst there is a link to the Go glob library used, and it mentions double
asterisks, I was mainly left confused by the line in the README:

> Syntax is inspired by [standard
> wildcards](http://tldp.org/LDP/GNU-Linux-Tools-Summary/html/x11655.htm),
> except that ** is aka super-asterisk, that do not sensitive for separators.

Whilst the glob library README could be improved, I think it's natural to use
`ls` to try and test what would be matched (or copy config from tools like
lint-staged or pre-commit), so it would be great to call out this difference in
the lefthook documentation.

It might be quite useful to provide a means of testing/listing what files would
be matched for different commands - I found it necessary to do the below.

Example
=======

Let's say you have a directory structure like:

```
- src
  - foo
    - bar
      - nestedTwice.js
    - nestedOnce.js
  - topLevel.js
```

If you run `ls -1`, you get all three files:
```
ls -1 src/**/*.js
src/foo/bar/nestedTwice.js
src/foo/nestedOnce.js
src/topLevel.js
```

Given this lefthook config

```yaml
pre-commit:
  commands:
    eslint:
      run: ls -1 {staged_files}
      glob: "src/**/*.js"
```

And you run:

```sh
git add src
lefthook run pre-commit
```

The output is missing `src/topLevel.js`:

```
src/foo/bar/nestedTwice.js
src/foo/nestedOnce.js
```
@jamiecobbett
Copy link
Author

jamiecobbett commented Jan 30, 2025

I've also noticed that if you use the root: option, then it seems the paths in glob: don't take that into account - ie you must specify the full path, whereas I assumed it would be relative to the root.

If that's correct, I'm happy to add an explanation to the docs that to this PR, or open a separate one.

You'll need something like:

```yaml
glob: "{src/*.js,src/**/*.js}"
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On further testing, I'm fairly sure you just need glob: "src/*.js"

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

Successfully merging this pull request may close these issues.

1 participant