aruba 1.0.0.pre.alpha.2 → 1.0.1

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 (135) hide show
  1. checksums.yaml +5 -5
  2. data/.github/PULL_REQUEST_TEMPLATE.md +2 -1
  3. data/.rspec +0 -1
  4. data/.rubocop.yml +46 -182
  5. data/.rubocop_todo.yml +216 -0
  6. data/.simplecov +7 -5
  7. data/.travis.yml +56 -40
  8. data/.yardopts +3 -0
  9. data/CHANGELOG.md +1312 -0
  10. data/CONTRIBUTING.md +175 -83
  11. data/Gemfile +5 -69
  12. data/LICENSE +1 -1
  13. data/README.md +58 -21
  14. data/Rakefile +27 -54
  15. data/appveyor.yml +7 -10
  16. data/aruba.gemspec +38 -19
  17. data/bin/console +3 -12
  18. data/cucumber.yml +4 -22
  19. data/exe/aruba +1 -1
  20. data/fixtures/cli-app/README.md +1 -1
  21. data/fixtures/cli-app/Rakefile +1 -1
  22. data/fixtures/cli-app/bin/aruba-test-cli +1 -1
  23. data/fixtures/cli-app/cli-app.gemspec +4 -4
  24. data/fixtures/cli-app/lib/cli/app.rb +1 -1
  25. data/fixtures/cli-app/lib/cli/app/suppress_simple_cov_output.rb +3 -3
  26. data/fixtures/cli-app/lib/cli/app/version.rb +1 -1
  27. data/fixtures/cli-app/spec/spec_helper.rb +3 -2
  28. data/fixtures/empty-app/Rakefile +1 -1
  29. data/fixtures/empty-app/cli-app.gemspec +4 -4
  30. data/fixtures/empty-app/lib/cli/app.rb +0 -2
  31. data/fixtures/empty-app/lib/cli/app/version.rb +1 -1
  32. data/fixtures/getting-started-app/Gemfile +1 -1
  33. data/lib/aruba/api.rb +8 -15
  34. data/lib/aruba/api/bundler.rb +16 -0
  35. data/lib/aruba/api/commands.rb +272 -0
  36. data/lib/aruba/api/core.rb +82 -43
  37. data/lib/aruba/api/environment.rb +24 -7
  38. data/lib/aruba/api/filesystem.rb +66 -64
  39. data/lib/aruba/api/text.rb +17 -11
  40. data/lib/aruba/aruba_path.rb +25 -111
  41. data/lib/aruba/basic_configuration.rb +8 -25
  42. data/lib/aruba/basic_configuration/option.rb +2 -2
  43. data/lib/aruba/cli.rb +4 -1
  44. data/lib/aruba/colorizer.rb +10 -99
  45. data/lib/aruba/command.rb +4 -0
  46. data/lib/aruba/config/jruby.rb +15 -5
  47. data/lib/aruba/config_wrapper.rb +17 -2
  48. data/lib/aruba/configuration.rb +107 -0
  49. data/lib/aruba/console.rb +5 -7
  50. data/lib/aruba/console/help.rb +5 -2
  51. data/lib/aruba/contracts/absolute_path.rb +3 -3
  52. data/lib/aruba/contracts/is_power_of_two.rb +2 -2
  53. data/lib/aruba/contracts/relative_path.rb +3 -3
  54. data/lib/aruba/cucumber.rb +0 -3
  55. data/lib/aruba/cucumber/command.rb +227 -190
  56. data/lib/aruba/cucumber/environment.rb +1 -1
  57. data/lib/aruba/cucumber/file.rb +56 -50
  58. data/lib/aruba/cucumber/hooks.rb +10 -63
  59. data/lib/aruba/cucumber/testing_frameworks.rb +76 -50
  60. data/lib/aruba/event_bus.rb +4 -2
  61. data/lib/aruba/event_bus/name_resolver.rb +10 -10
  62. data/lib/aruba/events.rb +2 -1
  63. data/lib/aruba/hooks.rb +3 -5
  64. data/lib/aruba/in_config_wrapper.rb +10 -3
  65. data/lib/aruba/initializer.rb +40 -34
  66. data/lib/aruba/matchers/base/base_matcher.rb +2 -11
  67. data/lib/aruba/matchers/base/message_indenter.rb +19 -0
  68. data/lib/aruba/matchers/base/object_formatter.rb +2 -7
  69. data/lib/aruba/matchers/collection/include_an_object.rb +11 -13
  70. data/lib/aruba/matchers/command/be_successfully_executed.rb +8 -4
  71. data/lib/aruba/matchers/command/have_exit_status.rb +16 -4
  72. data/lib/aruba/matchers/command/have_finished_in_time.rb +5 -5
  73. data/lib/aruba/matchers/command/have_output.rb +12 -5
  74. data/lib/aruba/matchers/command/have_output_on_stderr.rb +4 -2
  75. data/lib/aruba/matchers/command/have_output_on_stdout.rb +4 -2
  76. data/lib/aruba/matchers/command/have_output_size.rb +2 -2
  77. data/lib/aruba/matchers/directory/be_an_existing_directory.rb +5 -7
  78. data/lib/aruba/matchers/directory/have_sub_directory.rb +10 -7
  79. data/lib/aruba/matchers/file/be_a_command_found_in_path.rb +2 -4
  80. data/lib/aruba/matchers/file/be_an_existing_executable.rb +4 -6
  81. data/lib/aruba/matchers/file/be_an_existing_file.rb +5 -7
  82. data/lib/aruba/matchers/file/have_file_content.rb +4 -4
  83. data/lib/aruba/matchers/file/have_file_size.rb +8 -8
  84. data/lib/aruba/matchers/file/have_same_file_content.rb +9 -12
  85. data/lib/aruba/matchers/path/a_path_matching_pattern.rb +2 -4
  86. data/lib/aruba/matchers/path/be_an_absolute_path.rb +3 -5
  87. data/lib/aruba/matchers/path/be_an_existing_path.rb +4 -6
  88. data/lib/aruba/matchers/path/have_permissions.rb +8 -8
  89. data/lib/aruba/matchers/string/include_output_string.rb +8 -10
  90. data/lib/aruba/matchers/string/match_output_string.rb +9 -11
  91. data/lib/aruba/matchers/string/output_string_eq.rb +7 -9
  92. data/lib/aruba/platform.rb +0 -8
  93. data/lib/aruba/platforms/announcer.rb +60 -85
  94. data/lib/aruba/platforms/aruba_file_creator.rb +4 -2
  95. data/lib/aruba/platforms/aruba_fixed_size_file_creator.rb +8 -3
  96. data/lib/aruba/platforms/aruba_logger.rb +22 -2
  97. data/lib/aruba/platforms/command_monitor.rb +15 -102
  98. data/lib/aruba/platforms/determine_disk_usage.rb +56 -19
  99. data/lib/aruba/platforms/filesystem_status.rb +9 -9
  100. data/lib/aruba/platforms/local_environment.rb +2 -2
  101. data/lib/aruba/platforms/simple_table.rb +3 -11
  102. data/lib/aruba/platforms/unix_command_string.rb +7 -4
  103. data/lib/aruba/platforms/unix_environment_variables.rb +19 -26
  104. data/lib/aruba/platforms/unix_platform.rb +18 -39
  105. data/lib/aruba/platforms/unix_which.rb +3 -2
  106. data/lib/aruba/platforms/windows_command_string.rb +20 -7
  107. data/lib/aruba/platforms/windows_environment_variables.rb +42 -30
  108. data/lib/aruba/platforms/windows_platform.rb +4 -0
  109. data/lib/aruba/platforms/windows_which.rb +9 -4
  110. data/lib/aruba/processes/basic_process.rb +21 -27
  111. data/lib/aruba/processes/debug_process.rb +16 -5
  112. data/lib/aruba/processes/in_process.rb +20 -9
  113. data/lib/aruba/processes/spawn_process.rb +64 -36
  114. data/lib/aruba/rspec.rb +28 -31
  115. data/lib/aruba/runtime.rb +16 -7
  116. data/lib/aruba/setup.rb +32 -17
  117. data/lib/aruba/tasks/docker_helpers.rb +4 -2
  118. data/lib/aruba/version.rb +1 -1
  119. metadata +194 -64
  120. data/History.md +0 -612
  121. data/bin/bootstrap +0 -34
  122. data/bin/build +0 -3
  123. data/bin/release +0 -3
  124. data/fixtures/spawn_process/stderr.sh +0 -3
  125. data/lib/aruba/api/command.rb +0 -309
  126. data/lib/aruba/api/deprecated.rb +0 -895
  127. data/lib/aruba/api/rvm.rb +0 -44
  128. data/lib/aruba/config.rb +0 -101
  129. data/lib/aruba/cucumber/rvm.rb +0 -3
  130. data/lib/aruba/in_process.rb +0 -14
  131. data/lib/aruba/jruby.rb +0 -4
  132. data/lib/aruba/matchers/path/match_path_pattern.rb +0 -41
  133. data/lib/aruba/matchers/rspec_matcher_include_regexp.rb +0 -25
  134. data/lib/aruba/platforms/disk_usage_calculator.rb +0 -20
  135. data/lib/aruba/spawn_process.rb +0 -11
