aruba 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +5 -1
  3. data/History.md +75 -55
  4. data/Rakefile +1 -1
  5. data/aruba.gemspec +0 -1
  6. data/features/api/command/run_simple.feature +37 -2
  7. data/features/api/command/stderr.feature +46 -0
  8. data/features/api/command/stdout.feature +46 -0
  9. data/features/configuration/activate_announcer_on_command_failure.feature +38 -0
  10. data/features/steps/command/run.feature +28 -0
  11. data/features/steps/command/shell.feature +155 -0
  12. data/features/steps/core/announce.feature +80 -0
  13. data/features/support/aruba.rb +3 -2
  14. data/lib/aruba/api/command.rb +7 -10
  15. data/lib/aruba/colorizer.rb +108 -0
  16. data/lib/aruba/config.rb +4 -2
  17. data/lib/aruba/cucumber/command.rb +12 -0
  18. data/lib/aruba/cucumber/hooks.rb +10 -0
  19. data/lib/aruba/errors.rb +6 -0
  20. data/lib/aruba/event_bus.rb +59 -0
  21. data/lib/aruba/event_bus/name_resolver.rb +168 -0
  22. data/lib/aruba/generators/script_file.rb +46 -0
  23. data/lib/aruba/matchers/path/have_permissions.rb +1 -1
  24. data/lib/aruba/platforms/announcer.rb +30 -23
  25. data/lib/aruba/platforms/filesystem_status.rb +68 -0
  26. data/lib/aruba/platforms/simple_table.rb +14 -7
  27. data/lib/aruba/platforms/unix_platform.rb +11 -2
  28. data/lib/aruba/platforms/unix_which.rb +0 -2
  29. data/lib/aruba/platforms/windows_which.rb +0 -2
  30. data/lib/aruba/processes/basic_process.rb +8 -0
  31. data/lib/aruba/processes/spawn_process.rb +31 -12
  32. data/lib/aruba/rspec.rb +12 -8
  33. data/lib/aruba/runtime.rb +2 -2
  34. data/lib/aruba/setup.rb +5 -2
  35. data/lib/aruba/version.rb +1 -1
  36. data/script/bootstrap +8 -0
  37. data/spec/aruba/api_spec.rb +1 -1
  38. data/spec/aruba/platform/simple_table_spec.rb +2 -2
  39. data/spec/event_bus/name_resolver_spec.rb +68 -0
  40. data/spec/event_bus_spec.rb +160 -0
  41. data/spec/spec_helper.rb +0 -3
  42. data/spec/support/configs/aruba.rb +5 -0
  43. metadata +22 -17
@@ -0,0 +1,46 @@
1
+ # Aruba
2
+ module Aruba
3
+ # Generate script files on command line
4
+ class ScriptFile
5
+ private
6
+
7
+ attr_reader :path, :content, :interpreter
8
+
9
+ public
10
+
11
+ def initialize(opts = {})
12
+ @path = opts[:path]
13
+ @content = opts[:content]
14
+ @interpreter = opts[:interpreter]
15
+ end
16
+
17
+ def call
18
+ Aruba.platform.write_file(path, "#{header}#{content}")
19
+ Aruba.platform.chmod(0755, path, {})
20
+ end
21
+
22
+ private
23
+
24
+ def header
25
+ if script_starts_with_shebang?
26
+ ''
27
+ elsif interpreter_is_absolute_path?
28
+ format("#!%s\n", interpreter)
29
+ elsif interpreter_is_just_the_name_of_shell?
30
+ format("#!/usr/bin/env %s\n", interpreter)
31
+ end
32
+ end
33
+
34
+ def interpreter_is_absolute_path?
35
+ Aruba.platform.absolute_path? interpreter
36
+ end
37
+
38
+ def interpreter_is_just_the_name_of_shell?
39
+ interpreter =~ /^[-_a-zA-Z.]+$/
40
+ end
41
+
42
+ def script_starts_with_shebang?
43
+ content.start_with? '#!'
44
+ end
45
+ end
46
+ end
@@ -30,7 +30,7 @@ require 'rspec/expectations/version'
30
30
  # end
31
31
  RSpec::Matchers.define :have_permissions do |expected|
