Hello community, here is the log from the commit of package rubygem-mixlib-cli for openSUSE:Factory checked in at 2019-08-06 15:09:58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/rubygem-mixlib-cli (Old) and /work/SRC/openSUSE:Factory/.rubygem-mixlib-cli.new.4126 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rubygem-mixlib-cli" Tue Aug 6 15:09:58 2019 rev:12 rq:717308 version:2.1.1 Changes: -------- --- /work/SRC/openSUSE:Factory/rubygem-mixlib-cli/rubygem-mixlib-cli.changes 2019-04-01 12:36:52.825871474 +0200 +++ /work/SRC/openSUSE:Factory/.rubygem-mixlib-cli.new.4126/rubygem-mixlib-cli.changes 2019-08-06 15:09:58.659787326 +0200 @@ -1,0 +2,6 @@ +Fri Jul 19 09:22:24 UTC 2019 - Stephan Kulow <[email protected]> + +- updated to version 2.1.1 + no changelog found + +------------------------------------------------------------------- Old: ---- mixlib-cli-2.0.3.gem New: ---- mixlib-cli-2.1.1.gem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ rubygem-mixlib-cli.spec ++++++ --- /var/tmp/diff_new_pack.o4XU9n/_old 2019-08-06 15:09:59.507786845 +0200 +++ /var/tmp/diff_new_pack.o4XU9n/_new 2019-08-06 15:09:59.511786843 +0200 @@ -24,7 +24,7 @@ # Name: rubygem-mixlib-cli -Version: 2.0.3 +Version: 2.1.1 Release: 0 %define mod_name mixlib-cli %define mod_full_name %{mod_name}-%{version} @@ -32,7 +32,7 @@ BuildRequires: %{ruby >= 2.4} BuildRequires: %{rubygem gem2rpm} BuildRequires: ruby-macros >= 5 -Url: https://www.github.com/mixlib-cli +Url: https://github.com/chef/mixlib-cli Source: https://rubygems.org/gems/%{mod_full_name}.gem Source1: gem2rpm.yml Summary: A simple mixin for CLI interfaces, including option parsing ++++++ mixlib-cli-2.0.3.gem -> mixlib-cli-2.1.1.gem ++++++ Binary files old/checksums.yaml.gz and new/checksums.yaml.gz differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/mixlib/cli/formatter.rb new/lib/mixlib/cli/formatter.rb --- old/lib/mixlib/cli/formatter.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/lib/mixlib/cli/formatter.rb 2019-06-10 13:14:12.000000000 +0200 @@ -0,0 +1,32 @@ + +module Mixlib + module CLI + class Formatter + # Create a string that includes both versions (short/long) of a flag name + # based on on whether short/long/both/neither are provided + # + # @param short [String] the short name of the option. Can be nil. + # @param long [String] the long name of the option. Can be nil. + # @return [String] the formatted flag name as described above + def self.combined_option_display_name(short, long) + usage = "" + # short/long may have an argument (--long ARG) + # splitting on " " and taking first ensures that we get just + # the flag name without the argument if one is present. + usage << short.split(" ").first if short + usage << "/" if long && short + usage << long.split(" ").first if long + usage + end + + # @param opt_arry [Array] + # + # @return [String] a friendly quoted list of items complete with "or" + def self.friendly_opt_list(opt_array) + opts = opt_array.map { |x| "'#{x}'" } + return opts.join(" or ") if opts.size < 3 + opts[0..-2].join(", ") + ", or " + opts[-1] + end + end + end +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/mixlib/cli/version.rb new/lib/mixlib/cli/version.rb --- old/lib/mixlib/cli/version.rb 2019-03-20 02:08:00.000000000 +0100 +++ new/lib/mixlib/cli/version.rb 2019-06-10 13:14:12.000000000 +0200 @@ -1,5 +1,5 @@ module Mixlib module CLI - VERSION = "2.0.3".freeze + VERSION = "2.1.1".freeze end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/mixlib/cli.rb new/lib/mixlib/cli.rb --- old/lib/mixlib/cli.rb 2019-03-20 02:08:00.000000000 +0100 +++ new/lib/mixlib/cli.rb 2019-06-10 13:14:12.000000000 +0200 @@ -1,6 +1,6 @@ # # Author:: Adam Jacob (<[email protected]>) -# Copyright:: Copyright (c) 2008-2016 Chef Software, Inc. +# Copyright:: Copyright (c) 2008-2019 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,7 +17,7 @@ # require "optparse" - +require "mixlib/cli/formatter" module Mixlib # == Mixlib::CLI @@ -30,8 +30,9 @@ # === DSL # When included, Mixlib::CLI also extends the including class with its # ClassMethods, which define the DSL. The primary methods of the DSL are - # ClassMethods#option, which defines a command line option, and - # ClassMethods#banner, which defines the "usage" banner. + # ClassMethods#option, which defines a command line option; + # ClassMethods#banner, which defines the "usage" banner; + # and ClassMethods#deprecated_option, which defines a deprecated command-line option. # # === Parsing # Command line options are parsed by calling the instance method @@ -93,14 +94,88 @@ # === Parameters # name<Symbol>:: The name of the option to add # args<Hash>:: A hash of arguments for the option, specifying how it should be parsed. - # === Returns - # true:: Always returns true. + # Supported arguments: + # :short - The short option, just like from optparse. Example: "-l LEVEL" + # :long - The long option, just like from optparse. Example: "--level LEVEL" + # :description - The description for this item, just like from optparse. + # :default - A default value for this option. Default values will be populated + # on parse into `config` or `default_default`, depending `use_separate_defaults` + # :boolean - indicates the flag is a boolean. You can use this if the flag takes no arguments + # The config value will be set to 'true' if the flag is provided on the CLI and this + # argument is set to true. The config value will be set to false only + # if it has a default value of false + # :required - When set, the option is required. If the command is run without this option, + # it will print a message informing the user of the missing requirement, and exit. Default is false. + # :proc - Proc that will be invoked if the human has specified this option. + # Two forms are supported: + # Proc/1 - provided value is passed in. + # Proc/2 - first argument is provided value. Second is the cli flag option hash. + # Both versions return the value to be assigned to the option. + # :show_options - this option is designated as one that shows all supported options/help when invoked. + # :exit - exit your program with the exit code when this option is given. Example: 0 + # :in - array containing a list of valid values. The value provided at run-time for the option is + # validated against this. If it is not in the list, it will print a message and exit. + # :on :head OR :tail - force this option to display at the beginning or end of the + # option list, respectively + # = + # @return <Hash> :: the config hash for the created option + # i def option(name, args) @options ||= {} raise(ArgumentError, "Option name must be a symbol") unless name.kind_of?(Symbol) @options[name.to_sym] = args end + # Declare a deprecated option + # + # Add a deprecated command line option. + # + # name<Symbol> :: The name of the deprecated option + # replacement<Symbol> :: The name of the option that replaces this option. + # long<String> :: The original long flag name, or flag name with argument, eg "--user USER" + # short<String> :: The original short-form flag name, eg "-u USER" + # boolean<String> :: true if this is a boolean flag, eg "--[no-]option". + # value_mapper<Proc/1> :: a block that accepts the original value from the deprecated option, + # and converts it to a value suitable for the new option. + # If not provided, the value provided to the deprecated option will be + # assigned directly to the converted option. + # keep<Boolean> :: Defaults to true, this ensure sthat `options[:deprecated_flag]` is + # populated when the deprecated flag is used. If set to false, + # only the value in `replacement` will be set. Results undefined + # if no replacement is provided. You can use this to enforce the transition + # to non-deprecated keys in your code. + # + # === Returns + # <Hash> :: The config hash for the created option. + def deprecated_option(name, + replacement: nil, + long: nil, + short: nil, + boolean: false, + value_mapper: nil, + keep: true) + + description = if replacement + replacement_cfg = options[replacement] + display_name = CLI::Formatter.combined_option_display_name(replacement_cfg[:short], replacement_cfg[:long]) + "This flag is deprecated. Use #{display_name} instead." + else + "This flag is deprecated and will be removed in a future release." + end + value_mapper ||= Proc.new { |v| v } + + option(name, + long: long, + short: short, + boolean: boolean, + description: description, + on: :tail, + deprecated: true, + keep: keep, + replacement: replacement, + value_mapper: value_mapper) + end + # Get the hash of current options. # # === Returns @@ -209,7 +284,6 @@ config_opts[:show_options] ||= false config_opts[:exit] ||= nil config_opts[:in] ||= nil - if config_opts.key?(:default) defaults_container[config_key] = config_opts[:default] end @@ -225,25 +299,30 @@ # # === Returns # argv<Array>:: Returns any un-parsed elements. - def parse_options(argv = ARGV) + def parse_options(argv = ARGV, show_deprecations: true) argv = argv.dup opt_parser.parse!(argv) + # Do this before our custom validations, so that custom + # validations apply to any converted deprecation values; + # but after parse! so that everything is populated. + handle_deprecated_options(show_deprecations) # Deal with any required values - options.each do |opt_key, opt_value| - if opt_value[:required] && !config.key?(opt_key) - reqarg = opt_value[:short] || opt_value[:long] + options.each do |opt_key, opt_config| + if opt_config[:required] && !config.key?(opt_key) + reqarg = opt_config[:short] || opt_config[:long] puts "You must supply #{reqarg}!" puts @opt_parser exit 2 end - if opt_value[:in] - unless opt_value[:in].kind_of?(Array) + if opt_config[:in] + unless opt_config[:in].kind_of?(Array) raise(ArgumentError, "Options config key :in must receive an Array") end - if config[opt_key] && !opt_value[:in].include?(config[opt_key]) - reqarg = opt_value[:short] || opt_value[:long] - puts "#{reqarg}: #{config[opt_key]} is not included in the list ['#{opt_value[:in].join("', '")}'] " + if config[opt_key] && !opt_config[:in].include?(config[opt_key]) + reqarg = Formatter.combined_option_display_name(opt_config[:short], opt_config[:long]) + puts "#{reqarg}: #{config[opt_key]} is not one of the allowed values: #{Formatter.friendly_opt_list(opt_config[:in])}" + # TODO - get rid of this. nobody wants to be spammed with a ton of information, particularly since we just told them the exact problem and how to fix it. puts @opt_parser exit 2 end @@ -267,7 +346,6 @@ # Create new options options.sort { |a, b| a[0].to_s <=> b[0].to_s }.each do |opt_key, opt_val| opt_args = build_option_arguments(opt_val) - opt_method = case opt_val[:on] when :on :on @@ -305,15 +383,58 @@ end end + # Iterates through options declared as deprecated, + # maps values to their replacement options, + # and prints deprecation warnings. + # + # @return NilClass + def handle_deprecated_options(show_deprecations) + merge_in_values = {} + config.each_key do |opt_key| + opt_cfg = options[opt_key] + + # Deprecated entries do not have defaults so no matter what + # separate_default_options are set, if we see a 'config' + # entry that contains a deprecated indicator, then the option was + # explicitly provided by the caller. + # + # opt_cfg may not exist if an inheriting application + # has directly inserted values info config. + next unless opt_cfg && opt_cfg[:deprecated] + + replacement_key = opt_cfg[:replacement] + if replacement_key + # This is the value passed into the deprecated flag. We'll use + # the declared value mapper (defaults to return the same value if caller hasn't + # provided a mapper). + deprecated_val = config[opt_key] + + # We can't modify 'config' since we're iterating it, apply updates + # at the end. + merge_in_values[replacement_key] = opt_cfg[:value_mapper].call(deprecated_val) + config.delete(opt_key) unless opt_cfg[:keep] + end + + # Warn about the deprecation. + if show_deprecations + # Description is also the deprecation message. + display_name = CLI::Formatter.combined_option_display_name(opt_cfg[:short], opt_cfg[:long]) + puts "#{display_name}: #{opt_cfg[:description]}" + end + end + config.merge!(merge_in_values) + nil + end + def build_option_arguments(opt_setting) arguments = Array.new - arguments << opt_setting[:short] if opt_setting.key?(:short) - arguments << opt_setting[:long] if opt_setting.key?(:long) + arguments << opt_setting[:short] if opt_setting[:short] + arguments << opt_setting[:long] if opt_setting[:long] if opt_setting.key?(:description) description = opt_setting[:description].dup description << " (required)" if opt_setting[:required] - description << " (included in ['#{opt_setting[:in].join("', '")}'])" if opt_setting[:in] + description << " (valid options: #{Formatter.friendly_opt_list(opt_setting[:in])})" if opt_setting[:in] opt_setting[:description] = description arguments << description end @@ -325,6 +446,5 @@ receiver.extend(Mixlib::CLI::ClassMethods) receiver.extend(Mixlib::CLI::InheritMethods) end - end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/metadata new/metadata --- old/metadata 2019-03-20 02:08:00.000000000 +0100 +++ new/metadata 2019-06-10 13:14:12.000000000 +0200 @@ -1,14 +1,14 @@ --- !ruby/object:Gem::Specification name: mixlib-cli version: !ruby/object:Gem::Version - version: 2.0.3 + version: 2.1.1 platform: ruby authors: - Chef Software, Inc. autorequire: bindir: bin cert_chain: [] -date: 2019-03-20 00:00:00.000000000 Z +date: 2019-06-10 00:00:00.000000000 Z dependencies: [] description: A simple mixin for CLI interfaces, including option parsing email: [email protected] @@ -19,8 +19,9 @@ - LICENSE - NOTICE - lib/mixlib/cli.rb +- lib/mixlib/cli/formatter.rb - lib/mixlib/cli/version.rb -homepage: https://www.github.com/mixlib-cli +homepage: https://github.com/chef/mixlib-cli licenses: - Apache-2.0 metadata: {} @@ -39,7 +40,7 @@ - !ruby/object:Gem::Version version: '0' requirements: [] -rubygems_version: 3.0.1 +rubygems_version: 3.0.3 signing_key: specification_version: 4 summary: A simple mixin for CLI interfaces, including option parsing