@@ -19,14 +19,19 @@ module Aruba
19
19
  # @param [Numeric] size
20
20
  # The size of the file
21
21
  #
22
- # @param [TrueClass, FalseClass] check_presence (false)
22
+ # @param [Boolean] check_presence (false)
23
23
  # Check if file exist
24
24
  def call(path, size, check_presence)
25
- fail "Expected #{path} to be present" if check_presence && !Aruba.platform.file?(path)
25
+ if check_presence && !Aruba.platform.file?(path)
26
+ raise "Expected #{path} to be present"
27
+ end
26
28
 
27
29
  Aruba.platform.mkdir(File.dirname(path))
28
30
 
29
- File.open(path, "wb"){ |f| f.seek(size - 1); f.write("\0") }
31
+ File.open(path, 'wb') do |f|
32
+ f.seek(size - 1)
33
+ f.write("\0")
34
+ end
30
35
 
31
36
  self
32
37
  end
@@ -10,12 +10,32 @@ module Aruba
10
10
 
11
11
  # Create logger
12
12
  #
13
- # @param [Logger] logger (::Logger.new( $stderr ))
14
- # The logger with should be used to output data
13
+ # @param [Hash] opts
14
+ # Options
15
+ #
16
+ # @option opts [Symbol] :default_mode Log level
15
17
  def initialize(opts = {})
