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

Commit d1ea62d

Browse files
committed
WIP: First stab at git post-commit hook
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
1 parent 678a21e commit d1ea62d

File tree

3 files changed

+49
-0
lines changed

3 files changed

+49
-0
lines changed

hooks/Gemfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
source 'https://rubygems.org'
2+
3+
gem 'parser'
4+
gem 'method_log'

hooks/post-commit

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/usr/bin/env bash
2+
3+
cd .git/hooks
4+
bundle exec ruby post_commit.rb

hooks/post_commit.rb

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
require 'bundler/setup'
2+
3+
require 'method_log/repository'
4+
require 'method_log/method_finder'
5+
require 'method_log/source_file'
6+
7+
def unindent(code)
8+
lines = code.split($/)
9+
indent = lines.reject { |l| l.strip.length == 0 }.map { |l| l[/^ */].length }.min
10+
lines.map { |l| l.sub(Regexp.new(' ' * indent), '') }.join($/)
11+
end
12+
13+
repository_path = File.expand_path('../..')
14+
rugged_repository = Rugged::Repository.new(repository_path)
15+
exit unless rugged_repository.head.name == 'refs/heads/master'
16+
last_commit_sha = rugged_repository.last_commit.oid
17+
18+
repository = MethodLog::Repository.new(repository_path)
19+
last_commit = repository.build_commit(last_commit_sha)
20+
21+
rugged_repository.checkout('method-log')
22+
begin
23+
new_commit = repository.build_commit
24+
last_commit.source_files.each do |source_file|
25+
next if source_file.path[%r{^(vendor|test)}]
26+
begin
27+
method_finder = MethodLog::MethodFinder.new(source_file)
28+
method_finder.instance_variable_get('@methods').each do |method_signature, method_definition|
29+
_, namespace, name = method_signature.match(/^(.*)([#.].*)$/).to_a
30+
path = namespace.split('::').push(name).join(File::SEPARATOR) + '.rb'
31+
new_commit.add(MethodLog::SourceFile.new(path: path, source: unindent(method_definition.source) + $/))
32+
end
33+
rescue Parser::SyntaxError => e
34+
p e
35+
end
36+
end
37+
new_commit.apply(user: last_commit.author, message: last_commit.message)
38+
rugged_repository.reset('HEAD', :hard)
39+
ensure
40+
rugged_repository.checkout('master')
41+
end

0 commit comments

Comments
 (0)