nugrant 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- Y2U0MTBmOTMyYzhmYzk5NDBjOTRlZmNhMWYyMDkyYzM3ZTBkOGRmZA==
4
+ YjUxMDRmNWQ5NTE4OWRjYWNiNzJlMzIxMTc1NWI2ZmI3MDBiZGUxOQ==
5
5
  data.tar.gz: !binary |-
6
- OGFkNTY2MjRjZTQ1ODhhM2FjNDBlNzVkZDE4NTA1NDdiODExNTExZA==
7
- !binary "U0hBNTEy":
6
+ NGY1MzI0ZTQ3NjVmNjBhMmViYzA0OWUwMDJjMDM1MDI2MWZlNGY1Mw==
7
+ SHA512:
8
8
  metadata.gz: !binary |-
9
- MjNmODVmZGQ1YjFlYjAxMjFjZWRmMWQyMDE0N2ZhNTlkM2RjNjM2NDJjYjVj
10
- NGE1NGE0NzE0MzNmMDc5MTNmODZiMWI3MWZmMDA4ZWM3NzI4ZmYxOTMzMTI5
11
- Njc0Zjg5ZTAwZTFmMzg5MTJhMjBiNzhlNzFmNzRhYTVlNmZlYzk=
9
+ YTE0NzgxZWM4YzcxODQ1MzA2ZmE1NTEyYTBkMjAyM2VhZjJiYmJlYzAxNzk2
10
+ NWVkYzQ0NWM4MGU1MDQ4ZWIzNDAxMGI3NWM2MDYzYWNkZTMzZmNhMTBlMzYy
11
+ OTAxYjQ5MmExNDBmOTk0YjJmNmNkNjliOTc3OGM4NTg5YjY0MWU=
12
12
  data.tar.gz: !binary |-
13
- NTFjZTVhZjIyNDEwN2VlMGMxZDg1MTYxY2ExZDVmZGMzYzI5NjExODgxZjY0
14
- NWQ5NTBhNzYxNWRlYTUzNTE1NzU5MWY5YTE0MTJkMGEyYzdkNjM2OWNlMmZh
15
- MmVkOGRiNmQ2OGIyZWVmMTVkN2FkZGZlZDY5MzdhY2YxY2I2M2Q=
13
+ NDIyMTA5ZDM1OTg1NDMwNTc4MDY0MGEzMTI2MWM1YWZkZTE3ZjM0NDQyNWMx
14
+ NDUyZTNiMmE3ZmYxYmQ2OTk1YTI2Mzc2NThlZDhjZGY0ODJjMWZmMGViNTgx
15
+ ZGU0Y2E5Y2I5NzJlNmVmMWQxN2Q0MWIyMWQ0NWU3ODIxNDY0YzU=
data/.gitignore CHANGED
@@ -19,3 +19,4 @@ test/version_tmp
19
19
  tmp
20
20
 
21
21
  test/resources/vagrantfiles/Vagrantfile
