Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get list of all commands of a class inheriting from Thor #731

Open
RonLek opened this issue Jun 24, 2020 · 1 comment
Open

Get list of all commands of a class inheriting from Thor #731

RonLek opened this issue Jun 24, 2020 · 1 comment

Comments

@RonLek
Copy link

RonLek commented Jun 24, 2020

I'm trying to get a list of all commands, subcommands and options of a class that inherits from Thor. For example, the module CLI below inherits from Thor and has two commands actor and service as shown below:

actor.rb

module CLI
  module Commands
    class Actor < CLI::Commands
      desc "monitor <AppName>", "Monitor the current app"
      def monitor(app_name)
      # do something
      end
 
      desc "new <AppName>", "New App"
      def new(app_name)
      # do something
      end
  end
end

service.rb

module CLI
  module Commands
    class Service < CLI::Commands
      desc "deploy <SERVICE_NAME>", "Deploy service"
      def deploy(name)
        # do something
       end
  end
end

I'm looking for a command list_commands that could list all commands and their methods and subcommands in a JSON like format

~ cli list_commands
cli: [
      actor: [ monitor, new ]
      service: [deploy]
]

Currently, kind of get what I what by putting help in front of each command/subcommand to get the next subcommand. My intention to use the output of the above command is to auto-generate a bash-completion script as new commands are added into the Commands module that inherits from CLI which inherits from Thor. Suggestions for any other approaches using some inbuilt mechanism in Thor are also welcome!

PS: Also take a look at a similar SO question

@tristanmorgan
Copy link

I took a slightly different approach to auto complete using complete -C /path/to/command command where instead of a script generated, bash calls the command directly to ask what should be used.

Related to #415

My code to fetch some of the data was:

  # list command names
  def list_commands
    commands = self.class.all_commands.keys.map { |elem| elem.tr('_', '-') }
    commands.reject! { |elem| %w[autocomplete default].include?(elem) }
  end

  # list flags for a command
  def  list_arguments(command:)
    options = self.class.all_commands[command].options.values
    exit 1 if options.empty?

    options.map(&:aliases).flatten! +
      options.map(&:switch_name)
  end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants