method_log 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: c433833678edcb6c769cc4af052d1f76789d0b1a
4
- data.tar.gz: 5ca47df97661e48f31f5b109964bcf8fa4ba81cd
2
+ SHA256:
3
+ metadata.gz: 125db342c6c8ad4ba938d3fac7cee3fc7dfe7330a53b4c882d051570d851791b
4
+ data.tar.gz: 817b5da57430c8703b8d7b00adba2de76714d03cd588ff36bdec79837615f978
5
5
  SHA512:
6
- metadata.gz: b649b279915c749afd19cae699e2b1d2d93573994f52caf0c296a786b03560e4694bc73b58746ff4dada2dd379437fcea22995d300bd5dd65f4ac005591be4ba
7
- data.tar.gz: 1136f3efdf3218496c00cd17e44365cdadd81add70fcbeccef303d6e40028c286e0a51f4e53a12b1d08899d0648dbc14a0f6303f1a8d7c3ed33cef577374906b
6
+ metadata.gz: edc71468238c1f9dc27f6698a8726a4c9768d6706091788b68f0dc2dd1e257a59e3b76a9f82713bde8403b3416cea7ba226450436c5921019699f1ec65995163
7
+ data.tar.gz: 82777e60269dd12aabed2842386603a89f627f5f87666c20f06680d7eade642d49afc4b491537817a3c93c4b5358c0a2eff1eae4e96037efd986f2a23fee7605
data/.travis.yml CHANGED
@@ -1,6 +1,9 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.1.0
3
+ - 2.6.3
4
+ - 2.5.5
5
+ - 2.4.6
6
+ - 2.3.8
7
+ - 2.2.10
8
+ - 2.1.10
4
9
  - 2.0.0
5
- - 1.9.3
6
-
data/README.md CHANGED
@@ -4,7 +4,7 @@ Trace the history of an individual method in a git repository (experimental).
4
4
 
5
5
  ### Requirements
6
6
 