32
32
  def permissions(file)
33
- @actual = format("%o", File::Stat.new(file).mode)[-4,4].gsub(/^0*/, '')
33
+ @actual = Aruba.platform.filesystem_status.new(file).mode
34
34
  end
35
35
 
36
36
  match do |actual|
@@ -1,4 +1,7 @@
1
1
  require 'shellwords'
2
+ require 'aruba/colorizer'
3
+
4
+ Aruba::AnsiColor.coloring = false if !STDOUT.tty? && !ENV.key?("AUTOTEST")
2
5
 
3
6
  # Aruba
4
7
  module Aruba
@@ -24,17 +27,6 @@ module Aruba
24
27
  # Aruba.announcer.announce(:my_channel, 'my message')
25
28
  #
26
29
  class Announcer
27
- # Dev null
28
- class NullAnnouncer
29
- def announce(*)
30
- nil
31
- end
32
-
33
- def mode?(*)
34
- true
35
- end
36
- end
37
-
38
30
  # Announcer using Kernel.puts
39
31
  class KernelPutsAnnouncer
40
32
  def announce(message)
@@ -49,7 +41,7 @@ module Aruba
49
41
  # Announcer using Main#puts
50
42
  class PutsAnnouncer
51
43
  def announce(message)
52
- Kernel.puts message
44
+ puts message
53
45
  end
54
46
 
55
47
  def mode?(m)
@@ -59,7 +51,7 @@ module Aruba
59
51
 
60
52
  private
61
53
 
62
- attr_reader :announcers, :default_announcer, :announcer, :channels, :output_formats
54
+ attr_reader :announcers, :announcer, :channels, :output_formats, :colorizer
63
55
 
64
56
  public
65
57
 
@@ -67,9 +59,9 @@ module Aruba
67
59
  @announcers = []
68
60
  @announcers << PutsAnnouncer.new
69
61
  @announcers << KernelPutsAnnouncer.new
70
- @announcers << NullAnnouncer.new
71
62
 
72
- @default_announcer = @announcers.last
63
+ @colorizer = Aruba::Colorizer.new
64
+
73
65
  @announcer = @announcers.first
74
66
  @channels = {}
75
67
  @output_formats = {}
@@ -88,13 +80,17 @@ module Aruba
88
80
  output_format :command, '$ %s'
89
81
  output_format :directory, '$ cd %s'
90
82
  output_format :environment, proc { |n, v| format('$ export %s=%s', n, Shellwords.escape(v)) }
91
- output_format :full_environment, proc { |h| Aruba.platform.simple_table(h) }
83
+ output_format :full_environment, proc { |h| format("<<-ENVIRONMENT\n%s\nENVIRONMENT", Aruba.platform.simple_table(h)) }
92
84
  output_format :modified_environment, proc { |n, v| format('$ export %s=%s', n, Shellwords.escape(v)) }
93
85
  output_format :stderr, "<<-STDERR\n%s\nSTDERR"
94
86
  output_format :stdout, "<<-STDOUT\n%s\nSTDOUT"
87
+ output_format :command_content, "<<-COMMAND\n%s\nCOMMAND"
95
88
  output_format :stop_signal, proc { |p, s| format('Command will be stopped with `kill -%s %s`', s, p) }
96
89
  output_format :timeout, '# %s-timeout: %s seconds'
97
90
  output_format :wait_time, '# %s: %s seconds'
91
+ # rubocop:disable Metrics/LineLength
92
+ output_format :command_filesystem_status, proc { |status| format("<<-COMMAND FILESYSTEM STATUS\n%s\nCOMMAND FILESYSTEM STATUS", Aruba.platform.simple_table(status.to_h, :sort => false)) }
93
+ # rubocop:enable Metrics/LineLength
98
94
 
99
95
  # rubocop:disable Metrics/LineLength
100
96
  if @options[:stdout]
@@ -135,7 +131,6 @@ module Aruba
135
131
 
136
132
  # Reset announcer
137
133
  def reset
138
- @default_announcer = @announcers.last
139
134
  @announcer = @announcers.first
140
135
  end
141
136
 
@@ -161,8 +156,8 @@ module Aruba
161
156
  #