16
18
  @mode = opts.fetch(:default_mode, :info)
17
19
  end
18
20
 
21
+ # @!method fatal(msg)
22
+ # Log a fatal level log message
23
+
24
+ # @!method warn(msg)
25
+ # Log a warn level log message
26
+
27
+ # @!method debug(msg)
28
+ # Log a debug level log message
29
+
30
+ # @!method info(msg)
31
+ # Log an info level log message
32
+
33
+ # @!method error(msg)
34
+ # Log an error level log message
35
+
36
+ # @!method unknown(msg)
37
+ # Log an unknown level log message
38
+
19
39
  [:fatal, :warn, :debug, :info, :error, :unknown].each do |m|
20
40
  define_method m do |msg|
21
41
  logger.public_send m, msg
@@ -20,7 +20,11 @@ module Aruba
20
20
  end
21
21
 
22
22
  def method_missing(*)
23
- fail NoCommandHasBeenStoppedError, 'No last command stopped available'
23
+ raise NoCommandHasBeenStoppedError, 'No last command stopped available'
24
+ end
25
+
26
+ def respond_to_missing?(*)
27
+ true
24
28
  end
25
29
  end
26
30
 
@@ -30,7 +34,11 @@ module Aruba
30
34
  end
31
35
 
32
36
  def method_missing(*)
33
- fail NoCommandHasBeenStartedError, 'No last command started available'
37
+ raise NoCommandHasBeenStartedError, 'No last command started available'
38
+ end
39
+
40
+ def respond_to_missing?(*)
41
+ true
34
42
  end
35
43
  end
36
44
 
@@ -40,23 +48,11 @@ module Aruba
40
48
 
41
49
  @last_command_stopped = DefaultLastCommandStopped.new
42
50
  @last_command_started = DefaultLastCommandStarted.new
43
-
44
51
  rescue KeyError => e
45
52
  raise ArgumentError, e.message
46
53
  end
47
54
 
48
- if Aruba::VERSION < '1'
49
- # Return the last command stopped
50
- def last_command_stopped
51
- return @last_command_stopped unless @last_command_stopped.nil?
52
-
53
- registered_commands.each(&:stop)
54
-
55
- @last_command_stopped
56
- end
57
- else
58
- attr_reader :last_command_stopped
59
- end
55
+ attr_reader :last_command_stopped
60
56
 
61
57
  # Set last command started
62
58
  #
@@ -66,7 +62,7 @@ module Aruba
66
62
  @last_command_started = find(cmd)
67
63
  end
68
64
 
69
- # Set last command started
65
+ # Set last command stopped
70
66
  #
71
67
  # @param [String] cmd
72
68
  # The commandline of the command
@@ -82,7 +78,7 @@ module Aruba
82
78
  cmd = cmd.commandline if cmd.respond_to? :commandline
83
79
  command = registered_commands.reverse.find { |c| c.commandline == cmd }
84
80
 
85
- fail CommandNotFoundError, "No command named '#{cmd}' has been started" if command.nil?
81
+ raise CommandNotFoundError, "No command named '#{cmd}' has been started" if command.nil?
86
82
 
87
83
  command
88
84
  end
@@ -95,37 +91,6 @@ module Aruba
95
91
  self
96
92
  end
97
93
 
98
- # @deprecated
99
- # Fetch output (stdout, stderr) from command
100
- #
101
- # @param [String] cmd
102
- # The command
103
- def output_from(cmd)
104
- cmd = Aruba.platform.detect_ruby(cmd)
105
- find(cmd).output
106
- end
107
-
108
- # @deprecated
109
- # Fetch stdout from command
110
- #
111
- # @param [String] cmd
112
- # The command
113
- def stdout_from(cmd)
114
- cmd = Aruba.platform.detect_ruby(cmd)
115
- find(cmd).stdout
116
- end
117
-
118
- # @deprecated
119
- # Fetch stderr from command
120
- #
121
- # @param [String] cmd
122
- # The command
123
- def stderr_from(cmd)
124
- cmd = Aruba.platform.detect_ruby(cmd)
125
- find(cmd).stderr
126
- end
127
-
128
- # @deprecated
129
94
  # Get stdout of all commands
130
95
  #
131
96
  # @return [String]
@@ -133,10 +98,9 @@ module Aruba
133
98
  def all_stdout
134
99
  registered_commands.each(&:stop)
135
100
 
136
- registered_commands.each_with_object("".dup) { |e, a| a << e.stdout }
101
+ registered_commands.each_with_object('') { |e, a| a << e.stdout }
137
102
  end
138
103
 
139
- # @deprecated
140
104
  # Get stderr of all commands
141
105
  #
142
106
  # @return [String]
@@ -144,10 +108,9 @@ module Aruba
144
108
  def all_stderr
145
109
  registered_commands.each(&:stop)
146
110
 
