plist4r 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,61 @@
1
+ require 'plist4r/config'
2
+ require 'fileutils'
3
+
4
+ module Plist4r
5
+ # This objects manages all of the commands to be executed by an instance of {Plist4r::Application}
6
+ # @see Plist4r::Application
7
+ # @see Plist4r::CLI
8
+ class Commands
9
+ PriorityOrder = [:ruby_lib]
10
+
11
+ # To be executed once. Branches out to subroutines, and handles the order-of-execution of
12
+ # those main subrountines.
13
+ def run
14
+ PriorityOrder.each do |command|
15
+ send command if self.class.method_defined?(command) && Plist4r::Config[:args][command]
16
+ end
17
+
18
+ left_to_execute = Plist4r::Config[:args].keys - PriorityOrder
19
+ Plist4r::Config[:args].each do |command, value|
20
+ send command if left_to_execute.include?(command) && self.class.method_defined?(command) && value
21
+ end
22
+ end
23
+
24
+ # Implements the `plist4r --ruby-lib` subcommand.
25
+ # @see Plist4r::CLI
26
+ def ruby_lib
27
+ plist4r_lib = File.expand_path "../../lib", File.dirname(__FILE__)
28
+ dest = File.expand_path(Plist4r::Config[:args][:dir] || FileUtils.pwd)
29
+
30
+ raise "sorry, cant write to the same source and destination" if plist4r_lib == dest
31
+ raise "sorry, cant write to a destination within the source folder" if dest =~ /^#{plist4r_lib}/
32
+
33
+ FileUtils.mkdir_p dest
34
+ FileUtils.rm_rf "#{dest}/plist4r"
35
+ FileUtils.cp_r Dir.glob("#{plist4r_lib}/*"), dest
36
+
37
+ if Plist4r::Config[:args][:brew]
38
+ backends = Dir.glob "#{dest}/plist4r/backend/*"
39
+ non_brew_files = [
40
+ backends - ["#{dest}/plist4r/backend/ruby_cocoa.rb"],
41
+ "#{dest}/plist4r/mixin/mixlib_cli.rb",
42
+ "#{dest}/plist4r/options.rb",
43
+ "#{dest}/plist4r/commands.rb",
44
+ "#{dest}/plist4r/application.rb",
45
+ # "#{dest}/plist4r/",
46
+ ].flatten
47
+ FileUtils.rm_rf(non_brew_files)
48
+
49
+ config = File.read "#{dest}/plist4r/config.rb"
50
+ config.gsub! /\n(\s*)backends \[.*\](\s*)\n/ do |match|
51
+ "\n#{$1}backends [\"ruby_cocoa\"]#{$2}\n"
52
+ end
53
+
54
+ File.open("#{dest}/plist4r/config.rb",'w') do |o|
55
+ o << config
56
+ end
57
+ end
58
+
59
+ end
60
+ end
61
+ end
@@ -4,6 +4,26 @@ require 'plist4r/backend'
4
4
  Dir.glob(File.dirname(__FILE__) + "/backend/**/*.rb").each {|b| require File.expand_path b}
5
5
 
6
6
  module Plist4r
7
+
8
+ # The special configuration object, which holds all runtime defaults for individual plist instances.
9
+ # When we create a new {Plist4r::Plist} object, it will inherit these defaults.
10
+ # @example
11
+ # # Reverse the priority order of backends
12
+ # Plist4r::Config[:backends].reverse!
13
+ #
14
+ # # Set the default folder from which to load / save plist files
15
+ # Plist4r::Config[:default_path] "/path/to/my/plist/files"
16
+ #
17
+ # # Save new plist files as binary plists (when format not known)
18
+ # Plist4r::Config[:default_format] :binary
19
+ #
20
+ # # Add custom / application specific Plist Type. You'll also need to subclass {Plist4r::PlistType}
21
+ # Expects class Plist4r::PlistType::MyPlistType to be defined
22
+ # require 'my_plist_type.rb'
23
+ # Plist4r::Config[:types] << "my_plist_type"
24
+ #
25
+ # # Raise an exception plist keys which dont belong to the selected Plist type
26
+ # Plist4r::Config[:strict_keys] true
7
27
  class Config
8
28
  extend Mixlib::Config
9
29
 
@@ -14,7 +34,7 @@ module Plist4r
14
34
  backends << Dir.glob(File.dirname(__FILE__) + "/backend/**/*.rb").collect {|b| File.basename(b,".rb") }
