dk 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +643 -1
  3. data/bin/dk +7 -0
  4. data/dk.gemspec +7 -3
  5. data/lib/dk/ansi.rb +98 -0
  6. data/lib/dk/cli.rb +173 -0
  7. data/lib/dk/config.rb +217 -0
  8. data/lib/dk/config_runner.rb +24 -0
  9. data/lib/dk/dk_runner.rb +13 -0
  10. data/lib/dk/dry_runner.rb +43 -0
  11. data/lib/dk/has_set_param.rb +42 -0
  12. data/lib/dk/has_ssh_opts.rb +36 -0
  13. data/lib/dk/has_the_runs.rb +23 -0
  14. data/lib/dk/has_the_stubs.rb +116 -0
  15. data/lib/dk/local.rb +84 -0
  16. data/lib/dk/null_logger.rb +13 -0
  17. data/lib/dk/remote.rb +132 -0
  18. data/lib/dk/runner.rb +202 -0
  19. data/lib/dk/task.rb +266 -0
  20. data/lib/dk/task_run.rb +17 -0
  21. data/lib/dk/test_runner.rb +54 -0
  22. data/lib/dk/tree_runner.rb +64 -0
  23. data/lib/dk/version.rb +1 -1
  24. data/lib/dk.rb +23 -1
  25. data/test/helper.rb +6 -1
  26. data/test/support/config/dk.rb +7 -0
  27. data/test/support/config/task_defs.rb +10 -0
  28. data/test/support/factory.rb +38 -0
  29. data/test/support/log/.gitkeep +0 -0
  30. data/test/system/has_the_stubs_tests.rb +355 -0
  31. data/test/system/runner_tests.rb +222 -0
  32. data/test/unit/ansi_tests.rb +40 -0
  33. data/test/unit/cli_tests.rb +317 -0
  34. data/test/unit/config_runner_tests.rb +60 -0
  35. data/test/unit/config_tests.rb +427 -0
  36. data/test/unit/dk_runner_tests.rb +34 -0
  37. data/test/unit/dk_tests.rb +49 -0
  38. data/test/unit/dry_runner_tests.rb +71 -0
  39. data/test/unit/has_set_param_tests.rb +46 -0
  40. data/test/unit/has_ssh_opts_tests.rb +81 -0
  41. data/test/unit/has_the_runs_tests.rb +37 -0
  42. data/test/unit/has_the_stubs_tests.rb +279 -0
  43. data/test/unit/local_tests.rb +174 -0
  44. data/test/unit/null_logger_tests.rb +17 -0
  45. data/test/unit/remote_tests.rb +330 -0
  46. data/test/unit/runner_tests.rb +398 -0
  47. data/test/unit/task_run_tests.rb +40 -0
  48. data/test/unit/task_tests.rb +943 -0
  49. data/test/unit/test_runner_tests.rb +189 -0
  50. data/test/unit/tree_runner_tests.rb +152 -0
  51. metadata +106 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- data.tar.gz: d2d1893fb49305eb768384b4d9bf8a60a41552b0
4
- metadata.gz: d8ed8258fd4b6ea24b0a0955fb39fe542a919fd5
5
2
  SHA512:
