Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Closes #144] 'install git-hook' command #146

Merged
merged 5 commits into from
Oct 21, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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