nugrant 2.0.0.dev2 → 2.0.0.pre1

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.
Files changed (54) hide show
  1. checksums.yaml +6 -14
  2. data/.gitignore +2 -1
  3. data/.travis.yml +2 -2
  4. data/CHANGELOG.md +148 -3
  5. data/Gemfile +8 -20
  6. data/README.md +266 -72
  7. data/Rakefile +1 -0
  8. data/lib/nugrant.rb +14 -6
  9. data/lib/nugrant/bag.rb +116 -62
  10. data/lib/nugrant/helper/bag.rb +19 -19
  11. data/lib/nugrant/helper/env/exporter.rb +208 -0
  12. data/lib/nugrant/helper/env/namer.rb +47 -0
  13. data/lib/nugrant/helper/parameters.rb +12 -0
  14. data/lib/nugrant/helper/stack.rb +86 -0
  15. data/lib/nugrant/mixin/parameters.rb +98 -0
  16. data/lib/nugrant/parameters.rb +14 -68
  17. data/lib/nugrant/vagrant/errors.rb +27 -0
  18. data/lib/nugrant/vagrant/v2/command/env.rb +101 -0
  19. data/lib/nugrant/vagrant/v2/command/helper.rb +30 -0
  20. data/lib/nugrant/vagrant/v2/command/parameters.rb +16 -4
  21. data/lib/nugrant/vagrant/v2/command/restricted_keys.rb +60 -0
  22. data/lib/nugrant/vagrant/v2/command/root.rb +12 -2
  23. data/lib/nugrant/vagrant/v2/config/user.rb +9 -21
  24. data/lib/nugrant/vagrant/v2/plugin.rb +0 -1
  25. data/lib/nugrant/version.rb +1 -1
  26. data/locales/en.yml +13 -0
  27. data/nugrant.gemspec +3 -7
  28. data/test/lib/nugrant/helper/env/test_exporter.rb +238 -0
  29. data/test/lib/nugrant/helper/test_bag.rb +16 -0
  30. data/test/lib/nugrant/helper/test_parameters.rb +17 -0
  31. data/test/lib/nugrant/helper/test_stack.rb +152 -0
  32. data/test/lib/nugrant/test_bag.rb +132 -22
  33. data/test/lib/nugrant/test_config.rb +95 -92
  34. data/test/lib/nugrant/test_parameters.rb +232 -177
  35. data/test/lib/test_helper.rb +3 -0
  36. data/test/resources/json/params_user_nil_values.json +9 -0
  37. data/test/resources/vagrantfiles/v2.defaults_mixed_string_symbols +18 -0
  38. data/test/resources/vagrantfiles/v2.defaults_null_values_in_vagrantuser +23 -0
  39. data/test/resources/vagrantfiles/v2.defaults_using_string +18 -0
  40. data/test/resources/vagrantfiles/v2.defaults_using_symbol +18 -0
  41. data/test/resources/{Vagrantfile.v2.empty → vagrantfiles/v2.empty} +0 -2
  42. data/test/resources/{Vagrantfile.v2.fake → vagrantfiles/v2.fake} +4 -3
  43. data/test/resources/vagrantfiles/v2.missing_parameter +3 -0
  44. data/test/resources/{Vagrantfile.v2.real → vagrantfiles/v2.real} +0 -2
  45. data/test/resources/yaml/params_user_nil_values.yml +5 -0
  46. metadata +55 -88
  47. data/lib/nugrant/vagrant/v1/command/parameters.rb +0 -134
  48. data/lib/nugrant/vagrant/v1/command/root.rb +0 -81
  49. data/lib/nugrant/vagrant/v1/config/user.rb +0 -37
  50. data/lib/nugrant/vagrant/v1/plugin.rb +0 -6
  51. data/lib/vagrant_init.rb +0 -2
  52. data/test/resources/Vagrantfile.v1.empty +0 -2
  53. data/test/resources/Vagrantfile.v1.fake +0 -10
  54. data/test/resources/Vagrantfile.v1.real +0 -19
