producer-core 0.4.3 → 0.4.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7369766247b31d978939ca38cea6e1ffda8e7e72
4
+ data.tar.gz: f0440319fe4a6c3e3dcf0352ac01a1dd39ed6a9f
5
+ SHA512:
6
+ metadata.gz: 3cf37a2d16b4e6bb4d42d0204ffc3f3a52016fc52358a625bc0eb86b13209241f75a6f171d29044414ff48dba4f339f6fff454d52b5d9ace33a4027f29d55117
7
+ data.tar.gz: 267659f33b453c84df3c0f9188ecb7f82ec08162bcc119afdf1b8da3776cc57d1b8014c846524b41202cb3ecbf3785ed66493e03f86987dc0cc46fd4845dd745
data/.travis.yml CHANGED
@@ -1,3 +1,7 @@
1
1
  language: ruby
2
+ cache: bundler
2
3
  rvm:
3
- - 2.1.4
4
+ - 2.2
5
+ - ruby-head
6
+ - 2.1
7
+ script: bundle exec rake ci
data/Guardfile CHANGED
@@ -1,3 +1,5 @@
1
+ directories %w[features lib spec]
2
+
1
3
  guard :cucumber, cli: '--format pretty --quiet', all_on_start: false do
2
4
  watch(%r{\Afeatures/.+\.feature\z})
3
5
  watch(%r{\Afeatures/support/.+\.rb\z}) { 'features' }