6
- data.tar.gz: 0c5edc8880e3593bd495f6be7a7aa899c080d26714e0bac3dbba7b259fcc8115bd7d6956dcdaddb8943bc6895a0302f7384f63d270fe706aa7f3358ab5bff2ef
7
- metadata.gz: 37f806c02035d10775755ee7e0bef1553ee05ce3b814235a1f3d5570eee3bc30701edf49c5ee129fc2534a1f6e6833c4701c51319cf51be12836e9852f1baacc
3
+ data.tar.gz: 6d18c6023b43628117f27c2b7c60441a125ba6f126cd40a712cf635e7f9956728b68d94387ccfee8d4a4b26047dd1de48328304c428c5477727aa560238c46b9
4
+ metadata.gz: c3224e1ceea343b4a365dde9955d30e4cb6062365053e44a0fe17c00b90a32363365135259fdaf6b3651a24e6bff0b7f2fc9a704c0902fdf85f6460391610778
5
+ SHA1:
6
+ data.tar.gz: 5dc5bf7f2a83491664acdb2a9d55112149eed2e3
7
+ metadata.gz: 494082902e15484e13409bad7f209d6342ac671a
data/README.md CHANGED
@@ -6,7 +6,649 @@ This is some automated task runner thingy ala cap/rake (except without all the d
6
6
 
7
7
  ## Usage
8
8
 
9
- TODO: Write code samples and usage instructions here
9
+ First define a task:
10
+
11
+ ```ruby
12
+ require 'dk/task'
13
+
14
+ class MyTask
15
+ include Dk::Task
16
+
17
+ desc "my task that does something great"
18
+
19
+ def run!
20
+ log_info "this task does something"
21
+
22
+ # ... do something ...
23
+ end
24
+
25
+ end
26
+ ```
27
+
28
+ Now route this task with a name so it can be run from the CLI:
29
+
30
+ ```ruby
31
+ # in config/dk.rb or whatever
32
+ require 'dk'
33
+
34
+ Dk.configure do
35
+
36
+ task 'my-task', MyTask
37
+
38
+ end
39
+ ```
40
+
41
+ Now run this task using the CLI:
42
+
43
+ ```
44
+ $ dk -T
45
+ my-task # my task that does something great
46
+ $ dk my-task
47
+ ```
48
+
49
+ ### CLI
50
+
51
+ ```
52
+ $ dk --help
53
+ Usage: dk [TASKS] [options]
54
+
55
+ Tasks:
56
+ my-other-task # my other task that does something great
57
+ my-task # my task that does something great
58
+
59
+ Options:
60
+ -T, --[no-]list-tasks list all tasks available to run
61
+ -d, --[no-]dry-run run the tasks without executing any local/remote cmds
62
+ -t, --[no-]tree print out the tree of tasks/sub-tasks that would be run
63
+ -v, --[no-]verbose run tasks showing verbose (ie debug log level) details
64
+ --version
65
+ --help
66
+ ```
67
+
68
+ ##### `--list-tasks` option
69
+
70
+ Use this option (or its `-T` abbrev) to list out all tasks that are available to run. This is similar to the `-T` option on cap and rake.
71
+
72
+ ```
73
+ $ dk -T
74
+ my-other-task # my other task that does something great
75
+ my-task # my task that does something great
76
+ ```
77
+
78
+ ##### `--dry-run` option
79
+
80
+ This option runs the tasks and logs everything just like the live runner does. However, this runner disables all system commands: both local commands and remote ssh commands. Use this to see what a task would do do without running any of the system commands.
81
+
82
+ ##### `--tree` option
83
+
84
+ This option runs the tasks like the live runner does and disables all system commands like the `--dry-run` option does. However, this option also disables all logging and tracks all tasks and sub-tasks that are run. It then outputs the tree of tasks that was run:
85
+
86
+ TODO: show task tree output example
87
+
88
+ Use this to show the user all the tasks/sub-tasks that are run and which parent tasks are running them.
89
+
90
+ ##### `--verbose` option
91
+
92
+ This option runs tasks showing more verbose output/details (ie it sets the logger's stdout log level to 'debug'). All Task `log_debug` messages will be shown on stdout with this option. This option also makes the stdout and file logs identical.
93
+
94
+ ### Config
95
+
96
+ Dk stores settings in a config. To modify the settings add a configure block:
97
+
98
+ ```ruby
99
+ require 'dk'
100
+
101
+ Dk.configure do
102
+
103
+ # settings go here...
104
+
105
+ end
106
+ ```
107
+
108
+ There are a number of DSL settings that can be configured. Use these to set param values, set default ssh settings, configure tasks that can be called from the CLI, etc.
109
+
110
+ ##### `set_param`
111
+
112
+ ```ruby
113
+ require 'dk'
114
+
115
+ Dk.configure do
116
+
117
+ set_param 'app_name', 'myapp'
118
+ set_param 'number_of_things', 5
119
+ # ...
120
+
121
+ end
122
+ ```
123
+
124
+ Use the `set_param` method to set new global param values. Any tasks that are run will have these param values available to them using the tasks's `params` helper method.
125
+
126
+ ##### `before`, `prepend_before`, `after`, `prepend_after`
127
+
128
+ You can configure tasks as callbacks on other tasks using these helper methods:
129
+
130
+ ```ruby
131
+ require 'dk'
132
+
133
+ Dk.configure do
134
+
135
+ before MyTask, MyBeforeTask
136
+ prepend_before MyTask, MyOtherBeforeTask, 'some_param' => 'some_value'
137
+ after MyTask, MyAfterTask, 'some_param' => 'some_value'
138
+ prepend_after MyTask, MyOtherAfterTask
139
+
140
+ end
141
+ ```
142
+
143
+ Each callback can be optionally configured with a set of params. Callbacks can either be appended or prepended (this can be especially useful when you want to control the order 3rd-party tasks are run in).
144
+
145
+ The callback tasks will be run in the order they are added before/after the `run!` method of the task they are added to. The [`halt` task helper](https://github.com/redding/dk#halt) does not stop these callbacks from running.
146
+
147
+ ##### `ssh_hosts`, `ssh_args`, `host_ssh_args`
148
+
149
+ ```ruby
150
+ require 'dk'
151
+
152
+ Dk.configure do
153
+
154
+ ssh_hosts 'all_servers', '1.example.com',
155
+ '2.example.com',
156
+ '3.example.com',
157
+ 'user@4.example.com',
158
+ 'user@5.example.com'
159
+
160
+ ssh_hosts 'primary_server', '1.example.com'
161
+
162
+ ssh_hosts 'web_servers', '1.example.com',
163
+ '2.example.com'
164
+
165
+ ssh_hosts 'db_server', '3.example.com'
166
+
167
+ ssh_hosts 'bg_servers', 'user@4.example.com',
168
+ 'user@5.example.com'
169
+
170
+ # these are custom args to use on all SSH cmds
171
+ ssh_args "-o ForwardAgent=yes "\
172
+ "-o ControlMaster=auto "\
173
+ "-o ControlPersist=60s "\
174
+ "-o UserKnownHostsFile=/dev/null "\
175
+ "-o StrictHostKeyChecking=no "\
176
+ "-o ConnectTimeout=10 "\
177
+ "-o LogLevel=quiet "
178
+
179
+ # these two hosts use custom SSH ports
180
+ host_ssh_args 'user@4.example.com', '-p 12345'
181
+ host_ssh_args 'user@5.example.com', '-p 12345'
182
+
183
+ end
184
+ ```
185
+
186
+ Use the `ssh_hosts` method to define a named set of hosts. These hosts can now be referred to by name when running `ssh` cmds in tasks.
187
+
188
+ Use the `ssh_args` and `host_ssh_args` methods to configure ssh cmd arguments to apply to all SSH cmds. The host-specific args are only applied to SSH cmds run on the specific host.
189
+
190
+ ##### `log_pattern`, `log_file`, `log_file_pattern`
191
+
192
+ ```ruby
193
+ require 'dk'
194
+
195
+ Dk.configure do
196
+
197
+ log_pattern '[%-5l] : %m\n' # [INFO] : blah blah\n"
198
+
199
+ log_file "log/dk.log" # log all task run details to this file
200
+ log_file_pattern '[%d %-5l] : %m\n' # [<datetime> INFO] : blah blah\n"
201
+
202
+ end
203
+ ```
204
+
205
+ Use the `log_pattern` and `log_file_pattern` methods to override the default log entry format for stdout and file logging respectively. By default, stdout logs just log the message while the file logs log the date level and message. Uese these to tweak as desired. Dk uses [Logsly](https://github.com/redding/logsly) for its loggers so check out its README for [details on using patterns](https://github.com/redding/logsly#patterns).
206
+
207
+ Use the `log_file` method to turn on file logging. If given a file path, Dk will log all task run details (verbosely) to the file. This is handy when problems occur running tasks in non-verbose mode. File logging is always done verbosely so you can use this to refere to the details of previous task runs even though you may not have seen these details in your stdout logs.
208
+
209
+ ##### `task`
210
+
211
+ ```ruby
212
+ require 'dk'
213
+
214
+ Dk.configure do
215
+
216
+ task 'deploy', MyDeployTask
217
+ task 'deploy:setup' MyDeploySetupTask
218
+
219
+ # ...
220
+
221
+ end
222
+ ```
223
+
224
+ Use the `task` method to configure tasks that are runnable via the CLI. This also will display information about the task when using the `--help option in the CLI.
225
+
226
+ **Note**: only tasks configured using this method will be runnable from the CLI.
227
+
228
+ ##### `stub_dry_tree_cmd`, `stub_dry_tree_ssh`
229
+
230
+ ```ruby
231
+ require 'dk'
232
+
233
+ Dk.configure do
234
+
235
+ stub_dry_tree_cmd("ls -la") do |spy| # spy is a Local::CmdSpy
236
+ spy.stdout = "..."
237
+ end
238
+
239
+ stub_dry_tree_ssh("ls -la") do |spy| # spy is a Remote::CmdSpy
240
+ spy.exitstatus = 1 # simulare the ssh call failing
241
+ end
242
+
243
+ # ...
244
+
245
+ end
246
+ ```
247
+
248
+ Use the `stub_dry_tree_cmd` and `stub_dry_tree_ssh` methods to add cmd and ssh stubs when using `--dry-run` or `--tree`. This can be used to control the stdout, stderr or exitstatus of a command. This is useful when a task uses the output of one command for another command or when the task does different logic depending on if a command succeeds or fails.
249
+
250
+ ### Task
251
+
252
+ #### Helper Methods
253
+
254
+ The `Dk::Task` mixin provides a bunch of helper methods to make writing tasks easier and for commonizing common functions.
255
+
256
+ ##### `params`, `set_param`, `param?`, `try_param`
257
+
258
+ ```ruby
259
+ require 'dk/task'
260
+
261
+ class MyTask
262
+ include Dk::Task
263
+
264
+ def run!
265
+ param?('some_param') #=> true
266
+ params['some_param'] #=> "some value"
267
+ try_param('some_param') #=> "some value"
268
+
269
+ param?('some_other_param') #=> false
270
+ params['some_other_param'] #=> Dk::NoParamError
271
+ try_param('some_other_param') #=> nil
272
+
273
+ set_param('some_other_param', 'some other value')
274
+ param?('some_other_param') #=> true
275
+ params['some_other_param'] #=> "some other value"
276
+ try_param('some_other_param') #=> "some other value"
277
+ end
278
+
279
+ end
280
+ ```
281
+
282
+ Use the `param` helper to access named params that the task was run with. Params can be added two ways: globally [from the main config](https://github.com/redding/dk#set_param) or from [callback definitions](https://github.com/redding/dk#task-callbacks) and [`run_task` calls](https://github.com/redding/dk#run_task).
283
+
284
+ Use the `set_param` method to set new global param values like you would on the main config. Any subsequent tasks that are run will have these param values available to them.
285
+
286
+ Use the `param?` method to check whether a specific param has been set. Prefer this over `params.key?` as the task params have special logic for interacting with any runner params that makes the traditional `key?` method unreliable.
287
+
288
+ By default, the params will raise an exception if you try and access a missing key (it will raise Dk::NoParamerror). The idea is that Dk will loudly notify you if you are accessing a param you expect to be set and it is not set. However, this may not be appropriate for every scenario, therefore you can use the `try_param` helper and it will just return `nil` if the param is not set.
289
+
290
+ ##### `before`, `prepend_before`, `after`, `prepend_after`
291
+
292
+ [Like in the Config](https://github.com/redding/dk#before-prepend_before-after-prepend_after), you can add tasks as callbacks on other tasks using these helper methods:
293
+
294
+ ```ruby
295
+ require 'dk/task'
296
+
297
+ class MyTask
298
+ include Dk::Task
299
+
300
+ def run!
301
+ before SomeTask, MyBeforeTask
302
+ prepend_before SomeTask, MyOtherBeforeTask, 'some_param' => 'some_value'
303
+ after SomeTask, MyAfterTask, 'some_param' => 'some_value'
304
+ prepend_after SomeTask, MyOtherAfterTask
305
+ end
306
+
307
+ end
308
+ ```
309
+
310
+ Each callback can be optionally configured with a set of params. Callbacks can either be appended or prepended (this can be especially useful when you want to control the order 3rd-party tasks are run in). Once a callback is added, it works just as it would if added via the Config.
311
+
312
+ ##### `ssh_hosts`
313
+
314
+ ```ruby
315
+ require 'dk/task'
316
+
317
+ class MyTask
318
+ include Dk::Task
319
+
320
+ def run!
321
+ ssh_hosts('my-app-servers') # => nil
322
+ ssh_hosts('my-web-servers') # => nil
323
+
324
+ ssh_hosts 'my-app-servers', '1.example.com'
325
+ ssh_hosts 'my-web-servers', '2.example.com', '3.example.com'
326
+
327
+ ssh_hosts('my-app-servers') # => ['1.example.com']
328
+ ssh_hosts('my-web-servers') # => ['2.example.com', '3.example.com']
329
+ end
330
+
331
+ end
332
+ ```
333
+
334
+ Use the `ssh_hosts` method to set new ssh host lists values like you would on the main config. Any subsequent tasks that are run will have these ssh hosts available to their `ssh` commands.
335
+
336
+ ##### `run_task`
337
+
338
+ ```ruby
339
+ require 'dk/task'
340
+ require 'my_other_task'
341
+
342
+ class MyTask
343
+ include Dk::Task
344
+
345
+ def run!
346
+ # ... do something before ...
347
+
348
+ run_task MyOtherTask, 'some_param' => 'some value'
349
+
350
+ # ... do something after ...
351
+ end
352
+
353
+ end
354
+ ```
355
+
356
+ Use the `run_task` helper to run other tasks. This method takes an optional set of param values. Any params given will be merged onto the global config params and made available to just the task being run.
357
+
358
+ ##### `cmd`, `cmd!`
359
+
360
+ ```ruby
361
+ require 'dk/task'
362
+
363
+ class MyTask
364
+ include Dk::Task
365
+
366
+ def run!
367
+ cmd "ls -la", :env => { 'PWD' => '/path/to/some/dir' }
368
+ cmd! "test -d some_file"
369
+ end
370
+
371
+ end
372
+ ```
373
+
374
+ Use the `cmd` helper to run local system cmds. Pass it a string system command to run and it runs it using [Scmd](https://github.com/redding/scmd). You can [optionally pass in an `:env` param](https://github.com/redding/scmd#environment-variables) with any ENV vars that need to be set. A `Dk::Local::Cmd` object is returned so you can access data such as the `stdout`, `stderr` and whether the command was successful or not.
375
+
376
+ The `cmd!` helper is identical to the `cmd` helper except that it raises a `Dk::Task::CmdRunError` if the command was not successful.
377
+
378
+ ##### `ssh`, `ssh!`
379
+
380
+ ```ruby
381
+ require 'dk/task'
382
+
383
+ class MyTask
384
+ include Dk::Task
385
+
386
+ def run!
387
+ hosts = ['1.example.com', 'user@2.example.com']
388
+ ssh "ls -la", :hosts => hosts
389
+ ssh! "test -d some_file", :hosts => hosts
390
+ end
391
+
392
+ end
393
+ ```
394
+
395
+ Use the `ssh` helper to run remote system cmds on hosts using ssh. Like the normal `cmd*` helpers, pass it a string system command and it runs the command on each host using by creating a local system cmd that runs ssh. Like `cmd*` you can optionally pass in an `:env` param with any ENV vars that need to be set locally. Similare to `cmd*`, a `Dk::Remote::Cmd` object is returned so you can access whether the command was successful or not.
396
+
397
+ The `ssh!` helper is identical to the `ssh` helper except that it raises a `Dk::Task::SSHRunError` if the command was not successful.
398
+
399
+ ##### `:dry_tree_run` cmd/ssh opt
400
+
401
+ ```ruby
402
+ require 'dk/task'
403
+
404
+ class MyTask
405
+ include Dk::Task
406
+
407
+ def run!
408
+ cmd! "test -d some_file", :dry_tree_run => true
409
+ ssh! "test -d some_file", :dry_tree_run => true
410
+ end
411
+
412
+ end
413
+ ```
414
+
415
+ Use this option to force the cmd/ssh to *always* run, even using the `--dry-run` and `--tree` CLI options (which put Scmd in test mode and don't run any cmds by default). The idea is that some cmds are essential to the running of the task and if they don't actually run, the task will error out. This is handy for tasks that don't change anything they just read data and that data is used to determine how a task should proceed. This allows you to still get the advantages of the dry run and tree CLI options.
416
+
417
+ ##### `halt`
418
+
419
+ ```ruby
420
+ require 'dk/task'
421
+
422
+ class MyTask
423
+ include Dk::Task
424
+
425
+ def run!
426
+ # ... do something ...
427
+
428
+ halt if nothing_more_to_do
429
+
430
+ # ... otherwise keep going ...
431
+ end
432
+
433
+ end
434
+ ```
435
+
436
+ Use the `halt` helper to stop executing the current task. This doesn't halt the entire run (callbacks, subsequent tasks, etc). It only halts the current task. If you want to stop running everything, just raise an exception.
437
+
438
+ ##### `log_info`, `log_debug`, `log_error`
439
+
440
+ ```ruby
441
+ require 'dk/task'
442
+
443
+ class MyTask
444
+ include Dk::Task
445
+
446
+ def run!
447
+ log_info "will always show up in the CLI output"
448
+ log_debug "will only show up in the CLI output in verbose mode"
449
+ log_error "will always show, but has special error handling"
450
+ end
451
+
452
+ end
453
+ ```
454
+
455
+ Use the `log_*` helpers to log information as the task is running. Each corresponds to a logger level. The CLI logs to stdout on the INFO level by default. When run in verbose mode, it logs to stdout on the DEBUG level. If an optional log file has been configured, the CLI will log to the file on DEBUG level regardless of any verbose mode setting.
456
+
457
+ You can optionally style your log messages:
458
+
459
+ ```ruby
460
+ log_info "my message", :red, :on_white
461
+ log_info "my " + Dk::Ansi.styled_msg("special", :bold, :blue) + " message"
462
+ ```
463
+
464
+ See `Dk::Ansi::CODES.keys` for a list of available style names.
465
+
466
+ #### Task Descriptions
467
+
468
+ ```ruby
469
+ require 'dk/task'
470
+
471
+ class MyTask
472
+ include Dk::Task
473
+
474
+ desc "This is a task that does something"
475
+
476
+ def run!
477
+ # ... do something ...
478
+ end
479
+
480
+ end
481
+ ```
482
+
483
+ The descriptions of any routed tasks will be displayed when running `--help` in the CLI.
484
+
485
+ #### Task Callbacks
486
+
487
+ You can configure other tasks as callbacks to your task:
488
+
489
+ ```ruby
490
+ require 'dk/task'
491
+
492
+ class MyTask
493
+ include Dk::Task
494
+
495
+ before MyBeforeTask
496
+ prepend_before MyOtherBeforeTask, 'some_param' => 'some_value'
497
+ after MyAfterTask, 'some_param' => 'some_value'
498
+ prepend_after MyOtherAfterTask
499
+
500
+ def run!
501
+ # ... do something ...
502
+ end
503
+
504
+ end
505
+ ```
506
+
507
+ Each callback can be optionally configured with a set of params. These tasks will be run in the order they are added before/after the `run!` method of the current task. The [`halt` helper](https://github.com/redding/dk#halt) does not stop these callbacks from running.
508
+
509
+ #### Default SSH Hosts
510
+
511
+ You can configure a default list of hosts to use for ssh commands made in a Task. These hosts will be used on all commands that don't specify a custom `:hosts` option:
512
+
513
+ ```ruby
514
+ require 'dk/task'
515
+
516
+ class MyTask
517
+ include Dk::Task
518
+
519
+ ssh_hosts ['1.example.com', 'user@2.example.com']
520
+
521
+ def run!
522
+ ssh('ls -la') # => will ssh to 1.example.com and user@2.example.com
523
+ ssh('ls -la', :hosts => ['3.example.com']) # => will ssh to 3.example.com
524
+ end
525
+
526
+ end
527
+ ```
528
+
529
+ You can also specify a named list of hosts that have been configured:
530
+
531
+ ```ruby
532
+ require 'dk/task'
533
+
534
+ class MyTask
535
+ include Dk::Task
536
+
537
+ ssh_hosts 'my-app-servers'
538
+
539
+ def run!
540
+ ssh('ls -la') # => will ssh to the configured 'my-app-servers' hosts
541
+ end
542
+
543
+ end
544
+ ```
545
+
546
+ You can also specify a proc that will be instance eval'd on the task instance:
547
+
548
+ ```ruby
549
+ require 'dk/task'
550
+
551
+ class MyTask
552
+ include Dk::Task
553
+
554
+ ssh_hosts{ params['some-servers'] }
555
+
556
+ def run!
557
+ ssh('ls -la') # => will ssh to the hosts specified by the 'some-servers' param
558
+ end
559
+
560
+ end
561
+ ```
562
+
563
+ #### Ensure Tasks Only Run Once
564
+
565
+ ```ruby
566
+ require 'dk/task'
567
+
568
+ class MyTask
569
+ include Dk::Task
570
+
571
+ run_only_once true
572
+
573
+ def run!
574
+ # ... do something ...
575
+ end
576
+
577
+ end
578
+ ```
579
+
580
+ Use this setting to ensure that a task only runs once no matter how many other tasks or sub-tasks either run it manually or configure it as a callback. This is useful for "gatekeeper" tasks such as tasks that validate params, etc. By default, tasks can run multiple times.
581
+
582
+ #### Testing Tasks
583
+
584
+ Dk comes with a test runner and some test helpers to assist in unit testing tasks. The test runner doesn't run any callback tasks and captures spies for the task, cmd and ssh calls it runs. It also turns off any logging.
585
+
586
+ ```ruby
587
+ # in your test file or whatever
588
+
589
+ include Dk::Task::TestHelpers
590
+
591
+ test "my task should do something" do
592
+ runner = test_runner(MyTask)
593
+ runner.run
594
+ runner.runs #=> [TaskRun, Local::CmdSpy, Remote::CmdSpy, ... ]
595
+
596
+ # make assertions that the logic you expect to run actually ran
597
+ task = runner.task #=> MyTask instance
598
+
599
+ # make assertions about your task instance if needed
600
+ end
601
+ ```
602
+
603
+ Dk's test helpers include methods for stubbing cmd and ssh calls. This allows controlling cmd/ssh behavior such as exit status, stdout and stderr. If a task expects to use the stdout/stderr or does special handling when a call errors then the stubbing methods can be used for testing.
604
+
605
+ ```ruby
606
+ # in your test file or whatever
607
+
608
+ include Dk::Task::TestHelpers
609
+
610
+ test "my task should do something" do
611
+ runner = test_runner(MyTask)
612
+ runner.stub_cmd("ls -la") do |spy| # spy is a Local::CmdSpy
613
+ spy.stdout = "..."
614
+ end
615
+ runner.stub_ssh("ls -la", :input => 'whatever') do |spy| # spy is a Remote::CmdSpy
616
+ spy.exitstatus = 1 # simulare the ssh call failing
617
+ end
618
+
619
+ # ....
620
+ end
621
+ ```
622
+
623
+ You can even stub with procs. Those procs will be instance eval'd against the task to determine if the stub is a match. This allows you to stub the same way the call is made in the task (which is handy when the cmds are driven by dynamic values on the task instance).
624
+
625
+ ```ruby
626
+ # in your test file or whatever
627
+
628
+ include Dk::Task::TestHelpers
629
+
630
+ test "my task should do something" do
631
+ runner = test_runner(MyTask)
632
+ runner.stub_cmd(proc{ self.class.some_cmd_str }, :opts => proc{ some_opts }) do |spy| # spy is a Local::CmdSpy
633
+ spy.stdout = "..."
634
+ end
635
+ runner.stub_ssh("ls -la", :input => proc{ some_task_input_val }) do |spy| # spy is a Remote::CmdSpy
636
+ spy.exitstatus = 1 # simulare the ssh call failing
637
+ end
638
+
639
+ # ....
640
+ end
641
+ ```
642
+
643
+ ## Dk 3rd-party gems
644
+
645
+ These gems extend Dk for specific behavior:
646
+
647
+ * [dk-pkg](https://github.com/redding/dk-pkg): Dk logic for installing pkgs
648
+ * [dk-abdeploy](https://github.com/redding/dk-abdeploy): Dk tasks that implement the A/B deploy scheme
649
+ * [dk-dumpdb](https://github.com/redding/dk-dumpdb): Build Dk tasks to dump and restore your databases
650
+
651
+ (if you build your own gem that extends Dk, let us know and we'll link it here)
10
652
 
11
653
  ## Installation
12
654
 
data/bin/dk ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Copyright (c) 2016 Kelly Redding & Collin Redding
4
+ #
5
+
6
+ require 'dk/cli'
7
+ Dk::CLI.run ARGV
data/dk.gemspec CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |gem|
8
8
  gem.version = Dk::VERSION
9
9
  gem.authors = ["Kelly Redding", "Collin Redding"]
10
10
  gem.email = ["kelly@kellyredding.com", "collin.redding@me.com"]
11
- gem.summary = "\"Why'd you name this repo DK?\" \"Don't know\" (this is some automated task runner thingy ala cap/rake)"
12
- gem.description = "\"Why'd you name this repo DK?\" \"Don't know\" (this is some automated task runner thingy ala cap/rake)"
11
+ gem.summary = "\"Why'd you name this repo dk?\" \"Don't know\" (this is some automated task runner thingy ala cap/rake)"
12
+ gem.description = "\"Why'd you name this repo dk?\" \"Don't know\" (this is some automated task runner thingy ala cap/rake)"
13
13
  gem.homepage = "https://github.com/redding/dk"
14
14
  gem.license = 'MIT'
15
15
 
@@ -18,6 +18,10 @@ Gem::Specification.new do |gem|
18
18
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
19
  gem.require_paths = ["lib"]
20
20
 
21
- gem.add_development_dependency("assert", ["~> 2.16.1"])
21
+ gem.add_development_dependency("assert", ["~> 2.16.3"])
22
+
23
+ gem.add_dependency("much-plugin", ["~> 0.2.0"])
24
+ gem.add_dependency("scmd", ["~> 3.0.3"])
25
+ gem.add_dependency("logsly", ["~> 1.3.2"])
22
26
 
23
27
  end