diff --git a/lib/tapioca/commands/abstract_gem.rb b/lib/tapioca/commands/abstract_gem.rb index 83c52e355..baabaa1af 100644 --- a/lib/tapioca/commands/abstract_gem.rb +++ b/lib/tapioca/commands/abstract_gem.rb @@ -71,6 +71,7 @@ def initialize( @include_doc = include_doc #: bool @include_loc = include_loc #: bool @include_exported_rbis = include_exported_rbis + @skipped_gems = [] #: Array[String] @halt_upon_load_error = halt_upon_load_error end diff --git a/lib/tapioca/commands/gem_generate.rb b/lib/tapioca/commands/gem_generate.rb index 6362655e5..302e1f0fe 100644 --- a/lib/tapioca/commands/gem_generate.rb +++ b/lib/tapioca/commands/gem_generate.rb @@ -30,6 +30,18 @@ def execute end end + unless @skipped_gems.empty? + say("\nNote: Tapioca skipped RBI generation for the following gems because they are ignored by default:", [:yellow, :bold]) + say(@skipped_gems.join(", "), [:yellow, :bold]) + end + + user_excluded_gems = @gem_names & @exclude + + unless user_excluded_gems.empty? + say("\nNote: Tapioca skipped RBI generation for the following gems because they were excluded:", [:yellow, :bold]) + say(user_excluded_gems.join(", "), [:yellow, :bold]) + end + if anything_done validate_rbi_files( command: default_command(:gem, @gem_names.join(" ")), @@ -56,11 +68,15 @@ def gems_to_generate(gem_names) gem = @bundle.gem(gem_name) if gem.nil? - next if @lsp_addon - - raise Tapioca::Error, set_color("Error: Cannot find gem '#{gem_name}'", :red) + if @lsp_addon + next + elsif Gemfile::GemSpec::IGNORED_GEMS.include?(gem_name) + @skipped_gems << gem_name + next + else + raise Tapioca::Error, set_color("Error: Cannot find gem '#{gem_name}'", :red) + end end - gems.concat(gem_dependencies(gem)) if @include_dependencies gems << gem end diff --git a/spec/tapioca/cli/gem_spec.rb b/spec/tapioca/cli/gem_spec.rb index 61484ad51..261207ac8 100644 --- a/spec/tapioca/cli/gem_spec.rb +++ b/spec/tapioca/cli/gem_spec.rb @@ -877,6 +877,87 @@ class Secret; end assert_success_status(result) end + it "reports explicitly requested ignored gems" do + result = @project.tapioca("gem sorbet", exclude: []) + + assert_stdout_includes(result, <<~OUT) + Note: Tapioca skipped RBI generation for the following gems because they are ignored by default: + sorbet + OUT + refute_includes(result.out, "Compiled sorbet") + + assert_empty_stderr(result) + assert_success_status(result) + end + + it "reports gems excluded by built-in and user configuration" do + result = @project.tapioca("gem sorbet rbi --exclude rbi") + + assert_stdout_includes(result, <<~OUT) + Note: Tapioca skipped RBI generation for the following gems because they are ignored by default: + sorbet + OUT + assert_stdout_includes(result, <<~OUT) + Note: Tapioca skipped RBI generation for the following gems because they were excluded: + rbi + OUT + refute_includes(result.out, "Compiled rbi") + + assert_empty_stderr(result) + assert_success_status(result) + end + + it "reports gems excluded by user configuration" do + result = @project.tapioca("gem rbi --exclude rbi") + + assert_stdout_includes(result, <<~OUT) + Note: Tapioca skipped RBI generation for the following gems because they were excluded: + rbi + OUT + refute_includes(result.out, "Compiled rbi") + + assert_empty_stderr(result) + assert_success_status(result) + end + + it "does not generate dependencies of explicitly excluded gems" do + @project.require_mock_gem(mock_gem("foo", "0.0.1", dependencies: ["bar"])) + @project.require_mock_gem(mock_gem("bar", "0.0.1")) + # Keep foo materialized after Bundler excludes it as a direct dependency. + @project.require_mock_gem(mock_gem("baz", "0.0.1", dependencies: ["foo"])) + @project.bundle_install! + + result = @project.tapioca("gem foo --include-dependencies --exclude foo") + + assert_stdout_includes(result, <<~OUT) + Note: Tapioca skipped RBI generation for the following gems because they were excluded: + foo + OUT + refute_includes(result.out, "Compiled foo") + refute_includes(result.out, "Compiled bar") + + assert_empty_stderr(result) + assert_success_status(result) + end + + it "does not report exclusions when no gems are explicitly requested" do + result = @project.tapioca("gem --exclude rbi") + + refute_includes(result.out, "because they were excluded") + + assert_empty_stderr(result) + assert_success_status(result) + end + + it "does not report exclusions when all gems are requested" do + result = @project.tapioca("gem --all --exclude rbi") + + refute_includes(result.out, "because they were excluded") + + assert_empty_stderr(result) + assert_success_status(result) + end + it "fails with error when gem cannot be found" do result = @project.tapioca("gem non_existent_gem")