Hello community,

here is the log from the commit of package rubygem-mixlib-config for 
openSUSE:Factory checked in at 2018-02-12 10:16:04
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/rubygem-mixlib-config (Old)
 and      /work/SRC/openSUSE:Factory/.rubygem-mixlib-config.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "rubygem-mixlib-config"

Mon Feb 12 10:16:04 2018 rev:9 rq:575440 version:2.2.5

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/rubygem-mixlib-config/rubygem-mixlib-config.changes  
    2016-10-10 16:22:35.000000000 +0200
+++ 
/work/SRC/openSUSE:Factory/.rubygem-mixlib-config.new/rubygem-mixlib-config.changes
 2018-02-12 10:16:04.343651390 +0100
@@ -1,0 +2,6 @@
+Sat Feb 10 05:30:12 UTC 2018 - factory-a...@kulow.org
+
+- updated to version 2.2.5
+  no changelog found
+
+-------------------------------------------------------------------

Old:
----
  mixlib-config-2.2.4.gem

New:
----
  mixlib-config-2.2.5.gem

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ rubygem-mixlib-config.spec ++++++
--- /var/tmp/diff_new_pack.Fm9LRD/_old  2018-02-12 10:16:05.059625590 +0100
+++ /var/tmp/diff_new_pack.Fm9LRD/_new  2018-02-12 10:16:05.063625446 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package rubygem-mixlib-config
 #
-# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 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
@@ -24,16 +24,16 @@
 #
 
 Name:           rubygem-mixlib-config
-Version:        2.2.4
+Version:        2.2.5
 Release:        0
 %define mod_name mixlib-config
 %define mod_full_name %{mod_name}-%{version}
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
+BuildRequires:  %{ruby >= 2.2}
 BuildRequires:  %{rubygem gem2rpm}
-BuildRequires:  %{ruby}
 BuildRequires:  ruby-macros >= 5
-Url:            http://www.chef.io
-Source:         http://rubygems.org/gems/%{mod_full_name}.gem
+Url:            https://www.chef.io
+Source:         https://rubygems.org/gems/%{mod_full_name}.gem
 Source1:        gem2rpm.yml
 Summary:        A class based configuration library
 License:        Apache-2.0

++++++ mixlib-config-2.2.4.gem -> mixlib-config-2.2.5.gem ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Gemfile new/Gemfile
--- old/Gemfile 2016-09-03 00:20:31.000000000 +0200
+++ new/Gemfile 2018-02-09 19:25:02.000000000 +0100
@@ -1,5 +1,3 @@
 source "https://rubygems.org";
 
 gemspec
-
-gem "github_changelog_generator", group: :changelog
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/README.md new/README.md
--- old/README.md       2016-09-03 00:20:31.000000000 +0200
+++ new/README.md       2018-02-09 19:25:02.000000000 +0100
@@ -43,6 +43,32 @@
   MyConfig[:first_value] = 'foobar' # sets first_value to 'foobar'
 ```
 
+If you prefer to allow your users to pass in configuration via YAML or JSON 
files, `mixlib-config` supports that too!
+
+```ruby
+  MyConfig.from_file('~/.myconfig.yml')
+  MyConfig.from_file('~/.myconfig.json')
+```
+
+This way, a user could write a YAML config file that looked like this:
+
+```yaml
+---
+first_value: 'hi'
+second_value: 'goodbye'
+```
+
+or a JSON file that looks like this:
+
+```json
+{
+  "first_value": "hi",
+  "second_value": "goodbye"
+}
+```
+
+Please note: There is an inherent limitation in the logic you can do with YAML 
and JSON file. At this time, `mixlib-config` does not support ERB or other 
logic in YAML or JSON config (read "static content only").
+
 ## Nested Configuration
 
 Often you want to be able to group configuration options to provide a common 
context. Mixlib::Config supports this thus:
@@ -61,14 +87,17 @@
 
 The user can write their config file in one of three formats:
 
-#### Method Style
+### Method Style
+
 ```ruby
 logging.base_filename 'superlog'
 logging.max_log_files 2
 ```
 
-#### Block Style
+### Block Style
+
 Using this format the block is executed in the context, so all configurables 
on that context is directly accessible
+
 ```ruby
 logging do
   base_filename 'superlog'
