Skip to content

Commit

Permalink
Merge pull request #146 from inaka/jfacorro.144.install.git-hook
Browse files Browse the repository at this point in the history
[Closes #144] 'install git-hook' command
  • Loading branch information
Brujo Benavides committed Oct 21, 2014
2 parents 46cc1fa + 8914d20 commit 14437d4
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 1 deletion.
6 changes: 6 additions & 0 deletions src/elvis.erl
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,9 @@ process_commands([rock | Cmds], Config) ->
process_commands([help | Cmds], Config) ->
Config = help(Config),
process_commands(Cmds, Config);
process_commands(['install', 'git-hook' | Cmds], Config) ->
elvis_git:install_hook(),
process_commands(Cmds, Config);
process_commands(['git-hook' | Cmds], Config) ->
git_hook(Config),
process_commands(Cmds, Config);
Expand Down Expand Up @@ -220,6 +223,9 @@ rock Rock your socks off by running all rules to your source files.
git-hook Pre-commit Git Hook: Gets all staged files and runs the rules
specified in the configuration to those
files.
install git-hook
Installs Elvis as a pre-commit hook in your current working
directory, which should be a git repository.
">>,
io:put_chars(Commands).

Expand Down
49 changes: 48 additions & 1 deletion src/elvis_git.erl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
-export([
staged_files/0,
staged_content/1,
relative_position/2
relative_position/2,
install_hook/0
]).

-define(LIST_STAGED,
Expand All @@ -12,6 +13,8 @@
-define(STAGED_CONTENT(Path),
"git show :" ++ Path).

-define(PRE_COMMIT_FILE, ".git/hooks/pre-commit").

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Public
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Expand Down Expand Up @@ -56,10 +59,54 @@ relative_position([Line | Lines], Num, Positions) ->
relative_position(Lines, Num, NewPositions)
end.

%% @doc Install a pre commit hook for the git repository
%% in the current dir.
-spec install_hook() -> ok.
install_hook() ->
try
check_git_dir(),
ok = filelib:ensure_dir(?PRE_COMMIT_FILE),
add_pre_commit_hook(),
elvis_utils:info("Elvis pre-commit hook installed. "
"Wop-bop-a-loom-a-blop-bam-boom!")
catch
_:Reason ->
elvis_utils:error_prn(Reason)
end.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Private
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% @doc Check if the current dir is a git repository.
check_git_dir() ->
case filelib:is_dir(".git") of
true -> ok;
false -> throw("Not a git repository.")
end.

%% @doc Adds elvis as a pre commit hook. If a pre-commit file already exists
%% appends the command to it, otherwise the file is created.
add_pre_commit_hook() ->
Filename = ?PRE_COMMIT_FILE,

Header = <<"#!/bin/sh\n">>,
Command = <<"elvis git-hook\n">>,

{Mode, Data} =
case filelib:is_file(Filename) of
true ->
{ok, Content} = file:read_file(?PRE_COMMIT_FILE),
case binary:match(Content, <<"elvis">>) of
nomatch -> {[append], Command};
_ -> throw("Elvis is already installed as a git hook.")
end;
false -> {[write], <<Header/binary, Command/binary>>}
end,

file:write_file(Filename, Data, Mode),
os:cmd("chmod +x " ++ ?PRE_COMMIT_FILE).

%% @private
%% @doc Return the corresponding local and global line increments based
%% on the line's type.
Expand Down

0 comments on commit 14437d4

Please sign in to comment.