15
35
  backends.flatten!.uniq!
16
36
 
17
- unsupported_keys true
37
+ strict_keys false
18
38
  raise_any_failure true
19
39
  deafult_format :xml
20
40
  default_path nil
@@ -24,7 +24,6 @@ module Plist4r
24
24
  def method_missing method_symbol, *args, &blk
25
25
  # puts "method_missing: #{method_symbol.inspect}, args: #{args.inspect}"
26
26
  # puts "@hash = #{@hash.inspect}"
27
- # puts "hi"
28
27
  valid_keys.each do |key_type, valid_keys_of_those_type|
29
28
  if valid_keys_of_those_type.include?(method_symbol.to_s.camelcase)
30
29
  puts "key_type = #{key_type}, method_symbol.to_s.camelcase = #{method_symbol.to_s.camelcase}, args = #{args.inspect}"
@@ -32,9 +31,8 @@ module Plist4r
32
31
  return set_or_return key_type, method_symbol.to_s.camelcase, *args, &blk
33
32
  end
34
33
  end
35
- # puts "there"
36
34
  # puts @plist.inspect
37
- if @plist.unsupported_keys
35
+ unless @plist.strict_keys
38
36
  key_type = nil
39
37
  # return eval("set_or_return key_type, method_symbol.to_s.camelcase, *args, &blk")
40
38
  return set_or_return key_type, method_symbol.to_s.camelcase, *args, &blk
@@ -66,6 +64,28 @@ module Plist4r
66
64
  end
67
65
  end
68
66
 
67
+ # Set a plist key to a specific value
68
+ # @param [String] The Plist key, as-is
69
+ # @param value A ruby object (Hash, String, Array, etc) to set as the value of the plist key
70
+ # @example
71
+ # plist.set "CFBundleIdentifier", "com.apple.myapp"
72
+ # @see #set_or_return
73
+ def set key, value
74
+ set_or_return nil, key, value
75
+ end
76
+
77
+ # Return the value of an existing plist key
78
+ # @return The key's current value, at the time this method was called
79
+ # @see #set_or_return
80
+ def value_of key
81
+ set_or_return nil, key
82
+ end
83
+
84
+ # Set or return a plist key, value pair
85
+ # @param [Symbol, nil] key_type The type of class which the value of the key must belong to. Used for validity check.
86
+ # If key_type is set to nil, then skip value data check
87
+ # @return the key's value
88
+ # @see #validate_value
69
89
  def set_or_return key_type, key, value=nil
70
90
  # puts "#{method_name}, key_type: #{key_type.inspect}, key: #{key.inspect}, value: #{value.inspect}"
71
91
  if value