@@ -76,8 +105,10 @@
 end
 ```
 
-#### Block with Argument Style
+### Block with Argument Style
+
 Using this format the context is given to the block as an argument
+
 ```ruby
 logging do |l|
   l.base_filename = 'superlog'
@@ -92,6 +123,100 @@
   MyConfig[:logging][:max_log_files]
 ```
 
+### Lists of Contexts
+For use cases where you need to be able to specify a list of things with 
identical configuration
+you can define a `context_config_list` like so:
+
+```ruby
+  require 'mixlib/config'
+
+  module MyConfig
+    extend Mixlib::Config
+
+    # The first argument is the plural word for your item, the second is the 
singular
+    config_context_list :apples, :apple do
+      default :species
+      default :color, 'red'
+      default :crispness, 10
+    end
+  end
+```
+
+With this definition everytime the `apple` is called within the config file it
+will create a new item that can be configured with a block like so:
+
+```ruby
+apple do
+  species 'Royal Gala'
+end
+apple do
+  species 'Granny Smith'
+  color 'green'
+end
+```
+
+You can then iterate over the defined values in code:
+
+```ruby
+MyConfig.apples.each do |apple|
+  puts "#{apple.species} are #{apple.color}"
+end
+
+# => Royal Gala are red
+# => Granny Smith are green
+```
+
+_**Note**: When using the config context lists they must use the [block 
style](#block-style) or [block with argument style](#block-with-argument-style)_
+
+### Hashes of Contexts
+For use cases where you need to be able to specify a list of things with 
identical configuration
+that are keyed to a specific value, you can define a `context_config_hash` 
like so:
+
+```ruby
+  require 'mixlib/config'
+
+  module MyConfig
+    extend Mixlib::Config
+
+    # The first argument is the plural word for your item, the second is the 
singular
+    config_context_hash :apples, :apple do
+      default :species
+      default :color, 'red'
+      default :crispness, 10
+    end
+  end
+```
+
+This can then be used in the config file like so:
+
+```ruby
+apple 'Royal Gala' do
+  species 'Royal Gala'
+end
+apple 'Granny Smith' do
+  species 'Granny Smith'
+  color 'green'
+end
+
+# You can also reopen a context to edit a value
+apple 'Royal Gala' do
+  crispness 3
+end
+```
+
+You can then iterate over the defined values in code:
+
+```ruby
+MyConfig.apples.each do |key, apple|
+  puts "#{key} => #{apple.species} are #{apple.color}"
+end
+
+# => Royal Gala => Royal Gala are red
+# => Granny Smith => Granny Smith are green
+```
+
+_**Note**: When using the config context hashes they must use the [block 
style](#block-style) or [block with argument style](#block-with-argument-style)_
+
 ## Default Values
 
 Mixlib::Config has a powerful default value facility. In addition to being 
able to specify explicit default values, you can even specify Ruby code blocks 
that will run if the config value is not set. This can allow you to build 
options whose values are based on other options.
@@ -147,3 +272,26 @@
 NOTE: if you have arrays of arrays, or other deep nesting, we suggest you use 
code blocks to set up your default values (`default(:option) { [ [ 1, 2 ], [ 3, 
4 ] ] }`). Deep children will not always be reset to their default values.
 
 Enjoy!
+
+## Contributing
+
+For information on contributing to this project see 
<https://github.com/chef/chef/blob/master/CONTRIBUTING.md>
+
+## License
+
+- Copyright:: Copyright (c) 2009-2016 Chef Software, Inc.
+- License:: Apache License, Version 2.0
+
+```text
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Rakefile new/Rakefile
--- old/Rakefile        2016-09-03 00:20:31.000000000 +0200
+++ new/Rakefile        2018-02-09 19:25:02.000000000 +0100
@@ -7,7 +7,7 @@
 
 Bundler::GemHelper.install_tasks
 
-task :default => :spec
+task default: [:style, :spec]
 
 desc "Run specs"
 RSpec::Core::RakeTask.new(:spec) do |spec|
@@ -16,23 +16,19 @@
 
 gem_spec = eval(File.read("mixlib-config.gemspec"))
 
