Stash modified files only if there were changes

When attempting to commit only a file deletion, that deletion would not
be included in the final commit.

This was caused by the pre-commit `HookContext` hard resetting even if
no changes were stashed. Since we stashed changes only if
`modified_files.any?` returned true, which was false if there were only
deletions, this would result in the deleted file being lost due to the
hard reset.

The solution is to change the check to diff against `HEAD` instead of
just a filtered set of changes.

Change-Id: I01bdda1e10a4241210ada9424a56a5fc8e560d0e
Reviewed-on: http://gerrit.causes.com/35914
Tested-by: jenkins <jenkins@causes.com>
Reviewed-by: Shane da Silva <shane@causes.com>
Test Ruby 2.1.0 via TravisCI

We've already been testing in Ruby 2.1.0 locally, but lets make sure
that contributor's commits are run against 2.1.0 as well.

Change-Id: Ib871fc0166bca2d772983abaf847094ce515d062
Reviewed-on: http://gerrit.causes.com/35915
Tested-by: jenkins <jenkins@causes.com>
Reviewed-by: Shane da Silva <shane@causes.com>
Return :warn instead of :fail on BundleCheck

When rebasing, returning :fail will abort rebase and the repository ends
up with a detached HEAD. Rebase becomes impossible unless you install
the needed gems first.

Change-Id: I6bc22934554dc4b422398082ccf076de97fd0251
Reviewed-on: http://gerrit.causes.com/35952
Tested-by: jenkins <jenkins@causes.com>
Reviewed-by: Shane da Silva <shane@causes.com>
Cut version 0.6.3

Change-Id: I07e8adab91dda82dcc243086bb9ee1c13181a89d
Reviewed-on: http://gerrit.causes.com/35953
Tested-by: jenkins <jenkins@causes.com>
Reviewed-by: Shane da Silva <shane@causes.com>
Add support for invoking processes in JRuby

Previously, we used the `Wopen3` library to simplify the act of
executing an external process and collecting its standard out/error
output and exit status.

Unfortunately, Wopen is implemented using `fork`, which isn't supported
by JRuby. After much research it's clear that this is not a trivial task
to support across multiple platforms, but fortunately there is a gem
called `childprocess` which takes care of this for us.

Unfortunately, to use the gem we have to change the signature of
`command` to take an array of arguments rather than a single shell
string, due to the underlying commands `childprocess` utilizes.

Another thing worth mentioning is that while it's perhaps not ideal to
be using temporary files to capture output when spawning external
processes, I was unable to get this to work consistently when using
straight-up pipes. For now, this implementation works consistently and
is acceptable.

Fixes #32

Change-Id: Ic4aa71ca61d50f38a8e4ea15b8e8dbcf146c1f69
Reviewed-on: http://gerrit.causes.com/35997
Tested-by: jenkins <jenkins@causes.com>
Reviewed-by: Shane da Silva <shane@causes.com>
Fix installer to work in JRuby

JRuby's implementation of `File.symlink?` raises an exception when the
file does not exist, which is different from the default MRI
implementation.

Fix by returning false when that exception is thrown.

Change-Id: I2672acdc265e29e8af1531d4e05293367558dc82
Reviewed-on: http://gerrit.causes.com/35998
Tested-by: jenkins <jenkins@causes.com>
Reviewed-by: Shane da Silva <shane@causes.com>
Ignore SignalException Rubocop check

This convention doesn't seem necessary.

Change-Id: I443032acba887e4bd0856219af1be37b74c5d9eb
Reviewed-on: http://gerrit.causes.com/35999
Tested-by: jenkins <jenkins@causes.com>
Reviewed-by: Shane da Silva <shane@causes.com>
Add TravisCI integration with JRuby

Now that we support JRuby, ensure we run our tests in a JRuby
environment with Travis.

Change-Id: I27fea02ed5c9a42bb38a6f8654599f478ef12fb2
Reviewed-on: http://gerrit.causes.com/36000
Tested-by: jenkins <jenkins@causes.com>
Reviewed-by: Shane da Silva <shane@causes.com>
Rename `command` helper to `execute`

Since we have already changed the signature of this helper in a previous
commit, rename it to further emphasize the difference, as well as make
the method name more verb-like.

Change-Id: Ie768052999d69c03943020b90eaccce9f2ecdb8b
Reviewed-on: http://gerrit.causes.com/36001
Tested-by: jenkins <jenkins@causes.com>
Reviewed-by: Shane da Silva <shane@causes.com>
Ignore SpecialGlobalVars Rubocop check

Including the `English` gem in order to silence this check doesn't seem
worthwhile.