@@ -0,0 +1,30 @@
1
+ require 'nugrant'
2
+ require 'nugrant/bag'
3
+ require 'nugrant/vagrant/v2/config/user'
4
+
5
+ module Nugrant
6
+ module Vagrant
7
+ module V2
8
+ module Command
9
+ class Helper
10
+ def self.get_restricted_keys()
11
+ bag_methods = Nugrant::Bag.instance_methods
12
+ parameters_methods = V2::Config::User.instance_methods
13
+
14
+ (bag_methods | parameters_methods).map(&:to_s)
15
+ end
16
+
17
+ def self.get_used_restricted_keys(hash, restricted_keys)
18
+ keys = []
19
+ hash.each do |key, value|
20
+ keys << key if restricted_keys.include?(key)
21
+ keys += get_used_restricted_keys(value, restricted_keys) if value.kind_of?(Hash)
22
+ end
23
+
24
+ keys.uniq
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,5 +1,6 @@
1
1
  require 'nugrant'
2
2
  require 'nugrant/helper/yaml'
3
+ require 'nugrant/vagrant/v2/command/helper'
3
4
 
4
5
  module Nugrant
5
6
  module Vagrant
@@ -61,7 +62,7 @@ module Nugrant
61
62
  @logger.debug("'Parameters' each target VM...")
62
63
  with_target_vms(arguments) do |vm|
63
64
  config = vm.config.user
64
- parameters = config ? config.parameters : Nugrant::Parameters.new()
65
+ parameters = config || Nugrant::Parameters.new()
65
66
 
66
67
  @env.ui.info("# Vm '#{vm.name}'", :prefix => false)
67
68
 
@@ -110,13 +111,16 @@ module Nugrant
110
111
 
111
112
  print_parameters(kind, {
112
113
  'config' => {
113
- 'user' => bag.__to_hash()
114
+ 'user' => bag.to_hash(:use_string_key => true)
114
115
  }
115
116
  })
116
117
  end
117
118
 
118
- def print_parameters(kind, data)
119
- string = Nugrant::Helper::Yaml.format(data.to_yaml, :indent => 1)
119
+ def print_parameters(kind, hash)
120
+ string = Nugrant::Helper::Yaml.format(hash.to_yaml, :indent => 1)
121
+ used_restricted_keys = Helper::get_used_restricted_keys(hash, Helper::get_restricted_keys())
122
+
123
+ print_warning(used_restricted_keys) if !used_restricted_keys.empty?()
120
124
 
121
125
  print_header(kind)
122
126
  @env.ui.info(string, :prefix => false)
@@ -127,6 +131,14 @@ module Nugrant
127
131
  @env.ui.info(" #{kind.capitalize} Parameters", :prefix => false)
128
132
  @env.ui.info(" " + "-" * length, :prefix => false)
129
133
  end
134
+
135
+ def print_warning(used_restricted_keys)
136
+ @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)
139
+ @env.ui.info(" #{used_restricted_keys.join(", ")}", :prefix => false)
140
+ @env.ui.info("", :prefix => false)
141
+ end
130
142
  end
131
143
  end
132
144
  end
@@ -0,0 +1,60 @@
1
+ require 'nugrant'
2
+ require 'nugrant/vagrant/v2/command/helper'
3
+
4
+ module Nugrant
5
+ module Vagrant
6
+ module V2
7
+ module Command
8
+ class RestrictedKeys < ::Vagrant.plugin("2", :command)
9
+ def initialize(arguments, environment)
10
+ super(arguments, environment)
11
+
12
+ @show_help = false
13
+ end
14
+
15
+ def create_parser()
16
+ return OptionParser.new do |parser|
17
+ parser.banner = "Usage: vagrant user restricted-keys"
18
+ parser.separator ""
19
+
20
+ parser.separator "Available options:"
21
+ parser.separator ""
22
+
23
+ parser.on("-h", "--help", "Print this help") do
24
+ @show_help = true
25
+ end
26
+
27
+ parser.separator ""
28
+ parser.separator "Prints keys that cannot be accessed using the method access syntax\n" +
29
+ "(`config.user.local`). Use array access syntax (`config.user['local']`)\n" +
30
+ "if you really want to use of the restricted keys\n"
31
+ end
32
+ end
33
+
34
+ def execute
35
+ parser = create_parser()
36
+ arguments = parse_options(parser)
37
+
38
+ return help(parser) if @show_help
39
+
40
+ @env.ui.info("The following keys are restricted, i.e. that method access (`config.user.first`)", :prefix => false)
41
+ @env.ui.info("will not work. If you really want to use a restricted key, use array access ", :prefix => false)
42
+ @env.ui.info("instead (`config.user['local']`).", :prefix => false)
43
+ @env.ui.info("", :prefix => false)
44
+
45
+ @env.ui.info("You can run `vagrant user parameters` to check if your config currently defines", :prefix => false)
46
+ @env.ui.info("one or more restricted keys shown below.", :prefix => false)
47
+ @env.ui.info("", :prefix => false)
48
+
49
+ restricted_keys = Helper::get_restricted_keys()
50
+ @env.ui.info(restricted_keys.sort().join(", "), :prefix => false)
51
+ end
52
+
53
+ def help(parser)
54
+ @env.ui.info(parser.help, :prefix => false)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -1,4 +1,7 @@
1
1
  require 'nugrant'