data/README.md ADDED
@@ -0,0 +1,386 @@
1
+ producer
2
+ ========
3
+
4
+ Software provisioning and configuration management tool, providing a
5
+ DSL to write "recipes".
6
+
7
+ [![Version ][badge-version-img]][badge-version-uri]
8
+ [![Build status ][badge-build-img]][badge-build-uri]
9
+ [![Code Climate ][badge-cclimate-img]][badge-cclimate-uri]
10
+
11
+
12
+ Getting started
13
+ ---------------
14
+
15
+ ### Installation (requires ruby ~> 2.1 and rubygems)
16
+
17
+ $ gem install producer-core
18
+
19
+
20
+ ### Simple recipe
21
+
22
+ Recipes are composed by tasks and a task includes actions. Here we
23
+ use the `echo` action, which output the given string to standard
24
+ output. All the power of the Ruby language is available.
25
+
26
+ ```ruby
27
+ hello_message = 'hello world!'
28
+
29
+ task :hello_world do
30
+ echo hello_message
31
+ echo hello_message.upcase
32
+ end
33
+ ```
34
+
35
+ $ producer simple_recipe.rb
36
+ hello world!
37
+ HELLO WORLD!
38
+
39
+
40
+ ### Shell command execution on remote host
41
+
42
+ The `sh` action will execute a shell command given as a string on
43
+ the targeted remote host. The remote host can be specified with the
44
+ CLI option `-t`.
45
+
46
+ ```ruby
47
+ task :show_zsh_pkg do
48
+ sh 'pkg info | grep zsh'
49
+ end
50
+ ```
51
+
52
+ $ producer -t localhost show_zsh_pkg.rb
53
+ zsh-5.0.7 The Z shell
54
+
55
+ When execution fails, recipe processing is stopped and the action
56
+ which triggered the failed execution is the last one to be applied.
57
+
58
+ ```ruby
59
+ task :sh_fail do
60
+ sh 'false'
61
+ echo 'end of recipe'
62
+ end
63
+ ```
64
+
65
+ $ producer -t localhost sh_fail.rb
66
+ RemoteCommandExecutionError: false
67
+ $
68
+
69
+ Only the first action is applied.
70
+
71
+
72
+ ### Task conditions
73
+
74
+ A task can be bound to a condition: when the condition fails actions
75
+ are skipped, otherwise actions are applied as usual.
76
+
77
+ This condition can be a simple ruby expression :
78
+
79
+ ```ruby
80
+ task :condition_pass do
81
+ condition { true }
82
+ echo 'will output'
83
+ end
84
+
85
+ task :condition_fail do
86
+ condition { false }
87
+ echo 'will NOT output'
88
+ end
89
+ ```
90
+
91
+ #### Built-in tests
92
+
93
+ Specific test keywords are also available in the condition block
94
+ context, `producer-core` ships with a few common tests,
95
+ `producer-stdlib` provides more, and custom tests can be defined.
96
+
97
+ Here we use the `sh` condition keyword which will pass when the
98
+ execution of the given shell command succeed, and fail when the
99
+ execution fails.
100
+
101
+ ```ruby
102
+ task :condition_sh_pass do
103
+ condition { sh 'true' }
104
+ echo 'will output'
105
+ end
106
+
107
+ task :condition_sh_fail do
108
+ condition { sh 'false' }
109
+ cho 'will NOT output'
110
+ end
111
+ ```
112
+
113
+
114
+ ### Nested tasks
115
+
116
+ Complex tasks can be split into nested subtasks. Conditions have
117
+ the same effect on tasks they have on actions, when the condition
118
+ fails, subtasks of the current task are skipped.
119
+
120
+ ```ruby
121
+ task :main_task do
122
+ condition { true }
123
+ task(:foo_subtask) { echo 'do foo' }
124
+ task(:bar_subtask) { echo 'do bar' }
125
+ task(:baz_subtask) do
126
+ condition { false }
127
+ task(:baz_subtask_subtask) { echo 'do baz' }
128
+ end
129
+ end
130
+ ```
131
+ $ producer nested_tasks.rb
132
+ do foo
133
+ do bar
134
+
135
+
136
+ Usage
137
+ -----
138
+
139
+ Usage: producer [options] [recipes]
140
+
141
+ options:
142
+ -v, --verbose enable verbose mode
143
+ -d, --debug enable debug mode
144
+ -n, --dry-run enable dry run mode
145
+ -t, --target HOST target host
146
+
147
+
148
+ Actions
149
+ -------
150
+
151
+ See:
152
+ https://github.com/tjouan/producer-core/tree/master/features/actions
153
+
154
+
155
+ Tests
156
+ -----
157
+
158
+ See:
159
+ https://github.com/tjouan/producer-core/tree/master/features/tests
160
+
161
+
162
+ Templates
163
+ ---------
164
+
165
+ The following example can setup jails on a FreeBSD host.
166
+
167
+ In `templates/freebsd/jail.conf.erb`:
168
+
169
+ ```erb
170
+ exec.start = "/bin/sh /etc/rc";
171
+ exec.stop = "/bin/sh /etc/rc.shutdown";
172
+ exec.clean;
173
+ mount.devfs;
174
+ allow.chflags;
175
+
176
+ path = "/var/jails/$name";
177
+
178
+ <% @jails.each do |jail| -%>
179
+ <%= jail[:name] %> {
180
+ interface "<%= @if %>";
181
+ ip4.addr = <%= jail[:addr4] %>;
182
+ }
183
+ <% end -%>
184
+ ```
185
+
186
+ Simple usage:
187
+
188
+ ```ruby
189
+ INTERFACE = 're0'.freeze
190
+ JAILS = [{
191
+ name: 'freebsd-10r1',
192
+ src: true,
193
+ addr4: '10.0.0.1'
194
+ }].freeze
195
+
196
+ task :jails_conf do
197
+ conf = template 'freebsd/jail.conf', if: INTERFACE, jails: JAILS
198
+ file_write_once '/etc/jail.conf', conf
199
+ end
200
+ ```
201
+
202
+
203
+ Macros
204
+ ------
205
+
206
+ FIXME
207
+
208
+
209
+ Test macros
210
+ -----------
211
+
212
+ FIXME
213
+
214
+
215
+ Macro composition
216
+ -----------------
217
+
218
+ FIXME
219
+
220
+
221
+ Background
222
+ ----------
223
+
224
+ producer started as a collection of heterogeneous scripts (Ruby,
225
+ POSIX shell, Perl…) in the late '90s. I wanted to experiment with the
226
+ design and usage of Domain Specific Languages in Ruby, and refactor
227
+ all my scripts as "recipes" in a common language.
228
+
229
+
230
+ Sample recipe
231
+ -------------
232
+
233
+ Based on the previous template example (FreeBSD jails.conf
234
+ template):
235
+
236
+ ```ruby
237
+ require 'producer/stdlib'
238
+
239
+ JAILS_ROOT = '/var/jails'.freeze
240
+ ZROOT = 'tank/jails'.freeze
241
+ INTERFACE = 're0'.freeze
242
+ SETS = {
243
+ base: '2b028a894d25711ad496762622a52d74b1e32ee04693ad1cf056e3ddcdc23975',
244
+ src: 'f919287a5ef51d4f133f27c99c54f2e8054f408d3dd53bc60f4e233cc75ec03d'
245
+ }.freeze
246
+ JAILS = [
247
+ {
248
+ name: 'freebsd-10r1',
249
+ src: true,
250
+ addr4: '10.0.0.1'
251
+ },
252
+ {
253
+ name: 'freebsd-10r1-gcc',
254
+ src: true,
255
+ addr4: '10.0.0.2'
256
+ }
257
+ ].freeze
258
+
259
+ task :freebsd_archives_fetch do
260
+ SETS.keys.each { |set| condition { no_file? "/tmp/#{set}.txz"} }
261
+
262
+ SETS.each do |set, sum|
263
+ sh <<-eoh
264
+ cd /tmp && \
265
+ fetch ftp://ftp.freebsd.org:/pub/FreeBSD/releases/amd64/10.1-RELEASE/#{set}.txz && \
266
+ sha256 -c #{sum} #{set}.txz
267
+ eoh
268
+ end
269
+ end
270
+
271
+ task :jails_fs_create do
272
+ condition { no_sh "zfs list #{ZROOT}" }
273
+ sh "zfs create -o mountpoint=#{JAILS_ROOT} -o compress=lz4 #{ZROOT}"
274
+ end
275
+
276
+ JAILS.each do |jail|
277
+ root = "#{JAILS_ROOT}/#{jail[:name]}"
278
+ fs = "#{ZROOT}/#{jail[:name]}"
279
+
280
+ task :jail_initialize do
281
+ condition { no_sh "zfs list #{fs}@install" }
282
+
283
+ task :jail_fs_create do
284
+ condition { no_sh "zfs list #{fs}" }
285
+
286
+ sh "zfs create #{fs}"
287
+
288
+ SETS.keys.each do |set|
289
+ next if set == 'src' && !jail[:src]
290
+ sh "tar -JxC #{root}/ -f /tmp/#{set}.txz"
291
+ end
292
+ end
293
+
294
+ task :rc_conf do
295
+ file_write_once "#{root}/etc/rc.conf", <<-eoh
296
+ hostname=#{jail[:name]}
297
+ # ...
298
+ eoh
299
+ end
300
+
301
+ task :root_passwd do
302
+ sh "chroot #{root} pw user mod root -w random"
303
+ end
304
+
305
+ task :mail_aliases do
306
+ condition { no_file? "#{root}/etc/mail/aliases.db" }
307
+
308
+ sh "chroot #{root} make -C /etc/mail aliases"
309
+ end
310
+
311
+ freebsd_update_patch_interactive "#{root}/usr/sbin/freebsd-update"
312
+
313
+ task :jail_snapshot_install do
314
+ sh "zfs snapshot #{fs}@install"
315
+ end
316
+ end
317
+
318
+ task :jail_update do
319
+ condition { no_sh "zfs list #{fs}@update" }
320
+
321
+ sh "chroot #{root} freebsd-update fetch install"
322
+ sh "zfs snapshot #{fs}@update"
323
+ end
324
+ end
325
+
326
+ task :jails_conf do
327
+ conf = template 'freebsd/jail.conf', if: INTERFACE, jails: JAILS
328
+ file_write_once '/etc/jail.conf', conf
329
+ end
330
+ ```
331
+
332
+
333
+ Similar or related code and tools
334
+ ---------------------------------
335
+
336
+ ### Ruby DSL
337
+
338
+ * https://github.com/sprinkle-tool/sprinkle
339
+ * http://www.capistranorb.com/
340
+ * http://babushka.me/ (with BDD features, no network support?)
341
+
342
+ ### Ruby DSL, shell script transpilation
343
+
344
+ * http://nadarei.co/mina/ (Rake based DSL, requires and uses bash)
345
+
346
+ ### Ruby-like DSL
347
+
348
+ * http://puppetlabs.com/ (Ruby supported on >= 2.6.x)
349
+
350
+ ### Agents, daemons
351
+
352
+ * https://github.com/saltstack/salt (Python, YAML)
353
+ * http://www.cobblerd.org/ (Python, many features)
354
+ * https://www.getchef.com/chef/
355
+
356
+ ### SSH
357
+
358
+ * https://github.com/ansible/ansible (Python, YAML)
359
+ * http://docs.fabfile.org/ (Python)
360
+ * https://github.com/sebastien/cuisine (Python DSL, uses Fabric)
361
+ * https://github.com/kenn/sunzi (Ruby, provisioning, shell based)
362
+ * http://solutious.com/projects/rudy/ (Ruby, provisioning)
363
+
364
+ ### Ruby SSH related code
365
+
366
+ * https://github.com/leehambley/sshkit
367
+ * https://github.com/gammons/screwcap
368
+ * https://github.com/delano/rye/
369
+ * https://github.com/jheiss/sshwrap
370
+
371
+ ### BDD
372
+
373
+ * https://github.com/hedgehog/cuken (Cucumber)
374
+ * http://serverspec.org/ (RSpec, Net::SSH)
375
+ * https://github.com/auxesis/cucumber-nagios (Cucumber, Net::SSH,
376
+ Webrat)
377
+ * http://larsyencken.github.io/marelle/ (Prolog, babushka inspired)
378
+
379
+
380
+
381
+ [badge-version-img]: https://img.shields.io/gem/v/producer-core.svg
382
+ [badge-version-uri]: https://rubygems.org/gems/producer-core
383
+ [badge-build-img]: https://img.shields.io/travis/tjouan/producer-core/master.svg
384
+ [badge-build-uri]: https://travis-ci.org/tjouan/producer-core
385
+ [badge-cclimate-img]: https://img.shields.io/codeclimate/github/tjouan/producer-core.svg
386
+ [badge-cclimate-uri]: https://codeclimate.com/github/tjouan/producer-core
data/Rakefile CHANGED
@@ -1,13 +1,16 @@
1
1
  require 'cucumber/rake/task'
