Add a new option for detecting Ruby files
At the moment pre commit hooks can use
- mime type filters (but there is none for Ruby)
- globs (for .rb) files which miss stuff that has
#!/usr/bin/env rubyat the top or Gemfile. - files to run a custom command, which never gets the --file param that you can pass in
So there is no clean way to define a pre-commit hook that will simply scan all Ruby files, instead you need to rely on location in the filesystem.
Feature request here would be to implement something like:
filetype: ruby
This would make it trivial to build a pre-commit hook that scans all Ruby files in a repo.
Hey @SamSaffron, I've prepared the update https://github.com/evilmartians/lefthook/pull/1185, so it adds text/x-ruby, but it will work only for scripts with shebang like #!/usr/bin/env ruby.
What you ask for is to filter by .rb, shebang, maybe the content, but that's a tricky thing to implement.
What you can do if you know the structure of the project:
pre-commit:
jobs:
- run: echo {staged_files}
glob:
- "Gemfile"
- "ruby-scripts/*"
- "*.rb"
So, in this case you'll have all Gemfiles, ruby scripts (if you know where they are located) and other .rb files. I hope this is helpful.
Thanks so much!
In Discourse's case it is a bit tricky.
At the moment our /bin directory only contains Ruby files, but I worry that someone will check in a bash file there (which seems fair) and then be very confused about linting.
With the mime type change are you going to allow for a mix and match? Stuff that is text/x-ruby OR anything called Gemfile / *.thor and so on. (should we make .thor and .rake file extension ruby?)
We are here at the moment:
https://github.com/discourse/discourse/blob/main/lefthook.yml
@SamSaffron filters are reducing the scope, so in your case adding both glob and file_types will work just like if filte_type is added (which is more restrictive I guess).
But it may work if you had a special job for testing only scripts, like this:
- run: bundle exec stree check Gemfile {staged_files}
glob:
- "bin/*"
file_types:
- "text/x-ruby"
Of course this is kind of duplication, but you may consider using jobs.
I see you're using commands. You can switch to jobs which allow grouping and using one glob setting for many underlying jobs, like this:
pre-commit:
parallel: true
jobs:
- name: Ruby source linting
glob:
- "*.{rb,rake,thor}"
- "Gemfile"
group:
parallel: true
jobs:
- run: bundle exec stree check Gemfile {staged_files}
- run: bundle exec rubocop --force-exclusion {staged_files}
- name: Ruby scripts linting
glob:
- "bin/*"
file_types:
- "text/x-ruby"
group:
parallel: true
jobs:
- run: bundle exec stree check Gemfile {staged_files}
- run: bundle exec rubocop --force-exclusion {staged_files}
Thanks Valentin, yeah makes sense to cut down some of the duplication