147
- registered_commands.each_with_object("".dup) { |e, a| a << e.stderr }
111
+ registered_commands.each_with_object('') { |e, a| a << e.stderr }
148
112
  end
149
113
 
150
- # @deprecated
151
114
  # Get stderr and stdout of all commands
152
115
  #
153
116
  # @return [String]
@@ -156,56 +119,6 @@ module Aruba
156
119
  all_stdout << all_stderr
157
120
  end
158
121
 
159
- # @deprecated
160
- def last_exit_status
161
- Aruba.platform.deprecated('The use of "#last_exit_status" is deprecated. Use "last_command_(started|stopped).exit_status" instead')
162
-
163
- return @last_exit_status if @last_exit_status
164
- registered_commands.each(&:stop)
165
- @last_exit_status
166
- end
167
-
168
- # @deprecated
169
- def stop_process(process)
170
- @last_command_stopped = process
171
- @last_exit_status = process.stop(announcer)
172
- end
173
-
174
- # @deprecated
175
- def terminate_process!(process)
176
- process.terminate
177
- end
178
-
179
- # @deprecated
180
- def stop_processes!
181
- Aruba.platform.deprecated('The use of "#stop_processes!" is deprecated.')
182
-
183
- registered_commands.each(&:stop)
184
- end
185
-
186
- # @deprecated
187
- # Terminate all running processes
188
- def terminate_processes
189
- Aruba.platform.deprecated('The use of "#terminate_processes" is deprecated.')
190
-
191
- registered_commands.each(&:terminate)
192
- end
193
-
194
- # @deprecated
195
- def only_processes
196
- Aruba.platform.deprecated('The use of "#only_processes" is deprecated.')
197
-
198
- registered_commands
199
- end
200
-
201
- # @deprecated
202
- def get_process(wanted)
203
- command = find(wanted)
204
- raise ArgumentError.new("No process named '#{wanted}' has been started") unless command
205
-
206
- command
207
- end
208
-
209
122
  # Register command to monitor
210
123
  def register_command(cmd)
211
124
  registered_commands << cmd
@@ -1,33 +1,70 @@
1
- require 'aruba/platforms/disk_usage_calculator'
1
+ require 'aruba/file_size'
2
2
 
3
- # Aruba
4
3
  module Aruba
5
- # Platforms
6
4
  module Platforms
7
5
  # Determinate disk usage
8
6
  #
9
7
  # @private
10
8
  class DetermineDiskUsage
11
- def call(*args)
12
- args = args.flatten
13
-
14
- deprecated_block_size = args.pop
15
- paths = args
16
-
17
- size = paths.flatten.map do |p|
18
- # TODO: replace the `call` methods signature so that you can use just
19
- # p.minimum_disk_space_used
20
- #
21
- # (Same result, since the values are multiplied, so
22
- # deprecated_block_size is canceled out
23
- DiskUsageCalculator.new.call(
24
- (p.minimum_disk_space_used / deprecated_block_size),
25
- deprecated_block_size
26
- )
9
+ def call(paths)
10
+ size = paths.flatten.map do |path|
11
+ minimum_disk_space_used path
27
12
  end.inject(0, &:+)
28
13
 
29
14
  FileSize.new(size)
30
15
  end