@@ -0,0 +1,199 @@
1
+
2
+ require 'optparse'
3
+
4
+ module Plist4r
5
+ module Mixlib
6
+ #
7
+ # Author:: Adam Jacob (<adam@opscode.com>)
8
+ # Copyright:: Copyright (c) 2008 Opscode, Inc.
9
+ # License:: Apache License, Version 2.0
10
+ #
11
+ # Licensed under the Apache License, Version 2.0 (the "License");
12
+ # you may not use this file except in compliance with the License.
13
+ # You may obtain a copy of the License at
14
+ #
15
+ # http://www.apache.org/licenses/LICENSE-2.0
16
+ #
17
+ # Unless required by applicable law or agreed to in writing, software
18
+ # distributed under the License is distributed on an "AS IS" BASIS,
19
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
+ # See the License for the specific language governing permissions and
21
+ # limitations under the License.
22
+ #
23
+ module CLI
24
+ module ClassMethods
25
+ # Add a command line option.
26
+ #
27
+ # === Parameters
28
+ # name<Symbol>:: The name of the option to add
29
+ # args<Hash>:: A hash of arguments for the option, specifying how it should be parsed.
30
+ # === Returns
31
+ # true:: Always returns true.
32
+ def option(name, args)
33
+ @options ||= {}
34
+ raise(ArgumentError, "Option name must be a symbol") unless name.kind_of?(Symbol)
35
+ @options[name.to_sym] = args
36
+ end
37
+
38
+ # Get the hash of current options.
39
+ #
40
+ # === Returns
41
+ # @options<Hash>:: The current options hash.
42
+ def options
43
+ @options ||= {}
44
+ @options
45
+ end
46
+
47
+ # Set the current options hash
48
+ #
49
+ # === Parameters
50
+ # val<Hash>:: The hash to set the options to
51
+ #
52
+ # === Returns
53
+ # @options<Hash>:: The current options hash.
54
+ def options=(val)
55
+ raise(ArgumentError, "Options must recieve a hash") unless val.kind_of?(Hash)
56
+ @options = val
57
+ end
58
+
59
+ # Change the banner. Defaults to:
60
+ # Usage: #{0} (options)
61
+ #
62
+ # === Parameters
63
+ # bstring<String>:: The string to set the banner to
64
+ #
65
+ # === Returns
66
+ # @banner<String>:: The current banner
67
+ def banner(bstring=nil)
68
+ if bstring
69
+ @banner = bstring
70
+ else
71
+ @banner ||= "Usage: #{$0} (options)"
72
+ @banner
73
+ end
74
+ end
75
+ end
76
+
77
+ attr_accessor :options, :config, :banner, :opt_parser
78
+
79
+ # Create a new Mixlib::CLI class. If you override this, make sure you call super!
80
+ #
81
+ # === Parameters
82
+ # *args<Array>:: The array of arguments passed to the initializer
83
+ #
84
+ # === Returns
85
+ # object<Mixlib::Config>:: Returns an instance of whatever you wanted :)
86
+ def initialize(*args)
87
+ @options = Hash.new
88
+ @config = Hash.new
89
+
90
+ # Set the banner
91
+ @banner = self.class.banner
92
+
93
+ # Dupe the class options for this instance
94
+ klass_options = self.class.options
95
+ klass_options.keys.inject(@options) { |memo, key| memo[key] = klass_options[key].dup; memo }
96
+
97
+ # Set the default configuration values for this instance
98
+ @options.each do |config_key, config_opts|
99
+ config_opts[:on] ||= :on
100
+ config_opts[:boolean] ||= false
101
+ config_opts[:required] ||= false
102
+ config_opts[:proc] ||= nil
103
+ config_opts[:show_options] ||= false
104
+ config_opts[:exit] ||= nil
105
+
106
+ if config_opts.has_key?(:default)
107
+ @config[config_key] = config_opts[:default]
108
+ end
109
+ end
110
+
111
+ super(*args)
112
+ end
113
+
114
+ # Parses an array, by default ARGV, for command line options (as configured at
115
+ # the class level).
116
+ # === Parameters
117
+ # argv<Array>:: The array of arguments to parse; defaults to ARGV
118
+ #
119
+ # === Returns
120
+ # argv<Array>:: Returns any un-parsed elements.
121
+ def parse_options(argv=ARGV)
122
+ argv = argv.dup
123
+ @opt_parser = OptionParser.new do |opts|
124
+ # Set the banner
125
+ opts.banner = banner
126
+
127
+ # Create new options
128
+ options.sort { |a, b| a[0].to_s <=> b[0].to_s }.each do |opt_key, opt_val|
129
+ opt_args = build_option_arguments(opt_val)
130
+
131
+ opt_method = case opt_val[:on]
132
+ when :on
133
+ :on
134
+ when :tail
135
+ :on_tail
136
+ when :head
137
+ :on_head
138
+ else
139
+ raise ArgumentError, "You must pass :on, :tail, or :head to :on"
140
+ end
141
+
142
+ parse_block = case opt_val[:boolean]
143
+ when true
144
+ Proc.new() do
145
+ config[opt_key] = (opt_val[:proc] && opt_val[:proc].call(true)) || true
146
+ puts opts if opt_val[:show_options]
147
+ exit opt_val[:exit] if opt_val[:exit]
148
+ end
149
+ when false
150
+ Proc.new() do |c|
151
+ config[opt_key] = (opt_val[:proc] && opt_val[:proc].call(c)) || c
152
+ puts opts if opt_val[:show_options]
153
+ exit opt_val[:exit] if opt_val[:exit]
154
+ end
155
+ end
156
+
157
+ full_opt = [ opt_method ]
158
+ opt_args.inject(full_opt) { |memo, arg| memo << arg; memo }
159
+ full_opt << parse_block
160
+ opts.send(*full_opt)
161
+ end
162
+ end
163
+ @opt_parser.parse!(argv)
164
+
165
+ # Deal with any required values
166
+ options.each do |opt_key, opt_value|
167
+ if opt_value[:required] && ! config[opt_key]
168
+ reqarg = opt_value[:short] || opt_value[:long]
169
+ puts "You must supply #{reqarg}!"
170
+ puts @opt_parser
171
+ exit 2
172
+ end
173
+ end
174
+
175
+ argv
176
+ end
177
+
178
+ def build_option_arguments(opt_setting)
179
+ arguments = Array.new
180
+
181
+ arguments << opt_setting[:short] if opt_setting.has_key?(:short)
182
+ arguments << opt_setting[:long] if opt_setting.has_key?(:long)
183
+
184
+ if opt_setting.has_key?(:description)
185
+ description = opt_setting[:description]
186
+ description << " (required)" if opt_setting[:required]
187
+ arguments << description
188
+ end
189
+
190
+ arguments
191
+ end
192
+
193
+ def self.included(receiver)
194
+ receiver.extend(Mixlib::CLI::ClassMethods)
195
+ end
196
+
197
+ end
198
+ end
199
+ end
@@ -1,178 +1,184 @@
1
- #
2
- # Author:: Adam Jacob (<adam@opscode.com>)
3
- # Author:: Nuo Yan (<nuo@opscode.com>)
4
- # Author:: Christopher Brown (<cb@opscode.com>)
5
- # Copyright:: Copyright (c) 2008 Opscode, Inc.
6
- # License:: Apache License, Version 2.0
7
- #
8
- # Licensed under the Apache License, Version 2.0 (the "License");
9
- # you may not use this file except in compliance with the License.
10
- # You may obtain a copy of the License at
11
- #
12
- # http://www.apache.org/licenses/LICENSE-2.0
13
- #
14
- # Unless required by applicable law or agreed to in writing, software
15
- # distributed under the License is distributed on an "AS IS" BASIS,
16
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
- # See the License for the specific language governing permissions and
18
- # limitations under the License.
19
- #
20
1
 