+begin
+  require "chefstyle"
+  require "rubocop/rake_task"
+  RuboCop::RakeTask.new(:style) do |task|
+    task.options += ["--display-cop-names", "--no-color"]
+  end
+rescue LoadError
+  puts "chefstyle/rubocop is not available.  gem install chefstyle to do style 
checking."
+end
+
 RDoc::Task.new do |rdoc|
   rdoc.rdoc_dir = "rdoc"
   rdoc.title = "mixlib-config #{gem_spec.version}"
   rdoc.rdoc_files.include("README*")
   rdoc.rdoc_files.include("lib/**/*.rb")
 end
-
-begin
-  require "github_changelog_generator/task"
-
-  GitHubChangelogGenerator::RakeTask.new :changelog do |config|
-    config.issues = false
-    config.future_release = Mixlib::Config::VERSION
-    config.enhancement_labels = "enhancement,Enhancement,New 
Feature,Feature".split(",")
-    config.bug_labels = "bug,Bug,Improvement,Upstream Bug".split(",")
-    config.exclude_labels = 
"duplicate,question,invalid,wontfix,no_changelog,Exclude From 
Changelog,Question,Discussion".split(",")
-  end
-rescue LoadError
-  puts "github_changelog_generator is not available. gem install 
github_changelog_generator to generate changelogs"
-end
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/config/version.rb 
new/lib/mixlib/config/version.rb
--- old/lib/mixlib/config/version.rb    2016-09-03 00:20:31.000000000 +0200
+++ new/lib/mixlib/config/version.rb    2018-02-09 19:25:02.000000000 +0100
@@ -19,7 +19,7 @@
 module Mixlib
   module Config
 
-    VERSION = "2.2.4"
+    VERSION = "2.2.5"
 
   end
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/mixlib/config.rb new/lib/mixlib/config.rb
--- old/lib/mixlib/config.rb    2016-09-03 00:20:31.000000000 +0200
+++ new/lib/mixlib/config.rb    2018-02-09 19:25:02.000000000 +0100
@@ -30,10 +30,14 @@
       class << base; attr_accessor :configuration; end
       class << base; attr_accessor :configurables; end
       class << base; attr_accessor :config_contexts; end
+      class << base; attr_accessor :config_context_lists; end
+      class << base; attr_accessor :config_context_hashes; end
       class << base; attr_accessor :config_parent; end
       base.configuration = Hash.new
       base.configurables = Hash.new
       base.config_contexts = Hash.new
+      base.config_context_lists = Hash.new
+      base.config_context_hashes = Hash.new
       base.initialize_mixlib_config
     end
 
@@ -49,7 +53,51 @@
     # === Parameters
     # filename<String>:: A filename to read from
     def from_file(filename)
-      self.instance_eval(IO.read(filename), filename, 1)
+      if %w{ .yml .yaml }.include?(File.extname(filename))
+        from_yaml(filename)
+      elsif File.extname(filename) == ".json"
+        from_json(filename)
+      else
+        instance_eval(IO.read(filename), filename, 1)
+      end
+    end
+
+    # Parses valid YAML structure into Ruby so it can be ingested into the 
Class
+    #
+    # === Parameters
+    # filename<String>:: A filename to read from
+    def from_yaml(filename)
+      require "yaml"
+      from_hash(YAML.load(IO.read(filename)), filename)
+    end
+
+    # Parses valid JSON structure into Ruby
+    #
+    # === Parameters
+    # filename<String>:: A filename to read from
+    def from_json(filename)
+      require "json"
+      from_hash(JSON.parse(IO.read(filename)), filename)
+    end
+
+    # Transforms a Hash into method-style configuration syntax to be processed
+    #
+    # === Parameters
+    # hash<Hash>:: A Hash containing configuration
+    def from_hash(hash, filename = "in_memory")
+      ruby_translation = []
+
+      to_dotted_hash(hash).each do |k, v|
+        if v.is_a? Array
+          ruby_translation << "#{k} #{v}"
+        elsif v.is_a? String
+          ruby_translation << "#{k} \"#{v}\""
+        else
+          ruby_translation << "#{k} #{v}"
+        end
+      end
+
+      instance_eval(ruby_translation.join("\n"), filename, 1)
     end
 
     # Pass Mixlib::Config.configure() a block, and it will yield itself