Change-Id: Idc9789e68bc38957b520909c7efa36d92d5f6cb3
Reviewed-on: http://gerrit.causes.com/36002
Tested-by: jenkins <jenkins@causes.com>
Reviewed-by: Shane da Silva <shane@causes.com>
Display better error when hooks already exist

When non-Overcommit hooks were already installed in a repo, Overcommit
would raise an exception. Change the behavior to gracefully catch the
exception and display a normal error message.

Change-Id: Ibc11c3d9f476a47c403133ebe1b90f138078a1ca
Reviewed-on: http://gerrit.causes.com/36003
Tested-by: jenkins <jenkins@causes.com>
Reviewed-by: Shane da Silva <shane@causes.com>
Add --force flag to always overwrite hooks

If a user attempted to install Overcommit hooks into a git repository
that already had non-overcommit hooks, it would report an error. Allow
the user to specify a `--force` flag which disables this error and
ensures the hooks are installed, overwriting if necessary.

Closes #7

Change-Id: I9390e5e122572444202f0b1ef8ae172a15c5b4dc
Reviewed-on: http://gerrit.causes.com/36004
Tested-by: jenkins <jenkins@causes.com>
Reviewed-by: Shane da Silva <shane@causes.com>
Update image_optim development dependency

Change-Id: I01b263713ad1211105e4eab118dbac5da2dacec0
Reviewed-on: http://gerrit.causes.com/36005
Tested-by: jenkins <jenkins@causes.com>
Reviewed-by: Shane da Silva <shane@causes.com>
Cut version 0.7.0

Change-Id: I1f453ed07e9be95f045944bbcffa5775868d96dd
Reviewed-on: http://gerrit.causes.com/36020
Tested-by: jenkins <jenkins@causes.com>
Reviewed-by: Shane da Silva <shane@causes.com>
Add TravisLint pre-commit hook

Add pre-commit hook for checking Travis CI configuration files via the
`travis-lint` gem (https://github.com/travis-ci/travis-lint).

Change-Id: I3584eef11ffe12b1e8a339de531ec1d904842e29
Reviewed-on: http://gerrit.causes.com/36059
Tested-by: jenkins <jenkins@causes.com>
Reviewed-by: Shane da Silva <shane@causes.com>
Rename fail_check matcher to fail_hook

The name `fail_check` is a holdover from Overcommit pre-0.6.0. Change
the name to `fail_hook` to emphasize that it applies to the `Hook`
class (ideally we would just use `fail`, but that is a reserved word).

Also renamed the `CheckMatcher` class to `HookMatcher` and fixed a
Rubocop lint.

Change-Id: I25a5b9fb4ec37bbcb5026fed0810432e40eec7db
Reviewed-on: http://gerrit.causes.com/36060
Tested-by: jenkins <jenkins@causes.com>
Reviewed-by: Shane da Silva <shane@causes.com>
Fix warning messages in HookMatcher on Ruby 1.8.7

Ruby 1.8.7 prints out the following warning wing when using a hook
matcher with no arguments:

    warning: multiple values for a block parameter (0 for 1)

In an effort to quiet these warnings, convert the matchers to accept an
argument splat.

This change also sets us up to easily extend the matchers to support
additional options in the future, should we elect to go down that route.

Change-Id: Ie4e973a895bb1ad6084d1de87028addf4d61a886
Reviewed-on: http://gerrit.causes.com/36061
Tested-by: jenkins <jenkins@causes.com>
Reviewed-by: Shane da Silva <shane@causes.com>
Fix some Rubocop lints

Major offense is the use of redundant `return` in order to avoid having
to specify square brackets for the tuple that gets returned.

Change-Id: Ied0f10a81f2753ca721d5961c08bfb5f93f587cf
Reviewed-on: http://gerrit.causes.com/36062
Tested-by: jenkins <jenkins@causes.com>
Reviewed-by: Shane da Silva <shane@causes.com>
Print notice during inline install of gem

When a user attempts to run an overcommit hook without the `overcommit`
gem being installed, the hook file would ask the user if they wanted to
install the gem. If the user entered "y" and enter, it was possible for
the installation to appear "frozen" as no output would occur for quite
some time while the gems are fetched from Rubygems.

A simple solution is to display an "Installing..." message the moment
the user hits enter, so that they know they should wait (rather than
cancelling assuming something is frozen).

Change-Id: Id660073627258439b6424d6a277f34a4bb88d170
Reviewed-on: http://gerrit.causes.com/36177
Tested-by: jenkins <jenkins@causes.com>
Reviewed-by: Shane da Silva <shane@causes.com>