method_log 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/Gemfile +5 -0
- data/LICENSE +19 -0
- data/README.md +34 -0
- data/Rakefile +7 -0
- data/bin/method_log +13 -0
- data/lib/method_log/api.rb +20 -0
- data/lib/method_log/commit.rb +50 -0
- data/lib/method_log/method_commit.rb +25 -0
- data/lib/method_log/method_definition.rb +28 -0
- data/lib/method_log/method_finder.rb +51 -0
- data/lib/method_log/repository.rb +28 -0
- data/lib/method_log/source_file.rb +23 -0
- data/lib/method_log/version.rb +3 -0
- data/lib/method_log.rb +2 -0
- data/method_log.gemspec +25 -0
- data/samples/repository.git/HEAD +1 -0
- data/samples/repository.git/config +5 -0
- data/samples/repository.git/description +1 -0
- data/samples/repository.git/hooks/README.sample +5 -0
- data/samples/repository.git/info/exclude +2 -0
- data/samples/repository.git/objects/45/0ab23bfa0bd482244c42c7e18fad84526258fc +0 -0
- data/samples/repository.git/objects/4c/5ba880d306780e033a5c35d3805b5f6f76aa41 +1 -0
- data/samples/repository.git/objects/b0/3eef6ca386d8463c28dd26f52333aba9af05dc +5 -0
- data/samples/repository.git/objects/e0/ec752ebc5a724d5c2880dce3126948555b9709 +0 -0
- data/samples/repository.git/objects/ef/ebdb1a26d03939042f2f9c09f2aa49d87d1169 +2 -0
- data/samples/repository.git/objects/f6/6529c35058f591594fdc9affad66ebd6a16d0f +1 -0
- data/samples/repository.git/refs/heads/master +1 -0
- data/spec/api_spec.rb +62 -0
- data/spec/commit_spec.rb +45 -0
- data/spec/method_commit_spec.rb +24 -0
- data/spec/method_definition_spec.rb +39 -0
- data/spec/method_finder_spec.rb +53 -0
- data/spec/source_file_spec.rb +35 -0
- data/spec/spec_helper.rb +1 -0
- metadata +129 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6a64a5c77324253051cdea911808a4d26fbcf07a
|
4
|
+
data.tar.gz: 8cf7ac058dea844d6ffbcfff7e87ce7d64bd91bf
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c1a4955bc308e0e733e3f156f44ba796a2ce639660f4988a87949ef7ab6ef85b0dd1975f540c96386cac17ff72ef912700da0d2f3477d863ff5eb6b3b2f428ea
|
7
|
+
data.tar.gz: 7176a109612715acd7b7e57f35800bb2c4c533ccf82b56ccd40dd305f67b0cc9a0f1d96cafa7233bcf24c1f9ae7e168031dd730c5b9e29e4e4b1367a6d85aa7e
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Gemfile.lock
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (C) 2014 by James Mead
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
## Method Log
|
2
|
+
|
3
|
+
Trace the history of an individual method in a git repository.
|
4
|
+
|
5
|
+
### Install
|
6
|
+
|
7
|
+
gem install method_log
|
8
|
+
|
9
|
+
### Run
|
10
|
+
|
11
|
+
method_log <method-signature> # e.g. Foo::Bar#baz
|
12
|
+
|
13
|
+
### Todo
|
14
|
+
|
15
|
+
* Support earlier versions of Ruby
|
16
|
+
* Support class methods
|
17
|
+
* Support namespaced classes e.g. `class Foo::Bar`
|
18
|
+
* Support for Rspec tests
|
19
|
+
* Display diffs in method implementation between commits
|
20
|
+
* Only display diffs when method implementation has changed
|
21
|
+
* Default to looking for git repo in current working directory
|
22
|
+
* Default to looking for commits in current git branch
|
23
|
+
* Maybe add as new git command or extension to existing command e.g. `git log`
|
24
|
+
* Optimise search for method definitions:
|
25
|
+
* First look in file where method was last defined
|
26
|
+
* Simple text search for files containing method name to narrow files that need to be parsed
|
27
|
+
|
28
|
+
### Credits
|
29
|
+
|
30
|
+
Written by [James Mead](http://jamesmead.org) and the other members of [Go Free Range](http://gofreerange.com).
|
31
|
+
|
32
|
+
### License
|
33
|
+
|
34
|
+
Released under the [MIT License](https://github.com/freerange/method_log/blob/master/LICENSE).
|
data/Rakefile
ADDED
data/bin/method_log
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'method_log'
|
5
|
+
require 'method_log/repository'
|
6
|
+
require 'method_log/api'
|
7
|
+
|
8
|
+
repository = MethodLog::Repository.new(path: ARGV[0])
|
9
|
+
api = MethodLog::API.new(repository: repository)
|
10
|
+
method_commits = api.history(ARGV[1])
|
11
|
+
method_commits.each do |method_commit|
|
12
|
+
puts method_commit
|
13
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'method_log/method_finder'
|
2
|
+
require 'method_log/method_commit'
|
3
|
+
|
4
|
+
module MethodLog
|
5
|
+
class API
|
6
|
+
def initialize(repository:)
|
7
|
+
@repository = repository
|
8
|
+
end
|
9
|
+
|
10
|
+
def history(method_identifier)
|
11
|
+
@repository.commits.map do |commit|
|
12
|
+
method_definitions = commit.source_files.inject([]) do |definitions, source_file|
|
13
|
+
method_finder = MethodFinder.new(source_file: source_file)
|
14
|
+
definitions += Array(method_finder.find(method_identifier))
|
15
|
+
end
|
16
|
+
MethodCommit.new(commit: commit, method_definition: method_definitions.first)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'rugged'
|
2
|
+
|
3
|
+
require 'method_log/source_file'
|
4
|
+
|
5
|
+
module MethodLog
|
6
|
+
class Commit
|
7
|
+
attr_reader :sha
|
8
|
+
|
9
|
+
def initialize(repository: repository, sha: sha)
|
10
|
+
@repository = repository
|
11
|
+
@sha = sha
|
12
|
+
@index = Rugged::Index.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def add(source_file)
|
16
|
+
oid = @repository.write(source_file.source, :blob)
|
17
|
+
@index.add(path: source_file.path, oid: oid, mode: 0100644)
|
18
|
+
end
|
19
|
+
|
20
|
+
def apply
|
21
|
+
tree = @index.write_tree(@repository)
|
22
|
+
parents = @repository.empty? ? [] : [@repository.head.target].compact
|
23
|
+
user = { email: 'test@example.com', name: 'test', time: Time.now }
|
24
|
+
@sha = Rugged::Commit.create(@repository, tree: tree, parents: parents, update_ref: 'HEAD', author: user, committer: user, message: 'commit-message')
|
25
|
+
end
|
26
|
+
|
27
|
+
def source_files
|
28
|
+
commit = @repository.lookup(sha)
|
29
|
+
source_files = []
|
30
|
+
commit.tree.walk_blobs do |root, blob_hash|
|
31
|
+
path = root.empty? ? blob_hash[:name] : File.join(root, blob_hash[:name])
|
32
|
+
source = @repository.lookup(blob_hash[:oid]).text
|
33
|
+
source_files << SourceFile.new(path: path, source: source)
|
34
|
+
end
|
35
|
+
source_files
|
36
|
+
end
|
37
|
+
|
38
|
+
def ==(other)
|
39
|
+
sha == other.sha
|
40
|
+
end
|
41
|
+
|
42
|
+
def hash
|
43
|
+
sha.hash
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_s
|
47
|
+
sha
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module MethodLog
|
2
|
+
class MethodCommit
|
3
|
+
def initialize(commit:, method_definition:)
|
4
|
+
@commit = commit
|
5
|
+
@method_definition = method_definition
|
6
|
+
end
|
7
|
+
|
8
|
+
def ==(other)
|
9
|
+
(commit == other.commit) && (method_definition == other.method_definition)
|
10
|
+
end
|
11
|
+
|
12
|
+
def hash
|
13
|
+
[commit, method_definition].hash
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_s
|
17
|
+
"#{commit}: #{method_definition}"
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
|
22
|
+
attr_reader :commit
|
23
|
+
attr_reader :method_definition
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module MethodLog
|
2
|
+
class MethodDefinition
|
3
|
+
def initialize(source_file:, lines:)
|
4
|
+
@source_file = source_file
|
5
|
+
@lines = lines
|
6
|
+
end
|
7
|
+
|
8
|
+
def ==(other)
|
9
|
+
(source_file == other.source_file) && (lines == other.lines)
|
10
|
+
end
|
11
|
+
|
12
|
+
def hash
|
13
|
+
[source_file, lines].hash
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_s
|
17
|
+
[
|
18
|
+
"#{source_file.path}:#{lines}",
|
19
|
+
source_file.snippet(lines)
|
20
|
+
].join($/)
|
21
|
+
end
|
22
|
+
|
23
|
+
protected
|
24
|
+
|
25
|
+
attr_reader :source_file
|
26
|
+
attr_reader :lines
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'ripper'
|
2
|
+
|
3
|
+
require 'method_log/method_definition'
|
4
|
+
|
5
|
+
module MethodLog
|
6
|
+
class MethodFinder < Ripper
|
7
|
+
def initialize(source_file:)
|
8
|
+
super(source_file.source)
|
9
|
+
@source_file = source_file
|
10
|
+
@namespaces = []
|
11
|
+
@methods = {}
|
12
|
+
@at_scope_start = false
|
13
|
+
parse
|
14
|
+
end
|
15
|
+
|
16
|
+
def find(method_identifier)
|
17
|
+
@methods[method_identifier]
|
18
|
+
end
|
19
|
+
|
20
|
+
def on_kw(name)
|
21
|
+
case name
|
22
|
+
when 'def'
|
23
|
+
@line_number = lineno
|
24
|
+
when 'class', 'module'
|
25
|
+
@at_scope_start = true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def on_const(name)
|
30
|
+
if @at_scope_start
|
31
|
+
@namespaces << name
|
32
|
+
@at_scope_start = false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def on_def(name, *args)
|
37
|
+
identifier = "#{@namespaces.join('::')}##{name}"
|
38
|
+
lines = (@line_number - 1)..(lineno - 1)
|
39
|
+
definition = MethodDefinition.new(source_file: @source_file, lines: lines)
|
40
|
+
@methods[identifier] = definition
|
41
|
+
end
|
42
|
+
|
43
|
+
def on_class(*args)
|
44
|
+
@namespaces.pop
|
45
|
+
end
|
46
|
+
|
47
|
+
def on_module(*args)
|
48
|
+
@namespaces.pop
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rugged'
|
2
|
+
|
3
|
+
require 'method_log/commit'
|
4
|
+
|
5
|
+
module MethodLog
|
6
|
+
class Repository
|
7
|
+
attr_reader :commits
|
8
|
+
|
9
|
+
def initialize(path:)
|
10
|
+
@repository = Rugged::Repository.new(path)
|
11
|
+
@commits = []
|
12
|
+
if @repository.ref('refs/heads/master')
|
13
|
+
@repository.walk(@repository.last_commit) do |commit|
|
14
|
+
@commits << build_commit(sha: commit.oid)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def build_commit(sha: nil)
|
20
|
+
Commit.new(repository: @repository, sha: sha)
|
21
|
+
end
|
22
|
+
|
23
|
+
def add(commit)
|
24
|
+
commit.apply
|
25
|
+
@commits << commit
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module MethodLog
|
2
|
+
class SourceFile
|
3
|
+
attr_reader :path
|
4
|
+
attr_reader :source
|
5
|
+
|
6
|
+
def initialize(path:, source:)
|
7
|
+
@path = path
|
8
|
+
@source = source
|
9
|
+
end
|
10
|
+
|
11
|
+
def ==(other)
|
12
|
+
(path == other.path) && (source == other.source)
|
13
|
+
end
|
14
|
+
|
15
|
+
def hash
|
16
|
+
[path, source].hash
|
17
|
+
end
|
18
|
+
|
19
|
+
def snippet(range)
|
20
|
+
lines = source.split($/)[range].join($/)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/method_log.rb
ADDED
data/method_log.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
lib = File.expand_path('../lib/', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
|
4
|
+
require 'method_log/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = 'method_log'
|
8
|
+
s.version = MethodLog::VERSION
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.authors = ['James Mead']
|
11
|
+
s.email = ['james@floehopper.org']
|
12
|
+
s.homepage = 'http://jamesmead.org'
|
13
|
+
s.summary = 'Trace the history of an individual method in a git repository.'
|
14
|
+
s.license = 'MIT'
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- spec/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ['lib']
|
20
|
+
|
21
|
+
s.add_dependency 'rugged'
|
22
|
+
|
23
|
+
s.add_development_dependency 'rake'
|
24
|
+
s.add_development_dependency 'rspec'
|
25
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
ref: refs/heads/master
|
@@ -0,0 +1 @@
|
|
1
|
+
Unnamed repository; edit this file 'description' to name the repository.
|
@@ -0,0 +1 @@
|
|
1
|
+
x�� �0�NiB���;��b��o�0�U�bݖ��aܯ ���%�#���-�a�H�jyb����2oC�S�&T�
|
@@ -0,0 +1 @@
|
|
1
|
+
x+)JMU06a040031QH���+Jbx�ToOT�o�F�B����9#��
|
@@ -0,0 +1 @@
|
|
1
|
+
efebdb1a26d03939042f2f9c09f2aa49d87d1169
|
data/spec/api_spec.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'method_log/api'
|
4
|
+
require 'method_log/source_file'
|
5
|
+
require 'method_log/repository'
|
6
|
+
require 'method_log/commit'
|
7
|
+
require 'method_log/method_definition'
|
8
|
+
require 'method_log/method_commit'
|
9
|
+
|
10
|
+
describe MethodLog::API do
|
11
|
+
let(:repository_path) { File.expand_path('../repository.git', __FILE__) }
|
12
|
+
|
13
|
+
before do
|
14
|
+
FileUtils.mkdir_p(repository_path)
|
15
|
+
Rugged::Repository.init_at(repository_path, :bare)
|
16
|
+
end
|
17
|
+
|
18
|
+
after do
|
19
|
+
FileUtils.rm_rf(repository_path)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'finds class instance method in repository with two commits with single source file' do
|
23
|
+
foo_1 = MethodLog::SourceFile.new(path: 'foo.rb', source: %{
|
24
|
+
class Foo
|
25
|
+
def bar
|
26
|
+
# implementation
|
27
|
+
end
|
28
|
+
end
|
29
|
+
}.strip)
|
30
|
+
|
31
|
+
foo_2 = MethodLog::SourceFile.new(path: 'foo.rb', source: %{
|
32
|
+
# move method definition down one line
|
33
|
+
class Foo
|
34
|
+
def bar
|
35
|
+
# implementation
|
36
|
+
end
|
37
|
+
end
|
38
|
+
}.strip)
|
39
|
+
|
40
|
+
repository = MethodLog::Repository.new(path: repository_path)
|
41
|
+
|
42
|
+
commit_1 = repository.build_commit
|
43
|
+
commit_1.add(foo_1)
|
44
|
+
repository.add(commit_1)
|
45
|
+
|
46
|
+
commit_2 = repository.build_commit
|
47
|
+
commit_2.add(foo_2)
|
48
|
+
repository.add(commit_2)
|
49
|
+
|
50
|
+
repository = MethodLog::Repository.new(path: repository_path)
|
51
|
+
api = MethodLog::API.new(repository: repository)
|
52
|
+
method_commits = api.history('Foo#bar')
|
53
|
+
|
54
|
+
method_definition_1 = MethodLog::MethodDefinition.new(source_file: foo_1, lines: 1..3)
|
55
|
+
method_definition_2 = MethodLog::MethodDefinition.new(source_file: foo_2, lines: 2..4)
|
56
|
+
|
57
|
+
method_commit_1 = MethodLog::MethodCommit.new(commit: commit_1, method_definition: method_definition_1)
|
58
|
+
method_commit_2 = MethodLog::MethodCommit.new(commit: commit_2, method_definition: method_definition_2)
|
59
|
+
|
60
|
+
expect(method_commits).to eq([method_commit_2, method_commit_1])
|
61
|
+
end
|
62
|
+
end
|
data/spec/commit_spec.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'method_log/repository'
|
2
|
+
require 'method_log/commit'
|
3
|
+
require 'method_log/source_file'
|
4
|
+
|
5
|
+
describe MethodLog::Commit do
|
6
|
+
let(:sha) { 'b54d38bbd989f4b54c38fd77767d89d1' }
|
7
|
+
let(:commit) { MethodLog::Commit.new(sha: sha) }
|
8
|
+
let(:commit_with_same_sha) { MethodLog::Commit.new(sha: sha) }
|
9
|
+
|
10
|
+
it 'is equal to another commit with same SHA' do
|
11
|
+
expect(commit).to eq(commit_with_same_sha)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'has same hash as another commit with same SHA' do
|
15
|
+
expect(commit.hash).to eq(commit_with_same_sha.hash)
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'using a real git repository' do
|
19
|
+
let(:repository_path) { File.expand_path('../repository.git', __FILE__) }
|
20
|
+
|
21
|
+
before do
|
22
|
+
FileUtils.mkdir_p(repository_path)
|
23
|
+
Rugged::Repository.init_at(repository_path, :bare)
|
24
|
+
end
|
25
|
+
|
26
|
+
after do
|
27
|
+
FileUtils.rm_rf(repository_path)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'stores source files added to a commit in the repository against a real commit' do
|
31
|
+
source_one = MethodLog::SourceFile.new(path: 'path/to/source_one.rb', source: 'source-one')
|
32
|
+
source_two = MethodLog::SourceFile.new(path: 'path/to/source_two.rb', source: 'source-two')
|
33
|
+
|
34
|
+
repository = MethodLog::Repository.new(path: repository_path)
|
35
|
+
commit = repository.build_commit
|
36
|
+
commit.add(source_one)
|
37
|
+
commit.add(source_two)
|
38
|
+
commit.apply
|
39
|
+
|
40
|
+
repository = MethodLog::Repository.new(path: repository_path)
|
41
|
+
commit = repository.commits.first
|
42
|
+
expect(commit.source_files).to eq([source_one, source_two])
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'method_log/method_commit'
|
2
|
+
require 'method_log/commit'
|
3
|
+
require 'method_log/source_file'
|
4
|
+
require 'method_log/method_definition'
|
5
|
+
|
6
|
+
describe MethodLog::MethodCommit do
|
7
|
+
let(:commit) { MethodLog::Commit.new }
|
8
|
+
let(:source_file) { MethodLog::SourceFile.new(path: '/path/to/source.rb', source: 'source') }
|
9
|
+
let(:method_definition) { MethodLog::MethodDefinition.new(source_file: source_file, lines: 5..7) }
|
10
|
+
let(:method_commit) {
|
11
|
+
MethodLog::MethodCommit.new(commit: commit, method_definition: method_definition)
|
12
|
+
}
|
13
|
+
let(:method_commit_with_same_commit_and_method_definition) {
|
14
|
+
MethodLog::MethodCommit.new(commit: commit, method_definition: method_definition)
|
15
|
+
}
|
16
|
+
|
17
|
+
it 'is equal to another method commit with same commit and method definition' do
|
18
|
+
expect(method_commit).to eq(method_commit_with_same_commit_and_method_definition)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'has same hash as another method commit with same commit and method definition' do
|
22
|
+
expect(method_commit.hash).to eq(method_commit_with_same_commit_and_method_definition.hash)
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'method_log/method_definition'
|
2
|
+
require 'method_log/source_file'
|
3
|
+
|
4
|
+
describe MethodLog::MethodDefinition do
|
5
|
+
let(:source_file) do
|
6
|
+
MethodLog::SourceFile.new(path: 'path/to/source.rb', source: %{
|
7
|
+
class Foo
|
8
|
+
def bar
|
9
|
+
# implementation
|
10
|
+
end
|
11
|
+
end
|
12
|
+
}.strip)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'is equal to another method definition with same source file and line numbers' do
|
16
|
+
definition_one = MethodLog::MethodDefinition.new(source_file: source_file, lines: 1..3)
|
17
|
+
definition_two = MethodLog::MethodDefinition.new(source_file: source_file, lines: 1..3)
|
18
|
+
|
19
|
+
expect(definition_one).to eq(definition_two)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'has same hash as another method definition with same path and line numbers' do
|
23
|
+
definition_one = MethodLog::MethodDefinition.new(source_file: source_file, lines: 1..3)
|
24
|
+
definition_two = MethodLog::MethodDefinition.new(source_file: source_file, lines: 1..3)
|
25
|
+
|
26
|
+
expect(definition_one.hash).to eq(definition_two.hash)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'describes method definition' do
|
30
|
+
definition = MethodLog::MethodDefinition.new(source_file: source_file, lines: 1..3)
|
31
|
+
|
32
|
+
expect(definition.to_s).to eq(%{
|
33
|
+
path/to/source.rb:1..3
|
34
|
+
def bar
|
35
|
+
# implementation
|
36
|
+
end
|
37
|
+
}.strip)
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'method_log/source_file'
|
4
|
+
require 'method_log/method_finder'
|
5
|
+
|
6
|
+
describe MethodLog::MethodFinder do
|
7
|
+
it 'finds definition of instance method on class' do
|
8
|
+
foo = MethodLog::SourceFile.new(path: 'foo.rb', source: %{
|
9
|
+
class Foo
|
10
|
+
def bar
|
11
|
+
# implementation
|
12
|
+
end
|
13
|
+
end
|
14
|
+
}.strip)
|
15
|
+
|
16
|
+
method_finder = MethodLog::MethodFinder.new(source_file: foo)
|
17
|
+
method_definition = method_finder.find('Foo#bar')
|
18
|
+
|
19
|
+
expect(method_definition).to eq(MethodLog::MethodDefinition.new(source_file: foo, lines: 1..3))
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'finds definition of instance method on module' do
|
23
|
+
foo = MethodLog::SourceFile.new(path: 'foo.rb', source: %{
|
24
|
+
module Foo
|
25
|
+
def bar
|
26
|
+
# implementation
|
27
|
+
end
|
28
|
+
end
|
29
|
+
}.strip)
|
30
|
+
|
31
|
+
method_finder = MethodLog::MethodFinder.new(source_file: foo)
|
32
|
+
method_definition = method_finder.find('Foo#bar')
|
33
|
+
|
34
|
+
expect(method_definition).to eq(MethodLog::MethodDefinition.new(source_file: foo, lines: 1..3))
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'finds definition of instance method on class within module' do
|
38
|
+
foo = MethodLog::SourceFile.new(path: 'foo.rb', source: %{
|
39
|
+
module Foo
|
40
|
+
class Bar
|
41
|
+
def baz
|
42
|
+
# implementation
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
}.strip)
|
47
|
+
|
48
|
+
method_finder = MethodLog::MethodFinder.new(source_file: foo)
|
49
|
+
method_definition = method_finder.find('Foo::Bar#baz')
|
50
|
+
|
51
|
+
expect(method_definition).to eq(MethodLog::MethodDefinition.new(source_file: foo, lines: 2..4))
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'method_log/source_file'
|
4
|
+
|
5
|
+
describe MethodLog::SourceFile do
|
6
|
+
it 'is equal to another source file with same path and source' do
|
7
|
+
file_one = MethodLog::SourceFile.new(path: 'path/to/source.rb', source: 'source-one')
|
8
|
+
file_two = MethodLog::SourceFile.new(path: 'path/to/source.rb', source: 'source-one')
|
9
|
+
|
10
|
+
expect(file_one).to eq(file_two)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'has same hash as another source file with same path and source' do
|
14
|
+
file_one = MethodLog::SourceFile.new(path: 'path/to/source.rb', source: 'source-one')
|
15
|
+
file_two = MethodLog::SourceFile.new(path: 'path/to/source.rb', source: 'source-one')
|
16
|
+
|
17
|
+
expect(file_one.hash).to eq(file_two.hash)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'describes source file' do
|
21
|
+
file = MethodLog::SourceFile.new(path: 'path/to/source.rb', source: %{
|
22
|
+
class Foo
|
23
|
+
def bar
|
24
|
+
# implementation
|
25
|
+
end
|
26
|
+
end
|
27
|
+
}.strip)
|
28
|
+
|
29
|
+
expect(file.snippet(1..3).strip).to eq(%{
|
30
|
+
def bar
|
31
|
+
# implementation
|
32
|
+
end
|
33
|
+
}.strip)
|
34
|
+
end
|
35
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
|
metadata
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: method_log
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- James Mead
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-02-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rugged
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description:
|
56
|
+
email:
|
57
|
+
- james@floehopper.org
|
58
|
+
executables:
|
59
|
+
- method_log
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- ".gitignore"
|
64
|
+
- Gemfile
|
65
|
+
- LICENSE
|
66
|
+
- README.md
|
67
|
+
- Rakefile
|
68
|
+
- bin/method_log
|
69
|
+
- lib/method_log.rb
|
70
|
+
- lib/method_log/api.rb
|
71
|
+
- lib/method_log/commit.rb
|
72
|
+
- lib/method_log/method_commit.rb
|
73
|
+
- lib/method_log/method_definition.rb
|
74
|
+
- lib/method_log/method_finder.rb
|
75
|
+
- lib/method_log/repository.rb
|
76
|
+
- lib/method_log/source_file.rb
|
77
|
+
- lib/method_log/version.rb
|
78
|
+
- method_log.gemspec
|
79
|
+
- samples/repository.git/HEAD
|
80
|
+
- samples/repository.git/config
|
81
|
+
- samples/repository.git/description
|
82
|
+
- samples/repository.git/hooks/README.sample
|
83
|
+
- samples/repository.git/info/exclude
|
84
|
+
- samples/repository.git/objects/45/0ab23bfa0bd482244c42c7e18fad84526258fc
|
85
|
+
- samples/repository.git/objects/4c/5ba880d306780e033a5c35d3805b5f6f76aa41
|
86
|
+
- samples/repository.git/objects/b0/3eef6ca386d8463c28dd26f52333aba9af05dc
|
87
|
+
- samples/repository.git/objects/e0/ec752ebc5a724d5c2880dce3126948555b9709
|
88
|
+
- samples/repository.git/objects/ef/ebdb1a26d03939042f2f9c09f2aa49d87d1169
|
89
|
+
- samples/repository.git/objects/f6/6529c35058f591594fdc9affad66ebd6a16d0f
|
90
|
+
- samples/repository.git/refs/heads/master
|
91
|
+
- spec/api_spec.rb
|
92
|
+
- spec/commit_spec.rb
|
93
|
+
- spec/method_commit_spec.rb
|
94
|
+
- spec/method_definition_spec.rb
|
95
|
+
- spec/method_finder_spec.rb
|
96
|
+
- spec/source_file_spec.rb
|
97
|
+
- spec/spec_helper.rb
|
98
|
+
homepage: http://jamesmead.org
|
99
|
+
licenses:
|
100
|
+
- MIT
|
101
|
+
metadata: {}
|
102
|
+
post_install_message:
|
103
|
+
rdoc_options: []
|
104
|
+
require_paths:
|
105
|
+
- lib
|
106
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - ">="
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
requirements: []
|
117
|
+
rubyforge_project:
|
118
|
+
rubygems_version: 2.2.0
|
119
|
+
signing_key:
|
120
|
+
specification_version: 4
|
121
|
+
summary: Trace the history of an individual method in a git repository.
|
122
|
+
test_files:
|
123
|
+
- spec/api_spec.rb
|
124
|
+
- spec/commit_spec.rb
|
125
|
+
- spec/method_commit_spec.rb
|
126
|
+
- spec/method_definition_spec.rb
|
127
|
+
- spec/method_finder_spec.rb
|
128
|
+
- spec/source_file_spec.rb
|
129
|
+
- spec/spec_helper.rb
|