t-ruby 0.0.11 → 0.0.34

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f72a8bc0185eae719b855a9edb95a6fa17f9d9f3b4dfadf67f5a32b0a6ab0e32
4
- data.tar.gz: 376722902f19f751b420e6e6e9c7951aebf45bc76c081c498d8ba4d92e7383f8
3
+ metadata.gz: aaa0445c84cb0a6685e788645a19fee5d30d2f1e6f79052122fb16e8a3f08e91
4
+ data.tar.gz: 446845b5b1e470964f664d590197262f0e3555b82dd59f7b75a484324b99ec63
5
5
  SHA512:
6
- metadata.gz: d742076e86ec5f1fdcd4bac9fe98b2fff48ed3fc964caa420f11e1d88263db26e55768e5fa6f00f1a976712d3aaf4cb6d541b3c79df863550c6f84eb2fba481b
7
- data.tar.gz: ee975f1c9b0c70254f96082178734c8ae1f799565d193425a80d416bb60f088a4ccf41516b878d35a1c257ec7557c47220c65045b2d5099bfbb855446fb513f5
6
+ metadata.gz: e422c5535edcb5085efd7018825c1675b06b3c2bb3657da1c6d9f6b07202233b53c03c145888fbdc221fc78df4873d18c2d0f4326d19ede16134eda409fb7418
7
+ data.tar.gz: 0d988eaa6c08a586af4c965447087467e500cc75de4d7bc879c239c3f6924caf504123fc3117ed9be4e676b0ae2715bdadf888218e8072702c1a66bbb329a288
data/lib/t_ruby/cli.rb CHANGED
@@ -9,6 +9,7 @@ module TRuby
9
9
  trc <file.trb> Compile a .trb file to .rb
10
10
  trc <file.rb> Copy .rb file to build/ and generate .rbs
11
11
  trc --init Initialize a new t-ruby project
12
+ trc --config, -c <path> Use custom config file
12
13
  trc --watch, -w Watch input files and recompile on change
13
14
  trc --decl <file.trb> Generate .d.trb declaration file
14
15
  trc --lsp Start LSP server (for IDE integration)
@@ -19,6 +20,7 @@ module TRuby
19
20
  trc hello.trb Compile hello.trb to build/hello.rb
20
21
  trc utils.rb Copy utils.rb to build/ and generate utils.rbs
21
22
  trc --init Create trbconfig.yml and src/, build/ directories
23
+ trc -c custom.yml file.trb Compile with custom config file
22
24
  trc -w Watch all .trb and .rb files in current directory
23
25
  trc -w src/ Watch all .trb and .rb files in src/ directory
24
26
  trc --watch hello.trb Watch specific file for changes
@@ -66,8 +68,12 @@ module TRuby
66
68
  return
67
69
  end
68
70
 
69
- input_file = @args.first
70
- compile(input_file)
71
+ # Extract config path if --config or -c flag is present
72
+ config_path = extract_config_path
73
+
74
+ # Get input file (first non-flag argument)
75
+ input_file = find_input_file
76
+ compile(input_file, config_path: config_path)
71
77
  end
72
78
 
73
79
  private
@@ -80,24 +86,43 @@ module TRuby
80
86
  created = []
81
87
  skipped = []
82
88
 
83
- # Create trbconfig.yml
89
+ # Create trbconfig.yml with new schema
84
90
  if File.exist?(config_file)
85
91
  skipped << config_file
86
92
  else
87
93
  File.write(config_file, <<~YAML)
88
- emit:
89
- rb: true
90
- rbs: true
91
- dtrb: false
92
-
93
- paths:
94
- src: "./#{src_dir}"
95
- out: "./#{build_dir}"
96
-
97
- strict:
98
- rbs_compat: true
99
- null_safety: false
100
- inference: basic
94
+ # T-Ruby configuration file
95
+ # See: https://type-ruby.github.io/docs/getting-started/project-configuration
96
+
97
+ source:
98
+ include:
99
+ - #{src_dir}
100
+ exclude: []
101
+ extensions:
102
+ - ".trb"
103
+ - ".rb"
104
+
105
+ output:
106
+ ruby_dir: #{build_dir}
107
+ # rbs_dir: sig # Optional: separate directory for .rbs files
108
+ preserve_structure: true
109
+ # clean_before_build: false
110
+
111
+ compiler:
112
+ strictness: standard # strict | standard | permissive
113
+ generate_rbs: true
114
+ target_ruby: "3.0"
115
+ # experimental: []
116
+ # checks:
117
+ # no_implicit_any: false
118
+ # no_unused_vars: false
119
+ # strict_nil: false
120
+
121
+ watch:
122
+ # paths: [] # Additional paths to watch
123
+ debounce: 100
124
+ # clear_screen: false
125
+ # on_success: "bundle exec rspec"
101
126
  YAML