2
2
  require 'rspec/core/rake_task'
3
3
 
4
- desc 'Run all scenarios'
5
- Cucumber::Rake::Task.new(:features) do |t|
4
+ task default: %i[features spec]
5
+
6
+ Cucumber::Rake::Task.new(:features)
7
+
8
+ Cucumber::Rake::Task.new(:features_no_sshd) do |t|
9
+ t.instance_eval { @desc << ' excluding @sshd'}
6
10
  t.cucumber_opts = '--tags ~@sshd'
7
11
  end
8
12
 
9
- desc 'Run all specs'
10
13
  RSpec::Core::RakeTask.new(:spec)
11
14
 
12
-
13
- task default: [:features, :spec]
15
+ desc 'Run CI test suite'
16
+ task ci: %i[features_no_sshd spec]
@@ -1,11 +1,13 @@
1
1
  Feature: CLI debug option
2
2
 
3
- Background:
4
- Given a recipe with:
5
- """
6
- task(:trigger_error) { fail 'some error' }
7
- """
8
-
9
- Scenario: reports recipe errors
3
+ Scenario: reports recipe errors with their cause
4
+ Given a recipe with an error
10
5
  When I execute the recipe with option -d
11
6
  Then the output must match /\ARuntimeError:.*\n\ncause:\nRuntimeError:/
