tapioca 0.6.4 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +8 -2
  3. data/README.md +27 -15
  4. data/Rakefile +10 -14
  5. data/lib/tapioca/cli.rb +65 -80
  6. data/lib/tapioca/{generators/base.rb → commands/command.rb} +16 -9
  7. data/lib/tapioca/{generators → commands}/dsl.rb +59 -45
  8. data/lib/tapioca/{generators → commands}/gem.rb +93 -30
  9. data/lib/tapioca/{generators → commands}/init.rb +9 -13
  10. data/lib/tapioca/{generators → commands}/require.rb +8 -10
  11. data/lib/tapioca/commands/todo.rb +84 -0
  12. data/lib/tapioca/commands.rb +13 -0
  13. data/lib/tapioca/dsl/compiler.rb +185 -0
  14. data/lib/tapioca/{compilers/dsl → dsl/compilers}/aasm.rb +12 -9
  15. data/lib/tapioca/{compilers/dsl → dsl/compilers}/action_controller_helpers.rb +13 -20
  16. data/lib/tapioca/{compilers/dsl → dsl/compilers}/action_mailer.rb +10 -8
  17. data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_job.rb +11 -9
  18. data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_model_attributes.rb +13 -11
  19. data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_model_secure_password.rb +10 -12
  20. data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_record_associations.rb +28 -34
  21. data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_record_columns.rb +18 -16
  22. data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_record_enum.rb +14 -12
  23. data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_record_fixtures.rb +10 -8
  24. data/lib/tapioca/dsl/compilers/active_record_relations.rb +712 -0
  25. data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_record_scope.rb +21 -20
  26. data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_record_typed_store.rb +11 -16
  27. data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_resource.rb +10 -8
  28. data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_storage.rb +11 -11
  29. data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_support_concern.rb +19 -14
  30. data/lib/tapioca/{compilers/dsl → dsl/compilers}/active_support_current_attributes.rb +16 -21
  31. data/lib/tapioca/{compilers/dsl → dsl/compilers}/config.rb +10 -8
  32. data/lib/tapioca/{compilers/dsl → dsl/compilers}/frozen_record.rb +13 -11
  33. data/lib/tapioca/{compilers/dsl → dsl/compilers}/identity_cache.rb +23 -22
  34. data/lib/tapioca/{compilers/dsl → dsl/compilers}/mixed_in_class_attributes.rb +12 -10
  35. data/lib/tapioca/{compilers/dsl → dsl/compilers}/protobuf.rb +10 -8
  36. data/lib/tapioca/{compilers/dsl → dsl/compilers}/rails_generators.rb +12 -13
  37. data/lib/tapioca/{compilers/dsl → dsl/compilers}/sidekiq_worker.rb +14 -13
  38. data/lib/tapioca/{compilers/dsl → dsl/compilers}/smart_properties.rb +11 -9
  39. data/lib/tapioca/{compilers/dsl → dsl/compilers}/state_machines.rb +12 -10
  40. data/lib/tapioca/{compilers/dsl → dsl/compilers}/url_helpers.rb +16 -14
  41. data/lib/tapioca/dsl/compilers.rb +31 -0
  42. data/lib/tapioca/{compilers/dsl → dsl}/extensions/frozen_record.rb +2 -2
  43. data/lib/tapioca/dsl/helpers/active_record_column_type_helper.rb +114 -0
  44. data/lib/tapioca/dsl/helpers/active_record_constants_helper.rb +29 -0
  45. data/lib/tapioca/{compilers/dsl → dsl/helpers}/param_helper.rb +2 -2
  46. data/lib/tapioca/{compilers/dsl_compiler.rb → dsl/pipeline.rb} +41 -33
  47. data/lib/tapioca/gem/events.rb +120 -0
  48. data/lib/tapioca/gem/listeners/base.rb +48 -0
  49. data/lib/tapioca/gem/listeners/dynamic_mixins.rb +32 -0
  50. data/lib/tapioca/gem/listeners/methods.rb +183 -0
  51. data/lib/tapioca/gem/listeners/mixins.rb +101 -0
  52. data/lib/tapioca/gem/listeners/remove_empty_payload_scopes.rb +21 -0
  53. data/lib/tapioca/gem/listeners/sorbet_enums.rb +26 -0
  54. data/lib/tapioca/gem/listeners/sorbet_helpers.rb +29 -0
  55. data/lib/tapioca/gem/listeners/sorbet_props.rb +33 -0
  56. data/lib/tapioca/gem/listeners/sorbet_required_ancestors.rb +23 -0
  57. data/lib/tapioca/gem/listeners/sorbet_signatures.rb +79 -0
  58. data/lib/tapioca/gem/listeners/sorbet_type_variables.rb +51 -0
  59. data/lib/tapioca/gem/listeners/subconstants.rb +37 -0
  60. data/lib/tapioca/gem/listeners/yard_doc.rb +96 -0
  61. data/lib/tapioca/gem/listeners.rb +16 -0
  62. data/lib/tapioca/gem/pipeline.rb +365 -0
  63. data/lib/tapioca/helpers/cli_helper.rb +7 -0
  64. data/lib/tapioca/helpers/config_helper.rb +5 -8
  65. data/lib/tapioca/helpers/rbi_helper.rb +17 -0
  66. data/lib/tapioca/helpers/shims_helper.rb +87 -0
  67. data/lib/tapioca/helpers/sorbet_helper.rb +57 -0
  68. data/lib/tapioca/helpers/test/dsl_compiler.rb +118 -0
  69. data/lib/tapioca/helpers/test/isolation.rb +1 -1
  70. data/lib/tapioca/helpers/test/template.rb +13 -2
  71. data/lib/tapioca/internal.rb +17 -10
  72. data/lib/tapioca/rbi_ext/model.rb +2 -48
  73. data/lib/tapioca/rbi_formatter.rb +37 -0
  74. data/lib/tapioca/runtime/dynamic_mixin_compiler.rb +227 -0
  75. data/lib/tapioca/runtime/generic_type_registry.rb +166 -0
  76. data/lib/tapioca/runtime/loader.rb +123 -0
  77. data/lib/tapioca/runtime/reflection.rb +153 -0
  78. data/lib/tapioca/runtime/trackers/autoload.rb +72 -0
  79. data/lib/tapioca/runtime/trackers/constant_definition.rb +44 -0
  80. data/lib/tapioca/runtime/trackers/mixin.rb +80 -0
  81. data/lib/tapioca/runtime/trackers/required_ancestor.rb +50 -0
  82. data/lib/tapioca/{trackers.rb → runtime/trackers.rb} +4 -3
  83. data/lib/tapioca/sorbet_ext/generic_name_patch.rb +33 -15
  84. data/lib/tapioca/sorbet_ext/name_patch.rb +7 -1
  85. data/lib/tapioca/{compilers → static}/requires_compiler.rb +2 -2
  86. data/lib/tapioca/static/symbol_loader.rb +83 -0
  87. data/lib/tapioca/static/symbol_table_parser.rb +63 -0
  88. data/lib/tapioca/version.rb +1 -1
  89. data/lib/tapioca.rb +2 -7
  90. metadata +80 -60
  91. data/lib/tapioca/compilers/dsl/active_record_relations.rb +0 -720
  92. data/lib/tapioca/compilers/dsl/base.rb +0 -195
  93. data/lib/tapioca/compilers/dsl/helper/active_record_constants.rb +0 -27
  94. data/lib/tapioca/compilers/dynamic_mixin_compiler.rb +0 -223
  95. data/lib/tapioca/compilers/sorbet.rb +0 -59
  96. data/lib/tapioca/compilers/symbol_table/symbol_generator.rb +0 -780
  97. data/lib/tapioca/compilers/symbol_table/symbol_loader.rb +0 -90
  98. data/lib/tapioca/compilers/symbol_table_compiler.rb +0 -17
  99. data/lib/tapioca/compilers/todos_compiler.rb +0 -32
  100. data/lib/tapioca/generators/todo.rb +0 -76
  101. data/lib/tapioca/generators.rb +0 -9
  102. data/lib/tapioca/generic_type_registry.rb +0 -164
  103. data/lib/tapioca/helpers/active_record_column_type_helper.rb +0 -108
  104. data/lib/tapioca/loader.rb +0 -119
  105. data/lib/tapioca/reflection.rb +0 -151
  106. data/lib/tapioca/trackers/autoload.rb +0 -70
  107. data/lib/tapioca/trackers/constant_definition.rb +0 -42
  108. data/lib/tapioca/trackers/mixin.rb +0 -78
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6ea7bddec4d5d00918ca3236afee754f7f8dd9481d78bf8e26819c0140b154ff
4
- data.tar.gz: 681d5ed15d27c20833aa4df86dc1a61d721e0d5993a43073873f2406a254d806
3
+ metadata.gz: ef378ec3f3035d85d6aebfa4624896d216bcccd7d9332cbdc9d64be469b79b48
4
+ data.tar.gz: 2f34d64fadd075ed1653ec26d27c73a02bfff949440fc6d1fd8bf80116161b48
5
5
  SHA512:
