ripper-tags 0.1.0
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.
- data/Gemfile +5 -0
- data/README.md +57 -0
- data/Rakefile +6 -0
- data/bin/ripper-tags +76 -0
- data/lib/tag_ripper.rb +241 -0
- data/ripper-tags.gemspec +21 -0
- data/test/test_ripper_tags.rb +76 -0
- metadata +85 -0
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
## ripper-tags
|
2
|
+
|
3
|
+
fast, accurate ctags generator for ruby source code using Ripper
|
4
|
+
|
5
|
+
### usage (bin)
|
6
|
+
|
7
|
+
```
|
8
|
+
$ ripper-tags /usr/lib/ruby/1.8/timeout.rb
|
9
|
+
30 module Timeout
|
10
|
+
35 class Timeout::Error < Interrupt
|
11
|
+
37 class Timeout::ExitException < Exception
|
12
|
+
40 const Timeout::THIS_FILE
|
13
|
+
41 const Timeout::CALLER_OFFSET
|
14
|
+
52 def Timeout#timeout
|
15
|
+
100 def Object#timeout
|
16
|
+
108 const TimeoutError
|
17
|
+
|
18
|
+
$ ripper-tags --debug /usr/lib/ruby/1.8/timeout.rb
|
19
|
+
[[:module,
|
20
|
+
["Timeout", 30],
|
21
|
+
[[:class, ["Error", 35], ["Interrupt", 35], []],
|
22
|
+
[:class, ["ExitException", 37], ["Exception", 37], []],
|
23
|
+
[:assign, "THIS_FILE", 40],
|
24
|
+
[:assign, "CALLER_OFFSET", 41],
|
25
|
+
[:def, "timeout", 52]]],
|
26
|
+
[:def, "timeout", 100],
|
27
|
+
[:assign, "TimeoutError", 108]]
|
28
|
+
|
29
|
+
$ ripper-tags --vim /usr/lib/ruby/1.8/timeout.rb
|
30
|
+
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
|
31
|
+
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
|
32
|
+
CALLER_OFFSET /usr/lib/ruby/1.8/timeout.rb /^ CALLER_OFFSET = ((c = caller[0]) && THIS_FILE =~ c) ? 1 : 0$/;" C class:Timeout
|
33
|
+
Error /usr/lib/ruby/1.8/timeout.rb /^ class Error < Interrupt$/;" c class:Timeout inherits:Interrupt
|
34
|
+
ExitException /usr/lib/ruby/1.8/timeout.rb /^ class ExitException < ::Exception # :nodoc:$/;" c class:Timeout inherits:Exception
|
35
|
+
THIS_FILE /usr/lib/ruby/1.8/timeout.rb /^ THIS_FILE = \/\\A#{Regexp.quote(__FILE__)}:\/o$/;" C class:Timeout
|
36
|
+
Timeout /usr/lib/ruby/1.8/timeout.rb /^module Timeout$/;" m
|
37
|
+
TimeoutError /usr/lib/ruby/1.8/timeout.rb /^TimeoutError = Timeout::Error # :nodoc:$/;" C class:
|
38
|
+
timeout /usr/lib/ruby/1.8/timeout.rb /^def timeout(n, e = nil, &block) # :nodoc:$/;" f class:Object
|
39
|
+
timeout /usr/lib/ruby/1.8/timeout.rb /^ def timeout(sec, klass = nil)$/;" f class:Timeout
|
40
|
+
|
41
|
+
$ ripper-tags --json /usr/lib/ruby/1.8/timeout.rb
|
42
|
+
{"full_name":"Timeout","name":"Timeout","kind":"module","line":30,"language":"Ruby","path":"/usr/lib/ruby/1.8/timeout.rb","pattern":"module Timeout"}
|
43
|
+
{"full_name":"Timeout::Error","name":"Error","class":"Timeout","inherits":"Interrupt","kind":"class","line":35,"language":"Ruby","path":"/usr/lib/ruby/1.8/timeout.rb","pattern":" class Error < Interrupt"}
|
44
|
+
{"full_name":"Timeout::ExitException","name":"ExitException","class":"Timeout","inherits":"Exception","kind":"class","line":37,"language":"Ruby","path":"/usr/lib/ruby/1.8/timeout.rb","pattern":" class ExitException < ::Exception # :nodoc:"}
|
45
|
+
{"name":"THIS_FILE","full_name":"Timeout::THIS_FILE","class":"Timeout","kind":"constant","line":40,"language":"Ruby","path":"/usr/lib/ruby/1.8/timeout.rb","pattern":" THIS_FILE = /\\A#{Regexp.quote(__FILE__)}:/o"}
|
46
|
+
{"name":"CALLER_OFFSET","full_name":"Timeout::CALLER_OFFSET","class":"Timeout","kind":"constant","line":41,"language":"Ruby","path":"/usr/lib/ruby/1.8/timeout.rb","pattern":" CALLER_OFFSET = ((c = caller[0]) && THIS_FILE =~ c) ? 1 : 0"}
|
47
|
+
{"name":"timeout","full_name":"Timeout#timeout","class":"Timeout","kind":"method","line":52,"language":"Ruby","path":"/usr/lib/ruby/1.8/timeout.rb","pattern":" def timeout(sec, klass = nil)"}
|
48
|
+
{"name":"timeout","full_name":"Object#timeout","class":"Object","kind":"method","line":100,"language":"Ruby","path":"/usr/lib/ruby/1.8/timeout.rb","pattern":"def timeout(n, e = nil, &block) # :nodoc:"}
|
49
|
+
{"name":"TimeoutError","full_name":"TimeoutError","class":"","kind":"constant","line":108,"language":"Ruby","path":"/usr/lib/ruby/1.8/timeout.rb","pattern":"TimeoutError = Timeout::Error # :nodoc:"}
|
50
|
+
```
|
51
|
+
|
52
|
+
### usage (api)
|
53
|
+
|
54
|
+
``` ruby
|
55
|
+
require 'tag_ripper'
|
56
|
+
tags = TagRipper.extract("def abc() end", "mycode.rb")
|
57
|
+
```
|
data/Rakefile
ADDED
data/bin/ripper-tags
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'tag_ripper'
|
4
|
+
require 'pp'
|
5
|
+
|
6
|
+
if ARGV.delete('--json')
|
7
|
+
require 'yajl'
|
8
|
+
json = true
|
9
|
+
end
|
10
|
+
if ARGV.delete('--debug')
|
11
|
+
debug = true
|
12
|
+
end
|
13
|
+
if ARGV.delete('--vim')
|
14
|
+
vim = true
|
15
|
+
all_tags = []
|
16
|
+
end
|
17
|
+
|
18
|
+
ARGV.each do |file|
|
19
|
+
begin
|
20
|
+
data = File.read(file)
|
21
|
+
sexp = TagRipper.new(data, file).parse
|
22
|
+
v = TagRipper::Visitor.new(sexp, file, data)
|
23
|
+
|
24
|
+
if debug
|
25
|
+
pp sexp
|
26
|
+
elsif json
|
27
|
+
v.tags.each do |tag|
|
28
|
+
puts Yajl.dump(tag)
|
29
|
+
end
|
30
|
+
elsif vim
|
31
|
+
all_tags += v.tags
|
32
|
+
else
|
33
|
+
v.tags.each do |tag|
|
34
|
+
kind = case tag[:kind]
|
35
|
+
when /method$/ then 'def'
|
36
|
+
when /^const/ then 'const'
|
37
|
+
else tag[:kind]
|
38
|
+
end
|
39
|
+
if kind == 'class' && tag[:inherits]
|
40
|
+
suffix = " < #{tag[:inherits]}"
|
41
|
+
else
|
42
|
+
suffix = ''
|
43
|
+
end
|
44
|
+
|
45
|
+
puts "#{tag[:line].to_s.rjust(5)} #{kind.to_s.rjust(6)} #{tag[:full_name]}#{suffix}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
rescue Exception => e
|
49
|
+
STDERR.puts [e, file].inspect
|
50
|
+
raise e
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
if vim
|
55
|
+
puts <<-EOC
|
56
|
+
!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;" to lines/
|
57
|
+
!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/
|
58
|
+
EOC
|
59
|
+
|
60
|
+
all_tags.sort_by!{ |t| t[:name] }
|
61
|
+
all_tags.each do |tag|
|
62
|
+
kwargs = ''
|
63
|
+
kwargs << "\tclass:#{tag[:class].gsub('::','.')}" if tag[:class]
|
64
|
+
kwargs << "\tinherits:#{tag[:inherits].gsub('::','.')}" if tag[:inherits]
|
65
|
+
|
66
|
+
kind = case tag[:kind]
|
67
|
+
when 'method' then 'f'
|
68
|
+
when 'singleton method' then 'F'
|
69
|
+
when 'constant' then 'C'
|
70
|
+
else tag[:kind].slice(0,1)
|
71
|
+
end
|
72
|
+
|
73
|
+
code = tag[:pattern].gsub('\\','\\\\\\\\').gsub('/','\\/')
|
74
|
+
puts "%s\t%s\t/^%s$/;\"\t%c%s" % [tag[:name], tag[:path], code, kind, kwargs]
|
75
|
+
end
|
76
|
+
end
|
data/lib/tag_ripper.rb
ADDED
@@ -0,0 +1,241 @@
|
|
1
|
+
require 'ripper'
|
2
|
+
|
3
|
+
class TagRipper < Ripper
|
4
|
+
def self.extract(data, file='(eval)')
|
5
|
+
sexp = new(data, file).parse
|
6
|
+
Visitor.new(sexp, file, data).tags
|
7
|
+
end
|
8
|
+
|
9
|
+
SCANNER_EVENTS.each do |event|
|
10
|
+
module_eval(<<-End, __FILE__, __LINE__ + 1)
|
11
|
+
def on_#{event}(tok)
|
12
|
+
[tok, lineno]
|
13
|
+
end
|
14
|
+
End
|
15
|
+
end
|
16
|
+
|
17
|
+
def on_stmts_add(first, *rest)
|
18
|
+
(first || []) + rest.compact
|
19
|
+
end
|
20
|
+
|
21
|
+
def on_module(name, body)
|
22
|
+
[:module, name, *body.compact]
|
23
|
+
end
|
24
|
+
def on_class(name, superclass, body)
|
25
|
+
superclass.flatten!(1) if superclass
|
26
|
+
[:class, name, superclass, *body.compact]
|
27
|
+
end
|
28
|
+
def on_def(method, args, body)
|
29
|
+
[:def, *method]
|
30
|
+
end
|
31
|
+
def on_defs(receiver, op, method, args, body)
|
32
|
+
receiver.flatten!(1) if receiver
|
33
|
+
[:defs, receiver && receiver[0], *method]
|
34
|
+
end
|
35
|
+
def on_alias(lhs, rhs)
|
36
|
+
[:alias, lhs[0], rhs[0], rhs[1]]
|
37
|
+
end
|
38
|
+
def on_assign(lhs, rhs)
|
39
|
+
return if lhs.nil?
|
40
|
+
return if lhs[0] == :field
|
41
|
+
return if lhs[0] == :aref_field
|
42
|
+
[:assign, *lhs.flatten(1)]
|
43
|
+
end
|
44
|
+
def on_sclass(name, body)
|
45
|
+
[:sclass, name && name.flatten(1), *body.compact]
|
46
|
+
end
|
47
|
+
def on_field(lhs, op, rhs)
|
48
|
+
[:field, lhs && lhs[0], rhs[0], rhs[1]]
|
49
|
+
end
|
50
|
+
def on_aref_field(*args)
|
51
|
+
[:aref_field, *args]
|
52
|
+
end
|
53
|
+
|
54
|
+
def on_const_path_ref(a, b)
|
55
|
+
a.flatten!(1)
|
56
|
+
[[a && a[0], b[0]].join('::'), b[1]]
|
57
|
+
end
|
58
|
+
|
59
|
+
def on_binary(*args)
|
60
|
+
end
|
61
|
+
|
62
|
+
def on_command(name, *args)
|
63
|
+
# if name =~ /^(attr_|alias)/
|
64
|
+
# [name.to_sym, *args]
|
65
|
+
# end
|
66
|
+
end
|
67
|
+
def on_bodystmt(*args)
|
68
|
+
args
|
69
|
+
end
|
70
|
+
def on_if(condition, success, failure)
|
71
|
+
ret = [success, failure].flatten(1).compact
|
72
|
+
ret.any?? ret : nil
|
73
|
+
end
|
74
|
+
|
75
|
+
def on_unless_mod(condition, success)
|
76
|
+
nil
|
77
|
+
end
|
78
|
+
alias on_if_mod on_unless_mod
|
79
|
+
|
80
|
+
def on_var_ref(*args)
|
81
|
+
on_vcall(*args) || args
|
82
|
+
end
|
83
|
+
|
84
|
+
def on_vcall(name)
|
85
|
+
[name[0].to_sym] if name[0].to_s =~ /private|protected|public$/
|
86
|
+
end
|
87
|
+
|
88
|
+
def on_call(lhs, op, rhs)
|
89
|
+
[:call, lhs && lhs[0], rhs && rhs[0], rhs[1]]
|
90
|
+
end
|
91
|
+
|
92
|
+
def on_do_block(*args)
|
93
|
+
args
|
94
|
+
end
|
95
|
+
|
96
|
+
def on_method_add_block(method, body)
|
97
|
+
return unless method and body
|
98
|
+
if method[2] == 'class_eval'
|
99
|
+
[:class_eval, [method[1], method[3]], body.last]
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
class Visitor
|
104
|
+
attr_reader :tags
|
105
|
+
|
106
|
+
def initialize(sexp, path, data)
|
107
|
+
@path = path
|
108
|
+
@lines = data.split("\n")
|
109
|
+
@namespace = []
|
110
|
+
@tags = []
|
111
|
+
|
112
|
+
process(sexp)
|
113
|
+
end
|
114
|
+
|
115
|
+
def emit_tag(kind, line, opts={})
|
116
|
+
@tags << opts.merge(
|
117
|
+
:kind => kind.to_s,
|
118
|
+
:line => line,
|
119
|
+
:language => 'Ruby',
|
120
|
+
:path => @path,
|
121
|
+
:pattern => @lines[line-1].chomp,
|
122
|
+
:access => @current_access
|
123
|
+
).delete_if{ |k,v| v.nil? }
|
124
|
+
end
|
125
|
+
|
126
|
+
def process(sexp)
|
127
|
+
return unless sexp
|
128
|
+
return if Symbol === sexp
|
129
|
+
|
130
|
+
case sexp[0]
|
131
|
+
when Array
|
132
|
+
sexp.each{ |child| process(child) }
|
133
|
+
when Symbol
|
134
|
+
name, *args = sexp
|
135
|
+
__send__("on_#{name}", *args)
|
136
|
+
when String, nil
|
137
|
+
# nothing
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def on_module_or_class(kind, name, superclass, body)
|
142
|
+
name, line = *name
|
143
|
+
@namespace << name
|
144
|
+
|
145
|
+
prev_access = @current_access
|
146
|
+
@current_access = nil
|
147
|
+
|
148
|
+
if superclass
|
149
|
+
superclass_name = superclass[0] == :call ?
|
150
|
+
superclass[1] :
|
151
|
+
superclass[0]
|
152
|
+
end
|
153
|
+
full_name = @namespace.join('::')
|
154
|
+
parts = full_name.split('::')
|
155
|
+
class_name = parts.pop
|
156
|
+
|
157
|
+
emit_tag kind, line,
|
158
|
+
:full_name => full_name,
|
159
|
+
:name => class_name,
|
160
|
+
:class => parts.any? && parts.join('::') || nil,
|
161
|
+
:inherits => superclass_name
|
162
|
+
|
163
|
+
process(body)
|
164
|
+
ensure
|
165
|
+
@current_access = prev_access
|
166
|
+
@namespace.pop
|
167
|
+
end
|
168
|
+
|
169
|
+
def on_module(name, body)
|
170
|
+
on_module_or_class(:module, name, nil, body)
|
171
|
+
end
|
172
|
+
|
173
|
+
def on_class(name, superclass, body)
|
174
|
+
on_module_or_class(:class, name, superclass, body)
|
175
|
+
end
|
176
|
+
|
177
|
+
def on_private() @current_access = 'private' end
|
178
|
+
def on_protected() @current_access = 'protected' end
|
179
|
+
def on_public() @current_access = 'public' end
|
180
|
+
|
181
|
+
def on_assign(name, line)
|
182
|
+
return unless name =~ /^[A-Z]/
|
183
|
+
|
184
|
+
emit_tag :constant, line,
|
185
|
+
:name => name,
|
186
|
+
:full_name => (@namespace + [name]).join('::'),
|
187
|
+
:class => @namespace.join('::')
|
188
|
+
end
|
189
|
+
|
190
|
+
def on_alias(name, other, line)
|
191
|
+
ns = (@namespace.empty?? 'Object' : @namespace.join('::'))
|
192
|
+
|
193
|
+
emit_tag :alias, line,
|
194
|
+
:name => name,
|
195
|
+
:inherits => other,
|
196
|
+
:full_name => "#{ns}#{@is_singleton ? '.' : '#'}#{name}",
|
197
|
+
:class => ns
|
198
|
+
end
|
199
|
+
|
200
|
+
def on_def(name, line)
|
201
|
+
kind = @is_singleton ? 'singleton method' : 'method'
|
202
|
+
ns = (@namespace.empty?? 'Object' : @namespace.join('::'))
|
203
|
+
|
204
|
+
emit_tag kind, line,
|
205
|
+
:name => name,
|
206
|
+
:full_name => "#{ns}#{@is_singleton ? '.' : '#'}#{name}",
|
207
|
+
:class => ns
|
208
|
+
end
|
209
|
+
|
210
|
+
def on_defs(klass, name, line)
|
211
|
+
ns = (@namespace + [klass != 'self' ? klass : nil]).compact
|
212
|
+
emit_tag 'singleton method', line,
|
213
|
+
:name => name,
|
214
|
+
:full_name => ns.join('::') + ".#{name}",
|
215
|
+
:class => ns.join('::')
|
216
|
+
end
|
217
|
+
|
218
|
+
def on_sclass(name, body)
|
219
|
+
name, line = *name
|
220
|
+
@namespace << name unless name == 'self'
|
221
|
+
prev_is_singleton, @is_singleton = @is_singleton, true
|
222
|
+
process(body)
|
223
|
+
ensure
|
224
|
+
@namespace.pop unless name == 'self'
|
225
|
+
@is_singleton = prev_is_singleton
|
226
|
+
end
|
227
|
+
|
228
|
+
def on_class_eval(name, body)
|
229
|
+
name, line = *name
|
230
|
+
@namespace << name
|
231
|
+
process(body)
|
232
|
+
ensure
|
233
|
+
@namespace.pop
|
234
|
+
end
|
235
|
+
|
236
|
+
def on_call(*args)
|
237
|
+
end
|
238
|
+
alias on_aref_field on_call
|
239
|
+
alias on_field on_call
|
240
|
+
end
|
241
|
+
end
|
data/ripper-tags.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'ripper-tags'
|
3
|
+
s.version = '0.1.0'
|
4
|
+
|
5
|
+
s.summary = 'ctags generator for ruby code'
|
6
|
+
s.description = 'fast, accurate ctags generator for ruby source code using Ripper'
|
7
|
+
|
8
|
+
s.homepage = 'http://github.com/tmm1/ripper-tags'
|
9
|
+
s.has_rdoc = false
|
10
|
+
|
11
|
+
s.authors = ['Aman Gupta']
|
12
|
+
s.email = ['aman@tmm1.net']
|
13
|
+
|
14
|
+
s.add_dependency 'yajl-ruby'
|
15
|
+
|
16
|
+
s.require_paths = ['lib']
|
17
|
+
s.bindir = 'bin'
|
18
|
+
s.executables << 'ripper-tags'
|
19
|
+
|
20
|
+
s.files = `git ls-files`.split("\n")
|
21
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require File.expand_path('../../lib/tag_ripper', __FILE__)
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
class TagRipperTest < Test::Unit::TestCase
|
5
|
+
def test_extract_basics
|
6
|
+
tags = TagRipper.extract(<<-EOC)
|
7
|
+
Const1 = 123
|
8
|
+
def gmethod
|
9
|
+
end
|
10
|
+
module M
|
11
|
+
class C
|
12
|
+
Const2 = 456
|
13
|
+
def imethod
|
14
|
+
end
|
15
|
+
alias imethod_alias imethod
|
16
|
+
def self.cmethod
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
class M::C
|
21
|
+
def imethod2
|
22
|
+
end
|
23
|
+
def self.cmethod2
|
24
|
+
end
|
25
|
+
class << self
|
26
|
+
def cmethod3
|
27
|
+
end
|
28
|
+
alias cmethod_alias cmethod3
|
29
|
+
end
|
30
|
+
end
|
31
|
+
M::C.class_eval do
|
32
|
+
def imethod3
|
33
|
+
end
|
34
|
+
def self.cmethod4
|
35
|
+
end
|
36
|
+
end
|
37
|
+
EOC
|
38
|
+
|
39
|
+
assert_equal %w[
|
40
|
+
Const1
|
41
|
+
Object#gmethod
|
42
|
+
M
|
43
|
+
M::C
|
44
|
+
M::C::Const2
|
45
|
+
M::C#imethod
|
46
|
+
M::C#imethod_alias
|
47
|
+
M::C.cmethod
|
48
|
+
M::C
|
49
|
+
M::C#imethod2
|
50
|
+
M::C.cmethod2
|
51
|
+
M::C.cmethod3
|
52
|
+
M::C.cmethod_alias
|
53
|
+
M::C#imethod3
|
54
|
+
M::C.cmethod4
|
55
|
+
], tags.map{ |t| t[:full_name] }
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_extract_access
|
59
|
+
tags = TagRipper.extract(<<-EOC)
|
60
|
+
class Test
|
61
|
+
def abc() end
|
62
|
+
private
|
63
|
+
def def() end
|
64
|
+
protected
|
65
|
+
def ghi() end
|
66
|
+
public
|
67
|
+
def jkl() end
|
68
|
+
end
|
69
|
+
EOC
|
70
|
+
|
71
|
+
assert_equal nil, tags.find{ |t| t[:name] == 'abc' }[:access]
|
72
|
+
assert_equal 'private', tags.find{ |t| t[:name] == 'def' }[:access]
|
73
|
+
assert_equal 'protected', tags.find{ |t| t[:name] == 'ghi' }[:access]
|
74
|
+
assert_equal 'public', tags.find{ |t| t[:name] == 'jkl' }[:access]
|
75
|
+
end
|
76
|
+
end
|
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ripper-tags
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Aman Gupta
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2013-01-01 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: yajl-ruby
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
34
|
+
description: fast, accurate ctags generator for ruby source code using Ripper
|
35
|
+
email:
|
36
|
+
- aman@tmm1.net
|
37
|
+
executables:
|
38
|
+
- ripper-tags
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files: []
|
42
|
+
|
43
|
+
files:
|
44
|
+
- Gemfile
|
45
|
+
- README.md
|
46
|
+
- Rakefile
|
47
|
+
- bin/ripper-tags
|
48
|
+
- lib/tag_ripper.rb
|
49
|
+
- ripper-tags.gemspec
|
50
|
+
- test/test_ripper_tags.rb
|
51
|
+
homepage: http://github.com/tmm1/ripper-tags
|
52
|
+
licenses: []
|
53
|
+
|
54
|
+
post_install_message:
|
55
|
+
rdoc_options: []
|
56
|
+
|
57
|
+
require_paths:
|
58
|
+
- lib
|
59
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
hash: 3
|
65
|
+
segments:
|
66
|
+
- 0
|
67
|
+
version: "0"
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
hash: 3
|
74
|
+
segments:
|
75
|
+
- 0
|
76
|
+
version: "0"
|
77
|
+
requirements: []
|
78
|
+
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 1.8.24
|
81
|
+
signing_key:
|
82
|
+
specification_version: 3
|
83
|
+
summary: ctags generator for ruby code
|
84
|
+
test_files: []
|
85
|
+
|