tapioca 0.11.8 → 0.11.9
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 +4 -4
- data/README.md +116 -49
- data/lib/tapioca/cli.rb +76 -67
- data/lib/tapioca/commands/{dsl.rb → abstract_dsl.rb} +32 -78
- data/lib/tapioca/commands/{gem.rb → abstract_gem.rb} +26 -93
- data/lib/tapioca/commands/annotations.rb +9 -7
- data/lib/tapioca/commands/check_shims.rb +2 -0
- data/lib/tapioca/commands/command.rb +9 -2
- data/lib/tapioca/commands/configure.rb +2 -2
- data/lib/tapioca/commands/dsl_compiler_list.rb +31 -0
- data/lib/tapioca/commands/dsl_generate.rb +40 -0
- data/lib/tapioca/commands/dsl_verify.rb +25 -0
- data/lib/tapioca/commands/gem_generate.rb +51 -0
- data/lib/tapioca/commands/gem_sync.rb +37 -0
- data/lib/tapioca/commands/gem_verify.rb +36 -0
- data/lib/tapioca/commands/require.rb +2 -0
- data/lib/tapioca/commands/todo.rb +21 -2
- data/lib/tapioca/commands.rb +8 -2
- data/lib/tapioca/dsl/compiler.rb +8 -4
- data/lib/tapioca/dsl/compilers/action_controller_helpers.rb +3 -1
- data/lib/tapioca/dsl/compilers/active_model_validations_confirmation.rb +94 -0
- data/lib/tapioca/dsl/compilers/active_record_columns.rb +19 -9
- data/lib/tapioca/dsl/compilers/active_record_typed_store.rb +3 -2
- data/lib/tapioca/dsl/compilers/active_support_concern.rb +1 -1
- data/lib/tapioca/dsl/compilers/graphql_input_object.rb +1 -1
- data/lib/tapioca/dsl/compilers/graphql_mutation.rb +9 -2
- data/lib/tapioca/dsl/compilers/json_api_client_resource.rb +208 -0
- data/lib/tapioca/dsl/helpers/active_record_column_type_helper.rb +20 -4
- data/lib/tapioca/dsl/helpers/graphql_type_helper.rb +20 -3
- data/lib/tapioca/dsl/pipeline.rb +6 -4
- data/lib/tapioca/gem/pipeline.rb +103 -36
- data/lib/tapioca/gemfile.rb +13 -7
- data/lib/tapioca/helpers/git_attributes.rb +34 -0
- data/lib/tapioca/helpers/test/template.rb +4 -4
- data/lib/tapioca/internal.rb +1 -0
- data/lib/tapioca/loaders/dsl.rb +11 -1
- data/lib/tapioca/sorbet_ext/generic_name_patch.rb +0 -27
- data/lib/tapioca/static/symbol_loader.rb +9 -8
- data/lib/tapioca/version.rb +1 -1
- metadata +19 -10
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: d9a73b205d42dc103e1e4816c7915a3b4764cdeb6894f384a66e500e95bfbc5a
         | 
| 4 | 
            +
              data.tar.gz: ff14910658ef17ebe542f8adb67c70e24ed755b41f31860071425d95917c9172
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 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      #  | 
| 74 | 
            +
              tapioca --version, -v      # Show version
         | 
| 76 75 | 
             
              tapioca annotations        # Pull gem RBI annotations from remote sources
         | 
| 77 | 
            -
              tapioca check-shims        #  | 
| 78 | 
            -
              tapioca configure          #  | 
| 79 | 
            -
              tapioca dsl [constant...]  #  | 
| 80 | 
            -
              tapioca gem [gem...]       #  | 
| 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               #  | 
| 83 | 
            -
              tapioca require            #  | 
| 84 | 
            -
              tapioca todo               #  | 
| 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 | 
            -
             | 
| 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 | 
            -
             | 
| 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.  | 
| 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 | 
            -
             | 
| 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 | 
            -
             | 
| 670 | 
            +
            #### Writing custom DSL extensions
         | 
| 671 671 |  | 
| 672 | 
            -
             | 
| 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 | 
            -
             | 
| 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 | 
            -
             | 