6
- metadata.gz: a2e885fa0010d90899b1f167e3a68c1d65f7cec21d7386a321a51d753fdf6e4deaf97d5c0866b7969cf90f42a5aa68af858e173237f8fc0a7c31bc08c3931185
7
- data.tar.gz: a48f142ad8402b07c2b4724801b2dee912f1b95975bb9951feb97aef433a46c248e458527827be3a450336f2c62195714a5f5b476ed7704dad4ccefdb93aca98
6
+ metadata.gz: 78b6ce07ee08391457763a8e9069b0ff0efaa1be26cdeec7f334d2b45afa6ec12fd152d24c42d4c2b6834db25af77f74d6401bf577fd749ed446ef122dc01161
7
+ data.tar.gz: 0b1998a9a72153d24747838606ff636cf8718efc67aa98e0c9d3ff01849d677840cd73f0adb8f289cc8c6f7e07b20bd37594bbcd1aea1b91761132fd07a1a9db
data/Gemfile CHANGED
@@ -10,6 +10,7 @@ gem("minitest-reporters")
10
10
  gem("pry-byebug")
11
11
  gem("rubocop-shopify", require: false)
12
12
  gem("rubocop-sorbet", ">= 0.4.1")
13
+ gem("rubocop-rspec", require: false)
13
14
  gem("sorbet")
