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.
- checksums.yaml +4 -4
- data/.travis.yml +5 -1
- data/History.md +75 -55
- data/Rakefile +1 -1
- data/aruba.gemspec +0 -1
- data/features/api/command/run_simple.feature +37 -2
- data/features/api/command/stderr.feature +46 -0
- data/features/api/command/stdout.feature +46 -0
- data/features/configuration/activate_announcer_on_command_failure.feature +38 -0
- data/features/steps/command/run.feature +28 -0
- data/features/steps/command/shell.feature +155 -0
- data/features/steps/core/announce.feature +80 -0
- data/features/support/aruba.rb +3 -2
- data/lib/aruba/api/command.rb +7 -10
- data/lib/aruba/colorizer.rb +108 -0
- data/lib/aruba/config.rb +4 -2
- data/lib/aruba/cucumber/command.rb +12 -0
- data/lib/aruba/cucumber/hooks.rb +10 -0
- data/lib/aruba/errors.rb +6 -0
- data/lib/aruba/event_bus.rb +59 -0
- data/lib/aruba/event_bus/name_resolver.rb +168 -0
- data/lib/aruba/generators/script_file.rb +46 -0
- data/lib/aruba/matchers/path/have_permissions.rb +1 -1
- data/lib/aruba/platforms/announcer.rb +30 -23
- data/lib/aruba/platforms/filesystem_status.rb +68 -0
- data/lib/aruba/platforms/simple_table.rb +14 -7
- data/lib/aruba/platforms/unix_platform.rb +11 -2
- data/lib/aruba/platforms/unix_which.rb +0 -2
- data/lib/aruba/platforms/windows_which.rb +0 -2
- data/lib/aruba/processes/basic_process.rb +8 -0
- data/lib/aruba/processes/spawn_process.rb +31 -12
- data/lib/aruba/rspec.rb +12 -8
- data/lib/aruba/runtime.rb +2 -2
- data/lib/aruba/setup.rb +5 -2
- data/lib/aruba/version.rb +1 -1
- data/script/bootstrap +8 -0
- data/spec/aruba/api_spec.rb +1 -1
- data/spec/aruba/platform/simple_table_spec.rb +2 -2
- data/spec/event_bus/name_resolver_spec.rb +68 -0
- data/spec/event_bus_spec.rb +160 -0
- data/spec/spec_helper.rb +0 -3
- data/spec/support/configs/aruba.rb +5 -0
- 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 =
|
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
|
-
|
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, :
|
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
|
-
@
|
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(
|
165
|
-
channels[
|
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
|
-
|
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
|
-
|
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)
|
195
|
+
announcer.announce(message)
|
189
196
|
|
190
|
-
|
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
|
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
|
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
|
@@ -58,16 +58,7 @@ module Aruba
|
|
58
58
|
|
59
59
|
@started = true
|
60
60
|
|
61
|
-
|
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,
|
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,
|
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)
|
63
|
-
aruba.announcer.activate(:directory)
|
64
|
-
aruba.announcer.activate(:full_environment)
|
65
|
-
aruba.announcer.activate(:stderr)
|
66
|
-
aruba.announcer.activate(:stdout)
|
67
|
-
aruba.announcer.activate(:stop_signal)
|
68
|
-
aruba.announcer.activate(:timeout)
|
69
|
-
aruba.announcer.activate(: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
|
|