diff --git a/lib/thor.rb b/lib/thor.rb index cc4591b0..7a3ea072 100644 --- a/lib/thor.rb +++ b/lib/thor.rb @@ -65,8 +65,15 @@ def desc(usage, description, options = {}) # Defines the long description of the next command. # + # Long description is by default indented, line-wrapped and repeated whitespace merged. + # In order to print long description verbatim, with indentation and spacing exactly + # as found in the code, use the +wrap+ option + # + # long_desc 'your very long description', wrap: false + # # ==== Parameters # long description + # options # def long_desc(long_description, options = {}) if options[:for] @@ -74,6 +81,7 @@ def long_desc(long_description, options = {}) command.long_description = long_description if long_description else @long_desc = long_description + @long_desc_wrap = options[:wrap] != false end end @@ -258,7 +266,11 @@ def command_help(shell, command_name) if command.long_description shell.say "Description:" - shell.print_wrapped(command.long_description, indent: 2) + if command.wrap_long_description + shell.print_wrapped(command.long_description, indent: 2) + else + shell.say command.long_description + end else shell.say command.description end @@ -535,14 +547,15 @@ def create_command(meth) #:nodoc: @usage ||= nil @desc ||= nil @long_desc ||= nil + @long_desc_wrap ||= nil @hide ||= nil if @usage && @desc base_class = @hide ? Thor::HiddenCommand : Thor::Command relations = {exclusive_option_names: method_exclusive_option_names, at_least_one_option_names: method_at_least_one_option_names} - commands[meth] = base_class.new(meth, @desc, @long_desc, @usage, method_options, relations) - @usage, @desc, @long_desc, @method_options, @hide = nil + commands[meth] = base_class.new(meth, @desc, @long_desc, @long_desc_wrap, @usage, method_options, relations) + @usage, @desc, @long_desc, @long_desc_wrap, @method_options, @hide = nil @method_exclusive_option_names, @method_at_least_one_option_names = nil true elsif all_commands[meth] || meth == "method_missing" diff --git a/lib/thor/command.rb b/lib/thor/command.rb index 9cd7719f..c6bdf74b 100644 --- a/lib/thor/command.rb +++ b/lib/thor/command.rb @@ -1,9 +1,9 @@ class Thor - class Command < Struct.new(:name, :description, :long_description, :usage, :options, :options_relation, :ancestor_name) + class Command < Struct.new(:name, :description, :long_description, :wrap_long_description, :usage, :options, :options_relation, :ancestor_name) FILE_REGEXP = /^#{Regexp.escape(File.dirname(__FILE__))}/ - def initialize(name, description, long_description, usage, options = nil, options_relation = nil) - super(name.to_s, description, long_description, usage, options || {}, options_relation || {}) + def initialize(name, description, long_description, wrap_long_description, usage, options = nil, options_relation = nil) + super(name.to_s, description, long_description, wrap_long_description, usage, options || {}, options_relation || {}) end def initialize_copy(other) #:nodoc: @@ -136,7 +136,7 @@ def hidden? # A dynamic command that handles method missing scenarios. class DynamicCommand < Command def initialize(name, options = nil) - super(name.to_s, "A dynamically-generated command", name.to_s, name.to_s, options) + super(name.to_s, "A dynamically-generated command", name.to_s, nil, name.to_s, options) end def run(instance, args = []) diff --git a/spec/command_spec.rb b/spec/command_spec.rb index 7e409933..5efdb392 100644 --- a/spec/command_spec.rb +++ b/spec/command_spec.rb @@ -6,7 +6,7 @@ def command(options = {}, usage = "can_has") options[key] = Thor::Option.parse(key, value) end - @command ||= Thor::Command.new(:can_has, "I can has cheezburger", "I can has cheezburger\nLots and lots of it", usage, options) + @command ||= Thor::Command.new(:can_has, "I can has cheezburger", "I can has cheezburger\nLots and lots of it", nil, usage, options) end describe "#formatted_usage" do @@ -54,7 +54,7 @@ def command(options = {}, usage = "can_has") describe "#dup" do it "dup options hash" do - command = Thor::Command.new("can_has", nil, nil, nil, foo: true, bar: :required) + command = Thor::Command.new("can_has", nil, nil, nil, nil, foo: true, bar: :required) command.dup.options.delete(:foo) expect(command.options[:foo]).to be end diff --git a/spec/fixtures/script.thor b/spec/fixtures/script.thor index 4dab58fe..92fb0cb0 100644 --- a/spec/fixtures/script.thor +++ b/spec/fixtures/script.thor @@ -96,6 +96,18 @@ END def name_with_dashes end + desc "long_description", "a" * 80 + long_desc <<-D, wrap: false +No added indentation, Inline +whatespace not merged, +Linebreaks preserved + and + indentation + too + D + def long_description_unwrapped + end + method_options :all => :boolean method_option :lazy, :lazy_default => "yes" method_option :lazy_numeric, :type => :numeric, :lazy_default => 42 diff --git a/spec/thor_spec.rb b/spec/thor_spec.rb index 4f9108df..4f4852fa 100644 --- a/spec/thor_spec.rb +++ b/spec/thor_spec.rb @@ -642,6 +642,21 @@ def shell HELP end + it "prints long description unwrapped if asked for" do + expect(capture(:stdout) { MyScript.command_help(shell, "long_description_unwrapped") }).to eq(<<-HELP) +Usage: + thor my_script:long_description + +Description: +No added indentation, Inline +whatespace not merged, +Linebreaks preserved + and + indentation + too +HELP + end + it "doesn't assign the long description to the next command without one" do expect(capture(:stdout) do MyScript.command_help(shell, "name_with_dashes")