rails / thor

Thor is a toolkit for building powerful command-line interfaces.
http://whatisthor.com/
MIT License
5.13k stars 552 forks source link

Are there any alternatives to no_methods? #744

Closed jigarius closed 3 years ago

jigarius commented 3 years ago

I'm working on a small CLI app where I'm using Thor. I have a helper method in my Cli class like this:

class Cli < Thor
  extend T::Sig

  desc "play", "Play the game"
  sig { void }
  def play
    choice = input_choice
    # Do something with the choice
  end

  private

  no_commands do
    sig { void }
    def input_choice
      # Build a message and show it with puts
      ask("Make a choice", { limited_to: ['r', 'p', 's'] })
    end
  end
end

Despite using no_commands, I keep getting a warning:

[WARNING] Attempted to create command "input_choice" without usage or description.
Call desc if you want this method to be available as command or declare it inside a no_commands{} block.
Invoked from "/usr/local/bundle/gems/sorbet-runtime-0.5.6196/lib/types/private/methods/_methods.rb:456:in `method_added'".

Maybe Thor is not compatible with Sorbet? I was wondering if there's another way to indicate that a method is not a command? Maybe something like:

# ...
thor_ignore
sig { void }
def input_choice
end
# ...
rafaelfranca commented 3 years ago

Does no_commands work if you remove the sig call?

jigarius commented 3 years ago

Yes. I've temporarily removed the sig to tackle the issue. However, removing the sig makes that method lose typing info for it's arguments.

rafaelfranca commented 3 years ago

I don't think there is something we can do here. Sorbet is removing the method you defined and adding it with the same name and different implementation to check types at runtime. This means that the method defined by Sorbet, not the method defined by you, is defined outside of the no_commands block.

You could try remove_command like documented in the no_commands method, but I'm not sure if that would work either.

Looking into the code the no_commands should only be required for public methods. If you define a private method outside of the no_commands block, with a sig, does it work?

jigarius commented 3 years ago

I already tried using remove_command, but that didn't help. Also, I continue to get the error even if the input_choice method is under private.

I'll try asking the Sorbet team if they have any suggested workarounds for these kind of things. I'm closing the issue for now. Thanks for the fast responses.

idengager commented 2 years ago

@jigarius 👋 Did you find any workarounds?

jigarius commented 2 years ago

I can't remember 😞 Actually, I moved the helper method to a different class as it made more sense. Thus, the issue became outdated for me.

Reference: cli.rb