14
15
 
15
16
  group(:deployment, :development) do
@@ -25,8 +26,12 @@ group(:development, :test) do
25
26
  gem("activerecord-typedstore", require: false)
26
27
  gem("sqlite3")
27
28
  gem("identity_cache", require: false)
28
- gem("cityhash", git: "https://github.com/csfrancis/cityhash.git",
29
- ref: "3cfc7d01f333c01811d5e834f1495eaa29f87c36", require: false)
29
+ gem(
30
+ "cityhash",
31
+ git: "https://github.com/csfrancis/cityhash.git",
32
+ ref: "3cfc7d01f333c01811d5e834f1495eaa29f87c36",
33
+ require: false
34
+ )
30
35
  gem("activeresource", require: false)
31
36
  gem("google-protobuf", require: false)
32
37
  gem("shopify-money", require: false)
@@ -36,6 +41,7 @@ group(:development, :test) do
36
41
  gem("aasm", require: false)
37
42
  gem("bcrypt", require: false)
38
43
  gem("xpath", require: false)
44
+ gem("rubocop-lsp", require: false)
39
45
 
40
46
  # net-smtp was removed from default gems in Ruby 3.1, but is used by the `mail` gem.
41
47
  # So we need to add it as a dependency until `mail` is fixed:
data/README.md CHANGED
@@ -123,6 +123,12 @@ Options:
123
123
  # Default: true
