Coder Social home page Coder Social logo

elixir_git_hooks's Introduction

Coverage Status Hex version Hex Docs Build Status Inline docs

GitHooks πŸͺ

Configure git hooks in your Elixir projects.

Main features:

  • Simplicity: Automatic or manually install the configured git hook actions.
  • Flexibility: You choose what to use to define the git hooks actions:
    • Bash commands
    • Executable files
    • Elixir modules
  • No limits: Any git hook is and will be supported out of the box, you can check here the git hooks list available.

Table of Contents

Installation

Add to dependencies:

def deps do
  [
    {:git_hooks, "~> 0.7.0", only: [:dev], runtime: false}
  ]
end

Then install and compile the dependencies:

mix deps.get && mix deps.compile

Backup current hooks

This library will backup automatically your current git hooks before overwriting them.

The backup files will have the file extension .pre_git_hooks_backup.

Automatic installation

This library will install automatically the configured git hooks in your config.exs file.

See configuration to disable the automatic install.

Manual installation

You can manually install the configured git hooks at any time by running:

mix git_hooks.install

Configuration

Auto install

To disable the automatic install of the git hooks set the configuration key auto_install to false.

Hook configuration

One or more git hooks can be configured, those hooks will be the ones installed in your git project.

Currently there are supported two configuration options:

  • tasks: A list of the commands that will be executed when running a git hook. See types of tasks for more info.
  • verbose: If true, the output of the mix tasks will be visible. This can be configured globally or per git hook.
  • branches: Allow or forbid the hook configuration to run (or not) in certain branches using whitelist or blacklist configuration (see example below). You can use regular expressions to match a branch name.

Git submodules

This library supports git submodules, just add your git_hooks configuration to any of the submodules projects.

Setting a custom git hooks config path is also supported:

git config core.hooksPath .myCustomGithooks/

Custom project path

This library assumes a simple Elixir project architecture. This is, an Elixir project in the root of a git repository.

If you have a different project architecture, you can specify the absolute path of your project using the project_path configuration:

{project_path, 0} = System.cmd("pwd", [])
project_path = String.replace(project_path, ~r/\n/, "/")

config :git_hooks,
  hooks: [
    pre_commit: [
      tasks: [
        {:cmd, "mix format --check-formatted"}
      ]
    ]
  ],
  project_path: project_path

Custom mix path

This library expects elixir to be installed in your system and the mix binary to be available. If you want to provide a specific path to run the mix executable, it can be done using the mix_path configuration.

The following example would run the hooks on a docker container:

config :git_hooks,
  auto_install: false,
  mix_path: "docker-compose exec mix",
Troubleshooting in docker containers

The mix_path configuration can be used to run mix hooks on a Docker container. If you have a TTY error running mix in a Docker container use docker exec --tty $(docker-compose ps -q web) mix as the mix_path. See this issue as reference.

Example config

In config/config.exs

use Mix.Config

# somewhere in your config file
if Mix.env() == :dev do
  config :git_hooks,
    auto_install: true,
    verbose: true,
    branches: [
      whitelist: ["feature-.*"],
      blacklist: ["master"]
    ],
    hooks: [
      pre_commit: [
        tasks: [
          {:cmd, "mix format --check-formatted"}
        ]
      ],
      pre_push: [
        verbose: false,
        tasks: [
          {:cmd, "mix dialyzer"},
          {:cmd, "mix test --color"},
          {:cmd, "echo 'success!'"}
        ]
      ]
    ]
end

Task types

For more information, check the module documentation for each of the different supported tasks.

Mix task

This is the preferred option to run mix tasks, as it will provide the best execution feedback.

Just add in your config the mix tasks you want to run. You can also set the args to be used by the mix task:

config :git_hooks,
  verbose: true,
  hooks: [
    commit_msg: [
      tasks: [
        {:mix_task, :test},
        {:mix_task, :format, ["--dry-run"]}
      ]
    ]
  ]

By default this library expects by default the following return values from mix tasks:

0
:ok
nil

If you want to support additional success return values from your mix tasks, you can add them by adding the following configuration:

config :git_hooks,
  extra_success_returns: [
    {:noop, []},
    {:ok, []}
  ]

Command

To run a simple command you can either declare a string or a tuple with the command you want to run. For example, having "mix test" and {:cmd, "mix test"} in the hook tasks will be equivalent.

