lib/tapioca/cli.rb in tapioca-0.6.4 vs lib/tapioca/cli.rb in tapioca-0.7.0

- old
+ new

@@ -3,10 +3,11 @@ module Tapioca class Cli < Thor include CliHelper include ConfigHelper + include ShimsHelper FILE_HEADER_OPTION_DESC = "Add a \"This file is generated\" header on top of each generated RBI file" class_option :config, aliases: ["-c"], @@ -20,29 +21,27 @@ desc: "Verbose output for debugging purposes", default: false desc "init", "initializes folder structure" def init - generator = Generators::Init.new( + command = Commands::Init.new( sorbet_config: SORBET_CONFIG_FILE, tapioca_config: TAPIOCA_CONFIG_FILE, - default_postrequire: DEFAULT_POSTREQUIRE_FILE, - default_command: DEFAULT_COMMAND + default_postrequire: DEFAULT_POSTREQUIRE_FILE ) - generator.generate + command.execute end desc "require", "generate the list of files to be required by tapioca" option :postrequire, type: :string, default: DEFAULT_POSTREQUIRE_FILE def require - generator = Generators::Require.new( + command = Commands::Require.new( requires_path: options[:postrequire], - sorbet_config_path: SORBET_CONFIG_FILE, - default_command: DEFAULT_COMMAND + sorbet_config_path: SORBET_CONFIG_FILE ) Tapioca.silence_warnings do - generator.generate + command.execute end end desc "todo", "generate the list of unresolved constants" option :todo_file, @@ -52,17 +51,16 @@ option :file_header, type: :boolean, desc: FILE_HEADER_OPTION_DESC, default: true def todo - generator = Generators::Todo.new( + command = Commands::Todo.new( todo_file: options[:todo_file], - file_header: options[:file_header], - default_command: DEFAULT_COMMAND + file_header: options[:file_header] ) Tapioca.silence_warnings do - generator.generate + command.execute end end desc "dsl [constant...]", "generate RBIs for dynamic methods" option :outdir, @@ -74,17 +72,17 @@ type: :boolean, desc: FILE_HEADER_OPTION_DESC, default: true option :only, type: :array, - banner: "generator [generator ...]", - desc: "Only run supplied DSL generator(s)", + banner: "compiler [compiler ...]", + desc: "Only run supplied DSL compiler(s)", default: [] option :exclude, type: :array, - banner: "generator [generator ...]", - desc: "Exclude supplied DSL generator(s)", + banner: "compiler [compiler ...]", + desc: "Exclude supplied DSL compiler(s)", default: [] option :verify, type: :boolean, default: false, desc: "Verifies RBIs are up-to-date" @@ -96,35 +94,39 @@ option :workers, aliases: ["-w"], type: :numeric, desc: "EXPERIMENTAL: Number of parallel workers to use when generating RBIs", default: 1 + option :rbi_max_line_length, + type: :numeric, + desc: "Set the max line length of generated RBIs. Signatures longer than the max line length will be wrapped", + default: 120 def dsl(*constants) - generator = Generators::Dsl.new( + command = Commands::Dsl.new( requested_constants: constants, outpath: Pathname.new(options[:outdir]), only: options[:only], exclude: options[:exclude], file_header: options[:file_header], - compiler_path: Tapioca::Compilers::Dsl::DSL_COMPILERS_DIR, + compiler_path: Tapioca::Dsl::Compilers::DIRECTORY, tapioca_path: TAPIOCA_DIR, - default_command: DEFAULT_COMMAND, should_verify: options[:verify], quiet: options[:quiet], verbose: options[:verbose], - number_of_workers: options[:workers] + number_of_workers: options[:workers], + rbi_formatter: rbi_formatter(options) ) if options[:workers] != 1 say( "Using more than one worker is experimental and might produce results that are not deterministic", :red ) end Tapioca.silence_warnings do - generator.generate + command.execute end end desc "gem [gem...]", "generate RBIs from gems" option :outdir, @@ -177,27 +179,42 @@ option :workers, aliases: ["-w"], type: :numeric, desc: "EXPERIMENTAL: Number of parallel workers to use when generating RBIs", default: 1 + option :auto_strictness, + type: :boolean, + desc: "Autocorrect strictness in gem RBIs in case of conflict with the DSL RBIs", + default: true + option :dsl_dir, + aliases: ["--dsl-dir"], + banner: "directory", + desc: "The DSL directory used to correct gems strictnesses", + default: DEFAULT_DSL_DIR + option :rbi_max_line_length, + type: :numeric, + desc: "Set the max line length of generated RBIs. Signatures longer than the max line length will be wrapped", + default: 120 def gem(*gems) Tapioca.silence_warnings do all = options[:all] verify = options[:verify] - generator = Generators::Gem.new( + command = Commands::Gem.new( gem_names: all ? [] : gems, exclude: options[:exclude], prerequire: options[:prerequire], postrequire: options[:postrequire], typed_overrides: options[:typed_overrides], - default_command: DEFAULT_COMMAND, outpath: Pathname.new(options[:outdir]), file_header: options[:file_header], doc: options[:doc], include_exported_rbis: options[:exported_gem_rbis], - number_of_workers: options[:workers] + number_of_workers: options[:workers], + auto_strictness: options[:auto_strictness], + dsl_dir: options[:dsl_dir], + rbi_formatter: rbi_formatter(options) ) raise MalformattedArgumentError, "Options '--all' and '--verify' are mutually exclusive" if all && verify unless gems.empty? @@ -211,83 +228,51 @@ :red ) end if gems.empty? && !all - generator.sync(should_verify: verify) + command.sync(should_verify: verify) else - generator.generate + command.execute end end end + map "gems" => :gem - desc "clean-shims", "clean duplicated definitions in shim RBIs" + desc "check-shims", "check duplicated definitions in shim RBIs" option :gem_rbi_dir, type: :string, desc: "Path to gem RBIs", default: DEFAULT_GEM_DIR option :dsl_rbi_dir, type: :string, desc: "Path to DSL RBIs", default: DEFAULT_DSL_DIR option :shim_rbi_dir, type: :string, desc: "Path to shim RBIs", default: DEFAULT_SHIM_DIR - def clean_shims(*files_to_clean) + def check_shims index = RBI::Index.new - # Index gem RBIs - gem_rbi_dir = options[:gem_rbi_dir] - say("Loading gem RBIs from #{gem_rbi_dir}... ") - gem_rbis_files = Dir.glob("#{gem_rbi_dir}/**/*.rbi").sort - gem_rbis_trees = RBI::Parser.parse_files(gem_rbis_files) - index.visit_all(gem_rbis_trees) - say(" Done", :green) - - # Index dsl RBIs - dsl_rbi_dir = options[:dsl_rbi_dir] - say("Loading dsl RBIs from #{dsl_rbi_dir}... ") - dsl_rbis_files = Dir.glob("#{dsl_rbi_dir}/**/*.rbi").sort - dsl_rbis_trees = RBI::Parser.parse_files(dsl_rbis_files) - index.visit_all(dsl_rbis_trees) - say(" Done", :green) - - # Clean shim RBIs - if files_to_clean.empty? - shim_rbi_dir = options[:shim_rbi_dir] - print("Cleaning shim RBIs from #{shim_rbi_dir}...") - files_to_clean = Dir.glob("#{shim_rbi_dir}/*.rbi") - else - print("Cleaning shim RBIs...") + shim_rbi_dir = options[:shim_rbi_dir] + if !Dir.exist?(shim_rbi_dir) || Dir.empty?(shim_rbi_dir) + say("No shim RBIs to check", :green) + exit(0) end - done_something = T.let(false, T::Boolean) - files_to_clean.sort.each do |path| - original = RBI::Parser.parse_file(path) - cleaned, operations = RBI::Rewriters::RemoveKnownDefinitions.remove(original, index) + index_rbis(index, "shim", shim_rbi_dir) + index_rbis(index, "gem", options[:gem_rbi_dir]) + index_rbis(index, "dsl", options[:dsl_rbi_dir]) - next if operations.empty? - done_something = true - - operations.each do |operation| - print("\n #{operation}") + duplicates = duplicated_nodes_from_index(index, shim_rbi_dir) + unless duplicates.empty? + duplicates.each do |key, nodes| + say_error("\nDuplicated RBI for #{key}:", :red) + nodes.each do |node| + say_error(" * #{node.loc}", :red) + end end - - if cleaned.empty? - print("\n Deleted empty file #{path}") - FileUtils.rm(path) - else - File.write(path, cleaned.string) - end + say_error("\nPlease remove the duplicated definitions from the #{shim_rbi_dir} directory.", :red) + exit(1) end - if done_something - say("\nDone", :green) - else - say(" Done ", :green) - say("(nothing to do)", :yellow) - end - rescue Errno::ENOENT => e - say_error("\nCan't read RBI: #{e}") - exit(1) - rescue RBI::ParseError => e - say_error("\nCan't parse RBI: #{e} (#{e.location})") - exit(1) + say("\nNo duplicates found in shim RBIs", :green) + exit(0) end - map T.unsafe(["--version", "-v"] => :__print_version) + map ["--version", "-v"] => :__print_version desc "--version, -v", "show version" def __print_version puts "Tapioca v#{Tapioca::VERSION}" end