tapioca 0.11.8 → 0.11.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +116 -49
  3. data/lib/tapioca/cli.rb +76 -67
  4. data/lib/tapioca/commands/{dsl.rb → abstract_dsl.rb} +32 -78
  5. data/lib/tapioca/commands/{gem.rb → abstract_gem.rb} +26 -93
  6. data/lib/tapioca/commands/annotations.rb +9 -7
  7. data/lib/tapioca/commands/check_shims.rb +2 -0
  8. data/lib/tapioca/commands/command.rb +9 -2
  9. data/lib/tapioca/commands/configure.rb +2 -2
  10. data/lib/tapioca/commands/dsl_compiler_list.rb +31 -0
  11. data/lib/tapioca/commands/dsl_generate.rb +40 -0
  12. data/lib/tapioca/commands/dsl_verify.rb +25 -0
  13. data/lib/tapioca/commands/gem_generate.rb +51 -0
  14. data/lib/tapioca/commands/gem_sync.rb +37 -0
  15. data/lib/tapioca/commands/gem_verify.rb +36 -0
  16. data/lib/tapioca/commands/require.rb +2 -0
  17. data/lib/tapioca/commands/todo.rb +21 -2
  18. data/lib/tapioca/commands.rb +8 -2
  19. data/lib/tapioca/dsl/compiler.rb +8 -4
  20. data/lib/tapioca/dsl/compilers/action_controller_helpers.rb +3 -1
  21. data/lib/tapioca/dsl/compilers/active_model_validations_confirmation.rb +94 -0
  22. data/lib/tapioca/dsl/compilers/active_record_columns.rb +19 -9
  23. data/lib/tapioca/dsl/compilers/active_record_typed_store.rb +3 -2
  24. data/lib/tapioca/dsl/compilers/active_support_concern.rb +1 -1
  25. data/lib/tapioca/dsl/compilers/graphql_input_object.rb +1 -1
  26. data/lib/tapioca/dsl/compilers/graphql_mutation.rb +9 -2
  27. data/lib/tapioca/dsl/compilers/json_api_client_resource.rb +208 -0
  28. data/lib/tapioca/dsl/helpers/active_record_column_type_helper.rb +20 -4
  29. data/lib/tapioca/dsl/helpers/graphql_type_helper.rb +20 -3
  30. data/lib/tapioca/dsl/pipeline.rb +6 -4
  31. data/lib/tapioca/gem/pipeline.rb +103 -36
  32. data/lib/tapioca/gemfile.rb +13 -7
  33. data/lib/tapioca/helpers/git_attributes.rb +34 -0
  34. data/lib/tapioca/helpers/test/template.rb +4 -4
  35. data/lib/tapioca/internal.rb +1 -0
  36. data/lib/tapioca/loaders/dsl.rb +11 -1
  37. data/lib/tapioca/sorbet_ext/generic_name_patch.rb +0 -27
  38. data/lib/tapioca/static/symbol_loader.rb +9 -8
  39. data/lib/tapioca/version.rb +1 -1
  40. metadata +19 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2e1d35be8426874dde08ba495772d5076d85167f24fa5cfa16b59f424ca3c820
4
- data.tar.gz: ce7b53d0399658d9ecfdcda6e42f030b2316bfcd75c3c02ee018dbab966bce30
3
+ metadata.gz: d9a73b205d42dc103e1e4816c7915a3b4764cdeb6894f384a66e500e95bfbc5a
4
+ data.tar.gz: ff14910658ef17ebe542f8adb67c70e24ed755b41f31860071425d95917c9172
5
5
  SHA512:
6
- metadata.gz: 6dd882c66362cc1666f9e89a9634c38b3131fba7a10b0c5fabe19f5675e98adf308132b07c09b3f62d3035f4fc7ab05f36693de13cb74701324aee3933c43234
7
- data.tar.gz: 74f78ab7a8d5f284b4a1efbcb7eaf098d609294b3c201e227890d3f1276a5c689ee528b5a610a8a4039eaf549c1e0655c71da04631d62b174a16baf23e312bf4
6
+ metadata.gz: 34217744dc8a5ae07940fbd4c6a6c6f1a513d6d6169d9fb9ff1785c9bced7b57022cc4573857f70cbbe24b744915e019ad57bdffe349c981a4bc2e675ab23bc6
7
+ data.tar.gz: 141e26b30087b8573d13b739e52ad5dd9b4934d14dcb1870135e4b91efcc1e3205410e6b625b295be879d6c230a44d95b0a495a8a0bffa7b208d2d6c4efd1df1
data/README.md CHANGED
@@ -47,9 +47,8 @@ Tapioca makes it easy to work with [Sorbet](https://sorbet.org) in your codebase
47
47
  * [Generating RBI files for Rails and other DSLs](#generating-rbi-files-for-rails-and-other-dsls)
48
48
  * [Keeping RBI files for DSLs up-to-date](#keeping-rbi-files-for-dsls-up-to-date)
49
49
  * [Writing custom DSL compilers](#writing-custom-dsl-compilers)
50
+ * [Writing custom DSL extensions](#writing-custom-dsl-extensions)
50
51
  * [RBI files for missing constants and methods](#rbi-files-for-missing-constants-and-methods)
51
- * [Generating the RBI file for missing constants](#generating-the-rbi-file-for-missing-constants)
52
- * [Manually writing RBI definitions (shims)](#manually-writing-rbi-definitions-shims)
53
52
  * [Configuration](#configuration)
54
53
  * [Contributing](#contributing)
55
54
  * [License](#license)
@@ -60,7 +59,7 @@ Tapioca makes it easy to work with [Sorbet](https://sorbet.org) in your codebase
60
59
  Add this line to your application's `Gemfile`:
61
60
 
62
61
  ```rb
63
- group :development do
62
+ group :development, :test do
64
63
  gem 'tapioca', require: false
65
64
  end
66
65
  ```
@@ -72,16 +71,16 @@ Run `bundle install` and make sure Tapioca is properly installed:
72
71
  $ tapioca help
73
72
 
74
73
  Commands:
75
- tapioca --version, -v # show version
74
+ tapioca --version, -v # Show version
76
75
  tapioca annotations # Pull gem RBI annotations from remote sources
77
- tapioca check-shims # check duplicated definitions in shim RBIs
78
- tapioca configure # initialize folder structure and type checking configuration
79
- tapioca dsl [constant...] # generate RBIs for dynamic methods
80
- tapioca gem [gem...] # generate RBIs from gems
76
+ tapioca check-shims # Check duplicated definitions in shim RBIs
77
+ tapioca configure # Initialize folder structure and type checking configuration
78
+ tapioca dsl [constant...] # Generate RBIs for dynamic methods
79
+ tapioca gem [gem...] # Generate RBIs from gems
81
80
  tapioca help [COMMAND] # Describe available commands or one specific command
82
- tapioca init # get project ready for type checking
83
- tapioca require # generate the list of files to be required by tapioca
84
- tapioca todo # generate the list of unresolved constants
81
+ tapioca init # Get project ready for type checking
82
+ tapioca require # Generate the list of files to be required by tapioca
83
+ tapioca todo # Generate the list of unresolved constants
85
84
 
86
85
  Options:
87
86
  -c, [--config=<config file path>] # Path to the Tapioca configuration file
@@ -121,7 +120,7 @@ Options:
121
120
  # Default: sorbet/tapioca/config.yml
122
121
  -V, [--verbose], [--no-verbose] # Verbose output for debugging purposes
123
122
 
124
- get project ready for type checking
123
+ Get project ready for type checking
125
124
  ```
126
125
  <!-- END_HELP_COMMAND_INIT -->
127
126
 
@@ -172,6 +171,7 @@ Options:
172
171
  --post, -a, [--postrequire=file] # A file to be required after Bundler.require is called
173
172
  # Default: sorbet/tapioca/require.rb
174
173
  -x, [--exclude=gem [gem ...]] # Exclude the given gem(s) from RBI generation
174
+ [--include-dependencies], [--no-include-dependencies] # Generate RBI files for dependencies of the given gem(s)
175
175
  --typed, -t, [--typed-overrides=gem:level [gem:level ...]] # Override for typed sigils for generated gem RBIs
176
176
  # Default: {"activesupport"=>"false"}
177
177
  [--verify], [--no-verify] # Verify RBIs are up-to-date
@@ -196,11 +196,11 @@ Options:
196
196
  # Default: sorbet/tapioca/config.yml
197
197
  -V, [--verbose], [--no-verbose] # Verbose output for debugging purposes
198
198
 
199
- generate RBIs from gems
199
+ Generate RBIs from gems
200
200
  ```
201
201
  <!-- END_HELP_COMMAND_GEM -->
202
202
 
203
- By default, running `tapioca gem` will only generate the RBI files for gems that have been added to or removed from the project's `Gemfile` this means that Tapioca will not regenerate the RBI files for untouched gems. However, when changing Tapioca configuration or bumping its version, it may be useful to force the regeneration of the RBI files previously generated. This can be done with the `--all` option:
203
+ By default, running `tapioca gem` will only generate the RBI files for gems that have been added to or removed from the project's `Gemfile` this means that Tapioca will not regenerate the RBI files for untouched gems. If you want to force the regeneration you can supply gem names to the `tapioca gem` command. When supplying gem names if you want to generate RBI files for their dependencies as well, you can use the `--include-dependencies` option. When changing Tapioca configuration or bumping its version, it may be useful to force the regeneration of all the RBI files previously generated. This can be done with the `--all` option:
204
204
 
205
205
  ```shell
206
206
  bin/tapioca gems --all
@@ -483,7 +483,7 @@ Options:
483
483
  # Default: sorbet/tapioca/config.yml
484
484
  -V, [--verbose], [--no-verbose] # Verbose output for debugging purposes
485
485
 
486
- generate RBIs for dynamic methods
486
+ Generate RBIs for dynamic methods
487
487
  ```
488
488
  <!-- END_HELP_COMMAND_DSL -->
489
489
 
@@ -667,57 +667,121 @@ No errors! Great job.
667
667
 
668
668
  For more concrete and advanced examples, take a look at [Tapioca's default DSL compilers](https://github.com/Shopify/tapioca/tree/main/lib/tapioca/dsl/compilers).
669
669
 
670
- ### RBI files for missing constants and methods
670
+ #### Writing custom DSL extensions
671
671
 
672
- Even after generating the RBIs, it is possible that some constants or methods are still undefined for Sorbet.
672
+ When writing custom DSL compilers, it is sometimes necessary to rely on an extension, i.e. a bit of code that is being loaded before the application in order to override some behavior. This is typically useful when a DSL's implementation does not store enough information for the compiler to properly define signatures.
673
673
 
674
- This might be for multiple reasons, with the most frequents ones being:
674
+ Let's reuse the previous `Encryptable` module as an example, but this time let's imagine that the implementation of `attr_encrypted` does not store attribute names:
675
675
 
676
- * The constant or method comes from a part of the gem that Tapioca cannot load (optional dependency, wrong architecture, etc.)
677
- * The constant or method comes from a DSL or meta-programming that Tapioca doesn't support yet
678
- * The constant or method only exists when a specific code path is executed
679
676
 
680
- The best way to deal with such occurrences is to manually create RBI files (shims) for them so you can also add types but depending on the amount of meta-programming used in your project this can mean an overwhelming amount of manual work.
677
+ ```rb
678
+ module Encryptable
679
+ def self.included(base)
680
+ base.extend(ClassMethods)
681
+ end
681
682
 
682
- #### Generating the RBI file for missing constants
683
+ module ClassMethods
684
+ def attr_encrypted(attr_name)
685
+ attr_accessor(attr_name)
683
686
 
684
- To get you started quickly, Tapioca can create a RBI file containing a stub of all the missing constants so you can typecheck your project without missing constants and shim them later as you need them.
687
+ encrypted_attr_name = :"#{attr_name}_encrypted"
685
688
 
686
- To generate the RBI file for the missing constants used in your application run the following command:
689
+ define_method(encrypted_attr_name) do
690
+ value = send(attr_name)
691
+ encrypt(value)
692
+ end
687
693
 
688
- ```shell
689
- $ bin/tapioca todo
694
+ define_method("#{encrypted_attr_name}=") do |value|
695
+ send("#{attr_name}=", decrypt(value))
696
+ end
697
+ end
698
+ end
690
699
 
691
- Compiling sorbet/rbi/todo.rbi, this may take a few seconds... Done
692
- All unresolved constants have been written to sorbet/rbi/todo.rbi.
693
- Please review changes and commit them.
700
+ private
701
+
702
+ def encrypt(value)
703
+ value.unpack("H*").first
704
+ end
705
+
706
+ def decrypt(value)
707
+ [value].pack("H*")
708
+ end
709
+ end
694
710
  ```
695
711
 
696
- This will generate the file `sorbet/rbi/todo.rbi` defining all unresolved constants as empty modules. Since the constants are "missing", Tapioca does not know if they should be marked as modules or classes and will use modules as a safer default. This file should be reviewed, corrected, if necessary, and then committed in your repository.
712
+ Without the `attribute_names` array, the compiler has no way of knowing which methods were defined by the `attr_encrypted` DSL. This can be solved by defining an extension that will override the behavior of `attr_encrypted`:
697
713
 
698
- <!-- START_HELP_COMMAND_TODO -->
699
- ```shell
700
- $ tapioca help todo
714
+ ```rb
715
+ require "encryptable"
701
716
 
702
- Usage:
703
- tapioca todo
717
+ module Tapioca
718
+ module Extensions
719
+ module Encryptable
720
+ attr_reader :__tapioca_encrypted_attributes
704
721
 
705
- Options:
706
- [--todo-file=TODO_FILE] # Path to the generated todo RBI file
707
- # Default: sorbet/rbi/todo.rbi
708
- [--file-header], [--no-file-header] # Add a "This file is generated" header on top of each generated RBI file
709
- # Default: true
710
- -c, [--config=<config file path>] # Path to the Tapioca configuration file
711
- # Default: sorbet/tapioca/config.yml
712
- -V, [--verbose], [--no-verbose] # Verbose output for debugging purposes
722
+ def attr_encrypted(attr_name)
723
+ @__tapioca_encrypted_attributes ||= []
724
+ @__tapioca_encrypted_attributes << attr_name.to_s
713
725
 
714
- generate the list of unresolved constants
726
+ super
727
+ end
728
+
729
+ ::Encryptable::ClassMethods.prepend(self)
730
+ end
731
+ end
732
+ end
715
733
  ```
716
- <!-- END_HELP_COMMAND_TODO -->
717
734
 
718
- #### Manually writing RBI definitions (shims)
735
+ The compiler can now use the `__tapioca_encrypted_attributes` array managed by the extension:
719
736
 
720
- A _shim_ is a hand-crafted RBI file that tells Sorbet about constants, ancestors, methods, etc. that it can't understand statically and aren't already generated by Tapioca.
737
+ ```rb
738
+ module Tapioca
739
+ module Compilers
740
+ class Encryptable < Tapioca::Dsl::Compiler
741
+ extend T::Sig
742
+
743
+ ConstantType = type_member {{ fixed: T.class_of(Encryptable) }}
744
+
745
+ sig { override.returns(T::Enumerable[Module]) }
746
+ def self.gather_constants
747
+ # Collect all the classes that include Encryptable
748
+ all_classes.select { |c| c < ::Encryptable }
749
+ end
750
+
751
+ sig { override.void }
752
+ def decorate
753
+ # Create a RBI definition for each class that includes Encryptable
754
+ root.create_path(constant) do |klass|
755
+ # For each encrypted attribute we find in the class
756
+ constant.__tapioca_encrypted_attributes.each do |attr_name|
757
+ # Create the RBI definitions for all the missing methods
758
+ klass.create_method(attr_name, return_type: "String")
759
+ klass.create_method("#{attr_name}=", parameters: [ create_param("value", type: "String") ], return_type: "void")
760
+ klass.create_method("#{attr_name}_encrypted", return_type: "String")
761
+ klass.create_method("#{attr_name}_encrypted=", parameters: [ create_param("value", type: "String") ], return_type: "void")
762
+ end
763
+ end
764
+ end
765
+ end
766
+ end
767
+ end
768
+ ```
769
+
770
+ In order for DSL extensions to be discovered by Tapioca, they either needs to be placed inside the `sorbet/tapioca/extensions` directory of your application or be inside a `tapioca/dsl/extensions` folder on the load path.
771
+
772
+ For more concrete and advanced examples, take a look at [Tapioca's default DSL extensions](https://github.com/Shopify/tapioca/tree/main/lib/tapioca/dsl/extensions).
773
+
774
+ ### RBI files for missing constants and methods
775
+
776
+ Even after generating the RBIs, it is possible that some constants or methods are still undefined for Sorbet.
777
+
778
+ This might be for multiple reasons, with the most frequents ones being:
779
+
780
+ * The constant or method comes from a part of the gem that Tapioca cannot load (optional dependency, wrong architecture, etc.)
781
+ * The constant or method comes from a DSL or meta-programming that Tapioca doesn't support yet
782
+ * The constant or method only exists when a specific code path is executed
783
+
784
+ The best way to deal with such occurrences is _shims_. A shim is a hand-crafted RBI file that tells Sorbet about constants, ancestors, methods, etc. that it can't understand statically and aren't already generated by Tapioca.
721
785
 
722
786
  These shims are usually placed in the `sorbet/rbi/shims` directory. From there, conventionally, you should follow the directory structure of the project to the file you'd like to shim. For example, say you had a `person.rb` file found at `app/models/person.rb`. If you were to add a shim for it, you'd want to create your RBI file at `sorbet/rbi/shims/app/models/person.rbi`.
723
787
 
@@ -782,10 +846,12 @@ Options:
782
846
  # Default: sorbet/tapioca/config.yml
783
847
  -V, [--verbose], [--no-verbose] # Verbose output for debugging purposes
784
848
 
785
- check duplicated definitions in shim RBIs
849
+ Check duplicated definitions in shim RBIs
786
850
  ```
787
851
  <!-- END_HELP_COMMAND_CHECK_SHIMS -->
788
852
 
853
+ Depending on the amount of meta-programming used in your project this can mean an overwhelming amount of manual work. In this case, you should consider [writting a custom DSL compiler](#writing-custom-dsl-compilers).
854
+
789
855
  ### Configuration
790
856
 
791
857
  Tapioca supports loading command defaults from a configuration file. The default configuration file location is `sorbet/tapioca/config.yml` but this default can be changed using the `--config` flag and supplying an alternative configuration file path.
@@ -839,6 +905,7 @@ gem:
839
905
  prerequire: ''
840
906
  postrequire: sorbet/tapioca/require.rb
841
907
  exclude: []
908
+ include_dependencies: false
842
909
  typed_overrides:
843
910
  activesupport: 'false'
844
911
  verify: false
data/lib/tapioca/cli.rb CHANGED
@@ -23,7 +23,7 @@ module Tapioca
23
23
  desc: "Verbose output for debugging purposes",
24
24
  default: false
25
25
 
26
- desc "init", "get project ready for type checking"
26
+ desc "init", "Get project ready for type checking"
27
27
  def init
28
28
  # We need to make sure that trackers stay enabled until the `gem` command is invoked
29
29
  Runtime::Trackers.with_trackers_enabled do
@@ -31,12 +31,17 @@ module Tapioca
31
31
  invoke(:annotations)
32
32
  invoke(:gem)
33
33
  end
34
- invoke(:todo)
34
+
35
+ # call the command directly to skip deprecation warning
36
+ Commands::Todo.new(
37
+ todo_file: DEFAULT_TODO_FILE,
38
+ file_header: true,
39
+ ).run
35
40
 
36
41
  print_init_next_steps
37
42
  end
38
43
 
39
- desc "configure", "initialize folder structure and type checking configuration"
44
+ desc "configure", "Initialize folder structure and type checking configuration"
40
45
  option :postrequire, type: :string, default: DEFAULT_POSTREQUIRE_FILE
41
46
  def configure
42
47
  command = Commands::Configure.new(
@@ -44,22 +49,20 @@ module Tapioca
44
49
  tapioca_config: options[:config],
45
50
  default_postrequire: options[:postrequire],
46
51
  )
47
- command.execute
52
+ command.run
48
53
  end
49
54
 
50
- desc "require", "generate the list of files to be required by tapioca"
55
+ desc "require", "Generate the list of files to be required by tapioca"
51
56
  option :postrequire, type: :string, default: DEFAULT_POSTREQUIRE_FILE
52
57
  def require
53
58
  command = Commands::Require.new(
54
59
  requires_path: options[:postrequire],
55
60
  sorbet_config_path: SORBET_CONFIG_FILE,
56
61
  )
57
- Tapioca.silence_warnings do
58
- command.execute
59
- end
62
+ command.run
60
63
  end
61
64
 
62
- desc "todo", "generate the list of unresolved constants"
65
+ desc "todo", "Generate the list of unresolved constants"
63
66
  option :todo_file,
64
67
  type: :string,
65
68
  desc: "Path to the generated todo RBI file",
@@ -73,12 +76,10 @@ module Tapioca
73
76
  todo_file: options[:todo_file],
74
77
  file_header: options[:file_header],
75
78
  )
76
- Tapioca.silence_warnings do
77
- command.execute
78
- end
79
+ command.run_with_deprecation
79
80
  end
80
81
 
81
- desc "dsl [constant...]", "generate RBIs for dynamic methods"
82
+ desc "dsl [constant...]", "Generate RBIs for dynamic methods"
82
83
  option :outdir,
83
84
  aliases: ["--out", "-o"],
84
85
  banner: "directory",
@@ -140,7 +141,7 @@ module Tapioca
140
141
  # Assume anything starting with a capital letter or colon is a class, otherwise a path
141
142
  constants, paths = constant_or_paths.partition { |c| c =~ /\A[A-Z:]/ }
142
143
 
143
- command = Commands::Dsl.new(
144
+ command_args = {
144
145
  requested_constants: constants,
145
146
  requested_paths: paths.map { |p| Pathname.new(p) },
146
147
  outpath: Pathname.new(options[:outdir]),
@@ -148,25 +149,26 @@ module Tapioca
148
149
  exclude: options[:exclude],
149
150
  file_header: options[:file_header],
150
151
  tapioca_path: TAPIOCA_DIR,
151
- should_verify: options[:verify],
152
152
  quiet: options[:quiet],
153
153
  verbose: options[:verbose],
154
154
  number_of_workers: options[:workers],
155
155
  rbi_formatter: rbi_formatter(options),
156
156
  app_root: options[:app_root],
157
157
  halt_upon_load_error: options[:halt_upon_load_error],
158
- )
159
-
160
- Tapioca.silence_warnings do
161
- if options[:list_compilers]
162
- command.list_compilers
163
- else
164
- command.execute
165
- end
158
+ }
159
+
160
+ command = if options[:verify]
161
+ Commands::DslVerify.new(**command_args)
162
+ elsif options[:list_compilers]
163
+ Commands::DslCompilerList.new(**command_args)
164
+ else
165
+ Commands::DslGenerate.new(**command_args)
166
166
  end
167
+
168
+ command.run
167
169
  end
168
170
 
169
- desc "gem [gem...]", "generate RBIs from gems"
171
+ desc "gem [gem...]", "Generate RBIs from gems"
170
172
  option :outdir,
171
173
  aliases: ["--out", "-o"],
172
174
  banner: "directory",
@@ -196,6 +198,10 @@ module Tapioca
196
198
  banner: "gem [gem ...]",
197
199
  desc: "Exclude the given gem(s) from RBI generation",
198
200
  default: []
201
+ option :include_dependencies,
202
+ type: :boolean,
203
+ desc: "Generate RBI files for dependencies of the given gem(s)",
204
+ default: false
199
205
  option :typed_overrides,
200
206
  aliases: ["--typed", "-t"],
201
207
  type: :hash,
@@ -245,47 +251,54 @@ module Tapioca
245
251
  desc: "Halt upon a load error while loading the Rails application",
246
252
  default: true
247
253
  def gem(*gems)
248
- Tapioca.silence_warnings do
249
- set_environment(options)
250
-
251
- all = options[:all]
252
- verify = options[:verify]
253
-
254
- command = Commands::Gem.new(
255
- gem_names: all ? [] : gems,
256
- exclude: options[:exclude],
257
- prerequire: options[:prerequire],
258
- postrequire: options[:postrequire],
259
- typed_overrides: options[:typed_overrides],
260
- outpath: Pathname.new(options[:outdir]),
261
- file_header: options[:file_header],
262
- include_doc: options[:doc],
263
- include_loc: options[:loc],
264
- include_exported_rbis: options[:exported_gem_rbis],
265
- number_of_workers: options[:workers],
266
- auto_strictness: options[:auto_strictness],
267
- dsl_dir: options[:dsl_dir],
268
- rbi_formatter: rbi_formatter(options),
269
- halt_upon_load_error: options[:halt_upon_load_error],
270
- )
271
-
272
- raise MalformattedArgumentError, "Options '--all' and '--verify' are mutually exclusive" if all && verify
273
-
274
- unless gems.empty?
275
- raise MalformattedArgumentError, "Option '--all' must be provided without any other arguments" if all
276
- raise MalformattedArgumentError, "Option '--verify' must be provided without any other arguments" if verify
277
- end
254
+ set_environment(options)
278
255
 
279
- if gems.empty? && !all
280
- command.sync(should_verify: verify, exclude: options[:exclude])
281
- else
282
- command.execute
283
- end
256
+ all = options[:all]
257
+ verify = options[:verify]
258
+ include_dependencies = options[:include_dependencies]
259
+
260
+ raise MalformattedArgumentError, "Options '--all' and '--verify' are mutually exclusive" if all && verify
261
+
262
+ if gems.empty?
263
+ raise MalformattedArgumentError,
264
+ "Option '--include-dependencies' must be provided with gems" if include_dependencies
265
+ else
266
+ raise MalformattedArgumentError, "Option '--all' must be provided without any other arguments" if all
267
+ raise MalformattedArgumentError, "Option '--verify' must be provided without any other arguments" if verify
284
268
  end
269
+
270
+ command_args = {
271
+ gem_names: all ? [] : gems,
272
+ exclude: options[:exclude],
273
+ include_dependencies: options[:include_dependencies],
274
+ prerequire: options[:prerequire],
275
+ postrequire: options[:postrequire],
276
+ typed_overrides: options[:typed_overrides],
277
+ outpath: Pathname.new(options[:outdir]),
278
+ file_header: options[:file_header],
279
+ include_doc: options[:doc],
280
+ include_loc: options[:loc],
281
+ include_exported_rbis: options[:exported_gem_rbis],
282
+ number_of_workers: options[:workers],
283
+ auto_strictness: options[:auto_strictness],
284
+ dsl_dir: options[:dsl_dir],
285
+ rbi_formatter: rbi_formatter(options),
286
+ halt_upon_load_error: options[:halt_upon_load_error],
287
+ }
288
+
289
+ command = if verify
290
+ Commands::GemVerify.new(**command_args)
291
+ elsif !gems.empty? || all
292
+ Commands::GemGenerate.new(**command_args)
293
+ else
294
+ Commands::GemSync.new(**command_args)
295
+ end
296
+
297
+ command.run
285
298
  end
286
299
  map "gems" => :gem
287
300
 
288
- desc "check-shims", "check duplicated definitions in shim RBIs"
301
+ desc "check-shims", "Check duplicated definitions in shim RBIs"
289
302
  option :gem_rbi_dir, type: :string, desc: "Path to gem RBIs", default: DEFAULT_GEM_DIR
290
303
  option :dsl_rbi_dir, type: :string, desc: "Path to DSL RBIs", default: DEFAULT_DSL_DIR
291
304
  option :shim_rbi_dir, type: :string, desc: "Path to shim RBIs", default: DEFAULT_SHIM_DIR
@@ -304,9 +317,7 @@ module Tapioca
304
317
  number_of_workers: options[:workers],
305
318
  )
306
319
 
307
- Tapioca.silence_warnings do
308
- command.execute
309
- end
320
+ command.run
310
321
  end
311
322
 
312
323
  desc "annotations", "Pull gem RBI annotations from remote sources"
@@ -335,14 +346,12 @@ module Tapioca
335
346
  typed_overrides: options[:typed_overrides],
336
347
  )
337
348
 
338
- Tapioca.silence_warnings do
339
- command.execute
340
- end
349
+ command.run
341
350
  end
342
351
 
343
352
  map ["--version", "-v"] => :__print_version
344
353
 
345
- desc "--version, -v", "show version"
354
+ desc "--version, -v", "Show version"
346
355
  def __print_version
347
356
  puts "Tapioca v#{Tapioca::VERSION}"
348
357
  end