124
124
  -w, [--workers=N] # EXPERIMENTAL: Number of parallel workers to use when generating RBIs
125
125
  # Default: 1
126
+ [--auto-strictness], [--no-auto-strictness] # Autocorrect strictness in gem RBIs in case of conflict with the DSL RBIs
127
+ # Default: true
128
+ --dsl-dir, [--dsl-dir=directory] # The DSL directory used to correct gems strictnesses
129
+ # Default: sorbet/rbi/dsl
130
+ [--rbi-max-line-length=N] # Set the max line length of generated RBIs. Signatures longer than the max line length will be wrapped
131
+ # Default: 120
126
132
  -c, [--config=<config file path>] # Path to the Tapioca configuration file
127
133
  # Default: sorbet/tapioca/config.yml
128
134
  -V, [--verbose], [--no-verbose] # Verbose output for debugging purposes
@@ -159,7 +165,7 @@ generate the list of unresolved constants
159
165
 
160
166
  Command: `tapioca dsl [constant...]`
161
167
 
162
- This will generate DSL RBIs for specified constants (or for all handled constants, if a constant name is not supplied). You can read about DSL RBI generators supplied by `tapioca` in [the manual](manual/generators.md).
168
+ This will generate DSL RBIs for specified constants (or for all handled constants, if a constant name is not supplied). You can read about DSL RBI compilers supplied by `tapioca` in [the manual](manual/compilers.md).
163
169
 
164
170
  <!-- START_HELP_COMMAND_DSL -->
165
171
  ```shell
@@ -167,19 +173,21 @@ Usage:
167
173
  tapioca dsl [constant...]
168
174
 
169
175
  Options:
170
- --out, -o, [--outdir=directory] # The output directory for generated DSL RBI files
171
- # Default: sorbet/rbi/dsl
172
- [--file-header], [--no-file-header] # Add a "This file is generated" header on top of each generated RBI file
173
- # Default: true
174
- [--only=generator [generator ...]] # Only run supplied DSL generator(s)
175
- [--exclude=generator [generator ...]] # Exclude supplied DSL generator(s)
176
- [--verify], [--no-verify] # Verifies RBIs are up-to-date
177
- -q, [--quiet], [--no-quiet] # Supresses file creation output
178
- -w, [--workers=N] # EXPERIMENTAL: Number of parallel workers to use when generating RBIs
179
- # Default: 1
180
- -c, [--config=<config file path>] # Path to the Tapioca configuration file
181
- # Default: sorbet/tapioca/config.yml
182
- -V, [--verbose], [--no-verbose] # Verbose output for debugging purposes
176
+ --out, -o, [--outdir=directory] # The output directory for generated DSL RBI files
177
+ # Default: sorbet/rbi/dsl
178
+ [--file-header], [--no-file-header] # Add a "This file is generated" header on top of each generated RBI file
179
+ # Default: true
180
+ [--only=compiler [compiler ...]] # Only run supplied DSL compiler(s)
181
+ [--exclude=compiler [compiler ...]] # Exclude supplied DSL compiler(s)
182
+ [--verify], [--no-verify] # Verifies RBIs are up-to-date
183
+ -q, [--quiet], [--no-quiet] # Supresses file creation output
184
+ -w, [--workers=N] # EXPERIMENTAL: Number of parallel workers to use when generating RBIs
185
+ # Default: 1
186
+ [--rbi-max-line-length=N] # Set the max line length of generated RBIs. Signatures longer than the max line length will be wrapped
187
+ # Default: 120
188
+ -c, [--config=<config file path>] # Path to the Tapioca configuration file
189
+ # Default: sorbet/tapioca/config.yml
190
+ -V, [--verbose], [--no-verbose] # Verbose output for debugging purposes
183
191
 
184
192
  generate RBIs for dynamic methods
185
193
  ```