21
- class Object # http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html
2
+ class Object
3
+ # http://dannytatom.github.com/metaid
4
+ #
5
+ # http://www.bestechvideos.com/2008/07/01/ruby-plus-59-ruby-metaclasses-part-5
6
+ #
7
+ # @see Plist4r::Mixlib::Config
22
8
  def meta_def name, &blk
23
9
  (class << self; self; end).instance_eval { define_method name, &blk }
24
10
  end
25
11
  end
26
12
 
27
- module Mixlib
28
- module Config
13
+ module Plist4r
14
+ module Mixlib
15
+ #
16
+ # Author:: Adam Jacob (<adam@opscode.com>)
17
+ # Author:: Nuo Yan (<nuo@opscode.com>)
18
+ # Author:: Christopher Brown (<cb@opscode.com>)
19
+ # Copyright:: Copyright (c) 2008 Opscode, Inc.
20
+ # License:: Apache License, Version 2.0
21
+ #
22
+ # Licensed under the Apache License, Version 2.0 (the "License");
23
+ # you may not use this file except in compliance with the License.
24
+ # You may obtain a copy of the License at
25
+ #
26
+ # http://www.apache.org/licenses/LICENSE-2.0
27
+ #
28
+ # Unless required by applicable law or agreed to in writing, software
29
+ # distributed under the License is distributed on an "AS IS" BASIS,
30
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31
+ # See the License for the specific language governing permissions and
32
+ # limitations under the License.
33
+ #
34
+ module Config
29
35
 
30
- def self.extended(base)
31
- class << base; attr_accessor :configuration; end
32
- base.configuration = Hash.new
33
- end
36
+ def self.extended(base)
37
+ class << base; attr_accessor :configuration; end
38
+ base.configuration = Hash.new
39
+ end
34
40
 
35
- # Loads a given ruby file, and runs instance_eval against it in the context of the current
36
- # object.
37
- #
38
- # Raises an IOError if the file cannot be found, or is not readable.
39
- #
40
- # === Parameters
41
- # <string>:: A filename to read from
42
- def from_file(filename)
43
- self.instance_eval(IO.read(filename), filename, 1)
44
- end
41
+ # Loads a given ruby file, and runs instance_eval against it in the context of the current
42
+ # object.
43
+ #
44
+ # Raises an IOError if the file cannot be found, or is not readable.
45
+ #
46
+ # === Parameters
47
+ # <string>:: A filename to read from
48
+ def from_file(filename)
49
+ self.instance_eval(IO.read(filename), filename, 1)
50
+ end
45
51
 