162
157
  # @param [Symbol] channel
163
158
  # The name of the channel to activate
164
- def activate(channel)
165
- channels[channel.to_sym] = true
159
+ def activate(*chns)
160
+ chns.flatten.each { |c| channels[c.to_sym] = true }
166
161
 
167
162
  self
168
163
  end
@@ -174,7 +169,11 @@ module Aruba
174
169
  #
175
170
  # @param [Array] args
176
171
  # Arguments
177
- def announce(channel, *args)
172
+ #
173
+ # @yield
174
+ # If block is given, that one is called and the return value is used as
175
+ # message to be announced.
176
+ def announce(channel, *args, &block)
178
177
  channel = channel.to_sym
179
178
 
180
179
  the_output_format = if output_formats.key? channel
@@ -183,11 +182,19 @@ module Aruba
183
182
  proc { |v| format('%s', v) }
184
183
  end
185
184
 
186
- message = the_output_format.call(*args)
185
+ return unless activated?(channel)
186
+
187
+ message = if block_given?
188
+ the_output_format.call(block.call)
189
+ else
190
+ the_output_format.call(*args)
191
+ end
192
+ message += "\n"
193
+ message = colorizer.cyan(message)
187
194
 
188
- announcer.announce(message) if channels[channel]
195
+ announcer.announce(message)
189
196
 
190
- default_announcer.announce message
197
+ nil
191
198
  end
192
199
 
193
200
  # @deprecated
@@ -0,0 +1,68 @@
1
+ require 'forwardable'
2
+
3
+ module Aruba
4
+ module Platforms
5
+ # File System Status object
6
+ #
7
+ # This is a wrapper for File::Stat returning only a subset of information.
8
+ class FilesystemStatus
9
+ METHODS = [
10
+ :executable?,
11
+ :ctime,
12
+ :atime,
13
+ :mtime,
14
+ :size
15
+ ]
16
+
17
+ extend Forwardable
18
+
19
+ private
20
+
21
+ attr_reader :status
22
+
23
+ public
24
+
25
+ if RUBY_VERSION >= '1.9.3'
26
+ def_delegators :@status, *METHODS
27
+ else
28
+ def_delegators :@status, :executable?, :ctime, :atime, :mtime, :size
29
+ end
30
+
31
+ def initialize(path)
32
+ @status = File::Stat.new(path)
33
+ end
34
+
35
+ # Return permissions
36
+ def mode
37
+ format("%o", status.mode)[-4,4].gsub(/^0*/, '')
38
+ end
39
+
40
+ # Return owner
41
+ def owner
42
+ status.uid
43
+ end
44
+
45
+ # Return owning group
46
+ def group
47
+ status.gid
48
+ end
49
+
50
+ # Convert status to hash
51
+ #
52
+ # @return [Hash]
53
+ # A hash of values
54
+ def to_h
55
+ {
56
+ :owner => owner,
57
+ :group => group,
58
+ :mode => mode,
59
+ :executable => executable?,
60
+ :ctime => ctime,
61
+ :atime => atime,
62
+ :mtime => mtime,
63
+ :size => size
64
+ }
65
+ end
66
+ end
67
+ end
68
+ end
@@ -6,7 +6,7 @@ module Aruba
6
6
  class SimpleTable
7
7
  private
8
8
 
9
- attr_reader :hash
9
+ attr_reader :hash, :opts
10
10
 
11
11
  public
12
12
 
@@ -14,8 +14,11 @@ module Aruba
14
14
  #
15
15
  # @param [Hash] hash
16
16
  # Input
17
- def initialize(hash)
17
+ def initialize(hash, opts)
18
18
  @hash = hash
19
+ @opts = {
20
+ :sort => true
21
+ }.merge opts
19
22
  end
20
23
 
21
24
  # Generate table
@@ -24,7 +27,7 @@ module Aruba
24
27
  # The table
25
28
  def to_s
26
29
  longest_key = hash.keys.map(&:to_s).max_by(&:length)
27
- return [] if longest_key.nil?
30
+ return '' if longest_key.nil?
28
31
 
29
32
  name_size = longest_key.length
30
33
 
@@ -34,12 +37,16 @@ module Aruba
34
37
  hash.each do |k,v|
