Always work with UTF-8 for commit messages

I've observed mysterious failures to parse commit messages with UTF-8
characters in them on the CentOS box where I am running the Twigg app.
This same box handles the same repos just fine on the command line, but
explodes within the context of the Sinatra app.

Specifically, a commit message with UTF-8 in it (specifically, some em
dashes) was bailing when the parser tried to match a regex against a
line. Debugging statements revealed that the string contained multibyte
UTF-8 encoded codepoints, but Ruby was marking the string as
"ASCII-8BIT", and an invalid one at that.

Alas, due to our office move I am unable to troubleshoot this further
(the machine is down for the weekend), but I was able to establish that
the fix applied in this commit works. Specifically, the call to
`#force_encoding` fixes the problem; I added the `--encoding=UTF-8` arg
to `git log` just to be totally explicit and robust in the face of odd
local configuration or other unpredictable factors.

Maybe when the machine comes back up I'll be able to do more digging to
figure out what bizarre circumstance is forcing the log output to be
treated as though it weren't UTF-8.

Change-Id: I2116c4dc4a7ff466203a5ec3195e29a5f13cd7b5
Reviewed-on: https://gerrit.causes.com/28302
Reviewed-by: Greg Hurrell <greg@causes.com>
Tested-by: Greg Hurrell <greg@causes.com>
Make twigg-cache gem degrade gracefully in the absence of memcache

If memcached goes down, behave as though everything is a cache miss
rather than exploding with a Dalli::RingError.

As there are only two methods (`#get` and `#set`) which require the
treatment, I did it the dumb and simple way. If we ever need to wrap
more methods like this I'll come up with something DRY-er.

Change-Id: Idad181702ff9616e7147dff26360087bc1462ab0
Reviewed-on: https://gerrit.causes.com/28303
Reviewed-by: Greg Hurrell <greg@causes.com>
Tested-by: Greg Hurrell <greg@causes.com>
Update twigg gem Gemfile.lock

This was overlooked in the release of twigg-app 0.0.5. Bring the
Gemfile.lock up to speed.

Change-Id: I94800895adf68909be2fa9433b3d2467018817a7
Reviewed-on: https://gerrit.causes.com/28304
Reviewed-by: Greg Hurrell <greg@causes.com>
Tested-by: Greg Hurrell <greg@causes.com>
Fix minor cosmetic typos in twigg/lib/twigg/cacher.rb

As most of this code was written late at night, a few cosmetic typos
have crept in. Fix them.

Change-Id: I4c27d775c018ffff6e7bc4337303d1d55a52d9af
Reviewed-on: https://gerrit.causes.com/28305
Reviewed-by: Greg Hurrell <greg@causes.com>
Tested-by: Greg Hurrell <greg@causes.com>
Simplify `require_bundle` Rake task

Change-Id: I326c9bb31cb22614cf05a23232dc395feba9e0ec
Reviewed-on: https://gerrit.causes.com/28306
Reviewed-by: Greg Hurrell <greg@causes.com>
Tested-by: Greg Hurrell <greg@causes.com>
Move RELEASE_PREREQS up into common.rake

For re-use by the different subdirectory Rakefiles.

Change-Id: Ifd0238291f8a6896c7712f23b207d64dcc622a7c
Reviewed-on: https://gerrit.causes.com/28307
Reviewed-by: Greg Hurrell <greg@causes.com>
Tested-by: Greg Hurrell <greg@causes.com>
Use `version` local variable in twigg Rakefile

I am about to substantially copy this Rakefile for the other gem
subdirectories, so I'm moving the version constant into a local
`version` variable so that there are fewer places to edit when switching
to a different gem.

Change-Id: I86110a977f8461cf8ec00471e186a8b11c8ca94e
Reviewed-on: https://gerrit.causes.com/28308
Reviewed-by: Greg Hurrell <greg@causes.com>
Tested-by: Greg Hurrell <greg@causes.com>
Add twigg-cache Rakefile

The contents here are substantially similar to those of the twigg gem's
Rakefile. Now that the two Rakefiles are in place, I'll be DRYing them
up in the next commit or two.

Change-Id: Ifa02cef3c0940f85892fee3ef801109827a94ee4
Reviewed-on: https://gerrit.causes.com/28309
Reviewed-by: Greg Hurrell <greg@causes.com>
Tested-by: Greg Hurrell <greg@causes.com>
Move RSpec Rake stuff up into common.rake

For DRYness.

Change-Id: I1ec3d1529071a895a509c9828f9bc95f70c19dd1
Reviewed-on: https://gerrit.causes.com/28310
Reviewed-by: Greg Hurrell <greg@causes.com>
Tested-by: Greg Hurrell <greg@causes.com>
Fix minor spacing issue in common.rake

Change-Id: I447f7bedbcbad5154fa47286744092cdbc53f253
Reviewed-on: https://gerrit.causes.com/28311
Reviewed-by: Greg Hurrell <greg@causes.com>
Tested-by: Greg Hurrell <greg@causes.com>
Bring all subdirectory Rakefiles up to DRY parity

Move pretty much everything up into common.rake, and ensure that each
subdirectory gem has the prereqs it needs (specifically RSpec) in order
to be able to run all the tasks.

Note that we're using instance variables here to communicate between the
Rakefiles and the common.rake tasks. This was deemed ever so slightly
less ugly than the alternatives (eg. $global vars, ENV vars).