46
- # Pass Mixlib::Config.configure() a block, and it will yield self.configuration.
47
- #
48
- # === Parameters
49
- # <block>:: A block that is sent self.configuration as its argument
50
- def configure(&block)
51
- block.call(self.configuration)
52
- end
52
+ # Pass Mixlib::Config.configure() a block, and it will yield self.configuration.
53
+ #
54
+ # === Parameters
55
+ # <block>:: A block that is sent self.configuration as its argument
56
+ def configure(&block)
57
+ block.call(self.configuration)
58
+ end
53
59
 
54
- # Get the value of a configuration option
55
- #
56
- # === Parameters
57
- # config_option<Symbol>:: The configuration option to return
58
- #
59
- # === Returns
60
- # value:: The value of the configuration option
61
- #
62
- # === Raises
63
- # <ArgumentError>:: If the configuration option does not exist
64
- def [](config_option)
65
- self.configuration[config_option.to_sym]
66
- end
60
+ # Get the value of a configuration option
61
+ #
62
+ # === Parameters
63
+ # config_option<Symbol>:: The configuration option to return
64
+ #
65
+ # === Returns
66
+ # value:: The value of the configuration option
67
+ #
68
+ # === Raises
69
+ # <ArgumentError>:: If the configuration option does not exist
70
+ def [](config_option)
71
+ self.configuration[config_option.to_sym]
72
+ end
67
73
 
68
- # Set the value of a configuration option
69
- #
70
- # === Parameters
71
- # config_option<Symbol>:: The configuration option to set (within the [])
72
- # value:: The value for the configuration option
73
- #
74
- # === Returns
75
- # value:: The new value of the configuration option
76
- def []=(config_option, value)
77
- internal_set(config_option,value)
78
- end
74
+ # Set the value of a configuration option
75
+ #
76
+ # === Parameters
77
+ # config_option<Symbol>:: The configuration option to set (within the [])
78
+ # value:: The value for the configuration option
79
+ #
80
+ # === Returns
81
+ # value:: The new value of the configuration option
82
+ def []=(config_option, value)
83
+ internal_set(config_option,value)
84
+ end
79
85
 
80
- # Check if Mixlib::Config has a configuration option.
81
- #
82
- # === Parameters
83
- # key<Symbol>:: The configuration option to check for
84
- #
85
- # === Returns
86
- # <True>:: If the configuration option exists
87
- # <False>:: If the configuration option does not exist
88
- def has_key?(key)
89
- self.configuration.has_key?(key.to_sym)
90
- end
86
+ # Check if Mixlib::Config has a configuration option.
87
+ #
88
+ # === Parameters
89
+ # key<Symbol>:: The configuration option to check for
90
+ #
91
+ # === Returns
92
+ # <True>:: If the configuration option exists
93
+ # <False>:: If the configuration option does not exist
94
+ def has_key?(key)
95
+ self.configuration.has_key?(key.to_sym)
96
+ end
91
97
 
92
- # Merge an incoming hash with our config options
93
- #
94
- # === Parameters
95
- # hash<Hash>:: The incoming hash
96
- #
97
- # === Returns
98
- # result of Hash#merge!
99
- def merge!(hash)
100
- self.configuration.merge!(hash)
101
- end
98
+ # Merge an incoming hash with our config options
99
+ #
100
+ # === Parameters
101
+ # hash<Hash>:: The incoming hash
102
+ #
103
+ # === Returns
104
+ # result of Hash#merge!
105
+ def merge!(hash)
106
+ self.configuration.merge!(hash)
107
+ end
102
108
 
103
- # Return the set of config hash keys
104
- #
105
- # === Returns
106
- # result of Hash#keys
107
- def keys
108
- self.configuration.keys
109
- end
109
+ # Return the set of config hash keys
110
+ #
111
+ # === Returns
112
+ # result of Hash#keys
113
+ def keys
114
+ self.configuration.keys
115
+ end
110
116
 
111
- # Creates a shallow copy of the internal hash
112
- #
113
- # === Returns
114
- # result of Hash#dup
115
- def hash_dup
116
- self.configuration.dup
117
- end
117
+ # Creates a shallow copy of the internal hash
118
+ #
119
+ # === Returns
120
+ # result of Hash#dup
121
+ def hash_dup
122
+ self.configuration.dup
123
+ end
118
124
 