35
38
  rows << format("# %-#{name_size}s => %s", k, v)
36
39
  end
37
-
38
- rows.sort
39
40
  else
40
- hash.each_with_object([]) do |(k,v), a|
41
+ rows = hash.each_with_object([]) do |(k,v), a|
41
42
  a << format("# %-#{name_size}s => %s", k, v)
42
- end.sort
43
+ end
44
+ end
45
+
46
+ if opts[:sort] == true
47
+ rows.sort.join("\n")
48
+ else
49
+ rows.join("\n")
43
50
  end
44
51
  end
45
52
  end
@@ -14,6 +14,7 @@ require 'aruba/platforms/local_environment'
14
14
  require 'aruba/platforms/aruba_logger'
15
15
  require 'aruba/platforms/announcer'
16
16
  require 'aruba/platforms/command_monitor'
17
+ require 'aruba/platforms/filesystem_status'
17
18
 
18
19
  # Aruba
19
20
  module Aruba
@@ -41,6 +42,10 @@ module Aruba
41
42
  UnixCommandString
42
43
  end
43
44
 
45
+ def filesystem_status
46
+ FilesystemStatus
47
+ end
48
+
44
49
  def announcer
45
50
  Announcer
46
51
  end
@@ -73,6 +78,10 @@ module Aruba
73
78
  LocalEnvironment.new.call(env, &block)
74
79
  end
75
80
 
81
+ def default_shell
82
+ 'bash'
83
+ end
84
+
76
85
  def detect_ruby(cmd)
77
86
  if cmd =~ /^ruby\s/
78
87
  cmd.gsub(/^ruby\s/, "#{current_ruby} ")
@@ -245,8 +254,8 @@ module Aruba
245
254
  end
246
255
 
247
256
  # Transform hash to a string table which can be output on stderr/stdout
248
- def simple_table(hash)
249
- SimpleTable.new(hash).to_s
257
+ def simple_table(hash, opts = {})
258
+ SimpleTable.new(hash, opts).to_s
250
259
  end
251
260
 
252
261
  # Resolve path for command using the PATH-environment variable
@@ -1,5 +1,3 @@
1
- require 'aruba/platform'
2
-
3
1
  # Aruba
4
2
  module Aruba
5
3
  # Platforms
@@ -1,5 +1,3 @@
1
- require 'aruba/platform'
2
-
3
1
  # Aruba
4
2
  module Aruba
5
3
  # Platforms
@@ -67,6 +67,14 @@ module Aruba
67
67
  NotImplementedError
68
68
  end
69
69
 
70
+ def filesystem_status
71
+ NotImplementedError
72
+ end
73
+
74
+ def content
75
+ NotImplementedError
76
+ end
77
+
70
78
  def wait
71
79
  NotImplementedError
72
80
  end
@@ -58,16 +58,7 @@ module Aruba
58
58
 
59
59
  @started = true
60
60
 
61
- # gather fully qualified path
62
- cmd = Aruba.platform.which(command, environment['PATH'])
63
-
64
- # rubocop:disable Metrics/LineLength
65
- fail LaunchError, %(Command "#{command}" not found in PATH-variable "#{environment['PATH']}".) if cmd.nil?
66
- # rubocop:enable Metrics/LineLength
67
-
68
- cmd = Aruba.platform.command_string.new(cmd)
69
-
70
- @process = ChildProcess.build(*[cmd.to_a, arguments].flatten)
61
+ @process = ChildProcess.build(*[command_string.to_a, arguments].flatten)
71
62
  @stdout_file = Tempfile.new('aruba-stdout-')
72
63
  @stderr_file = Tempfile.new('aruba-stderr-')
73
64
 
@@ -123,7 +114,7 @@ module Aruba
123
114
  def stdout(opts = {})
124
115
  return @stdout_cache if stopped?
125
116
 
126
- wait_for_io opts.fetch(:wait_for_io, @io_wait) do
117
+ wait_for_io opts.fetch(:wait_for_io, io_wait_timeout) do
127
118
  @process.io.stdout.flush
128
119
  open(@stdout_file.path).read
129
120
  end