7
- * Ruby >= v1.9.3 (due to requirements of the `rugged` gem)
7
+ * Ruby >= v2.0.0 (due to requirements of the `parser` gem); although parsing of source code for Ruby >= v1.8 is possible
8
8
  * The [rugged](https://github.com/libgit2/rugged) Ruby gem (listed as dependency in gemspec)
9
9
  * The [libgit2](https://github.com/libgit2/libgit2) C library (included as part of rugged gem)
10
10
  * The [parser](https://github.com/whitequark/parser) Ruby gem (listed as dependency in gemspec)
@@ -15,21 +15,17 @@ Trace the history of an individual method in a git repository (experimental).
15
15
 
16
16
  ### Run
17
17
 
18
- $ method_log <options> <method-signature>
19
-
20
- # options:
21
- --patch, -p: Generate patch.
22
- --ruby-version, -r <s>: Parser Ruby version (18, 19, 20, 21) (default: current)
23
- --max-count, -n <i>: Limit the number of commits to output.
24
- --stop-at-latest-introduction-of-method, -s: Stop at lastest introduction of method.
25
- --help, -h: Show usage.
26
-
27
- # method-signature
28
- Uses the Ruby Index format e.g. Foo#bar, Bar::Baz#foo, Baz.foo.
29
-
30
- ### Todo
31
-
32
- * Support for Rspec tests
18
+ #### Display the commit history for a single method
19
+
20
+ $ method_log [options] <method-signature>
21
+
22
+ #### Build a parallel git repository of method definitions
23
+
24
+ $ build_methods_repo [options] <source-repo-path> <target-repo-path>
25
+
26
+ ### To Do
27
+
28
+ * Parsing support for RSpec tests
33
29
  * Default to looking for commits in current git branch
34
30
  * Check what happens with merge commits
35
31
  * Maybe add as new git command or extension to existing command e.g. `git log`
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'method_log'
4
+ require 'optimist'
5
+
6
+ options = Optimist::options do
7
+ version MethodLog::VERSION
8
+ banner <<-EOS
9
+ Build a parallel git repository of method definitions.
10
+
11
+ Usage:
12
+ build_methods_repo [options] <source-repo-path> <target-repo-path>
13
+
14
+ source-repo-path: the path to the source repository from which to read
15
+ target-repo-path: the path to the target repository to which to write
16
+
17
+ [options] are:
18
+ EOS
19
+ opt :ruby_version, 'Parser Ruby version (e.g. 2.5)', default: 'current'
20
+ opt :excluded_directories, 'Directories in source repository to exclude from analysis', type: :strings, default: []
21
+ end
22
+
23
+ Optimist.die 'No source path specified' if ARGV[0].nil?
24
+ source_path = ARGV[0]
25
+ Optimist.die 'Source repository does not exist' unless Dir.exist?(source_path)
26
+
27
+ Optimist.die 'No target path specified' if ARGV[1].nil?
28
+ target_path = ARGV[1]
29
+ Optimist.die 'Target repository already exists' if Dir.exist?(target_path)
30
+
31
+ case ruby_version = options[:ruby_version]
32
+ when 'current'
33
+ require 'parser/current'
34
+ when /^(\d)\.(\d)$/
35
+ begin
36
+ require "parser/ruby#{$1}#{$2}"
37
+ Parser::CurrentRuby = Parser.const_get("Ruby#{$1}#{$2}")
38
+ rescue LoadError
39
+ Optimist.die "Ruby version not supported: #{ruby_version}"
40
+ end
41
+ else
42
+ Optimist.die "Ruby version not supported: #{ruby_version}"
43
+ end
44
+
45
+ require 'method_log/repository'
46
+ require 'method_log/method_finder'
47
+ require 'method_log/source_file'
48
+
49
+ def unindent(code)
50
+ lines = code.split($/)
51
+ indent = lines.reject { |l| l.strip.length == 0 }.map { |l| l[/^ */].length }.min
52
+ lines.map { |l| l.sub(Regexp.new(' ' * indent), '') }.join($/)
53
+ end
54
+
55
+ new_repository_path = File.expand_path(target_path)
56
+ Rugged::Repository.init_at(new_repository_path, :bare)
57
+ new_repository = MethodLog::Repository.new(new_repository_path)
58
+
59
+ repository_path = File.expand_path(source_path)
60
+ repository = MethodLog::Repository.new(repository_path)
61
+ repository.commits(sorting: Rugged::SORT_TOPO | Rugged::SORT_REVERSE).each do |commit|
62
+ puts commit.to_s
63
+ new_commit = new_repository.build_commit
64
+ commit.source_files.each do |source_file|
65
+ next if options[:excluded_directories].any? { |d| source_file.path.start_with?(d) }
66
+ begin
67
+ method_finder = MethodLog::MethodFinder.new(source_file)
68
+ method_finder.methods.each do |method_signature, method_definition|
69
+ _, namespace, name = method_signature.match(/^(.*)([#.].*)$/).to_a
70
+ path = namespace.split('::').push(name).join(File::SEPARATOR) + '.rb'
71
+ method_source = unindent(method_definition.source) + $/
72
+ method_source_file = MethodLog::SourceFile.new(path: path, source: method_source)
73
+ new_commit.add(method_source_file)
74
+ end
75
+ rescue Parser::SyntaxError => e
76
+ p e
77
+ end
78
+ end
79
+ new_commit.apply(user: commit.author, message: commit.message)
80
+ end
data/bin/method_log CHANGED
@@ -1,40 +1,51 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'method_log'
4
- require 'trollop'
4
+ require 'optimist'
5
5
 
6
- options = Trollop::options do
7
- opt :patch, 'Generate patch.', short: 'p'
8
- opt :ruby_version, 'Parser Ruby version (18, 19, 20, 21)', default: 'current'
6
+ options = Optimist::options do
7
+ version MethodLog::VERSION
8
+ banner <<-EOS
9
+ Display the commit history for a single method.
10
+
11
+ Usage:
12
+ method_log [options] <method-signature>
13
+
14
+ where <method-signature> is in the Ruby Index format e.g. Foo#bar, Bar::Baz#foo, Baz.foo.
15
+
16
+ and [options] are:
17
+ EOS
18
+ opt :patch, 'Generate patch.'
19
+ opt :ruby_version, 'Parser Ruby version (e.g. 2.5)', default: 'current'
9
20
  opt :max_count, 'Limit the number of commits to output.', type: :integer, short: 'n'
10
21
  opt :stop_at_latest_introduction_of_method, 'Stop at lastest introduction of method.', default: true
22
+ opt :repository_path, 'Path to repository', default: Dir.pwd
11
23
  end
12
24
 
25
+ Optimist.die 'No method signature specified' if ARGV.empty?
26
+ method_signature = ARGV[0]
27
+
13
28
  case ruby_version = options[:ruby_version]
14
29
  when 'current'
15
30
  require 'parser/current'
16
- when '18', '19', '20', '21'
17
- require 'parser/ruby18'
18
- require 'parser/ruby19'
19
- require 'parser/ruby20'
20
- require 'parser/ruby21'
21
- Parser::CurrentRuby = Parser.const_get("Ruby#{ruby_version}")
31
+ when /^(\d)\.(\d)$/
32
+ begin
33
+ require "parser/ruby#{$1}#{$2}"
34
+ Parser::CurrentRuby = Parser.const_get("Ruby#{$1}#{$2}")
35
+ rescue LoadError
36
+ Optimist.die "Ruby version not supported: #{ruby_version}"
37
+ end
22
38
  else
23
- raise "Ruby version not supported: #{ruby_version}"
39
+ Optimist.die "Ruby version not supported: #{ruby_version}"
24
40
  end
25
41
 
26
- require 'method_log'
27
42
  require 'method_log/repository'
28
43
  require 'method_log/api'
29
44
 
30
- repository = MethodLog::Repository.new(Dir.pwd)
45
+ repository = MethodLog::Repository.new(options[:repository_path])
31
46
  api = MethodLog::API.new(repository)
32
- api.diffs(ARGV[0], options).each do |method_commit, method_diff|
33
- puts "commit #{method_commit.sha}"
34
- puts "Author: #{method_commit.author[:name]} <#{method_commit.author[:email]}>"
35
- puts "Date: #{method_commit.author[:time].strftime('%a %b %-e %T %Y %z')}"
36
- puts
37
- puts method_commit.message
47
+ api.diffs(method_signature, options).each do |method_commit, method_diff|
48
+ puts method_commit.to_s
38
49
  puts
39
50
  if options[:patch]
40
51
  puts method_diff.to_s(:color)
@@ -39,6 +39,16 @@ module MethodLog
39
39
  method_definition && method_definition.source_file
40
40
  end
41
41
 
42
+ def to_s
43
+ [
44
+ "commit #{sha}",
45
+ "Author: #{author[:name]} <#{author[:email]}>",
46
+ "Date: #{author[:time].strftime('%a %b %-e %T %Y %z')}",
47
+ '',
48
+ message
49
+ ].join($/)
50
+ end
51
+
42
52
  protected
43
53
 
44
54
  attr_reader :commit
@@ -7,6 +7,8 @@ require 'method_log/scope'
7
7
 
8
8
  module MethodLog
9
9
  class MethodFinder < Parser::AST::Processor
10
+ attr_reader :methods
11
+
10
12
  def initialize(source_file)
11
13
  @source_file = source_file
12
14
  @scope = Scope::Root.new
@@ -25,9 +25,10 @@ module MethodLog
25
25
  end
26
26
 
27
27
  def commits(options = {})
28
+ options[:sorting] ||= Rugged::SORT_TOPO
28
29
  Enumerator.new do |yielder|
29
30
  if @repository.ref('refs/heads/master')
30
- @repository.walk(@repository.last_commit).with_index do |commit, index|
31
+ @repository.walk(@repository.last_commit, options[:sorting]).with_index do |commit, index|
31
32
  break if options[:max_count] && index >= options[:max_count] - 1
32
33
  yielder << build_commit(commit.oid)
33
34
  end
@@ -35,4 +36,4 @@ module MethodLog
35
36
  end
36
37
  end
37
38
  end
38
- end
39
+ end
@@ -1,3 +1,3 @@
1
1
  module MethodLog
2
- VERSION = '0.1.1'
2
+ VERSION = '0.2.0'
3
3
  end
data/method_log.gemspec CHANGED
@@ -18,13 +18,13 @@ Gem::Specification.new do |s|
18
18
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
19
  s.require_paths = ['lib']
20
20
 
21
- s.required_ruby_version = '>= 1.9.3'
21
+ s.required_ruby_version = '>= 2.0.0'
22
22
 
23
23
  s.add_dependency 'rugged'
24
- s.add_dependency 'parser'
24
+ s.add_dependency 'parser', '~> 2.5'
25
25
  s.add_dependency 'diffy'
26
- s.add_dependency 'trollop'
26
+ s.add_dependency 'optimist'
27
27
 
28
28
  s.add_development_dependency 'rake'
29
- s.add_development_dependency 'rspec'
29
+ s.add_development_dependency 'rspec', '~> 3.0'
30
30
  end
data/spec/api_spec.rb CHANGED
@@ -140,4 +140,4 @@ module MethodLog
140
140
  [method_commits, method_diffs]
141
141
  end
142
142
  end
143
- end
143
+ end
data/spec/commit_spec.rb CHANGED
@@ -66,8 +66,8 @@ module MethodLog
66
66
  repository = Repository.new(repository_path)
67
67
  commit = repository.commits.to_a.last
68
68
 
69
- expect(commit.contains?(source_file)).to be_true
70
- expect(commit.contains?(another_source_file)).to be_false
69
+ expect(commit.contains?(source_file)).to be true
70
+ expect(commit.contains?(another_source_file)).to be false
71
71
  end
72
72
 
73
73
  it 'makes author available' do
@@ -9,8 +9,8 @@ module MethodLog
9
9
  let(:diff) { MethodDiff.new(first_commit, second_commit) }
10
10
 
11
11
  it 'generates text diff of the method source for two commits' do
12
- first_commit.stub(:method_source).and_return(%{line 1\nline 2\n})
13
- second_commit.stub(:method_source).and_return(%{line 2\nline 3\n})
12
+ allow(first_commit).to receive(:method_source).and_return(%{line 1\nline 2\n})
13
+ allow(second_commit).to receive(:method_source).and_return(%{line 2\nline 3\n})
14
14
  expect(diff.to_s).to eq(%{-line 1\n line 2\n+line 3\n})
15
15
  end
16
16
  end
@@ -218,7 +218,7 @@ module MethodLog
218
218
  })
219
219
 
220
220
  method_finder = MethodFinder.new(foo)
221
- method_definition = method_finder.find('Foo::(ivar :@foo).bar')
221
+ method_definition = method_finder.find('Foo::s(:ivar, :@foo).bar')
222
222
 
223
223
  expect(method_definition).to eq(MethodDefinition.new(foo, 4..6))
224
224
  end
@@ -39,7 +39,7 @@ module MethodLog
39
39
  end
40
40
 
41
41
  it 'looks up source in repository using SHA if no source set' do
42
- repository.stub(:lookup).with(sha).and_return(blob)
42
+ allow(repository).to receive(:lookup).with(sha).and_return(blob)
43
43
  file = source(path: 'path/to/source.rb', repository: repository, sha: sha)
44
44
  expect(file.source).to eq('source')
45
45
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: method_log
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Mead
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-10 00:00:00.000000000 Z
11
+ date: 2019-06-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rugged
@@ -28,16 +28,16 @@ dependencies:
28
28
  name: parser
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '2.5'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '2.5'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: diffy
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: trollop
56
+ name: optimist
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -84,20 +84,21 @@ dependencies:
84
84
  name: rspec
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ">="
87
+ - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '0'
89
+ version: '3.0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ">="
94
+ - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '0'
96
+ version: '3.0'
97
97
  description:
98
98
  email:
99
99
  - james@floehopper.org
100
100
  executables:
101
+ - build_methods_repo
101
102
  - method_log
102
103
  extensions: []
103
104
  extra_rdoc_files: []
@@ -108,6 +109,7 @@ files:
108
109
  - LICENSE
109
110
  - README.md
110
111
  - Rakefile
112
+ - bin/build_methods_repo
111
113
  - bin/method_log
112
114
  - lib/method_log.rb
113
115
  - lib/method_log/api.rb
@@ -154,15 +156,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
154
156
  requirements:
155
157
  - - ">="
156
158
  - !ruby/object:Gem::Version
157
- version: 1.9.3
159
+ version: 2.0.0
158
160
  required_rubygems_version: !ruby/object:Gem::Requirement
159
161
  requirements:
160
162
  - - ">="
161
163
  - !ruby/object:Gem::Version
162
164
  version: '0'
163
165
  requirements: []
164
- rubyforge_project:
165
- rubygems_version: 2.2.0
166
+ rubygems_version: 3.0.3
166
167
  signing_key:
167
168
  specification_version: 4
168
169
  summary: Trace the history of an individual method in a git repository.