16
+
17
+ private
18
+
19
+ # TODO: Aruba.config.physical_block_size could be allowed to be nil
20
+ # (So the unit size can be autodetected)
21
+
22
+ # Report minimum disk space used
23
+ #
24
+ # This estimates the minimum bytes allocated by the path.
25
+ #
26
+ # E.g. a 1-byte text file on a typical EXT-3 filesystem takes up 4096 bytes
27
+ # (could be more if it was truncated or less for sparse files).
28
+ #
29
+ # Both `File::Stat` and the `stat()` system call will report 8 `blocks`
30
+ # (each "usually" represents 512 bytes). So 8 * 512 is exactly 4096 bytes.
31
+ #
32
+ # (The "magic" 512 bye implied makes the value of "blocks" so confusing).
33
+ #
34
+ # Currently Aruba allows you to set what's called the `physical_block_size`,
35
+ # which is a bit misleading - it's the "512" value. So if you somehow have a
36
+ # "filesystem unit size" of 8192 (instead of a typical 4KB), set the
37
+ # `physical_block_size` to 1024 (yes, divide by 8: 8192/8 = 1024).
38
+ #
39
+ # Ideally, Aruba should provide e.g. `Aruba.config.fs_allocation_unit`
40
+ # (with 4096 as the default), so you wouldn't have to "divide by 8".
41
+ #
42
+ # (typical_fs_unit / typical_dev_bsize = 4096 / 512 = 8)
43
+ #
44
+ #
45
+ # @return [Integer]
46
+ # Total bytes allocate
47
+ #
48
+ # TODO: this is recommended over the above "blocks"
49
+ def minimum_disk_space_used(path)
50
+ # TODO: replace Aruba.config.physical_block_size
51
+ # with something like Aruba.config.fs_allocation_unit
52
+ dev_bsize = Aruba.config.physical_block_size
53
+
54
+ stat = File::Stat.new(path.to_s)
55
+
56
+ blocks = stat.blocks
57
+ return (blocks * dev_bsize) if blocks
58
+
59
+ typical_fs_unit = 4096
60
+ typical_dev_bsize = 512 # google dev_bsize for more info
61
+
62
+ block_multiplier = typical_fs_unit / typical_dev_bsize
63
+ fs_unit_size = dev_bsize * block_multiplier
64
+ fs_units = (stat.size + fs_unit_size - 1) / fs_unit_size
65
+ fs_units = 1 if fs_units.zero?
66
+ fs_units * fs_unit_size
67
+ end
31
68
  end
32
69
  end
33
70
  end
@@ -30,7 +30,7 @@ module Aruba
30
30
 
31
31
  # Return permissions
32
32
  def mode
33
- format("%o", status.mode)[-4,4].gsub(/^0*/, '')
33
+ format('%o', status.mode)[-4, 4].gsub(/^0*/, '')
34
34
  end
35
35
 
36
36
  # Return owner
@@ -49,14 +49,14 @@ module Aruba
49
49
  # A hash of values
50
50
  def to_h
51
51
  {
52
- :owner => owner,
53
- :group => group,
54
- :mode => mode,
55
- :executable => executable?,
56
- :ctime => ctime,
57
- :atime => atime,
58
- :mtime => mtime,
59
- :size => size
52
+ owner: owner,
53
+ group: group,
54
+ mode: mode,
55
+ executable: executable?,
56
+ ctime: ctime,
57
+ atime: atime,
58
+ mtime: mtime,
59
+ size: size
60
60
  }
61
61
  end
62
62
  end
@@ -13,8 +13,8 @@ module Aruba
13
13
  #
14
14
  # @yield
15
15
  # The block of code which should with local ENV
16
- def call(env, &block)
17
- old_env = ENV.to_hash.dup
16
+ def call(env)
17
+ old_env = Aruba.platform.environment_variables.hash_from_env
18
18
 
19
19
  ENV.clear
20
20
  ENV.update env
@@ -17,7 +17,7 @@ module Aruba
17
17
  def initialize(hash, opts)
18
18
  @hash = hash
19
19
  @opts = {
20
- :sort => true
20
+ sort: true
21
21
  }.merge opts
22
22
  end
23
23
 
@@ -31,16 +31,8 @@ module Aruba
31
31
 
32
32
  name_size = longest_key.length
33
33
 
34
- if RUBY_VERSION < '2'
35
- rows = []
36
-
37
- hash.each do |k,v|
38
- rows << format("# %-#{name_size}s => %s", k, v)
39
- end
40
- else
41
- rows = hash.each_with_object([]) do |(k,v), a|
42
- a << format("# %-#{name_size}s => %s", k, v)
43
- end
34
+ rows = hash.each_with_object([]) do |(k, v), a|
35
+ a << format("# %-#{name_size}s => %s", k, v)
44
36
  end