2
+ require 'nugrant/vagrant/v2/command/env'
3
+ require 'nugrant/vagrant/v2/command/parameters'
4
+ require 'nugrant/vagrant/v2/command/restricted_keys'
2
5
  require 'nugrant/version'
3
6
 
4
7
  module Nugrant
@@ -15,9 +18,16 @@ module Nugrant
15
18
  @argv = @arguments
16
19
 
17
20
  @subcommands = ::Vagrant::Registry.new()
21
+ @subcommands.register(:env) do
22
+ Command::Env
23
+ end
24
+
18
25
  @subcommands.register(:parameters) do
19
- require File.expand_path("../parameters", __FILE__)
20
- Parameters
26
+ Command::Parameters
27
+ end
28
+
29
+ @subcommands.register(:'restricted-keys') do
30
+ Command::RestrictedKeys
21
31
  end
22
32
 
23
33
  @show_help = false
@@ -1,35 +1,23 @@
1
1
  require 'nugrant'
2
+ require 'nugrant/mixin/parameters'
3
+ require 'nugrant/vagrant/errors'
2
4
 
3
5
  module Nugrant
4
6
  module Vagrant
5
7
  module V2
6
8
  module Config
7
9
  class User < ::Vagrant.plugin("2", :config)
8
- attr_reader :parameters
10
+ attr_reader :__current, :__user, :__system, :__defaults, :__all
9
11
 
10
12
  def initialize()
11
- @parameters = Nugrant::Parameters.new({:config => {:params_filename => ".vagrantuser"}})
13
+ compute_bags!({:params_filename => ".vagrantuser"}, options = {
14
+ :key_error => Proc.new do |key|
15
+ raise Errors::ParameterNotFoundError, :key => key.to_s
16
+ end
17
+ })
12
18
  end
13
19
 
14
- def [](param_name)
15
- return @parameters[param_name]
16
- end
17
-
18
- def method_missing(method, *args, &block)
19
- return @parameters.method_missing(method, *args, &block)
20
- end
21
-
22
- def each(&block)
23
- @parameters.each(&block)
24
- end
25
-
26
- def defaults(parameters)
27
- @parameters.defaults(parameters)
28
- end
29
-
30
- def defaults=(parameters)
31
- @parameters.defaults=(parameters)
32
- end
20
+ include Mixin::Parameters
33
21
  end
34
22
  end
35
23
  end
@@ -7,7 +7,6 @@ module Nugrant
7
7
 
8
8
  command "user" do
9
9
  require_relative "command/root"
10
-
11
10
  Command::Root
12
11
  end
13
12
 
@@ -1,3 +1,3 @@
1
1
  module Nugrant
2
- VERSION = "2.0.0.dev2"
2
+ VERSION = "2.0.0.pre1"
3
3
  end
data/locales/en.yml ADDED
@@ -0,0 +1,13 @@
1
+ en:
2
+ nugrant:
3
+ vagrant:
4
+ errors:
5
+ parameter_not_found: |-
6
+ Nugrant: Parameter '%{key}' was not found, is it defined in
7
+ your .vagrantuser file? Here where we think the error
8
+ could be in your Vagrantfile:
9
+
10
+ %{context}
11
+
12
+ If you think it should be found, don't hesitate to fill an
13
+ issue @ https://github.com/maoueh/nugrant/issues.
data/nugrant.gemspec CHANGED
@@ -25,13 +25,9 @@ Gem::Specification.new do |gem|
25
25
 
26
26
  gem.files = `git ls-files`.split($/)
27
27
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
28
- gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
28
+ gem.test_files = gem.files.grep(%r{^(test/lib)/})
29
29
  gem.require_paths = ["lib"]
30
30
 
31
- gem.requirements << "json if you plan to use json parameters format"
32
-
33
- gem.add_dependency 'multi_json', '~> 1.7'
34
-
35
- gem.add_development_dependency "rake"
36
- gem.add_development_dependency "json"
31
+ gem.add_dependency "insensitive_hash", "~> 0.3"
32
+ gem.add_dependency "multi_json", "~> 1.8"
37
33
  end