@@ -57,7 +105,7 @@
     # === Parameters
     # block<Block>:: A block that is called with self.configuration as the 
argument.
     def configure(&block)
-      yield(self.configuration)
+      yield(configuration)
     end
 
     # Get the value of a config option
@@ -98,7 +146,7 @@
     # <True>:: If the config option exists
     # <False>:: If the config option does not exist
     def has_key?(key)
-      self.configuration.has_key?(key.to_sym)
+      configuration.has_key?(key.to_sym)
     end
 
     # Resets a config option to its default.
@@ -106,13 +154,13 @@
     # === Parameters
     # symbol<Symbol>:: Name of the config option
     def delete(symbol)
-      self.configuration.delete(symbol)
+      configuration.delete(symbol)
     end
 
     # Resets all config options to their defaults.
     def reset
       self.configuration = Hash.new
-      self.config_contexts.values.each { |config_context| config_context.reset 
}
+      config_contexts.values.each { |config_context| config_context.reset }
     end
 
     # Makes a copy of any non-default values.
@@ -159,19 +207,31 @@
     #     }
     #
     def save(include_defaults = false)
-      result = self.configuration.dup
+      result = configuration.dup
       if include_defaults
-        (self.configurables.keys - result.keys).each do |missing_default|
+        (configurables.keys - result.keys).each do |missing_default|
           # Ask any configurables to save themselves into the result array
-          if self.configurables[missing_default].has_default
-            result[missing_default] = 
self.configurables[missing_default].default
+          if configurables[missing_default].has_default
+            result[missing_default] = configurables[missing_default].default
           end
         end
       end
-      self.config_contexts.each_pair do |key, context|
+      config_contexts.each_pair do |key, context|
         context_result = context.save(include_defaults)
         result[key] = context_result if context_result.size != 0 || 
include_defaults
       end
+      config_context_lists.each_pair do |key, meta|
+        meta[:values].each do |context|
+          context_result = context.save(include_defaults)
+          result[key] = (result[key] || []) << context_result if 
context_result.size != 0 || include_defaults
+        end
+      end
+      config_context_hashes.each_pair do |key, meta|
+        meta[:values].each_pair do |context_key, context|
+          context_result = context.save(include_defaults)
+          (result[key] ||= {})[context_key] = context_result if 
context_result.size != 0 || include_defaults
+        end
+      end
       result
     end
     alias :to_hash :save
@@ -180,7 +240,7 @@
     #
     # === Parameters
     # hash<Hash>: a hash in the same format as output by save.
-    # 
+    #
     # === Returns
     # self
     def restore(hash)
@@ -192,6 +252,26 @@
           config_context.reset
         end
       end
+      config_context_lists.each do |key, meta|
+        meta[:values] = []
+        if hash.has_key?(key)
+          hash[key].each do |val|
+            context = define_context(meta[:definition_blocks])
+            context.restore(val)
+            meta[:values] << context
+          end
+        end
+      end
+      config_context_hashes.each do |key, meta|
+        meta[:values] = {}
+        if hash.has_key?(key)
+          hash[key].each do |vkey, val|
+            context = define_context(meta[:definition_blocks])
+            context.restore(val)
+            meta[:values][vkey] = context
+          end
+        end
+      end
     end
 
     # Merge an incoming hash with our config options
@@ -203,11 +283,11 @@
     # self
     def merge!(hash)
       hash.each do |key, value|
-        if self.config_contexts.has_key?(key)
+        if config_contexts.has_key?(key)
           # Grab the config context and let internal_get cache it if so desired
-          self.config_contexts[key].restore(value)
+          config_contexts[key].restore(value)
         else
-          self.configuration[key] = value
+          configuration[key] = value
         end
       end
       self
@@ -221,7 +301,7 @@
     # === Returns
     # result of Hash#keys
     def keys
-      self.configuration.keys
+      configuration.keys
     end
 
     # Creates a shallow copy of the internal hash
@@ -332,6 +412,70 @@
       context
     end
 