Also note that the `import` statement works a little oddly. At the time
it is evaluated, it effectively acts as an "intent to include" rather
than an immediate evaluation of the contents of the file. Rake will
evaluate it only after it has fully evaluated the including file. This
means that you can't have anything in the including file that depends on
the immediate evaluation of the imported file (for example, constants
defined in the imported file).

This actually means that my intermediate step of moving RELEASE_PREREQS
up into common.rake was a misstep. The evaluation order is:

  - start evaluating Rakefile
  - register intent to evaluate common.rake
  - continue evaluating Rakefile
  - hit RELEASE_PREREQS, go boom

Change-Id: Iaed37bb30ceb2b70b3d83e693d4e650f91749ae0
Reviewed-on: https://gerrit.causes.com/28312
Reviewed-by: Greg Hurrell <greg@causes.com>
Tested-by: Greg Hurrell <greg@causes.com>
Update top-level Rakefile to work with all subdirectory Rakefiles

Change-Id: Ie109130582be14a3b683032a1c9e52a807db55c9
Reviewed-on: https://gerrit.causes.com/28313
Reviewed-by: Greg Hurrell <greg@causes.com>
Tested-by: Greg Hurrell <greg@causes.com>
Pluralize "argument(s)" correctly when warning about ignored args

Spit and polish.

Change-Id: I5832bbde90c5b00767a80a688e52f03d2cc9deda
Reviewed-on: https://gerrit.causes.com/28314
Reviewed-by: Greg Hurrell <greg@causes.com>
Tested-by: Greg Hurrell <greg@causes.com>
Add twigg-pivotal gem

This is a first crude cut at implementing Pivotal Tracker integration.
With this commit, we have a `twigg pivotal stats` subcommand that prints
out a basic overview of the open stories in a Pivotal Tracker instance,
grouped by state (started, delivered etc).

The output is not too pretty, but I'll clean that up in subsequent
commits. The code should be fairly straightforward to plug in to the web
app, and I'll be doing that presently.

As with other elements in Twigg, this is being done as a separate gem in
order to keep the dependency footprint small; not everybody in the world
uses or needs Pivotal Tracker. I opted to use rest-client to talk to the
Pivotal API as the existing Pivotal gems haven't yet been updated for v5
of the API, and are probably overkill for what we need here.

Change-Id: I875a9e34570a8493aec07607e387cae6491959ad
Reviewed-on: https://gerrit.causes.com/28315
Reviewed-by: Greg Hurrell <greg@causes.com>
Tested-by: Greg Hurrell <greg@causes.com>
Add /pivotal page to twigg-app

This brings us up to parity with the command line `twigg pivotal stats`,
and perhaps a little further, because we have links back to the related
Pivotal stories now.

Change-Id: I82eb14f5b7e72fa1abb875d34d5639d8ec6f7a38
Reviewed-on: https://gerrit.causes.com/28316
Reviewed-by: Greg Hurrell <greg@causes.com>
Tested-by: Greg Hurrell <greg@causes.com>
Make /pivotal tables sortable

Change-Id: I2dbfed634195012860dcb6e6a87477f487e22d6b
Reviewed-on: https://gerrit.causes.com/28317
Reviewed-by: Greg Hurrell <greg@causes.com>
Tested-by: Greg Hurrell <greg@causes.com>
Fix bugs with custom inflections

There were a couple of latent bugs in the custom inflection handling of
the `#pluralize` method:

  - it wasn't possible to set up multiple custom inflections
  - storage of custom inflections was not globally shared, but was
    rather happening on a per-instance basis (ie. in the instances of
    the classes where the `Util` module was being mixed-in)

This commit fixes both issues, and adds specs to cover the base
functionality as well as guard against regressions of these specific
issues.

Change-Id: I4e49f5b981193bbaa16e54dcb590efc5adc40932
Reviewed-on: https://gerrit.causes.com/28318
Reviewed-by: Greg Hurrell <greg@causes.com>
Tested-by: Greg Hurrell <greg@causes.com>
Show only summary of Pivotal data on dashboard page

The full output of /pivotal is a bit much for the dashboard page; just
show the summary table instead.

I am not sure if this `summary_only` param is the right way to do this,
but it at least frees me from having to set up another endpoint, so
seems like a reasonable trade off for the time-being.

Change-Id: I6d066fd75c1d506c6292c0e35e5fad30aebd2b3d
Reviewed-on: https://gerrit.causes.com/28319
Reviewed-by: Greg Hurrell <greg@causes.com>
Tested-by: Greg Hurrell <greg@causes.com>
Replace #inject call with simpler #sum

Change-Id: I963ecc137945f2528f961ef00592c55e5f11aee3
Reviewed-on: https://gerrit.causes.com/28320
Reviewed-by: Greg Hurrell <greg@causes.com>
Tested-by: Greg Hurrell <greg@causes.com>
Turn author titles into real tooltips on /pivotal

The Bootstrap-provided tooltips are more usable than the native display
of title attributes, appearing immediately on hover rather than after a
delay. Note that this is still progressive, because the title attribute
is still present.

Change-Id: I8a80db571e766df760dfdbc9393f589667e873ed
Reviewed-on: https://gerrit.causes.com/28321
Reviewed-by: Greg Hurrell <greg@causes.com>
Tested-by: Greg Hurrell <greg@causes.com>