plist4r 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
-