+    # Allows you to create a new list of config contexts where you can define 
new
+    # options with default values.
+    #
+    # This method allows you to open up the configurable more than once.
+    #
+    # For example:
+    #
+    # config_context_list :listeners, :listener do
+    #   configurable(:url).defaults_to("http://localhost";)
+    # end
+    #
+    # === Parameters
+    # symbol<Symbol>: the plural name for contexts in the list
+    # symbol<Symbol>: the singular name for contexts in the list
+    # block<Block>: a block that will be run in the context of this new config
+    # class.
+    def config_context_list(plural_symbol, singular_symbol, &block)
+      if configurables.has_key?(symbol)
+        raise ReopenedConfigurableWithConfigContextError, "Cannot redefine 
config value #{plural_symbol} with a config context"
+      end
+
+      unless config_context_lists.has_key?(plural_symbol)
+        config_context_lists[plural_symbol] = {
+          definition_blocks: [],
+          values: [],
+        }
+        define_list_attr_accessor_methods(plural_symbol, singular_symbol)
+      end
+
+      config_context_lists[plural_symbol][:definition_blocks] << block if 
block_given?
+    end
+
+    # Allows you to create a new hash of config contexts where you can define 
new
+    # options with default values.
+    #
+    # This method allows you to open up the configurable more than once.
+    #
+    # For example:
+    #
+    # config_context_hash :listeners, :listener do
+    #   configurable(:url).defaults_to("http://localhost";)
+    # end
+    #
+    # === Parameters
+    # symbol<Symbol>: the plural name for contexts in the list
+    # symbol<Symbol>: the singular name for contexts in the list
+    # block<Block>: a block that will be run in the context of this new config
+    # class.
+    def config_context_hash(plural_symbol, singular_symbol, &block)
+      if configurables.has_key?(symbol)
+        raise ReopenedConfigurableWithConfigContextError, "Cannot redefine 
config value #{plural_symbol} with a config context"
+      end
+
+      unless config_context_hashes.has_key?(plural_symbol)
+        config_context_hashes[plural_symbol] = {
+          definition_blocks: [],
+          values: {},
+        }
+        define_hash_attr_accessor_methods(plural_symbol, singular_symbol)
+      end
+
+      config_context_hashes[plural_symbol][:definition_blocks] << block if 
block_given?
+    end
+
     NOT_PASSED = Object.new
 
     # Gets or sets strict mode.  When strict mode is on, only values which
@@ -407,6 +551,27 @@
 
     private
 
+    # Given a (nested) Hash, turn it into a single top-level hash using dots as
+    # nesting notation. This allows for direction translation into method-style
+    # setting of Config.
+    #
+    # === Parameters
+    # hash<Hash>:: The hash to "de-nestify"
+    # recursive_key<String>:: The existing key to prepend going forward
+    #
+    # === Returns
+    # value:: A single-depth Hash using dot notation to indicate nesting
+    def to_dotted_hash(hash, recursive_key = "")
+      hash.each_with_object({}) do |(k , v), ret|
+        key = recursive_key + k.to_s
+        if v.is_a? Hash
+          ret.merge!(to_dotted_hash(v, key + "."))
+        else
+          ret[key] = v
+        end
+      end
+    end
+
     # Internal dispatch setter for config values.
     #
     # === Parameters
@@ -415,7 +580,7 @@
     #
     def internal_set(symbol, value)
       if configurables.has_key?(symbol)
-        configurables[symbol].set(self.configuration, value)
+        configurables[symbol].set(configuration, value)
       elsif config_contexts.has_key?(symbol)
         config_contexts[symbol].restore(value.to_hash)
       else
@@ -430,9 +595,13 @@
 
     def internal_get(symbol)
       if configurables.has_key?(symbol)
-        configurables[symbol].get(self.configuration)
+        configurables[symbol].get(configuration)
       elsif config_contexts.has_key?(symbol)
         config_contexts[symbol]
+      elsif config_context_lists.has_key?(symbol)
+        config_context_lists[symbol]
+      elsif config_context_hashes.has_key?(symbol)
+        config_context_hashes[symbol]
       else
         if config_strict_mode == :warn
           Chef::Log.warn("Reading unsupported config value #{symbol}.")
@@ -476,5 +645,62 @@
         end
       end
     end
