1

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"]}
      ]
    ]
  ]
Adam Millerchip
  • 20,844
  • 5
  • 51
  • 74
user13653
  • 303
  • 3
  • 7
  • Hi! I don't know if there is a package for this, but you might be able to accomplish it using `git diff --name-only | xargs mix credo` (since credo accepts a list of files as arguments). The same can be done with `mix format`. Hope it helps! – sabiwara Dec 20 '21 at 11:38
  • 1
    @sabiwara `diff --name-only --cached | xargs mix credo` need the missing --cached arg. I'll try using this. – user13653 Dec 20 '21 at 21:10

1 Answers1

2

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.

user13653
  • 303
  • 3
  • 7