nugrant 2.0.0.pre2 → 2.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 969a898ed0ac4d45b6adc22f43304d80a61d3eda
4
- data.tar.gz: a2f9140bab38bd74f9297cda110572d49c0f8425
3
+ metadata.gz: c0de10dfbe571d6be4e0c7a7c3fa3c7d4893fc88
4
+ data.tar.gz: 9fbec16a209341335a171f6fe57128b71bfa6e60
5
5
  SHA512:
6
- metadata.gz: ba35c594059cb9c04fef4495e55ca55fddbdafe95041335cd6ddec5e4234d6c65150f6418d407fc3d9dad28cff383a7402c369d0c429f3541eed7c00c7ed7dfe
7
- data.tar.gz: b5684cd172236eb57add8c9492fc8818b23707f813adbc2c9dc21ce951f5b8c4f949646e208a2acdb510f1ef53ea68ddb4491872f4af96fd530cacf2c38b03e1
6
+ metadata.gz: a7d7b102855c2af842e76eaa609b96b4a6b5316a4f8a05a956e5515b514024e356ff5b4afd23dc9a2fc25126998d90146626e018e29851ed1952721351259b41
7
+ data.tar.gz: 5c16317e800d0c725ae2f2544935de78da3cf994b1214032f4a0ddbf1ffc3b86ec84437a7e188f4864a230dd172b35809ac9d1afa2b0c666b52bc767704cedce
@@ -1,5 +1,10 @@
1
1
  # 2.0.0 (In progress)
2
2
 
3
+ * Fixed bad implementation of config class `::Vagrant.plugin("2", :config)`
4
+ where `merge` was not implemented and was causing errors. Now, all objects
5
+ (i.e. `Config`, `Bag` and `Parameters` implements `merge` and `merge!`
6
+ correctly).
7
+
3
8
  * Added possibility to change array merge strategy. This can
4
9
  be used in Vagrant by doing `config.user.array_merge_strategy = <strategy>`
5
10
  where valid strategies are:
data/Gemfile CHANGED
@@ -1,13 +1,11 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  group :development do
4
- gem "rake", "~> 10.1"
5
- gem "minitest", "~> 5.2"
4
+ gem "rake", "~> 10.3"
5
+ gem "minitest", "~> 5.3"
6
6
  gem "minitest-reporters", "~> 1.0"
7
7
 
8
- gem "win32console", :platforms => ['mswin', 'mingw', :'x64_mingw']
9
-
10
- gem "vagrant", :git => "https://github.com/mitchellh/vagrant.git", :tag => "v1.5.1"
8
+ gem "vagrant", :git => "https://github.com/mitchellh/vagrant.git", :tag => "v1.6.2"
11
9
  end
12
10
 
13
11
  group :plugins do
data/README.md CHANGED
@@ -20,7 +20,7 @@ Supported platforms:
20
20
  * Vagrant 1.x
21
21
  * Ruby 1.9.3+
22
22
 
23
- ## Overview
23
+ ## Quick Start
24
24
 
25
25
  Using Nugrant as a plug-in provides an easy and hierarchical system to manage
26
26
  machine and user specific parameters.
@@ -65,13 +65,26 @@ The order is project `.vagrantuser` overrides `$HOME/.vagrantuser` overrides
65
65
  `$SYSTEM/.vagrantuser` where `$HOME` is the user's home directory and `$SYSTEM`
66
66
  is the platform dependent folder where system global parameters are set.
67
67
 