+
+    def define_list_attr_accessor_methods(plural_symbol, singular_symbol)
+      # When Ruby 1.8.7 is no longer supported, this stuff can be done with 
define_singleton_method!
+      meta = class << self; self; end
+      # Getter for list
+      meta.send :define_method, plural_symbol do
+        internal_get(plural_symbol)[:values]
+      end
+      # Adds a single new context to the list
+      meta.send :define_method, singular_symbol do |&block|
+        context_list_details = internal_get(plural_symbol)
+        new_context = define_context(context_list_details[:definition_blocks])
+        context_list_details[:values] << new_context
+        # If the block expects no arguments, then instance_eval
+        if block.arity == 0
+          new_context.instance_eval(&block)
+        else # yield to the block
+          block.yield(new_context)
+        end
+      end
+    end
+
+    def define_hash_attr_accessor_methods(plural_symbol, singular_symbol)
+      # When Ruby 1.8.7 is no longer supported, this stuff can be done with 
define_singleton_method!
+      meta = class << self; self; end
+      # Getter for list
+      meta.send :define_method, plural_symbol do
+        internal_get(plural_symbol)[:values]
+      end
+      # Adds a single new context to the list
+      meta.send :define_method, singular_symbol do |key, &block|
+        context_hash_details = internal_get(plural_symbol)
+        context = if context_hash_details[:values].has_key? key
+                    context_hash_details[:values][key]
+                  else
+                    new_context = 
define_context(context_hash_details[:definition_blocks])
+                    context_hash_details[:values][key] = new_context
+                    new_context
+                  end
+        # If the block expects no arguments, then instance_eval
+        if block.arity == 0
+          context.instance_eval(&block)
+        else # yield to the block
+          block.yield(context)
+        end
+      end
+    end
+
+    def define_context(definition_blocks)
+      context = Class.new
+      context.extend(::Mixlib::Config)
+      context.config_parent = self
+      definition_blocks.each do |block|
+        context.instance_eval(&block)
+      end
+      context
+    end
   end
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metadata new/metadata
--- old/metadata        2016-09-03 00:20:31.000000000 +0200
+++ new/metadata        2018-02-09 19:25:02.000000000 +0100
@@ -1,14 +1,14 @@
 --- !ruby/object:Gem::Specification
 name: mixlib-config
 version: !ruby/object:Gem::Version
-  version: 2.2.4
+  version: 2.2.5
 platform: ruby
 authors:
 - Chef Software, Inc.
 autorequire: 
 bindir: bin
 cert_chain: []
-date: 2016-09-02 00:00:00.000000000 Z
+date: 2018-02-09 00:00:00.000000000 Z
 dependencies:
 - !ruby/object:Gem::Dependency
   name: rake
@@ -39,6 +39,20 @@
       - !ruby/object:Gem::Version
         version: '3.0'
 - !ruby/object:Gem::Dependency
+  name: chefstyle
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - ">="
+      - !ruby/object:Gem::Version
+        version: '0'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - ">="
+      - !ruby/object:Gem::Version
+        version: '0'
+- !ruby/object:Gem::Dependency
   name: rdoc
   requirement: !ruby/object:Gem::Requirement
     requirements:
@@ -74,7 +88,7 @@
 - mixlib-config.gemspec
 - spec/mixlib/config_spec.rb
 - spec/spec_helper.rb
-homepage: http://www.chef.io
+homepage: https://www.chef.io
 licenses:
 - Apache-2.0
 metadata: {}
@@ -86,7 +100,7 @@
   requirements:
   - - ">="
     - !ruby/object:Gem::Version
-      version: '0'
+      version: '2.2'
 required_rubygems_version: !ruby/object:Gem::Requirement
   requirements:
   - - ">="
@@ -94,7 +108,7 @@
       version: '0'
 requirements: []
 rubyforge_project: 
-rubygems_version: 2.6.6
+rubygems_version: 2.7.4
 signing_key: 
 specification_version: 4
 summary: A class based configuration library
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mixlib-config.gemspec new/mixlib-config.gemspec
--- old/mixlib-config.gemspec   2016-09-03 00:20:31.000000000 +0200
+++ new/mixlib-config.gemspec   2018-02-09 19:25:02.000000000 +0100
@@ -13,16 +13,18 @@
     "LICENSE",
     "README.md",
   ]
