Skip to content
This repository has been archived by the owner on Jul 3, 2020. It is now read-only.

Commit

Permalink
WIP: First stab at git post-commit hook
Browse files Browse the repository at this point in the history
The post-commit hook parses the state of the code after each commit to the
`master` branch, builds a tree of method definition "files" using ri-style
naming, and adds a corresponding commit to the orphan `method-log` branch.

* This code assumes the `method-log` branch already exists.

* I've not thought about what happens if the history on `master` is re-written.

* There is no explicit reference between the commits on `master` and those on
the `method-log` branch.

* I'm not sure how tenable it is to use a `Gemfile` and bundler for this hook.
Maybe an in-line `Gemfile` [1] might be better.

* I've duplicated some code from elsewhere in the repo, e.g. `#unindent`.

* I've used `instance_variable_get` on the instance of `MethodFinder`, but it
would be easy to surface this as a public attribute reader method.

[1]: http://bundler.io/whats_new.html#inline
  • Loading branch information
floehopper committed Jul 17, 2015
1 parent 159d128 commit 937ccc2
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 0 deletions.
4 changes: 4 additions & 0 deletions hooks/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
source 'https://rubygems.org'

gem 'parser'
gem 'method_log'
4 changes: 4 additions & 0 deletions hooks/post-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env bash

cd .git/hooks
bundle exec ruby post_commit.rb
41 changes: 41 additions & 0 deletions hooks/post_commit.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
require 'bundler/setup'

require 'method_log/repository'
require 'method_log/method_finder'
require 'method_log/source_file'

def unindent(code)
lines = code.split($/)
indent = lines.reject { |l| l.strip.length == 0 }.map { |l| l[/^ */].length }.min
lines.map { |l| l.sub(Regexp.new(' ' * indent), '') }.join($/)
end

repository_path = File.expand_path('../..')
rugged_repository = Rugged::Repository.new(repository_path)
exit unless rugged_repository.head.name == 'refs/heads/master'
last_commit_sha = rugged_repository.last_commit.oid

repository = MethodLog::Repository.new(repository_path)
last_commit = repository.build_commit(last_commit_sha)

rugged_repository.checkout('method-log')
begin
new_commit = repository.build_commit
last_commit.source_files.each do |source_file|
next if source_file.path[%r{^(vendor|test)}]
begin
method_finder = MethodLog::MethodFinder.new(source_file)
method_finder.instance_variable_get('@methods').each do |method_signature, method_definition|
_, namespace, name = method_signature.match(/^(.*)([#.].*)$/).to_a
path = namespace.split('::').push(name).join(File::SEPARATOR) + '.rb'
new_commit.add(MethodLog::SourceFile.new(path: path, source: unindent(method_definition.source) + $/))
end
rescue Parser::SyntaxError => e
p e
end
end
new_commit.apply(user: last_commit.author, message: last_commit.message)
rugged_repository.reset('HEAD', :hard)
ensure
rugged_repository.checkout('master')
end

0 comments on commit 937ccc2

Please sign in to comment.