producer-core 0.4.3 → 0.4.5

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 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