-  s.files = [ "LICENSE", "NOTICE", "README.md", "Gemfile", "Rakefile" ] + 
Dir.glob("*.gemspec") +
+  s.files = ["LICENSE", "NOTICE", "README.md", "Gemfile", "Rakefile"] + 
Dir.glob("*.gemspec") +
     Dir.glob("{lib,spec}/**/*", File::FNM_DOTMATCH).reject { |f| 
File.directory?(f) }
-  s.homepage = "http://www.chef.io";
+  s.homepage = "https://www.chef.io";
   s.require_paths = ["lib"]
   s.rubygems_version = "1.8.23"
+  s.required_ruby_version = ">= 2.2"
   s.summary = "A class based configuration library"
   s.description = s.summary
   s.license = "Apache-2.0"
 
   s.add_development_dependency "rake"
   s.add_development_dependency "rspec", "~> 3.0"
+  s.add_development_dependency "chefstyle"
   s.add_development_dependency "rdoc"
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spec/mixlib/config_spec.rb 
new/spec/mixlib/config_spec.rb
--- old/spec/mixlib/config_spec.rb      2016-09-03 00:20:31.000000000 +0200
+++ new/spec/mixlib/config_spec.rb      2018-02-09 19:25:02.000000000 +0100
@@ -30,28 +30,28 @@
     allow(File).to receive(:exists?).and_return(true)
     allow(File).to receive(:readable?).and_return(true)
     allow(IO).to receive(:read).with("config.rb").and_return("alpha = 
'omega'\nfoo = 'bar'")
-    expect(lambda {
+    expect(lambda do
       ConfigIt.from_file("config.rb")
-    }).to_not raise_error
+    end).to_not raise_error
   end
 
   it "doesn't raise an ArgumentError with an explanation if you try and set a 
non-existent variable" do
-    expect(lambda {
+    expect(lambda do
       ConfigIt[:foobar] = "blah"
-    }).to_not raise_error
+    end).to_not raise_error
   end
 
   it "raises an Errno::ENOENT if it can't find the file" do
-    expect(lambda {
+    expect(lambda do
       ConfigIt.from_file("/tmp/timmytimmytimmy")
-    }).to raise_error(Errno::ENOENT)
+    end).to raise_error(Errno::ENOENT)
   end
 
   it "allows the error to bubble up when it's anything other than IOError" do
     allow(IO).to receive(:read).with("config.rb").and_return("@#asdf")
-    expect(lambda {
+    expect(lambda do
       ConfigIt.from_file("config.rb")
-    }).to raise_error(SyntaxError)
+    end).to raise_error(SyntaxError)
   end
 
   it "allows you to reference a value by index" do
@@ -796,6 +796,20 @@
       expect(@klass.blah.x).to eql(10)
       expect(@klass.save).to eql({ :blah => { :x => 10 } })
     end
+
+    # this tests existing (somewhat bizzare) behavior of mixlib-config where 
testing to
+    # see if a key exists is equivalent to testing if the key has been set -- 
we can still
+    # retrieve the default value if it was set.  the code in chef/chef which 
merges
+    # knife config values into cli values will be sensitive to this behavior.
+    it "defaults values do not show up when querying with #has_key?" do
+      expect(@klass.blah.has_key?(:x)).to be false
+      expect(@klass.blah.x).to be 5
+    end
+
+    it "if we assign the values, they show up when querying with #has_key?" do
+      @klass.blah.x = 5
+      expect(@klass.blah.has_key?(:x)).to be true
+    end
   end
 
   describe "When a configurable exists with a nested context" do
@@ -1003,4 +1017,201 @@
     end).to 
raise_error(Mixlib::Config::ReopenedConfigContextWithConfigurableError)
   end
 