@@ -228,6 +236,7 @@ dsl:
228
236
  verify: false
229
237
  quiet: false
230
238
  workers: 1
239
+ rbi_max_line_length: 120
231
240
  gem:
232
241
  outdir: sorbet/rbi/gems
233
242
  file_header: true
@@ -241,7 +250,10 @@ gem:
241
250
  doc: false
242
251
  exported_gem_rbis: true
243
252
  workers: 1
244
- clean_shims:
253
+ auto_strictness: true
254
+ dsl_dir: sorbet/rbi/dsl
255
+ rbi_max_line_length: 120
256
+ check_shims:
245
257
  gem_rbi_dir: sorbet/rbi/gems
246
258
  dsl_rbi_dir: sorbet/rbi/dsl
247
259
  shim_rbi_dir: sorbet/rbi/shims
data/Rakefile CHANGED
@@ -1,22 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "bundler/gem_tasks"
4
- require "rake/testtask"
5
4
  Dir["tasks/**/*.rake"].each { |t| load t }
6
5
 
7
- Rake.application.options.trace = false
6
+ require "rubocop/rake_task"
7
+ RuboCop::RakeTask.new
8
8
 
9
- Rake::TestTask.new do |t|
10
- t.libs << "lib"
11
- t.libs << "spec"
12
- t.warning = false
13
- t.test_files = FileList["spec/**/*_spec.rb"]
9
+ desc "Run tests"
10
+ task :test do
11
+ require "shellwords"
12
+ test = Array(ENV.fetch("TEST", []))
13
+ test_opts = Shellwords.split(ENV.fetch("TESTOPTS", ""))
14
+ success = system("bin/test", *test, *test_opts)
15
+ success || exit(false)
14
16
  end
15
17
 
16
- task(:spec) do
17
- Rake::Task[:test].execute
18
- rescue RuntimeError
19
- exit(1)
20
- end
21
-
22
- task(default: :spec)
18
+ task(default: :test)
data/lib/tapioca/cli.rb CHANGED
@@ -5,6 +5,7 @@ module Tapioca
5
5
  class Cli < Thor
6
6
  include CliHelper
7
7
  include ConfigHelper
8
+ include ShimsHelper
8
9
 
9
10
  FILE_HEADER_OPTION_DESC = "Add a \"This file is generated\" header on top of each generated RBI file"
10
11
 
@@ -22,25 +23,23 @@ module Tapioca
22
23
 
23
24
  desc "init", "initializes folder structure"
24
25
  def init