7
+
8
+ Scenario: does not exclude anything from backtrace
9
+ Given a recipe using a remote
10
+ When I execute the recipe on unknown remote target with option -d
11
+ Then the output must contain "producer-core"
12
+ And the output must contain "net-ssh"
13
+ And the output must contain ruby lib directory
@@ -1,20 +1,32 @@
1
1
  Feature: CLI error reporting
2
2
 
3
- Background:
4
- Given a recipe with:
5
- """
6
- task(:trigger_error) { fail 'some error' }
7
- """
8
-
9
3
  Scenario: reports recipe errors
4
+ Given a recipe with an error
10
5
  When I execute the recipe
11
6
  Then the exit status must be 70
12
7
  And the output must match /\ARuntimeError: some error\n/
13
8
 
14
9
  Scenario: reports errors with a backtrace
10
+ Given a recipe with an error
15
11
  When I execute the recipe
16
12
  Then the output must match /^\s+recipe\.rb:\d+:in /
17
13
 
18
14
  Scenario: prepends recipe file path in the backtrace
15
+ Given a recipe with an error
19
16
  When I execute the recipe
20
17
  Then the output must match /^\s+recipe\.rb \(recipe\)\n\s+recipe\.rb:/
18
+
19
+ Scenario: excludes producer from backtrace
20
+ Given a recipe using a remote
21
+ When I execute the recipe on unknown remote target
22
+ Then the output must not contain "producer-core"
23
+
24
+ Scenario: excludes net-ssh from backtrace
25
+ Given a recipe using a remote
26
+ When I execute the recipe on unknown remote target
27
+ Then the output must not contain "net-ssh"
28
+
29
+ Scenario: excludes ruby standard library from backtrace
30
+ Given a recipe using a remote
31
+ When I execute the recipe on unknown remote target
32
+ Then the output must not contain ruby lib directory
@@ -13,4 +13,5 @@ Feature: CLI usage
13
13
  -d, --debug enable debug mode