+  describe "config context lists" do
+    let(:klass) do
+      klass = Class.new
+      klass.extend ::Mixlib::Config
+      klass.instance_eval do
+        config_context_list(:tests, :test) do
+          default :y, 20
+        end
+      end
+      klass
+    end
+    it "defines list methods when declaring a config_context_list" do
+      expect(klass.methods).to include :test
+      expect(klass.methods).to include :tests
+    end
+
+    it "creates a new item each time the singular list is called" do
+      klass.test do
+        y 40
+      end
+      klass.test do
+        y 50
+      end
+      expect(klass.tests.length).to be 2
+      expect(klass.tests.first.y).to be 40
+      expect(klass.tests.last.y).to be 50
+    end
+
+    it "can save the config list" do
+      klass.test do
+        y 40
+      end
+      klass.test do
+        y 50
+      end
+      expect(klass.save).to eq({
+        tests: [
+          { y: 40 },
+          { y: 50 },
+        ],
+      })
+    end
+
+    it "can restore the config list from a hash" do
+      hash = {
+        tests: [
+          { y: 40 },
+          { y: 50 },
+        ],
+      }
+      klass.restore(hash)
+      expect(klass.tests.length).to be 2
+      expect(klass.tests.first.y).to be 40
+      expect(klass.tests.last.y).to be 50
+    end
+  end
+
+  describe "config context hashes" do
+    let(:klass) do
+      klass = Class.new
+      klass.extend ::Mixlib::Config
+      klass.instance_eval do
+        config_context_hash(:tests, :test) do
+          default :y, 20
+        end
+      end
+      klass
+    end
+
+    it "defines list methods when declaring a config_context_hash" do
+      expect(klass.methods).to include :test
+      expect(klass.methods).to include :tests
+    end
+
+    context "when called with a new key each time" do
+      it "creates a new item each time" do
+        klass.test :one do
+          y 40
+        end
+        klass.test :two do
+          y 50
+        end
+        expect(klass.tests.length).to be 2
+        expect(klass.tests[:one].y).to be 40
+        expect(klass.tests[:two].y).to be 50
+      end
+    end
+    context "when called with the same key" do
+      it "modifies the existing value" do
+        klass.test :only do
+          y 40
+        end
+        klass.test :only do
+          y 50
+        end
+        expect(klass.tests.length).to be 1
+        expect(klass.tests[:only].y).to be 50
+      end
+    end
+
+    it "can save the config hash" do
+      klass.test :one do
+        y 40
+      end
+      klass.test :two do
+        y 50
+      end
+      expect(klass.save).to eq({
+        tests: {
+          one: { y: 40 },
+          two: { y: 50 },
+        },
+      })
+    end
+
+    it "can restore the config hash from a hash" do
+      hash = {
+        tests: {
+          one: { y: 40 },
+          two: { y: 50 },
+        },
+      }
+      klass.restore(hash)
+      expect(klass.tests.length).to be 2
+      expect(klass.tests[:one].y).to be 40
+      expect(klass.tests[:two].y).to be 50
+    end
+  end
+
+  describe ".from_yaml" do
+    let(:yaml) do
+      <<-EOH
+---
+foo:
+  - bar
+  - baz
+  - matazz
+alpha: beta
+      EOH
+    end
+
+    it "turns YAML into method-style setting" do
+      allow(File).to receive(:exists?).and_return(true)
+      allow(File).to receive(:readable?).and_return(true)
+      allow(IO).to receive(:read).with("config.yml").and_return(yaml)
+
+      expect(lambda do
+        ConfigIt.from_file("config.yml")
+      end).to_not raise_error
+
+      expect(ConfigIt.foo).to eql(%w{ bar baz matazz })
+      expect(ConfigIt.alpha).to eql("beta")
+    end
+  end
+
+  describe ".from_json" do
+    let(:json) do
+      <<-EOH
+{
+  "foo": [
+    "bar",
+    "baz",
+    "matazz"
+  ],
+  "alpha": "beta"
+}
+      EOH
+    end
+
+    it "turns YAML into method-style setting" do
+      allow(File).to receive(:exists?).and_return(true)
+      allow(File).to receive(:readable?).and_return(true)
+      allow(IO).to receive(:read).with("config.json").and_return(json)
+
+      expect(lambda do
+        ConfigIt.from_file("config.json")
+      end).to_not raise_error
+
+      expect(ConfigIt.foo).to eql(%w{ bar baz matazz })
+      expect(ConfigIt.alpha).to eql("beta")
+    end
+  end
+
+  describe ".from_hash" do
+    let(:hash) do
+      {
+        "alpha" => "beta",
+        "foo" => %w{ bar baz matazz},
+      }
+    end
+
+    it "translates the Hash into method-style" do
+      ConfigIt.from_hash(hash)
+      expect(ConfigIt.foo).to eql(%w{ bar baz matazz })
+      expect(ConfigIt.alpha).to eql("beta")
+    end
+  end
 end


Reply via email to