@@ -142,7 +133,7 @@ module Aruba
142
133
  def stderr(opts = {})
143
134
  return @stderr_cache if stopped?
144
135
 
145
- wait_for_io opts.fetch(:wait_for_io, @io_wait) do
136
+ wait_for_io opts.fetch(:wait_for_io, io_wait_timeout) do
146
137
  @process.io.stderr.flush
147
138
  open(@stderr_file.path).read
148
139
  end
@@ -241,8 +232,36 @@ module Aruba
241
232
  raise CommandAlreadyStoppedError, %(Command "#{commandline}" with PID "#{pid}" has already stopped.)
242
233
  end
243
234
 
235
+ # Return file system stats for the given command
236
+ #
237
+ # @return [Aruba::Platforms::FilesystemStatus]
238
+ # This returns a File::Stat-object
239
+ def filesystem_status
240
+ Aruba.platform.filesystem_status.new(command_string.to_s)
241
+ end
242
+
243
+ # Content of command
244
+ #
245
+ # @return [String]
246
+ # The content of the script/command. This might be binary output as
247
+ # string if your command is a binary executable.
248
+ def content
249
+ File.read command_string.to_s
250
+ end
251
+
244
252
  private
245
253
 
254
+ def command_string
255
+ # gather fully qualified path
256
+ cmd = Aruba.platform.which(command, environment['PATH'])
257
+
258
+ # rubocop:disable Metrics/LineLength
259
+ fail LaunchError, %(Command "#{command}" not found in PATH-variable "#{environment['PATH']}".) if cmd.nil?
260
+ # rubocop:enable Metrics/LineLength
261
+
262
+ Aruba.platform.command_string.new(cmd)
263
+ end
264
+
246
265
  def wait_for_io(time_to_wait, &block)
247
266
  sleep time_to_wait.to_i
248
267
  block.call
data/lib/aruba/rspec.rb CHANGED
@@ -59,14 +59,16 @@ RSpec.configure do |config|
59
59
  aruba.announcer.activate(:changed_environment)
60
60
  end
61
61
 
62
- aruba.announcer.activate(:command) if example.metadata[:announce_command]
63
- aruba.announcer.activate(:directory) if example.metadata[:announce_directory]
64
- aruba.announcer.activate(:full_environment) if example.metadata[:announce_full_environment]
65
- aruba.announcer.activate(:stderr) if example.metadata[:announce_stderr]
66
- aruba.announcer.activate(:stdout) if example.metadata[:announce_stdout]
67
- aruba.announcer.activate(:stop_signal) if example.metadata[:announce_stop_signal]
68
- aruba.announcer.activate(:timeout) if example.metadata[:announce_timeout]
69
- aruba.announcer.activate(:wait_time) if example.metadata[:announce_wait_time]
62
+ aruba.announcer.activate(:command) if example.metadata[:announce_command]
63
+ aruba.announcer.activate(:directory) if example.metadata[:announce_directory]
64
+ aruba.announcer.activate(:full_environment) if example.metadata[:announce_full_environment]
65
+ aruba.announcer.activate(:stderr) if example.metadata[:announce_stderr]
66
+ aruba.announcer.activate(:stdout) if example.metadata[:announce_stdout]
67
+ aruba.announcer.activate(:stop_signal) if example.metadata[:announce_stop_signal]
68
+ aruba.announcer.activate(:timeout) if example.metadata[:announce_timeout]
69
+ aruba.announcer.activate(:wait_time) if example.metadata[:announce_wait_time]
70
+ aruba.announcer.activate(:command_content) if example.metadata[:announce_command_content]
71
+ aruba.announcer.activate(:command_filesystem_status) if example.metadata[:announce_command_filesystem_status]
70
72
 
71
73
  if example.metadata[:announce_output]
72
74
  aruba.announcer.activate(:stderr)
@@ -84,6 +86,8 @@ RSpec.configure do |config|
84
86
  aruba.announcer.activate(:stop_signal)
85
87
  aruba.announcer.activate(:timeout)
86
88
  aruba.announcer.activate(:wait_time)
89
+ aruba.announcer.activate(:command_content)
90
+ aruba.announcer.activate(:command_filesystem_status)
87
91
  end
88
92
  end
89
93