| 677 | 
            +
            ```rb
         | 
| 678 | 
            +
            module Encryptable
         | 
| 679 | 
            +
              def self.included(base)
         | 
| 680 | 
            +
                base.extend(ClassMethods)
         | 
| 681 | 
            +
              end
         | 
| 681 682 |  | 
| 682 | 
            -
             | 
| 683 | 
            +
              module ClassMethods
         | 
| 684 | 
            +
                def attr_encrypted(attr_name)
         | 
| 685 | 
            +
                  attr_accessor(attr_name)
         | 
| 683 686 |  | 
| 684 | 
            -
             | 
| 687 | 
            +
                  encrypted_attr_name = :"#{attr_name}_encrypted"
         | 
| 685 688 |  | 
| 686 | 
            -
             | 
| 689 | 
            +
                  define_method(encrypted_attr_name) do
         | 
| 690 | 
            +
                    value = send(attr_name)
         | 
| 691 | 
            +
                    encrypt(value)
         | 
| 692 | 
            +
                  end
         | 
| 687 693 |  | 
| 688 | 
            -
             | 
| 689 | 
            -
             | 
| 694 | 
            +
                  define_method("#{encrypted_attr_name}=") do |value|
         | 
| 695 | 
            +
                    send("#{attr_name}=", decrypt(value))
         | 
| 696 | 
            +
                  end
         | 
| 697 | 
            +
                end
         | 
| 698 | 
            +
              end
         | 
| 690 699 |  | 
| 691 | 
            -
             | 
| 692 | 
            -
             | 
| 693 | 
            -
             | 
| 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 | 
            -
             | 
| 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 | 
            -
             | 
| 699 | 
            -
             | 
| 700 | 
            -
            $ tapioca help todo
         | 
| 714 | 
            +
            ```rb
         | 
| 715 | 
            +
            require "encryptable"
         | 
| 701 716 |  | 
| 702 | 
            -
             | 
| 703 | 
            -
               | 
| 717 | 
            +
            module Tapioca
         | 
| 718 | 
            +
              module Extensions
         | 
| 719 | 
            +
                module Encryptable
         | 
| 720 | 
            +
                  attr_reader :__tapioca_encrypted_attributes
         | 
| 704 721 |  | 
| 705 | 
            -
             | 
| 706 | 
            -
             | 
| 707 | 
            -
             | 
| 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 | 
            -
             | 
| 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 | 
            -
             | 
| 735 | 
            +
            The compiler can now use the `__tapioca_encrypted_attributes` array managed by the extension:
         | 
| 719 736 |  | 
| 720 | 
            -
             | 
| 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 | 
            -
             | 
| 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", " | 
| 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 | 
            -
             | 
| 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", " | 
| 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. | 
| 52 | 
            +
                  command.run
         | 
| 48 53 | 
             
                end
         | 
| 49 54 |  | 
| 50 | 
            -
                desc "require", " | 
| 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 | 
            -
                   | 
| 58 | 
            -
                    command.execute
         | 
| 59 | 
            -
                  end
         | 
| 62 | 
            +
                  command.run
         | 
| 60 63 | 
             
                end
         | 
| 61 64 |  | 
| 62 | 
            -
                desc "todo", " | 
| 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 | 
            -
                   | 
| 77 | 
            -
                    command.execute
         | 
| 78 | 
            -
                  end
         | 
| 79 | 
            +
                  command.run_with_deprecation
         | 
| 79 80 | 
             
                end
         | 
| 80 81 |  | 
| 81 | 
            -
                desc "dsl [constant...]", " | 
| 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 | 
            -
                   | 
| 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 | 
            -
                   | 
| 161 | 
            -
                     | 
| 162 | 
            -
             | 
| 163 | 
            -
                     | 
| 164 | 
            -
             | 
| 165 | 
            -
                     | 
| 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...]", " | 
| 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 | 
            -
                   | 
| 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 | 
            -
             | 
| 280 | 
            -
             | 
| 281 | 
            -
             | 
| 282 | 
            -
             | 
| 283 | 
            -
             | 
| 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", " | 
| 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 | 
            -
                   | 
| 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 | 
            -
                   | 
| 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", " | 
| 354 | 
            +
                desc "--version, -v", "Show version"
         | 
| 346 355 | 
             
                def __print_version
         | 
| 347 356 | 
             
                  puts "Tapioca v#{Tapioca::VERSION}"
         | 
| 348 357 | 
             
                end
         |