ruby_header_parser 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.
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyHeaderParser
4
+ # function definition in header file
5
+ class FunctionDefinition
6
+ # @!attribute name
7
+ # @return [String]
8
+ attr_accessor :name
9
+
10
+ # @!attribute definition
11
+ # @return [String]
12
+ attr_accessor :definition
13
+
14
+ # @!attribute typeref
15
+ # @return [TyperefDefinition]
16
+ attr_accessor :typeref
17
+
18
+ # @!attribute args
19
+ # @return [Array<ArgumentDefinition>]
20
+ attr_accessor :args
21
+
22
+ # @param name [String]
23
+ # @param definition [String]
24
+ # @param typeref [TyperefDefinition]
25
+ # @param args [Array<ArgumentDefinition>]
26
+ def initialize(name:, definition:, typeref:, args:)
27
+ @name = name
28
+ @definition = definition
29
+ @typeref = typeref
30
+ @args = args
31
+ end
32
+
33
+ # @param other [FunctionDefinition]
34
+ # @return [Boolean]
35
+ def ==(other)
36
+ other.is_a?(FunctionDefinition) && name == other.name && definition == other.definition &&
37
+ typeref == other.typeref && args == other.args
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,376 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyHeaderParser
4
+ # parse `ruby.h` using `ctags`
5
+ class Parser # rubocop:disable Metrics/ClassLength
6
+ # @!attribute [r] header_file
7
+ # @return [String]
8
+ attr_reader :header_file
9
+
10
+ # @!attribute [r] include_paths
11
+ # @return [Array<String>]
12
+ attr_reader :include_paths
13
+
14
+ # @!attribute [r] dist_preprocessed_header_file
15
+ # @return [String]
16
+ attr_reader :dist_preprocessed_header_file
17
+
18
+ # @!attribute [r] data
19
+ # @return [RubyHeaderParser::Config]
20
+ attr_reader :config
21
+
22
+ DEFAULT_HEADER_FILE = "#{RbConfig::CONFIG["rubyhdrdir"]}/ruby.h".freeze
23
+
24
+ DEFAULT_INCLUDE_PATHS = [
25
+ RbConfig::CONFIG["rubyarchhdrdir"],
26
+ RbConfig::CONFIG["rubyhdrdir"],
27
+ ].freeze
28
+
29
+ # @param header_file [String] Path to `ruby.h`
30
+ # @param include_paths [Array<String>]
31
+ # @param dist_preprocessed_header_file [String,nil] Destination path to the output of preprocessed ruby.h.
32
+ # (default: `"#{Dir.tmpdir}/ruby_preprocessed.h"`)
33
+ # @param config_file [String,nil] Path to config file (default: `config/default.yml`)
34
+ #
35
+ # @note `dist_preprocessed_header_file` is used as the output destination for temporary files when the parser
36
+ # is executed
37
+ #
38
+ # @note See [CONFIG.md](../file.CONFIG.html) for config file details
39
+ def initialize(dist_preprocessed_header_file: nil, header_file: DEFAULT_HEADER_FILE,
40
+ include_paths: DEFAULT_INCLUDE_PATHS, config_file: nil)
41
+ @header_file = header_file
42
+ @include_paths = include_paths
43
+ @dist_preprocessed_header_file = dist_preprocessed_header_file || File.join(Dir.tmpdir, "ruby_preprocessed.h")
44
+
45
+ config_file ||= File.expand_path("../../config/default.yml", __dir__.to_s)
46
+ @config = Config.new(config_file)
47
+ end
48
+
49
+ # @return [Array<RubyHeaderParser::FunctionDefinition>]
50
+ def extract_function_definitions
51
+ __extract_function_definitions(c_kinds: "p", kind: "p", is_parse_multiline_definition: true)
52
+ end
53
+
54
+ # @return [Array<RubyHeaderParser::FunctionDefinition>]
55
+ def extract_static_inline_function_definitions
56
+ __extract_function_definitions(c_kinds: "+p-d", kind: "f", is_parse_multiline_definition: false)
57
+ end
58
+
59
+ # @return [Array<RubyHeaderParser::StructDefinition>]
60
+ def extract_struct_definitions
61
+ stdout = execute_ctags("--c-kinds=s --fields=+n")
62
+
63
+ stdout.each_line.with_object([]) do |line, definitions|
64
+ parts = line.split("\t")
65
+
66
+ struct_name = parts[0]
67
+ next unless config.should_generate_struct?(struct_name)
68
+
69
+ definitions << StructDefinition.new(
70
+ name: struct_name,
71
+ )
72
+ end
73
+ end
74
+
75
+ # @return [Array<RubyHeaderParser::TyperefDefinition>]
76
+ def extract_type_definitions
77
+ stdout = execute_ctags("--c-kinds=t --fields=+n")
78
+
79
+ stdout.each_line.with_object([]) do |line, definitions|
80
+ parts = line.split("\t")
81
+
82
+ type_name = parts[0]
83
+
84
+ next unless config.should_generate_type?(type_name)
85
+
86
+ definitions << TypeDefinition.new(
87
+ name: type_name,
88
+ )
89
+ end.uniq(&:name)
90
+ end
91
+
92
+ # @return [Array<RubyHeaderParser::EnumDefinition>]
93
+ def extract_enum_definitions
94
+ stdout = execute_ctags("--c-kinds=e --fields=+n")
95
+
96
+ name_to_definitions =
97
+ stdout.each_line.with_object({}) do |line, hash|
98
+ parts = line.split("\t")
99
+
100
+ enum_name = Util.find_field(parts, "enum")
101
+ next unless enum_name
102
+
103
+ value = parts[0]
104
+
105
+ next unless config.should_generate_enum?(enum_name)
106
+
107
+ hash[enum_name] ||= EnumDefinition.new(name: enum_name)
108
+ hash[enum_name].values << value
109
+ end
110
+
111
+ name_to_definitions.values
112
+ end
113
+
114
+ private
115
+
116
+ # @param c_kinds [String]
117
+ # @param kind [String]
118
+ # @param is_parse_multiline_definition [Boolean]
119
+ # @return [Array<RubyHeaderParser::FunctionDefinition>]
120
+ def __extract_function_definitions(c_kinds:, kind:, is_parse_multiline_definition:)
121
+ stdout = execute_ctags("--c-kinds=#{c_kinds} --fields=+nS --extras=+q")
122
+
123
+ stdout.each_line.map do |line|
124
+ generate_function_definition_from_line(line:, kind:, is_parse_multiline_definition:)
125
+ end.compact.uniq(&:name)
126
+ end
127
+
128
+ # @param line [String]
129
+ # @param kind [String]
130
+ # @param is_parse_multiline_definition [Boolean]
131
+ #
132
+ # @return [RubyHeaderParser::FunctionDefinition, nil]
133
+ def generate_function_definition_from_line(line:, kind:, is_parse_multiline_definition:)
134
+ parts = line.split("\t")
135
+
136
+ function_name = parts[0]
137
+ filepath = parts[1]
138
+
139
+ return nil unless config.should_generate_function?(function_name)
140
+
141
+ return nil unless parts[3] == kind
142
+
143
+ line_num = Util.find_field(parts, "line").to_i
144
+ definition = parse_function_definition(filepath:, pattern: parts[2], line_num:, is_parse_multiline_definition:)
145
+
146
+ args = parse_definition_args(function_name, Util.find_field(parts, "signature"))
147
+
148
+ # Exclude functions with variable-length arguments
149
+ return nil if args&.last&.type == "..."
150
+
151
+ typeref_field = Util.find_field(parts, "typeref:typename")
152
+
153
+ FunctionDefinition.new(
154
+ definition:,
155
+ name: function_name,
156
+ typeref: create_typeref(definition:, function_name:, typeref_field:, filepath:, line_num:),
157
+ args:,
158
+ )
159
+ end
160
+
161
+ # @param args [String]
162
+ # @return [String]
163
+ def execute_ctags(args = "")
164
+ unless File.exist?(dist_preprocessed_header_file)
165
+ include_args = include_paths.map { |path| "-I #{path}" }.join(" ")
166
+ system("gcc -E #{include_args} #{header_file} -o #{dist_preprocessed_header_file}", exception: true)
167
+ end
168
+
169
+ `ctags --languages=C --language-force=C #{args} -f - #{dist_preprocessed_header_file}`
170
+ end
171
+
172
+ # @param file [String]
173
+ # @param line_num [Integer]
174
+ def read_definition_from_header_file(file, line_num)
175
+ definition = +""
176
+
177
+ File.open(file, "r") do |f|
178
+ f.each_with_index do |line, index|
179
+ if index + 1 >= line_num
180
+ definition << line.strip
181
+ return definition if definition.end_with?(");")
182
+ end
183
+ end
184
+ end
185
+ ""
186
+ end
187
+
188
+ # @param filepath [String]
189
+ # @param pattern [String]
190
+ # @param line_num [Integer]
191
+ # @param is_parse_multiline_definition [Boolean]
192
+ # @return [String]
193
+ def parse_function_definition(filepath:, pattern:, line_num:, is_parse_multiline_definition:)
194
+ definition =
195
+ if pattern.end_with?("$/;\"")
196
+ pattern.delete_prefix("/^").delete_suffix("$/;\"")
197
+ elsif is_parse_multiline_definition
198
+ read_definition_from_header_file(filepath, line_num)
199
+ else
200
+ pattern.delete_prefix("/^")
201
+ end
202
+
203
+ definition.strip.delete_suffix(";")
204
+ end
205
+
206
+ # @param function_name [String]
207
+ # @param signature [String,nil]
208
+ # @return [Array<RubyHeaderParser::ArgumentDefinition>]
209
+ def parse_definition_args(function_name, signature)
210
+ return [] unless signature
211
+
212
+ signature = signature.strip.delete_prefix("(").delete_suffix(")")
213
+ return [] if signature.match?(/^void$/i)
214
+
215
+ args = Util.split_signature(signature)
216
+
217
+ arg_pos = 0
218
+ args.map do |arg|
219
+ arg_pos += 1
220
+ generate_argument_definition(function_name:, arg:, arg_pos:)
221
+ end
222
+ end
223
+
224
+ # @param definition [String]
225
+ # @param function_name [String]
226
+ # @param typeref_field [String,nil]
227
+ # @param filepath [String]
228
+ # @param line_num [Integer]
229
+ # @return [RubyHeaderParser::TyperefDefinition]
230
+ def create_typeref(definition:, function_name:, typeref_field:, filepath:, line_num:)
231
+ typeref_type = parse_typeref_type(definition:, function_name:, typeref_field:, filepath:, line_num:)
232
+
233
+ typeref_pointer = nil
234
+ if typeref_type.match?(/\*+$/)
235
+ typeref_type = typeref_type.gsub(/\*+$/, "").strip
236
+ typeref_pointer = config.function_self_pointer_hint(function_name)
237
+ end
238
+
239
+ TyperefDefinition.new(type: typeref_type, pointer: typeref_pointer)
240
+ end
241
+
242
+ # @param definition [String]
243
+ # @param function_name [String]
244
+ # @param typeref_field [String,nil]
245
+ # @param filepath [String]
246
+ # @param line_num [Integer]
247
+ # @return [String]
248
+ def parse_typeref_type(definition:, function_name:, typeref_field:, filepath:, line_num:)
249
+ typeref_type =
250
+ if typeref_field
251
+ typeref_field.gsub(/[A-Z_]+\s*\(\(.*\)\)/, "")
252
+ else
253
+ # parse typeref in definition
254
+ type = definition[0...definition.index(function_name)] || ""
255
+ type.gsub("char *", "char*").strip
256
+ end
257
+
258
+ typeref_type = Util.sanitize_type(typeref_type)
259
+ return typeref_type unless typeref_type.empty?
260
+
261
+ # Check prev line
262
+ line = read_file_line(filepath:, line_num: line_num - 1)
263
+ return Util.sanitize_type(line) if line
264
+
265
+ ""
266
+ end
267
+
268
+ # @param filepath [String]
269
+ # @param line_num [Integer]
270
+ def read_file_line(filepath:, line_num:)
271
+ return nil if line_num < 1
272
+
273
+ lines = File.open(filepath, "rb") { |f| f.readlines(chomp: true) }
274
+ lines[line_num - 1]
275
+ end
276
+
277
+ # @param function_name [String]
278
+ # @param arg [String]
279
+ # @param arg_pos [Integer]
280
+ #
281
+ # @return [ArgumentDefinition]
282
+ def generate_argument_definition(function_name:, arg:, arg_pos:)
283
+ parts = arg.split
284
+
285
+ if parts.count < 2
286
+ return ArgumentDefinition.new(
287
+ type: parts[0],
288
+ name: "arg#{arg_pos}",
289
+ pointer: nil,
290
+ )
291
+ end
292
+
293
+ loop do
294
+ pointer_index = parts.index("*")
295
+ break unless pointer_index
296
+
297
+ parts[pointer_index - 1] << "*"
298
+ parts.delete_at(pointer_index)
299
+ end
300
+
301
+ type, pointer, length = analyze_argument_type(function_name:, arg_pos:, parts:)
302
+
303
+ ArgumentDefinition.new(
304
+ name: parts[-1],
305
+ type:,
306
+ pointer:,
307
+ length:,
308
+ )
309
+ end
310
+
311
+ # @param function_name [String]
312
+ # @param arg_pos [Integer]
313
+ # @param parts [Array<String>]
314
+ #
315
+ # @return [Array<String, Symbol, Integer>]
316
+ # - type [String]
317
+ # - pointer [Symbol]
318
+ # - length [Integer]
319
+ def analyze_argument_type(function_name:, arg_pos:, parts:)
320
+ pointer, length = prepare_argument_parts(arg_pos:, parts:)
321
+ type = parts[0...-1] || []
322
+ original_type = Util.sanitize_type(type.join(" "))
323
+
324
+ case original_type
325
+ when /\*+$/
326
+ type = original_type.gsub(/\*+$/, "").strip
327
+ pointer = config.function_arg_pointer_hint(function_name:, pos: arg_pos)
328
+
329
+ when /^void\s*/, /\(.*\)/
330
+ # function pointer (e.g. void *(*func)(void *)) is treated as `void*`
331
+ type = "void"
332
+ pointer = config.function_arg_pointer_hint(function_name:, pos: arg_pos)
333
+
334
+ else
335
+ type = original_type
336
+ end
337
+
338
+ length = pointer_length(original_type) if pointer == :sref
339
+
340
+ [type, pointer, length]
341
+ end
342
+
343
+ # @param arg_pos [Integer]
344
+ # @param parts [Array<String>]
345
+ #
346
+ # @return [Array<Symbol, Integer>]
347
+ # - pointer [Symbol,nil]
348
+ # - length [Integer]
349
+ def prepare_argument_parts(parts:, arg_pos:)
350
+ if parts[-1] =~ /\[([0-9]+)?\]$/
351
+ parts[-1].gsub!(/\[([0-9]+)?\]$/, "")
352
+ length = ::Regexp.last_match(1).to_i
353
+
354
+ unless parts[-1] =~ /^[0-9a-zA-Z_]+$/
355
+ # last elements isn't dummy argument
356
+ parts << "arg#{arg_pos}"
357
+ end
358
+
359
+ return [:array, length]
360
+ end
361
+
362
+ unless parts[-1] =~ /^[0-9a-zA-Z_]+$/
363
+ # last elements isn't dummy argument
364
+ parts << "arg#{arg_pos}"
365
+ end
366
+
367
+ [nil, 0]
368
+ end
369
+
370
+ # @param type [String]
371
+ def pointer_length(type)
372
+ type =~ /(\*+)$/
373
+ ::Regexp.last_match(1)&.length || 0
374
+ end
375
+ end
376
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyHeaderParser
4
+ # struct definition in header file
5
+ class StructDefinition
6
+ # @!attribute name
7
+ # @return [String]
8
+ attr_accessor :name
9
+
10
+ # @param name [String]
11
+ def initialize(name:)
12
+ @name = name
13
+ end
14
+
15
+ # @param other [StructDefinition]
16
+ # @return [Boolean]
17
+ def ==(other)
18
+ other.is_a?(StructDefinition) && name == other.name
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyHeaderParser
4
+ # type definition in header file
5
+ class TypeDefinition
6
+ # @!attribute name
7
+ # @return [String]
8
+ attr_accessor :name
9
+
10
+ # @param name [String]
11
+ def initialize(name:)
12
+ @name = name
13
+ end
14
+
15
+ # @param other [TypeDefinition]
16
+ # @return [Boolean]
17
+ def ==(other)
18
+ other.is_a?(TypeDefinition) && name == other.name
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyHeaderParser
4
+ # typeref definition for {RubyHeaderParser::FunctionDefinition}
5
+ class TyperefDefinition
6
+ # @!attribute type
7
+ # @return [String]
8
+ attr_accessor :type
9
+
10
+ # @!attribute pointer
11
+ # @return [Symbol,nil] :ref, :raw
12
+ attr_accessor :pointer
13
+
14
+ # @param type [String]
15
+ # @param pointer [Symbol,nil] :ref, :raw
16
+ def initialize(type:, pointer: nil)
17
+ @type = type
18
+ @pointer = pointer
19
+ end
20
+
21
+ # @return [Boolean]
22
+ def pointer?
23
+ !!pointer
24
+ end
25
+
26
+ # @param other [TyperefDefinition]
27
+ # @return [Boolean]
28
+ def ==(other)
29
+ other.is_a?(TyperefDefinition) && type == other.type && pointer == other.pointer
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyHeaderParser
4
+ # util methods
5
+ module Util
6
+ # @param array [Array<String>]
7
+ # @param field_name [String]
8
+ # @return [String,nil]
9
+ def self.find_field(array, field_name)
10
+ array.each do |element|
11
+ return element.delete_prefix("#{field_name}:").strip if element.start_with?("#{field_name}:")
12
+ end
13
+
14
+ nil
15
+ end
16
+
17
+ # @param signature [String]
18
+ # @return [Array<String>]
19
+ def self.split_signature(signature)
20
+ signature.scan(/[^,]+\([^()]*\)|[^,]+/).flatten.map(&:strip)
21
+ end
22
+
23
+ # @param type [String]
24
+ # @return [String]
25
+ def self.sanitize_type(type)
26
+ type.gsub(/(enum|volatile|const|struct|static\s+inline)\s+/i, "").gsub("const*", "").strip
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyHeaderParser
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "yaml"
4
+ require "tmpdir"
5
+
6
+ require_relative "ruby_header_parser/version"
7
+
8
+ # Parser for ruby.h
9
+ module RubyHeaderParser
10
+ class Error < StandardError; end
11
+
12
+ autoload :ArgumentDefinition, "ruby_header_parser/argument_definition"
13
+ autoload :Config, "ruby_header_parser/config"
14
+ autoload :EnumDefinition, "ruby_header_parser/enum_definition"
15
+ autoload :FunctionDefinition, "ruby_header_parser/function_definition"
16
+ autoload :Parser, "ruby_header_parser/parser"
17
+ autoload :StructDefinition, "ruby_header_parser/struct_definition"
18
+ autoload :TypeDefinition, "ruby_header_parser/type_definition"
19
+ autoload :TyperefDefinition, "ruby_header_parser/typeref_definition"
20
+ autoload :Util, "ruby_header_parser/util"
21
+ end
@@ -0,0 +1,116 @@
1
+ ---
2
+ path: ".gem_rbs_collection"
3
+ gems:
4
+ - name: ast
5
+ version: '2.4'
6
+ source:
7
+ type: git
8
+ name: ruby/gem_rbs_collection
9
+ revision: 704f7e6b395fca717cc25c562598ca86015ed545
10
+ remote: https://github.com/ruby/gem_rbs_collection.git
11
+ repo_dir: gems
12
+ - name: binding_of_caller
13
+ version: '1.0'
14
+ source:
15
+ type: git
16
+ name: ruby/gem_rbs_collection
17
+ revision: 704f7e6b395fca717cc25c562598ca86015ed545
18
+ remote: https://github.com/ruby/gem_rbs_collection.git
19
+ repo_dir: gems
20
+ - name: dbm
21
+ version: '0'
22
+ source:
23
+ type: stdlib
24
+ - name: diff-lcs
25
+ version: '1.5'
26
+ source:
27
+ type: git
28
+ name: ruby/gem_rbs_collection
29
+ revision: 704f7e6b395fca717cc25c562598ca86015ed545
30
+ remote: https://github.com/ruby/gem_rbs_collection.git
31
+ repo_dir: gems
32
+ - name: fileutils
33
+ version: '0'
34
+ source:
35
+ type: stdlib
36
+ - name: json
37
+ version: '0'
38
+ source:
39
+ type: stdlib
40
+ - name: parallel
41
+ version: '1.20'
42
+ source:
43
+ type: git
44
+ name: ruby/gem_rbs_collection
45
+ revision: 704f7e6b395fca717cc25c562598ca86015ed545
46
+ remote: https://github.com/ruby/gem_rbs_collection.git
47
+ repo_dir: gems
48
+ - name: parser
49
+ version: '3.2'
50
+ source:
51
+ type: git
52
+ name: ruby/gem_rbs_collection
53
+ revision: 704f7e6b395fca717cc25c562598ca86015ed545
54
+ remote: https://github.com/ruby/gem_rbs_collection.git
55
+ repo_dir: gems
56
+ - name: pstore
57
+ version: '0'
58
+ source:
59
+ type: stdlib
60
+ - name: psych
61
+ version: '0'
62
+ source:
63
+ type: stdlib
64
+ - name: rainbow
65
+ version: '3.0'
66
+ source:
67
+ type: git
68
+ name: ruby/gem_rbs_collection
69
+ revision: 704f7e6b395fca717cc25c562598ca86015ed545
70
+ remote: https://github.com/ruby/gem_rbs_collection.git
71
+ repo_dir: gems
72
+ - name: rake
73
+ version: '13.0'
74
+ source:
75
+ type: git
76
+ name: ruby/gem_rbs_collection
77
+ revision: 704f7e6b395fca717cc25c562598ca86015ed545
78
+ remote: https://github.com/ruby/gem_rbs_collection.git
79
+ repo_dir: gems
80
+ - name: regexp_parser
81
+ version: '2.8'
82
+ source:
83
+ type: git
84
+ name: ruby/gem_rbs_collection
85
+ revision: 704f7e6b395fca717cc25c562598ca86015ed545
86
+ remote: https://github.com/ruby/gem_rbs_collection.git
87
+ repo_dir: gems
88
+ - name: rspec-parameterized-core
89
+ version: 1.0.1
90
+ source:
91
+ type: rubygems
92
+ - name: rspec-parameterized-table_syntax
93
+ version: 1.0.1
94
+ source:
95
+ type: rubygems
96
+ - name: rubocop
97
+ version: '1.57'
98
+ source:
99
+ type: git
100
+ name: ruby/gem_rbs_collection
101
+ revision: 704f7e6b395fca717cc25c562598ca86015ed545
102
+ remote: https://github.com/ruby/gem_rbs_collection.git
103
+ repo_dir: gems
104
+ - name: rubocop-ast
105
+ version: '1.30'
106
+ source:
107
+ type: git
108
+ name: ruby/gem_rbs_collection
109
+ revision: 704f7e6b395fca717cc25c562598ca86015ed545
110
+ remote: https://github.com/ruby/gem_rbs_collection.git
111
+ repo_dir: gems
112
+ - name: yaml
113
+ version: '0'
114
+ source:
115
+ type: stdlib
116
+ gemfile_lock_path: Gemfile.lock
@@ -0,0 +1,26 @@
1
+ # Download sources
2
+ sources:
3
+ - type: git
4
+ name: ruby/gem_rbs_collection
5
+ remote: https://github.com/ruby/gem_rbs_collection.git
6
+ revision: main
7
+ repo_dir: gems
8
+
9
+ # You can specify local directories as sources also.
10
+ # - type: local
11
+ # path: path/to/your/local/repository
12
+
13
+ # A directory to install the downloaded RBSs
14
+ path: .gem_rbs_collection
15
+
16
+ gems:
17
+ - name: rbs
18
+ ignore: true
19
+ - name: steep
20
+ ignore: true
21
+ - name: yard
22
+ ignore: true
23
+ - name: ruby_header_parser
24
+ ignore: true
25
+
26
+ - name: yaml