68
- We use it in our team to specify the various parameters required for
69
- Vagrant `chef-solo` provisioner by putting the a `.vagrantuser` in our
70
- home directory under a key `chef`. It gets merged with the project's
71
- `.vagrantuser` file (if it exists), so it they can be overridden there.
68
+ Use the command `vagrant user parameters` to see the final merged hierarchy
69
+ seen by Nugrant. This command also prints [restricted keys](#restricted-keys) defined
70
+ in your hierarchy.
72
71
 
73
- Please refer to section [Usage](#usage) for all details and explanations
74
- needed to fully use and understand Nugrant.
72
+ You can access parameters in your `Vagrantfile` either by method access
73
+ (i.e. `config.user.<key>`) or by array access (i.e. `config.user[<key>]`).
74
+ This support is working for any deepness, only `config.user` is different
75
+ because provided directly by `Vagrant` and not by this plugin.
76
+
77
+ However, a drawback with method access, not present with array access, is its
78
+ set of [restricted keys](#restricted-keys) for which usage is prohibited. These
79
+ are in facts calls to method defined by the [Bag](lib/nugrant/bag.rb) class
80
+ ([Bag](lib/nugrant/bag.rb) extends [Hash](http://ruby-doc.org/core-2.0/Hash.html)).
81
+ It's plain Ruby, use it at your advantage like iterating through a collection
82
+ using the `.each` method.
83
+
84
+ This is where the quick start end. Continue to section [Installation](#installation)
85
+ if you need so help on how to install Nugrant. Or jump to [Usage](#usage) section
86
+ which describe in greater details all necessary information needed to deeply
87
+ understand Nugrant and use it at its full potential.
75
88
 
76
89
  ## Installation
77
90
 
@@ -274,9 +287,14 @@ is not provided by this plug-in but by Vagrant itself.
274
287
 
275
288
  Each non-final parameter (i.e a parameter that contains other parameters and
276
289
  not a scalar value) is in fact a [Bag](/lib/nugrant/bag.rb)
277
- object. You can call any defined methods on it. Since this object is also
278
- [Enumerable](http://ruby-doc.org/core-2.0/Enumerable.html), you can do neat things
279
- like iterating over your values or filtering them.
290
+ object. You can call any defined methods on it. This object extends
291
+ [Hash](http://ruby-doc.org/core-2.0/Hash.html) (itself including
292
+ module [Enumerable](http://ruby-doc.org/core-2.0/Enumerable.html)). Hence,
293
+ you can do neat things like iterating over your values or filtering them:
294
+
295
+ config.user.application.users.each do |key, data|
296
+ puts "Key #{key}: #{data}"
297
+ end
280
298
 
281
299
  ##### Restricted keys
282
300
 
@@ -333,8 +351,11 @@ As stated previously, when two arrays are merged together,
333
351
  the default strategy is to replace current array with new one.
334
352
 
335
353
  However, in some certain circumstances, you may need another
336
- behavior. That is why we also provide two other strategies
337
- that can be used.
354
+ behavior. Here the list of strategies that can be used.
355
+
356
+ * `:replace` (*default*)
357
+ With this strategy, the new array completely replace the
358
+ current one.
338
359
 
339
360
  * `:concat`
340
361
  With this strategy, new array is appended to the end
@@ -355,6 +376,10 @@ to change the array merge strategy:
355
376
  config.ssh.port config.user.vm.ssh_port
356
377
  end
357
378
 
379
+ Note that you should change the array merge strategy before
380
+ you access any keys because it's just once set that values
381
+ are computed using the new strategy.
382
+
358
383
  If you specify an unsupported strategy, nothing will happen.
359
384
 
360
385
  #### Commands
@@ -1,3 +1,5 @@
1
+ require 'nugrant/config'
2
+
1
3
  module Nugrant
2
4
  class Bag < Hash
3
5
 
@@ -27,14 +29,30 @@ module Nugrant
27
29
  @__config = Config::convert(config)
28
30
 
29
31
  (elements || {}).each do |key, value|
30
- self[key] = value.kind_of?(Hash) ? Bag.new(value, config) : value
32
+ self[key] = value
31
33
  end
32
34
  end
33
35
 
36
+ def config=(config)
37
+ @__config = Config::convert(config)
38
+ end
39
+
34
40
  def method_missing(method, *args, &block)
35
41
  self[method]
36
42
  end
37
43
 
44
+ ##
45
+ ### Enumerable Overridden Methods (for string & symbol indifferent access)
46
+ ##
47
+
48
+ def count(item)
49
+ super(__try_convert_item(item))
50
+ end
51
+
52
+ def find_index(item = nil, &block)
53
+ block_given? ? super(&block) : super(__try_convert_item(item))
54
+ end
55
+
38
56
  ##
39
57
  ### Hash Overridden Methods (for string & symbol indifferent access)
40
58
  ##
@@ -47,34 +65,74 @@ module Nugrant
47
65
  end
48
66
 
49
67
  def []=(input, value)
50
- super(__convert_key(input), value)
68
+ super(__convert_key(input), __convert_value(value))
69
+ end
70
+
71
+ def assoc(key)
72
+ super(__convert_key(key))
73
+ end
74
+
75
+ def delete(key)
76
+ super(__convert_key(key))
77
+ end
78
+
79
+ def fetch(key, default = nil)
80
+ super(__convert_key(key), default)
81
+ end
82
+
83
+ def has_key?(key)
84
+ super(__convert_key(key))
85
+ end
86
+
87
+ def include?(item)
88
+ super(__try_convert_item(item))
51
89
  end
52
90
 
53
91
  def key?(key)
54
92
  super(__convert_key(key))
55
93
  end
56
94
 
57
- ##
58
- # This method deeply merge two instance together
59
- #
60
- #
61
- def merge!(input)
62
- input.each do |key, value|
95
+ def member?(item)
96
+ super(__try_convert_item(item))
97
+ end
98
+
99
+ def dup()
100
+ self.class.new(self, @__config.dup())
101
+ end
102
+
103
+ def merge(other, options = {})
104
+ result = dup()
105
+ result.merge!(other)
106
+ end
107
+
108
+ def merge!(other, options = {})
109
+ other.each do |key, value|
63
110
  current = __get(key)
64
111
  case
65
112
  when current == nil
66
113
  self[key] = value
67
114
 
68
115
  when current.kind_of?(Hash) && value.kind_of?(Hash)
69
- current.merge!(value)
116
+ current.merge!(value, options)
70
117
 
71
118
  when current.kind_of?(Array) && value.kind_of?(Array)
72
- self[key] = send("__#{@__config.array_merge_strategy}_array_merge", current, value)
119
+ strategy = options[:array_merge_strategy]
120
+ if not Nugrant::Config.supported_array_merge_strategy(strategy)
121
+ strategy = @__config.array_merge_strategy
122
+ end
123
+
124
+ self[key] = send("__#{strategy}_array_merge", current, value)
73
125
 
74
126
  when value != nil
75
127
  self[key] = value
76
128
  end
77
129
  end
130
+
131
+ self
132
+ end
133
+
134
+ def store(key, value)
135
+ self[key] = value
78
136
  end
79
137
 
80
138
  def to_hash(options = {})
@@ -90,9 +148,14 @@ module Nugrant
90
148
  end]
91
149
  end
92
150
 
93
- ##
94
- ### Aliases
95
- ##
151
+ def walk(path = [], &block)
152
+ each do |key, value|
153
+ nested_bag = value.kind_of?(Nugrant::Bag)
154
+
155
+ value.walk(path + [key], &block) if nested_bag
156
+ yield path + [key], key, value if not nested_bag
157
+ end
158
+ end
96
159
 
97
160
  alias_method :to_ary, :to_a
98
161
 
@@ -108,13 +171,33 @@ module Nugrant
108
171
  raise ArgumentError, "Key cannot be converted to symbol, current value [#{key}] (#{key.class.name})"
109
172
  end
110
173
 
174
+ ##
175
+ # This function change value convertible to Bag into actual Bag.
176
+ # This trick enable deeply using all Bag functionalities and also
177
+ # ensures at the same time a deeply preventive copy since a new
178
+ # instance is created for this nested structure.
179
+ #
180
+ # @param value The value to convert to bag if necessary
181
+ # @return The converted value
182
+ #
183
+ def __convert_value(value)
184
+ value.kind_of?(Hash) ? Bag.new(value, @__config) : value
185
+ end
186
+
111
187
  def __get(key)
112
188
  # Calls Hash method [__convert_key(key)], used internally to retrieve value without raising Undefined parameter
113
189
  self.class.superclass.instance_method(:[]).bind(self).call(__convert_key(key))
114
190
  end
115
191
 
192
+ ##
193
+ # The concat order is the reversed compared to others
194
+ # because we assume that new values have precedence
195
+ # over current ones. Hence, the are prepended to
196
+ # current values. This is also logical for parameters
197
+ # because of the order in which bags are merged.
198
+ #
116
199
  def __concat_array_merge(current_array, new_array)
117
- current_array + new_array
200
+ new_array + current_array
118
201
  end
119
202
 
120
203
  def __extend_array_merge(current_array, new_array)
@@ -124,5 +207,13 @@ module Nugrant
124
207
  def __replace_array_merge(current_array, new_array)
125
208
  new_array
126
209
  end
210
+
211
+ def __try_convert_item(args)
212
+ return [__convert_key(args[0]), args[1]] if args.kind_of?(Array)
213
+
214
+ __convert_key(args)
215
+ rescue
216
+ args
217
+ end
127
218
  end
128
219
  end
@@ -125,6 +125,40 @@ module Nugrant
125
125
  validate()
126
126
  end
127
127
 
128
+ def ==(other)
129
+ self.class.equal?(other.class) &&
130
+ instance_variables.all? do |variable|
131
+ instance_variable_get(variable) == other.instance_variable_get(variable)
132
+ end
133
+ end
134
+
135
+ def [](key)
136
+ instance_variable_get("@#{key}")
137
+ rescue
138
+ nil
139
+ end
140
+
141
+ def merge(other)
142
+ result = dup()
143
+ result.merge!(other)
144
+ end
145
+
146
+ def merge!(other)
147
+ other.instance_variables.each do |variable|
148
+ instance_variable_set(variable, other.instance_variable_get(variable)) if instance_variables.include?(variable)
149
+ end
150
+
151
+ self
152
+ end
153
+
154
+ def to_h()
155
+ Hash[instance_variables.map do |variable|
156
+ [variable[1..-1].to_sym, instance_variable_get(variable)]
157
+ end]
158
+ end
159
+
160
+ alias_method :to_hash, :to_h
161
+
128
162
  def validate()
129
163
  raise ArgumentError,
130
164
  "Invalid value for :params_format. \
@@ -117,7 +117,7 @@ module Nugrant
117
117
  # @return (side-effect) Yields each key and value to a block
118
118
  #
119
119
  # Options:
120
- # * :namer => The namer used to transform bag segments into variable name, default to Namer::default().
120
+ # * :namer => The namer used to transform bag parents into variable name, default to Namer::default().
121
121
  # * :override => If true, variable a exported even when the override an existing env key, default to true.
122
122
  #
123
123
  def self.export(bag, options = {})
@@ -125,8 +125,8 @@ module Nugrant
125
125
  override = options.fetch(:override, true)
126
126
 
127
127
  variables = {}
128
- walk_bag(bag) do |segments, key, value|
129
- key = namer.call(segments)
128
+ bag.walk do |path, key, value|
129
+ key = namer.call(path)
130
130
 
131
131
  variables[key] = value if override or not ENV[key]
132
132
  end
@@ -189,19 +189,6 @@ module Nugrant
189
189
  # TODO: Handle platform differently
190
190
  "unset #{key}"
191
191
  end
192
-
193
- # FIXME: Move this directly into bag class
194
- def self.walk_bag(bag, parents = [], &block)
195
- commands = []
196
-
197
- bag.each do |key, value|
198
- segments = parents + [key]
199
- nested_bag = value.kind_of?(Nugrant::Bag)
200
-
201
- walk_bag(value, segments, &block) if nested_bag
202
- yield segments, key, value if not nested_bag
203
- end
204
- end
205
192
  end
206
193
  end
207
194
  end
@@ -1,3 +1,7 @@
1
+ require 'nugrant/bag'
2
+ require 'nugrant/config'
3
+ require 'nugrant/helper/bag'
4
+
1
5
  module Nugrant
2
6
  module Mixin
3
7
  ##
@@ -5,17 +9,32 @@ module Nugrant
5
9
  # logic between default Parameters class and Vagrant
6
10
  # implementation.
7
11
  #
8
- # This method delegates method missing to the overall
9
- # bag instance. This means that even if the class
12
+ # This module delegates method missing to the final
13
+ # bag hierarchy (@__all). This means that even if the class
10
14
  # including this module doesn't inherit Bag directly,
11
15
  # it act exactly like one.
12
16
  #
13
- # To initialize the mixin module correctly, you must call
14
- # the compute_bags! method at least once to initialize
15
- # all variables. You should make this call in including
16
- # class' constructor directly.
17
+ # When including this module, you must respect an important
18
+ # constraint.
19
+ #
20
+ # The including class must call `setup!` before starting using
21
+ # parameters retrieval. This is usually performed in
22
+ # the `initialize` method directly but could be in a different place
23
+ # depending on the including class lifecycle. The call to `setup!` is
24
+ # important to initialize all required instance variables.
25
+ #
26
+ # Here an example where `setup!` is called in constructor. Your constructor
27
+ # does not need to have these arguments, they are there as an example.
28
+ #
29
+ # ```
30
+ # def initialize(defaults = {}, config = {}, options = {})
31
+ # setup!(defaults, config, options)
32
+ # end
33
+ # ```
17
34
  #
18
35
  module Parameters
36
+ attr_reader :__config, :__current, :__user, :__system, :__defaults, :__all
37
+
19
38
  def method_missing(method, *args, &block)
20
39
  case
21
40
  when @__all.class.method_defined?(method)
@@ -25,14 +44,14 @@ module Nugrant
25
44
  end
26
45
  end
27
46
 
28
- def defaults()
29
- @__defaults
30
- end
31
-
32
47
  def array_merge_strategy
33
48
  @__config.array_merge_strategy
34
49
  end
35
50
 
51
+ ##
52
+ # Change the current array merge strategy for this parameters.
53
+ #
54
+ # @param strategy The new strategy to use.
36
55
  def array_merge_strategy=(strategy)
37
56
  return if not Nugrant::Config.supported_array_merge_strategy(strategy)
38
57
 
@@ -42,10 +61,14 @@ module Nugrant
42
61
  compute_all!()
43
62
  end
44
63
 
64
+ def defaults()
65
+ @__defaults
66
+ end
67
+
45
68
  ##
46
69
  # Set the new default values for the
47
70
  # various parameters contain by this instance.
48
- # This will call __compute_all() to recompute
71
+ # This will call `compute_all!` to recompute
49
72
  # correct precedences.
50
73
  #
51
74
  # =| Attributes
@@ -58,6 +81,32 @@ module Nugrant
58
81
  compute_all!()
59
82
  end
60
83
 
84
+ def merge(other)
85
+ result = dup()
86
+ result.merge!(other)
87
+ end
88
+
89
+ def merge!(other)
90
+ @__config.merge!(other.__config)
91
+
92
+ # Updated Bags' config
93
+ @__current.config = @__config
94
+ @__user.config = @__config
95
+ @__system.config = @__config
96
+ @__defaults.config = @__config
97
+
98
+ # Merge other into Bags
99
+ @__current.merge!(other.__current, :array_merge_strategy => :replace)
100
+ @__user.merge!(other.__user, :array_merge_strategy => :replace)
101
+ @__system.merge!(other.__system, :array_merge_strategy => :replace)
102
+ @__defaults.merge!(other.__defaults, :array_merge_strategy => :replace)
103
+
104
+ # Recompute all from merged Bags
105
+ compute_all!()
106
+
107
+ self
108
+ end
109
+
61
110
  ##
62
111
  # Setup instance variables of the mixin. It will compute all parameters bags
63
112
  # (current, user, system, default and all) and stored them to these respective
@@ -75,19 +124,23 @@ module Nugrant
75
124
  #
76
125
  # * `config`
77
126
  # A Nugrant::Config object or hash passed to Nugrant::Config
78
- # constructor. Used to determine where to find the various
79
- # bag data sources.
127
+ # convert method. Used to determine where to find the various
128
+ # bag data sources and other configuration options.
80
129
  #
81
- # Passed to nested structures that require nugrant configuration
82
- # parameters like the Bag object and Helper::Bag module.
130
+ # Passed to nested structures that requires a Nugrant::Config object
131
+ # like the Bag object and Helper::Bag module.
83
132
  #
84
- def setup!(defaults = {}, config = {})
133
+ # * `options`
134
+ # Options hash used by this method exclusively. No options yet, added
135
+ # for future improvements.
136
+ #
137
+ def setup!(defaults = {}, config = {}, options = {})
85
138
  @__config = Nugrant::Config::convert(config);
86
139
 
140
+ @__defaults = Bag.new(defaults, @__config)
87
141
  @__current = Helper::Bag.read(@__config.current_path, @__config.params_format, @__config)
88
142
  @__user = Helper::Bag.read(@__config.user_path, @__config.params_format, @__config)
89
143
  @__system = Helper::Bag.read(@__config.system_path, @__config.params_format, @__config)
90
- @__defaults = Bag.new(defaults, @__config)
91
144
 
92
145
  compute_all!()
93
146
  end
@@ -1,10 +1,10 @@
1
- require 'nugrant/bag'
2
- require 'nugrant/config'
3
- require 'nugrant/helper/bag'
4
1
  require 'nugrant/mixin/parameters'
5
2
 
6
3
  module Nugrant
7
4
  class Parameters
5
+
6
+ include Mixin::Parameters
7
+
8
8
  ##
9
9
  # Create a new parameters object which holds completed
10
10
  # merged values. The following precedence is used to decide
@@ -14,14 +14,16 @@ module Nugrant
14
14
  # project < user < system < defaults
15
15
  #
16
16
  # =| Arguments
17
+ # * `defaults`
18
+ # Passed to Mixin::Parameters setup! method. See mixin
19
+ # module for further information.
20
+ #
17
21
  # * `config`
18
- # Passed to Mixin::Parameters setup! method. See method
19
- # for further information.
22
+ # Passed to Mixin::Parameters setup! method. See mixin
23
+ # module for further information.
20
24
  #
21
- def initialize(config)
22
- setup!({}, config)
25
+ def initialize(defaults = {}, config = {}, options = {})
26
+ setup!(defaults, config, options)
23
27
  end
24
-
25
- include Mixin::Parameters
26
28
  end
27
29
  end
@@ -9,6 +9,10 @@ module Nugrant
9
9
  module V2
10
10
  module Command
11
11
  class Env < ::Vagrant.plugin("2", :command)
12
+ def self.synopsis
13
+ "env utilities to export config.user as environment variables in host machine"
14
+ end
15
+
12
16
  def initialize(arguments, environment)
13
17
  super(arguments, environment)
14
18
 
@@ -75,8 +79,12 @@ module Nugrant
75
79
 
76
80
  @logger.debug("Nugrant 'Env'")
77
81
  with_target_vms(arguments) do |vm|
78
- config = vm.config.user
79
- parameters = config ? config : Nugrant::Parameters.new()
82
+ parameters = vm.config.user
83
+ if not parameters
84
+ @env.ui.info("# Vm '#{vm.name}' : unable to retrieve `config.user`, report as bug https://github.com/maoueh/nugrant/issues", :prefix => false)
85
+ next
86
+ end
87
+
80
88
  bag = parameters.__all
81
89
 
82
90
  options = {:type => @unset ? :unset : :export}
@@ -7,6 +7,10 @@ module Nugrant
7
7
  module V2
8
8
  module Command
9
9
  class Parameters < ::Vagrant.plugin("2", :command)
10
+ def self.synopsis
11
+ "prints parameters hierarchy as seen by Nugrant"
12
+ end
13
+
10
14
  def initialize(arguments, environment)
11
15
  super(arguments, environment)
12
16
 
@@ -61,8 +65,11 @@ module Nugrant
61
65
 
62
66
  @logger.debug("'Parameters' each target VM...")
63
67
  with_target_vms(arguments) do |vm|
64
- config = vm.config.user
65
- parameters = config || Nugrant::Parameters.new()
68
+ parameters = vm.config.user
69
+ if not parameters
70
+ @env.ui.info("# Vm '#{vm.name}' : unable to retrieve `config.user`, report as bug https://github.com/maoueh/nugrant/issues", :prefix => false)
71
+ next
72
+ end
66
73
 
67
74
  @env.ui.info("# Vm '#{vm.name}'", :prefix => false)
68
75
 
@@ -134,8 +141,8 @@ module Nugrant
134
141
 
135
142
  def print_warning(used_restricted_keys)
136
143
  @env.ui.info("", :prefix => false)
137
- @env.ui.info(" You are using some restricted keys. Method access will not work with", :prefix => false)
138
- @env.ui.info(" the following keys, only array access will:", :prefix => false)
144
+ @env.ui.info(" You are using some restricted keys. Method access (using .<key>) will", :prefix => false)
145
+ @env.ui.info(" not work, only array access ([<key>]) will. Offending keys:", :prefix => false)
139
146
  @env.ui.info(" #{used_restricted_keys.join(", ")}", :prefix => false)
140
147
  @env.ui.info("", :prefix => false)
141
148
  end
@@ -6,6 +6,10 @@ module Nugrant
6
6
  module V2
7
7
  module Command
8
8
  class RestrictedKeys < ::Vagrant.plugin("2", :command)
9
+ def self.synopsis
10
+ "prints list of restricted keys for method access"
11
+ end
12
+
9
13
  def initialize(arguments, environment)
10
14
  super(arguments, environment)
11
15
 
@@ -9,6 +9,10 @@ module Nugrant
9
9
  module V2
10
10
  module Command
11
11
  class Root < ::Vagrant.plugin("2", :command)
12
+ def self.synopsis
13
+ "manage Nugrant user defined parameters (config.user)"
14
+ end
15
+
12
16
  def initialize(arguments, environment)
13
17
  super(arguments, environment)
14
18
 
@@ -36,7 +40,7 @@ module Nugrant
36
40
 
37
41
  def create_parser()
38
42
  return OptionParser.new do |parser|
39
- parser.banner = "Usage: vagrant user [-h] [-v] <command> [<args>]"
43
+ parser.banner = "Usage: vagrant user [-h] [-v] <subcommand> [<args>]"
40
44
 
41
45
  parser.separator ""
42
46
  parser.on("-h", "--help", "Print this help") do
@@ -58,7 +62,7 @@ module Nugrant
58
62
  end
59
63
 
60
64
  parser.separator ""
61
- parser.separator "For help on any individual command run `vagrant user COMMAND -h`"
65
+ parser.separator "For help on any individual command run `vagrant user <subcommand> -h`"
62
66
  end
63
67
  end
64
68
 
@@ -1,4 +1,3 @@
1
- require 'nugrant'
2
1
  require 'nugrant/mixin/parameters'
3
2
  require 'nugrant/vagrant/errors'
4
3
 
@@ -7,10 +6,11 @@ module Nugrant
7
6
  module V2
8
7
  module Config
9
8
  class User < ::Vagrant.plugin("2", :config)
10
- attr_reader :__current, :__user, :__system, :__defaults, :__all
11
9
 
12
- def initialize()
13
- setup!({},
10
+ include Mixin::Parameters
11
+
12
+ def initialize(defaults = {}, config = {})
13
+ setup!(defaults,
14
14
  :params_filename => ".vagrantuser",
15
15
  :key_error => Proc.new do |key|
16
16
  raise Errors::ParameterNotFoundError, :key => key.to_s
@@ -21,7 +21,7 @@ module Nugrant
21
21
  )
22
22
  end
23
23
 
24
- include Mixin::Parameters
24
+
25
25
  end
26
26
  end
27
27
  end
@@ -1,3 +1,3 @@
1
1
  module Nugrant
2
- VERSION = "2.0.0.pre2"
2
+ VERSION = "2.0.0.rc1"
3
3
  end
@@ -28,6 +28,5 @@ Gem::Specification.new do |gem|
28
28
  gem.test_files = gem.files.grep(%r{^(test/lib)/})
29
29
  gem.require_paths = ["lib"]
30
30
 
31
- gem.add_dependency "insensitive_hash", "~> 0.3"
32
31
  gem.add_dependency "multi_json", "~> 1.8"
33
32
  end
@@ -152,7 +152,7 @@ module Nugrant
152
152
 
153
153
  bag1.merge!(bag2);
154
154
 
155
- assert_equal({:first => [1, 2, 2, 3]}, bag1.to_hash())
155
+ assert_equal({:first => [2, 3, 1, 2]}, bag1.to_hash())
156
156
 
157
157
  bag1 = create_bag({"first" => [1, 2]}, :array_merge_strategy => :concat)
158
158
  bag2 = create_bag({:first => "string"})
@@ -162,6 +162,24 @@ module Nugrant
162
162
  assert_equal({:first => "string"}, bag1.to_hash())
163
163
  end
164
164
 
165
+ def test_merge_hash_keeps_indifferent_access
166
+ bag1 = create_bag({"first" => {:second => [1, 2]}})
167
+ bag1.merge!({:third => "three", "first" => {:second => [3, 4]}})
168
+
169
+ assert_equal({:first => {:second => [3, 4]}, :third => "three"}, bag1.to_hash())
170
+
171
+ assert_all_access_equal({:second => [3, 4]}, bag1, :first)
172
+ assert_all_access_equal([3, 4], bag1["first"], :second)
173
+ end
174
+
175
+ def test_set_a_slot_with_a_hash_keeps_indifferent_access
176
+ bag1 = create_bag({})
177
+ bag1["first"] = {:second => [1, 2]}
178
+
179
+ assert_all_access_equal({:second => [1, 2]}, bag1, :first)
180
+ assert_all_access_equal([1, 2], bag1["first"], :second)
181
+ end
182
+
165
183
  def test_nil_key()
166
184
  assert_raises(ArgumentError) do
167
185
  create_bag({nil => "value"})
@@ -219,9 +237,151 @@ module Nugrant
219
237
  "Some value"
220
238
  end)
221
239
 
222
- assert_equal("Some value", bag.invalid_value)
223
- assert_equal("Some value", bag["invalid_value"])
224
- assert_equal("Some value", bag[:invalid_value])
240
+ assert_all_access_equal("Some value", bag, :invalid_value)
241
+ end
242
+
243
+ def test_walk_bag
244
+ bag = create_bag({
245
+ :first => {
246
+ :level1 => "value1",
247
+ :level2 => "value2",
248
+ },
249
+ :second => {
250
+ :level1 => "value3",
251
+ :level2 => "value4",
252
+ },
253
+ :third => "value5"
254
+ })
255
+
256
+ lines = []
257
+ bag.walk do |path, key, value|
258
+ lines << "Path (#{path}), Key (#{key}), Value (#{value})"
259
+ end
260
+
261
+ assert_equal([
262
+ "Path ([:first, :level1]), Key (level1), Value (value1)",
263
+ "Path ([:first, :level2]), Key (level2), Value (value2)",
264
+ "Path ([:second, :level1]), Key (level1), Value (value3)",
265
+ "Path ([:second, :level2]), Key (level2), Value (value4)",
266
+ "Path ([:third]), Key (third), Value (value5)",
267
+ ], lines)
268
+ end
269
+
270
+ def test_merge
271
+ bag1 = create_bag({
272
+ :first => {
273
+ :level1 => "value1",
274
+ :level2 => "value2",
275
+ },
276
+ :second => {
277
+ :level1 => "value3",
278
+ :level2 => "value4",
279
+ },
280
+ :third => "value5"
281
+ })
282
+
283
+ bag2 = create_bag({
284
+ :first => {
285
+ :level2 => "overriden2",
286
+ },
287
+ :second => {
288
+ :level1 => "value3",
289
+ :level2 => "value4",
290
+ },
291
+ :third => "overriden5"
292
+ })
293
+
294
+ bag3 = bag1.merge(bag2)
295
+
296
+ refute_same(bag1, bag3)
297
+ refute_same(bag2, bag3)
298
+
299
+ assert_equal(Nugrant::Bag, bag3.class)
300
+
301
+ assert_all_access_equal("value1", bag3['first'], :level1)
302
+ assert_all_access_equal("overriden2", bag3['first'], :level2)
303
+ assert_all_access_equal("value3", bag3['second'], :level1)
304
+ assert_all_access_equal("value4", bag3['second'], :level2)
305
+ assert_all_access_equal("overriden5", bag3, :third)
306
+ end
307
+
308
+ def test_merge!
309
+ bag1 = create_bag({
310
+ :first => {
311
+ :level1 => "value1",
312
+ :level2 => "value2",
313
+ },
314
+ :second => {
315
+ :level1 => "value3",
316
+ :level2 => "value4",
317
+ },
318
+ :third => "value5"
319
+ })
320
+
321
+ bag2 = create_bag({
322
+ :first => {
323
+ :level2 => "overriden2",
324
+ },
325
+ :second => {
326
+ :level1 => "value3",
327
+ :level2 => "value4",
328
+ },
329
+ :third => "overriden5"
330
+ })
331
+
332
+ bag3 = bag1.merge!(bag2)
333
+
334
+ assert_same(bag1, bag3)
335
+ refute_same(bag2, bag3)
336
+
337
+ assert_equal(Nugrant::Bag, bag3.class)
338
+
339
+ assert_all_access_equal("value1", bag3['first'], :level1)
340
+ assert_all_access_equal("overriden2", bag3['first'], :level2)
341
+ assert_all_access_equal("value3", bag3['second'], :level1)
342
+ assert_all_access_equal("value4", bag3['second'], :level2)
343
+ assert_all_access_equal("overriden5", bag3, :third)
344
+ end
345
+
346
+ def test_merge_hash()
347
+ bag1 = create_bag({"first" => {:second => [1, 2]}}, :array_merge_strategy => :extend)
348
+
349
+ bag1.merge!({"first" => {:second => [2, 3]}});
350
+
351
+ assert_equal({:first => {:second => [1, 2, 3]}}, bag1.to_hash())
352
+ end
353
+
354
+ def test_merge_custom_array_merge_strategy()
355
+ bag1 = create_bag({"first" => {:second => [1, 2]}}, :array_merge_strategy => :extend)
356
+
357
+ bag1.merge!({"first" => {:second => [2, 3]}}, :array_merge_strategy => :replace);
358
+
359
+ assert_equal({:first => {:second => [2, 3]}}, bag1.to_hash())
360
+ end
361
+
362
+ def test_merge_custom_invalid_array_merge_strategy()
363
+ bag1 = create_bag({"first" => {:second => [1, 2]}}, :array_merge_strategy => :extend)
364
+ bag2 = bag1.merge({"first" => {:second => [2, 3]}}, :array_merge_strategy => nil);
365
+
366
+ assert_equal({:first => {:second => [1, 2, 3]}}, bag2.to_hash())
367
+
368
+ bag2 = bag1.merge({"first" => {:second => [2, 3]}}, :array_merge_strategy => :invalid);
369
+
370
+ assert_equal({:first => {:second => [1, 2, 3]}}, bag2.to_hash())
371
+ end
372
+
373
+ def test_change_config
374
+ bag1 = create_bag({"first" => [1, 2]}, :array_merge_strategy => :extend)
375
+ bag2 = create_bag({:first => [2, 3]})
376
+
377
+ bag3 = bag1.merge!(bag2);
378
+ bag3.config = {
379
+ :array_merge_strategy => :concat
380
+ }
381
+
382
+ bag3.merge!({"first" => [1, 2, 3]})
383
+
384
+ assert_equal([1, 2, 3, 1, 2, 3], bag3['first'])
225
385
  end
226
386
  end
227
387
  end
@@ -119,5 +119,61 @@ module Nugrant
119
119
  Nugrant::Config.new({:params_format => :invalid})
120
120
  end
121
121
  end
122
+
123
+ def test_merge
124
+ config1 = Nugrant::Config.new({
125
+ :params_filename => ".customparams",
126
+ :current_path => nil,
127
+ })
128
+
129
+ config2 = Nugrant::Config.new({
130
+ :params_filename => ".overrideparams",
131
+ :current_path => "something",
132
+ })
133
+
134
+ config3 = config1.merge(config2)
135
+
136
+ refute_same(config1, config3)
137
+ refute_same(config2, config3)
138
+
139
+ assert_equal(Nugrant::Config.new({
140
+ :params_filename => config2[:params_filename],
141
+ :params_format => config2[:params_format],
142
+ :current_path => config2[:current_path],
143
+ :user_path => config2[:user_path],
144
+ :system_path => config2[:system_path],
145
+ :array_merge_strategy => config2[:array_merge_strategy],
146
+ :key_error => config2[:key_error],
147
+ :parse_error => config2[:parse_error],
148
+ }), config3)
149
+ end
150
+
151
+ def test_merge!
152
+ config1 = Nugrant::Config.new({
153
+ :params_filename => ".customparams",
154
+ :current_path => nil,
155
+ })
156
+
157
+ config2 = Nugrant::Config.new({
158
+ :params_filename => ".overrideparams",
159
+ :current_path => "something",
160
+ })
161
+
162
+ config3 = config1.merge!(config2)
163
+
164
+ assert_same(config1, config3)
165
+ refute_same(config2, config3)
166
+
167
+ assert_equal(Nugrant::Config.new({
168
+ :params_filename => config2[:params_filename],
169
+ :params_format => config2[:params_format],
170
+ :current_path => config2[:current_path],
171
+ :user_path => config2[:user_path],
172
+ :system_path => config2[:system_path],
173
+ :array_merge_strategy => config2[:array_merge_strategy],
174
+ :key_error => config2[:key_error],
175
+ :parse_error => config2[:parse_error],
176
+ }), config3)
177
+ end
122
178
  end
123
179
  end
@@ -10,7 +10,7 @@ module Nugrant
10
10
  @@FORMATS = [:json, :yaml]
11
11
  @@INVALID_PATH = "impossible_file_path.yamljson.impossible"
12
12
 
13
- def create_parameters(format, current_filename, user_filename, system_filename)
13
+ def create_parameters(format, current_filename, user_filename, system_filename, defaults = {}, options = {})
14
14
  extension = case
15
15
  when format = :json
16
16
  "json"
@@ -26,11 +26,12 @@ module Nugrant
26
26
  user_path = "#{resource_path}/#{user_filename}.#{extension}" if user_filename
27
27
  system_path = "#{resource_path}/#{system_filename}.#{extension}" if system_filename
28
28
 
29
- return Nugrant::Parameters.new({
29
+ return Nugrant::Parameters.new(defaults, {
30
30
  :format => format,
31
31
  :current_path => current_path,
32
32
  :user_path => user_path,
33
33
  :system_path => system_path,
34
+ :array_merge_strategy => options[:array_merge_strategy]
34
35
  })
35
36
  end
36
37
 
@@ -273,15 +274,149 @@ module Nugrant
273
274
  end
274
275
  end
275
276
 
276
- def test_hash_method_collect()
277
+ def test_enumerable_method_insensitive()
277
278
  parameters = create_parameters(:json, "params_simple", invalid_path, invalid_path)
278
- parameters.defaults = {"test" => "override1", :level => "new1"}
279
+ parameters.defaults = {"test" => "override1", :level => :new1}
280
+
281
+ assert_equal(1, parameters.count([:test, "value"]))
282
+ assert_equal(1, parameters.count(["test", "value"]))
283
+ assert_equal(0, parameters.count(["test"]))
284
+ assert_equal(0, parameters.count([]))
285
+ assert_equal(0, parameters.count(:a))
286
+ assert_equal(0, parameters.count(nil))
287
+
288
+ assert_equal(0, parameters.find_index([:test, "value"]))
289
+ assert_equal(0, parameters.find_index(["test", "value"]))
290
+ assert_equal(nil, parameters.find_index(["test"]))
291
+ assert_equal(nil, parameters.find_index([]))
292
+ assert_equal(nil, parameters.find_index(:a))
293
+ assert_equal(nil, parameters.find_index(nil))
294
+ assert_equal(0, parameters.find_index() { |key, value| key == :test and value == "value" })
295
+
296
+ assert_equal(false, parameters.include?([:test, "value"]))
297
+ assert_equal(false, parameters.include?(["test", "value"]))
298
+ end
279
299
 
280
- pairs = parameters.collect do |key, value|
281
- [key, value]
282
- end
300
+ def test_hash_method_insensitive()
301
+ parameters = create_parameters(:json, "params_simple", invalid_path, invalid_path)
302
+ parameters.defaults = {"test" => "override1", :level => :new1}
303
+
304
+ assert_equal([:test, "value"], parameters.assoc("test"))
305
+ assert_equal([:test, "value"], parameters.assoc(:test))
306
+
307
+ # compare_by_identity ?
308
+
309
+ parameters.delete("test")
310
+ assert_equal(nil, parameters.assoc("test"))
311
+ assert_equal(nil, parameters.assoc(:test))
312
+
313
+ parameters = create_parameters(:json, "params_simple", invalid_path, invalid_path)
314
+ parameters.defaults = {"test" => "override1", :level => :new1}
315
+
316
+ assert_equal([[:test, "value"], [:level, :new1]], parameters.collect {|key, value| [key, value]})
317
+
318
+ assert_equal("value", parameters.fetch("test"))
319
+ assert_equal("value", parameters.fetch("test", "default"))
320
+ assert_equal("default", parameters.fetch("unknown", "default"))
321
+
322
+ assert_equal(true, parameters.has_key?("test"))
323
+ assert_equal(true, parameters.has_key?(:test))
324
+
325
+ assert_equal(true, parameters.include?("test"))
326
+ assert_equal(true, parameters.include?(:test))
327
+
328
+ assert_equal(true, parameters.member?("test"))
329
+ assert_equal(true, parameters.member?(:test))
330
+
331
+ parameters.store("another", "different")
332
+ assert_equal(true, parameters.member?("another"))
333
+ assert_equal(true, parameters.member?(:another))
334
+ end
335
+
336
+ def test_defaults_not_overwritten_on_array_merge_strategy_change
337
+ parameters = create_parameters(:json, "params_array", invalid_path, invalid_path)
338
+ parameters.defaults = {"level1" => {"level2" => ["4", "5", "6"]}}
339
+
340
+ parameters.array_merge_strategy = :concat
341
+
342
+ assert_equal(["4", "5", "6"], parameters.defaults().level1.level2)
343
+ assert_equal(["1", "2", "3", "4", "5", "6"], parameters.level1.level2)
344
+ end
345
+
346
+ def test_merge()
347
+ parameters1 = create_parameters(:json, "params_current_1", invalid_path, invalid_path, {
348
+ "0.1.1" => "default",
349
+ "0.1.0" => "default",
350
+ "0.0.1" => "default",
351
+ })
352
+
353
+ parameters2 = create_parameters(:json, "params_current_1", invalid_path, "params_system_1", {
354
+ "0.1.0" => "default_overriden",
355
+ })
356
+
357
+ parameters3 = parameters1.merge(parameters2)
358
+
359
+ refute_same(parameters1, parameters3)
360
+ refute_same(parameters2, parameters3)
361
+
362
+ assert_equal(Nugrant::Parameters, parameters3.class)
363
+
364
+ assert_level(parameters3, {
365
+ :'1.1.1' => "current",
366
+ :'1.1.0' => "current",
367
+ :'1.0.1' => "current",
368
+ :'0.1.1' => "system",
369
+ :'1.0.0' => "current",
370
+ :'0.1.0' => "default_overriden",
371
+ :'0.0.1' => "system",
372
+ })
373
+ end
374
+
375
+ def test_merge!()
376
+ parameters1 = create_parameters(:json, "params_current_1", invalid_path, invalid_path, {
377
+ "0.1.1" => "default",
378
+ "0.1.0" => "default",
379
+ "0.0.1" => "default",
380
+ })
381
+
382
+ parameters2 = create_parameters(:json, "params_current_1", invalid_path, "params_system_1", {
383
+ "0.1.0" => "default_overriden",
384
+ })
385
+
386
+ parameters3 = parameters1.merge!(parameters2)
387
+
388
+ assert_same(parameters1, parameters3)
389
+ refute_same(parameters2, parameters3)
390
+
391
+ assert_equal(Nugrant::Parameters, parameters3.class)
392
+
393
+ assert_level(parameters3, {
394
+ :'1.1.1' => "current",
395
+ :'1.1.0' => "current",
396
+ :'1.0.1' => "current",
397
+ :'0.1.1' => "system",
398
+ :'1.0.0' => "current",
399
+ :'0.1.0' => "default_overriden",
400
+ :'0.0.1' => "system",
401
+ })
402
+ end
403
+
404
+ def test_merge_with_different_array_merge_strategy()
405
+ parameters1 = create_parameters(:json, "params_array", invalid_path, invalid_path, {
406
+ "level1" => {
407
+ "level2" => ["3", "4", "5"]
408
+ }
409
+ }, :array_merge_strategy => :replace)
410
+
411
+ parameters2 = create_parameters(:json, "params_array", invalid_path, invalid_path, {
412
+ "level1" => {
413
+ "level2" => ["3", "6", "7"]
414
+ }
415
+ }, :array_merge_strategy => :concat)
416
+
417
+ parameters3 = parameters1.merge(parameters2)
283
418
 
284
- assert_equal([[:test, "value"], [:level, "new1"]], pairs)
419
+ assert_equal(["1", "2", "3", "3", "6", "7"], parameters3.level1.level2)
285
420
  end
286
421
 
287
422
  def formats()
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nugrant
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.pre2
4
+ version: 2.0.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthieu Vachon
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-23 00:00:00.000000000 Z
11
+ date: 2014-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: insensitive_hash
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ~>
18
- - !ruby/object:Gem::Version
19
- version: '0.3'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ~>
25
- - !ruby/object:Gem::Version
26
- version: '0.3'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: multi_json
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -158,7 +144,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
158
144
  version: 1.3.1
159
145
  requirements: []
160
146
  rubyforge_project:
161
- rubygems_version: 2.2.1
147
+ rubygems_version: 2.2.2
162
148
  signing_key:
163
149
  specification_version: 4
164
150
  summary: Library to handle user specific parameters from various location.