If you want to forward the git hook arguments, add the option include_hook_args: true.

config :git_hooks,
  verbose: true,
  hooks: [
    commit_msg: [
      tasks: [
        {:cmd, "echo 'test'"},
        {:cmd, "elixir ./priv/test_task.ex", include_hook_args: true},
      ]
    ]
  ]

Executable file

The following configuration uses a script file to be run with a git hook. If you want to forward the git hook arguments, add the option include_hook_args: true.

config :git_hooks,
  verbose: true,
  hooks: [
    commit_msg: [
      tasks: [
        {:file, "./priv/test_script"},
        {:file, "./priv/test_script_with_args", include_hook_args: true},
      ]
    ]
  ]

The script file executed will receive the arguments from git, so you can use them as you please.

Elixir module

It is also possible to use Elixir modules to execute actions for a given git hook.

Just add in your config the MFA ({module, function, arity}) definition:

config :git_hooks,
  verbose: true,
  hooks: [
    commit_msg: [
      tasks: [
        {MyModule, :execute, 2}
      ]
    ]
  ]

To check how many args you function should expect check the git documentation to know which parameters are being sent on each hook.

Removing a hook

When a git hook configuration is removed, the installed hook will automatically delete it.

Any backup done at the moment will still be kept.

Execution

Automatic execution

The configured mix tasks will run automatically for each git hook.

Manual execution

You can also run manually any configured git hook as well.

The following example will run the pre_commit configuration:

mix git_hooks.run pre_commit

It is also possible to run all the configured hooks:

mix git_hooks.run all

Copyright and License

Copyright Β© 2022 AdriΓ‘n QuintΓ‘s

Source code is released under the MIT license.

elixir_git_hooks's People

Contributors

akoutmos avatar celaxodon avatar clinejj avatar dependabot-preview[bot] avatar dependabot-support avatar dependabot[bot] avatar drobban avatar kianmeng avatar laibulle avatar mjc avatar paulo-silva avatar pojiro avatar qgadrian avatar thomas9911 avatar wentsul avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

elixir_git_hooks's Issues

Running pre-commit hook only for staged files

I'm trying to implement a pre-commit hook that would run mix format and mix credo only on staged files, but defining hook e.g.
config :git_hooks, hooks: [ pre_commit: [ verbose: true, tasks: [ {:mix_task, :credo} ], ] ]
runs mix credo for all source files. Is it possible to define the hook to take only the staged files as arguments for the mix command?
Writing a script for this works when I execute it with {:cmd, "bash script.sh"} but I don't get the colored output I can by running the mix task, and {:file, "script.sh"} fails because of :eacces error. Any guidance would be appreciated!

Don't run the hook when nothing in the project root has changed

Once #106 is merged, when your elixir app is inside a subdirectory, it will always run even if what is changed is outside your elixir project.

On pre-push, provided hooks should make use of the commit information provided by git on stdin to check if any of the commits being pushed touch things inside the project root.

I don't think it's appropriate to check only {lib,test} as it's possible to put code outside that location.

We also should not start mix to determine this.

commits=$(git rev-list -n 1 "$range" -- $project_path)
if [ "$commits" != "" ]
then
  ...
fi

this pseudocode should mostly work.

pre-push.sample shows how to get $range populated correctly.

Confusion after rebuilding dependencies until git_hooks.install

Just a request for consideration to add some hint in the documentation should you run into unchecked dependencies errors after changes to dependencies after hooks are installed or on newly cloned repos that don't auto install hooks. For example, if you blow away deps and re-build them, you apparently need to install the git_hooks again if they use a dependency (such as credo). Not sure why this is but it is very very confusing because running a git command that triggers a pre-commit (for example) will result in something like

Unchecked dependencies for environment dev:

  • blankable (Hex package)
    the dependency is not available, run "mix deps.get"
  • ex_doc (Hex package)
    the dependency is not available, run "mix deps.get"
  • recase (Hex package)
    the dependency is not available, run "mix deps.get"
  • dialyxir (Hex package)
    the dependency is not available, run "mix deps.get"
  • credo (Hex package)
    the dependency is not available, run "mix deps.get"
    ** (Mix) Can't continue due to errors on dependencies

Re-running mix git_hooks.install will solve this issue. I found this after experimenting with latest live_view (0.18) and then trying to revert. Chased my tail re-installing hex/phoenix, clobbering deps, mix deps.clean... anyway, it wasn't until I cloned the repo on a different machine that I got the same result until I installed the git hooks.

