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.
- data/.gitignore +2 -0
- data/.nojekyll +0 -0
- data/.yardopts +1 -0
- data/README.rdoc +18 -23
- data/Rakefile +16 -7
- data/VERSION +1 -1
- data/bin/plist4r +8 -0
- data/lib/plist4r.rb +35 -7
- data/lib/plist4r/application.rb +19 -0
- data/lib/plist4r/backend.rb +23 -2
- data/lib/plist4r/backend/example.rb +45 -4
- data/lib/plist4r/backend/haml.rb +1 -0
- data/lib/plist4r/backend/libxml4r.rb +3 -2
- data/lib/plist4r/backend/plutil.rb +4 -1
- data/lib/plist4r/backend/ruby_cocoa.rb +10 -3
- data/lib/plist4r/commands.rb +61 -0
- data/lib/plist4r/config.rb +21 -1
- data/lib/plist4r/mixin/data_methods.rb +23 -3
- data/lib/plist4r/mixin/mixlib_cli.rb +199 -0
- data/lib/plist4r/mixin/mixlib_config.rb +158 -152
- data/lib/plist4r/mixin/ordered_hash.rb +143 -135
- data/lib/plist4r/mixin/popen4.rb +25 -5
- data/lib/plist4r/mixin/ruby_stdlib.rb +13 -1
- data/lib/plist4r/options.rb +44 -0
- data/lib/plist4r/plist.rb +156 -13
- data/lib/plist4r/plist_type.rb +25 -4
- data/lib/plist4r/plist_type/launchd.rb +377 -263
- data/plist4r.gemspec +56 -48
- data/test.rb +2 -2
- metadata +13 -7
- data/lib/plist4r/mixin/class_attributes.rb +0 -128
@@ -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
|
data/lib/plist4r/config.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
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
|
28
|
-
module
|
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
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
36
|
+
def self.extended(base)
|
37
|
+
class << base; attr_accessor :configuration; end
|
38
|
+
base.configuration = Hash.new
|
39
|
+
end
|
34
40
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
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
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
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
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
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
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
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
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
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
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
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
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
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
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
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
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
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
|
-
|
141
|
+
protected :internal_set
|
136
142
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
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
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
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
|
-
|
173
|
-
|
178
|
+
# Returning
|
179
|
+
self.configuration[method_symbol]
|
174
180
|
|
181
|
+
end
|
175
182
|
end
|
176
183
|
end
|
177
184
|
end
|
178
|
-
|