How would one lint files staged to commit, not all files in the project, using mix credo
, mix format
, etc?
In the JavaScript ecosystem this is accomplished with lint-staged
and husky
. Elixir has its version of the husky package called git_hooks
, but I haven't found anything resembling lint-staged.
Is there an elixir package that exists to accomplish my goal of only running lint commands when I commit elixir files?
Example config I run with git_hook in config/dev.ex.
config :git_hooks,
auto_install: true,
verbose: true,
mix_path: "docker exec --tty $(docker-compose ps -q web) mix",
hooks: [
pre_commit: [
tasks: [
{:mix_task, :format, ["--check-formatted"]},
{:mix_task, :credo, ["--strict"]}
]
]
]
I got this working with git_hooks package and with the following:
config/dev.ex
config :git_hooks,
auto_install: true,
verbose: true,
mix_path: "docker exec --tty $(docker-compose ps -q web) mix",
hooks: [
pre_commit: [
tasks: [{:file, "./priv/githooks/pre_commit.sh"}]
]
]
priv/githooks/pre_commit.sh
#!/bin/ash
# notice the hash bang is for alpine linux's ash
# run mix format
git diff --name-only --cached | grep -E ".*\.(ex|exs)$" | xargs mix format --check-formatted
# run mix credo
git diff --name-only --cached | xargs mix credo --strict
Using the file task type, I used the git diff command and piped the staged files to the different mix commands for linting.