aruba 0.12.0 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
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