lib/tapioca/cli.rb in tapioca-0.4.27 vs lib/tapioca/cli.rb in tapioca-0.5.0
- old
+ new
@@ -1,8 +1,262 @@
# typed: true
# frozen_string_literal: true
-require 'thor'
+require "thor"
module Tapioca
- module Cli; end
+ class Cli < Thor
+ include(Thor::Actions)
+
+ class_option :outdir,
+ aliases: ["--out", "-o"],
+ banner: "directory",
+ desc: "The output directory for generated RBI files"
+ class_option :generate_command,
+ aliases: ["--cmd", "-c"],
+ banner: "command",
+ desc: "The command to run to regenerate RBI files"
+ class_option :file_header,
+ type: :boolean,
+ default: true,
+ desc: "Add a \"This file is generated\" header on top of each generated RBI file"
+ class_option :verbose,
+ aliases: ["-V"],
+ type: :boolean,
+ default: false,
+ desc: "Verbose output for debugging purposes"
+
+ map T.unsafe(["--version", "-v"] => :__print_version)
+
+ desc "init", "initializes folder structure"
+ def init
+ create_config
+ create_post_require
+ generate_binstub
+ end
+
+ desc "require", "generate the list of files to be required by tapioca"
+ def require
+ Tapioca.silence_warnings do
+ generator.build_requires
+ end
+ end
+
+ desc "todo", "generate the list of unresolved constants"
+ def todo
+ Tapioca.silence_warnings do
+ generator.build_todos
+ end
+ end
+
+ desc "dsl [constant...]", "generate RBIs for dynamic methods"
+ option :generators,
+ type: :array,
+ aliases: ["--gen", "-g"],
+ banner: "generator [generator ...]",
+ desc: "Only run supplied DSL generators"
+ option :exclude_generators,
+ type: :array,
+ banner: "generator [generator ...]",
+ desc: "Exclude supplied DSL generators"
+ option :verify,
+ type: :boolean,
+ default: false,
+ desc: "Verifies RBIs are up-to-date"
+ option :quiet,
+ aliases: ["-q"],
+ type: :boolean,
+ desc: "Supresses file creation output"
+ def dsl(*constants)
+ Tapioca.silence_warnings do
+ generator.build_dsl(
+ constants,
+ should_verify: options[:verify],
+ quiet: options[:quiet],
+ verbose: options[:verbose]
+ )
+ end
+ end
+
+ desc "gem [gem...]", "generate RBIs from gems"
+ option :all,
+ type: :boolean,
+ default: false,
+ desc: "Regenerate RBI files for all gems"
+ option :prerequire,
+ aliases: ["--pre", "-b"],
+ banner: "file",
+ desc: "A file to be required before Bundler.require is called"
+ option :postrequire,
+ aliases: ["--post", "-a"],
+ banner: "file",
+ desc: "A file to be required after Bundler.require is called"
+ option :exclude,
+ aliases: ["-x"],
+ type: :array,
+ banner: "gem [gem ...]",
+ desc: "Excludes the given gem(s) from RBI generation"
+ option :typed_overrides,
+ aliases: ["--typed", "-t"],
+ type: :hash,
+ banner: "gem:level [gem:level ...]",
+ desc: "Overrides for typed sigils for generated gem RBIs"
+ option :verify,
+ type: :boolean,
+ default: false,
+ desc: "Verifies RBIs are up-to-date"
+ def gem(*gems)
+ Tapioca.silence_warnings do
+ all = options[:all]
+ verify = options[:verify]
+
+ raise MalformattedArgumentError, "Options '--all' and '--verify' are mutually exclusive" if all && verify
+
+ unless gems.empty?
+ raise MalformattedArgumentError, "Option '--all' must be provided without any other arguments" if all
+ raise MalformattedArgumentError, "Option '--verify' must be provided without any other arguments" if verify
+ end
+
+ if gems.empty? && !all
+ generator.sync_rbis_with_gemfile(should_verify: verify)
+ else
+ generator.build_gem_rbis(all ? [] : gems)
+ end
+ end
+ end
+
+ desc "generate [gem...]", "DEPRECATED: generate RBIs from gems"
+ option :prerequire,
+ aliases: ["--pre", "-b"],
+ banner: "file",
+ desc: "A file to be required before Bundler.require is called"
+ option :postrequire,
+ aliases: ["--post", "-a"],
+ banner: "file",
+ desc: "A file to be required after Bundler.require is called"
+ option :exclude,
+ aliases: ["-x"],
+ type: :array,
+ banner: "gem [gem ...]",
+ desc: "Excludes the given gem(s) from RBI generation"
+ option :typed_overrides,
+ aliases: ["--typed", "-t"],
+ type: :hash,
+ banner: "gem:level [gem:level ...]",
+ desc: "Overrides for typed sigils for generated gem RBIs"
+ def generate(*gems)
+ gem_names = if gems.empty?
+ "--all"
+ else
+ gems.join(" ")
+ end
+ deprecation_message = <<~MSG
+ DEPRECATION: The `generate` command will be removed in a future release.
+
+ Start using `bin/tapioca gem #{gem_names}` instead.
+ MSG
+
+ say(deprecation_message, :red)
+ say("")
+
+ Tapioca.silence_warnings do
+ generator.build_gem_rbis(gems)
+ end
+
+ say("")
+ say(deprecation_message, :red)
+ end
+
+ desc "sync", "DEPRECATED: sync RBIs to Gemfile"
+ option :prerequire,
+ aliases: ["--pre", "-b"],
+ banner: "file",
+ desc: "A file to be required before Bundler.require is called"
+ option :postrequire,
+ aliases: ["--post", "-a"],
+ banner: "file",
+ desc: "A file to be required after Bundler.require is called"
+ option :exclude,
+ aliases: ["-x"],
+ type: :array,
+ banner: "gem [gem ...]",
+ desc: "Excludes the given gem(s) from RBI generation"
+ option :typed_overrides,
+ aliases: ["--typed", "-t"],
+ type: :hash,
+ banner: "gem:level [gem:level ...]",
+ desc: "Overrides for typed sigils for generated gem RBIs"
+ option :verify,
+ type: :boolean,
+ default: false,
+ desc: "Verifies RBIs are up-to-date"
+ def sync
+ deprecation_message = <<~MSG
+ DEPRECATION: The `sync` command will be removed in a future release.
+
+ Start using `bin/tapioca gem` instead.
+ MSG
+
+ say(deprecation_message, :red)
+ say("")
+
+ Tapioca.silence_warnings do
+ generator.sync_rbis_with_gemfile(should_verify: options[:verify])
+ end
+
+ say("")
+ say(deprecation_message, :red)
+ end
+
+ desc "--version, -v", "show version"
+ def __print_version
+ puts "Tapioca v#{Tapioca::VERSION}"
+ end
+
+ private
+
+ def create_config
+ create_file(Config::SORBET_CONFIG, skip: true) do
+ <<~CONTENT
+ --dir
+ .
+ CONTENT
+ end
+ end
+
+ def create_post_require
+ create_file(Config::DEFAULT_POSTREQUIRE, skip: true) do
+ <<~CONTENT
+ # typed: true
+ # frozen_string_literal: true
+
+ # Add your extra requires here (`tapioca require` can be used to boostrap this list)
+ CONTENT
+ end
+ end
+
+ def generate_binstub
+ bin_stub_exists = File.exist?("bin/tapioca")
+ installer = Bundler::Installer.new(Bundler.root, Bundler.definition)
+ spec = Bundler.definition.specs.find { |s| s.name == "tapioca" }
+ installer.generate_bundler_executable_stubs(spec, { force: true })
+ if bin_stub_exists
+ shell.say_status(:force, "bin/tapioca", :yellow)
+ else
+ shell.say_status(:create, "bin/tapioca", :green)
+ end
+ end
+
+ no_commands do
+ def self.exit_on_failure?
+ true
+ end
+
+ def generator
+ current_command = T.must(current_command_chain.first)
+ @generator ||= Generator.new(
+ ConfigBuilder.from_options(current_command, options)
+ )
+ end
+ end
+ end
end