Hello community, here is the log from the commit of package rubygem-thor for openSUSE:Factory checked in at 2019-12-14 12:21:43 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/rubygem-thor (Old) and /work/SRC/openSUSE:Factory/.rubygem-thor.new.4691 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rubygem-thor" Sat Dec 14 12:21:43 2019 rev:21 rq:756942 version:1.0.0 Changes: -------- --- /work/SRC/openSUSE:Factory/rubygem-thor/rubygem-thor.changes 2018-11-20 22:43:38.798255821 +0100 +++ /work/SRC/openSUSE:Factory/.rubygem-thor.new.4691/rubygem-thor.changes 2019-12-14 12:23:57.879194021 +0100 @@ -1,0 +2,16 @@ +Sat Dec 14 00:31:01 UTC 2019 - Manuel Schnitzer <[email protected]> + +- updated to version 1.0.0 + + * Drop support to Ruby 1.8 and 1.9. + * Deprecate relying on default `exit_on_failure?`. + In preparation to make Thor commands exit when there is a failure we are deprecating + defining a command without defining what behavior is expected when there is a failure. + + To fix the deprecation you need to define a class method called `exit_on_failure?` returning + + `false` if you want the current behavior or `true` if you want the new behavior. + * Deprecate defining an option with the default value using a different type as defined in the option. + * Allow options to be repeatable. See #674. + +------------------------------------------------------------------- Old: ---- thor-0.20.3.gem New: ---- thor-1.0.0.gem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ rubygem-thor.spec ++++++ --- /var/tmp/diff_new_pack.iLcMA1/_old 2019-12-14 12:23:58.315193955 +0100 +++ /var/tmp/diff_new_pack.iLcMA1/_new 2019-12-14 12:23:58.315193955 +0100 @@ -1,7 +1,7 @@ # # spec file for package rubygem-thor # -# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -12,7 +12,7 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # @@ -24,12 +24,12 @@ # Name: rubygem-thor -Version: 0.20.3 +Version: 1.0.0 Release: 0 %define mod_name thor %define mod_full_name %{mod_name}-%{version} BuildRoot: %{_tmppath}/%{name}-%{version}-build -BuildRequires: %{ruby >= 1.8.7} +BuildRequires: %{ruby >= 2.0.0} BuildRequires: %{rubygem gem2rpm} BuildRequires: ruby-macros >= 5 BuildRequires: update-alternatives ++++++ thor-0.20.3.gem -> thor-1.0.0.gem ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/CHANGELOG.md new/CHANGELOG.md --- old/CHANGELOG.md 2018-11-10 04:00:18.000000000 +0100 +++ new/CHANGELOG.md 2019-12-13 20:32:01.000000000 +0100 @@ -1,3 +1,15 @@ +# 1.0.0 +* Drop support to Ruby 1.8 and 1.9. +* Deprecate relying on default `exit_on_failure?`. + In preparation to make Thor commands exit when there is a failure we are deprecating + defining a command without defining what behavior is expected when there is a failure. + + To fix the deprecation you need to define a class method called `exit_on_failure?` returning + + `false` if you want the current behavior or `true` if you want the new behavior. +* Deprecate defining an option with the default value using a different type as defined in the option. +* Allow options to be repeatable. See #674. + # 0.20.3 * Support old versions of `did_you_mean`. @@ -5,7 +17,7 @@ * Fix `did_you_mean` support. # 0.20.1 -* Support new versions fo ERB. +* Support new versions of ERB. * Fix `check_unknown_options!` to not check the content that was not parsed, i.e. after a `--` or after the first unknown with `stop_on_unknown_option!` * Add `did_you_mean` support. Binary files old/checksums.yaml.gz and new/checksums.yaml.gz differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/thor/actions/create_file.rb new/lib/thor/actions/create_file.rb --- old/lib/thor/actions/create_file.rb 2018-11-10 04:00:18.000000000 +0100 +++ new/lib/thor/actions/create_file.rb 2019-12-13 20:32:01.000000000 +0100 @@ -1,4 +1,4 @@ -require "thor/actions/empty_directory" +require_relative "empty_directory" class Thor module Actions diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/thor/actions/create_link.rb new/lib/thor/actions/create_link.rb --- old/lib/thor/actions/create_link.rb 2018-11-10 04:00:18.000000000 +0100 +++ new/lib/thor/actions/create_link.rb 2019-12-13 20:32:01.000000000 +0100 @@ -1,4 +1,4 @@ -require "thor/actions/create_file" +require_relative "create_file" class Thor module Actions diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/thor/actions/directory.rb new/lib/thor/actions/directory.rb --- old/lib/thor/actions/directory.rb 2018-11-10 04:00:18.000000000 +0100 +++ new/lib/thor/actions/directory.rb 2019-12-13 20:32:01.000000000 +0100 @@ -1,4 +1,4 @@ -require "thor/actions/empty_directory" +require_relative "empty_directory" class Thor module Actions @@ -56,7 +56,7 @@ attr_reader :source def initialize(base, source, destination = nil, config = {}, &block) - @source = File.expand_path(base.find_in_source_paths(source.to_s)) + @source = File.expand_path(Dir[Util.escape_globs(base.find_in_source_paths(source.to_s))].first) @block = block super(base, destination, {:recursive => true}.merge(config)) end @@ -96,22 +96,12 @@ end end - if RUBY_VERSION < "2.0" - def file_level_lookup(previous_lookup) - File.join(previous_lookup, "{*,.[a-z]*}") - end - - def files(lookup) - Dir[lookup] - end - else - def file_level_lookup(previous_lookup) - File.join(previous_lookup, "*") - end + def file_level_lookup(previous_lookup) + File.join(previous_lookup, "*") + end - def files(lookup) - Dir.glob(lookup, File::FNM_DOTMATCH) - end + def files(lookup) + Dir.glob(lookup, File::FNM_DOTMATCH) end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/thor/actions/file_manipulation.rb new/lib/thor/actions/file_manipulation.rb --- old/lib/thor/actions/file_manipulation.rb 2018-11-10 04:00:18.000000000 +0100 +++ new/lib/thor/actions/file_manipulation.rb 2019-12-13 20:32:01.000000000 +0100 @@ -23,14 +23,14 @@ destination = args.first || source source = File.expand_path(find_in_source_paths(source.to_s)) - create_file destination, nil, config do + resulting_destination = create_file destination, nil, config do content = File.binread(source) content = yield(content) if block content end if config[:mode] == :preserve mode = File.stat(source).mode - chmod(destination, mode, config) + chmod(resulting_destination, mode, config) end end @@ -80,14 +80,14 @@ config = args.last.is_a?(Hash) ? args.pop : {} destination = args.first - if source =~ %r{^https?\://} + render = if source =~ %r{^https?\://} require "open-uri" + URI.send(:open, source) { |input| input.binmode.read } else source = File.expand_path(find_in_source_paths(source.to_s)) + open(source) { |input| input.binmode.read } end - render = open(source) { |input| input.binmode.read } - destination ||= if block_given? block.arity == 1 ? yield(render) : yield else diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/thor/actions/inject_into_file.rb new/lib/thor/actions/inject_into_file.rb --- old/lib/thor/actions/inject_into_file.rb 2018-11-10 04:00:18.000000000 +0100 +++ new/lib/thor/actions/inject_into_file.rb 2019-12-13 20:32:01.000000000 +0100 @@ -1,4 +1,4 @@ -require "thor/actions/empty_directory" +require_relative "empty_directory" class Thor module Actions @@ -21,9 +21,14 @@ # gems.split(" ").map{ |gem| " config.gem :#{gem}" }.join("\n") # end # + WARNINGS = { unchanged_no_flag: 'File unchanged! The supplied flag value not found!' } + def insert_into_file(destination, *args, &block) data = block_given? ? block : args.shift - config = args.shift + + config = args.shift || {} + config[:after] = /\z/ unless config.key?(:before) || config.key?(:after) + action InjectIntoFile.new(self, destination, data, config) end alias_method :inject_into_file, :insert_into_file @@ -45,8 +50,6 @@ end def invoke! - say_status :invoke - content = if @behavior == :after '\0' + replacement else @@ -54,7 +57,11 @@ end if exists? - replace!(/#{flag}/, content, config[:force]) + if replace!(/#{flag}/, content, config[:force]) + say_status(:invoke) + else + say_status(:unchanged, warning: WARNINGS[:unchanged_no_flag], color: :red) + end else unless pretend? raise Thor::Error, "The file #{ destination } does not appear to exist" @@ -78,7 +85,7 @@ protected - def say_status(behavior) + def say_status(behavior, warning: nil, color: nil) status = if behavior == :invoke if flag == /\A/ :prepend @@ -87,11 +94,13 @@ else :insert end + elsif warning + warning else :subtract end - super(status, config[:verbose]) + super(status, (color || config[:verbose])) end # Adds the content to the file. @@ -100,8 +109,10 @@ return if pretend? content = File.read(destination) if force || !content.include?(replacement) - content.gsub!(regexp, string) + success = content.gsub!(regexp, string) + File.open(destination, "wb") { |file| file.write(content) } + success end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/thor/actions.rb new/lib/thor/actions.rb --- old/lib/thor/actions.rb 2018-11-10 04:00:18.000000000 +0100 +++ new/lib/thor/actions.rb 2019-12-13 20:32:01.000000000 +0100 @@ -1,17 +1,16 @@ -require "uri" -require "thor/core_ext/io_binary_read" -require "thor/actions/create_file" -require "thor/actions/create_link" -require "thor/actions/directory" -require "thor/actions/empty_directory" -require "thor/actions/file_manipulation" -require "thor/actions/inject_into_file" +require_relative "actions/create_file" +require_relative "actions/create_link" +require_relative "actions/directory" +require_relative "actions/empty_directory" +require_relative "actions/file_manipulation" +require_relative "actions/inject_into_file" class Thor module Actions attr_accessor :behavior def self.included(base) #:nodoc: + super(base) base.extend ClassMethods end @@ -257,13 +256,19 @@ return if options[:pretend] - result = config[:capture] ? `#{command}` : system(command.to_s) + env_splat = [config[:env]] if config[:env] - if config[:abort_on_failure] - success = config[:capture] ? $?.success? : result - abort unless success + if config[:capture] + require "open3" + result, status = Open3.capture2e(*env_splat, command.to_s) + success = status.success? + else + result = system(*env_splat, command.to_s) + success = result end + abort if !success && config.fetch(:abort_on_failure, self.class.exit_on_failure?) + result end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/thor/base.rb new/lib/thor/base.rb --- old/lib/thor/base.rb 2018-11-10 04:00:18.000000000 +0100 +++ new/lib/thor/base.rb 2019-12-13 20:32:01.000000000 +0100 @@ -1,17 +1,17 @@ -require "thor/command" -require "thor/core_ext/hash_with_indifferent_access" -require "thor/core_ext/ordered_hash" -require "thor/error" -require "thor/invocation" -require "thor/parser" -require "thor/shell" -require "thor/line_editor" -require "thor/util" +require_relative "command" +require_relative "core_ext/hash_with_indifferent_access" +require_relative "error" +require_relative "invocation" +require_relative "nested_context" +require_relative "parser" +require_relative "shell" +require_relative "line_editor" +require_relative "util" class Thor - autoload :Actions, "thor/actions" - autoload :RakeCompat, "thor/rake_compat" - autoload :Group, "thor/group" + autoload :Actions, File.expand_path("actions", __dir__) + autoload :RakeCompat, File.expand_path("rake_compat", __dir__) + autoload :Group, File.expand_path("group", __dir__) # Shortcuts for help. HELP_MAPPINGS = %w(-h -? --help -D) @@ -89,6 +89,7 @@ class << self def included(base) #:nodoc: + super(base) base.extend ClassMethods base.send :include, Invocation base.send :include, Shell @@ -153,17 +154,20 @@ # If you want to raise an error when the default value of an option does not match # the type call check_default_type! - # This is disabled by default for compatibility. + # This will be the default; for compatibility a deprecation warning is issued if necessary. def check_default_type! @check_default_type = true end - def check_default_type #:nodoc: - @check_default_type ||= from_superclass(:check_default_type, false) + # If you want to use defaults that don't match the type of an option, + # either specify `check_default_type: false` or call `allow_incompatible_default_type!` + def allow_incompatible_default_type! + @check_default_type = false end - def check_default_type? #:nodoc: - !!check_default_type + def check_default_type #:nodoc: + @check_default_type = from_superclass(:check_default_type, nil) unless defined?(@check_default_type) + @check_default_type end # If true, option parsing is suspended as soon as an unknown option or a @@ -353,22 +357,22 @@ # Returns the commands for this Thor class. # # ==== Returns - # OrderedHash:: An ordered hash with commands names as keys and Thor::Command - # objects as values. + # Hash:: An ordered hash with commands names as keys and Thor::Command + # objects as values. # def commands - @commands ||= Thor::CoreExt::OrderedHash.new + @commands ||= Hash.new end alias_method :tasks, :commands # Returns the commands for this Thor class and all subclasses. # # ==== Returns - # OrderedHash:: An ordered hash with commands names as keys and Thor::Command - # objects as values. + # Hash:: An ordered hash with commands names as keys and Thor::Command + # objects as values. # def all_commands - @all_commands ||= from_superclass(:all_commands, Thor::CoreExt::OrderedHash.new) + @all_commands ||= from_superclass(:all_commands, Hash.new) @all_commands.merge!(commands) end alias_method :all_tasks, :all_commands @@ -415,14 +419,20 @@ # remove_command :this_is_not_a_command # end # - def no_commands - @no_commands = true - yield - ensure - @no_commands = false + def no_commands(&block) + no_commands_context.enter(&block) end + alias_method :no_tasks, :no_commands + def no_commands_context + @no_commands_context ||= NestedContext.new + end + + def no_commands? + no_commands_context.entered? + end + # Sets the namespace for the Thor or Thor::Group class. By default the # namespace is retrieved from the class name. If your Thor class is named # Scripts::MyScript, the help method, for example, will be called as: @@ -502,10 +512,16 @@ msg = "ERROR: \"#{basename} #{name}\" was called with ".dup msg << "no arguments" if args.empty? msg << "arguments " << args.inspect unless args.empty? - msg << "\nUsage: #{banner(command).inspect}" + msg << "\nUsage: \"#{banner(command).split("\n").join("\"\n \"")}\"" raise InvocationError, msg end + # A flag that makes the process exit with status 1 if any error happens. + def exit_on_failure? + Thor.deprecation_warning "Thor exit with status 0 on errors. To keep this behavior, you must define `exit_on_failure?` in `#{self.name}`" + false + end + protected # Prints the class options per group. If an option does not belong to @@ -563,7 +579,7 @@ # options<Hash>:: Described in both class_option and method_option. # scope<Hash>:: Options hash that is being built up def build_option(name, options, scope) #:nodoc: - scope[name] = Thor::Option.new(name, options.merge(:check_default_type => check_default_type?)) + scope[name] = Thor::Option.new(name, {:check_default_type => check_default_type}.merge!(options)) end # Receives a hash of options, parse them and add to the scope. This is a @@ -596,13 +612,15 @@ # Everytime someone inherits from a Thor class, register the klass # and file into baseclass. def inherited(klass) + super(klass) Thor::Base.register_klass_file(klass) - klass.instance_variable_set(:@no_commands, false) + klass.instance_variable_set(:@no_commands, 0) end # Fire this callback whenever a method is added. Added methods are # tracked as commands by invoking the create_command method. def method_added(meth) + super(meth) meth = meth.to_s if meth == "initialize" @@ -613,8 +631,7 @@ # Return if it's not a public instance method return unless public_method_defined?(meth.to_sym) - @no_commands ||= false - return if @no_commands || !create_command(meth) + return if no_commands? || !create_command(meth) is_thor_reserved_word?(meth, :command) Thor::Base.register_klass_file(self) @@ -641,11 +658,6 @@ end end - # A flag that makes the process exit with status 1 if any error happens. - def exit_on_failure? - false - end - # # The basename of the program invoking the thor class. # diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/thor/command.rb new/lib/thor/command.rb --- old/lib/thor/command.rb 2018-11-10 04:00:18.000000000 +0100 +++ new/lib/thor/command.rb 2019-12-13 20:32:01.000000000 +0100 @@ -49,24 +49,32 @@ formatted ||= "".dup - # Add usage with required arguments - formatted << if klass && !klass.arguments.empty? - usage.to_s.gsub(/^#{name}/) do |match| - match << " " << klass.arguments.map(&:usage).compact.join(" ") - end - else - usage.to_s - end + Array(usage).map do |specific_usage| + formatted_specific_usage = formatted - # Add required options - formatted << " #{required_options}" + formatted_specific_usage += required_arguments_for(klass, specific_usage) - # Strip and go! - formatted.strip + # Add required options + formatted_specific_usage += " #{required_options}" + + # Strip and go! + formatted_specific_usage.strip + end.join("\n") end protected + # Add usage with required arguments + def required_arguments_for(klass, usage) + if klass && !klass.arguments.empty? + usage.to_s.gsub(/^#{name}/) do |match| + match << " " << klass.arguments.map(&:usage).compact.join(" ") + end + else + usage.to_s + end + end + def not_debugging?(instance) !(instance.class.respond_to?(:debugging) && instance.class.debugging) end @@ -97,8 +105,7 @@ def handle_argument_error?(instance, error, caller) not_debugging?(instance) && (error.message =~ /wrong number of arguments/ || error.message =~ /given \d*, expected \d*/) && begin saned = sans_backtrace(error.backtrace, caller) - # Ruby 1.9 always include the called method in the backtrace - saned.empty? || (saned.size == 1 && RUBY_VERSION >= "1.9") + saned.empty? || saned.size == 1 end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/thor/core_ext/io_binary_read.rb new/lib/thor/core_ext/io_binary_read.rb --- old/lib/thor/core_ext/io_binary_read.rb 2018-11-10 04:00:18.000000000 +0100 +++ new/lib/thor/core_ext/io_binary_read.rb 1970-01-01 01:00:00.000000000 +0100 @@ -1,12 +0,0 @@ -class IO #:nodoc: - class << self - 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 - end -end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/thor/core_ext/ordered_hash.rb new/lib/thor/core_ext/ordered_hash.rb --- old/lib/thor/core_ext/ordered_hash.rb 2018-11-10 04:00:18.000000000 +0100 +++ new/lib/thor/core_ext/ordered_hash.rb 1970-01-01 01:00:00.000000000 +0100 @@ -1,129 +0,0 @@ -class Thor - module CoreExt - class OrderedHash < ::Hash - if RUBY_VERSION < "1.9" - def initialize(*args, &block) - super - @keys = [] - end - - def initialize_copy(other) - super - # make a deep copy of keys - @keys = other.keys - end - - def []=(key, value) - @keys << key unless key?(key) - super - end - - def delete(key) - if key? key - index = @keys.index(key) - @keys.delete_at index - end - super - end - - def delete_if - super - sync_keys! - self - end - - alias_method :reject!, :delete_if - - def reject(&block) - dup.reject!(&block) - end - - def keys - @keys.dup - end - - def values - @keys.map { |key| self[key] } - end - - def to_hash - self - end - - def to_a - @keys.map { |key| [key, self[key]] } - end - - def each_key - return to_enum(:each_key) unless block_given? - @keys.each { |key| yield(key) } - self - end - - def each_value - return to_enum(:each_value) unless block_given? - @keys.each { |key| yield(self[key]) } - self - end - - def each - return to_enum(:each) unless block_given? - @keys.each { |key| yield([key, self[key]]) } - self - end - - def each_pair - return to_enum(:each_pair) unless block_given? - @keys.each { |key| yield(key, self[key]) } - self - end - - alias_method :select, :find_all - - def clear - super - @keys.clear - self - end - - def shift - k = @keys.first - v = delete(k) - [k, v] - end - - def merge!(other_hash) - if block_given? - other_hash.each { |k, v| self[k] = key?(k) ? yield(k, self[k], v) : v } - else - other_hash.each { |k, v| self[k] = v } - end - self - end - - alias_method :update, :merge! - - def merge(other_hash, &block) - dup.merge!(other_hash, &block) - end - - # When replacing with another hash, the initial order of our keys must come from the other hash -ordered or not. - def replace(other) - super - @keys = other.keys - self - end - - def inspect - "#<#{self.class} #{super}>" - end - - private - - def sync_keys! - @keys.delete_if { |k| !key?(k) } - end - end - end - end -end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/thor/error.rb new/lib/thor/error.rb --- old/lib/thor/error.rb 2018-11-10 04:00:18.000000000 +0100 +++ new/lib/thor/error.rb 2019-12-13 20:32:01.000000000 +0100 @@ -1,22 +1,18 @@ class Thor - Correctable = - begin - require 'did_you_mean' + Correctable = if defined?(DidYouMean::SpellChecker) && defined?(DidYouMean::Correctable) + # In order to support versions of Ruby that don't have keyword + # arguments, we need our own spell checker class that doesn't take key + # words. Even though this code wouldn't be hit because of the check + # above, it's still necessary because the interpreter would otherwise be + # unable to parse the file. + class NoKwargSpellChecker < DidYouMean::SpellChecker # :nodoc: + def initialize(dictionary) + @dictionary = dictionary + end + end - # In order to support versions of Ruby that don't have keyword - # arguments, we need our own spell checker class that doesn't take key - # words. Even though this code wouldn't be hit because of the check - # above, it's still necessary because the interpreter would otherwise be - # unable to parse the file. - class NoKwargSpellChecker < DidYouMean::SpellChecker # :nodoc: - def initialize(dictionary) - @dictionary = dictionary - end - end - - DidYouMean::Correctable - rescue LoadError, NameError - end + DidYouMean::Correctable + end # Thor::Error is raised when it's caused by wrong usage of thor classes. Those # errors have their backtrace suppressed and are nicely shown to the user. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/thor/group.rb new/lib/thor/group.rb --- old/lib/thor/group.rb 2018-11-10 04:00:18.000000000 +0100 +++ new/lib/thor/group.rb 2019-12-13 20:32:01.000000000 +0100 @@ -1,4 +1,4 @@ -require "thor/base" +require_relative "base" # Thor has a special class called Thor::Group. The main difference to Thor class # is that it invokes all commands at once. It also include some methods that allows diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/thor/invocation.rb new/lib/thor/invocation.rb --- old/lib/thor/invocation.rb 2018-11-10 04:00:18.000000000 +0100 +++ new/lib/thor/invocation.rb 2019-12-13 20:32:01.000000000 +0100 @@ -1,6 +1,7 @@ class Thor module Invocation def self.included(base) #:nodoc: + super(base) base.extend ClassMethods end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/thor/line_editor/basic.rb new/lib/thor/line_editor/basic.rb --- old/lib/thor/line_editor/basic.rb 2018-11-10 04:00:18.000000000 +0100 +++ new/lib/thor/line_editor/basic.rb 2019-12-13 20:32:01.000000000 +0100 @@ -24,7 +24,7 @@ $stdin.gets else # Lazy-load io/console since it is gem-ified as of 2.3 - require "io/console" if RUBY_VERSION > "1.9.2" + require "io/console" $stdin.noecho(&:gets) end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/thor/line_editor/readline.rb new/lib/thor/line_editor/readline.rb --- old/lib/thor/line_editor/readline.rb 2018-11-10 04:00:18.000000000 +0100 +++ new/lib/thor/line_editor/readline.rb 2019-12-13 20:32:01.000000000 +0100 @@ -1,19 +1,19 @@ -begin - require "readline" -rescue LoadError -end - class Thor module LineEditor class Readline < Basic def self.available? + begin + require "readline" + rescue LoadError + end + Object.const_defined?(:Readline) end def readline if echo? ::Readline.completion_append_character = nil - # Ruby 1.8.7 does not allow Readline.completion_proc= to receive nil. + # rb-readline does not allow Readline.completion_proc= to receive nil. if complete = completion_proc ::Readline.completion_proc = complete end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/thor/line_editor.rb new/lib/thor/line_editor.rb --- old/lib/thor/line_editor.rb 2018-11-10 04:00:18.000000000 +0100 +++ new/lib/thor/line_editor.rb 2019-12-13 20:32:01.000000000 +0100 @@ -1,5 +1,5 @@ -require "thor/line_editor/basic" -require "thor/line_editor/readline" +require_relative "line_editor/basic" +require_relative "line_editor/readline" class Thor module LineEditor diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/thor/nested_context.rb new/lib/thor/nested_context.rb --- old/lib/thor/nested_context.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/lib/thor/nested_context.rb 2019-12-13 20:32:01.000000000 +0100 @@ -0,0 +1,29 @@ +class Thor + class NestedContext + def initialize + @depth = 0 + end + + def enter + push + + yield + ensure + pop + end + + def entered? + @depth > 0 + end + + private + + def push + @depth += 1 + end + + def pop + @depth -= 1 + end + end +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/thor/parser/arguments.rb new/lib/thor/parser/arguments.rb --- old/lib/thor/parser/arguments.rb 2018-11-10 04:00:18.000000000 +0100 +++ new/lib/thor/parser/arguments.rb 2019-12-13 20:32:01.000000000 +0100 @@ -9,7 +9,7 @@ arguments = [] args.each do |item| - break if item =~ /^-/ + break if item.is_a?(String) && item =~ /^-/ arguments << item end @@ -82,7 +82,7 @@ end def current_is_value? - peek && peek.to_s !~ /^-/ + peek && peek.to_s !~ /^-{1,2}\S+/ end # Runs through the argument array getting strings that contains ":" and diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/thor/parser/option.rb new/lib/thor/parser/option.rb --- old/lib/thor/parser/option.rb 2018-11-10 04:00:18.000000000 +0100 +++ new/lib/thor/parser/option.rb 2019-12-13 20:32:01.000000000 +0100 @@ -1,17 +1,18 @@ class Thor class Option < Argument #:nodoc: - attr_reader :aliases, :group, :lazy_default, :hide + attr_reader :aliases, :group, :lazy_default, :hide, :repeatable VALID_TYPES = [:boolean, :numeric, :hash, :array, :string] def initialize(name, options = {}) @check_default_type = options[:check_default_type] options[:required] = false unless options.key?(:required) + @repeatable = options.fetch(:repeatable, false) super - @lazy_default = options[:lazy_default] - @group = options[:group].to_s.capitalize if options[:group] - @aliases = Array(options[:aliases]) - @hide = options[:hide] + @lazy_default = options[:lazy_default] + @group = options[:group].to_s.capitalize if options[:group] + @aliases = Array(options[:aliases]) + @hide = options[:hide] end # This parse quick options given as method_options. It makes several @@ -111,7 +112,7 @@ def validate! raise ArgumentError, "An option cannot be boolean and required." if boolean? && required? - validate_default_type! if @check_default_type + validate_default_type! end def validate_default_type! @@ -128,7 +129,19 @@ @default.class.name.downcase.to_sym end - raise ArgumentError, "Expected #{@type} default value for '#{switch_name}'; got #{@default.inspect} (#{default_type})" unless default_type == @type + expected_type = (@repeatable && @type != :hash) ? :array : @type + + if default_type != expected_type + err = "Expected #{expected_type} default value for '#{switch_name}'; got #{@default.inspect} (#{default_type})" + + if @check_default_type + raise ArgumentError, err + elsif @check_default_type == nil + Thor.deprecation_warning "#{err}.\n" + + 'This will be rejected in the future unless you explicitly pass the options `check_default_type: false`' + + ' or call `allow_incompatible_default_type!` in your code' + end + end end def dasherized? diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/thor/parser/options.rb new/lib/thor/parser/options.rb --- old/lib/thor/parser/options.rb 2018-11-10 04:00:18.000000000 +0100 +++ new/lib/thor/parser/options.rb 2019-12-13 20:32:01.000000000 +0100 @@ -97,7 +97,8 @@ switch = normalize_switch(switch) option = switch_option(switch) - @assigns[option.human_name] = parse_peek(switch, option) + result = parse_peek(switch, option) + assign_result!(option, result) elsif @stop_on_unknown @parsing_options = false @extra << shifted @@ -132,6 +133,15 @@ protected + def assign_result!(option, result) + if option.repeatable && option.type == :hash + (@assigns[option.human_name] ||= {}).merge!(result) + elsif option.repeatable + (@assigns[option.human_name] ||= []) << result + else + @assigns[option.human_name] = result + end + end # Check if the current value in peek is a registered switch. # # Two booleans are returned. The first is true if the current value @@ -161,7 +171,7 @@ end def switch?(arg) - switch_option(normalize_switch(arg)) + !switch_option(normalize_switch(arg)).nil? end def switch_option(arg) @@ -194,7 +204,7 @@ shift false else - !no_or_skip?(switch) + @switches.key?(switch) || !no_or_skip?(switch) end else @switches.key?(switch) || !no_or_skip?(switch) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/thor/parser.rb new/lib/thor/parser.rb --- old/lib/thor/parser.rb 2018-11-10 04:00:18.000000000 +0100 +++ new/lib/thor/parser.rb 2019-12-13 20:32:01.000000000 +0100 @@ -1,4 +1,4 @@ -require "thor/parser/argument" -require "thor/parser/arguments" -require "thor/parser/option" -require "thor/parser/options" +require_relative "parser/argument" +require_relative "parser/arguments" +require_relative "parser/option" +require_relative "parser/options" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/thor/rake_compat.rb new/lib/thor/rake_compat.rb --- old/lib/thor/rake_compat.rb 2018-11-10 04:00:18.000000000 +0100 +++ new/lib/thor/rake_compat.rb 2019-12-13 20:32:01.000000000 +0100 @@ -25,6 +25,7 @@ end def self.included(base) + super(base) # Hack. Make rakefile point to invoker, so rdoc task is generated properly. rakefile = File.basename(caller[0].match(/(.*):\d+/)[1]) Rake.application.instance_variable_set(:@rakefile, rakefile) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/thor/runner.rb new/lib/thor/runner.rb --- old/lib/thor/runner.rb 2018-11-10 04:00:18.000000000 +0100 +++ new/lib/thor/runner.rb 2019-12-13 20:32:01.000000000 +0100 @@ -1,12 +1,13 @@ -require "thor" -require "thor/group" -require "thor/core_ext/io_binary_read" +require_relative "../thor" +require_relative "group" require "yaml" require "digest/md5" require "pathname" class Thor::Runner < Thor #:nodoc: # rubocop:disable ClassLength + autoload :OpenURI, "open-uri" + map "-T" => :list, "-i" => :install, "-u" => :update, "-v" => :version def self.banner(command, all = false, subcommand = false) @@ -111,7 +112,7 @@ desc "version", "Show Thor version" def version - require "thor/version" + require_relative "version" say "Thor #{Thor::VERSION}" end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/thor/shell/basic.rb new/lib/thor/shell/basic.rb --- old/lib/thor/shell/basic.rb 2018-11-10 04:00:18.000000000 +0100 +++ new/lib/thor/shell/basic.rb 2019-12-13 20:32:01.000000000 +0100 @@ -451,16 +451,25 @@ def ask_filtered(statement, color, options) answer_set = options[:limited_to] + case_insensitive = options.fetch(:case_insensitive, false) correct_answer = nil until correct_answer answers = answer_set.join(", ") answer = ask_simply("#{statement} [#{answers}]", color, options) - correct_answer = answer_set.include?(answer) ? answer : nil + correct_answer = answer_match(answer_set, answer, case_insensitive) say("Your response must be one of: [#{answers}]. Please try again.") unless correct_answer end correct_answer end + def answer_match(possibilities, answer, case_insensitive) + if case_insensitive + possibilities.detect{ |possibility| possibility.downcase == answer.downcase } + else + possibilities.detect{ |possibility| possibility == answer } + end + end + def merge(destination, content) #:nodoc: require "tempfile" Tempfile.open([File.basename(destination), File.extname(destination)], File.dirname(destination)) do |temp| diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/thor/shell/color.rb new/lib/thor/shell/color.rb --- old/lib/thor/shell/color.rb 2018-11-10 04:00:18.000000000 +0100 +++ new/lib/thor/shell/color.rb 2019-12-13 20:32:01.000000000 +0100 @@ -1,4 +1,4 @@ -require "thor/shell/basic" +require_relative "basic" class Thor module Shell @@ -97,7 +97,11 @@ protected def can_display_colors? - stdout.tty? + stdout.tty? && !are_colors_disabled? + end + + def are_colors_disabled? + !ENV['NO_COLOR'].nil? end # Overwrite show_diff to show diff with colors if Diff::LCS is diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/thor/shell/html.rb new/lib/thor/shell/html.rb --- old/lib/thor/shell/html.rb 2018-11-10 04:00:18.000000000 +0100 +++ new/lib/thor/shell/html.rb 2019-12-13 20:32:01.000000000 +0100 @@ -1,4 +1,4 @@ -require "thor/shell/basic" +require_relative "basic" class Thor module Shell @@ -51,13 +51,13 @@ 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) } - "<span style=\"#{html_colors.join('; ')};\">#{string}</span>" + "<span style=\"#{html_colors.join('; ')};\">#{Thor::Util.escape_html(string)}</span>" 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 - "<span style=\"#{styles.join('; ')};\">#{string}</span>" + "<span style=\"#{styles.join('; ')};\">#{Thor::Util.escape_html(string)}</span>" end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/thor/shell.rb new/lib/thor/shell.rb --- old/lib/thor/shell.rb 2018-11-10 04:00:18.000000000 +0100 +++ new/lib/thor/shell.rb 2019-12-13 20:32:01.000000000 +0100 @@ -24,9 +24,9 @@ SHELL_DELEGATED_METHODS = [:ask, :error, :set_color, :yes?, :no?, :say, :say_status, :print_in_columns, :print_table, :print_wrapped, :file_collision, :terminal_width] attr_writer :shell - autoload :Basic, "thor/shell/basic" - autoload :Color, "thor/shell/color" - autoload :HTML, "thor/shell/html" + autoload :Basic, File.expand_path("shell/basic", __dir__) + autoload :Color, File.expand_path("shell/color", __dir__) + autoload :HTML, File.expand_path("shell/html", __dir__) # Add shell to initialize config values. # diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/thor/util.rb new/lib/thor/util.rb --- old/lib/thor/util.rb 2018-11-10 04:00:18.000000000 +0100 +++ new/lib/thor/util.rb 2019-12-13 20:32:01.000000000 +0100 @@ -263,6 +263,22 @@ def escape_globs(path) path.to_s.gsub(/[*?{}\[\]]/, '\\\\\\&') end + + # Returns a string that has had any HTML characters escaped. + # + # ==== Examples + # + # Thor::Util.escape_html('<div>') # => "<div>" + # + # ==== Parameters + # String + # + # ==== Returns + # String + # + def escape_html(string) + CGI.escapeHTML(string) + end end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/thor/version.rb new/lib/thor/version.rb --- old/lib/thor/version.rb 2018-11-10 04:00:18.000000000 +0100 +++ new/lib/thor/version.rb 2019-12-13 20:32:01.000000000 +0100 @@ -1,3 +1,3 @@ class Thor - VERSION = "0.20.3" + VERSION = "1.0.0" end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/thor.rb new/lib/thor.rb --- old/lib/thor.rb 2018-11-10 04:00:18.000000000 +0100 +++ new/lib/thor.rb 2019-12-13 20:32:01.000000000 +0100 @@ -1,5 +1,5 @@ require "set" -require "thor/base" +require_relative "thor/base" class Thor class << self @@ -90,9 +90,14 @@ # ==== Parameters # Hash[String|Array => Symbol]:: Maps the string or the strings in the array to the given command. # - def map(mappings = nil) + def map(mappings = nil, **kw) @map ||= from_superclass(:map, {}) + if mappings && !kw.empty? + mappings = kw.merge!(mappings) + else + mappings ||= kw + end if mappings mappings.each do |key, value| if key.respond_to?(:each) @@ -170,7 +175,7 @@ handle_no_command_error(meth) unless command shell.say "Usage:" - shell.say " #{banner(command)}" + shell.say " #{banner(command).split("\n").join("\n ")}" shell.say class_options_help(shell, nil => command.options.values) if command.long_description @@ -339,6 +344,13 @@ command && disable_required_check.include?(command.name.to_sym) end + def deprecation_warning(message) #:nodoc: + unless ENV['THOR_SILENCE_DEPRECATION'] + warn "Deprecation warning: #{message}\n" + + 'You can silence deprecations warning by setting the environment variable THOR_SILENCE_DEPRECATION.' + end + end + protected def stop_on_unknown_option #:nodoc: @@ -393,7 +405,10 @@ # the namespace should be displayed as arguments. # def banner(command, namespace = nil, subcommand = false) - "#{basename} #{command.formatted_usage(self, $thor_runner, subcommand)}" + $thor_runner ||= false + command.formatted_usage(self, $thor_runner, subcommand).split("\n").map do |formatted_usage| + "#{basename} #{formatted_usage}" + end.join("\n") end def baseclass #:nodoc: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/metadata new/metadata --- old/metadata 2018-11-10 04:00:18.000000000 +0100 +++ new/metadata 2019-12-13 20:32:01.000000000 +0100 @@ -1,7 +1,7 @@ --- !ruby/object:Gem::Specification name: thor version: !ruby/object:Gem::Version - version: 0.20.3 + version: 1.0.0 platform: ruby authors: - Yehuda Katz @@ -9,22 +9,28 @@ autorequire: bindir: bin cert_chain: [] -date: 2018-11-10 00:00:00.000000000 Z +date: 2019-12-13 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: bundler requirement: !ruby/object:Gem::Requirement requirements: - - - "~>" + - - ">=" - !ruby/object:Gem::Version version: '1.0' + - - "<" + - !ruby/object:Gem::Version + version: '3' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - - "~>" + - - ">=" - !ruby/object:Gem::Version version: '1.0' + - - "<" + - !ruby/object:Gem::Version + version: '3' description: Thor is a toolkit for building powerful command-line interfaces. email: [email protected] executables: @@ -49,14 +55,13 @@ - lib/thor/base.rb - lib/thor/command.rb - lib/thor/core_ext/hash_with_indifferent_access.rb -- lib/thor/core_ext/io_binary_read.rb -- lib/thor/core_ext/ordered_hash.rb - lib/thor/error.rb - lib/thor/group.rb - lib/thor/invocation.rb - lib/thor/line_editor.rb - lib/thor/line_editor/basic.rb - lib/thor/line_editor/readline.rb +- lib/thor/nested_context.rb - lib/thor/parser.rb - lib/thor/parser/argument.rb - lib/thor/parser/arguments.rb @@ -83,15 +88,14 @@ requirements: - - ">=" - !ruby/object:Gem::Version - version: 1.8.7 + version: 2.0.0 required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 1.3.5 requirements: [] -rubyforge_project: -rubygems_version: 2.7.6 +rubygems_version: 3.0.3 signing_key: specification_version: 4 summary: Thor is a toolkit for building powerful command-line interfaces. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/thor.gemspec new/thor.gemspec --- old/thor.gemspec 2018-11-10 04:00:18.000000000 +0100 +++ new/thor.gemspec 2019-12-13 20:32:01.000000000 +0100 @@ -4,7 +4,7 @@ require "thor/version" Gem::Specification.new do |spec| - spec.add_development_dependency "bundler", "~> 1.0" + spec.add_development_dependency "bundler", ">= 1.0", "< 3" spec.authors = ["Yehuda Katz", "José Valim"] spec.description = "Thor is a toolkit for building powerful command-line interfaces." spec.email = "[email protected]" @@ -14,7 +14,7 @@ spec.licenses = %w(MIT) spec.name = "thor" spec.require_paths = %w(lib) - spec.required_ruby_version = ">= 1.8.7" + spec.required_ruby_version = ">= 2.0.0" spec.required_rubygems_version = ">= 1.3.5" spec.summary = spec.description spec.version = Thor::VERSION