22
+ test/resources/vagrantfiles/.vagrantuser
@@ -1,3 +1,21 @@
1
+ # 1.3.0 (November 19th, 2013)
2
+
3
+ * Now using [minitest](https://github.com/seattlerb/minitest) as our
4
+ testing library.
5
+
6
+ * Added a new command that can be used either standalone or via
7
+ a small bash script to easily export environment variables
8
+ from your currently set parameters. See
9
+ [GH-13](https://github.com/maoueh/nugrant/issues/13).
10
+
11
+ * Keys associated to a null value are considered as being missing
12
+ by the merge process. It is still possible to define a null
13
+ parameter, but it will be overridden by any parameter and will not
14
+ override any. See [GH-12](https://github.com/maoueh/nugrant/issues/12).
15
+
16
+ * Fixed output of command `vagrant user parameters`, the keys were
17
+ serialized as symbol instead of string.
18
+
1
19
  # 1.2.0 (October 24th, 2013)
2
20
 
3
21
  * Now showing better error message to the end-user when a parameter
@@ -16,9 +34,11 @@
16
34
  ```
17
35
 
18
36
  See [GH-8] (https://github.com/maoueh/nugrant/issues/8).
37
+
19
38
  * Ensured that keys used within a `Bag` are always symbol. This make
20
39
  sure that it is possible to retrieve a value with any access method.
21
40
  See [GH-9](https://github.com/maoueh/nugrant/issues/9).
41
+
22
42
  * Now using [multi_json](https://rubygems.org/gems/multi_json)
23
43
  for JSON handling.
24
44
 
@@ -27,8 +47,10 @@
27
47
  * Rewrite completely classes `Parameters` and `Bag`.
28
48
  * Reduced chances to have a parameter name collapsing with an
29
49
  implementation method.
50
+
30
51
  * Removed dependency on `deep_merge`. We do now perform
31
52
  our own merge.
53
+
32
54
  * Added possibility to iterate through keys by using
33
55
  `.each`:
34
56
 
@@ -41,6 +63,7 @@
41
63
  ### Backward Incompatibilities
42
64
 
43
65
  * `Parameters` is not extending the `Bag` class anymore.
66
+
44
67
  * `Parameters` and `Bag` attributes and methods are now almost
45
68
  all prefixed with __ to reduce clashes to a minimum when
46
69
  accessing parameters with method-like syntax
@@ -49,7 +72,8 @@
49
72
  # 1.0.1 (April 9th, 2013)
50
73
 
51
74
  * Fixed a crash when `user` config value is `nil` preventing `vagrant user parameters`
52
- from working as expected. [GH-4](https://github.com/maoueh/nugrant/issues/4)
75
+ from working as expected. See [GH-4](https://github.com/maoueh/nugrant/issues/4).
76
+
53
77
  * Fixed a bug preventing the version from being printed when doing `vagrant user -v`.
54
78
 
55
79
  # 1.0.0 (March 21th, 2013)
@@ -61,6 +85,7 @@
61
85
  # 0.0.14
62
86
 
63
87
  * Renamed `ParameterBag` to `Bag`
88
+
64
89
  * Cleanup `Bag` api
65
90
  * Renamed method `has_param?` to `has_key?` in `Bag`
66
91
  * Removed method `get_params` from `Bag`
@@ -70,6 +95,7 @@
70
95
  * Cleanup `Parameters` and `ParameterBag` interface
71
96
  * The method `defaults` has been removed from the bag
72
97
  * Setting defaults on `Parameters` now recompute the final bag
98
+
73
99
  * Improved `vagrant user parameters` command
74
100
  * Now using the exact config as seen by Vagrant, this includes defaults parameters
75
101
  * An option has been added to only see defaults parameters
@@ -77,8 +103,11 @@
77
103
  # 0.0.12
78
104
 
79
105
  * Added travis configuration file
106
+
80
107
  * Added travis build status icon to readme
108
+
81
109
  * Fixed a bug when `.vagrantuser` file is empty or not a hash type
110
+
82
111
  * Improved parameters command
83
112
  * The parameters command is now a proper subcommand
84
113
  * An option has been added to see system parameters
@@ -92,6 +121,7 @@
92
121
  # 0.0.10
93
122
 
94
123
  * Added a subcommand `parameters` for vagrant command `user`
124
+
95
125
  * Added a vagrant command `vagrant user subcommand [options]`
96
126
 
97
127
  # 0.0.9
@@ -101,7 +131,9 @@
101
131
  # 0.0.8
102
132
 
103
133
  * Introduced possibility to set default values
104
- * Introduced restricted keys (For now, restricted keys are [`defaults`])
134
+
135
+ * Introduced restricted keys (For now, restricted keys are [`defaults`]).
136
+
105
137
  * Fixed a bug with system-wide parameters
106
138
 
107
139
  # 0.0.7
@@ -119,4 +151,5 @@
119
151
  # 0.0.4
120
152
 
121
153
  * JSON is now the default file format for parameters (due to problem with YAML)
154
+
122
155
  * It is now possible to store parameters in the JSON format
data/README.md CHANGED
@@ -27,7 +27,7 @@ If you would like to use Nugrant as a library, simply reference
27
27
  it as a dependency of your application. Probably by adding it to
28
28
  your `Gemfile` or your `.gemspec` file.
29
29
 
30
- nugrant ~> 1.0.1
30
+ "nugrant", "~> 1.3"
31
31
 
32
32
  ### Vagrant
33
33
 
@@ -214,7 +214,7 @@ Here the list of locations where Nugrant looks for parameters:
214
214
  ### Paths
215
215
 
216
216
  When you want to specify paths on, specially on Windows, it's probably
217
- better to only use foward slash (`/`). The main reason for this is because
217
+ better to only use forward slash (`/`). The main reason for this is because
218
218
  Ruby, which will be used at the end by Vagrant is able to deal with forward
219
219
  slash even on Windows. This is great because with this, you can avoid
220
220
  values escaping in YAML file. If you need to use backward slash (`\`), don't
@@ -223,6 +223,18 @@ forget to properly escape it!
223
223
  value: "C:/Users/user/work/git"
224
224
  value: "C:\\Users\\user\\work\\git"
225
225
 
226
+ Moreover, it is preferable that paths are specified in full
227
+ (i.e. no `~` for HOME directory for example). Normally, they
228
+ should be handled by `Vagrant` but it may happen that it's not
229
+ the case. If your have an error with a specific parameter,
230
+ either expand it in your config:
231
+
232
+ project: "/home/joe/work/ruby/git"
233
+
234
+ Of expand it in the `Vagrantfile`:
235
+
236
+ config.vm.synced_folder File.expand_path(config.user.repository.project), "/git"
237
+
226
238
  ### Parameters access
227
239
 
228
240
  Parameters in the `Vagrantfile` can be retrieved via method call
@@ -295,6 +307,101 @@ Usage:
295
307
  nodes_path: /Users/Chef/kitchen/nodes
296
308
  roles_path: /Users/Chef/kitchen/roles
297
309
 
310
+ Add flag `-h` (or `--help`) for description of the command and a
311
+ list of available options.
312
+
313
+ #### Env
314
+
315
+ Sometimes, you would like to have acces to the different values
316
+ stored in your `.vagrantuser` from environment variables. This
317
+ command is meant is exactly for this.
318
+
319
+ By using one of the two methods below, you will be able to export
320
+ (but also unset) environment variables from your current
321
+ parameters as seen by Nugrant.
322
+
323
+ You can see the commands that will be executed by simply
324
+ calling the method:
325
+
326
+ vagrant user env
327
+
328
+ The name of the environment will be upper cased and full path of
329
+ the key, without the `config.user` prefix, separated
330
+ with `_`. For example, the key accessible using
331
+ `config.user.db.user` and with value `root` would generate the
332
+ export command:
333
+
334
+ export DB_USER=root
335
+
336
+ And the unset command:
337
+
338
+ unset DB_USER
339
+
340
+ The value are escaped so it is possible to define value containing
341
+ spaces for example.
342
+
343
+ A last note about generate commands is that pre-existing environment
344
+ variable are not taking in consideration by this command. So if
345
+ an environment variable with name `DB_USER` already exist, it
346
+ would be overwritten by an export command.
347
+
348
+ Add flag `-h` (or `--help`) for description of the command and a
349
+ list of available options.
350
+
351
+ ##### Method #1
352
+
353
+ If you plan to use frequently this feature, our best suggestion
354
+ is to create a little bash script that will simply delegates
355
+ to the real command. By having a bash script that calls the
356
+ command, you will be able to easily export environment variables
357
+ by sourcing the script.
358
+
359
+ Create a file named `nugrant2env` somewhere accessible from
360
+ the `$PATH` variable with the following content:
361
+
362
+ ```bash
363
+ #!/bin/env sh
364
+
365
+ $(vagrant user env "$@")
366
+ ```
367
+
368
+ This script will simply delegates to the `vagrant user env`
369
+ command and pass all arguments it receives to it. The
370
+ magic happens because the command `vagrant user env` outputs
371
+ the various export commands to the standard output.
372
+
373
+ By sourcing the simple delegating bash script, the parameters
374
+ seen by Nugrant will be available in your environment:
375
+
376
+ . nugrant2env
377
+
378
+ By default, export commands are generated. But you can pass
379
+ some options to the `nugrant2env` script, For example, to
380
+ generate the unset ones, add `--unset` (or simply `-u`).
381
+
382
+ . nugrant2env --unset
383
+
384
+ For a list of options, see the help of the command delegated
385
+ to:
386
+
387
+ vagrant user env -h
388
+
389
+ ##### Method #2
390
+
391
+ Use the command to generate a base script in the current
392
+ directory that you will then source:
393
+
394
+ vagrant user env -s
395
+
396
+ This will generate a script called `nugrant2env.sh` into the
397
+ current directory. You then simply source this script:
398
+
399
+ . nugrant2env.sh
400
+
401
+ Using vagrant user env -s -u will instead generate the bash
402
+ script that will unset the enviornment variables. Don't forget
403
+ to source it to unset variables.
404
+
298
405
  ## Contributing
299
406
 
300
407
  You can contribute by filling issues when something goes
@@ -42,7 +42,7 @@ module Nugrant
42
42
  current.__merge!(value)
43
43
  elsif current.kind_of?(Array) and value.kind_of?(Array)
44
44
  @__elements[key] = current | value
45
- else
45
+ elsif value != nil
46
46
  @__elements[key] = value
47
47
  end
48
48
 
@@ -59,12 +59,16 @@ module Nugrant
59
59
  end
60
60
  end
61
61
 
62
- def __to_hash()
62
+ def __to_hash(options = {})
63
63
  return {} if empty?()
64
64
 
65
+ string_key = options[:string_key]
66
+
65
67
  hash = {}
66
68
  each do |key, value|
67
- hash[key] = value.kind_of?(Bag) ? value.__to_hash() : value
69
+ key = key.to_s() if string_key
70
+
71
+ hash[key] = value.kind_of?(Bag) ? value.__to_hash(:string_key => string_key) : value
68
72
  end
69
73
 
70
74
  return hash
@@ -6,25 +6,23 @@ require 'nugrant/bag'
6
6
  module Nugrant
7
7
  module Helper
8
8
  module Bag
9
- def self.read(filepath, filetype, error_handler = nil)
10
- data = parse_data(filepath, filetype, error_handler)
9
+ def self.read(filepath, filetype, options = {})
10
+ data = parse_data(filepath, filetype, options)
11
11
 
12
12
  return Nugrant::Bag.new(data)
13
13
  end
14
14
 
15
- def self.parse_data(filepath, filetype, error_handler = nil)
15
+ def self.parse_data(filepath, filetype, options = {})
16
16
  return if not File.exists?(filepath)
17
17
 
18
- begin
19
- File.open(filepath, "rb") do |file|
20
- parsing_method = "parse_#{filetype}"
21
- return send(parsing_method, file.read)
22
- end
23
- rescue => error
24
- if error_handler
25
- # TODO: Implements error handler logic
26
- error_handler.handle("Could not parse the user #{filetype} parameters file '#{filepath}': #{error}")
27
- end
18
+ File.open(filepath, "rb") do |file|
19
+ parsing_method = "parse_#{filetype}"
20
+ return send(parsing_method, file.read)
21
+ end
22
+ rescue => error
23
+ if options[:error_handler]
24
+ # TODO: Implements error handler logic
25
+ options[:error_handler].handle("Could not parse the user #{filetype} parameters file '#{filepath}': #{error}")
28
26
  end
29
27
  end
30
28
 
@@ -33,7 +31,7 @@ module Nugrant
33
31
  end
34
32
 
35
33
  def self.parse_yml(data_string)
36
- YAML::ENGINE.yamler= 'syck' if defined?(YAML::ENGINE)
34
+ YAML::ENGINE.yamler = 'syck' if defined?(YAML::ENGINE)
37
35
 
38
36
  YAML.load(data_string)
39
37
  end
@@ -0,0 +1,232 @@
1
+ require 'shellwords'
2
+
3
+ module Nugrant
4
+ module Helper
5
+ class Env
6
+
7
+ @@DEFAULT_SCRIPT_PATH = "./nugrant2env.sh"
8
+
9
+ ##
10
+ # Notes on `namer`
11
+ #
12
+ # A namer is a lambda taking as argument an array of segments
13
+ # that should return a string representation of those segments.
14
+ # How the segments are transformed to a string is up to the
15
+ # namer. By using various namer, we can change how a bag key
16
+ # is transformed into and environment variable name. This is
17
+ # like the strategy pattern.
18
+ #
19
+
20
+ ##
21
+ # Returns the default namer, which join segments together
22
+ # using a character and upcase the result.
23
+ #
24
+ # @param `char` The character used to join segments together, default to `"_"`.
25
+ #
26
+ # @return A lambda that will simply joins segment using the `char` argument
27
+ # and upcase the result.
28
+ #
29
+ def self.default_namer(char = "_")
30
+ lambda do |segments|
31
+ segments.join(char).upcase()
32
+ end
33
+ end
34
+
35
+ ##
36
+ # Returns the prefix namer, which add a prefix to segments
37
+ # and delegate its work to another namer.
38
+ #
39
+ # @param prefix The prefix to add to segments.
40
+ # @param delegate_namer A namer that will be used to transform the prefixed segments.
41
+ #
42
+ # @return A lambda that will simply add prefix to segments and will call
43
+ # the delegate_namer with those new segments.
44
+ #
45
+ def self.prefix_namer(prefix, delegate_namer)
46
+ lambda do |segments|
47
+ delegate_namer.call([prefix] + segments)
48
+ end
49
+ end
50
+
51
+ def self.commands(type, bag, options = {})
52
+ # TODO: Replace by a map type => function name
53
+ case
54
+ when type == :export
55
+ export_commands(bag, options)
56
+ when type == :unset
57
+ unset_commands(bag, options)
58
+ end
59
+ end
60
+
61
+ ##
62
+ # Generate the list of export commands that must be
63
+ # executed so each bag variables is export to an
64
+ # environment variables
65
+ #
66
+ # @param bag The bag to export to environment variables
67
+ #
68
+ # @return A list of commands that can be used to
69
+ # export the bag to environment variables.
70
+ #
71
+ # Options:
72
+ # * :escape_value (true) => If true, escape the value to export.
73
+ #
74
+ # * :namer (nil) => A block taking as options the full path of
75
+ # an export variable key and return what
76
+ # the name the should be exported.
77
+ #
78
+ # * :override (true) => If true, an export command will be put
79
+ # in the list even if it already exist in
80
+ # the ENV array.
81
+ #
82
+ def self.export_commands(bag, options = {})
83
+ namer = options[:namer] || default_namer()
84
+ override = options.fetch(:override, true)
85
+
86
+ commands = []
87
+ walk_bag(bag) do |segments, key, value|
88
+ key = namer.call(segments)
89
+
90
+ commands << export_command(key, value, options) if override or not ENV[key]
91
+ end
92
+
93
+ commands
94
+ end
95
+
96
+ ##
97
+ # Generate the list of unset commands that must be
98
+ # executed so each bag variables is unset from the
99
+ # environment variables
100
+ #
101
+ # @param bag The bag to unset environment variables
102
+ #
103
+ # @return A list of commands that can be used to
104
+ # unset the bag from environment variables.
105
+ #
106
+ # Options:
107
+ # * :namer (nil) => A block taking as options the full path of
108
+ # an export variable key and return what
109
+ # the name the should be exported.
110
+ #
111
+ # * :override (true) => If true, an export command will be put
112
+ # in the list even if it already exist in
113
+ # the ENV array.
114
+ #
115
+ def self.unset_commands(bag, options = {})
116
+ namer = options[:namer] || default_namer()
117
+ override = options.fetch(:override, true)
118
+
119
+ commands = []
120
+ walk_bag(bag) do |segments, key, value|
121
+ key = namer.call(segments)
122
+
123
+ commands << unset_command(key, value, options) if override or not ENV[key]
124
+ end
125
+
126
+ commands
127
+ end
128
+
129
+ ##
130
+ # Returns a string representation of the command
131
+ # that needs to be used on the current platform
132
+ # to export an environment variable.
133
+ #
134
+ # @param key The key of the environment variable to export.
135
+ # It cannot be nil.
136
+ # @param value The value of the environment variable to export
137
+ #
138
+ # @return The export command, as a string
139
+ #
140
+ # Options:
141
+ # * :escape_value (true) => If true, escape the value to export.
142
+ #
143
+ def self.export_command(key, value, options = {})
144
+ value = value.to_s()
145
+ value = Shellwords.escape(value) if options[:escape_value] == nil || options[:escape_value]
146
+
147
+ # TODO: Handle platform differently
148
+ "export #{key}=#{value}"
149
+ end
150
+
151
+ ##
152
+ # Returns a string representation of the command
153
+ # that needs to be used on the current platform
154
+ # to unset an environment variable.
155
+ #
156
+ # @param key The key of the environment variable to export.
157
+ # It cannot be nil.
158
+ #
159
+ # @return The unset command, as a string
160
+ #
161
+ def self.unset_command(key, value, options = {})
162
+ # TODO: Handle platform differently
163
+ "unset #{key}"
164
+ end
165
+
166
+ ##
167
+ # Creates a bash script containing the commands that are required
168
+ # to export or unset a bunch of environment variables taken from the
169
+ # bag.
170
+ #
171
+ # @param bag The bag to create the script for.
172
+ #
173
+ # @return (side-effect) Creates a script file containing commands
174
+ # to export or unset environment variables for
175
+ # bag.
176
+ #
177
+ # Options:
178
+ # * :type => The type of command, default to :export
179
+ # * :script_path => The path where to write the script, defaults to `./nugrant2env.sh`.
180
+ # * See commands, export_commands and unset_commands for further options.
181
+ #
182
+ def self.write_script(bag, options = {})
183
+ file = File.open(File.expand_path(options[:script_path] || @@DEFAULT_SCRIPT_PATH), "w")
184
+
185
+ file.puts("#!/bin/env sh")
186
+ file.puts()
187
+
188
+ write_commands(bag, options, file)
189
+ ensure
190
+ file.close() if file
191
+ end
192
+
193
+ ##
194
+ # Creates a bash script containing the commands that are required
195
+ # to export or unset a bunch of environment variables taken from the
196
+ # bag.
197
+ #
198
+ # The
199
+ #
200
+ # @param bag The bag to create the script for.
201
+ # @param io The io where to output the commands, defaults to $stdout.
202
+ #
203
+ # @return (side-effect) Outputs to io the commands generated.
204
+ #
205
+ # Options:
206
+ # * :type => The type of command, default to :export
207
+ # * See commands, export_commands and unset_commands for further options.
208
+ #
209
+ def self.write_commands(bag, options = {}, io = $stdout)
210
+ commands = commands(options[:type] || :export, bag, options)
211
+
212
+ commands.each do |command|
213
+ io.puts(command)
214
+ end
215
+ end
216
+
217
+ private
218
+
219
+ def self.walk_bag(bag, parents = [], &block)
220
+ commands = []
221
+
222
+ bag.each do |key, value|
223
+ segments = parents + [key]
224
+ nested_bag = value.kind_of?(Nugrant::Bag)
225
+
226
+ walk_bag(value, segments, &block) if nested_bag
227
+ yield segments, key, value if not nested_bag
228
+ end
229
+ end
230
+ end
231
+ end
232
+ end