rails / thor

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

class_options in thor groups do not print in command help #661

Open pblesi opened 5 years ago

pblesi commented 5 years ago

Using this toy example:

#!/usr/bin/env ruby

require "thor"
require "thor/group"

class MyGroup < Thor::Group
  class_option :opt, aliases: :o, default: "1"

  def one
    puts options[:opt]
  end
end

class MyCLI < Thor
  register(MyGroup, "print_opt", "print_opt", "Prints the options")
end

MyCLI.start

And running:

bundle exec broken_class_options.rb help print_opt

Produces this output:

Usage:
  broken_class_options.rb print_opt

The class options are not printed for this group. This appears related to this issue: https://github.com/erikhuda/thor/issues/402

jaredcwhite commented 4 years ago

I came up with a workaround to this by overriding the help method in my top-level Thor class. It also outputs a nice overview if no commands are provided.

Here's a abbreviated example:

class Base < Thor
  register(BuildThor, "build", "build", "Build your site")
  register(ServeThor, "serve", "serve", "Serve your site locally")

  desc "help <command>", "Show detailed command usage information and exit"
  def help(subcommand = nil)
    if subcommand && respond_to?(subcommand)
      klass = Kernel.const_get("Bridgetown::Commands::#{subcommand.capitalize}Thor")
      klass.start(["-h"])
    else
      puts "Bridgetown is a Webpack-aware, Ruby-powered static site generator for the modern Jamstack era"
      puts ""
      puts "Version: #{Bridgetown::VERSION.magenta} \"#{Bridgetown::CODE_NAME.yellow}\""
      puts ""
      puts "Usage:"
      puts "  bridgetown <command> [options]"
      puts ""
      super
    end
  end
end
deepakmahakale commented 3 years ago

This solves the problem.

class MyGroup < Thor::Group
  class_option :opt, aliases: :o, default: "1"

  def one
    puts options[:opt]
  end
end

class MyCLI < Thor
  register(MyGroup, "print_opt", "print_opt", "Prints the options")
  tasks["print_opt"].options = MyGroup.class_options
end

And running:

bundle exec broken_class_options.rb help print_opt

Will now produce this output:

Usage:
  broken_class_options.rb print_opt

Options:
  o, [--opt=OPT]
                  # Default: 1

Prints the options