diff --git a/v2/ruby/lib/terminalwire/v2/rails.rb b/v2/ruby/lib/terminalwire/v2/rails.rb index 68cacf6..38bfc41 100644 --- a/v2/ruby/lib/terminalwire/v2/rails.rb +++ b/v2/ruby/lib/terminalwire/v2/rails.rb @@ -65,7 +65,7 @@ def self.dual_terminal(cli, v1: nil, v2: nil) # route. (A bare Rack handed to `match to:` drops streaming output in production; # the endpoint, like dual_terminal's, is what Rails routing needs.) def self.terminal(cli, verbose: nil, report: nil) - Terminalwire::V2::Server.dualize(cli) + Terminalwire::V2::Server.terminalize(cli) v2 = Terminalwire::V2::Server::Rack.new( cli, verbose: verbose.nil? ? verbose?() : verbose, diff --git a/v2/ruby/lib/terminalwire/v2/server/dual_thor.rb b/v2/ruby/lib/terminalwire/v2/server/dual_thor.rb index d241bad..18c7ea4 100644 --- a/v2/ruby/lib/terminalwire/v2/server/dual_thor.rb +++ b/v2/ruby/lib/terminalwire/v2/server/dual_thor.rb @@ -44,5 +44,18 @@ def self.dualize(klass, seen = {}) klass.subcommand_classes.each_value { |sub| dualize(sub, seen) } if klass.respond_to?(:subcommand_classes) klass end + + # Walk a Thor class + its subcommand tree, making every command class speak v2 + # NATIVELY — it includes Terminalwire::V2::Server::Thor (whose `terminalwire` + # dispatches with the v2 shell, no v1 `super`). This is the v2-only path: the + # app loads only the v2 gem. `dualize` is the transitional both-protocols path. + # Idempotent. Returns the class. + def self.terminalize(klass, seen = {}) + return klass if seen[klass] + seen[klass] = true + klass.include(Terminalwire::V2::Server::Thor) unless klass.include?(Terminalwire::V2::Server::Thor) + klass.subcommand_classes.each_value { |sub| terminalize(sub, seen) } if klass.respond_to?(:subcommand_classes) + klass + end end end diff --git a/v2/ruby/spec/server/rails_terminal_spec.rb b/v2/ruby/spec/server/rails_terminal_spec.rb index 11baad7..dd07da5 100644 --- a/v2/ruby/spec/server/rails_terminal_spec.rb +++ b/v2/ruby/spec/server/rails_terminal_spec.rb @@ -47,9 +47,11 @@ def env(protocols) expect(endpoint.instance_variable_get(:@by_subprotocol)["terminalwire.v2"]).to be(rack) end - it "dualizes the cli so it answers the v2 wire" do + it "terminalizes the cli so it speaks v2 natively (no v1 needed)" do described_class.terminal(cli) - expect(cli.include?(Terminalwire::V2::Server::DualThor)).to be(true) + expect(cli.include?(Terminalwire::V2::Server::Thor)).to be(true) + refute_includes_dual = !cli.include?(Terminalwire::V2::Server::DualThor) + expect(refute_includes_dual).to be(true) end end end