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