From 3e2dfe9d431758b2aa0996e304744881dc78825c Mon Sep 17 00:00:00 2001 From: Erik Michaels-Ober Date: Sat, 26 Nov 2016 10:21:02 -0800 Subject: [PATCH] Update RuboCop --- .rubocop.yml | 171 ++++++++++++++---- .travis.yml | 2 + Gemfile | 42 ++--- lib/thor.rb | 43 +++-- lib/thor/actions.rb | 43 +++-- lib/thor/actions/create_file.rb | 2 +- lib/thor/actions/create_link.rb | 2 +- lib/thor/actions/directory.rb | 4 +- lib/thor/actions/empty_directory.rb | 16 +- lib/thor/actions/file_manipulation.rb | 22 +-- lib/thor/actions/inject_into_file.rb | 24 +-- lib/thor/base.rb | 62 +++---- lib/thor/command.rb | 12 +- .../core_ext/hash_with_indifferent_access.rb | 2 +- lib/thor/core_ext/io_binary_read.rb | 12 +- lib/thor/core_ext/ordered_hash.rb | 2 +- lib/thor/error.rb | 4 +- lib/thor/group.rb | 24 +-- lib/thor/invocation.rb | 9 +- lib/thor/parser/argument.rb | 11 +- lib/thor/parser/arguments.rb | 31 ++-- lib/thor/parser/option.rb | 65 +++---- lib/thor/parser/options.rb | 12 +- lib/thor/runner.rb | 50 ++--- lib/thor/shell.rb | 2 +- lib/thor/shell/basic.rb | 58 +++--- lib/thor/shell/color.rb | 2 +- lib/thor/shell/html.rb | 8 +- lib/thor/util.rb | 15 +- spec/actions/create_file_spec.rb | 8 +- spec/actions/directory_spec.rb | 14 +- spec/actions/file_manipulation_spec.rb | 14 +- spec/actions/inject_into_file_spec.rb | 1 - spec/actions_spec.rb | 2 +- spec/base_spec.rb | 32 ++-- spec/command_spec.rb | 1 + .../hash_with_indifferent_access_spec.rb | 5 +- spec/core_ext/ordered_hash_spec.rb | 2 +- spec/exit_condition_spec.rb | 2 +- spec/fixtures/help.thor | 13 ++ spec/group_spec.rb | 32 ++-- spec/helper.rb | 6 +- spec/invocation_spec.rb | 13 +- spec/line_editor/readline_spec.rb | 6 +- spec/parser/argument_spec.rb | 1 - spec/parser/arguments_spec.rb | 2 +- spec/parser/option_spec.rb | 6 +- spec/parser/options_spec.rb | 66 ++++--- spec/quality_spec.rb | 22 +-- spec/rake_compat_spec.rb | 6 +- spec/register_spec.rb | 47 +++-- spec/runner_spec.rb | 74 ++++---- spec/shell/basic_spec.rb | 18 +- spec/shell/color_spec.rb | 3 +- spec/shell_spec.rb | 1 - spec/subcommand_spec.rb | 25 ++- spec/thor_spec.rb | 153 ++++++++-------- spec/util_spec.rb | 8 +- thor.gemspec | 10 +- 59 files changed, 722 insertions(+), 623 deletions(-) create mode 100644 spec/fixtures/help.thor diff --git a/.rubocop.yml b/.rubocop.yml index 38fa430cf..c7b3e949c 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,44 +1,41 @@ AllCops: - Includes: - - 'Gemfile' - - 'Thorfile' - - 'thor.gemspec' - -# Avoid long parameter lists -ParameterLists: - Max: 5 + TargetRubyVersion: 2.2 + +Metrics/ParameterLists: + Max: 6 CountKeywordArgs: true -MethodLength: +Metrics/MethodLength: + Max: 25 CountComments: false + +Metrics/AbcSize: + Enabled: false + +Metrics/ClassLength: + Max: 300 + +Metrics/ModuleLength: + Max: 300 + +Metrics/BlockLength: + Max: 30 + +Metrics/CyclomaticComplexity: + Max: 12 + +Metrics/PerceivedComplexity: Max: 15 -# Avoid more than `Max` levels of nesting. BlockNesting: Max: 4 -# Align with the style guide. -CollectionMethods: - PreferredMethods: - collect: 'map' - inject: 'reduce' - find: 'detect' - find_all: 'select' - -# Do not force public/protected/private keyword to be indented at the same -# level as the def keyword. My personal preference is to outdent these keywords -# because I think when scanning code it makes it easier to identify the -# sections of code and visually separate them. When the keyword is at the same -# level I think it sort of blends in with the def keywords and makes it harder -# to scan the code and see where the sections are. -AccessModifierIndentation: +Metrics/LineLength: Enabled: false -# Limit line length -LineLength: +AccessModifierIndentation: Enabled: false -# Disable documentation checking until a class needs to be documented once Documentation: Enabled: false @@ -77,17 +74,111 @@ CaseIndentation: DoubleNegation: Enabled: false -PercentLiteralDelimiters: - PreferredDelimiters: - '%': () - '%i': () - '%q': () - '%Q': () - '%r': '{}' - '%s': () - '%w': '[]' - '%W': '[]' - '%x': () - StringLiterals: EnforcedStyle: double_quotes + +Style/SymbolLiteral: + Enabled: false + +Lint/AssignmentInCondition: + Exclude: + - 'lib/thor/line_editor/readline.rb' + - 'lib/thor/parser/arguments.rb' + +Lint/EndAlignment: + Exclude: + - 'lib/thor/actions.rb' + - 'lib/thor/parser/option.rb' + +Lint/Eval: + Exclude: + - 'spec/helper.rb' + +Lint/HandleExceptions: + Exclude: + - 'lib/thor/line_editor/readline.rb' + +Lint/PercentStringArray: + Exclude: + - 'spec/parser/options_spec.rb' + +Lint/UnusedMethodArgument: + Exclude: + - 'lib/thor.rb' + - 'lib/thor/base.rb' + - 'lib/thor/command.rb' + - 'lib/thor/parser/arguments.rb' + - 'lib/thor/shell/html.rb' + - 'spec/actions/empty_directory_spec.rb' + +Style/AccessorMethodName: + Exclude: + - 'lib/thor/line_editor/basic.rb' + +Style/Alias: + Enabled: false + +Style/ClassAndModuleChildren: + Exclude: + - 'lib/thor/group.rb' + - 'lib/thor/runner.rb' + - 'spec/shell_spec.rb' + - 'spec/util_spec.rb' + +Style/ClassVars: + Exclude: + - 'lib/thor/util.rb' + - 'spec/util_spec.rb' + +Style/ConstantName: + Exclude: + - 'spec/line_editor_spec.rb' + +Style/GlobalVars: + Exclude: + - 'bin/thor' + - 'lib/thor.rb' + - 'lib/thor/base.rb' + - 'lib/thor/shell/basic.rb' + - 'spec/helper.rb' + - 'spec/rake_compat_spec.rb' + - 'spec/register_spec.rb' + - 'spec/thor_spec.rb' + +Style/IndentArray: + EnforcedStyle: consistent + +Style/MethodMissing: + Exclude: + - 'lib/thor/core_ext/hash_with_indifferent_access.rb' + - 'lib/thor/runner.rb' + +Style/MutableConstant: + Enabled: false + +Style/NumericLiteralPrefix: + Exclude: + - 'spec/actions/file_manipulation_spec.rb' + +Style/NumericPredicate: + Exclude: + - 'spec/**/*' + - 'lib/thor/parser/option.rb' + +Style/PerlBackrefs: + Exclude: + - 'lib/thor/actions/empty_directory.rb' + - 'lib/thor/core_ext/hash_with_indifferent_access.rb' + - 'lib/thor/parser/arguments.rb' + - 'lib/thor/parser/options.rb' + +Style/TrailingUnderscoreVariable: + Exclude: + - 'lib/thor/group.rb' + +Style/TrailingWhitespace: + Exclude: + - 'spec/shell/basic_spec.rb' + +Style/AlignParameters: + Enabled: false diff --git a/.travis.yml b/.travis.yml index 0e9112a06..8c452731d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,5 @@ +before_install: + - gem install bundler bundler_args: --without development language: ruby rvm: diff --git a/Gemfile b/Gemfile index df05841c4..be6f85e34 100644 --- a/Gemfile +++ b/Gemfile @@ -1,34 +1,34 @@ -source 'https://rubygems.org' +source "https://rubygems.org" -gem 'rake', '< 11' -gem 'rdoc', '~> 4.2.2' # This is to support Ruby 1.8 and 1.9 +gem "rake", "< 11" +gem "rdoc", "~> 4.2.2" # This is to support Ruby 1.8 and 1.9 group :development do - gem 'guard-rspec' - gem 'pry' + gem "guard-rspec" + gem "pry" platforms :ruby_21 do - gem 'pry-byebug' + gem "pry-byebug" end platforms :ruby_19, :ruby_20 do - gem 'pry-debugger' - gem 'pry-stack_explorer' + gem "pry-debugger" + gem "pry-stack_explorer" end end group :test do - gem 'addressable', '~> 2.3.6', :platforms => [:ruby_18] - gem 'childlabor' - gem 'coveralls', '>= 0.5.7' - gem 'json', '< 2' # This is to support Ruby 1.8 and 1.9 - gem 'mime-types', '~> 1.25', :platforms => [:jruby, :ruby_18] - gem 'rest-client', '~> 1.6.0', :platforms => [:jruby, :ruby_18] - gem 'rspec', '>= 3' - gem 'rspec-mocks', '>= 3' - gem 'rubocop', '>= 0.19', :platforms => [:ruby_20, :ruby_21] - gem 'simplecov', '>= 0.9' - gem 'term-ansicolor', '~> 1.3.2' # This is to support Ruby 1.8 and 1.9 - gem 'tins', '< 1.7' # This is to support Ruby 1.8 and 1.9 - gem 'webmock', '>= 1.20', '< 2' # This is to support Ruby 1.8 and 1.9.2 + gem "addressable", "~> 2.3.6", :platforms => [:ruby_18] + gem "childlabor" + gem "coveralls", ">= 0.5.7" + gem "json", "< 2" # This is to support Ruby 1.8 and 1.9 + gem "mime-types", "~> 1.25", :platforms => [:jruby, :ruby_18] + gem "rest-client", "~> 1.6.0", :platforms => [:jruby, :ruby_18] + gem "rspec", ">= 3" + gem "rspec-mocks", ">= 3" + gem "rubocop", ">= 0.19", :platforms => [:ruby_20, :ruby_21, :ruby_22, :ruby_23] + gem "simplecov", ">= 0.9" + gem "term-ansicolor", "~> 1.3.2" # This is to support Ruby 1.8 and 1.9 + gem "tins", "< 1.7" # This is to support Ruby 1.8 and 1.9 + gem "webmock", ">= 1.20", "< 2" # This is to support Ruby 1.8 and 1.9.2 end gemspec diff --git a/lib/thor.rb b/lib/thor.rb index 260286d18..b510d28df 100644 --- a/lib/thor.rb +++ b/lib/thor.rb @@ -1,7 +1,7 @@ require "set" require "thor/base" -class Thor # rubocop:disable ClassLength +class Thor class << self # Allows for custom "Command" package naming. # @@ -9,7 +9,7 @@ class << self # name # options # - def package_name(name, options = {}) + def package_name(name, _ = {}) @package_name = name.nil? || name == "" ? nil : name end @@ -57,7 +57,9 @@ def desc(usage, description, options = {}) command.usage = usage if usage command.description = description if description else - @usage, @desc, @hide = usage, description, options[:hide] || false + @usage = usage + @desc = description + @hide = options[:hide] || false end end @@ -235,10 +237,8 @@ def subcommand(subcommand, subcommand_class) define_method(subcommand) do |*args| args, opts = Thor::Arguments.split(args) - invoke_args = [args, opts, { :invoked_via_subcommand => true, :class_options => options }] - if opts.delete('--help') or opts.delete("-h") - invoke_args.unshift 'help' - end + invoke_args = [args, opts, {:invoked_via_subcommand => true, :class_options => options}] + invoke_args.unshift "help" if opts.delete("--help") || opts.delete("-h") invoke subcommand_class, *invoke_args end end @@ -327,6 +327,7 @@ def stop_on_unknown_option?(command) #:nodoc: end protected + def stop_on_unknown_option #:nodoc: @stop_on_unknown_option ||= Set.new end @@ -352,12 +353,14 @@ def dispatch(meth, given_args, given_opts, config) #:nodoc: # rubocop:disable Me opts.clear end else - args, opts = given_args, nil + args = given_args + opts = nil command = dynamic_command_class.new(meth) end opts = given_opts || opts || [] - config.merge!(:current_command => command, :command_options => command.options) + config[:current_command] = command + config[:command_options] = command.options instance = new(args, opts, config) yield instance if block_given? @@ -397,8 +400,8 @@ def create_command(meth) #:nodoc: elsif all_commands[meth] || meth == "method_missing" true else - puts "[WARNING] Attempted to create command #{meth.inspect} without usage or description. " << - "Call desc if you want this method to be available as command or declare it inside a " << + puts "[WARNING] Attempted to create command #{meth.inspect} 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 #{caller[1].inspect}." false end @@ -413,11 +416,7 @@ def initialize_added #:nodoc: # Retrieve the command name from given args. def retrieve_command_name(args) #:nodoc: meth = args.first.to_s unless args.empty? - if meth && (map[meth] || meth !~ /^\-/) - args.shift - else - nil - end + args.shift if meth && (map[meth] || meth !~ /^\-/) end alias_method :retrieve_task_name, :retrieve_command_name @@ -429,20 +428,20 @@ def retrieve_command_name(args) #:nodoc: # +normalize_command_name+ also converts names like +animal-prison+ # into +animal_prison+. def normalize_command_name(meth) #:nodoc: - return default_command.to_s.gsub("-", "_") unless meth + return default_command.to_s.tr("-", "_") unless meth possibilities = find_command_possibilities(meth) - if possibilities.size > 1 - fail AmbiguousTaskError, "Ambiguous command #{meth} matches [#{possibilities.join(', ')}]" - elsif possibilities.size < 1 - meth = meth || default_command + raise AmbiguousTaskError, "Ambiguous command #{meth} matches [#{possibilities.join(', ')}]" if possibilities.size > 1 + + if possibilities.empty? + meth ||= default_command elsif map[meth] meth = map[meth] else meth = possibilities.first end - meth.to_s.gsub("-", "_") # treat foo-bar as foo_bar + meth.to_s.tr("-", "_") # treat foo-bar as foo_bar end alias_method :normalize_task_name, :normalize_command_name diff --git a/lib/thor/actions.rb b/lib/thor/actions.rb index b08046bbf..0a6f55dbd 100644 --- a/lib/thor/actions.rb +++ b/lib/thor/actions.rb @@ -73,14 +73,15 @@ def add_runtime_options! # def initialize(args = [], options = {}, config = {}) self.behavior = case config[:behavior].to_s - when "force", "skip" - _cleanup_options_and_set(options, config[:behavior]) - :invoke - when "revoke" - :revoke - else - :invoke - end + when "force", "skip" + _cleanup_options_and_set(options, config[:behavior]) + :invoke + when "revoke" + :revoke + else + :invoke + end + super self.destination_root = config[:destination_root] end @@ -129,7 +130,7 @@ def source_paths # Receives a file or directory and search for it in the source paths. # - def find_in_source_paths(file) # rubocop:disable MethodLength + def find_in_source_paths(file) possible_files = [file, file + TEMPLATE_EXTNAME] relative_root = relative_to_original_destination_root(destination_root, false) @@ -146,13 +147,13 @@ def find_in_source_paths(file) # rubocop:disable MethodLength message << "Please invoke #{self.class.name}.source_root(PATH) with the PATH containing your templates. " end - if source_paths.empty? - message << "Currently you have no source paths." - else - message << "Your current source paths are: \n#{source_paths.join("\n")}" - end + message << if source_paths.empty? + "Currently you have no source paths." + else + "Your current source paths are: \n#{source_paths.join("\n")}" + end - fail Error, message + raise Error, message end # Do something in the root or on a provided subfolder. If a relative path @@ -214,10 +215,10 @@ def apply(path, config = {}) say_status :apply, path, verbose shell.padding += 1 if verbose - if is_uri - contents = open(path, "Accept" => "application/x-thor-template") { |io| io.read } + contents = if is_uri + open(path, "Accept" => "application/x-thor-template", &:read) else - contents = open(path) { |io| io.read } + open(path, &:read) end instance_eval(contents, path) @@ -250,9 +251,7 @@ def run(command, config = {}) say_status :run, desc, config.fetch(:verbose, true) - unless options[:pretend] - config[:capture] ? `#{command}` : system("#{command}") - end + !options[:pretend] && config[:capture] ? `#{command}` : system(command.to_s) end # Executes a ruby script (taking into account WIN32 platform quirks). @@ -308,7 +307,7 @@ def _shared_configuration #:nodoc: def _cleanup_options_and_set(options, key) #:nodoc: case options when Array - %w[--force -f --skip -s].each { |i| options.delete(i) } + %w(--force -f --skip -s).each { |i| options.delete(i) } options << "--#{key}" when Hash [:force, :skip, "force", "skip"].each { |i| options.delete(i) } diff --git a/lib/thor/actions/create_file.rb b/lib/thor/actions/create_file.rb index fcea39229..483706de2 100644 --- a/lib/thor/actions/create_file.rb +++ b/lib/thor/actions/create_file.rb @@ -84,7 +84,7 @@ def on_conflict_behavior(&block) def force_or_skip_or_conflict(force, skip, &block) if force say_status :force, :yellow - block.call unless pretend? + yield unless pretend? elsif skip say_status :skip, :yellow else diff --git a/lib/thor/actions/create_link.rb b/lib/thor/actions/create_link.rb index db2c2a828..120fcfc71 100644 --- a/lib/thor/actions/create_link.rb +++ b/lib/thor/actions/create_link.rb @@ -14,7 +14,7 @@ module Actions # # create_link "config/apache.conf", "/etc/apache.conf" # - def create_link(destination, *args, &block) + def create_link(destination, *args) config = args.last.is_a?(Hash) ? args.pop : {} source = args.first action CreateLink.new(self, destination, source, config) diff --git a/lib/thor/actions/directory.rb b/lib/thor/actions/directory.rb index 9c44cfbf3..3e98f6248 100644 --- a/lib/thor/actions/directory.rb +++ b/lib/thor/actions/directory.rb @@ -72,7 +72,7 @@ def revoke! protected - def execute! # rubocop:disable MethodLength + def execute! lookup = Util.escape_globs(source) lookup = config[:recursive] ? File.join(lookup, "**") : lookup lookup = file_level_lookup(lookup) @@ -85,7 +85,7 @@ def execute! # rubocop:disable MethodLength case file_source when /\.empty_directory$/ - dirname = File.dirname(file_destination).gsub(/\/\.$/, "") + dirname = File.dirname(file_destination).gsub(%r{/\.$}, "") next if dirname == given_destination base.empty_directory(dirname, config) when /#{TEMPLATE_EXTNAME}$/ diff --git a/lib/thor/actions/empty_directory.rb b/lib/thor/actions/empty_directory.rb index 281d8fb2f..2e544a117 100644 --- a/lib/thor/actions/empty_directory.rb +++ b/lib/thor/actions/empty_directory.rb @@ -32,7 +32,8 @@ class EmptyDirectory #:nodoc: # config:: give :verbose => false to not log the status. # def initialize(base, destination, config = {}) - @base, @config = base, {:verbose => true}.merge(config) + @base = base + @config = {:verbose => true}.merge(config) self.destination = destination end @@ -80,11 +81,10 @@ def pretend? # given_destination #=> baz # def destination=(destination) - if destination - @given_destination = convert_encoded_instructions(destination.to_s) - @destination = ::File.expand_path(@given_destination, base.destination_root) - @relative_destination = base.relative_to_original_destination_root(@destination) - end + return unless destination + @given_destination = convert_encoded_instructions(destination.to_s) + @destination = ::File.expand_path(@given_destination, base.destination_root) + @relative_destination = base.relative_to_original_destination_root(@destination) end # Filenames in the encoded form are converted. If you have a file: @@ -113,7 +113,7 @@ def invoke_with_conflict_check(&block) on_conflict_behavior(&block) else say_status :create, :green - block.call unless pretend? + yield unless pretend? end destination @@ -121,7 +121,7 @@ def invoke_with_conflict_check(&block) # What to do when the destination file already exists. # - def on_conflict_behavior(&block) + def on_conflict_behavior say_status :exist, :blue end diff --git a/lib/thor/actions/file_manipulation.rb b/lib/thor/actions/file_manipulation.rb index cb4219a8c..c4a93d50a 100644 --- a/lib/thor/actions/file_manipulation.rb +++ b/lib/thor/actions/file_manipulation.rb @@ -26,7 +26,7 @@ def copy_file(source, *args, &block) create_file destination, nil, config do content = File.binread(source) - content = block.call(content) if block + content = yield(content) if block content end if config[:mode] == :preserve @@ -49,7 +49,7 @@ def copy_file(source, *args, &block) # # link_file "doc/README" # - def link_file(source, *args, &block) + def link_file(source, *args) config = args.last.is_a?(Hash) ? args.pop : {} destination = args.first || source source = File.expand_path(find_in_source_paths(source.to_s)) @@ -82,7 +82,7 @@ def get(source, *args, &block) render = open(source) { |input| input.binmode.read } destination ||= if block_given? - block.arity == 1 ? block.call(render) : block.call + block.arity == 1 ? yield(render) : yield else File.basename(source) end @@ -114,7 +114,7 @@ def template(source, *args, &block) create_file destination, nil, config do content = CapturableERB.new(::File.binread(source), nil, "-", "@output_buffer").result(context) - content = block.call(content) if block + content = yield(content) if block content end end @@ -154,7 +154,7 @@ def chmod(path, mode, config = {}) # def prepend_to_file(path, *args, &block) config = args.last.is_a?(Hash) ? args.pop : {} - config.merge!(:after => /\A/) + config[:after] = /\A/ insert_into_file(path, *(args << config), &block) end alias_method :prepend_file, :prepend_to_file @@ -176,7 +176,7 @@ def prepend_to_file(path, *args, &block) # def append_to_file(path, *args, &block) config = args.last.is_a?(Hash) ? args.pop : {} - config.merge!(:before => /\z/) + config[:before] = /\z/ insert_into_file(path, *(args << config), &block) end alias_method :append_file, :append_to_file @@ -200,7 +200,7 @@ def append_to_file(path, *args, &block) # def inject_into_class(path, klass, *args, &block) config = args.last.is_a?(Hash) ? args.pop : {} - config.merge!(:after => /class #{klass}\n|class #{klass} .*\n/) + config[:after] = /class #{klass}\n|class #{klass} .*\n/ insert_into_file(path, *(args << config), &block) end @@ -285,7 +285,7 @@ def comment_lines(path, flag, *args) # def remove_file(path, config = {}) return unless behavior == :invoke - path = File.expand_path(path, destination_root) + path = File.expand_path(path, destination_root) say_status :remove, relative_to_original_destination_root(path), config.fetch(:verbose, true) ::FileUtils.rm_rf(path) if !options[:pretend] && File.exist?(path) @@ -301,8 +301,8 @@ def concat(string) @output_buffer.concat(string) end - def capture(*args, &block) - with_output_buffer { block.call(*args) } + def capture(*args) + with_output_buffer { yield(*args) } end def with_output_buffer(buf = "") #:nodoc: @@ -316,7 +316,7 @@ def with_output_buffer(buf = "") #:nodoc: # Thor::Actions#capture depends on what kind of buffer is used in ERB. # Thus CapturableERB fixes ERB to use String buffer. class CapturableERB < ERB - def set_eoutvar(compiler, eoutvar = '_erbout') + def set_eoutvar(compiler, eoutvar = "_erbout") compiler.put_cmd = "#{eoutvar}.concat" compiler.insert_cmd = "#{eoutvar}.concat" compiler.pre_cmd = ["#{eoutvar} = ''"] diff --git a/lib/thor/actions/inject_into_file.rb b/lib/thor/actions/inject_into_file.rb index d617efb68..20315edeb 100644 --- a/lib/thor/actions/inject_into_file.rb +++ b/lib/thor/actions/inject_into_file.rb @@ -22,11 +22,8 @@ module Actions # end # def insert_into_file(destination, *args, &block) - if block_given? - data, config = block, args.shift - else - data, config = args.shift, args.shift - end + data = block_given? ? block : args.shift + config = args.shift action InjectIntoFile.new(self, destination, data, config) end alias_method :inject_into_file, :insert_into_file @@ -39,9 +36,9 @@ def initialize(base, destination, data, config) @behavior, @flag = if @config.key?(:after) [:after, @config.delete(:after)] - else - [:before, @config.delete(:before)] - end + else + [:before, @config.delete(:before)] + end @replacement = data.is_a?(Proc) ? data.call : data @flag = Regexp.escape(@flag) unless @flag.is_a?(Regexp) @@ -94,12 +91,11 @@ def say_status(behavior) # Adds the content to the file. # def replace!(regexp, string, force) - unless base.options[:pretend] - content = File.binread(destination) - if force || !content.include?(replacement) - content.gsub!(regexp, string) - File.open(destination, "wb") { |file| file.write(content) } - end + return if base.options[:pretend] + content = File.binread(destination) + if force || !content.include?(replacement) + content.gsub!(regexp, string) + File.open(destination, "wb") { |file| file.write(content) } end end end diff --git a/lib/thor/base.rb b/lib/thor/base.rb index 8cd418637..506d9f850 100644 --- a/lib/thor/base.rb +++ b/lib/thor/base.rb @@ -14,11 +14,11 @@ class Thor autoload :Group, "thor/group" # Shortcuts for help. - HELP_MAPPINGS = %w[-h -? --help -D] + HELP_MAPPINGS = %w(-h -? --help -D) # Thor methods that should not be overwritten by the user. - THOR_RESERVED_WORDS = %w[invoke shell options behavior root destination_root relative_root - action add_file create_file in_root inside run run_ruby_script] + THOR_RESERVED_WORDS = %w(invoke shell options behavior root destination_root relative_root + action add_file create_file in_root inside run run_ruby_script) TEMPLATE_EXTNAME = ".tt" @@ -41,7 +41,7 @@ module Base # # config:: Configuration for this Thor class. # - def initialize(args = [], local_options = {}, config = {}) # rubocop:disable MethodLength + def initialize(args = [], local_options = {}, config = {}) parse_options = config[:current_command] && config[:current_command].disable_class_options ? {} : self.class.class_options # The start method splits inbound arguments at the first argument @@ -52,11 +52,13 @@ def initialize(args = [], local_options = {}, config = {}) # rubocop:disable Met command_options = config.delete(:command_options) # hook for start parse_options = parse_options.merge(command_options) if command_options if local_options.is_a?(Array) - array_options, hash_options = local_options, {} + array_options = local_options + hash_options = {} else # Handle the case where the class was explicitly instantiated # with pre-parsed options. - array_options, hash_options = [], local_options + array_options = [] + hash_options = local_options end # Let Thor::Options parse the options first, so it can remove @@ -205,8 +207,8 @@ def strict_args_position?(config) #:nodoc: # ==== Errors # ArgumentError:: Raised if you supply a required argument after a non required one. # - def argument(name, options = {}) # rubocop:disable MethodLength - is_thor_reserved_word?(name, :argument) + def argument(name, options = {}) + thor_reserved_word?(name, :argument) no_commands { attr_accessor name } required = if options.key?(:optional) @@ -219,11 +221,13 @@ def argument(name, options = {}) # rubocop:disable MethodLength remove_argument name - arguments.each do |argument| - next if argument.required? - fail ArgumentError, "You cannot have #{name.to_s.inspect} as required argument after " << - "the non-required argument #{argument.human_name.inspect}." - end if required + if required + arguments.each do |argument| + next if argument.required? + raise ArgumentError, "You cannot have #{name.to_s.inspect} as required argument after " \ + "the non-required argument #{argument.human_name.inspect}." + end + end options[:required] = required @@ -467,11 +471,8 @@ def public_command(*names) alias_method :public_task, :public_command def handle_no_command_error(command, has_namespace = $thor_runner) #:nodoc: - if has_namespace - fail UndefinedCommandError, "Could not find command #{command.inspect} in #{namespace.inspect} namespace." - else - fail UndefinedCommandError, "Could not find command #{command.inspect}." - end + raise UndefinedCommandError, "Could not find command #{command.inspect} in #{namespace.inspect} namespace." if has_namespace + raise UndefinedCommandError, "Could not find command #{command.inspect}." end alias_method :handle_no_task_error, :handle_no_command_error @@ -480,7 +481,7 @@ def handle_argument_error(command, error, args, arity) #:nodoc: msg << "no arguments" if args.empty? msg << "arguments " << args.inspect unless args.empty? msg << "\nUsage: #{banner(command).inspect}" - fail InvocationError, msg + raise InvocationError, msg end protected @@ -513,14 +514,13 @@ def print_options(shell, options, group_name = nil) padding = options.map { |o| o.aliases.size }.max.to_i * 4 options.each do |option| - unless option.hide - item = [option.usage(padding)] - item.push(option.description ? "# #{option.description}" : "") + next if option.hide + item = [option.usage(padding)] + item.push(option.description ? "# #{option.description}" : "") - list << item - list << ["", "# Default: #{option.default}"] if option.show_default? - list << ["", "# Possible values: #{option.enum.join(', ')}"] if option.enum - end + list << item + list << ["", "# Default: #{option.default}"] if option.show_default? + list << ["", "# Possible values: #{option.enum.join(', ')}"] if option.enum end shell.say(group_name ? "#{group_name} options:" : "Options:") @@ -529,9 +529,9 @@ def print_options(shell, options, group_name = nil) end # Raises an error if the word given is a Thor reserved word. - def is_thor_reserved_word?(word, type) #:nodoc: + def thor_reserved_word?(word, type) #:nodoc: return false unless THOR_RESERVED_WORDS.include?(word.to_s) - fail "#{word.inspect} is a Thor reserved word and cannot be defined as #{type}" + raise "#{word.inspect} is a Thor reserved word and cannot be defined as #{type}" end # Build an option and adds it to the given scope. @@ -566,7 +566,7 @@ def find_and_refresh_command(name) #:nodoc: elsif command = all_commands[name.to_s] # rubocop:disable AssignmentInCondition commands[name.to_s] = command.clone else - fail ArgumentError, "You supplied :for => #{name.inspect}, but the command #{name.inspect} could not be found." + raise ArgumentError, "You supplied :for => #{name.inspect}, but the command #{name.inspect} could not be found." end end alias_method :find_and_refresh_task, :find_and_refresh_command @@ -594,7 +594,7 @@ def method_added(meth) @no_commands ||= false return if @no_commands || !create_command(meth) - is_thor_reserved_word?(meth, :command) + thor_reserved_word?(meth, :command) Thor::Base.register_klass_file(self) end @@ -649,7 +649,7 @@ def initialize_added #:nodoc: # SIGNATURE: The hook invoked by start. def dispatch(command, given_args, given_opts, config) #:nodoc: - fail NotImplementedError + raise NotImplementedError end end end diff --git a/lib/thor/command.rb b/lib/thor/command.rb index bf4ac7840..ceda59170 100644 --- a/lib/thor/command.rb +++ b/lib/thor/command.rb @@ -33,7 +33,7 @@ def run(instance, args = []) rescue ArgumentError => e handle_argument_error?(instance, e, caller) ? instance.class.handle_argument_error(self, e, args, arity) : (raise e) rescue NoMethodError => e - handle_no_method_error?(instance, e, caller) ? instance.class.handle_no_command_error(name) : (fail e) + handle_no_method_error?(instance, e, caller) ? instance.class.handle_no_command_error(name) : (raise e) end # Returns the formatted usage by injecting given required arguments @@ -50,7 +50,7 @@ def formatted_usage(klass, namespace = true, subcommand = false) # Add usage with required arguments formatted << if klass && !klass.arguments.empty? usage.to_s.gsub(/^#{name}/) do |match| - match << " " << klass.arguments.map { |a| a.usage }.compact.join(" ") + match << " " << klass.arguments.map(&:usage).compact.join(" ") end else usage.to_s @@ -88,7 +88,7 @@ def local_method?(instance, name) end def sans_backtrace(backtrace, caller) #:nodoc: - saned = backtrace.reject { |frame| frame =~ FILE_REGEXP || (frame =~ /\.java:/ && RUBY_PLATFORM =~ /java/) || (frame =~ /^kernel\// && RUBY_ENGINE =~ /rbx/) } + saned = backtrace.reject { |frame| frame =~ FILE_REGEXP || (frame =~ /\.java:/ && RUBY_PLATFORM =~ /java/) || (frame =~ %r{^kernel/} && RUBY_ENGINE =~ /rbx/) } saned - caller end @@ -105,7 +105,7 @@ def handle_no_method_error?(instance, error, caller) error.message =~ /^undefined method `#{name}' for #{Regexp.escape(instance.to_s)}$/ end end - Task = Command # rubocop:disable ConstantName + Task = Command # A command that is hidden in help messages but still invocable. class HiddenCommand < Command @@ -113,7 +113,7 @@ def hidden? true end end - HiddenTask = HiddenCommand # rubocop:disable ConstantName + HiddenTask = HiddenCommand # A dynamic command that handles method missing scenarios. class DynamicCommand < Command @@ -129,5 +129,5 @@ def run(instance, args = []) end end end - DynamicTask = DynamicCommand # rubocop:disable ConstantName + DynamicTask = DynamicCommand end diff --git a/lib/thor/core_ext/hash_with_indifferent_access.rb b/lib/thor/core_ext/hash_with_indifferent_access.rb index 9e433ca76..66f62415c 100644 --- a/lib/thor/core_ext/hash_with_indifferent_access.rb +++ b/lib/thor/core_ext/hash_with_indifferent_access.rb @@ -68,7 +68,7 @@ def convert_key(key) # options.shebang # => "/usr/lib/local/ruby" # options.test_framework?(:rspec) # => options[:test_framework] == :rspec # - def method_missing(method, *args, &block) + def method_missing(method, *args) method = method.to_s if method =~ /^(\w+)\?$/ if args.empty? diff --git a/lib/thor/core_ext/io_binary_read.rb b/lib/thor/core_ext/io_binary_read.rb index 19f3c3d43..0f6e2e0af 100644 --- a/lib/thor/core_ext/io_binary_read.rb +++ b/lib/thor/core_ext/io_binary_read.rb @@ -1,10 +1,12 @@ class IO #:nodoc: class << self - def binread(file, *args) - fail ArgumentError, "wrong number of arguments (#{1 + args.size} for 1..3)" unless args.size < 3 - File.open(file, "rb") do |f| - f.read(*args) + unless method_defined? :binread + def binread(file, *args) + raise ArgumentError, "wrong number of arguments (#{1 + args.size} for 1..3)" unless args.size < 3 + File.open(file, "rb") do |f| + f.read(*args) + end end - end unless method_defined? :binread + end end end diff --git a/lib/thor/core_ext/ordered_hash.rb b/lib/thor/core_ext/ordered_hash.rb index db8bbb0c3..778772f3d 100644 --- a/lib/thor/core_ext/ordered_hash.rb +++ b/lib/thor/core_ext/ordered_hash.rb @@ -118,7 +118,7 @@ def inspect "#<#{self.class} #{super}>" end - private + private def sync_keys! @keys.delete_if { |k| !key?(k) } diff --git a/lib/thor/error.rb b/lib/thor/error.rb index 834d9938c..9910bfb2e 100644 --- a/lib/thor/error.rb +++ b/lib/thor/error.rb @@ -11,11 +11,11 @@ class Error < StandardError # Raised when a command was not found. class UndefinedCommandError < Error end - UndefinedTaskError = UndefinedCommandError # rubocop:disable ConstantName + UndefinedTaskError = UndefinedCommandError class AmbiguousCommandError < Error end - AmbiguousTaskError = AmbiguousCommandError # rubocop:disable ConstantName + AmbiguousTaskError = AmbiguousCommandError # Raised when a command was found, but not invoked properly. class InvocationError < Error diff --git a/lib/thor/group.rb b/lib/thor/group.rb index c4ee890d9..dd435475e 100644 --- a/lib/thor/group.rb +++ b/lib/thor/group.rb @@ -4,7 +4,7 @@ # is that it invokes all commands at once. It also include some methods that allows # invocations to be done at the class method, which are not available to Thor # commands. -class Thor::Group # rubocop:disable ClassLength +class Thor::Group class << self # The description for this Thor::Group. If none is provided, but a source root # exists, tries to find the USAGE one folder above it, otherwise searches @@ -53,7 +53,7 @@ def invocation_blocks #:nodoc: # The namespace/class given will have its options showed on the help # usage. Check invoke_from_option for more information. # - def invoke(*names, &block) # rubocop:disable MethodLength + def invoke(*names, &block) options = names.last.is_a?(Hash) ? names.pop : {} verbose = options.fetch(:verbose, true) @@ -62,7 +62,7 @@ def invoke(*names, &block) # rubocop:disable MethodLength invocation_blocks[name] = block if block_given? class_eval <<-METHOD, __FILE__, __LINE__ - def _invoke_#{name.to_s.gsub(/\W/, "_")} + def _invoke_#{name.to_s.gsub(/\W/, '_')} klass, command = self.class.prepare_for_invocation(nil, #{name.inspect}) if klass @@ -107,21 +107,21 @@ def _invoke_#{name.to_s.gsub(/\W/, "_")} # invoked. The block receives two parameters, an instance of the current # class and the klass to be invoked. # - def invoke_from_option(*names, &block) # rubocop:disable MethodLength + def invoke_from_option(*names, &block) options = names.last.is_a?(Hash) ? names.pop : {} verbose = options.fetch(:verbose, :white) names.each do |name| unless class_options.key?(name) - fail ArgumentError, "You have to define the option #{name.inspect} " << - "before setting invoke_from_option." + raise ArgumentError, "You have to define the option #{name.inspect} " \ + "before setting invoke_from_option." end invocations[name] = true invocation_blocks[name] = block if block_given? class_eval <<-METHOD, __FILE__, __LINE__ - def _invoke_from_option_#{name.to_s.gsub(/\W/, "_")} + def _invoke_from_option_#{name.to_s.gsub(/\W/, '_')} return unless options[#{name.inspect}] value = options[#{name.inspect}] @@ -188,7 +188,7 @@ def get_options_from_invocations(group_options, base_options) #:nodoc: # rubocop group_options[human_name] ||= [] group_options[human_name] += klass.class_options.values.select do |class_option| base_options[class_option.name.to_sym].nil? && class_option.group.nil? && - !group_options.values.flatten.any? { |i| i.name == class_option.name } + !group_options.values.flatten.any? { |i| i.name == class_option.name } end yield klass if block_given? @@ -204,11 +204,11 @@ def printable_commands(*) end alias_method :printable_tasks, :printable_commands - def handle_argument_error(command, error, args, arity) #:nodoc: + def handle_argument_error(command, error, _args, arity) #:nodoc: msg = "#{basename} #{command.name} takes #{arity} argument" msg << "s" if arity > 1 msg << ", but it should not." - fail error, msg + raise error, msg end protected @@ -267,9 +267,9 @@ def _invoke_for_class_method(klass, command = nil, *args, &block) #:nodoc: if block case block.arity when 3 - block.call(self, klass, command) + yield(self, klass, command) when 2 - block.call(self, klass) + yield(self, klass) when 1 instance_exec(klass, &block) end diff --git a/lib/thor/invocation.rb b/lib/thor/invocation.rb index 108c70439..b1114098f 100644 --- a/lib/thor/invocation.rb +++ b/lib/thor/invocation.rb @@ -108,8 +108,8 @@ def invoke(name = nil, *args) command, args, opts, config = args klass, command = _retrieve_class_and_command(name, command) - fail "Missing Thor class for invoke #{name}" unless klass - fail "Expected Thor class, got #{klass}" unless klass <= Thor::Base + raise "Missing Thor class for invoke #{name}" unless klass + raise "Expected Thor class, got #{klass}" unless klass <= Thor::Base args, opts, config = _parse_initialization_options(args, opts, config) klass.send(:dispatch, command, args, opts, config) do |instance| @@ -150,10 +150,9 @@ def _shared_configuration #:nodoc: # use the given name and return self as class. Otherwise, call # prepare_for_invocation in the current class. def _retrieve_class_and_command(name, sent_command = nil) #:nodoc: - case - when name.nil? + if name.nil? [self.class, nil] - when self.class.all_commands[name.to_s] + elsif self.class.all_commands[name.to_s] [self.class, name.to_s] else klass, command = self.class.prepare_for_invocation(nil, name) diff --git a/lib/thor/parser/argument.rb b/lib/thor/parser/argument.rb index 96f0eff78..7b628ef23 100644 --- a/lib/thor/parser/argument.rb +++ b/lib/thor/parser/argument.rb @@ -10,8 +10,8 @@ def initialize(name, options = {}) type = options[:type] - fail ArgumentError, "#{class_name} name can't be nil." if name.nil? - fail ArgumentError, "Type :#{type} is not valid for #{class_name.downcase}s." if type && !valid_type?(type) + raise ArgumentError, "#{class_name} name can't be nil." if name.nil? + raise ArgumentError, "Type :#{type} is not valid for #{class_name.downcase}s." if type && !valid_type?(type) @name = name.to_s @description = options[:desc] @@ -44,11 +44,8 @@ def show_default? protected def validate! - if required? && !default.nil? - fail ArgumentError, "An argument cannot be required and have default value." - elsif @enum && !@enum.is_a?(Array) - fail ArgumentError, "An argument cannot have an enum other than an array." - end + raise ArgumentError, "An argument cannot be required and have default value." if required? && !default.nil? + raise ArgumentError, "An argument cannot have an enum other than an array." if @enum && !@enum.is_a?(Array) end def valid_type?(type) diff --git a/lib/thor/parser/arguments.rb b/lib/thor/parser/arguments.rb index 558e763b2..522f1f889 100644 --- a/lib/thor/parser/arguments.rb +++ b/lib/thor/parser/arguments.rb @@ -24,7 +24,8 @@ def self.parse(*args) # Takes an array of Thor::Argument objects. # def initialize(arguments = []) - @assigns, @non_assigned_required = {}, [] + @assigns = {} + @non_assigned_required = [] @switches = arguments arguments.each do |argument| @@ -49,7 +50,7 @@ def parse(args) @assigns end - def remaining # rubocop:disable TrivialAccessors + def remaining @pile end @@ -73,7 +74,7 @@ def shift end def unshift(arg) - if arg.kind_of?(Array) + if arg.is_a?(Array) @pile = arg + @pile else @pile.unshift(arg) @@ -99,7 +100,7 @@ def parse_hash(name) while current_is_value? && peek.include?(":") key, value = shift.split(":", 2) - fail MalformattedArgumentError, "You can't specify '#{key}' more than once in option '#{name}'; got #{key}:#{hash[key]} and #{key}:#{value}" if hash.include? key + raise MalformattedArgumentError, "You can't specify '#{key}' more than once in option '#{name}'; got #{key}:#{hash[key]} and #{key}:#{value}" if hash.include? key hash[key] = value end hash @@ -129,13 +130,13 @@ def parse_numeric(name) return shift if peek.is_a?(Numeric) unless peek =~ NUMERIC && $& == peek - fail MalformattedArgumentError, "Expected numeric value for '#{name}'; got #{peek.inspect}" + raise MalformattedArgumentError, "Expected numeric value for '#{name}'; got #{peek.inspect}" end value = $&.index(".") ? shift.to_f : shift.to_i if @switches.is_a?(Hash) && switch = @switches[name] if switch.enum && !switch.enum.include?(value) - fail MalformattedArgumentError, "Expected '#{name}' to be one of #{switch.enum.join(', ')}; got #{value}" + raise MalformattedArgumentError, "Expected '#{name}' to be one of #{switch.enum.join(', ')}; got #{value}" end end value @@ -151,9 +152,9 @@ def parse_string(name) nil else value = shift - if @switches.is_a?(Hash) && switch = @switches[name] # rubocop:disable AssignmentInCondition + if @switches.is_a?(Hash) && switch = @switches[name] if switch.enum && !switch.enum.include?(value) - fail MalformattedArgumentError, "Expected '#{name}' to be one of #{switch.enum.join(', ')}; got #{value}" + raise MalformattedArgumentError, "Expected '#{name}' to be one of #{switch.enum.join(', ')}; got #{value}" end end value @@ -163,14 +164,12 @@ def parse_string(name) # Raises an error if @non_assigned_required array is not empty. # def check_requirement! - unless @non_assigned_required.empty? - names = @non_assigned_required.map do |o| - o.respond_to?(:switch_name) ? o.switch_name : o.human_name - end.join("', '") - - class_name = self.class.name.split("::").last.downcase - fail RequiredArgumentMissingError, "No value provided for required #{class_name} '#{names}'" - end + return if @non_assigned_required.empty? + names = @non_assigned_required.map do |o| + o.respond_to?(:switch_name) ? o.switch_name : o.human_name + end.join("', '") + class_name = self.class.name.split("::").last.downcase + raise RequiredArgumentMissingError, "No value provided for required #{class_name} '#{names}'" end end end diff --git a/lib/thor/parser/option.rb b/lib/thor/parser/option.rb index ffd906c24..654f7adce 100644 --- a/lib/thor/parser/option.rb +++ b/lib/thor/parser/option.rb @@ -40,31 +40,33 @@ def initialize(name, options = {}) # # By default all options are optional, unless :required is given. # - def self.parse(key, value) # rubocop:disable MethodLength + def self.parse(key, value) if key.is_a?(Array) name, *aliases = key else - name, aliases = key, [] + name = key + aliases = [] end name = name.to_s default = value type = case value - when Symbol - default = nil - if VALID_TYPES.include?(value) - value - elsif required = (value == :required) # rubocop:disable AssignmentInCondition - :string - end - when TrueClass, FalseClass - :boolean - when Numeric - :numeric - when Hash, Array, String - value.class.name.downcase.to_sym - end + when Symbol + default = nil + if VALID_TYPES.include?(value) + value + elsif required = (value == :required) # rubocop:disable AssignmentInCondition + :string + end + when TrueClass, FalseClass + :boolean + when Numeric + :numeric + when Hash, Array, String + value.class.name.downcase.to_sym + end + new(name.to_s, :required => required, :type => type, :default => default, :aliases => aliases) end @@ -86,7 +88,7 @@ def usage(padding = 0) sample = "[#{sample}]" unless required? if boolean? - sample << ", [#{dasherize("no-" + human_name)}]" unless name == "force" or name.start_with?("no-") + sample << ", [#{dasherize('no-' + human_name)}]" unless (name == "force") || name.start_with?("no-") end if aliases.empty? @@ -107,24 +109,25 @@ def #{type}? protected def validate! - fail ArgumentError, "An option cannot be boolean and required." if boolean? && required? + raise ArgumentError, "An option cannot be boolean and required." if boolean? && required? validate_default_type! end def validate_default_type! default_type = case @default - when nil - return - when TrueClass, FalseClass - required? ? :string : :boolean - when Numeric - :numeric - when Symbol - :string - when Hash, Array, String - @default.class.name.downcase.to_sym - end - fail ArgumentError, "An option's default must match its type." unless default_type == @type + when nil + return + when TrueClass, FalseClass + required? ? :string : :boolean + when Numeric + :numeric + when Symbol + :string + when Hash, Array, String + @default.class.name.downcase.to_sym + end + + raise ArgumentError, "An option's default must match its type." unless default_type == @type end def dasherized? @@ -136,7 +139,7 @@ def undasherize(str) end def dasherize(str) - (str.length > 1 ? "--" : "-") + str.gsub("_", "-") + (str.length > 1 ? "--" : "-") + str.tr("_", "-") end end end diff --git a/lib/thor/parser/options.rb b/lib/thor/parser/options.rb index 6cfba1160..188f416ee 100644 --- a/lib/thor/parser/options.rb +++ b/lib/thor/parser/options.rb @@ -14,7 +14,7 @@ def self.to_switches(options) when true "--#{key}" when Array - "--#{key} #{value.map { |v| v.inspect }.join(' ')}" + "--#{key} #{value.map(&:inspect).join(' ')}" when Hash "--#{key} #{value.map { |k, v| "#{k}:#{v}" }.join(' ')}" when nil, false @@ -40,7 +40,9 @@ def initialize(hash_options = {}, defaults = {}, stop_on_unknown = false) @non_assigned_required.delete(hash_options[key]) end - @shorts, @switches, @extra = {}, {}, [] + @shorts = {} + @switches = {} + @extra = [] options.each do |option| @switches[option.switch_name] = option @@ -52,7 +54,7 @@ def initialize(hash_options = {}, defaults = {}, stop_on_unknown = false) end end - def remaining # rubocop:disable TrivialAccessors + def remaining @extra end @@ -119,7 +121,7 @@ def parse(args) # rubocop:disable MethodLength def check_unknown! # an unknown option starts with - or -- and has no more --'s afterward. unknown = @extra.select { |str| str =~ /^--?(?:(?!--).)*$/ } - fail UnknownArgumentError, "Unknown switches '#{unknown.join(', ')}'" unless unknown.empty? + raise UnknownArgumentError, "Unknown switches '#{unknown.join(', ')}'" unless unknown.empty? end protected @@ -207,7 +209,7 @@ def parse_peek(switch, option) elsif option.lazy_default return option.lazy_default else - fail MalformattedArgumentError, "No value provided for option '#{switch}'" + raise MalformattedArgumentError, "No value provided for option '#{switch}'" end end diff --git a/lib/thor/runner.rb b/lib/thor/runner.rb index 1d768a4c8..9f1aaafa2 100644 --- a/lib/thor/runner.rb +++ b/lib/thor/runner.rb @@ -11,10 +11,18 @@ class Thor::Runner < Thor #:nodoc: # rubocop:disable ClassLength map "-T" => :list, "-i" => :install, "-u" => :update, "-v" => :version + def self.banner(command, all = false, subcommand = false) + "thor " + command.formatted_usage(self, all, subcommand) + end + + def self.exit_on_failure? + true + end + # Override Thor#help so it can give information about any class and any method. # def help(meth = nil) - if meth && !self.respond_to?(meth) + if meth && !respond_to?(meth) initialize_thorfiles(meth) klass, command = Thor::Util.find_class_and_command_by_namespace(meth) self.class.handle_no_command_error(command, false) if klass.nil? @@ -45,16 +53,18 @@ def install(name) # rubocop:disable MethodLength # command in said directory. begin if File.directory?(File.expand_path(name)) - base, package = File.join(name, "main.thor"), :directory - contents = open(base) { |input| input.read } + base = File.join(name, "main.thor") + package = :directory + contents = open(base, &:read) else - base, package = name, :file - contents = open(name) { |input| input.read } + base = name + package = :file + contents = open(name, &:read) end rescue OpenURI::HTTPError raise Error, "Error opening URI '#{name}'" rescue Errno::ENOENT - fail Error, "Error opening file '#{name}'" + raise Error, "Error opening file '#{name}'" end say "Your Thorfile contains:" @@ -108,9 +118,9 @@ def version desc "uninstall NAME", "Uninstall a named Thor module" def uninstall(name) - fail Error, "Can't find module '#{name}'" unless thor_yaml[name] + raise Error, "Can't find module '#{name}'" unless thor_yaml[name] say "Uninstalling #{name}." - FileUtils.rm_rf(File.join(thor_root, "#{thor_yaml[name][:filename]}")) + FileUtils.rm_rf(File.join(thor_root, (thor_yaml[name][:filename]).to_s)) thor_yaml.delete(name) save_yaml(thor_yaml) @@ -120,7 +130,7 @@ def uninstall(name) desc "update NAME", "Update a Thor file from its original location" def update(name) - fail Error, "Can't find module '#{name}'" if !thor_yaml[name] || !thor_yaml[name][:location] + raise Error, "Can't find module '#{name}'" if !thor_yaml[name] || !thor_yaml[name][:location] say "Updating '#{name}' from #{thor_yaml[name][:location]}" @@ -138,9 +148,7 @@ def update(name) filename = install(thor_yaml[name][:location]) end - unless filename == old_filename - File.delete(File.join(thor_root, old_filename)) - end + File.delete(File.join(thor_root, old_filename)) unless filename == old_filename end desc "installed", "List the installed Thor modules and commands" @@ -168,10 +176,6 @@ def list(search = "") private - def self.banner(command, all = false, subcommand = false) - "thor " + command.formatted_usage(self, all, subcommand) - end - def thor_root Thor::Util.thor_root end @@ -198,10 +202,6 @@ def save_yaml(yaml) File.open(yaml_file, "w") { |f| f.puts yaml.to_yaml } end - def self.exit_on_failure? - true - end - # Load the Thorfiles. If relevant_to is supplied, looks for specific files # in the thor_root instead of loading them all. # @@ -263,11 +263,11 @@ def thorfiles(relevant_to = nil, skip_lookup = false) def thorfiles_relevant_to(meth) lookup = [meth, meth.split(":")[0...-1].join(":")] - files = thor_yaml.select do |k, v| + files = thor_yaml.select do |_, v| v[:namespaces] && !(v[:namespaces] & lookup).empty? end - files.map { |k, v| File.join(thor_root, "#{v[:filename]}") } + files.map { |_, v| File.join(thor_root, (v[:filename]).to_s) } end # Display information about the given klasses. If with_module is given, @@ -276,7 +276,7 @@ def thorfiles_relevant_to(meth) def display_klasses(with_modules = false, show_internal = false, klasses = Thor::Base.subclasses) klasses -= [Thor, Thor::Runner, Thor::Group] unless show_internal - fail Error, "No Thor commands available" if klasses.empty? + raise Error, "No Thor commands available" if klasses.empty? show_modules if with_modules && !thor_yaml.empty? list = Hash.new { |h, k| h[k] = [] } @@ -306,8 +306,8 @@ def display_commands(namespace, list) #:nodoc: alias_method :display_tasks, :display_commands def show_modules #:nodoc: - info = [] - labels = %w[Modules Namespaces] + info = [] + labels = %w(Modules Namespaces) info << labels info << ["-" * labels[0].size, "-" * labels[1].size] diff --git a/lib/thor/shell.rb b/lib/thor/shell.rb index 707aac906..03eb7d196 100644 --- a/lib/thor/shell.rb +++ b/lib/thor/shell.rb @@ -9,7 +9,7 @@ class << self # it will use a colored log, otherwise it will use a basic one without color. # def shell - @shell ||= if ENV["THOR_SHELL"] && ENV["THOR_SHELL"].size > 0 + @shell ||= if ENV["THOR_SHELL"] && !ENV["THOR_SHELL"].empty? Thor::Shell.const_get(ENV["THOR_SHELL"]) elsif RbConfig::CONFIG["host_os"] =~ /mswin|mingw/ && !ENV["ANSICON"] Thor::Shell::Basic diff --git a/lib/thor/shell/basic.rb b/lib/thor/shell/basic.rb index 77faef0ea..87d47f27e 100644 --- a/lib/thor/shell/basic.rb +++ b/lib/thor/shell/basic.rb @@ -3,14 +3,17 @@ class Thor module Shell - class Basic # rubocop:disable ClassLength + class Basic attr_accessor :base attr_reader :padding # Initialize base, mute and padding to nil. # def initialize #:nodoc: - @base, @mute, @padding, @always_force = nil, false, 0, false + @base = nil + @mute = false + @padding = 0 + @always_force = false end # Mute everything that's inside given block @@ -24,7 +27,7 @@ def mute # Check if base is muted # - def mute? # rubocop:disable TrivialAccessors + def mute? @mute end @@ -36,7 +39,7 @@ def padding=(value) # Sets the output padding while executing a block and resets it. # - def indent(count = 1, &block) + def indent(count = 1) orig_padding = padding self.padding = padding + count yield @@ -157,7 +160,9 @@ def print_in_columns(array) def print_table(array, options = {}) # rubocop:disable MethodLength return if array.empty? - formats, indent, colwidth = [], options[:indent].to_i, options[:colwidth] + formats = [] + indent = options[:indent].to_i + colwidth = options[:colwidth] options[:truncate] = terminal_width if options[:truncate] == true formats << "%-#{colwidth + 2}s" if colwidth @@ -170,12 +175,12 @@ def print_table(array, options = {}) # rubocop:disable MethodLength start.upto(colcount - 1) do |index| maxima = array.map { |row| row[index] ? row[index].to_s.size : 0 }.max maximas << maxima - if index == colcount - 1 - # Don't output 2 trailing spaces when printing the last column - formats << "%-s" - else - formats << "%-#{maxima + 2}s" - end + formats << if index == colcount - 1 + # Don't output 2 trailing spaces when printing the last column + "%-s" + else + "%-#{maxima + 2}s" + end end formats[0] = formats[0].insert(0, " " * indent) @@ -187,15 +192,15 @@ def print_table(array, options = {}) # rubocop:disable MethodLength row.each_with_index do |column, index| maxima = maximas[index] - if column.is_a?(Numeric) + f = if column.is_a?(Numeric) if index == row.size - 1 # Don't output 2 trailing spaces when printing the last column - f = "%#{maxima}s" + "%#{maxima}s" else - f = "%#{maxima}s " + "%#{maxima}s " end else - f = formats[index] + formats[index] end sentence << f % column.to_s end @@ -220,7 +225,7 @@ def print_wrapped(message, options = {}) paras = message.split("\n\n") paras.map! do |unwrapped| - unwrapped.strip.gsub(/\n/, " ").squeeze(" ").gsub(/.{1,#{width}}(?:\s|\Z)/) { ($& + 5.chr).gsub(/\n\005/, "\n").gsub(/\005/, "\n") } + unwrapped.strip.tr("\n", " ").squeeze(" ").gsub(/.{1,#{width}}(?:\s|\Z)/) { ($& + 5.chr).gsub(/\n\005/, "\n").gsub(/\005/, "\n") } end paras.each do |para| @@ -239,7 +244,7 @@ def print_wrapped(message, options = {}) # destination:: the destination file to solve conflicts # block:: an optional block that returns the value to be used in diff # - def file_collision(destination) # rubocop:disable MethodLength + def file_collision(destination) return true if @always_force options = block_given? ? "[Ynaqdh]" : "[Ynaqh]" @@ -258,7 +263,7 @@ def file_collision(destination) # rubocop:disable MethodLength return @always_force = true when is?(:quit) say "Aborting..." - fail SystemExit + raise SystemExit when is?(:diff) show_diff(destination, yield) if block_given? say "Retrying..." @@ -271,10 +276,10 @@ def file_collision(destination) # rubocop:disable MethodLength # This code was copied from Rake, available under MIT-LICENSE # Copyright (c) 2003, 2004 Jim Weirich def terminal_width - if ENV["THOR_COLUMNS"] - result = ENV["THOR_COLUMNS"].to_i + result = if ENV["THOR_COLUMNS"] + ENV["THOR_COLUMNS"].to_i else - result = unix? ? dynamic_width : 80 + unix? ? dynamic_width : 80 end result < 10 ? 80 : result rescue @@ -293,7 +298,7 @@ def error(statement) # Apply color to the given string with optional bold. Disabled in the # Thor::Shell::Basic class. # - def set_color(string, *args) #:nodoc: + def set_color(string, *) #:nodoc: string end @@ -362,11 +367,11 @@ def dynamic_width end def dynamic_width_stty - %x(stty size 2>/dev/null).split[1].to_i + `stty size 2>/dev/null`.split[1].to_i end def dynamic_width_tput - %x(tput cols 2>/dev/null).to_i + `tput cols 2>/dev/null`.to_i end def unix? @@ -379,7 +384,7 @@ def truncate(string, width) if chars.length <= width chars.join else - ( chars[0, width - 3].join) + "..." + chars[0, width - 3].join + "..." end end end @@ -390,7 +395,8 @@ def as_unicode end else def as_unicode - old, $KCODE = $KCODE, "U" + old = $KCODE + $KCODE = "U" yield ensure $KCODE = old diff --git a/lib/thor/shell/color.rb b/lib/thor/shell/color.rb index 744a737f2..2a90d46b8 100644 --- a/lib/thor/shell/color.rb +++ b/lib/thor/shell/color.rb @@ -134,7 +134,7 @@ def output_diff_line(diff) #:nodoc: # for diff. # def diff_lcs_loaded? #:nodoc: - return true if defined?(Diff::LCS) + return true if defined?(Diff::LCS) return @diff_lcs_loaded unless @diff_lcs_loaded.nil? @diff_lcs_loaded = begin diff --git a/lib/thor/shell/html.rb b/lib/thor/shell/html.rb index 525f9a379..e39357842 100644 --- a/lib/thor/shell/html.rb +++ b/lib/thor/shell/html.rb @@ -51,13 +51,13 @@ class HTML < Basic def set_color(string, *colors) if colors.all? { |color| color.is_a?(Symbol) || color.is_a?(String) } html_colors = colors.map { |color| lookup_color(color) } - "#{string}" + "#{string}" else color, bold = colors html_color = self.class.const_get(color.to_s.upcase) if color.is_a?(Symbol) styles = [html_color] styles << BOLD if bold - "#{string}" + "#{string}" end end @@ -68,7 +68,7 @@ def set_color(string, *colors) # # TODO: Implement #ask for Thor::Shell::HTML def ask(statement, color = nil) - fail NotImplementedError, "Implement #ask for Thor::Shell::HTML" + raise NotImplementedError, "Implement #ask for Thor::Shell::HTML" end protected @@ -111,7 +111,7 @@ def output_diff_line(diff) #:nodoc: # for diff. # def diff_lcs_loaded? #:nodoc: - return true if defined?(Diff::LCS) + return true if defined?(Diff::LCS) return @diff_lcs_loaded unless @diff_lcs_loaded.nil? @diff_lcs_loaded = begin diff --git a/lib/thor/util.rb b/lib/thor/util.rb index f4ec83a15..a48ed8e8c 100644 --- a/lib/thor/util.rb +++ b/lib/thor/util.rb @@ -64,7 +64,7 @@ def namespaces_in_content(contents, file = __FILE__) new_constants = Thor::Base.subclasses.dup Thor::Base.subclasses.replace(old_constants) - new_constants.map! { |c| c.namespace } + new_constants.map!(&:namespace) new_constants.compact! new_constants end @@ -72,7 +72,7 @@ def namespaces_in_content(contents, file = __FILE__) # Returns the thor classes declared inside the given class. # def thor_classes_in(klass) - stringfied_constants = klass.constants.map { |c| c.to_s } + stringfied_constants = klass.constants.map(&:to_s) Thor::Base.subclasses.select do |subclass| next unless subclass.name stringfied_constants.include?(subclass.name.gsub("#{klass.name}::", "")) @@ -103,7 +103,7 @@ def snake_case(str) # def camel_case(str) return str if str !~ /_/ && str =~ /[A-Z]+.*/ - str.split("_").map { |i| i.capitalize }.join + str.split("_").map(&:capitalize).join end # Receives a namespace and tries to retrieve a Thor or Thor::Group class @@ -135,7 +135,8 @@ def find_class_and_command_by_namespace(namespace, fallback = true) klass = Thor::Util.find_by_namespace(pieces.join(":")) end unless klass # look for a Thor::Group with the right name - klass, command = Thor::Util.find_by_namespace(namespace), nil + klass = Thor::Util.find_by_namespace(namespace) + command = nil end if !klass && fallback # try a command in the default namespace command = namespace @@ -163,7 +164,7 @@ def load_thorfile(path, content = nil, debug = false) end end - def user_home # rubocop:disable MethodLength + def user_home @@user_home ||= if ENV["HOME"] ENV["HOME"] elsif ENV["USERPROFILE"] @@ -188,7 +189,7 @@ def user_home # rubocop:disable MethodLength # Returns the root where thor files are located, depending on the OS. # def thor_root - File.join(user_home, ".thor").gsub(/\\/, "/") + File.join(user_home, ".thor").tr('\\', "/") end # Returns the files in the thor root. On Windows thor_root will be something @@ -216,7 +217,7 @@ def globs_for(path) # Return the path to the ruby interpreter taking into account multiple # installations and windows extensions. # - def ruby_command # rubocop:disable MethodLength + def ruby_command @ruby_command ||= begin ruby_name = RbConfig::CONFIG["ruby_install_name"] ruby = File.join(RbConfig::CONFIG["bindir"], ruby_name) diff --git a/spec/actions/create_file_spec.rb b/spec/actions/create_file_spec.rb index 4bf82c996..19c8b6cf3 100644 --- a/spec/actions/create_file_spec.rb +++ b/spec/actions/create_file_spec.rb @@ -107,20 +107,20 @@ def silence! expect(Thor::LineEditor).to receive(:readline).with("Overwrite #{file}? (enter \"h\" for help) [Ynaqdh] ", anything).and_return("s") content = invoke! - expect(content).to match(/conflict doc\/config\.rb/) - expect(content).to match(/skip doc\/config\.rb/) + expect(content).to match(%r{conflict doc/config\.rb}) + expect(content).to match(%r{skip doc/config\.rb}) end it "creates the file if the file collision menu returns true" do create_file("doc/config.rb") expect(Thor::LineEditor).to receive(:readline).and_return("y") - expect(invoke!).to match(/force doc\/config\.rb/) + expect(invoke!).to match(%r{force doc/config\.rb}) end it "skips the file if the file collision menu returns false" do create_file("doc/config.rb") expect(Thor::LineEditor).to receive(:readline).and_return("n") - expect(invoke!).to match(/skip doc\/config\.rb/) + expect(invoke!).to match(%r{skip doc/config\.rb}) end it "executes the block given to show file content" do diff --git a/spec/actions/directory_spec.rb b/spec/actions/directory_spec.rb index 23a1637e1..2864cf4c3 100644 --- a/spec/actions/directory_spec.rb +++ b/spec/actions/directory_spec.rb @@ -24,7 +24,7 @@ def revoke!(*args, &block) end def exists_and_identical?(source_path, destination_path) - %w[config.rb README].each do |file| + %w(config.rb README).each do |file| source = File.join(source_root, source_path, file) destination = File.join(destination_root, destination_path, file) @@ -69,7 +69,7 @@ def exists_and_identical?(source_path, destination_path) end it "ignores files within excluding/ directories when exclude_pattern is provided" do - invoke! "doc", "docs", :exclude_pattern => /excluding\// + invoke! "doc", "docs", :exclude_pattern => %r{excluding/} file = File.join(destination_root, "docs", "excluding", "rdoc.rb") expect(File.exist?(file)).to be false end @@ -128,10 +128,10 @@ def exists_and_identical?(source_path, destination_path) it "logs status" do content = invoke!("doc") - expect(content).to match(/create doc\/README/) - expect(content).to match(/create doc\/config\.rb/) - expect(content).to match(/create doc\/rdoc\.rb/) - expect(content).to match(/create doc\/components/) + expect(content).to match(%r{create doc/README}) + expect(content).to match(%r{create doc/config\.rb}) + expect(content).to match(%r{create doc/rdoc\.rb}) + expect(content).to match(%r{create doc/components}) end it "yields a block" do @@ -144,7 +144,7 @@ def exists_and_identical?(source_path, destination_path) it "works with glob characters in the path" do content = invoke!("app{1}") - expect(content).to match(/create app\{1\}\/README/) + expect(content).to match(%r{create app\{1\}/README}) end end diff --git a/spec/actions/file_manipulation_spec.rb b/spec/actions/file_manipulation_spec.rb index 4f018391f..335f65615 100644 --- a/spec/actions/file_manipulation_spec.rb +++ b/spec/actions/file_manipulation_spec.rb @@ -29,23 +29,23 @@ def file describe "#chmod" do it "executes the command given" do - expect(FileUtils).to receive(:chmod_R).with(0755, file) # rubocop:disable SymbolName + expect(FileUtils).to receive(:chmod_R).with(0755, file) action :chmod, "foo", 0755 end it "does not execute the command if pretending" do - expect(FileUtils).not_to receive(:chmod_R) # rubocop:disable SymbolName + expect(FileUtils).not_to receive(:chmod_R) runner(:pretend => true) action :chmod, "foo", 0755 end it "logs status" do - expect(FileUtils).to receive(:chmod_R).with(0755, file) # rubocop:disable SymbolName + expect(FileUtils).to receive(:chmod_R).with(0755, file) expect(action(:chmod, "foo", 0755)).to eq(" chmod foo\n") end it "does not log status if required" do - expect(FileUtils).to receive(:chmod_R).with(0755, file) # rubocop:disable SymbolName + expect(FileUtils).to receive(:chmod_R).with(0755, file) expect(action(:chmod, "foo", 0755, :verbose => false)).to be_empty end end @@ -122,7 +122,7 @@ def file end it "allows the destination to be set as a block result" do - action(:get, "doc/README") { |c| "docs/README" } + action(:get, "doc/README") { "docs/README" } exists_and_identical?("doc/README", "docs/README") end @@ -207,7 +207,7 @@ def file it "accepts a context to use as the binding" do begin - @klass = 'FooBar' + @klass = "FooBar" action :template, "doc/config.rb", :context => eval("binding") expect(File.read(File.join(destination_root, "doc/config.rb"))).to eq("class FooBar; end\n") ensure @@ -271,7 +271,7 @@ def file end it "accepts a block" do - action(:gsub_file, "doc/README", "__start__") { |match| match.gsub("__", "").upcase } + action(:gsub_file, "doc/README", "__start__") { |match| match.gsub("__", "").upcase } expect(File.binread(file)).to eq("START\nREADME\n__end__\n") end diff --git a/spec/actions/inject_into_file_spec.rb b/spec/actions/inject_into_file_spec.rb index 05112a11e..97f67eb9b 100644 --- a/spec/actions/inject_into_file_spec.rb +++ b/spec/actions/inject_into_file_spec.rb @@ -83,7 +83,6 @@ def file expect(File.read(file)).to eq("__start__\nREADME\nmore content\nmore content\n__end__\n") end - end describe "#revoke!" do diff --git a/spec/actions_spec.rb b/spec/actions_spec.rb index 746460b51..12e304311 100644 --- a/spec/actions_spec.rb +++ b/spec/actions_spec.rb @@ -39,7 +39,7 @@ def file end it "when behavior is set to skip, overwrite options" do - runner = MyCounter.new([1], %w[--force], :behavior => :skip) + runner = MyCounter.new([1], %w(--force), :behavior => :skip) expect(runner.behavior).to eq(:invoke) expect(runner.options.force).not_to be true expect(runner.options.skip).to be true diff --git a/spec/base_spec.rb b/spec/base_spec.rb index 5f10a34cb..4ba1f689f 100644 --- a/spec/base_spec.rb +++ b/spec/base_spec.rb @@ -54,12 +54,12 @@ def hello describe "#argument" do it "sets a value as required and creates an accessor for it" do - expect(MyCounter.start(%w[1 2 --third 3])[0]).to eq(1) - expect(Scripts::MyScript.start(%w[zoo my_special_param --param=normal_param])).to eq("my_special_param") + expect(MyCounter.start(%w(1 2 --third 3))[0]).to eq(1) + expect(Scripts::MyScript.start(%w(zoo my_special_param --param=normal_param))).to eq("my_special_param") end it "does not set a value in the options hash" do - expect(BrokenCounter.start(%w[1 2 --third 3])[0]).to be nil + expect(BrokenCounter.start(%w(1 2 --third 3))[0]).to be nil end end @@ -71,22 +71,22 @@ def hello describe ":aliases" do it "supports string aliases without a dash prefix" do - expect(MyCounter.start(%w[1 2 -z 3])[4]).to eq(3) + expect(MyCounter.start(%w(1 2 -z 3))[4]).to eq(3) end it "supports symbol aliases" do - expect(MyCounter.start(%w[1 2 -y 3])[5]).to eq(3) - expect(MyCounter.start(%w[1 2 -r 3])[5]).to eq(3) + expect(MyCounter.start(%w(1 2 -y 3))[5]).to eq(3) + expect(MyCounter.start(%w(1 2 -r 3))[5]).to eq(3) end end describe "#class_option" do it "sets options class wise" do - expect(MyCounter.start(%w[1 2 --third 3])[2]).to eq(3) + expect(MyCounter.start(%w(1 2 --third 3))[2]).to eq(3) end it "does not create an accessor for it" do - expect(BrokenCounter.start(%w[1 2 --third 3])[3]).to be false + expect(BrokenCounter.start(%w(1 2 --third 3))[3]).to be false end end @@ -249,7 +249,7 @@ def hello ENV["THOR_DEBUG"] = "1" expect do - MyScript.start %w[what --debug] + MyScript.start %w(what --debug) end.to raise_error(Thor::UndefinedCommandError, 'Could not find command "what" in "my_script" namespace.') ensure ENV["THOR_DEBUG"] = nil @@ -258,36 +258,36 @@ def hello it "raises an error instead of rescuing if :debug option is given" do expect do - MyScript.start %w[what], :debug => true + MyScript.start %w(what), :debug => true end.to raise_error(Thor::UndefinedCommandError, 'Could not find command "what" in "my_script" namespace.') end it "does not steal args" do - args = %w[foo bar --force true] + args = %w(foo bar --force true) MyScript.start(args) - expect(args).to eq(%w[foo bar --force true]) + expect(args).to eq(%w(foo bar --force true)) end it "checks unknown options" do expect(capture(:stderr) do - MyScript.start(%w[foo bar --force true --unknown baz]) + MyScript.start(%w(foo bar --force true --unknown baz)) end.strip).to eq("Unknown switches '--unknown'") end it "checks unknown options except specified" do expect(capture(:stderr) do - expect(MyScript.start(%w[with_optional NAME --omg --invalid])).to eq(["NAME", {}, %w[--omg --invalid]]) + expect(MyScript.start(%w(with_optional NAME --omg --invalid))).to eq(["NAME", {}, %w(--omg --invalid)]) end.strip).to be_empty end end describe "attr_*" do it "does not add attr_reader as a command" do - expect(capture(:stderr) { MyScript.start(%w[another_attribute]) }).to match(/Could not find/) + expect(capture(:stderr) { MyScript.start(%w(another_attribute)) }).to match(/Could not find/) end it "does not add attr_writer as a command" do - expect(capture(:stderr) { MyScript.start(%w[another_attribute= foo]) }).to match(/Could not find/) + expect(capture(:stderr) { MyScript.start(%w(another_attribute= foo)) }).to match(/Could not find/) end it "does not add attr_accessor as a command" do diff --git a/spec/command_spec.rb b/spec/command_spec.rb index 6e5ad2cf7..98295268a 100644 --- a/spec/command_spec.rb +++ b/spec/command_spec.rb @@ -67,6 +67,7 @@ def command(options = {}) def self.handle_no_command_error(name) name end + def can_has "fail" end diff --git a/spec/core_ext/hash_with_indifferent_access_spec.rb b/spec/core_ext/hash_with_indifferent_access_spec.rb index 1709c6385..b43751b0d 100644 --- a/spec/core_ext/hash_with_indifferent_access_spec.rb +++ b/spec/core_ext/hash_with_indifferent_access_spec.rb @@ -10,7 +10,7 @@ expect(@hash["foo"]).to eq("bar") expect(@hash[:foo]).to eq("bar") - expect(@hash.values_at(:foo, :baz)).to eq(%w[bar bee]) + expect(@hash.values_at(:foo, :baz)).to eq(%w(bar bee)) expect(@hash.delete(:foo)).to eq("bar") end @@ -44,7 +44,8 @@ end it "merges keys independent if they are symbols or strings" do - @hash.merge!("force" => false, :baz => "boom") + @hash["force"] = false + @hash[:baz] = "boom" expect(@hash[:force]).to eq(false) expect(@hash["baz"]).to eq("boom") end diff --git a/spec/core_ext/ordered_hash_spec.rb b/spec/core_ext/ordered_hash_spec.rb index 8cc6143e8..0e631e7f8 100644 --- a/spec/core_ext/ordered_hash_spec.rb +++ b/spec/core_ext/ordered_hash_spec.rb @@ -12,7 +12,7 @@ end it "doesn't iterate through any items" do - @hash.each { fail } + @hash.each { raise } end it "has an empty key and values list" do diff --git a/spec/exit_condition_spec.rb b/spec/exit_condition_spec.rb index 807b5af4e..9c81280d4 100644 --- a/spec/exit_condition_spec.rb +++ b/spec/exit_condition_spec.rb @@ -9,7 +9,7 @@ desc "my_action", "testing EPIPE" define_method :my_action do epiped = true - fail Errno::EPIPE + raise Errno::EPIPE end end diff --git a/spec/fixtures/help.thor b/spec/fixtures/help.thor new file mode 100644 index 000000000..24d7cd615 --- /dev/null +++ b/spec/fixtures/help.thor @@ -0,0 +1,13 @@ +Bundler.require :development, :default + +class Help < Thor + + desc :bugs, "ALL TEH BUGZ!" + option "--not_help", :type => :boolean + def bugs + puts "Invoked!" + end + +end + +Help.start(ARGV) diff --git a/spec/group_spec.rb b/spec/group_spec.rb index 35aaf9e74..e6fe02d46 100644 --- a/spec/group_spec.rb +++ b/spec/group_spec.rb @@ -3,22 +3,22 @@ describe Thor::Group do describe "command" do it "allows to use private methods from parent class as commands" do - expect(ChildGroup.start).to eq(%w[bar foo baz]) + expect(ChildGroup.start).to eq(%w(bar foo baz)) expect(ChildGroup.new.baz("bar")).to eq("bar") end end describe "#start" do it "invokes all the commands under the Thor group" do - expect(MyCounter.start(%w[1 2 --third 3])).to eq([1, 2, 3, nil, nil, nil]) + expect(MyCounter.start(%w(1 2 --third 3))).to eq([1, 2, 3, nil, nil, nil]) end it "uses argument's default value" do - expect(MyCounter.start(%w[1 --third 3])).to eq([1, 2, 3, nil, nil, nil]) + expect(MyCounter.start(%w(1 --third 3))).to eq([1, 2, 3, nil, nil, nil]) end it "invokes all the commands in the Thor group and its parents" do - expect(BrokenCounter.start(%w[1 2 --third 3])).to eq([nil, 2, 3, false, 5, nil]) + expect(BrokenCounter.start(%w(1 2 --third 3))).to eq([nil, 2, 3, false, 5, nil]) end it "raises an error if a required argument is added after a non-required" do @@ -28,7 +28,7 @@ end it "raises when an exception happens within the command call" do - expect { BrokenCounter.start(%w[1 2 --fail]) }.to raise_error(NameError, /undefined local variable or method `this_method_does_not_exist'/) + expect { BrokenCounter.start(%w(1 2 --fail)) }.to raise_error(NameError, /undefined local variable or method `this_method_does_not_exist'/) end it "raises an error when a Thor group command expects arguments" do @@ -37,7 +37,7 @@ it "invokes help message if any of the shortcuts are given" do expect(MyCounter).to receive(:help) - MyCounter.start(%w[-h]) + MyCounter.start(%w(-h)) end end @@ -117,11 +117,11 @@ end it "does not invoke if the option is nil" do - expect(capture(:stdout) { G.start(%w[--skip-invoked]) }).not_to match(/invoke/) + expect(capture(:stdout) { G.start(%w(--skip-invoked)) }).not_to match(/invoke/) end it "prints a message if invocation cannot be found" do - content = capture(:stdout) { G.start(%w[--invoked unknown]) } + content = capture(:stdout) { G.start(%w(--invoked unknown)) } expect(content).to match(/error unknown \[not found\]/) end @@ -129,7 +129,7 @@ error = nil content = capture(:stdout) do error = capture(:stderr) do - G.start(%w[--invoked e]) + G.start(%w(--invoked e)) end end expect(content).to match(/invoke e/) @@ -162,7 +162,7 @@ end it "does not invoke if the option is false" do - expect(capture(:stdout) { H.start(%w[--no-defined]) }).not_to match(/invoke/) + expect(capture(:stdout) { H.start(%w(--no-defined)) }).not_to match(/invoke/) end it "shows invocation information to the user" do @@ -195,9 +195,9 @@ def hi end end - expect(klass.start(%w[jose])).to eq(["Hi jose"]) - expect(klass.start(%w[jose --loud])).to eq(["Hi JOSE"]) - expect(klass.start(%w[--loud jose])).to eq(["Hi JOSE"]) + expect(klass.start(%w(jose))).to eq(["Hi jose"]) + expect(klass.start(%w(jose --loud))).to eq(["Hi JOSE"]) + expect(klass.start(%w(--loud jose))).to eq(["Hi JOSE"]) end it "provides extra args as `args`" do @@ -214,9 +214,9 @@ def hi end end - expect(klass.start(%w[jose])).to eq(["Hi jose"]) - expect(klass.start(%w[jose --loud])).to eq(["Hi JOSE"]) - expect(klass.start(%w[--loud jose])).to eq(["Hi JOSE"]) + expect(klass.start(%w(jose))).to eq(["Hi jose"]) + expect(klass.start(%w(jose --loud))).to eq(["Hi JOSE"]) + expect(klass.start(%w(--loud jose))).to eq(["Hi JOSE"]) end end end diff --git a/spec/helper.rb b/spec/helper.rb index 7363d5e34..251b216cd 100644 --- a/spec/helper.rb +++ b/spec/helper.rb @@ -1,6 +1,6 @@ $TESTING = true -if RUBY_VERSION >= '1.9' +if RUBY_VERSION >= "1.9" require "simplecov" require "coveralls" @@ -24,7 +24,6 @@ WebMock.disable_net_connect!(:allow => "coveralls.io") - # Set shell to basic $0 = "thor" $thor_runner = true @@ -72,7 +71,8 @@ def destination_root # This code was adapted from Ruby on Rails, available under MIT-LICENSE # Copyright (c) 2004-2013 David Heinemeier Hansson def silence_warnings - old_verbose, $VERBOSE = $VERBOSE, nil + old_verbose = $VERBOSE + $VERBOSE = nil yield ensure $VERBOSE = old_verbose diff --git a/spec/invocation_spec.rb b/spec/invocation_spec.rb index 01160d27c..3241a1e0d 100644 --- a/spec/invocation_spec.rb +++ b/spec/invocation_spec.rb @@ -34,16 +34,16 @@ it "accepts a class as argument with a command to invoke" do base = A.new([], :last_name => "Valim") - expect(base.invoke(B, :one, %w[Jose])).to eq("Valim, Jose") + expect(base.invoke(B, :one, %w(Jose))).to eq("Valim, Jose") end it "allows customized options to be given" do base = A.new([], :last_name => "Wrong") - expect(base.invoke(B, :one, %w[Jose], :last_name => "Valim")).to eq("Valim, Jose") + expect(base.invoke(B, :one, %w(Jose), :last_name => "Valim")).to eq("Valim, Jose") end it "reparses options in the new class" do - expect(A.start(%w[invoker --last-name Valim])).to eq("Valim, Jose") + expect(A.start(%w(invoker --last-name Valim))).to eq("Valim, Jose") end it "shares initialize options with invoked class" do @@ -62,11 +62,11 @@ expect(I.new.invoke("two")).to eq([:two]) if RUBY_VERSION < "1.9.3" - result = J.start(["one", "two" ]) + result = J.start(%w(one two)) expect(result).to include(:one) expect(result).to include(:two) else - expect(J.start(["one", "two" ])).to eq([:one, :two]) + expect(J.start(%w(one two))).to eq([:one, :two]) end end @@ -76,7 +76,8 @@ end it "allow extra configuration values to be given" do - base, shell = A.new, Thor::Base.shell.new + base = A.new + shell = Thor::Base.shell.new expect(base.invoke("b:three", [], {}, :shell => shell).shell).to eq(shell) end diff --git a/spec/line_editor/readline_spec.rb b/spec/line_editor/readline_spec.rb index dda489c61..b2b0712d6 100644 --- a/spec/line_editor/readline_spec.rb +++ b/spec/line_editor/readline_spec.rb @@ -38,12 +38,12 @@ it "provides tab completion when given a limited_to option" do expect(::Readline).to receive(:readline) expect(::Readline).to receive(:completion_proc=) do |proc| - expect(proc.call("")).to eq %w[Apples Chicken Chocolate] - expect(proc.call("Ch")).to eq %w[Chicken Chocolate] + expect(proc.call("")).to eq %w(Apples Chicken Chocolate) + expect(proc.call("Ch")).to eq %w(Chicken Chocolate) expect(proc.call("Chi")).to eq ["Chicken"] end - editor = Thor::LineEditor::Readline.new("Best food: ", :limited_to => %w[Apples Chicken Chocolate]) + editor = Thor::LineEditor::Readline.new("Best food: ", :limited_to => %w(Apples Chicken Chocolate)) editor.readline end diff --git a/spec/parser/argument_spec.rb b/spec/parser/argument_spec.rb index 0b1c1cc46..1bc946908 100644 --- a/spec/parser/argument_spec.rb +++ b/spec/parser/argument_spec.rb @@ -2,7 +2,6 @@ require "thor/parser" describe Thor::Argument do - def argument(name, options = {}) @argument ||= Thor::Argument.new(name, options) end diff --git a/spec/parser/arguments_spec.rb b/spec/parser/arguments_spec.rb index 196fe542f..c8b0be11e 100644 --- a/spec/parser/arguments_spec.rb +++ b/spec/parser/arguments_spec.rb @@ -37,7 +37,7 @@ def parse(*args) it "accepts arrays" do create :string => nil, :array => nil expect(parse("product", "title", "age")["string"]).to eq("product") - expect(parse("product", "title", "age")["array"]).to eq(%w[title age]) + expect(parse("product", "title", "age")["array"]).to eq(%w(title age)) end describe "with no inputs" do diff --git a/spec/parser/option_spec.rb b/spec/parser/option_spec.rb index 05cd2d8d9..8a7c329b4 100644 --- a/spec/parser/option_spec.rb +++ b/spec/parser/option_spec.rb @@ -11,7 +11,6 @@ def option(name, options = {}) end describe "#parse" do - describe "with value as a symbol" do describe "and symbol is a valid type" do it "has type equals to the symbol" do @@ -137,13 +136,13 @@ def option(name, options = {}) it "raises an error if default is inconsistent with type" do expect do - option = option("foo", :type => :numeric, :default => "bar") + option("foo", :type => :numeric, :default => "bar") end.to raise_error(ArgumentError, "An option's default must match its type.") end it "does not raises an error if default is an symbol and type string" do expect do - option = option("foo", :type => :string, :default => :bar) + option("foo", :type => :string, :default => :bar) end.not_to raise_error end @@ -172,7 +171,6 @@ def option(name, options = {}) end describe "#usage" do - it "returns usage for string types" do expect(parse(:foo, :string).usage).to eq("[--foo=FOO]") end diff --git a/spec/parser/options_spec.rb b/spec/parser/options_spec.rb index 9a6a21d24..ec1d79186 100644 --- a/spec/parser/options_spec.rb +++ b/spec/parser/options_spec.rb @@ -41,7 +41,7 @@ def remaining it "joins several values" do switches = Thor::Options.to_switches(:color => true, :foo => "bar").split(" ").sort - expect(switches).to eq(%w["bar" --color --foo]) + expect(switches).to eq(%w("bar" --color --foo)) end it "accepts arrays" do @@ -55,12 +55,11 @@ def remaining it "accepts underscored options" do expect(Thor::Options.to_switches(:under_score_option => "foo bar")).to eq('--under_score_option "foo bar"') end - end describe "#parse" do it "allows multiple aliases for a given switch" do - create %w[--foo --bar --baz] => :string + create %w(--foo --bar --baz) => :string expect(parse("--foo", "12")["foo"]).to eq("12") expect(parse("--bar", "12")["foo"]).to eq("12") expect(parse("--baz", "12")["foo"]).to eq("12") @@ -72,12 +71,12 @@ def remaining end it "allows custom short-name aliases" do - create %w[--bar -f] => :string + create %w(--bar -f) => :string expect(parse("-f", "12")).to eq("bar" => "12") end it "accepts conjoined short switches" do - create %w[--foo -f] => true, %w[--bar -b] => true, %w[--app -a] => true + create %w(--foo -f) => true, %w(--bar -b) => true, %w(--app -a) => true opts = parse("-fba") expect(opts["foo"]).to be true expect(opts["bar"]).to be true @@ -85,7 +84,7 @@ def remaining end it "accepts conjoined short switches with input" do - create %w[--foo -f] => true, %w[--bar -b] => true, %w[--app -a] => :required + create %w(--foo -f) => true, %w(--bar -b) => true, %w(--app -a) => :required opts = parse "-fba", "12" expect(opts["foo"]).to be true expect(opts["bar"]).to be true @@ -139,31 +138,31 @@ def remaining it "interprets everything after -- as args instead of options" do create(:foo => :string, :bar => :required) - expect(parse(%w[--bar abc moo -- --foo def -a])).to eq("bar" => "abc") - expect(remaining).to eq(%w[moo --foo def -a]) + expect(parse(%w(--bar abc moo -- --foo def -a))).to eq("bar" => "abc") + expect(remaining).to eq(%w(moo --foo def -a)) end it "ignores -- when looking for single option values" do create(:foo => :string, :bar => :required) - expect(parse(%w[--bar -- --foo def -a])).to eq("bar" => "--foo") - expect(remaining).to eq(%w[def -a]) + expect(parse(%w(--bar -- --foo def -a))).to eq("bar" => "--foo") + expect(remaining).to eq(%w(def -a)) end it "ignores -- when looking for array option values" do create(:foo => :array) - expect(parse(%w[--foo a b -- c d -e])).to eq("foo" => %w[a b c d -e]) + expect(parse(%w(--foo a b -- c d -e))).to eq("foo" => %w(a b c d -e)) expect(remaining).to eq([]) end it "ignores -- when looking for hash option values" do create(:foo => :hash) - expect(parse(%w[--foo a:b -- c:d -e])).to eq("foo" => {"a" => "b", "c" => "d"}) - expect(remaining).to eq(%w[-e]) + expect(parse(%w(--foo a:b -- c:d -e))).to eq("foo" => {"a" => "b", "c" => "d"}) + expect(remaining).to eq(%w(-e)) end it "ignores trailing --" do create(:foo => :string) - expect(parse(%w[--foo --])).to eq("foo" => nil) + expect(parse(%w(--foo --))).to eq("foo" => nil) expect(remaining).to eq([]) end @@ -214,39 +213,39 @@ def remaining end it "stops parsing on first non-option" do - expect(parse(%w[foo --verbose])).to eq({}) - expect(remaining).to eq(%w[foo --verbose]) + expect(parse(%w(foo --verbose))).to eq({}) + expect(remaining).to eq(%w(foo --verbose)) end it "stops parsing on unknown option" do - expect(parse(%w[--bar --verbose])).to eq({}) - expect(remaining).to eq(%w[--bar --verbose]) + expect(parse(%w(--bar --verbose))).to eq({}) + expect(remaining).to eq(%w(--bar --verbose)) end it "retains -- after it has stopped parsing" do - expect(parse(%w[--bar -- whatever])).to eq({}) - expect(remaining).to eq(%w[--bar -- whatever]) + expect(parse(%w(--bar -- whatever))).to eq({}) + expect(remaining).to eq(%w(--bar -- whatever)) end it "still accepts options that are given before non-options" do - expect(parse(%w[--verbose foo])).to eq("verbose" => true) - expect(remaining).to eq(%w[foo]) + expect(parse(%w(--verbose foo))).to eq("verbose" => true) + expect(remaining).to eq(%w(foo)) end it "still accepts options that require a value" do - expect(parse(%w[--foo bar baz])).to eq("foo" => "bar") - expect(remaining).to eq(%w[baz]) + expect(parse(%w(--foo bar baz))).to eq("foo" => "bar") + expect(remaining).to eq(%w(baz)) end it "still interprets everything after -- as args instead of options" do - expect(parse(%w[-- --verbose])).to eq({}) - expect(remaining).to eq(%w[--verbose]) + expect(parse(%w(-- --verbose))).to eq({}) + expect(remaining).to eq(%w(--verbose)) end end describe "with :string type" do before do - create %w[--foo -f] => :required + create %w(--foo -f) => :required end it "accepts a switch assignment" do @@ -290,7 +289,7 @@ def remaining end it "raises error when value isn't in enum" do - enum = %w[apple banana] + enum = %w(apple banana) create :fruit => Thor::Option.new("fruit", :type => :string, :enum => enum) expect { parse("--fruit", "orange") }.to raise_error(Thor::MalformattedArgumentError, "Expected '--fruit' to be one of #{enum.join(', ')}; got orange") @@ -344,7 +343,7 @@ def remaining it "doesn't eat the next part of the param" do create :foo => :boolean expect(parse("--foo", "bar")).to eq("foo" => true) - expect(@opt.remaining).to eq(%w[bar]) + expect(@opt.remaining).to eq(%w(bar)) end end @@ -366,7 +365,7 @@ def remaining end it "must not allow the same hash key to be specified multiple times" do - expect {parse("--attributes", "name:string", "name:integer")}.to raise_error(Thor::MalformattedArgumentError, "You can't specify 'name' more than once in option '--attributes'; got name:string and name:integer") + expect { parse("--attributes", "name:string", "name:integer") }.to raise_error(Thor::MalformattedArgumentError, "You can't specify 'name' more than once in option '--attributes'; got name:string and name:integer") end end @@ -376,15 +375,15 @@ def remaining end it "accepts a switch= assignment" do - expect(parse("--attributes=a", "b", "c")["attributes"]).to eq(%w[a b c]) + expect(parse("--attributes=a", "b", "c")["attributes"]).to eq(%w(a b c)) end it "accepts a switch assignment" do - expect(parse("--attributes", "a", "b", "c")["attributes"]).to eq(%w[a b c]) + expect(parse("--attributes", "a", "b", "c")["attributes"]).to eq(%w(a b c)) end it "must not mix values with other switches" do - expect(parse("--attributes", "a", "b", "c", "--baz", "cool")["attributes"]).to eq(%w[a b c]) + expect(parse("--attributes", "a", "b", "c", "--baz", "cool")["attributes"]).to eq(%w(a b c)) end end @@ -413,6 +412,5 @@ def remaining "Expected '--limit' to be one of #{enum.join(', ')}; got 3") end end - end end diff --git a/spec/quality_spec.rb b/spec/quality_spec.rb index e4e438fe2..99efb6246 100644 --- a/spec/quality_spec.rb +++ b/spec/quality_spec.rb @@ -2,36 +2,30 @@ def check_for_spec_defs_with_single_quotes(filename) failing_lines = [] - File.readlines(filename).each_with_index do |line,number| + File.readlines(filename).each_with_index do |line, number| failing_lines << number + 1 if line =~ /^ *(describe|it|context) {1}'{1}/ end - unless failing_lines.empty? - "#{filename} uses inconsistent single quotes on lines #{failing_lines.join(', ')}" - end + "#{filename} uses inconsistent single quotes on lines #{failing_lines.join(', ')}" unless failing_lines.empty? end def check_for_tab_characters(filename) failing_lines = [] - File.readlines(filename).each_with_index do |line,number| + File.readlines(filename).each_with_index do |line, number| failing_lines << number + 1 if line =~ /\t/ end - unless failing_lines.empty? - "#{filename} has tab characters on lines #{failing_lines.join(', ')}" - end + "#{filename} has tab characters on lines #{failing_lines.join(', ')}" unless failing_lines.empty? end def check_for_extra_spaces(filename) failing_lines = [] - File.readlines(filename).each_with_index do |line,number| + File.readlines(filename).each_with_index do |line, number| next if line =~ /^\s+#.*\s+\n$/ failing_lines << number + 1 if line =~ /\s+\n$/ end - unless failing_lines.empty? - "#{filename} has spaces on the EOL on lines #{failing_lines.join(', ')}" - end + "#{filename} has spaces on the EOL on lines #{failing_lines.join(', ')}" unless failing_lines.empty? end RSpec::Matchers.define :be_well_formed do @@ -39,9 +33,7 @@ def check_for_extra_spaces(filename) actual.join("\n") end - match do |actual| - actual.empty? - end + match(&:empty?) end it "has no malformed whitespace" do diff --git a/spec/rake_compat_spec.rb b/spec/rake_compat_spec.rb index fac5c9c48..5a20556f3 100644 --- a/spec/rake_compat_spec.rb +++ b/spec/rake_compat_spec.rb @@ -32,7 +32,7 @@ class ThorTask < Thor describe Thor::RakeCompat do it "sets the rakefile application" do - expect(%w[rake_compat_spec.rb Thorfile]).to include(Rake.application.rakefile) + expect(%w(rake_compat_spec.rb Thorfile)).to include(Rake.application.rakefile) end it "adds rake tasks to thor classes too" do @@ -62,11 +62,11 @@ class ThorTask < Thor it "invoking the thor task invokes the rake task" do expect(capture(:stdout) do - ThorTask.start %w[cool] + ThorTask.start %w(cool) end).to eq("COOL\n") expect(capture(:stdout) do - ThorTask::HiperMega.start %w[super] + ThorTask::HiperMega.start %w(super) end).to eq("HIPER MEGA SUPER\n") end end diff --git a/spec/register_spec.rb b/spec/register_spec.rb index 2a08bae61..8d6b808eb 100644 --- a/spec/register_spec.rb +++ b/spec/register_spec.rb @@ -100,84 +100,91 @@ def with_args(*args) ExcitingPluginCLI, "exciting", "do exciting things", - "Various non-boring actions") + "Various non-boring actions" +) BoringVendorProvidedCLI.register( SuperSecretPlugin, "secret", "secret stuff", "Nothing to see here. Move along.", - :hide => true) + :hide => true +) BoringVendorProvidedCLI.register( GroupPlugin, "groupwork", "Do a bunch of things in a row", - "purple monkey dishwasher") + "purple monkey dishwasher" +) BoringVendorProvidedCLI.register( CompatibleWith19Plugin, "zoo", "zoo [-w animal]", - "Shows a provided animal or just zebra") + "Shows a provided animal or just zebra" +) BoringVendorProvidedCLI.register( PluginWithDefault, "say", "say message", - "subcommands ftw") + "subcommands ftw" +) BoringVendorProvidedCLI.register( PluginWithDefaultMultipleArguments, "say_multiple", "say message", - "subcommands ftw") + "subcommands ftw" +) BoringVendorProvidedCLI.register( PluginWithDefaultcommandAndDeclaredArgument, "say_argument", "say message", - "subcommands ftw") + "subcommands ftw" +) BoringVendorProvidedCLI.register(SubcommandWithDefault, "subcommand", "subcommand", "Run subcommands") describe ".register-ing a Thor subclass" do it "registers the plugin as a subcommand" do - fireworks_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[exciting fireworks]) } + fireworks_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w(exciting fireworks)) } expect(fireworks_output).to eq("kaboom!\n") end it "includes the plugin's usage in the help" do - help_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[help]) } + help_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w(help)) } expect(help_output).to include("do exciting things") end context "with a default command," do it "invokes the default command correctly" do - output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[say hello]) } + output = capture(:stdout) { BoringVendorProvidedCLI.start(%w(say hello)) } expect(output).to include("hello") end it "invokes the default command correctly with multiple args" do - output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[say_multiple hello adam]) } + output = capture(:stdout) { BoringVendorProvidedCLI.start(%w(say_multiple hello adam)) } expect(output).to include("hello") expect(output).to include("adam") end it "invokes the default command correctly with a declared argument" do - output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[say_argument hello]) } + output = capture(:stdout) { BoringVendorProvidedCLI.start(%w(say_argument hello)) } expect(output).to include("hello") end it "displays the subcommand's help message" do - output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[subcommand help]) } + output = capture(:stdout) { BoringVendorProvidedCLI.start(%w(subcommand help)) } expect(output).to include("default subcommand") expect(output).to include("subcommand with argument") end it "invokes commands with their actual args" do - output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[subcommand with_args actual_argument]) } + output = capture(:stdout) { BoringVendorProvidedCLI.start(%w(subcommand with_args actual_argument)) } expect(output.strip).to eql("received arguments: actual_argument") end end @@ -186,7 +193,7 @@ def with_args(*args) it "includes the plugin's subcommand name in subcommand's help" do begin $thor_runner = false - help_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[exciting]) } + help_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w(exciting)) } expect(help_output).to include("thor exciting_plugin_c_l_i fireworks") ensure $thor_runner = true @@ -196,12 +203,12 @@ def with_args(*args) context "when hidden" do it "omits the hidden plugin's usage from the help" do - help_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[help]) } + help_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w(help)) } expect(help_output).not_to include("secret stuff") end it "registers the plugin as a subcommand" do - secret_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[secret squirrel]) } + secret_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w(secret squirrel)) } expect(secret_output).to eq("I love nuts\n") end end @@ -209,19 +216,19 @@ def with_args(*args) describe ".register-ing a Thor::Group subclass" do it "registers the group as a single command" do - group_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[groupwork]) } + group_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w(groupwork)) } expect(group_output).to eq("part one\npart two\n") end end describe "1.8 and 1.9 syntax compatibility" do it "is compatible with both 1.8 and 1.9 syntax w/o command options" do - group_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[zoo]) } + group_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w(zoo)) } expect(group_output).to match(/zebra/) end it "is compatible with both 1.8 and 1.9 syntax w/command options" do - group_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[zoo -w lion]) } + group_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w(zoo -w lion)) } expect(group_output).to match(/lion/) end end diff --git a/spec/runner_spec.rb b/spec/runner_spec.rb index bf7688557..6a8cc67fa 100644 --- a/spec/runner_spec.rb +++ b/spec/runner_spec.rb @@ -14,40 +14,40 @@ def when_no_thorfiles_exist describe "#help" do it "shows information about Thor::Runner itself" do - expect(capture(:stdout) { Thor::Runner.start(%w[help]) }).to match(/List the available thor commands/) + expect(capture(:stdout) { Thor::Runner.start(%w(help)) }).to match(/List the available thor commands/) end it "shows information about a specific Thor::Runner command" do - content = capture(:stdout) { Thor::Runner.start(%w[help list]) } + content = capture(:stdout) { Thor::Runner.start(%w(help list)) } expect(content).to match(/List the available thor commands/) expect(content).not_to match(/help \[COMMAND\]/) end it "shows information about a specific Thor class" do - content = capture(:stdout) { Thor::Runner.start(%w[help my_script]) } + content = capture(:stdout) { Thor::Runner.start(%w(help my_script)) } expect(content).to match(/zoo\s+# zoo around/m) end it "shows information about a specific command from a specific Thor class" do - content = capture(:stdout) { Thor::Runner.start(%w[help my_script:zoo]) } + content = capture(:stdout) { Thor::Runner.start(%w(help my_script:zoo)) } expect(content).to match(/zoo around/) expect(content).not_to match(/help \[COMMAND\]/) end it "shows information about a specific Thor group class" do - content = capture(:stdout) { Thor::Runner.start(%w[help my_counter]) } + content = capture(:stdout) { Thor::Runner.start(%w(help my_counter)) } expect(content).to match(/my_counter N/) end it "raises error if a class/command cannot be found" do - content = capture(:stderr) { Thor::Runner.start(%w[help unknown]) } + content = capture(:stderr) { Thor::Runner.start(%w(help unknown)) } expect(content.strip).to eq('Could not find command "unknown" in "default" namespace.') end it "raises error if a class/command cannot be found for a setup without thorfiles" do when_no_thorfiles_exist do expect(Thor::Runner).to receive :exit - content = capture(:stderr) { Thor::Runner.start(%w[help unknown]) } + content = capture(:stderr) { Thor::Runner.start(%w(help unknown)) } expect(content.strip).to eq('Could not find command "unknown".') end end @@ -55,44 +55,44 @@ def when_no_thorfiles_exist describe "#start" do it "invokes a command from Thor::Runner" do - ARGV.replace %w[list] + ARGV.replace %w(list) expect(capture(:stdout) { Thor::Runner.start }).to match(/my_counter N/) end it "invokes a command from a specific Thor class" do - ARGV.replace %w[my_script:zoo] + ARGV.replace %w(my_script:zoo) expect(Thor::Runner.start).to be true end it "invokes the default command from a specific Thor class if none is specified" do - ARGV.replace %w[my_script] + ARGV.replace %w(my_script) expect(Thor::Runner.start).to eq("default command") end it "forwards arguments to the invoked command" do - ARGV.replace %w[my_script:animal horse] - expect(Thor::Runner.start).to eq(%w[horse]) + ARGV.replace %w(my_script:animal horse) + expect(Thor::Runner.start).to eq(%w(horse)) end it "invokes commands through shortcuts" do - ARGV.replace %w[my_script -T horse] - expect(Thor::Runner.start).to eq(%w[horse]) + ARGV.replace %w(my_script -T horse) + expect(Thor::Runner.start).to eq(%w(horse)) end it "invokes a Thor::Group" do - ARGV.replace %w[my_counter 1 2 --third 3] + ARGV.replace %w(my_counter 1 2 --third 3) expect(Thor::Runner.start).to eq([1, 2, 3, nil, nil, nil]) end it "raises an error if class/command can't be found" do - ARGV.replace %w[unknown] + ARGV.replace %w(unknown) content = capture(:stderr) { Thor::Runner.start } expect(content.strip).to eq('Could not find command "unknown" in "default" namespace.') end it "raises an error if class/command can't be found in a setup without thorfiles" do when_no_thorfiles_exist do - ARGV.replace %w[unknown] + ARGV.replace %w(unknown) expect(Thor::Runner).to receive :exit content = capture(:stderr) { Thor::Runner.start } expect(content.strip).to eq('Could not find command "unknown".') @@ -100,20 +100,20 @@ def when_no_thorfiles_exist end it "does not swallow NoMethodErrors that occur inside the called method" do - ARGV.replace %w[my_script:call_unexistent_method] + ARGV.replace %w(my_script:call_unexistent_method) expect { Thor::Runner.start }.to raise_error(NoMethodError) end it "does not swallow Thor::Group InvocationError" do - ARGV.replace %w[whiny_generator] + ARGV.replace %w(whiny_generator) expect { Thor::Runner.start }.to raise_error(ArgumentError, /thor wrong_arity takes 1 argument, but it should not/) end it "does not swallow Thor InvocationError" do - ARGV.replace %w[my_script:animal] + ARGV.replace %w(my_script:animal) content = capture(:stderr) { Thor::Runner.start } - expect(content.strip).to eq(%Q(ERROR: "thor animal" was called with no arguments -Usage: "thor my_script:animal TYPE")) + expect(content.strip).to eq('ERROR: "thor animal" was called with no arguments +Usage: "thor my_script:animal TYPE"') end end @@ -124,7 +124,7 @@ def when_no_thorfiles_exist "random" => { :location => @location, :filename => "4a33b894ffce85d7b412fc1b36f88fe0", - :namespaces => %w[amazing] + :namespaces => %w(amazing) } } @@ -138,54 +138,54 @@ def when_no_thorfiles_exist describe "list" do it "gives a list of the available commands" do - ARGV.replace %w[list] + ARGV.replace %w(list) content = capture(:stdout) { Thor::Runner.start } expect(content).to match(/amazing:describe NAME\s+# say that someone is amazing/m) end it "gives a list of the available Thor::Group classes" do - ARGV.replace %w[list] + ARGV.replace %w(list) expect(capture(:stdout) { Thor::Runner.start }).to match(/my_counter N/) end it "can filter a list of the available commands by --group" do - ARGV.replace %w[list --group standard] + ARGV.replace %w(list --group standard) expect(capture(:stdout) { Thor::Runner.start }).to match(/amazing:describe NAME/) ARGV.replace [] expect(capture(:stdout) { Thor::Runner.start }).not_to match(/my_script:animal TYPE/) - ARGV.replace %w[list --group script] + ARGV.replace %w(list --group script) expect(capture(:stdout) { Thor::Runner.start }).to match(/my_script:animal TYPE/) end it "can skip all filters to show all commands using --all" do - ARGV.replace %w[list --all] + ARGV.replace %w(list --all) content = capture(:stdout) { Thor::Runner.start } expect(content).to match(/amazing:describe NAME/) expect(content).to match(/my_script:animal TYPE/) end it "doesn't list superclass commands in the subclass" do - ARGV.replace %w[list] + ARGV.replace %w(list) expect(capture(:stdout) { Thor::Runner.start }).not_to match(/amazing:help/) end it "presents commands in the default namespace with an empty namespace" do - ARGV.replace %w[list] + ARGV.replace %w(list) expect(capture(:stdout) { Thor::Runner.start }).to match(/^thor :cow\s+# prints 'moo'/m) end it "runs commands with an empty namespace from the default namespace" do - ARGV.replace %w[:command_conflict] + ARGV.replace %w(:command_conflict) expect(capture(:stdout) { Thor::Runner.start }).to eq("command\n") end it "runs groups even when there is a command with the same name" do - ARGV.replace %w[command_conflict] + ARGV.replace %w(command_conflict) expect(capture(:stdout) { Thor::Runner.start }).to eq("group\n") end it "runs commands with no colon in the default namespace" do - ARGV.replace %w[cow] + ARGV.replace %w(cow) expect(capture(:stdout) { Thor::Runner.start }).to eq("moo\n") end end @@ -197,7 +197,7 @@ def when_no_thorfiles_exist end it "uninstalls existing thor modules" do - silence(:stdout) { Thor::Runner.start(%w[uninstall random]) } + silence(:stdout) { Thor::Runner.start(%w(uninstall random)) } end end @@ -207,7 +207,7 @@ def when_no_thorfiles_exist end it "displays the modules installed in a pretty way" do - stdout = capture(:stdout) { Thor::Runner.start(%w[installed]) } + stdout = capture(:stdout) { Thor::Runner.start(%w(installed)) } expect(stdout).to match(/random\s*amazing/) expect(stdout).to match(/amazing:describe NAME\s+# say that someone is amazing/m) end @@ -231,12 +231,12 @@ def when_no_thorfiles_exist expect(File).to receive(:delete).with(path) end silence_warnings do - silence(:stdout) { Thor::Runner.start(%w[update random]) } + silence(:stdout) { Thor::Runner.start(%w(update random)) } end end it "installs thor files" do - ARGV.replace %W[install #{@location}] + ARGV.replace %W(install #{@location}) silence_warnings do silence(:stdout) { Thor::Runner.start } end diff --git a/spec/shell/basic_spec.rb b/spec/shell/basic_spec.rb index da4a2c5a2..d5affc919 100644 --- a/spec/shell/basic_spec.rb +++ b/spec/shell/basic_spec.rb @@ -28,19 +28,19 @@ def shell end it "accepts custom indentation amounts" do - shell.indent(6) { + shell.indent(6) do expect(shell.padding).to eq(6) - } + end end it "increases the padding when nested" do - shell.indent { + shell.indent do expect(shell.padding).to eq(1) - shell.indent { + shell.indent do expect(shell.padding).to eq(2) - } - } + end + end expect(shell.padding).to eq(0) end end @@ -69,13 +69,13 @@ def shell end it "prints a message to the user with the available options and determines the correctness of the answer" do - flavors = %w[strawberry chocolate vanilla] + flavors = %w(strawberry chocolate vanilla) expect(Thor::LineEditor).to receive(:readline).with('What\'s your favorite Neopolitan flavor? [strawberry, chocolate, vanilla] ', :limited_to => flavors).and_return("chocolate") expect(shell.ask('What\'s your favorite Neopolitan flavor?', :limited_to => flavors)).to eq("chocolate") end it "prints a message to the user with the available options and reasks the question after an incorrect repsonse" do - flavors = %w[strawberry chocolate vanilla] + flavors = %w(strawberry chocolate vanilla) expect($stdout).to receive(:print).with("Your response must be one of: [strawberry, chocolate, vanilla]. Please try again.\n") expect(Thor::LineEditor).to receive(:readline).with('What\'s your favorite Neopolitan flavor? [strawberry, chocolate, vanilla] ', :limited_to => flavors).and_return("moose tracks", "chocolate") expect(shell.ask('What\'s your favorite Neopolitan flavor?', :limited_to => flavors)).to eq("chocolate") @@ -87,7 +87,7 @@ def shell end it "prints a message to the user with the available options and reasks the question after an incorrect repsonse and then returns the default" do - flavors = %w[strawberry chocolate vanilla] + flavors = %w(strawberry chocolate vanilla) expect($stdout).to receive(:print).with("Your response must be one of: [strawberry, chocolate, vanilla]. Please try again.\n") expect(Thor::LineEditor).to receive(:readline).with('What\'s your favorite Neopolitan flavor? [strawberry, chocolate, vanilla] (vanilla) ', :default => "vanilla", :limited_to => flavors).and_return("moose tracks", "") expect(shell.ask("What's your favorite Neopolitan flavor?", :default => "vanilla", :limited_to => flavors)).to eq("vanilla") diff --git a/spec/shell/color_spec.rb b/spec/shell/color_spec.rb index 867d55aa8..6ef4b5b79 100644 --- a/spec/shell/color_spec.rb +++ b/spec/shell/color_spec.rb @@ -16,7 +16,7 @@ def shell shell.ask "Is this green?", :green expect(Thor::LineEditor).to receive(:readline).with("\e[32mIs this green? [Yes, No, Maybe] \e[0m", anything).and_return("Yes") - shell.ask "Is this green?", :green, :limited_to => %w[Yes No Maybe] + shell.ask "Is this green?", :green, :limited_to => %w(Yes No Maybe) end it "handles an Array of colors" do @@ -71,7 +71,6 @@ def shell expect(out.chomp).to eq("\e[1m\e[34mWow! This still works?\e[0m") end - end describe "#say_status" do diff --git a/spec/shell_spec.rb b/spec/shell_spec.rb index 17e4d7812..50adcf3f7 100644 --- a/spec/shell_spec.rb +++ b/spec/shell_spec.rb @@ -43,5 +43,4 @@ class Thor::Shell::TestShell < Thor::Shell::Basic; end end end end - end diff --git a/spec/subcommand_spec.rb b/spec/subcommand_spec.rb index f189f2172..554ec06eb 100644 --- a/spec/subcommand_spec.rb +++ b/spec/subcommand_spec.rb @@ -1,48 +1,45 @@ require "helper" describe Thor do - describe "#subcommand" do - it "maps a given subcommand to another Thor subclass" do - barn_help = capture(:stdout) { Scripts::MyDefaults.start(%w[barn]) } + barn_help = capture(:stdout) { Scripts::MyDefaults.start(%w(barn)) } expect(barn_help).to include("barn help [COMMAND] # Describe subcommands or one specific subcommand") end it "passes commands to subcommand classes" do - expect(capture(:stdout) { Scripts::MyDefaults.start(%w[barn open]) }.strip).to eq("Open sesame!") + expect(capture(:stdout) { Scripts::MyDefaults.start(%w(barn open)) }.strip).to eq("Open sesame!") end it "passes arguments to subcommand classes" do - expect(capture(:stdout) { Scripts::MyDefaults.start(%w[barn open shotgun]) }.strip).to eq("That's going to leave a mark.") + expect(capture(:stdout) { Scripts::MyDefaults.start(%w(barn open shotgun)) }.strip).to eq("That's going to leave a mark.") end it "ignores unknown options (the subcommand class will handle them)" do - expect(capture(:stdout) { Scripts::MyDefaults.start(%w[barn paint blue --coats 4]) }.strip).to eq("4 coats of blue paint") + expect(capture(:stdout) { Scripts::MyDefaults.start(%w(barn paint blue --coats 4)) }.strip).to eq("4 coats of blue paint") end it "passes parsed options to subcommands" do - output = capture(:stdout) { TestSubcommands::Parent.start(%w[sub print_opt --opt output]) } + output = capture(:stdout) { TestSubcommands::Parent.start(%w(sub print_opt --opt output)) } expect(output).to eq("output") end it "accepts the help switch and calls the help command on the subcommand" do - output = capture(:stdout) { TestSubcommands::Parent.start(%w[sub print_opt --help]) } - sub_help = capture(:stdout) { TestSubcommands::Parent.start(%w[sub help print_opt]) } + output = capture(:stdout) { TestSubcommands::Parent.start(%w(sub print_opt --help)) } + sub_help = capture(:stdout) { TestSubcommands::Parent.start(%w(sub help print_opt)) } expect(output).to eq(sub_help) end it "accepts the help short switch and calls the help command on the subcommand" do - output = capture(:stdout) { TestSubcommands::Parent.start(%w[sub print_opt -h]) } - sub_help = capture(:stdout) { TestSubcommands::Parent.start(%w[sub help print_opt]) } + output = capture(:stdout) { TestSubcommands::Parent.start(%w(sub print_opt -h)) } + sub_help = capture(:stdout) { TestSubcommands::Parent.start(%w(sub help print_opt)) } expect(output).to eq(sub_help) end it "the help command on the subcommand and after it should result in the same output" do - output = capture(:stdout) { TestSubcommands::Parent.start(%w[sub help])} - sub_help = capture(:stdout) { TestSubcommands::Parent.start(%w[help sub])} + output = capture(:stdout) { TestSubcommands::Parent.start(%w(sub help)) } + sub_help = capture(:stdout) { TestSubcommands::Parent.start(%w(help sub)) } expect(output).to eq(sub_help) end end - end diff --git a/spec/thor_spec.rb b/spec/thor_spec.rb index 60c987c77..5d945ee91 100644 --- a/spec/thor_spec.rb +++ b/spec/thor_spec.rb @@ -3,59 +3,59 @@ describe Thor do describe "#method_option" do it "sets options to the next method to be invoked" do - args = %w[foo bar --force] + args = %w(foo bar --force) _, options = MyScript.start(args) expect(options).to eq("force" => true) end describe ":lazy_default" do it "is absent when option is not specified" do - _, options = MyScript.start(%w[with_optional]) + _, options = MyScript.start(%w(with_optional)) expect(options).to eq({}) end it "sets a default that can be overridden for strings" do - _, options = MyScript.start(%w[with_optional --lazy]) + _, options = MyScript.start(%w(with_optional --lazy)) expect(options).to eq("lazy" => "yes") - _, options = MyScript.start(%w[with_optional --lazy yesyes!]) + _, options = MyScript.start(%w(with_optional --lazy yesyes!)) expect(options).to eq("lazy" => "yesyes!") end it "sets a default that can be overridden for numerics" do - _, options = MyScript.start(%w[with_optional --lazy-numeric]) + _, options = MyScript.start(%w(with_optional --lazy-numeric)) expect(options).to eq("lazy_numeric" => 42) - _, options = MyScript.start(%w[with_optional --lazy-numeric 20000]) + _, options = MyScript.start(%w(with_optional --lazy-numeric 20000)) expect(options).to eq("lazy_numeric" => 20_000) end it "sets a default that can be overridden for arrays" do - _, options = MyScript.start(%w[with_optional --lazy-array]) - expect(options).to eq("lazy_array" => %w[eat at joes]) + _, options = MyScript.start(%w(with_optional --lazy-array)) + expect(options).to eq("lazy_array" => %w(eat at joes)) - _, options = MyScript.start(%w[with_optional --lazy-array hello there]) - expect(options).to eq("lazy_array" => %w[hello there]) + _, options = MyScript.start(%w(with_optional --lazy-array hello there)) + expect(options).to eq("lazy_array" => %w(hello there)) end it "sets a default that can be overridden for hashes" do - _, options = MyScript.start(%w[with_optional --lazy-hash]) + _, options = MyScript.start(%w(with_optional --lazy-hash)) expect(options).to eq("lazy_hash" => {"swedish" => "meatballs"}) - _, options = MyScript.start(%w[with_optional --lazy-hash polish:sausage]) + _, options = MyScript.start(%w(with_optional --lazy-hash polish:sausage)) expect(options).to eq("lazy_hash" => {"polish" => "sausage"}) end end describe "when :for is supplied" do it "updates an already defined command" do - _, options = MyChildScript.start(%w[animal horse --other=fish]) + _, options = MyChildScript.start(%w(animal horse --other=fish)) expect(options[:other]).to eq("fish") end describe "and the target is on the parent class" do it "updates an already defined command" do - args = %w[example_default_command my_param --new-option=verified] + args = %w(example_default_command my_param --new-option=verified) options = Scripts::MyScript.start(args) expect(options[:new_option]).to eq("verified") end @@ -81,7 +81,7 @@ end it "invokes the default command if no command is specified even if switches are given" do - expect(MyScript.start(%w[--with option])).to eq("with" => "option") + expect(MyScript.start(%w(--with option))).to eq("with" => "option") end it "inherits the default command from parent" do @@ -108,27 +108,27 @@ def boring(*args) end it "passes remaining args to command when it encounters a non-option" do - expect(my_script.start(%w[exec command --verbose])).to eq [{}, %w[command --verbose]] + expect(my_script.start(%w(exec command --verbose))).to eq [{}, %w(command --verbose)] end it "passes remaining args to command when it encounters an unknown option" do - expect(my_script.start(%w[exec --foo command --bar])).to eq [{}, %w[--foo command --bar]] + expect(my_script.start(%w(exec --foo command --bar))).to eq [{}, %w(--foo command --bar)] end it "still accepts options that are given before non-options" do - expect(my_script.start(%w[exec --verbose command --foo])).to eq [{"verbose" => true}, %w[command --foo]] + expect(my_script.start(%w(exec --verbose command --foo))).to eq [{"verbose" => true}, %w(command --foo)] end it "still accepts options that require a value" do - expect(my_script.start(%w[exec --mode rashly command])).to eq [{"mode" => "rashly"}, %w[command]] + expect(my_script.start(%w(exec --mode rashly command))).to eq [{"mode" => "rashly"}, %w(command)] end it "still passes everything after -- to command" do - expect(my_script.start(%w[exec -- --verbose])).to eq [{}, %w[--verbose]] + expect(my_script.start(%w(exec -- --verbose))).to eq [{}, %w(--verbose)] end - it "does not affect ordinary commands" do - expect(my_script.start(%w[boring command --verbose])).to eq [{"verbose" => true}, %w[command]] + it "does not affect ordinary commands" do + expect(my_script.start(%w(boring command --verbose))).to eq [{"verbose" => true}, %w(command)] end context "when provided with multiple command names" do @@ -161,12 +161,12 @@ def boring(*args) describe "#map" do it "calls the alias of a method if one is provided" do - expect(MyScript.start(%w[-T fish])).to eq(%w[fish]) + expect(MyScript.start(%w(-T fish))).to eq(%w(fish)) end it "calls the alias of a method if several are provided via #map" do - expect(MyScript.start(%w[-f fish])).to eq(["fish", {}]) - expect(MyScript.start(%w[--foo fish])).to eq(["fish", {}]) + expect(MyScript.start(%w(-f fish))).to eq(["fish", {}]) + expect(MyScript.start(%w(--foo fish))).to eq(["fish", {}]) end it "inherits all mappings from parent" do @@ -176,27 +176,27 @@ def boring(*args) describe "#package_name" do it "provides a proper description for a command when the package_name is assigned" do - content = capture(:stdout) { PackageNameScript.start(%w[help]) } + content = capture(:stdout) { PackageNameScript.start(%w(help)) } expect(content).to match(/Baboon commands:/m) end # TODO: remove this, might be redundant, just wanted to prove full coverage it "provides a proper description for a command when the package_name is NOT assigned" do - content = capture(:stdout) { MyScript.start(%w[help]) } + content = capture(:stdout) { MyScript.start(%w(help)) } expect(content).to match(/Commands:/m) end end describe "#desc" do it "provides description for a command" do - content = capture(:stdout) { MyScript.start(%w[help]) } + content = capture(:stdout) { MyScript.start(%w(help)) } expect(content).to match(/thor my_script:zoo\s+# zoo around/m) end it "provides no namespace if $thor_runner is false" do begin $thor_runner = false - content = capture(:stdout) { MyScript.start(%w[help]) } + content = capture(:stdout) { MyScript.start(%w(help)) } expect(content).to match(/thor zoo\s+# zoo around/m) ensure $thor_runner = true @@ -205,17 +205,17 @@ def boring(*args) describe "when :for is supplied" do it "overwrites a previous defined command" do - expect(capture(:stdout) { MyChildScript.start(%w[help]) }).to match(/animal KIND \s+# fish around/m) + expect(capture(:stdout) { MyChildScript.start(%w(help)) }).to match(/animal KIND \s+# fish around/m) end end describe "when :hide is supplied" do it "does not show the command in help" do - expect(capture(:stdout) { MyScript.start(%w[help]) }).not_to match(/this is hidden/m) + expect(capture(:stdout) { MyScript.start(%w(help)) }).not_to match(/this is hidden/m) end it "but the command is still invokable, does not show the command in help" do - expect(MyScript.start(%w[hidden yesyes])).to eq(%w[yesyes]) + expect(MyScript.start(%w(hidden yesyes))).to eq(%w(yesyes)) end end end @@ -228,13 +228,13 @@ def boring(*args) end it "overwrites default options if called on the method scope" do - args = %w[zoo --force --param feathers] + args = %w(zoo --force --param feathers) options = MyChildScript.start(args) expect(options).to eq("force" => true, "param" => "feathers") end it "allows default options to be merged with method options" do - args = %w[animal bird --force --param 1.0 --other tweets] + args = %w(animal bird --force --param 1.0 --other tweets) arg, options = MyChildScript.start(args) expect(arg).to eq("bird") expect(options).to eq("force" => true, "param" => 1.0, "other" => "tweets") @@ -243,15 +243,15 @@ def boring(*args) describe "#start" do it "calls a no-param method when no params are passed" do - expect(MyScript.start(%w[zoo])).to eq(true) + expect(MyScript.start(%w(zoo))).to eq(true) end it "calls a single-param method when a single param is passed" do - expect(MyScript.start(%w[animal fish])).to eq(%w[fish]) + expect(MyScript.start(%w(animal fish))).to eq(%w(fish)) end it "does not set options in attributes" do - expect(MyScript.start(%w[with_optional --all])).to eq([nil, {"all" => true}, []]) + expect(MyScript.start(%w(with_optional --all))).to eq([nil, {"all" => true}, []]) end it "raises an error if the wrong number of params are provided" do @@ -259,52 +259,52 @@ def boring(*args) stderr = capture(:stderr) { Scripts::Arities.start(args) } expect(stderr.strip).to eq(msg) end - arity_asserter.call %w[zero_args one], %Q(ERROR: "thor zero_args" was called with arguments ["one"] -Usage: "thor scripts:arities:zero_args") - arity_asserter.call %w[one_arg], %Q(ERROR: "thor one_arg" was called with no arguments -Usage: "thor scripts:arities:one_arg ARG") - arity_asserter.call %w[one_arg one two], %Q(ERROR: "thor one_arg" was called with arguments ["one", "two"] -Usage: "thor scripts:arities:one_arg ARG") - arity_asserter.call %w[one_arg one two], %Q(ERROR: "thor one_arg" was called with arguments ["one", "two"] -Usage: "thor scripts:arities:one_arg ARG") - arity_asserter.call %w[two_args one], %Q(ERROR: "thor two_args" was called with arguments ["one"] -Usage: "thor scripts:arities:two_args ARG1 ARG2") - arity_asserter.call %w[optional_arg one two], %Q(ERROR: "thor optional_arg" was called with arguments ["one", "two"] -Usage: "thor scripts:arities:optional_arg [ARG]") + arity_asserter.call %w(zero_args one), 'ERROR: "thor zero_args" was called with arguments ["one"] +Usage: "thor scripts:arities:zero_args"' + arity_asserter.call %w(one_arg), 'ERROR: "thor one_arg" was called with no arguments +Usage: "thor scripts:arities:one_arg ARG"' + arity_asserter.call %w(one_arg one two), 'ERROR: "thor one_arg" was called with arguments ["one", "two"] +Usage: "thor scripts:arities:one_arg ARG"' + arity_asserter.call %w(one_arg one two), 'ERROR: "thor one_arg" was called with arguments ["one", "two"] +Usage: "thor scripts:arities:one_arg ARG"' + arity_asserter.call %w(two_args one), 'ERROR: "thor two_args" was called with arguments ["one"] +Usage: "thor scripts:arities:two_args ARG1 ARG2"' + arity_asserter.call %w(optional_arg one two), 'ERROR: "thor optional_arg" was called with arguments ["one", "two"] +Usage: "thor scripts:arities:optional_arg [ARG]"' end it "raises an error if the invoked command does not exist" do - expect(capture(:stderr) { Amazing.start(%w[animal]) }.strip).to eq('Could not find command "animal" in "amazing" namespace.') + expect(capture(:stderr) { Amazing.start(%w(animal)) }.strip).to eq('Could not find command "animal" in "amazing" namespace.') end it "calls method_missing if an unknown method is passed in" do - expect(MyScript.start(%w[unk hello])).to eq([:unk, %w[hello]]) + expect(MyScript.start(%w(unk hello))).to eq([:unk, %w(hello)]) end it "does not call a private method no matter what" do - expect(capture(:stderr) { MyScript.start(%w[what]) }.strip).to eq('Could not find command "what" in "my_script" namespace.') + expect(capture(:stderr) { MyScript.start(%w(what)) }.strip).to eq('Could not find command "what" in "my_script" namespace.') end it "uses command default options" do - options = MyChildScript.start(%w[animal fish]).last + options = MyChildScript.start(%w(animal fish)).last expect(options).to eq("other" => "method default") end it "raises when an exception happens within the command call" do - expect { MyScript.start(%w[call_myself_with_wrong_arity]) }.to raise_error(ArgumentError) + expect { MyScript.start(%w(call_myself_with_wrong_arity)) }.to raise_error(ArgumentError) end context "when the user enters an unambiguous substring of a command" do it "invokes a command" do - expect(MyScript.start(%w[z])).to eq(MyScript.start(%w[zoo])) + expect(MyScript.start(%w(z))).to eq(MyScript.start(%w(zoo))) end it "invokes a command, even when there's an alias it resolves to the same command" do - expect(MyScript.start(%w[hi arg])).to eq(MyScript.start(%w[hidden arg])) + expect(MyScript.start(%w(hi arg))).to eq(MyScript.start(%w(hidden arg))) end it "invokes an alias" do - expect(MyScript.start(%w[animal_pri])).to eq(MyScript.start(%w[zoo])) + expect(MyScript.start(%w(animal_pri))).to eq(MyScript.start(%w(zoo))) end end @@ -312,16 +312,15 @@ def boring(*args) it "raises an exception and displays a message that explains the ambiguity" do shell = Thor::Base.shell.new expect(shell).to receive(:error).with("Ambiguous command call matches [call_myself_with_wrong_arity, call_unexistent_method]") - MyScript.start(%w[call], :shell => shell) + MyScript.start(%w(call), :shell => shell) end it "raises an exception when there is an alias" do shell = Thor::Base.shell.new expect(shell).to receive(:error).with("Ambiguous command f matches [foo, fu]") - MyScript.start(%w[f], :shell => shell) + MyScript.start(%w(f), :shell => shell) end end - end describe "#help" do @@ -415,11 +414,11 @@ def shell describe "instance method" do it "calls the class method" do - expect(capture(:stdout) { MyScript.start(%w[help]) }).to match(/Commands:/) + expect(capture(:stdout) { MyScript.start(%w(help)) }).to match(/Commands:/) end it "calls the class method" do - expect(capture(:stdout) { MyScript.start(%w[help foo]) }).to match(/Usage:/) + expect(capture(:stdout) { MyScript.start(%w(help foo)) }).to match(/Usage:/) end end @@ -435,7 +434,7 @@ def bar end it "shows the command help" do - content = capture(:stdout) { klass.start(%w{help}) } + content = capture(:stdout) { klass.start(%w(help)) } expect(content).to match(/Commands:/) end end @@ -445,11 +444,11 @@ def bar it "triggers a subcommand help when passed --help" do parent = Class.new(Thor) child = Class.new(Thor) - parent.desc 'child', 'child subcommand' - parent.subcommand 'child', child - parent.desc 'dummy', 'dummy' + parent.desc "child", "child subcommand" + parent.subcommand "child", child + parent.desc "dummy", "dummy" expect(child).to receive(:help).with(anything, anything) - parent.start ['child', '--help'] + parent.start ["child", "--help"] end end @@ -480,9 +479,9 @@ def hi(name) end end - expect(klass.start(%w[hi jose])).to eq("Hi jose") - expect(klass.start(%w[hi jose --loud])).to eq("Hi JOSE") - expect(klass.start(%w[hi --loud jose])).to eq("Hi JOSE") + expect(klass.start(%w(hi jose))).to eq("Hi jose") + expect(klass.start(%w(hi jose --loud))).to eq("Hi JOSE") + expect(klass.start(%w(hi --loud jose))).to eq("Hi JOSE") end it "passes through unknown options" do @@ -493,8 +492,8 @@ def unknown(*args) end end - expect(klass.start(%w[unknown foo --bar baz bat --bam])).to eq(%w[foo --bar baz bat --bam]) - expect(klass.start(%w[unknown --bar baz])).to eq(%w[--bar baz]) + expect(klass.start(%w(unknown foo --bar baz bat --bam))).to eq(%w(foo --bar baz bat --bam)) + expect(klass.start(%w(unknown --bar baz))).to eq(%w(--bar baz)) end it "does not pass through unknown options with strict args" do @@ -507,8 +506,8 @@ def unknown(*args) end end - expect(klass.start(%w[unknown --bar baz])).to eq([]) - expect(klass.start(%w[unknown foo --bar baz])).to eq(%w[foo]) + expect(klass.start(%w(unknown --bar baz))).to eq([]) + expect(klass.start(%w(unknown foo --bar baz))).to eq(%w(foo)) end it "strict args works in the inheritance chain" do @@ -523,12 +522,12 @@ def unknown(*args) end end - expect(klass.start(%w[unknown --bar baz])).to eq([]) - expect(klass.start(%w[unknown foo --bar baz])).to eq(%w[foo]) + expect(klass.start(%w(unknown --bar baz))).to eq([]) + expect(klass.start(%w(unknown foo --bar baz))).to eq(%w(foo)) end it "send as a command name" do - expect(MyScript.start(%w[send])).to eq(true) + expect(MyScript.start(%w(send))).to eq(true) end end end diff --git a/spec/util_spec.rb b/spec/util_spec.rb index 9fe213c34..af6812053 100644 --- a/spec/util_spec.rb +++ b/spec/util_spec.rb @@ -131,17 +131,17 @@ def self.clear_user_home! it "returns the *nix system path if file cannot be expanded and separator does not exist" do expect(File).to receive(:expand_path).with("~").and_raise(RuntimeError) previous_value = File::ALT_SEPARATOR - capture(:stderr) { File.const_set(:ALT_SEPARATOR, false) } # rubocop:disable SymbolName + capture(:stderr) { File.const_set(:ALT_SEPARATOR, false) } expect(Thor::Util.user_home).to eq("/") - capture(:stderr) { File.const_set(:ALT_SEPARATOR, previous_value) } # rubocop:disable SymbolName + capture(:stderr) { File.const_set(:ALT_SEPARATOR, previous_value) } end it "returns the windows system path if file cannot be expanded and a separator exists" do expect(File).to receive(:expand_path).with("~").and_raise(RuntimeError) previous_value = File::ALT_SEPARATOR - capture(:stderr) { File.const_set(:ALT_SEPARATOR, true) } # rubocop:disable SymbolName + capture(:stderr) { File.const_set(:ALT_SEPARATOR, true) } expect(Thor::Util.user_home).to eq("C:/") - capture(:stderr) { File.const_set(:ALT_SEPARATOR, previous_value) } # rubocop:disable SymbolName + capture(:stderr) { File.const_set(:ALT_SEPARATOR, previous_value) } end it "returns HOME/.thor if set" do diff --git a/thor.gemspec b/thor.gemspec index c4d33829e..567e6719d 100644 --- a/thor.gemspec +++ b/thor.gemspec @@ -8,13 +8,13 @@ Gem::Specification.new do |spec| spec.authors = ["Yehuda Katz", "José Valim"] spec.description = "Thor is a toolkit for building powerful command-line interfaces." spec.email = "ruby-thor@googlegroups.com" - spec.executables = %w[thor] - spec.files = %w[.document thor.gemspec] + Dir['*.md', 'bin/*', 'lib/**/*.rb'] + spec.executables = %w(thor) + spec.files = %w(.document thor.gemspec) + Dir["*.md", "bin/*", "lib/**/*.rb"] spec.homepage = "http://whatisthor.com/" - spec.licenses = %w[MIT] + spec.licenses = %w(MIT) spec.name = "thor" - spec.require_paths = %w[lib] - spec.required_ruby_version = '>= 1.8.7' + spec.require_paths = %w(lib) + spec.required_ruby_version = ">= 1.8.7" spec.required_rubygems_version = ">= 1.3.5" spec.summary = spec.description spec.version = Thor::VERSION