119
- # Internal dispatch setter, calling either the real defined method or setting the
120
- # hash value directly
121
- #
122
- # === Parameters
123
- # method_symbol<Symbol>:: Name of the method (variable setter)
124
- # value<Object>:: Value to be set in config hash
125
- #
126
- def internal_set(method_symbol,value)
127
- method_name = method_symbol.id2name
128
- if (self.public_methods - ["[]="]).include?("#{method_name}=")
129
- self.send("#{method_name}=", value)
130
- else
131
- self.configuration[method_symbol] = value
125
+ # Internal dispatch setter, calling either the real defined method or setting the
126
+ # hash value directly
127
+ #
128
+ # === Parameters
129
+ # method_symbol<Symbol>:: Name of the method (variable setter)
130
+ # value<Object>:: Value to be set in config hash
131
+ #
132
+ def internal_set(method_symbol,value)
133
+ method_name = method_symbol.id2name
134
+ if (self.public_methods - ["[]="]).include?("#{method_name}=")
135
+ self.send("#{method_name}=", value)
136
+ else
137
+ self.configuration[method_symbol] = value
138
+ end
132
139
  end
133
- end
134
140
 
135
- protected :internal_set
141
+ protected :internal_set
136
142
 
137
- # metaprogramming to ensure that the slot for method_symbol
138
- # gets set to value after any other logic is run
139
- # === Parameters
140
- # method_symbol<Symbol>:: Name of the method (variable setter)
141
- # blk<Block>:: logic block to run in setting slot method_symbol to value
142
- # value<Object>:: Value to be set in config hash
143
- #
144
- def config_attr_writer(method_symbol, &blk)
145
- method_name = "#{method_symbol.to_s}="
146
- meta_def method_name do |value|
147
- self.configuration[method_symbol] = blk.call(value)
143
+ # metaprogramming to ensure that the slot for method_symbol
144
+ # gets set to value after any other logic is run
145
+ # === Parameters
146
+ # method_symbol<Symbol>:: Name of the method (variable setter)
147
+ # blk<Block>:: logic block to run in setting slot method_symbol to value
148
+ # value<Object>:: Value to be set in config hash
149
+ #
150
+ def config_attr_writer(method_symbol, &blk)
151
+ method_name = "#{method_symbol.to_s}="
152
+ meta_def method_name do |value|
153
+ self.configuration[method_symbol] = blk.call(value)
154
+ end
148
155
  end
149
- end
150
156
 
151
- # Allows for simple lookups and setting of configuration options via method calls
152
- # on Mixlib::Config. If there any arguments to the method, they are used to set
153
- # the value of the configuration option. Otherwise, it's a simple get operation.
154
- #
155
- # === Parameters
156
- # method_symbol<Symbol>:: The method called. Must match a configuration option.
157
- # *args:: Any arguments passed to the method
158
- #
159
- # === Returns
160
- # value:: The value of the configuration option.
161
- #
162
- # === Raises
163
- # <ArgumentError>:: If the method_symbol does not match a configuration option.
164
- def method_missing(method_symbol, *args)
165
- num_args = args.length
166
- # Setting
167
- if num_args > 0
168
- method_symbol = $1.to_sym unless (method_symbol.to_s =~ /(.+)=$/).nil?
169
- internal_set method_symbol, (num_args == 1 ? args[0] : args)
170
- end
157
+ # Allows for simple lookups and setting of configuration options via method calls
158
+ # on Mixlib::Config. If there any arguments to the method, they are used to set
159
+ # the value of the configuration option. Otherwise, it's a simple get operation.
160
+ #
161
+ # === Parameters
162
+ # method_symbol<Symbol>:: The method called. Must match a configuration option.
163
+ # *args:: Any arguments passed to the method
164
+ #
165
+ # === Returns
166
+ # value:: The value of the configuration option.
167
+ #
168
+ # === Raises
169
+ # <ArgumentError>:: If the method_symbol does not match a configuration option.
170
+ def method_missing(method_symbol, *args)
171
+ num_args = args.length
172
+ # Setting
173
+ if num_args > 0
174
+ method_symbol = $1.to_sym unless (method_symbol.to_s =~ /(.+)=$/).nil?
175
+ internal_set method_symbol, (num_args == 1 ? args[0] : args)
176
+ end
171
177
 
172
- # Returning
173
- self.configuration[method_symbol]
178
+ # Returning
179
+ self.configuration[method_symbol]
174
180
 
181
+ end
175
182
  end
176
183
  end
177
184
  end
178
-