25
- generator = Generators::Init.new(
26
+ command = Commands::Init.new(
26
27
  sorbet_config: SORBET_CONFIG_FILE,
27
28
  tapioca_config: TAPIOCA_CONFIG_FILE,
28
- default_postrequire: DEFAULT_POSTREQUIRE_FILE,
29
- default_command: DEFAULT_COMMAND
29
+ default_postrequire: DEFAULT_POSTREQUIRE_FILE
30
30
  )
31
- generator.generate
31
+ command.execute
32
32
  end
33
33
 
34
34
  desc "require", "generate the list of files to be required by tapioca"
35
35
  option :postrequire, type: :string, default: DEFAULT_POSTREQUIRE_FILE
36
36
  def require
37
- generator = Generators::Require.new(
37
+ command = Commands::Require.new(
38
38
  requires_path: options[:postrequire],
39
- sorbet_config_path: SORBET_CONFIG_FILE,
40
- default_command: DEFAULT_COMMAND
39
+ sorbet_config_path: SORBET_CONFIG_FILE
41
40
  )
42
41
  Tapioca.silence_warnings do
43
- generator.generate
42
+ command.execute
44
43
  end
45
44
  end
46
45
 
@@ -54,13 +53,12 @@ module Tapioca
54
53
  desc: FILE_HEADER_OPTION_DESC,
55
54
  default: true
56
55
  def todo
57
- generator = Generators::Todo.new(
56
+ command = Commands::Todo.new(
58
57
  todo_file: options[:todo_file],
59
- file_header: options[:file_header],
60
- default_command: DEFAULT_COMMAND
58
+ file_header: options[:file_header]
61
59
  )
62
60
  Tapioca.silence_warnings do
63
- generator.generate
61
+ command.execute
64
62
  end
65
63
  end
66
64
 
@@ -76,13 +74,13 @@ module Tapioca
76
74
  default: true
77
75
  option :only,
78
76
  type: :array,
79
- banner: "generator [generator ...]",
80
- desc: "Only run supplied DSL generator(s)",
77
+ banner: "compiler [compiler ...]",
78
+ desc: "Only run supplied DSL compiler(s)",
81
79
  default: []
82
80
  option :exclude,
83
81
  type: :array,
84
- banner: "generator [generator ...]",
85
- desc: "Exclude supplied DSL generator(s)",
82
+ banner: "compiler [compiler ...]",
83
+ desc: "Exclude supplied DSL compiler(s)",
86
84
  default: []
87
85
  option :verify,
88
86
  type: :boolean,
@@ -98,20 +96,24 @@ module Tapioca
98
96
  type: :numeric,
99
97
  desc: "EXPERIMENTAL: Number of parallel workers to use when generating RBIs",
100
98
  default: 1
99
+ option :rbi_max_line_length,
100
+ type: :numeric,
101
+ desc: "Set the max line length of generated RBIs. Signatures longer than the max line length will be wrapped",
102
+ default: 120
101
103
  def dsl(*constants)
102
- generator = Generators::Dsl.new(
104
+ command = Commands::Dsl.new(
103
105
  requested_constants: constants,
104
106
  outpath: Pathname.new(options[:outdir]),
105
107
  only: options[:only],
106
108
  exclude: options[:exclude],
107
109
  file_header: options[:file_header],
108
- compiler_path: Tapioca::Compilers::Dsl::DSL_COMPILERS_DIR,
110
+ compiler_path: Tapioca::Dsl::Compilers::DIRECTORY,
109
111
  tapioca_path: TAPIOCA_DIR,
110
- default_command: DEFAULT_COMMAND,
111
112
  should_verify: options[:verify],
112
113
  quiet: options[:quiet],
113
114
  verbose: options[:verbose],
114
- number_of_workers: options[:workers]
115
+ number_of_workers: options[:workers],
116
+ rbi_formatter: rbi_formatter(options)
115
117
  )
116
118
 
117
119
  if options[:workers] != 1
@@ -122,7 +124,7 @@ module Tapioca
122
124
  end
123
125
 
124
126
  Tapioca.silence_warnings do
125
- generator.generate
127
+ command.execute
126
128
  end
127
129
  end
128
130
 
@@ -179,23 +181,38 @@ module Tapioca
179
181
  type: :numeric,
180
182
  desc: "EXPERIMENTAL: Number of parallel workers to use when generating RBIs",
181
183
  default: 1
184
+ option :auto_strictness,
185
+ type: :boolean,
186
+ desc: "Autocorrect strictness in gem RBIs in case of conflict with the DSL RBIs",
187
+ default: true
188
+ option :dsl_dir,
189
+ aliases: ["--dsl-dir"],
190
+ banner: "directory",
191
+ desc: "The DSL directory used to correct gems strictnesses",
192
+ default: DEFAULT_DSL_DIR
193
+ option :rbi_max_line_length,
194
+ type: :numeric,
195
+ desc: "Set the max line length of generated RBIs. Signatures longer than the max line length will be wrapped",
196
+ default: 120
182
197
  def gem(*gems)
183
198
  Tapioca.silence_warnings do
184
199
  all = options[:all]
185
200
  verify = options[:verify]
186
201
 
187
- generator = Generators::Gem.new(
202
+ command = Commands::Gem.new(
188
203
  gem_names: all ? [] : gems,
189
204
  exclude: options[:exclude],
190
205
  prerequire: options[:prerequire],
191
206
  postrequire: options[:postrequire],
192
207
  typed_overrides: options[:typed_overrides],
193
- default_command: DEFAULT_COMMAND,
194
208
  outpath: Pathname.new(options[:outdir]),
195
209
  file_header: options[:file_header],
196
210
  doc: options[:doc],
197
211
  include_exported_rbis: options[:exported_gem_rbis],
198
- number_of_workers: options[:workers]
212
+ number_of_workers: options[:workers],
213
+ auto_strictness: options[:auto_strictness],
214
+ dsl_dir: options[:dsl_dir],
215
+ rbi_formatter: rbi_formatter(options)
199
216
  )
200
217
 
201
218
  raise MalformattedArgumentError, "Options '--all' and '--verify' are mutually exclusive" if all && verify
@@ -213,80 +230,48 @@ module Tapioca
213
230
  end
214
231
 
215
232
  if gems.empty? && !all
216
- generator.sync(should_verify: verify)
233
+ command.sync(should_verify: verify)
217
234
  else
218
- generator.generate
235
+ command.execute
219
236
  end
220
237
  end
221
238
  end
239
+ map "gems" => :gem
222
240
 
223
- desc "clean-shims", "clean duplicated definitions in shim RBIs"
241
+ desc "check-shims", "check duplicated definitions in shim RBIs"
224
242
  option :gem_rbi_dir, type: :string, desc: "Path to gem RBIs", default: DEFAULT_GEM_DIR
225
243
  option :dsl_rbi_dir, type: :string, desc: "Path to DSL RBIs", default: DEFAULT_DSL_DIR
226
244
  option :shim_rbi_dir, type: :string, desc: "Path to shim RBIs", default: DEFAULT_SHIM_DIR
227
- def clean_shims(*files_to_clean)
245
+ def check_shims
228
246
  index = RBI::Index.new
229
247
 
230
- # Index gem RBIs
231
- gem_rbi_dir = options[:gem_rbi_dir]
232
- say("Loading gem RBIs from #{gem_rbi_dir}... ")
233
- gem_rbis_files = Dir.glob("#{gem_rbi_dir}/**/*.rbi").sort
234
- gem_rbis_trees = RBI::Parser.parse_files(gem_rbis_files)
235
- index.visit_all(gem_rbis_trees)
236
- say(" Done", :green)
237
-
238
- # Index dsl RBIs
239
- dsl_rbi_dir = options[:dsl_rbi_dir]
240
- say("Loading dsl RBIs from #{dsl_rbi_dir}... ")
241
- dsl_rbis_files = Dir.glob("#{dsl_rbi_dir}/**/*.rbi").sort
242
- dsl_rbis_trees = RBI::Parser.parse_files(dsl_rbis_files)
243
- index.visit_all(dsl_rbis_trees)
244
- say(" Done", :green)
245
-
246
- # Clean shim RBIs
247
- if files_to_clean.empty?
248
- shim_rbi_dir = options[:shim_rbi_dir]
249
- print("Cleaning shim RBIs from #{shim_rbi_dir}...")
250
- files_to_clean = Dir.glob("#{shim_rbi_dir}/*.rbi")
251
- else
252
- print("Cleaning shim RBIs...")
248
+ shim_rbi_dir = options[:shim_rbi_dir]
249
+ if !Dir.exist?(shim_rbi_dir) || Dir.empty?(shim_rbi_dir)
250
+ say("No shim RBIs to check", :green)
251
+ exit(0)
253
252
  end
254
253
 
255
- done_something = T.let(false, T::Boolean)
256
- files_to_clean.sort.each do |path|
257
- original = RBI::Parser.parse_file(path)
258
- cleaned, operations = RBI::Rewriters::RemoveKnownDefinitions.remove(original, index)
254
+ index_rbis(index, "shim", shim_rbi_dir)
255
+ index_rbis(index, "gem", options[:gem_rbi_dir])
256
+ index_rbis(index, "dsl", options[:dsl_rbi_dir])
259
257
 
260
- next if operations.empty?
261
- done_something = true
262
-
263
- operations.each do |operation|
264
- print("\n #{operation}")
265
- end
266
-
267
- if cleaned.empty?
268
- print("\n Deleted empty file #{path}")
269
- FileUtils.rm(path)
270
- else
271
- File.write(path, cleaned.string)
258
+ duplicates = duplicated_nodes_from_index(index, shim_rbi_dir)
259
+ unless duplicates.empty?
260
+ duplicates.each do |key, nodes|
261
+ say_error("\nDuplicated RBI for #{key}:", :red)
262
+ nodes.each do |node|
263
+ say_error(" * #{node.loc}", :red)
264
+ end
272
265
  end
266
+ say_error("\nPlease remove the duplicated definitions from the #{shim_rbi_dir} directory.", :red)
267
+ exit(1)
273
268
  end
274
269
 
275
- if done_something
276
- say("\nDone", :green)
277
- else
278
- say(" Done ", :green)
279
- say("(nothing to do)", :yellow)
280
- end
281
- rescue Errno::ENOENT => e
282
- say_error("\nCan't read RBI: #{e}")
283
- exit(1)
284
- rescue RBI::ParseError => e
285
- say_error("\nCan't parse RBI: #{e} (#{e.location})")
286
- exit(1)
270
+ say("\nNo duplicates found in shim RBIs", :green)
271
+ exit(0)
287
272
  end
288
273
 
289
- map T.unsafe(["--version", "-v"] => :__print_version)
274
+ map ["--version", "-v"] => :__print_version
290
275
 
291
276
  desc "--version, -v", "show version"
292
277
  def __print_version
@@ -2,8 +2,8 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Tapioca
5
- module Generators
6
- class Base
5
+ module Commands
6
+ class Command
7
7
  extend T::Sig
8
8
  extend T::Helpers
9
9
 
@@ -16,17 +16,24 @@ module Tapioca
16
16
 
17
17
  abstract!
18
18
 
19
- sig { params(default_command: String, file_writer: Thor::Actions).void }
20
- def initialize(default_command:, file_writer: FileWriter.new)
21
- @file_writer = file_writer
22
- @default_command = default_command
19
+ sig { void }
20
+ def initialize
21
+ @file_writer = T.let(FileWriter.new, Thor::Actions)
23
22
  end
24
23
 
25
24
  sig { abstract.void }
26
- def generate; end
25
+ def execute; end
27
26
 
28
27
  private
29
28
 
29
+ sig { params(command: Symbol, args: String).returns(String) }
30
+ def default_command(command, *args)
31
+ [Tapioca::BINARY_FILE, command.to_s, *args].join(" ")
32
+ end
33
+
34
+ sig { returns(Thor::Actions) }
35
+ attr_reader :file_writer
36
+
30
37
  sig do
31
38
  params(
32
39
  path: T.any(String, Pathname),
@@ -37,7 +44,7 @@ module Tapioca
37
44
  ).void
38
45
  end
39
46
  def create_file(path, content, force: true, skip: false, verbose: true)
40
- @file_writer.create_file(path, force: force, skip: skip, verbose: verbose) { content }
47
+ file_writer.create_file(path, force: force, skip: skip, verbose: verbose) { content }
41
48
  end
42
49
 
43
50
  sig do
@@ -47,7 +54,7 @@ module Tapioca
47
54
  ).void
48
55
  end
49
56
  def remove_file(path, verbose: true)
50
- @file_writer.remove_file(path, verbose: verbose)
57
+ file_writer.remove_file(path, verbose: verbose)
51
58
  end
52
59
  end
53
60
  end