102
127
  created << config_file
103
128
  end
@@ -161,8 +186,8 @@ module TRuby
161
186
  exit 1
162
187
  end
163
188
 
164
- def compile(input_file)
165
- config = Config.new
189
+ def compile(input_file, config_path: nil)
190
+ config = Config.new(config_path)
166
191
  compiler = Compiler.new(config)
167
192
 
168
193
  output_path = compiler.compile(input_file)
@@ -171,5 +196,36 @@ module TRuby
171
196
  puts "Error: #{e.message}"
172
197
  exit 1
173
198
  end
199
+
200
+ # Extract config path from --config or -c flag
201
+ def extract_config_path
202
+ config_index = @args.index("--config") || @args.index("-c")
203
+ return nil unless config_index
204
+
205
+ @args[config_index + 1]
206
+ end
207
+
208
+ # Find the input file (first non-flag argument)
209
+ def find_input_file
210
+ skip_next = false
211
+ @args.each do |arg|
212
+ if skip_next
213
+ skip_next = false
214
+ next
215
+ end
216
+
217
+ # Skip known flags with arguments
218
+ if %w[--config -c --decl].include?(arg)
219
+ skip_next = true
220
+ next
221
+ end
222
+
223
+ # Skip flags without arguments
224
+ next if arg.start_with?("-")
225
+
226
+ return arg
227
+ end
228
+ nil
229
+ end
174
230
  end
175
231
  end
@@ -47,16 +47,19 @@ module TRuby
47
47
  File.write(output_path, output)
48
48
 
49
49
  # Generate .rbs file if enabled in config
50
- if @config.emit["rbs"]
50
+ if @config.compiler["generate_rbs"]
51
+ rbs_dir = @config.rbs_dir
52
+ FileUtils.mkdir_p(rbs_dir)
51
53
  if @use_ir && parser.ir_program
52
- generate_rbs_from_ir(base_filename, out_dir, parser.ir_program)
54
+ generate_rbs_from_ir(base_filename, rbs_dir, parser.ir_program)
53
55
  else
54
- generate_rbs_file(base_filename, out_dir, parse_result)
56
+ generate_rbs_file(base_filename, rbs_dir, parse_result)
55
57
  end
56
58
  end
57
59
 
58
- # Generate .d.trb file if enabled in config
59
- if @config.emit["dtrb"]
60
+ # Generate .d.trb file if enabled in config (legacy support)
61
+ # TODO: Add compiler.generate_dtrb option in future
62
+ if @config.compiler.key?("generate_dtrb") && @config.compiler["generate_dtrb"]
60
63
  generate_dtrb_file(input_path, out_dir)
61
64
  end
62
65
 
@@ -236,8 +239,10 @@ module TRuby
236
239
  FileUtils.cp(input_path, output_path)
237
240
 
238
241
  # Generate .rbs file if enabled in config
239
- if @config.emit["rbs"]
240
- generate_rbs_from_ruby(base_filename, out_dir, input_path)
242
+ if @config.compiler["generate_rbs"]
243
+ rbs_dir = @config.rbs_dir
244
+ FileUtils.mkdir_p(rbs_dir)
245
+ generate_rbs_from_ruby(base_filename, rbs_dir, input_path)
241
246
  end
242
247
 
243
248
  output_path
data/lib/t_ruby/config.rb CHANGED
@@ -3,51 +3,393 @@
3
3
  require "yaml"
4
4
 
5
5
  module TRuby
6
+ # Error raised when configuration is invalid
7
+ class ConfigError < StandardError; end
8
+
6
9
  class Config