So, this probably warrants either some research about why this happens and maybe some note in the readme. Thanks for such a useful tool.

To repro:

  1. in working repro with pre-commit hooks that use dependencies (like credo, doctor...), remove the deps folder
  2. mix do deps.get, deps.compile
  3. any git command that triggers a hook (for example the pre-commit via git commit) will fail with (Mix) Can't continue due to errors on dependencies...
  4. solved by running mix git_hooks.install again

Add support to mix tasks results

Mix tasks raise an error if they are valid, but determining if they are successful or not depends on the return of the task.

This library needs to support to handle mix task results on the project configuration, right now only the "common cases" are controlled.

Meanwhile, using command line tasks is preferred.

/dev/tty: Device not configured in pre-commit hook

I am using construction like this in my pre-commit hook:

exec </dev/tty

	read -n 1 -p "Are you sure, you want to continue? [Ny] " yesno

	case $yesno in
	[yY])
		echo "OK"
		;;

	*)
		echo "Doing nothing."
		exit 1
		;;
	esac

	exec <&-

If I run the pre-commit hook directly from my terminal, it works. If I run it with elixir_git_hooks configured like this:

config :git_hooks,
  verbose: true,
  auto_install: true,
  hooks: [
    pre_commit: [
      tasks: [
        {:file, ".githooks/pre-commit"}
      ]
    ]
  ]

It raises an exception saying that .githooks/pre-commit: line 22: /dev/tty: Device not configured

On line 22, is this: exec </dev/tty

Any idea how I could fix this error?

Thanks a lot. :-)

Couldn't find git_hooks.db file

Hi,

As I understand it, hooks aren't version controlled. Also, when you clone a repository, this will not bring down the .git/hooks/* directory with it.

With that said, when I run mix deps.get, I get this error

==> git_hooks
Compiling 5 files (.ex)
β†— Installing git hooks...
⚠ Couldn't find git_hooks.db file, won't be able to restore old backups: %File.Error{action: "open", path: "/Users/oliverswitzer/workspace/fusign/deps/../.git/hooks/git_hooks.db", reason: :enoent}
⚠ Check that you are not missing `.git` folder, otherwise open a ticket at https://github.com/qgadrian/elixir_git_hooks/issues/new
Generated git_hooks app

I do not have a .git/hooks directory because I cloned this repo. Is it possible to initialize the hooks directory if it doesn't exist, instead of blowing up like this?

Handling version control of hooks seems like a main feature for this repo, so I was hoping that people cloning repos wouldn't have to get in the nitty gritty of creating the hooks directory themselves in order to use this lib.

Returning non-zero status code from executable script for commit-msg hook does not abort git commit

Hi,

In the Git documentation for commit-msg git hook it says that "Exiting with a non-zero status causes the command to abort".

But if I configure elixir_git_hooks as follows:

config/config.exs:

config :git_hooks,
    verbose: true,
    hooks: [
      commit_msg: [
        tasks: [
          {:file, "./priv/conv_commit_msg_check.sh", include_hook_args: true}
        ]
      ]
    ]

./priv/conv_commit_msg_check.sh:

#!/bin/sh
MSG_FILE=$1
MSG_HEAD=$(head -1 $MSG_FILE)

export REGEX='^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\([a-z]+\))?: [a-z ]+$'
export ERROR_MSG="Commit message format must match regex \"${REGEX}\""

if [[ ! $MSG_HEAD =~ $REGEX ]]; then
  echo "Bad commit head \"$MSG_HEAD\""
  echo $ERROR_MSG
  exit 1
fi

exit 0

When I commit with an invalid message, I get:

β†— Running hooks for :commit_msg
Bad commit head "Ok."
Commit message format must match regex "^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\([a-z]+\))?: [a-z ]+$"
[master 631f559] Ok.
 2 files changed, 26 insertions(+), 1 deletion(-)
 create mode 100755 priv/conv_commit_msg_check.sh

So, the git hook script works (it prints "Bad commit head"), but the commit is not aborted.

This is because elixir_git_hooks is running mix git_hooks.run commit_msg "$@", but as far as I know, mix <task> will always return 0 status code even when you do exit(1) from your code in Mix.Tasks.<task>.run(_).

The only way to force mix <task> to return a non-zero return code is to raise an error from the mix task run(_) function.