14
14
  -n, --dry-run enable dry run mode
15
15
  -t, --target HOST target host
16
+
16
17
  """
@@ -25,3 +25,11 @@ end
25
25
  Then /^the error output must contain exactly "([^"]+)"$/ do |content|
26
26
  assert_exact_output content, all_stderr
27
27
  end
28
+
29
+ Then /^the output must contain ruby lib directory$/ do
30
+ assert_partial_output RbConfig::CONFIG['rubylibdir'], all_output
31
+ end
32
+
33
+ Then /^the output must not contain ruby lib directory$/ do
34
+ assert_no_partial_output RbConfig::CONFIG['rubylibdir'], all_output
35
+ end
@@ -2,6 +2,14 @@ Given /^a recipe with:$/ do |recipe_body|
2
2
  write_file 'recipe.rb', recipe_body
3
3
  end
4
4
 
5
+ Given /^a recipe with an error$/ do
6
+ write_file 'recipe.rb', "task(:trigger_error) { fail 'some error' }\n"
7
+ end
8
+
9
+ Given /^a recipe using a remote$/ do
10
+ write_file 'recipe.rb', "task(:some_task) { sh 'echo hello' }\n"
11
+ end
12
+
5
13
  Given /^a recipe named "([^"]+)" with:$/ do |recipe_path, recipe_body|
6
14
  write_file recipe_path, recipe_body
7
15
  end
@@ -14,6 +22,16 @@ When /^I execute the recipe on remote target$/ do
14
22
  run_simple 'producer recipe.rb -t some_host.test', false
15
23
  end
16
24
 
25
+ When /^I execute the recipe on unknown remote target$/ do
26
+ run_simple 'producer recipe.rb -t #unknown_host.test', false
27
+ assert_matching_output '\ASocketError', all_output
28
+ end
29
+
30
+ When /^I execute the recipe on unknown remote target with option (-.+)$/ do |option|
31
+ run_simple "producer recipe.rb #{option} -t #unknown_host.test", false
32
+ assert_matching_output '\ASocketError', all_output
33
+ end
34
+
17
35
  When /^I successfully execute the recipe$/ do
18
36
  step 'I execute the recipe'
19
37
  assert_exit_status 0
@@ -2,7 +2,6 @@ require 'aruba/cucumber'
2
2
  require 'aruba/in_process'
3
3
  require 'producer/core'
4
4
 
5
-
6
5
  class ArubaProgramWrapper
7
6
  def initialize(argv, stdin = $stdin, stdout = $stdout, stderr = $stderr,
8
7
  kernel = Kernel)
@@ -18,16 +17,18 @@ class ArubaProgramWrapper
18
17
  @argv.dup, stdin: @stdin, stdout: @stdout, stderr: @stderr
19
18
  )
20
19
  rescue SystemExit => e
21
- @kernel.exit(e.status)
20
+ @kernel.exit e.status
22
21
  end
23
22
  end
24
23
 
25
24
 
25
+ # Raise aruba default timeout so test suite can run on a slow machine.
26
26
  Before do
27
- @_sshd_fast = true
27
+ @aruba_timeout_seconds = 8
28
28
  end
29
- require 'cucumber/sshd/cucumber'
30
29
 
30
+ # Use aruba "in process" optimization only for scenarios not tagged @exec.
31
+ # We need a real process in a few cases: real program name, interactive usage…
31
32
  Before('@exec') do
32
33
  Aruba.process = Aruba::SpawnProcess
33
34
  end
@@ -36,3 +37,15 @@ Before('~@exec') do
36
37
  Aruba::InProcess.main_class = ArubaProgramWrapper
37
38
  Aruba.process = Aruba::InProcess
38
39
  end
40
+
41
+ # Fake home directory for @fake_home tagged scenarios.
42
+ Before('@fake_home') do
43
+ ENV['HOME'] = File.expand_path(current_dir)
44
+ end
45
+
46
+ # Enable cucumber-sshd "fast" mode (persists sshd across scenarios), and
47
+ # register hooks for @sshd tagged scenarios.
48
+ Before do
49
+ @_sshd_fast = true
50
+ end
51
+ require 'cucumber/sshd/cucumber'
@@ -2,9 +2,10 @@ module Producer
2
2
  module Core
3
3
  class ErrorFormatter
4
4
  FILTERS = [
5
- /\/producer-\w+\/(?:bin|lib)\//,
6
- /\/net\/ssh\//,
7
- /\/net\/sftp\//
5
+ /\/producer-\w+/,
6
+ Regexp.new(RbConfig::CONFIG['rubylibdir']),
7
+ /\/net-ssh/,
8
+ /\/net-sftp/
8
9
  ].freeze
9
10
 
10
11
  def initialize(debug: false, force_cause: [])
@@ -17,7 +18,7 @@ module Producer
17
18
  end
18
19
 
19
20
  def format(exception)
20
- lines = format_exception exception
21
+ lines = format_exception exception, filter: !debug?
21
22
 
22
23
  if debug? && exception.cause
23
24
  lines << ''
@@ -1,5 +1,5 @@
1
1
  module Producer
2
2
  module Core
3
- VERSION = '0.4.3'.freeze
3
+ VERSION = '0.4.5'.freeze
4
4
  end
5
5
  end
@@ -21,7 +21,7 @@ Gem::Specification.new do |s|
21
21
  s.add_dependency 'net-sftp', '~> 2.1'
22
22
 
23
23
  s.add_development_dependency 'rspec', '~> 3.1'
24
- s.add_development_dependency 'cucumber', '~> 1.3'
24
+ s.add_development_dependency 'cucumber', '~> 2.0'
25
25
  s.add_development_dependency 'aruba', '~> 0.5'
26
26
  s.add_development_dependency 'cucumber-sshd', '~> 0.1'
27
27
  s.add_development_dependency 'rake', '~> 10.1'
@@ -23,10 +23,14 @@ module Producer
23
23
  end
24
24
 
25
25
  describe '#format' do
26
- def exception
27
- begin fail 'original exception' rescue fail 'some exception' end
28
- rescue
29
- $!.tap { |o| o.set_backtrace %w[back trace] }
26
+ let(:rubylibdir) { RbConfig::CONFIG['rubylibdir'] }
27
+ let(:bt) { %W[backtrace /producer-core /net-ssh #{rubylibdir}] }
28
+ let(:exception) { RuntimeError.new('some exception').tap { |o| o.set_backtrace bt } }
29
+
30
+ def exception_with_cause
31
+ begin fail 'exception cause' rescue fail 'some exception' end
32
+ rescue => e
33
+ e.tap { |o| o.set_backtrace bt }
30
34
  end
31
35
 
32
36
  it 'formats the message' do
@@ -35,21 +39,44 @@ module Producer
35
39
  end
36
40
 
37
41
  it 'indents the backtrace' do
38
- expect(formatter.format exception).to match /^\s+back$/
42
+ expect(formatter.format exception).to match /^\s+backtrace$/
43
+ end
44
+
45
+ it 'excludes producer code from the backtrace' do
46
+ expect(formatter.format exception).not_to include 'producer-core'
39
47
  end
40
48
 
41
- context 'filtering' do
42
- before { exception.set_backtrace %w[back trace /producer-core/lib/] }
49
+ it 'excludes net-ssh from the backtrace' do
50
+ expect(formatter.format exception).not_to include 'net-ssh'
51
+ end
43
52
 
44
- it 'excludes producer code from the backtrace' do
45
- expect(formatter.format exception).not_to include 'producer-core'
53
+ it 'excludes ruby lib directory from the backtrace' do
54
+ expect(formatter.format exception).not_to include rubylibdir
55
+ end
56
+
57
+ context 'when exception has a cause' do
58
+ it 'does not include the cause' do
59
+ expect(formatter.format exception_with_cause)
60
+ .not_to include 'exception cause'
46
61
  end
62
+ end
47
63
 
48
- context 'when debug is enabled' do
49
- let(:debug) { true }
64
+ context 'when debug is enabled' do
65
+ let(:debug) { true }
66
+
67
+ it 'does not filter the backtrace' do
68
+ expect(formatter.format exception).to include 'producer-core'
69
+ end
70
+
71
+ context 'when exception has a cause' do
72
+ it 'includes the exception cause' do
73
+ expect(formatter.format exception_with_cause)
74
+ .to include 'exception cause'
75
+ end
50
76
 
51
- it 'does not exclude producer code from the backtrace' do
52
- expect(formatter.format exception).to include 'producer-core'
77
+ it 'formats the cause' do
78
+ expect(formatter.format exception_with_cause)
79
+ .to match /^cause:\nRuntimeError: exception cause/
53
80
  end
54
81
  end
55
82
  end
metadata CHANGED
@@ -1,20 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: producer-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
5
- prerelease:
4
+ version: 0.4.5
6
5
  platform: ruby
7
6
  authors:
8
7
  - Thibault Jouan
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2015-02-18 00:00:00.000000000 Z
11
+ date: 2015-04-03 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: net-ssh
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - "~>"
20
18
  - !ruby/object:Gem::Version
@@ -22,7 +20,6 @@ dependencies:
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - "~>"
28
25
  - !ruby/object:Gem::Version
@@ -30,7 +27,6 @@ dependencies:
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: net-sftp
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
31
  - - "~>"
36
32
  - !ruby/object:Gem::Version
@@ -38,7 +34,6 @@ dependencies:
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
38
  - - "~>"
44
39
  - !ruby/object:Gem::Version
@@ -46,7 +41,6 @@ dependencies:
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: rspec
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
45
  - - "~>"
52
46
  - !ruby/object:Gem::Version
@@ -54,7 +48,6 @@ dependencies:
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
52
  - - "~>"
60
53
  - !ruby/object:Gem::Version
@@ -62,23 +55,20 @@ dependencies:
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: cucumber
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
59
  - - "~>"
68
60
  - !ruby/object:Gem::Version
69
- version: '1.3'
61
+ version: '2.0'
70
62
  type: :development
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
66
  - - "~>"
76
67
  - !ruby/object:Gem::Version
77
- version: '1.3'
68
+ version: '2.0'
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: aruba
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
73
  - - "~>"
84
74
  - !ruby/object:Gem::Version
@@ -86,7 +76,6 @@ dependencies:
86
76
  type: :development
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
80
  - - "~>"
92
81
  - !ruby/object:Gem::Version
@@ -94,7 +83,6 @@ dependencies:
94
83
  - !ruby/object:Gem::Dependency
95
84
  name: cucumber-sshd
96
85
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
86
  requirements:
99
87
  - - "~>"
100
88
  - !ruby/object:Gem::Version
@@ -102,7 +90,6 @@ dependencies:
102
90
  type: :development
103
91
  prerelease: false
104
92
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
93
  requirements:
107
94
  - - "~>"
108
95
  - !ruby/object:Gem::Version
@@ -110,7 +97,6 @@ dependencies:
110
97
  - !ruby/object:Gem::Dependency
111
98
  name: rake
112
99
  requirement: !ruby/object:Gem::Requirement
113
- none: false
114
100
  requirements:
115
101
  - - "~>"
116
102
  - !ruby/object:Gem::Version
@@ -118,7 +104,6 @@ dependencies:
118
104
  type: :development
119
105
  prerelease: false
120
106
  version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
107
  requirements:
123
108
  - - "~>"
124
109
  - !ruby/object:Gem::Version
@@ -136,6 +121,7 @@ files:
136
121
  - Gemfile
137
122
  - Guardfile
138
123
  - LICENSE
124
+ - README.md
139
125
  - Rakefile
140
126
  - bin/producer
141
127
  - config/cucumber.yaml
@@ -168,9 +154,6 @@ files:
168
154
  - features/steps/remote_steps.rb
169
155
  - features/steps/ssh_steps.rb
170
156
  - features/support/env.rb
171
- - features/support/env_aruba_timeout.rb
172
- - features/support/env_cucumber_doc_string.rb
173
- - features/support/env_fake_home.rb
174
157
  - features/task/ask.feature
175
158
  - features/task/condition.feature
176
159
  - features/task/nested_tasks.feature
@@ -274,27 +257,26 @@ files:
274
257
  - spec/support/test_env_helpers.rb
275
258
  homepage: https://rubygems.org/gems/producer-core
276
259
  licenses: []
260
+ metadata: {}
277
261
  post_install_message:
278
262
  rdoc_options: []
279
263
  require_paths:
280
264
  - lib
281
265
  required_ruby_version: !ruby/object:Gem::Requirement
282
- none: false
283
266
  requirements:
284
267
  - - ">="
285
268
  - !ruby/object:Gem::Version
286
269
  version: '0'
287
270
  required_rubygems_version: !ruby/object:Gem::Requirement
288
- none: false
289
271
  requirements:
290
272
  - - ">="
291
273
  - !ruby/object:Gem::Version
292
274
  version: '0'
293
275
  requirements: []
294
276
  rubyforge_project:
295
- rubygems_version: 1.8.30
277
+ rubygems_version: 2.4.5
296
278
  signing_key:
297
- specification_version: 3
279
+ specification_version: 4
298
280
  summary: Provisioning tool
299
281
  test_files:
300
282
  - features/actions/echo.feature
@@ -326,9 +308,6 @@ test_files:
326
308
  - features/steps/remote_steps.rb
327
309
  - features/steps/ssh_steps.rb
328
310
  - features/support/env.rb
329
- - features/support/env_aruba_timeout.rb
330
- - features/support/env_cucumber_doc_string.rb
331
- - features/support/env_fake_home.rb
332
311
  - features/task/ask.feature
333
312
  - features/task/condition.feature
334
313
  - features/task/nested_tasks.feature
@@ -1,3 +0,0 @@
1
- Before do
2
- @aruba_timeout_seconds = 8
3
- end
@@ -1,23 +0,0 @@
1
- require 'cucumber/formatter/pretty'
2
-
3
- module Cucumber
4
- module Ast
5
- class DocString
6
- alias :old_initialize :initialize
7
-
8
- def initialize(string, content_type)
9
- old_initialize(string + "\n", content_type)
10
- end
11
- end
12
- end
13
-
14
- module Formatter
15
- class Pretty
16
- alias :old_doc_string :doc_string
17
-
18
- def doc_string(string)
19
- old_doc_string(string.chomp)
20
- end
21
- end
22
- end
23
- end
@@ -1,3 +0,0 @@
1
- Before('@fake_home') do
2
- ENV['HOME'] = File.expand_path(current_dir)
3
- end