10
+ # Valid strictness levels
11
+ VALID_STRICTNESS = %w[strict standard permissive].freeze
12
+ # New schema structure (v0.0.12+)
7
13
  DEFAULT_CONFIG = {
8
- "emit" => {
9
- "rb" => true,
10
- "rbs" => true,
11
- "dtrb" => false
14
+ "source" => {
15
+ "include" => ["src"],
16
+ "exclude" => [],
17
+ "extensions" => [".trb"]
18
+ },
19
+ "output" => {
20
+ "ruby_dir" => "build",
21
+ "rbs_dir" => nil,
22
+ "preserve_structure" => true,
23
+ "clean_before_build" => false
12
24
  },
13
- "paths" => {
14
- "src" => "./src",
15
- "out" => "./build"
25
+ "compiler" => {
26
+ "strictness" => "standard",
27
+ "generate_rbs" => true,
28
+ "target_ruby" => "3.0",
29
+ "experimental" => [],
30
+ "checks" => {
31
+ "no_implicit_any" => false,
32
+ "no_unused_vars" => false,
33
+ "strict_nil" => false
34
+ }
16
35
  },
17
- "strict" => {
18
- "rbs_compat" => true,
19
- "null_safety" => false,
20
- "inference" => "basic"
36
+ "watch" => {
37
+ "paths" => [],
38
+ "debounce" => 100,
39
+ "clear_screen" => false,
40
+ "on_success" => nil
21
41
  }
22
42
  }.freeze
23
43
 
24
- attr_reader :emit, :paths, :strict
44
+ # Legacy keys for migration detection
45
+ LEGACY_KEYS = %w[emit paths strict include exclude].freeze
46
+
47
+ # Always excluded (not configurable)
48
+ AUTO_EXCLUDE = [".git"].freeze
49
+
50
+ attr_reader :source, :output, :compiler, :watch, :version_requirement
25
51
 
26
52
  def initialize(config_path = nil)
27
- config = load_config(config_path)
28
- @emit = config["emit"]
29
- @paths = config["paths"]
30
- @strict = config["strict"]
53
+ raw_config = load_raw_config(config_path)
54
+ config = process_config(raw_config)
55
+
56
+ @source = config["source"]
57
+ @output = config["output"]
58
+ @compiler = config["compiler"]
59
+ @watch = config["watch"]
60
+ @version_requirement = raw_config["version"]
61
+ end
62
+
63
+ # Get output directory for compiled Ruby files
64
+ # @return [String] output directory path
65
+ def ruby_dir
66
+ @output["ruby_dir"] || "build"
67
+ end
68
+
69
+ # Get output directory for RBS files
70
+ # @return [String] RBS output directory (defaults to ruby_dir if not specified)
71
+ def rbs_dir
72
+ @output["rbs_dir"] || ruby_dir
73
+ end
74
+
75
+ # Check if source directory structure should be preserved in output
76
+ # @return [Boolean] true if structure should be preserved
77
+ def preserve_structure?
78
+ @output["preserve_structure"] != false
79
+ end
80
+
81
+ # Check if output directory should be cleaned before build
82
+ # @return [Boolean] true if should clean before build
83
+ def clean_before_build?
84
+ @output["clean_before_build"] == true
85
+ end
86
+
87
+ # Get compiler strictness level
88
+ # @return [String] one of: strict, standard, permissive
89
+ def strictness
90
+ @compiler["strictness"] || "standard"
91
+ end
92
+
93
+ # Check if RBS files should be generated
94
+ # @return [Boolean] true if RBS files should be generated
95
+ def generate_rbs?
96
+ @compiler["generate_rbs"] != false
97
+ end
98
+
99
+ # Get target Ruby version
100
+ # @return [String] target Ruby version (e.g., "3.0", "3.2")
101
+ def target_ruby
102
+ (@compiler["target_ruby"] || "3.0").to_s
103
+ end
104
+
105
+ # Get list of enabled experimental features
106
+ # @return [Array<String>] list of experimental feature names
107
+ def experimental_features
108
+ @compiler["experimental"] || []
109
+ end
110
+
111
+ # Check if a specific experimental feature is enabled
112
+ # @param feature [String] feature name to check
113
+ # @return [Boolean] true if feature is enabled
114
+ def experimental_enabled?(feature)
115
+ experimental_features.include?(feature)
116
+ end
117
+
118
+ # Check if no_implicit_any check is enabled
119
+ # @return [Boolean] true if check is enabled
120
+ def check_no_implicit_any?
121
+ @compiler.dig("checks", "no_implicit_any") == true
122
+ end
123
+
124
+ # Check if no_unused_vars check is enabled
125
+ # @return [Boolean] true if check is enabled
126
+ def check_no_unused_vars?
127
+ @compiler.dig("checks", "no_unused_vars") == true
128
+ end
129
+
130
+ # Check if strict_nil check is enabled
131
+ # @return [Boolean] true if check is enabled
132
+ def check_strict_nil?
133
+ @compiler.dig("checks", "strict_nil") == true
134
+ end
135
+
136
+ # Get additional watch paths
137
+ # @return [Array<String>] list of additional paths to watch
138
+ def watch_paths
139
+ @watch["paths"] || []
140
+ end
141
+
142
+ # Get watch debounce delay in milliseconds
143
+ # @return [Integer] debounce delay in milliseconds
144
+ def watch_debounce
145
+ @watch["debounce"] || 100
146
+ end
147
+
148
+ # Check if terminal should be cleared before rebuild
149
+ # @return [Boolean] true if terminal should be cleared
150
+ def watch_clear_screen?
151
+ @watch["clear_screen"] == true
152
+ end
153
+
154
+ # Get command to run after successful compilation
155
+ # @return [String, nil] command to run on success
156
+ def watch_on_success
157
+ @watch["on_success"]
158
+ end
159
+
160
+ # Check if current T-Ruby version satisfies the version requirement
161
+ # @return [Boolean] true if version is satisfied or no requirement specified
162
+ def version_satisfied?
163
+ return true if @version_requirement.nil?
164
+
165
+ requirement = Gem::Requirement.new(@version_requirement)
166
+ current = Gem::Version.new(TRuby::VERSION)
167
+ requirement.satisfied_by?(current)
168
+ rescue ArgumentError
169
+ false
170
+ end
171
+
172
+ # Validate the configuration
173
+ # @raise [ConfigError] if configuration is invalid
174
+ def validate!
175
+ validate_strictness!
176
+ true
31
177
  end
32
178
 
179
+ # Backwards compatible: alias for ruby_dir
33
180
  def out_dir
34
- @paths["out"]
181
+ ruby_dir
35
182
  end
36
183
 
184
+ # Backwards compatible: first source.include directory
37
185
  def src_dir
38
- @paths["src"]
186
+ @source["include"].first || "src"
187
+ end
188
+
189
+ # Get source include directories
190
+ # @return [Array<String>] list of include directories
191
+ def source_include
192
+ @source["include"] || ["src"]
193
+ end
194
+
195
+ # Get source exclude patterns
196
+ # @return [Array<String>] list of exclude patterns
197
+ def source_exclude
198
+ @source["exclude"] || []
199
+ end
200
+
201
+ # Get source file extensions
202
+ # @return [Array<String>] list of file extensions (e.g., [".trb", ".truby"])
203
+ def source_extensions
204
+ @source["extensions"] || [".trb"]
205
+ end
206
+
207
+ # Get include patterns for file discovery
208
+ def include_patterns
209
+ extensions = @source["extensions"] || [".trb"]
210
+ extensions.map { |ext| "**/*#{ext}" }
211
+ end
212
+
213
+ # Get exclude patterns
214
+ def exclude_patterns
215
+ @source["exclude"] || []
216
+ end
217
+
218
+ # Find all source files matching include patterns, excluding exclude patterns
219
+ # @return [Array<String>] list of matching file paths
220
+ def find_source_files
221
+ files = []
222
+
223
+ @source["include"].each do |include_dir|
224
+ base_dir = File.expand_path(include_dir)
225
+ next unless Dir.exist?(base_dir)
226
+
227
+ include_patterns.each do |pattern|
228
+ full_pattern = File.join(base_dir, pattern)
229
+ files.concat(Dir.glob(full_pattern))
230
+ end
231
+ end
232
+
233
+ # Filter out excluded files
234
+ files.reject { |f| excluded?(f) }.uniq.sort
235
+ end
236
+
237
+ # Check if a file path should be excluded
238
+ # @param file_path [String] absolute or relative file path
239
+ # @return [Boolean] true if file should be excluded
240
+ def excluded?(file_path)
241
+ relative_path = relative_to_src(file_path)
242
+ all_exclude_patterns.any? { |pattern| matches_pattern?(relative_path, pattern) }
39
243
  end
40
244
 
41
245
  private
42
246
 
43
- def load_config(config_path)
44
- if config_path && File.exist?(config_path)
45
- YAML.safe_load_file(config_path, permitted_classes: [Symbol])
46
- elsif File.exist?("trbconfig.yml")
47
- YAML.safe_load_file("trbconfig.yml", permitted_classes: [Symbol])
247
+ # Validate strictness value
248
+ def validate_strictness!
249
+ value = strictness
250
+ return if VALID_STRICTNESS.include?(value)
251
+
252
+ raise ConfigError, "Invalid compiler.strictness: '#{value}'. Must be one of: #{VALID_STRICTNESS.join(', ')}"
253
+ end
254
+
255
+ def load_raw_config(config_path)
256
+ raw = if config_path && File.exist?(config_path)
257
+ YAML.safe_load_file(config_path, permitted_classes: [Symbol]) || {}
258
+ elsif File.exist?("trbconfig.yml")
259
+ YAML.safe_load_file("trbconfig.yml", permitted_classes: [Symbol]) || {}
260
+ else
261
+ {}
262
+ end
263
+ expand_env_vars(raw)
264
+ end
265
+
266
+ # Expand environment variables in config values
267
+ # Supports ${VAR} and ${VAR:-default} syntax
268
+ def expand_env_vars(obj)
269
+ case obj
270
+ when Hash
271
+ obj.transform_values { |v| expand_env_vars(v) }
272
+ when Array
273
+ obj.map { |v| expand_env_vars(v) }
274
+ when String
275
+ expand_env_string(obj)
276
+ else
277
+ obj
278
+ end
279
+ end
280
+
281
+ # Expand environment variables in a single string
282
+ def expand_env_string(str)
283
+ str.gsub(/\$\{([^}]+)\}/) do |_match|
284
+ var_expr = ::Regexp.last_match(1)
285
+ if var_expr.include?(":-")
286
+ var_name, default_value = var_expr.split(":-", 2)
287
+ ENV.fetch(var_name, default_value)
288
+ else
289
+ ENV.fetch(var_expr, "")
290
+ end
291
+ end
292
+ end
293
+
294
+ def process_config(raw_config)
295
+ if legacy_config?(raw_config)
296
+ warn "DEPRECATED: trbconfig.yml uses legacy format. Please migrate to new schema (source/output/compiler/watch)."
297
+ migrate_legacy_config(raw_config)
298
+ else
299
+ merge_with_defaults(raw_config)
300
+ end
301
+ end
302
+
303
+ def legacy_config?(raw_config)
304
+ LEGACY_KEYS.any? { |key| raw_config.key?(key) }
305
+ end
306
+
307
+ def migrate_legacy_config(raw_config)
308
+ result = deep_dup(DEFAULT_CONFIG)
309
+
310
+ # Migrate emit -> compiler.generate_rbs
311
+ if raw_config["emit"]
312
+ result["compiler"]["generate_rbs"] = raw_config["emit"]["rbs"] if raw_config["emit"].key?("rbs")
313
+ end
314
+
315
+ # Migrate paths -> source.include and output.ruby_dir
316
+ if raw_config["paths"]
317
+ if raw_config["paths"]["src"]
318
+ src_path = raw_config["paths"]["src"].sub(%r{^\./}, "")
319
+ result["source"]["include"] = [src_path]
320
+ end
321
+ if raw_config["paths"]["out"]
322
+ out_path = raw_config["paths"]["out"].sub(%r{^\./}, "")
323
+ result["output"]["ruby_dir"] = out_path
324
+ end
325
+ end
326
+
327
+ # Migrate include/exclude patterns
328
+ if raw_config["include"]
329
+ # Keep legacy include patterns as-is for now
330
+ result["source"]["include"] = [result["source"]["include"].first || "src"]
331
+ end
332
+
333
+ if raw_config["exclude"]
334
+ result["source"]["exclude"] = raw_config["exclude"]
335
+ end
336
+
337
+ result
338
+ end
339
+
340
+ def merge_with_defaults(user_config)
341
+ result = deep_dup(DEFAULT_CONFIG)
342
+ deep_merge(result, user_config)
343
+ result
344
+ end
345
+
346
+ def deep_dup(hash)
347
+ hash.each_with_object({}) do |(key, value), result|
348
+ result[key] = value.is_a?(Hash) ? deep_dup(value) : (value.is_a?(Array) ? value.dup : value)
349
+ end
350
+ end
351
+
352
+ def deep_merge(target, source)
353
+ source.each do |key, value|
354
+ if value.is_a?(Hash) && target[key].is_a?(Hash)
355
+ deep_merge(target[key], value)
356
+ elsif !value.nil?
357
+ target[key] = value
358
+ end
359
+ end
360
+ end
361
+
362
+ # Combine auto-excluded patterns with user-configured patterns
363
+ def all_exclude_patterns
364
+ patterns = AUTO_EXCLUDE.dup
365
+ patterns << out_dir.sub(%r{^\./}, "") # Add output directory
366
+ patterns.concat(exclude_patterns)
367
+ patterns.uniq
368
+ end
369
+
370
+ # Convert absolute path to relative path from first src_dir
371
+ def relative_to_src(file_path)
372
+ base_dir = File.expand_path(src_dir)
373
+ full_path = File.expand_path(file_path)
374
+
375
+ if full_path.start_with?(base_dir)
376
+ full_path.sub("#{base_dir}/", "")
48
377
  else
49
- DEFAULT_CONFIG.dup
378
+ file_path
50
379
  end
51
380
  end
381
+
382
+ # Check if path matches a glob/directory pattern
383
+ def matches_pattern?(path, pattern)
384
+ # Direct directory match (e.g., "node_modules" matches "node_modules/foo.rb")
385
+ return true if path.start_with?("#{pattern}/") || path == pattern
386
+
387
+ # Check if any path component matches
388
+ path_parts = path.split("/")
389
+ return true if path_parts.include?(pattern)
390
+
391
+ # Glob pattern match
392
+ File.fnmatch?(pattern, path, File::FNM_PATHNAME | File::FNM_DOTMATCH)
393
+ end
52
394
  end
53
395
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TRuby
4
- VERSION = "0.0.11"
4
+ VERSION = "0.0.34"
5
5
  end
@@ -91,7 +91,9 @@ module TRuby
91
91
  end
92
92
 
93
93
  def handle_changes(modified, added, removed)
94
- changed_files = (modified + added).select { |f| f.end_with?(".trb") || f.end_with?(".rb") }
94
+ changed_files = (modified + added)
95
+ .select { |f| f.end_with?(".trb") || f.end_with?(".rb") }
96
+ .reject { |f| @config.excluded?(f) }
95
97
  return if changed_files.empty? && removed.empty?
96
98
 
97
99
  puts
@@ -231,26 +233,34 @@ module TRuby
231
233
  end
232
234
 
233
235
  def find_trb_files
234
- files = []
235
- @paths.each do |path|
236
- if File.directory?(path)
237
- files.concat(Dir.glob(File.join(path, "**", "*.trb")))
238
- elsif File.file?(path) && path.end_with?(".trb")
239
- files << path
240
- end
241
- end
242
- files.uniq
236
+ find_source_files_by_extension(".trb")
243
237
  end
244
238
 
245
239
  def find_rb_files
240
+ find_source_files_by_extension(".rb")
241
+ end
242
+
243
+ def find_source_files_by_extension(ext)
246
244
  files = []
247
- @paths.each do |path|
248
- if File.directory?(path)
249
- files.concat(Dir.glob(File.join(path, "**", "*.rb")))
250
- elsif File.file?(path) && path.end_with?(".rb")
251
- files << path
245
+
246
+ # If watching specific paths, use those paths
247
+ # Otherwise, use Config's find_source_files which respects include/exclude patterns
248
+ if @paths == [File.expand_path(".")]
249
+ # Default case: use config's src_dir with include/exclude patterns
250
+ files = @config.find_source_files.select { |f| f.end_with?(ext) }
251
+ else
252
+ # Specific paths provided: search in those paths but still apply exclude patterns
253
+ @paths.each do |path|
254
+ if File.directory?(path)
255
+ Dir.glob(File.join(path, "**", "*#{ext}")).each do |file|
256
+ files << file unless @config.excluded?(file)
257
+ end
258
+ elsif File.file?(path) && path.end_with?(ext) && !@config.excluded?(path)
259
+ files << path
260
+ end
252
261
  end
253
262
  end
263
+
254
264
  files.uniq
255
265
  end
256
266
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: t-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.11
4
+ version: 0.0.34
5
5
  platform: ruby
6
6
  authors:
7
7
  - Y. Fred Kim