So I guess that changing the call to error_exit() from lib/mix/tasks/git_hooks/run.ex#L138 to instead raise an exception will fix this, at least in the case of commit-msg git hook. But I am not sure if this is OK for the other git-hooks.

Thank you,
Dan

feature request: allow tasks to be configured to run in parallel

it would be awesome to allow tasks to be run in parallel to speed things up. perhaps something like:

config :git_hooks,
  hooks: [
    pre_commit: [
      tasks: [
        {:parallel, [
          {:serial, [
            {:mix_task, :format, ["--check-formatted"]},
            {:mix_task, :test},
          ]},
          {:serial, [
            {:cmd, "npm run lint-staged --prefix infrastructure"},
            {:cmd, "npm test --prefix infrastructure"}
          ]}
        ]}
      ]
    ]
  ]

Pre-commit hook appears execute after commit has taken place

Hi.

I have my project set up similarly to that described in README.md:

if Mix.env() != :prod do
  config :git_hooks,
    auto_install: true,
    verbose: true,
    hooks: [
      pre_commit: [
        tasks: [
          {:cmd, "mix format"}
        ]
      ],
      pre_push: [
        tasks: [
          {:cmd, "mix credo --strict"},
          {:cmd, "mix dialyzer"},
          {:cmd, "mix test"}
        ]
      ],
      post_checkout: [
        tasks: [
          {:cmd, "mix deps.get"}
        ]
      ]
    ]
end

The pre_push and post_checkout hooks work fine.

The pre_commit hook does execute, but it executes after the commit has taken place. What I then end up with is:

  1. A commit with unformatted files in it
  2. A bunch of staged changes with formatted files

Any ideas what I'm doing wrongly? Is this a bug? If so any extra information I can gather?

git_hooks.run not found

After the update to 0.7.0, we received the message git_hooks.run not found, which will be related to the project path. It won't support spaces around the route.

I'm open to doing a PR

suggested change for the cd.

[ "$project_path" != "" ] && cd "$project_path"

With older git returns an error

with git version before 2.22

run:

> mix git_hooks.run all
error: unknown option `show-current'

I looked up on the internet and you can get the version with:

git rev-parse --abbrev-ref HEAD

as well

Document how to override the MIX_ENV when running hooks

I have a typical use case, a pre_push hook will run tests before uploading patches to the remote repository. The default environment is dev so , but my tests should run in the test environment. I end up having to run this awkward command to get the correct environment:

MIX_ENV=test git push

Is there a recommended way to transparently override the environment? Should this be included in the documentation?

mix compile --warnings-as-errors succeeds, but git_hooks registers as a failure

Hey there,

We noticed that after upgrading from 0.6.4 --> 0.7.0+, one of the steps in our pre-push pipeline was breaking. This was due to mix compile --warnings-as-errors returning {:noop, []} and that isn't one of the "successes" here. Unsure if there is more complexity other than adding the result there? Happy to open a PR, if so lemme know

As a workaround, we've changed our config from...

config :git_hooks,
  hooks: [
    pre_push: [
      tasks: [
        {:mix_task, :compile, ["--warnings-as-errors"]}
      ]
    ]
  ]

to this, for the time being...

config :git_hooks,
  hooks: [
    pre_push: [
      tasks: [
        {:cmd, "mix compile --warnings-as-errors"}
      ]
    ]
  ]

Exact error wording:

Γ— mix task `compile` failed, return result: {:noop, []}

mono-repo with multiple applications

Hello,

I'm using a mono-repo with multiple applications in their sub-directory, like

repo
└─ .git
└─ app1
   └─ .git
└─ app2
   └─ .git

So far, I had installed git_hooks v0.6.5 in the app sub-directories for some pre_commit hook defined for ex. in repo/app1/config/config.exs like

if Mix.env() != :prod do
  config :git_hooks,
    auto_install: true,
    verbose: true,
    hooks: [
      pre_commit: [
        tasks: [
          {:cmd, "mix credo"},
...

but it never worked for me: hooks never got fired automatically.
Then I saw #96.
So I removed repo/app1/.git/hooks/ and I updated to git_hooks v0.7.1
Before that, I had only .samples in repo/.git/hooks/.
After the update, a new pre-commit file appeared in repo/.git/hooks that showed

#!/bin/sh
[ "/Users/jerome/repo/app1/deps/git_hooks" != "" ] && cd /Users/jerome/repo/app1/deps/git_hooks

mix git_hooks.run pre_commit "$@"
[ $? -ne 0 ] && exit 1
exit 0

So, it seems to me that it shouldn't work if I would do it also in app2/, doesn't it?

Then I tried anyway to commit a file in app1/ with some credo issue I introduced, which produced

repo> cd app1
app1> git commit -m 'test pre-commit hook' lib/app1/worker.ex
Unchecked dependencies for environment dev:
* blankable (Hex package)
  the dependency is not available, run "mix deps.get"
* ex_doc (Hex package)
  the dependency is not available, run "mix deps.get"
* recase (Hex package)
  the dependency is not available, run "mix deps.get"
* dialyxir (Hex package)
  the dependency is not available, run "mix deps.get"
* credo (Hex package)
  the dependency is not available, run "mix deps.get"
** (Mix) Can't continue due to errors on dependencies

So maybe I did something wrong, but I can't get it to work in my case.
If, just for testing, I change pre-commit to be

#!/bin/sh
#[ "/Users/jerome/repo/app1/deps/git_hooks" != "" ] && cd /Users/jerome/repo/app1/deps/git_hooks
cd /Users/jerome/repo/app1
...

Then the same test would work

repo> cd app1
app1> git commit -m 'test pre-commit hook' lib/app1/worker.ex
β†— Running hooks for :pre_commit
...
Γ— `pre_commit`: `mix credo` execution failed

Any thought about that? πŸ™‚

[Feature request] overriding the git hook so that we can make it run mix tasks inside of docker compose

My team uses docker compose to run our Phoenix app and try to execute all of our mix tasks within that context with

docker-compose exec mix <insert task here>

(We do this to avoid having to set up the elixir/erlang ecosystem on every new dev machine)

It would be amazing if it were possible to override the default installed git hook to use docker-compose exec mix <elixir git hooks task> instead of mix <elixir git hook task> so we don't have to have mix on our local machine. I would add this functionality myself and open a PR, but I wasn't totally sure where I would do that... I know Mix.Tasks.GitHooks.Install would likely have to be modified, but I don't know how we would thread a config value that might override mix to be docker-compose exec mix... to that install function.

Ideally, we could specify this some key in our config for git hooks that would tell elixir_git_hooks to install the git hook with a slightly different prefix than mix. Does this seem possible?

Thanks in advance!

Passing git hook args to the scripts

This project is very nice, thank you for your time and effort :-)

I was considering using it in my current project, but one of our usecase is to append commit message with the branch ticket number (example: my branch is feature/23_awesome_feature I want my commit to be named #23 Nice commit message) and one of the way to achieve that is to use the commit-msg git hook.

This hook receives one argument, the temporary commit message file path, and expects the script to modify the file and return 0 (success code) or anything else (error code).

Except if I am mistaken, but here the scripts do not receive any args. Is there any reason for that ? I would gladly do a pull request to add that feature if you want :) .

Invalid hook path and script when using git_path

Hello,

I have a git repository, where the Elixir project is inside a subfolder (let's say ./my_app/) instead of being at the root of the git repo. The README suggests that we can use the git_path option in that case. So I have the following directory structure:

β”œβ”€ .git/
└─ my_app/
   β”œβ”€ mix.exs
   β”œβ”€ config/
   β”‚  └─ config.exs
   └─ ...

and the following config:

  config :git_hooks,
    git_path: "../.git",
    auto_install: true,
    verbose: true,
    hooks: [
      pre_commit: [
        tasks: [
          {:cmd, "mix format --check-formatted"}
        ]
      ]
    ]

When I run mix compile, I see

==> git_hooks
Compiling 15 files (.ex)
β†— Installing git hooks...

But I see no hook in my .git directory. Instead, it seems to have used my_app/deps/.git as I have a my_app/deps/.git/hooks/pre-commit file in there.

When I install the hooks manually though, it works:

❯ mix git_hooks.install
β†— Installing git hooks...
β†— Writing git hook for `pre_commit` to `../.git/hooks/pre-commit`
β†— Backing up git hook file `../.git/hooks/pre-commit` to `../.git/hooks/pre-commit.pre_git_hooks_backup`

However, I get another problem after that: the hook script does not take into account the location of my project:

#!/bin/sh

# There should be a `cd /my_app` here
mix git_hooks.run pre_commit "$@"
[ $? -ne 0 ] && exit 1
exit 0
fi

If I try to commit I get:

** (Mix) The task "git_hooks.run" could not be found
Note no mix.exs was found in the current directory

Is there anyhting I'm doing wrong? How can I solve those issues?

Seeing please ensure :git_hooks exists or remove the configuration.

So everything is working but I am seeing this warning for some reason.

Not really sure why.

You have configured application :git_hooks in your configuration file,
but the application is not available.

This usually means one of:

  1. You have not added the application as a dependency in a mix.exs file.

  2. You are configuring an application that does not really exist.

Please ensure :git_hooks exists or remove the configuration.

Cut a new release with updated dependencies

Hello!

I've seen that your deps have been recently updated by dependabot.
Do you think you could try cutting a new release with the updated dependencies?

I'm trying to use recase 0.7.0 but cannot because of the hard dependency git_hooks has on 0.6.0. :(

Maybe soften the version requirement on minor version number? Along the lines of {:recase, "~> 0.7"}.

Colouring of output generated by the hook script is lost

BEGIN RANT
First of all, I was overjoyed to find this! Thanks for doing this! ❀️

I've tried putting verbose instructions (like in this SO post) in our CONTRIBUTING guide to set up our recommended gith-hooks -- but some people just ignore it and get very annoyed when the CI fails their PR because they pushed badly formatted code.

Hopefully, just doing mix git_hooks.install would make things easier 🀞
END RANT


I like to run credo right after I commit, but I lose the beautifully colorized credo output when the hook runs via the mix task πŸ™

Steps to reproduce

My relevant config.exs

config :git_hooks,
  verbose: true,
  hooks: [
    pre_commit: [
      mix_tasks: [
        "format --check-formatted"
      ]
    ],
    post_commit: [
      mix_tasks: [
        "credo --strict"
      ]
    ]
  ]

Expected result

Something like this 🌈 (image).

But got this: (image)

No colors

Compilation error when export `deps_path` is set

When deps_path is set to a directory outside of the project workspace, build and hook installation fail. I suppose that the library is installed there and the git rev-parse --git-path "" command is executed in that directory, which is not a Git repository indeed. See logs:

==> git_hooks
Compiling 16 files (.ex)
β†— Installing git hooks...
fatal: not a git repository (or any parent up to mount point /home/app)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).

== Compilation error in file lib/git_hooks.ex ==
** (MatchError) no match of right hand side value: {"", 128}
    lib/git/path.ex:50: GitHooks.Git.Path.resolve_git_path_based_on_git_version/1
    lib/git/path.ex:15: GitHooks.Git.Path.resolve_app_path/0
    lib/mix/tasks/git_hooks/install.ex:48: Mix.Tasks.GitHooks.Install.install/1
    lib/git_hooks.ex:7: (module)
could not compile dependency :git_hooks, "mix compile" failed. You can recompile this dependency with "mix deps.compile git_hooks", update it with "mix deps.update git_hooks" or clean it with "mix deps.clean git_hooks"

0.6.5 release

Is there a plan to release 0.6.5 soon?
I am just waiting for ae998f3 to be included in the next release.

Add `auto install` option

Add auto install option to allow having the git hooks configuration and leveraing on developers if they want to install or not.

Using && within a :cmd appears to be a problem?

In a pre-commit hook I've got:

{:cmd, "mix ecto.create && mix ecto.migrate && mix ecto.rollback --all"}

Results in

** (Mix) Could not invoke task "ecto.create": 1 error found!
--all : Unknown option

Almost as if it's trying to run mix ecto.create --all

Permission issue when trying deleting old git hook

Hi, thanks for maintining this library for us all to use!!

There seems to be a bug with permissions introduced in 7655a94 which I suspects happens when we try to delete the old git hook files. I tried to run the command with and without sudo permissions and without.

I can confirm that 0.2.0 runs fine!

[jiachen@jiachen cadet]$ uname -a
Linux jiachen 4.19.42-1-MANJARO #1 SMP PREEMPT Fri May 10 20:52:43 UTC 2019 x86_64 GNU/Linux
[jiachen@jiachen cadet]$ mix --version
Erlang/OTP 21 [erts-10.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]

Mix 1.8.1 (compiled with Erlang/OTP 20)
[jiachen@jiachen cadet]$ mix git_hooks.run pre_commit

** (File.Error) could not remove files and directories recursively from "/home/jiachen/Desktop/source-academy/shuming/cadet/_build/dev/lib/git_hooks": permission denied
    (elixir) lib/file.ex:1252: File.rm_rf!/1
    (mix) lib/mix/tasks/deps.compile.ex:66: anonymous fn/4 in Mix.Tasks.Deps.Compile.compile/2
    (elixir) lib/enum.ex:1327: Enum."-map/2-lists^map/1-0-"/2
    (elixir) lib/enum.ex:1327: Enum."-map/2-lists^map/1-0-"/2
    (mix) lib/mix/tasks/deps.compile.ex:64: Mix.Tasks.Deps.Compile.compile/2
    (mix) lib/mix/tasks/deps.loadpaths.ex:89: Mix.Tasks.Deps.Loadpaths.deps_check/2
    (mix) lib/mix/tasks/deps.loadpaths.ex:28: Mix.Tasks.Deps.Loadpaths.run/1
    (mix) lib/mix/task.ex:331: Mix.Task.run_task/3
[jiachen@jiachen cadet]$ sudo mix git_hooks.run pre_commit
[sudo] password for jiachen: 
==> git_hooks
Compiling 5 files (.ex)
⚠ Remove old git hook ``

== Compilation error in file lib/git_hooks.ex ==
** (File.Error) could not remove file "/home/jiachen/Desktop/source-academy/shuming/cadet/deps/../.git/hooks": not owner
    (elixir) lib/file.ex:1092: File.rm!/1
    (elixir) lib/enum.ex:769: Enum."-each/2-lists^foreach/1-0-"/2
    (elixir) lib/enum.ex:769: Enum.each/2
    lib/mix/tasks/git_hooks/install.ex:40: Mix.Tasks.GitHooks.Install.install/1
    lib/git_hooks.ex:5: (module)
could not compile dependency :git_hooks, "mix compile" failed. You can recompile this dependency with "mix deps.compile git_hooks", update it with "mix deps.update git_hooks" or clean it with "mix deps.clean git_hooks"
[jiachen@jiachen cadet]$ mix git_hooks.run pre_commit
** (File.Error) could not remove files and directories recursively from "/home/jiachen/Desktop/source-academy/shuming/cadet/_build/dev/lib/git_hooks": permission denied
    (elixir) lib/file.ex:1252: File.rm_rf!/1
    (mix) lib/mix/tasks/deps.compile.ex:66: anonymous fn/4 in Mix.Tasks.Deps.Compile.compile/2
    (elixir) lib/enum.ex:1327: Enum."-map/2-lists^map/1-0-"/2
    (mix) lib/mix/tasks/deps.compile.ex:64: Mix.Tasks.Deps.Compile.compile/2
    (mix) lib/mix/tasks/deps.loadpaths.ex:89: Mix.Tasks.Deps.Loadpaths.deps_check/2
    (mix) lib/mix/tasks/deps.loadpaths.ex:28: Mix.Tasks.Deps.Loadpaths.run/1
    (mix) lib/mix/task.ex:331: Mix.Task.run_task/3
    (mix) lib/mix/task.ex:355: Mix.Task.get_task_or_run/3

Pre commit/push hooks fail in the latest version

Hi πŸ‘‹ ,

Thanks for this project!

Pre-commit or push hooks fail in the latest version for me under macOS Monterey 12.3 (whether it matters), I wonder if conditional cd shown in the screenshot is the culprit. (this commit)

image

image

My config:

if Mix.env() == :dev do
  config :git_hooks,
    verbose: true,
    hooks: [
      pre_commit: [
        tasks: [
          {:cmd, "mix format --check-formatted"}
        ]
      ],
      pre_push: [
        tasks: [
          {:cmd, "mix quality"}
        ]
      ]
    ]
end

Seem to work fine with the version 0.6.5.

How to reproduce:

  1. Download git_hooks_bug.zip
  2. mix deps.get && mix compile
  3. touch test.txt && git commit -m whatever

only flag of mix dependencies doesnt work

I did add git_hooks configs to the config.exs file and set only flag for [:dev, :test] to be used but in case of PROD environment, i see the following logs.

You have configured application :git_hooks in your configuration file,
but the application is not available.

This usually means one of:

1. You have not added the application as a dependency in a mix.exs file.

2. You are configuring an application that does not really exist.

Please ensure :git_hooks exists or remove the configuration.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.