mattock 0.9.0 → 0.10.0
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.
- checksums.yaml +4 -4
- data/lib/mattock/cascading-definition.rb +2 -2
- data/lib/mattock/task.rb +7 -6
- data/lib/mattock/tasklib.rb +1 -1
- metadata +38 -32
- data/lib/mattock/configurable.rb +0 -29
- data/lib/mattock/configurable/class-methods.rb +0 -227
- data/lib/mattock/configurable/directory-structure.rb +0 -163
- data/lib/mattock/configurable/field-metadata.rb +0 -157
- data/lib/mattock/configurable/field-processor.rb +0 -54
- data/lib/mattock/configurable/instance-methods.rb +0 -87
- data/lib/mattock/configurable/proxy-value.rb +0 -30
- data/spec/configurable.rb +0 -270
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 70b769461d13694dbd33d6aca28506eb472e8ae5
|
4
|
+
data.tar.gz: 27701d143e0ddd82f0edd468a2b7d8e82ef6a3e0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c900dab527d13a9debdb1b7675476da4cca839c59fa2883831f968a3871b307a2114d139e1cb632d47fe50a91241bd869da57c70b55e2fbbdf8760b9ad5539a4
|
7
|
+
data.tar.gz: 8f0b1dfb07599a17df00ba078c591569164c023c721a9e367ade70ed76515577881206ad7e8d3980693415b2d811865f591cc7ed5bab3bbf236b6ea187c8a408
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'calibrate/configurable'
|
2
2
|
|
3
3
|
module Mattock
|
4
4
|
#Collects shared configuration management behavior for TaskLibs and Tasks
|
@@ -23,7 +23,7 @@ module Mattock
|
|
23
23
|
#
|
24
24
|
#For an overview see {TaskLib}
|
25
25
|
module CascadingDefinition
|
26
|
-
include Configurable
|
26
|
+
include Calibrate::Configurable
|
27
27
|
|
28
28
|
def setup_cascade(*other_definitions)
|
29
29
|
@runtime = false
|
data/lib/mattock/task.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'mattock/cascading-definition'
|
2
|
+
require 'calibrate'
|
2
3
|
require 'singleton' #Rake fails to require this properly
|
3
4
|
require 'rake/task'
|
4
5
|
require 'rake/file_task'
|
@@ -10,10 +11,10 @@ module Mattock
|
|
10
11
|
# configuration block to change how a common task behaves, while still
|
11
12
|
# overriding Rake API methods like Task#needed? and Task#timestamp
|
12
13
|
module ConfigurableTask
|
13
|
-
include Configurable
|
14
|
+
include Calibrate::Configurable
|
14
15
|
include CascadingDefinition
|
15
16
|
include DeferredDefinition
|
16
|
-
include Configurable::DirectoryStructure
|
17
|
+
include Calibrate::Configurable::DirectoryStructure
|
17
18
|
|
18
19
|
module ClassMethods
|
19
20
|
def default_taskname(name)
|
@@ -21,9 +22,9 @@ module Mattock
|
|
21
22
|
end
|
22
23
|
|
23
24
|
def define_task(*args)
|
24
|
-
configs = args.take_while{|arg| Configurable === arg}
|
25
|
+
configs = args.take_while{|arg| Calibrate::Configurable === arg}
|
25
26
|
extracted_task_args = args[configs.length..-1]
|
26
|
-
if extracted_task_args.any?{|arg| Configurable === arg}
|
27
|
+
if extracted_task_args.any?{|arg| Calibrate::Configurable === arg}
|
27
28
|
raise "Mattock::Task classes should be created with parent configs, then Rake task args"
|
28
29
|
end
|
29
30
|
|
@@ -56,8 +57,8 @@ module Mattock
|
|
56
57
|
|
57
58
|
def self.included(sub)
|
58
59
|
sub.extend ClassMethods
|
59
|
-
Configurable.included(sub)
|
60
|
-
Configurable::DirectoryStructure.included(sub)
|
60
|
+
Calibrate::Configurable.included(sub)
|
61
|
+
Calibrate::Configurable::DirectoryStructure.included(sub)
|
61
62
|
DeferredDefinition.add_settings(sub)
|
62
63
|
sub.setting :task_name
|
63
64
|
sub.setting :task_args
|
data/lib/mattock/tasklib.rb
CHANGED
@@ -50,7 +50,7 @@ module Mattock
|
|
50
50
|
#configuration options are built using {Configurable}
|
51
51
|
class TaskLib < ::Rake::TaskLib
|
52
52
|
include CascadingDefinition
|
53
|
-
include Configurable::DirectoryStructure
|
53
|
+
include Calibrate::Configurable::DirectoryStructure
|
54
54
|
|
55
55
|
attr_writer :namespace_name
|
56
56
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mattock
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Judson Lester
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-08-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: corundum
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - ~>
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: 0.3.1
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: calibrate
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.0.1
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ~>
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.0.1
|
83
97
|
description: |2+
|
84
98
|
If Rake won't do it by itself, you oughtta Mattock.
|
85
99
|
|
@@ -99,43 +113,35 @@ extra_rdoc_files:
|
|
99
113
|
- doc/README
|
100
114
|
- doc/Specifications
|
101
115
|
files:
|
102
|
-
-
|
103
|
-
-
|
104
|
-
-
|
105
|
-
-
|
106
|
-
-
|
107
|
-
- yard_templates/default/layout/html/tasklib_list.erb
|
116
|
+
- doc/README
|
117
|
+
- doc/Specifications
|
118
|
+
- lib/mattock.rb
|
119
|
+
- lib/mattock/bundle-command-task.rb
|
120
|
+
- lib/mattock/cascading-definition.rb
|
108
121
|
- lib/mattock/command-task.rb
|
109
122
|
- lib/mattock/command-tasklib.rb
|
110
|
-
- lib/mattock/
|
111
|
-
- lib/mattock/template-host.rb
|
112
|
-
- lib/mattock/yard_extensions.rb
|
123
|
+
- lib/mattock/configuration-store.rb
|
113
124
|
- lib/mattock/remote-command-task.rb
|
114
|
-
- lib/mattock/bundle-command-task.rb
|
115
|
-
- lib/mattock/tasklib.rb
|
116
125
|
- lib/mattock/task.rb
|
126
|
+
- lib/mattock/tasklib.rb
|
127
|
+
- lib/mattock/template-host.rb
|
117
128
|
- lib/mattock/template-task.rb
|
118
|
-
- lib/mattock/
|
119
|
-
- lib/mattock/
|
120
|
-
- lib/mattock/configurable/proxy-value.rb
|
121
|
-
- lib/mattock/configurable/instance-methods.rb
|
122
|
-
- lib/mattock/configurable/class-methods.rb
|
123
|
-
- lib/mattock/configurable/directory-structure.rb
|
124
|
-
- lib/mattock/configurable/field-metadata.rb
|
125
|
-
- lib/mattock/configuration-store.rb
|
126
|
-
- lib/mattock/cascading-definition.rb
|
127
|
-
- lib/mattock.rb
|
128
|
-
- doc/README
|
129
|
-
- doc/Specifications
|
129
|
+
- lib/mattock/testing/rake-example-group.rb
|
130
|
+
- lib/mattock/yard_extensions.rb
|
130
131
|
- spec/command-task.rb
|
131
|
-
- spec/tasklib.rb
|
132
|
-
- spec/configurable.rb
|
133
132
|
- spec/configuration-store.rb
|
134
|
-
- spec/
|
133
|
+
- spec/tasklib.rb
|
135
134
|
- spec/template-host.rb
|
136
|
-
-
|
135
|
+
- spec/yard-extensions.rb
|
137
136
|
- spec_help/gem_test_suite.rb
|
138
|
-
|
137
|
+
- spec_help/spec_helper.rb
|
138
|
+
- yard_templates/default/layout/html/setup.rb
|
139
|
+
- yard_templates/default/layout/html/tasklib_list.erb
|
140
|
+
- yard_templates/default/module/html/setting_summary.erb
|
141
|
+
- yard_templates/default/module/html/settings.erb
|
142
|
+
- yard_templates/default/module/html/task_definition.erb
|
143
|
+
- yard_templates/default/module/setup.rb
|
144
|
+
homepage: https://git.lrdesign.com/judson/mattock/tree/master
|
139
145
|
licenses:
|
140
146
|
- MIT
|
141
147
|
metadata: {}
|
@@ -145,7 +151,7 @@ rdoc_options:
|
|
145
151
|
- --main
|
146
152
|
- doc/README
|
147
153
|
- --title
|
148
|
-
- mattock-0.
|
154
|
+
- mattock-0.10.0 RDoc
|
149
155
|
require_paths:
|
150
156
|
- lib/
|
151
157
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -160,7 +166,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
160
166
|
version: '0'
|
161
167
|
requirements: []
|
162
168
|
rubyforge_project: mattock
|
163
|
-
rubygems_version: 2.
|
169
|
+
rubygems_version: 2.4.8
|
164
170
|
signing_key:
|
165
171
|
specification_version: 3
|
166
172
|
summary: A powerful companion to Rake
|
data/lib/mattock/configurable.rb
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
module Mattock
|
2
|
-
#Handles setting options on objects it's mixed into
|
3
|
-
#
|
4
|
-
#Settings can have default values or be required (as opposed to defaulting to
|
5
|
-
#nil). Settings and their defaults are inherited (and can be overridden) by
|
6
|
-
#subclasses.
|
7
|
-
#
|
8
|
-
#Mattock also includes a yard-extension that will document settings of a
|
9
|
-
#Configurable
|
10
|
-
#
|
11
|
-
#@example (see ClassMethods)
|
12
|
-
module Configurable
|
13
|
-
class Exception < ::StandardError
|
14
|
-
end
|
15
|
-
|
16
|
-
class NoDefaultValue < Exception
|
17
|
-
def initialize(field_name, klass)
|
18
|
-
super("No default value for field #{field_name} on class #{klass.name}")
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
require 'mattock/configurable/field-metadata'
|
25
|
-
require 'mattock/configurable/proxy-value'
|
26
|
-
require 'mattock/configurable/field-processor'
|
27
|
-
require 'mattock/configurable/class-methods'
|
28
|
-
require 'mattock/configurable/instance-methods'
|
29
|
-
require 'mattock/configurable/directory-structure'
|
@@ -1,227 +0,0 @@
|
|
1
|
-
module Mattock
|
2
|
-
module Configurable
|
3
|
-
RequiredField = Object.new.freeze
|
4
|
-
|
5
|
-
#Describes class level DSL & machinery for working with configuration
|
6
|
-
#managment.
|
7
|
-
#
|
8
|
-
#@example
|
9
|
-
# class ConfExample
|
10
|
-
# include Configurable
|
11
|
-
#
|
12
|
-
# setting :foo
|
13
|
-
# settings :bar => 1, :baz => 3
|
14
|
-
# nil_fields :hoo, :ha, :harum
|
15
|
-
# required_fields :must
|
16
|
-
#
|
17
|
-
# def initialize
|
18
|
-
# setup_defaults
|
19
|
-
# end
|
20
|
-
# end
|
21
|
-
#
|
22
|
-
# ce = ConfExample.new
|
23
|
-
# ce.bar #=> 1
|
24
|
-
# ce.hoo #=> nil
|
25
|
-
# ce.hoo = "hallo"
|
26
|
-
# ce.check_required #=> raises error because :must and :foo aren't set
|
27
|
-
module ClassMethods
|
28
|
-
def inspect_instance(instance, indent="")
|
29
|
-
field_names.map do |name|
|
30
|
-
meta = field_metadata(name)
|
31
|
-
"#{indent}#{meta.inspect_on(instance, indent * 2)}"
|
32
|
-
end.join("\n")
|
33
|
-
end
|
34
|
-
|
35
|
-
def default_values
|
36
|
-
@default_values ||= []
|
37
|
-
end
|
38
|
-
|
39
|
-
def field_names
|
40
|
-
names = default_values.map{|field| field.name}
|
41
|
-
if Configurable > superclass
|
42
|
-
names | superclass.field_names
|
43
|
-
else
|
44
|
-
names
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def field_metadata(name)
|
49
|
-
field = default_values.find{|field| field.name == name}
|
50
|
-
if field.nil? and Configurable > superclass
|
51
|
-
superclass.field_metadata(name)
|
52
|
-
else
|
53
|
-
field
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
#@raises NoDefaultValue
|
58
|
-
def default_value_for(name)
|
59
|
-
field = field_metadata(name)
|
60
|
-
raise NoDefaultValue.new(name,self) unless field.is?(:defaulting)
|
61
|
-
return field.default_value
|
62
|
-
end
|
63
|
-
|
64
|
-
#Creates an anonymous Configurable - useful in complex setups for nested
|
65
|
-
#settings
|
66
|
-
#@example SSH options
|
67
|
-
# setting :ssh => nested(:username => "me", :password => nil)
|
68
|
-
def nested(hash=nil, &block)
|
69
|
-
nested = Class.new(Struct)
|
70
|
-
nested.settings(hash || {})
|
71
|
-
if block_given?
|
72
|
-
nested.instance_eval(&block)
|
73
|
-
end
|
74
|
-
return nested
|
75
|
-
end
|
76
|
-
|
77
|
-
#Quick list of setting fields with a default value of nil. Useful
|
78
|
-
#especially with {CascadingDefinition#resolve_configuration}
|
79
|
-
def nil_fields(*names)
|
80
|
-
names.each do |name|
|
81
|
-
setting(name, nil)
|
82
|
-
end
|
83
|
-
self
|
84
|
-
end
|
85
|
-
alias nil_field nil_fields
|
86
|
-
|
87
|
-
#List fields with no default for with a value must be set before
|
88
|
-
#definition.
|
89
|
-
def required_fields(*names)
|
90
|
-
names.each do |name|
|
91
|
-
setting(name)
|
92
|
-
end
|
93
|
-
self
|
94
|
-
end
|
95
|
-
alias required_field required_fields
|
96
|
-
|
97
|
-
#Defines a setting on this class - much like a attr_accessible call, but
|
98
|
-
#allows for defaults and required settings
|
99
|
-
def setting(name, default_value = RequiredField)
|
100
|
-
name = name.to_sym
|
101
|
-
metadata =
|
102
|
-
if default_value == RequiredField
|
103
|
-
FieldMetadata.new(name, nil).is(:required).isnt(:defaulting)
|
104
|
-
else
|
105
|
-
FieldMetadata.new(name, default_value)
|
106
|
-
end
|
107
|
-
|
108
|
-
attr_writer(name)
|
109
|
-
define_method(metadata.reader_method) do
|
110
|
-
metadata.value_on(self)
|
111
|
-
end
|
112
|
-
|
113
|
-
if existing = default_values.find{|field| field.name == name} and existing.default_value != default_value
|
114
|
-
source_line = caller.drop_while{|line| /#{__FILE__}/ =~ line}.first
|
115
|
-
warn "Changing default value of #{self.name}##{name} from #{existing.default_value.inspect} to #{default_value.inspect} (at: #{source_line})"
|
116
|
-
end
|
117
|
-
default_values << metadata
|
118
|
-
metadata
|
119
|
-
end
|
120
|
-
|
121
|
-
def runtime_required_fields(*names)
|
122
|
-
names.each do |name|
|
123
|
-
runtime_setting(name)
|
124
|
-
end
|
125
|
-
self
|
126
|
-
end
|
127
|
-
alias runtime_required_field runtime_required_fields
|
128
|
-
|
129
|
-
def runtime_setting(name, default_value = RequiredField)
|
130
|
-
setting(name, default_value).is(:runtime)
|
131
|
-
end
|
132
|
-
|
133
|
-
#@param [Hash] hash Pairs of name/value to be converted into
|
134
|
-
# setting/default
|
135
|
-
def settings(hash)
|
136
|
-
hash.each_pair do |name, value|
|
137
|
-
setting(name, value)
|
138
|
-
end
|
139
|
-
return self
|
140
|
-
end
|
141
|
-
alias runtime_settings settings
|
142
|
-
|
143
|
-
def set_defaults_on(instance)
|
144
|
-
if Configurable > superclass
|
145
|
-
superclass.set_defaults_on(instance)
|
146
|
-
end
|
147
|
-
default_values.each do |field|
|
148
|
-
next unless field.is? :defaulting
|
149
|
-
value = field.build_default_value
|
150
|
-
instance.__send__(field.writer_method, value)
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
def missing_required_fields_on(instance)
|
155
|
-
missing = []
|
156
|
-
if Configurable > superclass
|
157
|
-
missing = superclass.missing_required_fields_on(instance)
|
158
|
-
end
|
159
|
-
default_values.each do |field|
|
160
|
-
if field.missing_on?(instance)
|
161
|
-
missing << field.name
|
162
|
-
else
|
163
|
-
set_value = instance.__send__(field.reader_method)
|
164
|
-
if Configurable === set_value
|
165
|
-
missing += set_value.class.missing_required_fields_on(set_value).map do |sub_field|
|
166
|
-
[field.name, sub_field].join(".")
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|
170
|
-
end
|
171
|
-
return missing
|
172
|
-
end
|
173
|
-
|
174
|
-
def to_hash(obj)
|
175
|
-
hash = if Configurable > superclass
|
176
|
-
superclass.to_hash(obj)
|
177
|
-
else
|
178
|
-
{}
|
179
|
-
end
|
180
|
-
hash.merge( Hash[default_values.map{|field|
|
181
|
-
begin
|
182
|
-
value = obj.__send__(field.reader_method)
|
183
|
-
value =
|
184
|
-
case value
|
185
|
-
when Configurable
|
186
|
-
value.to_hash
|
187
|
-
else
|
188
|
-
value
|
189
|
-
end
|
190
|
-
[field.name, value]
|
191
|
-
rescue NoMethodError
|
192
|
-
end
|
193
|
-
}])
|
194
|
-
end
|
195
|
-
|
196
|
-
def from_hash(obj, hash) #XXX It'd be really nice if this could report unused fields
|
197
|
-
if Configurable > superclass
|
198
|
-
superclass.from_hash(obj, hash)
|
199
|
-
end
|
200
|
-
default_values.each do |field|
|
201
|
-
catch :next do
|
202
|
-
key = field.reader_method.to_s
|
203
|
-
value = hash.fetch(key.to_s) do
|
204
|
-
key = key.to_sym
|
205
|
-
hash.fetch(key) do
|
206
|
-
throw :next
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
existing_value = obj.__send__(field.reader_method)
|
211
|
-
if Configurable === existing_value and value.is_a? Hash
|
212
|
-
existing_value.from_hash(value)
|
213
|
-
else
|
214
|
-
obj.__send__(field.writer_method, value)
|
215
|
-
end
|
216
|
-
end
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
def included(mod)
|
221
|
-
mod.extend ClassMethods
|
222
|
-
end
|
223
|
-
end
|
224
|
-
|
225
|
-
extend ClassMethods
|
226
|
-
end
|
227
|
-
end
|
@@ -1,163 +0,0 @@
|
|
1
|
-
require 'rake'
|
2
|
-
|
3
|
-
module Mattock
|
4
|
-
module Configurable
|
5
|
-
class MissingRelativePaths < Exception; end
|
6
|
-
|
7
|
-
#XXX Consider making the actual dir/path settings r/o
|
8
|
-
#Very easy to say
|
9
|
-
# filename = "string"
|
10
|
-
#rather than
|
11
|
-
# filename.relative_path = "string"
|
12
|
-
#and it isn't clear which (abs/rel) you mean
|
13
|
-
#
|
14
|
-
module DirectoryStructure
|
15
|
-
class StructurePath
|
16
|
-
include Configurable
|
17
|
-
|
18
|
-
setting :absolute_path
|
19
|
-
setting :relative_path
|
20
|
-
|
21
|
-
alias abspath absolute_path
|
22
|
-
alias relpath relative_path
|
23
|
-
|
24
|
-
#No #path - ambiguous whether that would be abspath or pathname
|
25
|
-
|
26
|
-
def initialize(rel_path)
|
27
|
-
self.relative_path = rel_path unless rel_path == Configurable::RequiredField
|
28
|
-
end
|
29
|
-
|
30
|
-
def pathname
|
31
|
-
@pathname ||=
|
32
|
-
begin
|
33
|
-
fail_unless_set(:absolute_path)
|
34
|
-
require 'pathname'
|
35
|
-
Pathname.new(absolute_path)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
alias path_name pathname
|
39
|
-
|
40
|
-
def to_s
|
41
|
-
fail_unless_set(:absolute_path)
|
42
|
-
absolute_path
|
43
|
-
end
|
44
|
-
|
45
|
-
def inspect
|
46
|
-
"<path: #{
|
47
|
-
if field_unset?(:absolute_path)
|
48
|
-
if field_unset?(:relative_path)
|
49
|
-
"<<?>>"
|
50
|
-
else
|
51
|
-
"?/#{relative_path}"
|
52
|
-
end
|
53
|
-
else
|
54
|
-
absolute_path.inspect
|
55
|
-
end
|
56
|
-
}>"
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
module ClassMethods
|
61
|
-
RequiredField = Configurable::RequiredField
|
62
|
-
|
63
|
-
def root_paths
|
64
|
-
@root_paths ||= []
|
65
|
-
end
|
66
|
-
|
67
|
-
def path_heirarchy
|
68
|
-
@path_heirarchy ||= []
|
69
|
-
end
|
70
|
-
attr_writer :path_heirarchy
|
71
|
-
|
72
|
-
def path_fields
|
73
|
-
@path_fields ||= []
|
74
|
-
end
|
75
|
-
|
76
|
-
def dir(field_name, *args)
|
77
|
-
rel_path = RequiredField
|
78
|
-
if String === args.first
|
79
|
-
rel_path = args.shift
|
80
|
-
end
|
81
|
-
parent_field = path(field_name, rel_path)
|
82
|
-
|
83
|
-
self.path_heirarchy += args.map do |child_field|
|
84
|
-
[parent_field, child_field]
|
85
|
-
end
|
86
|
-
return parent_field
|
87
|
-
end
|
88
|
-
|
89
|
-
def path(field_name, rel_path=RequiredField)
|
90
|
-
field = setting(field_name, StructurePath.new(rel_path))
|
91
|
-
root_paths << field
|
92
|
-
path_fields << field
|
93
|
-
return field
|
94
|
-
end
|
95
|
-
|
96
|
-
def resolve_path_on(instance, parent, child_field, missing_relatives)
|
97
|
-
child = child_field.value_on(instance)
|
98
|
-
return unless child.field_unset?(:absolute_path)
|
99
|
-
if child.field_unset?(:relative_path)
|
100
|
-
missing_relatives << child_field
|
101
|
-
return
|
102
|
-
end
|
103
|
-
child.absolute_path = File::join(parent.absolute_path, child.relative_path)
|
104
|
-
end
|
105
|
-
|
106
|
-
def resolve_paths_on(instance)
|
107
|
-
superclass_exception = nil
|
108
|
-
if superclass < DirectoryStructure
|
109
|
-
begin
|
110
|
-
superclass.resolve_paths_on(instance)
|
111
|
-
rescue MissingRelativePaths => mrp
|
112
|
-
superclass_exception = mrp
|
113
|
-
end
|
114
|
-
end
|
115
|
-
missing_relatives = []
|
116
|
-
|
117
|
-
(root_paths - path_heirarchy.map{|_, child| child }).each do |field|
|
118
|
-
resolve_path_on(instance, instance, field, missing_relatives)
|
119
|
-
end
|
120
|
-
|
121
|
-
path_heirarchy.reverse.each do |parent_field, child_field|
|
122
|
-
next if missing_relatives.include?(parent_field)
|
123
|
-
parent = parent_field.value_on(instance)
|
124
|
-
resolve_path_on(instance, parent, child_field, missing_relatives)
|
125
|
-
end
|
126
|
-
|
127
|
-
case [missing_relatives.empty?, superclass_exception.nil?]
|
128
|
-
when [true, false]
|
129
|
-
raise superclass_exception
|
130
|
-
when [false, true]
|
131
|
-
raise MissingRelativePaths, "Required field#{missing_relatives.length == 1 ? "" : "s"} #{missing_relatives.map{|field| "#{field.name}.relative_path".inspect}.join(", ")} unset on #{self.inspect}"
|
132
|
-
when [false, false]
|
133
|
-
raise MissingRelativePaths, "Required field#{missing_relatives.length == 1 ? "" : "s"} #{missing_relatives.map{|field| "#{field.name}.relative_path".inspect}.join(", ")} unset on #{self.inspect}" + "\n" + superclass_exception.message
|
134
|
-
end
|
135
|
-
|
136
|
-
path_fields.each do |field|
|
137
|
-
value = field.value_on(instance)
|
138
|
-
next unless value.field_unset?(:relative_path)
|
139
|
-
value.relative_path = value.absolute_path
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
def self.included(sub)
|
145
|
-
sub.extend ClassMethods
|
146
|
-
dir_path =
|
147
|
-
if not (file_path = ::Rake.application.rakefile).nil?
|
148
|
-
File::dirname(File::expand_path(file_path))
|
149
|
-
elsif not (dir_path = ::Rake.application.original_dir).nil?
|
150
|
-
dir_path
|
151
|
-
else
|
152
|
-
file_path = caller[0].split(':')[0]
|
153
|
-
File::dirname(File::expand_path(file_path))
|
154
|
-
end
|
155
|
-
sub.setting :absolute_path, dir_path
|
156
|
-
end
|
157
|
-
|
158
|
-
def resolve_paths
|
159
|
-
self.class.resolve_paths_on(self)
|
160
|
-
end
|
161
|
-
end
|
162
|
-
end
|
163
|
-
end
|
@@ -1,157 +0,0 @@
|
|
1
|
-
module Mattock
|
2
|
-
module Configurable
|
3
|
-
class FieldMetadata
|
4
|
-
attr_accessor :name, :default_value
|
5
|
-
|
6
|
-
DEFAULT_PROPERTIES = {
|
7
|
-
:copiable => true,
|
8
|
-
:proxiable => true,
|
9
|
-
:required => false,
|
10
|
-
:runtime => false,
|
11
|
-
:defaulting => true,
|
12
|
-
}
|
13
|
-
def initialize(name, value)
|
14
|
-
@name = name
|
15
|
-
@default_value = value
|
16
|
-
@properties = DEFAULT_PROPERTIES.clone
|
17
|
-
end
|
18
|
-
|
19
|
-
def inspect
|
20
|
-
set_props = DEFAULT_PROPERTIES.keys.find_all do |prop|
|
21
|
-
@properties[prop]
|
22
|
-
end
|
23
|
-
"Field: #{name}: #{default_value.inspect} #{set_props.inspect}"
|
24
|
-
end
|
25
|
-
|
26
|
-
def inspect_on(instance, indent=nil)
|
27
|
-
set_props = DEFAULT_PROPERTIES.keys.find_all do |prop|
|
28
|
-
@properties[prop]
|
29
|
-
end
|
30
|
-
"Field: #{name}: #{value_on(instance).inspect} \n#{indent||""}(default: #{default_value.inspect} immediate: #{immediate_value_on(instance).inspect}) #{set_props.inspect}"
|
31
|
-
end
|
32
|
-
|
33
|
-
def validate_property_name(name)
|
34
|
-
unless DEFAULT_PROPERTIES.has_key?(name)
|
35
|
-
raise "Invalid field property #{name.inspect} - valid are: #{DEFAULT_PROPERTIES.keys.inspect}"
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def is?(property)
|
40
|
-
validate_property_name(property)
|
41
|
-
@properties[property]
|
42
|
-
end
|
43
|
-
|
44
|
-
def is_not?(property)
|
45
|
-
validate_property_name(property)
|
46
|
-
!@properties[property]
|
47
|
-
end
|
48
|
-
alias isnt? is_not?
|
49
|
-
|
50
|
-
def is(property)
|
51
|
-
validate_property_name(property)
|
52
|
-
@properties[property] = true
|
53
|
-
self
|
54
|
-
end
|
55
|
-
|
56
|
-
def is_not(property)
|
57
|
-
validate_property_name(property)
|
58
|
-
@properties[property] = false
|
59
|
-
self
|
60
|
-
end
|
61
|
-
alias isnt is_not
|
62
|
-
|
63
|
-
def ivar_name
|
64
|
-
"@#{name}"
|
65
|
-
end
|
66
|
-
|
67
|
-
def writer_method
|
68
|
-
"#{name}="
|
69
|
-
end
|
70
|
-
|
71
|
-
def reader_method
|
72
|
-
name
|
73
|
-
end
|
74
|
-
|
75
|
-
def copy_from(instance)
|
76
|
-
return if unset_on?(instance)
|
77
|
-
copy_value(immediate_value_on(instance))
|
78
|
-
end
|
79
|
-
|
80
|
-
def build_default_value
|
81
|
-
if Module === @default_value and Configurable > @default_value
|
82
|
-
value = @default_value.new
|
83
|
-
value.class.set_defaults_on(value)
|
84
|
-
value
|
85
|
-
else
|
86
|
-
copy_value(@default_value)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def copy_value(value)
|
91
|
-
case value
|
92
|
-
when Symbol, Numeric, NilClass, TrueClass, FalseClass
|
93
|
-
value
|
94
|
-
else
|
95
|
-
if value.class == BasicObject
|
96
|
-
value
|
97
|
-
elsif value.respond_to?(:dup)
|
98
|
-
value.dup
|
99
|
-
elsif value.respond_to?(:clone)
|
100
|
-
value.clone
|
101
|
-
else
|
102
|
-
value
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
def immediate_value_on(instance)
|
108
|
-
instance.instance_variable_get(ivar_name)
|
109
|
-
#instance.__send__(reader_method)
|
110
|
-
end
|
111
|
-
|
112
|
-
def value_on(instance)
|
113
|
-
value = immediate_value_on(instance)
|
114
|
-
if ProxyValue === value
|
115
|
-
value.field.value_on(value.source)
|
116
|
-
else
|
117
|
-
value
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
def set_on?(instance)
|
122
|
-
return true unless instance.__send__(reader_method).nil?
|
123
|
-
return false unless instance.instance_variable_defined?(ivar_name)
|
124
|
-
value = immediate_value_on(instance)
|
125
|
-
if ProxyValue === value
|
126
|
-
value.field.set_on?(value.source)
|
127
|
-
else
|
128
|
-
true
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
def unset_on?(instance)
|
133
|
-
!set_on?(instance)
|
134
|
-
end
|
135
|
-
|
136
|
-
def missing_on?(instance)
|
137
|
-
return false unless is?(:required)
|
138
|
-
if instance.respond_to?(:runtime?) and !instance.runtime?
|
139
|
-
return runtime_missing_on?(instance)
|
140
|
-
else
|
141
|
-
return !set_on?(instance)
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
def runtime_missing_on?(instance)
|
146
|
-
return false if is?(:runtime)
|
147
|
-
return true unless instance.instance_variable_defined?(ivar_name)
|
148
|
-
value = immediate_value_on(instance)
|
149
|
-
if ProxyValue === value
|
150
|
-
value.field.runtime_missing_on?(value.source)
|
151
|
-
else
|
152
|
-
false
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end
|
@@ -1,54 +0,0 @@
|
|
1
|
-
module Mattock
|
2
|
-
module Configurable
|
3
|
-
class FieldProcessor
|
4
|
-
def initialize(source)
|
5
|
-
@source = source
|
6
|
-
@field_names = filter(source.class.field_names)
|
7
|
-
end
|
8
|
-
attr_accessor :field_names
|
9
|
-
attr_reader :source
|
10
|
-
|
11
|
-
def filter(field_names)
|
12
|
-
field_names.find_all do |name|
|
13
|
-
source.class.field_metadata(name).is?(filter_attribute)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def can_process(field, target)
|
18
|
-
target.respond_to?(field.writer_method)
|
19
|
-
end
|
20
|
-
|
21
|
-
def to(target)
|
22
|
-
field_names.each do |name|
|
23
|
-
field = source.class.field_metadata(name)
|
24
|
-
next unless can_process(field, target)
|
25
|
-
target.__send__(field.writer_method, value(field))
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
class SettingsCopier < FieldProcessor
|
31
|
-
def filter_attribute
|
32
|
-
:copiable
|
33
|
-
end
|
34
|
-
|
35
|
-
def can_process(field, target)
|
36
|
-
super and not( field.unset_on?(source) and field.unset_on?(target) )
|
37
|
-
end
|
38
|
-
|
39
|
-
def value(field)
|
40
|
-
return field.copy_from(source)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
class SettingsProxier < FieldProcessor
|
45
|
-
def filter_attribute
|
46
|
-
:proxiable
|
47
|
-
end
|
48
|
-
|
49
|
-
def value(field)
|
50
|
-
ProxyValue.new(source, field)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
@@ -1,87 +0,0 @@
|
|
1
|
-
require 'mattock/configurable/directory-structure'
|
2
|
-
|
3
|
-
module Mattock
|
4
|
-
module Configurable
|
5
|
-
def initialize_copy(original)
|
6
|
-
original.copy_settings_to(self)
|
7
|
-
end
|
8
|
-
|
9
|
-
def copy_settings
|
10
|
-
SettingsCopier.new(self)
|
11
|
-
end
|
12
|
-
|
13
|
-
def copy_settings_to(other)
|
14
|
-
copy_settings.to(other)
|
15
|
-
self
|
16
|
-
end
|
17
|
-
|
18
|
-
def proxy_settings
|
19
|
-
SettingsProxier.new(self)
|
20
|
-
end
|
21
|
-
|
22
|
-
def proxy_settings_to(other)
|
23
|
-
proxy_settings.to(other)
|
24
|
-
end
|
25
|
-
|
26
|
-
def to_hash
|
27
|
-
self.class.to_hash(self)
|
28
|
-
end
|
29
|
-
|
30
|
-
def from_hash(hash)
|
31
|
-
self.class.from_hash(self, hash)
|
32
|
-
end
|
33
|
-
|
34
|
-
def unset_defaults_guard
|
35
|
-
raise "Tried to check required settings before running setup_defaults"
|
36
|
-
end
|
37
|
-
|
38
|
-
#Call during initialize to set default values on settings - if you're using
|
39
|
-
#Configurable outside of Mattock, be sure this gets called.
|
40
|
-
def setup_defaults
|
41
|
-
def self.unset_defaults_guard
|
42
|
-
end
|
43
|
-
|
44
|
-
self.class.set_defaults_on(self)
|
45
|
-
self
|
46
|
-
end
|
47
|
-
|
48
|
-
#Checks that all required fields have be set, otherwise raises an error
|
49
|
-
#@raise RuntimeError if any required fields are unset
|
50
|
-
def check_required
|
51
|
-
unset_defaults_guard
|
52
|
-
missing = self.class.missing_required_fields_on(self)
|
53
|
-
unless missing.empty?
|
54
|
-
raise "Required field#{missing.length > 1 ? "s" : ""} #{missing.map{|field| field.to_s.inspect}.join(", ")} unset on #{self.inspect}"
|
55
|
-
end
|
56
|
-
self
|
57
|
-
end
|
58
|
-
|
59
|
-
def proxy_value
|
60
|
-
ProxyDecorator.new(self)
|
61
|
-
end
|
62
|
-
|
63
|
-
#XXX deprecate
|
64
|
-
def unset?(value)
|
65
|
-
warn "#unset? is deprecated - use field_unset? instead"
|
66
|
-
value.nil?
|
67
|
-
end
|
68
|
-
|
69
|
-
def field_unset?(name)
|
70
|
-
self.class.field_metadata(name).unset_on?(self)
|
71
|
-
end
|
72
|
-
|
73
|
-
#Requires that a named field be set
|
74
|
-
def fail_unless_set(name)
|
75
|
-
if field_unset?(name)
|
76
|
-
raise "Assertion failed: Field #{name} unset"
|
77
|
-
end
|
78
|
-
true
|
79
|
-
end
|
80
|
-
alias fail_if_unset fail_unless_set
|
81
|
-
|
82
|
-
class Struct
|
83
|
-
include Configurable
|
84
|
-
include Configurable::DirectoryStructure
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
module Mattock
|
2
|
-
module Configurable
|
3
|
-
class ProxyValue
|
4
|
-
def initialize(source, field)
|
5
|
-
@source, @field = source, field
|
6
|
-
end
|
7
|
-
attr_reader :source, :field
|
8
|
-
|
9
|
-
def inspect
|
10
|
-
"#{self.class.name.split(':').last}: #{source.class.name}.#{field.inspect}"
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
class ProxyDecorator
|
15
|
-
def initialize(configurable)
|
16
|
-
@configurable = configurable
|
17
|
-
end
|
18
|
-
|
19
|
-
def method_missing(name, *args, &block)
|
20
|
-
unless block.nil? and args.empty?
|
21
|
-
raise NoMethodError, "method `#{name}' not defined with arguments or block when proxied"
|
22
|
-
end
|
23
|
-
unless @configurable.respond_to?(name)
|
24
|
-
raise NoMethodError, "cannot proxy `#{name}' - undefined on #{@configurable}"
|
25
|
-
end
|
26
|
-
return ProxyValue.new(@configurable, @configurable.class.field_metadata(name))
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
data/spec/configurable.rb
DELETED
@@ -1,270 +0,0 @@
|
|
1
|
-
require 'mattock'
|
2
|
-
|
3
|
-
describe Mattock::Configurable do
|
4
|
-
class TestSuperStruct
|
5
|
-
include Mattock::Configurable
|
6
|
-
|
7
|
-
setting(:three, 3)
|
8
|
-
required_field(:four)
|
9
|
-
required_field(:override)
|
10
|
-
end
|
11
|
-
|
12
|
-
class TestStruct < TestSuperStruct
|
13
|
-
settings(:one => 1, :two => nested(:a => "a"){ required_field(:b)} )
|
14
|
-
nil_field(:five)
|
15
|
-
|
16
|
-
def override
|
17
|
-
17
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
subject do
|
22
|
-
TestStruct.new.setup_defaults
|
23
|
-
end
|
24
|
-
|
25
|
-
it "should set defaults" do
|
26
|
-
subject.one.should == 1
|
27
|
-
subject.two.a.should == "a"
|
28
|
-
subject.three.should == 3
|
29
|
-
subject.five.should be_nil
|
30
|
-
end
|
31
|
-
|
32
|
-
it "#to_hash" do
|
33
|
-
hash = subject.to_hash
|
34
|
-
hash[:one].should == 1
|
35
|
-
hash[:two][:a].should == "a"
|
36
|
-
end
|
37
|
-
|
38
|
-
it "#from_hash" do
|
39
|
-
subject.from_hash({:one => 111, "two" => { :a => "aaa" }})
|
40
|
-
|
41
|
-
subject.one.should == 111
|
42
|
-
subject.two.a.should == "aaa"
|
43
|
-
end
|
44
|
-
|
45
|
-
it "should complain about unset required fields" do
|
46
|
-
expect do
|
47
|
-
subject.check_required
|
48
|
-
end.to raise_error
|
49
|
-
end
|
50
|
-
|
51
|
-
it "should complain about unset nested required fields" do
|
52
|
-
subject.four = 4
|
53
|
-
expect do
|
54
|
-
subject.check_required
|
55
|
-
end.to raise_error
|
56
|
-
end
|
57
|
-
|
58
|
-
it "should not complain when required fields are set" do
|
59
|
-
subject.four = 4
|
60
|
-
subject.two.b = "b"
|
61
|
-
expect do
|
62
|
-
subject.check_required
|
63
|
-
end.to_not raise_error
|
64
|
-
subject.override.should == 17
|
65
|
-
end
|
66
|
-
|
67
|
-
it "should inspect cleanly" do
|
68
|
-
subject.inspect.should be_a(String)
|
69
|
-
end
|
70
|
-
|
71
|
-
describe "with DirectoryStructure" do
|
72
|
-
class DirectoryThing
|
73
|
-
include Mattock::Configurable
|
74
|
-
include DirectoryStructure
|
75
|
-
|
76
|
-
dir(:ephemeral_mountpoint,
|
77
|
-
dir(:bundle_workdir, "bundle_workdir",
|
78
|
-
path(:bundle_manifest),
|
79
|
-
path(:credentials_archive, "aws-creds.tar.gz"),
|
80
|
-
dir(:credentials_dir, "aws-creds",
|
81
|
-
path(:private_key_file, "pk.pem"),
|
82
|
-
path(:certificate_file, "cert.pem")
|
83
|
-
)
|
84
|
-
)
|
85
|
-
)
|
86
|
-
|
87
|
-
dir(:next_to_me, "rainbow", dir(:in_there, "a_place", path(:nearby, "a.file")))
|
88
|
-
|
89
|
-
path(:loose_path, "here")
|
90
|
-
end
|
91
|
-
|
92
|
-
describe "distinctness" do
|
93
|
-
let :one do
|
94
|
-
DirectoryThing.new.tap do |thing|
|
95
|
-
thing.setup_defaults
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
let :other do
|
100
|
-
DirectoryThing.new.tap do |thing|
|
101
|
-
thing.setup_defaults
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
it "should have same values" do
|
106
|
-
one.bundle_workdir.relative_path.should == other.bundle_workdir.relative_path
|
107
|
-
end
|
108
|
-
|
109
|
-
it "should have different actual objects" do
|
110
|
-
one.bundle_workdir.relative_path.should_not equal other.bundle_workdir.relative_path
|
111
|
-
one.bundle_workdir.should_not equal other.bundle_workdir
|
112
|
-
end
|
113
|
-
|
114
|
-
end
|
115
|
-
|
116
|
-
def subject
|
117
|
-
DirectoryThing.new.tap do |thing|
|
118
|
-
thing.setup_defaults
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
it "should complain about missing fields" do
|
123
|
-
expect do
|
124
|
-
subject.check_required
|
125
|
-
end.to raise_error(/Required field/)
|
126
|
-
end
|
127
|
-
|
128
|
-
it "should inspect cleanly" do
|
129
|
-
subject.inspect.should be_a(String)
|
130
|
-
end
|
131
|
-
|
132
|
-
describe "with root path configured, but missing a relative path" do
|
133
|
-
def subject
|
134
|
-
DirectoryThing.new.tap do |thing|
|
135
|
-
thing.setup_defaults
|
136
|
-
thing.ephemeral_mountpoint.absolute_path = "/tmp"
|
137
|
-
thing.resolve_paths
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
it "should complain about missing fields" do
|
142
|
-
expect do
|
143
|
-
subject.check_required
|
144
|
-
end.to raise_error(/Required field/)
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
describe "with required paths configured" do
|
149
|
-
def subject
|
150
|
-
DirectoryThing.new.tap do |thing|
|
151
|
-
thing.setup_defaults
|
152
|
-
thing.ephemeral_mountpoint.absolute_path = "/tmp"
|
153
|
-
thing.bundle_manifest.relative_path = "image.manifest.xml"
|
154
|
-
thing.resolve_paths
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
it "should not complain about required fields" do
|
159
|
-
expect do
|
160
|
-
subject.check_required
|
161
|
-
end.not_to raise_error
|
162
|
-
end
|
163
|
-
|
164
|
-
its("nearby.absolute_path"){ should =~ %r"rainbow/a_place/a.file$"}
|
165
|
-
its("nearby.absolute_path"){ should =~ %r"^#{subject.absolute_path}"}
|
166
|
-
|
167
|
-
its("certificate_file.absolute_path"){ should == "/tmp/bundle_workdir/aws-creds/cert.pem" }
|
168
|
-
its("bundle_manifest.absolute_path"){ should == "/tmp/bundle_workdir/image.manifest.xml" }
|
169
|
-
its("credentials_dir.absolute_path"){ should == "/tmp/bundle_workdir/aws-creds" }
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
describe "multiple instances" do
|
174
|
-
class MultiSource
|
175
|
-
include Mattock::Configurable
|
176
|
-
|
177
|
-
setting :one, 1
|
178
|
-
setting :nest, nested{
|
179
|
-
setting :two, 2
|
180
|
-
}
|
181
|
-
end
|
182
|
-
|
183
|
-
let :first do
|
184
|
-
MultiSource.new.setup_defaults
|
185
|
-
end
|
186
|
-
|
187
|
-
let :second do
|
188
|
-
MultiSource.new.setup_defaults
|
189
|
-
end
|
190
|
-
|
191
|
-
before :each do
|
192
|
-
first.one = "one"
|
193
|
-
first.nest.two = "two"
|
194
|
-
second
|
195
|
-
end
|
196
|
-
|
197
|
-
it "should not have any validation errors" do
|
198
|
-
expect do
|
199
|
-
first.check_required
|
200
|
-
second.check_required
|
201
|
-
end.not_to raise_error
|
202
|
-
end
|
203
|
-
|
204
|
-
it "should accurately reflect settings" do
|
205
|
-
first.one.should == "one"
|
206
|
-
second.one.should == 1
|
207
|
-
|
208
|
-
first.nest.two.should == "two"
|
209
|
-
second.nest.two.should == 2
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
|
-
describe "copying settings" do
|
214
|
-
class LeftStruct
|
215
|
-
include Mattock::Configurable
|
216
|
-
|
217
|
-
setting(:normal, "1")
|
218
|
-
setting(:nested, nested{
|
219
|
-
setting :value, "2"
|
220
|
-
})
|
221
|
-
setting(:no_copy, 2).isnt(:copiable)
|
222
|
-
setting(:no_proxy, 3).isnt(:proxiable)
|
223
|
-
setting(:no_nothing, 4).isnt(:copiable).isnt(:proxiable)
|
224
|
-
setting(:not_on_target, 5)
|
225
|
-
end
|
226
|
-
|
227
|
-
class RightStruct
|
228
|
-
include Mattock::Configurable
|
229
|
-
|
230
|
-
required_fields(:normal, :nested, :no_copy, :no_proxy, :no_nothing)
|
231
|
-
end
|
232
|
-
|
233
|
-
let :left do
|
234
|
-
LeftStruct.new.setup_defaults
|
235
|
-
end
|
236
|
-
|
237
|
-
let :right do
|
238
|
-
RightStruct.new.setup_defaults
|
239
|
-
end
|
240
|
-
|
241
|
-
it "should make copies not references" do
|
242
|
-
left.copy_settings_to(right)
|
243
|
-
right.normal.should == left.normal
|
244
|
-
right.normal.should_not equal(left.normal)
|
245
|
-
right.nested.value.should == left.nested.value
|
246
|
-
right.nested.should_not equal(left.nested)
|
247
|
-
right.nested.value.should_not equal left.nested.value
|
248
|
-
end
|
249
|
-
|
250
|
-
it "should not copy no_copy" do
|
251
|
-
left.copy_settings_to(right)
|
252
|
-
right.field_unset?(:normal).should be_false
|
253
|
-
right.normal.should == "1"
|
254
|
-
right.field_unset?(:no_copy).should be_true
|
255
|
-
right.field_unset?(:no_proxy).should be_false
|
256
|
-
right.no_proxy.should == 3
|
257
|
-
right.field_unset?(:no_nothing).should be_true
|
258
|
-
end
|
259
|
-
|
260
|
-
it "should not proxy no_proxy" do
|
261
|
-
left.proxy_settings.to(right)
|
262
|
-
right.field_unset?(:normal).should be_false
|
263
|
-
right.normal.should == "1"
|
264
|
-
right.field_unset?(:no_copy).should be_false
|
265
|
-
right.no_copy.should == 2
|
266
|
-
right.field_unset?(:no_proxy).should be_true
|
267
|
-
right.field_unset?(:no_nothing).should be_true
|
268
|
-
end
|
269
|
-
end
|
270
|
-
end
|