@@ -0,0 +1,238 @@
1
+ require 'minitest/autorun'
2
+
3
+ require 'nugrant/bag'
4
+ require 'nugrant/helper/env/exporter'
5
+
6
+ module Nugrant
7
+ module Helper
8
+ module Env
9
+ class TestExporter < ::Minitest::Test
10
+ def create_bag(parameters)
11
+ return Nugrant::Bag.new(parameters)
12
+ end
13
+
14
+ def assert_export(expected, key, value, options = {})
15
+ actual = Env::Exporter.command(:export, key, value, options)
16
+
17
+ assert_equal(expected, actual)
18
+ end
19
+
20
+ def assert_unset(expected, key, options = {})
21
+ actual = Env::Exporter.command(:unset, key, options)
22
+
23
+ assert_equal(expected, actual)
24
+ end
25
+
26
+ def assert_autoenv_exporter(expected, bag, options = {})
27
+ io = StringIO.new()
28
+ Env::Exporter.autoenv_exporter(bag, options.merge({:io => io}))
29
+
30
+ actual = io.string().split(/\r?\n/)
31
+
32
+ assert_equal(expected, actual)
33
+ end
34
+
35
+ def assert_script_exporter(expected, bag, options = {})
36
+ io = StringIO.new()
37
+ Env::Exporter.script_exporter(bag, options.merge({:io => io}))
38
+
39
+ actual = io.string().split(/\r?\n/)
40
+
41
+ assert_equal(expected, actual)
42
+ end
43
+
44
+ def assert_terminal_exporter(expected, bag, options = {})
45
+ io = StringIO.new()
46
+ Env::Exporter.terminal_exporter(bag, options.merge({:io => io}))
47
+
48
+ actual = io.string().split(/\r?\n/)
49
+
50
+ assert_equal(expected, actual)
51
+ end
52
+
53
+ def assert_unset_commands(expected, bag, options = {})
54
+ actual = Env::Exporter.unset_commands(bag, options)
55
+
56
+ assert_equal(expected, actual)
57
+ end
58
+
59
+ def test_valid_exporter
60
+ assert_equal(true, Env::Exporter.valid?(:autoenv))
61
+ assert_equal(true, Env::Exporter.valid?(:script))
62
+ assert_equal(true, Env::Exporter.valid?(:terminal))
63
+ assert_equal(false, Env::Exporter.valid?(:foreman))
64
+ end
65
+
66
+ def test_export_command
67
+ assert_export("export TEST=\\\"running\\ with\\ space\\\"", "TEST", "\"running with space\"")
68
+ assert_export("export TEST=running with space", "TEST", "running with space", :escape_value => false)
69
+ end
70
+
71
+ def test_unset_command
72
+ assert_unset("unset TEST", "TEST")
73
+ end
74
+
75
+ def test_terminal_exporter_export
76
+ bag = create_bag({
77
+ :level1 => {
78
+ :level2 => {
79
+ :first => "first with space",
80
+ :second => "\"second\\"
81
+ },
82
+ :third => "third"
83
+ },
84
+ :existing => "downcase",
85
+ })
86
+
87
+ stub_env(:existing => "exist", :EXISTING => "exist") do
88
+ assert_terminal_exporter([
89
+ "export EXISTING=downcase",
90
+ "export LEVEL1_LEVEL2_FIRST=first\\ with\\ space",
91
+ "export LEVEL1_LEVEL2_SECOND=\\\"second\\\\",
92
+ "export LEVEL1_THIRD=third",
93
+ ], bag)
94
+
95
+ assert_terminal_exporter([
96
+ "export LEVEL1_LEVEL2_FIRST=first\\ with\\ space",
97
+ "export LEVEL1_LEVEL2_SECOND=\\\"second\\\\",
98
+ "export LEVEL1_THIRD=third",
99
+ ], bag, :override => false)
100
+
101
+ assert_terminal_exporter([
102
+ "export EXISTING=downcase",
103
+ "export LEVEL1_LEVEL2_FIRST=first with space",
104
+ "export LEVEL1_LEVEL2_SECOND=\"second\\",
105
+ "export LEVEL1_THIRD=third",
106
+ ], bag, :type => :export, :override => true, :escape_value => false)
107
+
108
+ default_namer = Env::Namer.default(".")
109
+ prefix_namer = Env::Namer.prefix("CONFIG", default_namer)
110
+
111
+ assert_terminal_exporter([
112
+ "export CONFIG.EXISTING=downcase",
113
+ "export CONFIG.LEVEL1.LEVEL2.FIRST=first with space",
114
+ "export CONFIG.LEVEL1.LEVEL2.SECOND=\"second\\",
115
+ "export CONFIG.LEVEL1.THIRD=third",
116
+ ], bag, :override => true, :escape_value => false, :namer => prefix_namer)
117
+ end
118
+ end
119
+
120
+ def test_terminal_exporter_unset
121
+ bag = create_bag({
122
+ :level1 => {
123
+ :level2 => {
124
+ :first => "first",
125
+ :second => "second"
126
+ },
127
+ :third => "third"
128
+ },
129
+ :existing => "downcase",
130
+ })
131
+
132
+ stub_env(:existing => "exist", :EXISTING => "exist") do
133
+ assert_terminal_exporter([
134
+ "unset EXISTING",
135
+ "unset LEVEL1_LEVEL2_FIRST",
136
+ "unset LEVEL1_LEVEL2_SECOND",
137
+ "unset LEVEL1_THIRD",
138
+ ], bag, :type => :unset)
139
+
140
+ assert_terminal_exporter([
141
+ "unset LEVEL1_LEVEL2_FIRST",
142
+ "unset LEVEL1_LEVEL2_SECOND",
143
+ "unset LEVEL1_THIRD",
144
+ ], bag, :override => false, :type => :unset)
145
+
146
+ default_namer = Env::Namer.default(".")
147
+ prefix_namer = Env::Namer.prefix("CONFIG", default_namer)
148
+
149
+ assert_terminal_exporter([
150
+ "unset CONFIG.EXISTING",
151
+ "unset CONFIG.LEVEL1.LEVEL2.FIRST",
152
+ "unset CONFIG.LEVEL1.LEVEL2.SECOND",
153
+ "unset CONFIG.LEVEL1.THIRD",
154
+ ], bag, :override => true, :namer => prefix_namer, :type => :unset)
155
+ end
156
+ end
157
+
158
+ def test_autoenv_exporter
159
+ bag = create_bag({
160
+ :level1 => {
161
+ :level2 => {
162
+ :first => "first",
163
+ :second => "second"
164
+ },
165
+ :third => "third"
166
+ },
167
+ :existing => "downcase",
168
+ })
169
+
170
+ assert_autoenv_exporter([
171
+ "export EXISTING=downcase",
172
+ "export LEVEL1_LEVEL2_FIRST=first",
173
+ "export LEVEL1_LEVEL2_SECOND=second",
174
+ "export LEVEL1_THIRD=third",
175
+ ], bag, :type => :export)
176
+
177
+ assert_autoenv_exporter([
178
+ "unset EXISTING",
179
+ "unset LEVEL1_LEVEL2_FIRST",
180
+ "unset LEVEL1_LEVEL2_SECOND",
181
+ "unset LEVEL1_THIRD",
182
+ ], bag, :type => :unset)
183
+ end
184
+
185
+ def test_script_exporter
186
+ bag = create_bag({
187
+ :level1 => {
188
+ :level2 => {
189
+ :first => "first",
190
+ :second => "second"
191
+ },
192
+ :third => "third"
193
+ },
194
+ :existing => "downcase",
195
+ })
196
+
197
+ assert_script_exporter([
198
+ "#!/bin/env sh",
199
+ "",
200
+ "export EXISTING=downcase",
201
+ "export LEVEL1_LEVEL2_FIRST=first",
202
+ "export LEVEL1_LEVEL2_SECOND=second",
203
+ "export LEVEL1_THIRD=third",
204
+ ], bag, :type => :export)
205
+
206
+ assert_script_exporter([
207
+ "#!/bin/env sh",
208
+ "",
209
+ "unset EXISTING",
210
+ "unset LEVEL1_LEVEL2_FIRST",
211
+ "unset LEVEL1_LEVEL2_SECOND",
212
+ "unset LEVEL1_THIRD",
213
+ ], bag, :type => :unset)
214
+ end
215
+
216
+ def replace_env(variables)
217
+ ENV.clear()
218
+
219
+ variables = Hash[variables.map do |name, value|
220
+ [name.to_s, value]
221
+ end]
222
+
223
+ ENV.update(variables)
224
+ end
225
+
226
+ def stub_env(new = {})
227
+ old = ENV.to_hash()
228
+
229
+ replace_env(new)
230
+ yield
231
+
232
+ ensure
233
+ replace_env(old)
234
+ end
235
+ end
236
+ end
237
+ end
238
+ end