45
37
 
46
38
  if opts[:sort] == true
@@ -6,14 +6,17 @@ module Aruba
6
6
  # Platforms
7
7
  module Platforms
8
8
  # This is a command which should be run
9
- class UnixCommandString < SimpleDelegator
10
- def initialize(cmd)
11
- __setobj__ cmd
9
+ #
10
+ # @private
11
+ class UnixCommandString
12
+ def initialize(command, *arguments)
13
+ @command = command
14
+ @arguments = arguments
12
15
  end
13
16
 
14
17
  # Convert to array
15
18
  def to_a
16
- Shellwords.split __getobj__
19
+ [@command, *@arguments]
17
20
  end
18
21
  end
19
22
  end
@@ -9,15 +9,9 @@ module Aruba
9
9
  attr_reader :other_env, :block
10
10
 
11
11
  def initialize(other_env, &block)
12
- @other_env = other_env
12
+ @other_env = other_env.to_h.transform_values(&:to_s)
13
13
 
14
- to_hash = RUBY_VERSION >= '2' ? :to_h : :to_hash
15
-
16
- @other_env = @other_env.public_send(to_hash).each_with_object({}) { |(k, v), a| a[k] = v.to_s }
17
-
18
- @block = if block_given?
19
- block
20
- end
14
+ @block = (block if block_given?)
21
15
  end
22
16
 
23
17
  def call(env)
@@ -56,11 +50,7 @@ module Aruba
56
50
  def initialize(env = ENV)
57
51
  @actions = []
58
52
 
59
- @env = if RUBY_VERSION < '2.0'
60
- env.to_hash
61
- else
62
- env.to_h
63
- end
53
+ @env = env.to_h
64
54
  end
65
55
 
66
56
  # Update environment with other en
@@ -73,7 +63,7 @@ module Aruba
73
63
  def update(other_env)
74
64
  actions << UpdateAction.new(other_env)
75
65
 
76
- UnixEnvironmentVariables.new(to_h)
66
+ self
77
67
  end
78
68
 
79
69
  # Fetch variable from environment
@@ -133,7 +123,7 @@ module Aruba
133
123
  name = name.to_s
134
124
  value = self[name].to_s + value.to_s
135
125
 
136
- actions << UpdateAction.new(name => value )
126
+ actions << UpdateAction.new(name => value)
137
127
 
138
128
  value
139
129
  end
@@ -184,11 +174,7 @@ module Aruba
184
174
  # @return [Hash]
185
175
  # A new hash from environment
186
176
  def to_h
187
- if RUBY_VERSION < '2.0'
188
- Marshal.load(Marshal.dump(prepared_environment.to_hash))
189
- else
190
- Marshal.load(Marshal.dump(prepared_environment.to_h))
191
- end
177
+ actions.inject(hash_from_env.merge(env)) { |a, e| e.call(a) }
192
178
  end
193
179
 
194
180
  # Reset environment
@@ -200,14 +186,21 @@ module Aruba
200
186
  value
201
187
  end
202
188
 
189
+ def nest
190
+ old_actions = @actions.dup
191
+ yield(self)
192
+ ensure
193
+ @actions = old_actions
194
+ end
195
+
196
+ def self.hash_from_env
197
+ ENV.to_hash
198
+ end
199
+
203
200
  private
204
201
 
205
- def prepared_environment
206
- if RUBY_VERSION == '1.9.3'
207
- actions.inject(ENV.to_hash.merge(env)) { |a, e| e.call(a) }
208
- else
209
- actions.each_with_object(ENV.to_hash.merge(env)) { |e, a| a = e.call(a) }
210
- end
202
+ def hash_from_env
203
+ self.class.hash_from_env
211
204
  end
212
205
  end
213
206
  end