stickyflag 0.2.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.
Files changed (76) hide show
  1. data/.gitignore +7 -0
  2. data/.rspec +4 -0
  3. data/.simplecov +9 -0
  4. data/.travis.yml +13 -0
  5. data/Gemfile +2 -0
  6. data/LICENSE.md +7 -0
  7. data/README.md +49 -0
  8. data/Rakefile +19 -0
  9. data/TODO.md +3 -0
  10. data/bin/stickyflag +6 -0
  11. data/features/clear.feature +14 -0
  12. data/features/clear_quietly.feature +23 -0
  13. data/features/configuration.feature +14 -0
  14. data/features/get.feature +14 -0
  15. data/features/get_quietly.feature +23 -0
  16. data/features/set.feature +14 -0
  17. data/features/set_quietly.feature +22 -0
  18. data/features/step_definitions/configuration_steps.rb +31 -0
  19. data/features/step_definitions/database_steps.rb +41 -0
  20. data/features/step_definitions/pending_steps.rb +5 -0
  21. data/features/step_definitions/tag_steps.rb +62 -0
  22. data/features/support/cukegem.rb +82 -0
  23. data/features/support/env.rb +37 -0
  24. data/features/tags.feature +18 -0
  25. data/features/unset.feature +14 -0
  26. data/features/unset_quietly.feature +23 -0
  27. data/lib/stickyflag/configuration.rb +66 -0
  28. data/lib/stickyflag/database.rb +162 -0
  29. data/lib/stickyflag/external_cmds.rb +64 -0
  30. data/lib/stickyflag/patches/tempfile_encoding.rb +22 -0
  31. data/lib/stickyflag/patches/tmpnam.rb +38 -0
  32. data/lib/stickyflag/paths.rb +47 -0
  33. data/lib/stickyflag/tag_factory.rb +108 -0
  34. data/lib/stickyflag/tags/c.rb +25 -0
  35. data/lib/stickyflag/tags/mmd.rb +168 -0
  36. data/lib/stickyflag/tags/pdf.rb +119 -0
  37. data/lib/stickyflag/tags/png.rb +61 -0
  38. data/lib/stickyflag/tags/source_code.rb +99 -0
  39. data/lib/stickyflag/tags/tex.rb +25 -0
  40. data/lib/stickyflag/version.rb +12 -0
  41. data/lib/stickyflag.rb +253 -0
  42. data/spec/spec_helper.rb +22 -0
  43. data/spec/stickyflag/configuration_spec.rb +132 -0
  44. data/spec/stickyflag/database_spec.rb +331 -0
  45. data/spec/stickyflag/external_cmds_spec.rb +175 -0
  46. data/spec/stickyflag/patches/tempfile_encoding_spec.rb +26 -0
  47. data/spec/stickyflag/patches/tmpnam_spec.rb +35 -0
  48. data/spec/stickyflag/paths_spec.rb +29 -0
  49. data/spec/stickyflag/tag_factory_spec.rb +185 -0
  50. data/spec/stickyflag/tags/c_spec.rb +14 -0
  51. data/spec/stickyflag/tags/mmd_spec.rb +40 -0
  52. data/spec/stickyflag/tags/pdf_spec.rb +39 -0
  53. data/spec/stickyflag/tags/png_spec.rb +6 -0
  54. data/spec/stickyflag/tags/tex_spec.rb +6 -0
  55. data/spec/stickyflag_spec.rb +482 -0
  56. data/spec/support/examples/c_all_comments.c +3 -0
  57. data/spec/support/examples/c_no_tags.c +5 -0
  58. data/spec/support/examples/c_with_tag.c +6 -0
  59. data/spec/support/examples/mmd_all_meta.mmd +6 -0
  60. data/spec/support/examples/mmd_crazy_keys.mmd +8 -0
  61. data/spec/support/examples/mmd_crazy_tags.mmd +9 -0
  62. data/spec/support/examples/mmd_no_tags.mmd +1 -0
  63. data/spec/support/examples/mmd_with_tag.mmd +3 -0
  64. data/spec/support/examples/pdf_no_tags.pdf +0 -0
  65. data/spec/support/examples/pdf_with_tag.pdf +0 -0
  66. data/spec/support/examples/png_no_tags.png +0 -0
  67. data/spec/support/examples/png_with_tag.png +0 -0
  68. data/spec/support/examples/tex_no_tags.tex +10 -0
  69. data/spec/support/examples/tex_with_tag.tex +11 -0
  70. data/spec/support/examples/untaggable.txt +0 -0
  71. data/spec/support/examples.rb +32 -0
  72. data/spec/support/run_with_args.rb +36 -0
  73. data/spec/support/silence_stream.rb +12 -0
  74. data/spec/support/tag_handler_behavior.rb +125 -0
  75. data/stickyflag.gemspec +48 -0
  76. metadata +399 -0
@@ -0,0 +1,482 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'thor'
3
+ require 'stickyflag'
4
+
5
+ describe 'StickyFlag' do
6
+ describe '#config' do
7
+ context 'without any further parameters' do
8
+ it 'prints out the configuration' do
9
+ run_with_args('config') do |sf|
10
+ sf.should_receive(:dump_config)
11
+ end
12
+ end
13
+ end
14
+
15
+ context 'with --reset' do
16
+ it 'resets the configuration' do
17
+ run_with_args('config', '--reset') do |sf|
18
+ sf.should_receive(:reset_config!)
19
+ end
20
+ end
21
+ end
22
+
23
+ context 'with --list' do
24
+ it 'prints out the configuration' do
25
+ run_with_args('config', '--list') do |sf|
26
+ sf.should_receive(:dump_config)
27
+ end
28
+ end
29
+
30
+ it 'prints out the configuration with --quiet' do
31
+ run_with_args('config', '--list', '--quiet') do |sf|
32
+ sf.should_receive(:dump_config)
33
+ end
34
+ end
35
+ end
36
+
37
+ context 'with a key but no value' do
38
+ it 'prints the value for that configuration item' do
39
+ run_with_args('config', '--key', 'root') do |sf|
40
+ sf.set_config :root, "/usr"
41
+ sf.should_receive(:say).with("root: '/usr'")
42
+ end
43
+ end
44
+ end
45
+
46
+ context 'with a value but no key' do
47
+ it 'raises an error' do
48
+ expect {
49
+ run_with_args('config', 'asdf')
50
+ }.to raise_error
51
+ end
52
+ end
53
+
54
+ context 'with a key and a value' do
55
+ it 'sets the configuration value' do
56
+ run_with_args('config', '--key', 'root', '/usr') do |sf|
57
+ sf.set_config :root, ''
58
+ sf.should_receive(:set_config).with('root', '/usr')
59
+ end
60
+ end
61
+
62
+ it 'prints the new value' do
63
+ run_with_args('config', '--key', 'root', '/usr') do |sf|
64
+ sf.set_config :root, ''
65
+ sf.should_receive(:say).with("'root' set to '/usr'")
66
+ end
67
+ end
68
+
69
+ it "doesn't print out if we're given --quiet" do
70
+ run_with_args('config', '--key', 'root', '/usr', '--quiet') do |sf|
71
+ sf.set_config :root, ''
72
+ sf.should_not_receive(:say)
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ describe '#get' do
79
+ context 'with no arguments' do
80
+ it 'raises an error' do
81
+ expect {
82
+ run_with_args('get')
83
+ }.to raise_error
84
+ end
85
+ end
86
+
87
+ context 'with a missing file' do
88
+ it 'prints an error message' do
89
+ run_with_args('get', 'bad.pdf') do |sf|
90
+ sf.should_receive(:say_status).with(:error, /bad\.pdf/, kind_of(Symbol))
91
+ end
92
+ end
93
+
94
+ it 'does not print an error message with --quiet' do
95
+ run_with_args('get', 'bad.pdf', '--quiet') do |sf|
96
+ sf.should_not_receive(:say)
97
+ sf.should_not_receive(:say_status)
98
+ end
99
+ end
100
+
101
+ it 'does not print an error message with --force' do
102
+ run_with_args('get', 'bad.pdf', '--force') do |sf|
103
+ sf.should_not_receive(:say)
104
+ sf.should_not_receive(:say_status)
105
+ end
106
+ end
107
+ end
108
+
109
+ context 'with a file without tags' do
110
+ it 'prints a no-tags message' do
111
+ run_with_args('get', example_path('c_no_tags.c')) do |sf|
112
+ sf.should_receive(:say).with(/.*c_no_tags.c: no tags/)
113
+ end
114
+ end
115
+
116
+ it 'does not print a no-tags message with --quiet' do
117
+ run_with_args('get', example_path('c_no_tags.c'), '--quiet') do |sf|
118
+ sf.should_not_receive(:say)
119
+ sf.should_not_receive(:say_status)
120
+ end
121
+ end
122
+
123
+ it 'does not print a no-tags message with --force' do
124
+ run_with_args('get', example_path('c_no_tags.c'), '--force') do |sf|
125
+ sf.should_not_receive(:say)
126
+ sf.should_not_receive(:say_status)
127
+ end
128
+ end
129
+ end
130
+
131
+ context 'with a file with tags' do
132
+ it 'prints the tags' do
133
+ run_with_args('get', example_path('mmd_crazy_tags.mmd')) do |sf|
134
+ sf.should_receive(:say).with(/ asdf, /)
135
+ end
136
+ end
137
+
138
+ it 'prints the tags with --quiet' do
139
+ run_with_args('get', example_path('mmd_crazy_tags.mmd'), '--quiet') do |sf|
140
+ sf.should_receive(:say).with(/ asdf, /)
141
+ end
142
+ end
143
+
144
+ it 'prints the tags with --force' do
145
+ run_with_args('get', example_path('mmd_crazy_tags.mmd'), '--force') do |sf|
146
+ sf.should_receive(:say).with(/ asdf, /)
147
+ end
148
+ end
149
+ end
150
+
151
+ context 'with multiple files with tags' do
152
+ it 'prints all the files' do
153
+ run_with_args('get', example_path('mmd_crazy_tags.mmd'), example_path('c_with_tag.c')) do |sf|
154
+ sf.should_receive(:say).with(/mmd_crazy_tags\.mmd/)
155
+ sf.should_receive(:say).with(/c_with_tag\.c/)
156
+ end
157
+ end
158
+ end
159
+ end
160
+
161
+ describe '#set' do
162
+ context 'with no parameters' do
163
+ it 'raises an error' do
164
+ expect {
165
+ run_with_args('set')
166
+ }.to raise_error
167
+ end
168
+ end
169
+
170
+ context 'with just a file' do
171
+ it 'raises an error' do
172
+ expect {
173
+ run_with_args('set', 'bad.pdf')
174
+ }.to raise_error
175
+ end
176
+ end
177
+
178
+ context 'with a good file and an invalid tag' do
179
+ it 'raises an error' do
180
+ expect {
181
+ run_with_args('set', __FILE__, 'asdf,asdf')
182
+ }.to raise_error
183
+ end
184
+
185
+ it 'also raises on blank tags' do
186
+ expect {
187
+ run_with_args('set', __FILE__, '')
188
+ }.to raise_error
189
+ end
190
+ end
191
+
192
+ context 'with a missing file and a good tag' do
193
+ it 'prints an error message' do
194
+ run_with_args('set', 'bad.pdf', 'asdf') do |sf|
195
+ sf.should_receive(:say_status).with(:error, /bad\.pdf/, :red)
196
+ end
197
+ end
198
+
199
+ it 'does not print an error message with --quiet' do
200
+ run_with_args('set', 'bad.pdf', 'asdf', '--quiet') do |sf|
201
+ sf.should_not_receive(:say)
202
+ sf.should_not_receive(:say_status)
203
+ end
204
+ end
205
+ end
206
+
207
+ context 'with a good file and a good tag' do
208
+ before(:each) do
209
+ @path = copy_example('c_with_tag.c')
210
+ end
211
+ after(:each) do
212
+ File.unlink(@path)
213
+ end
214
+
215
+ it 'sets the tags' do
216
+ run_with_args('set', @path, 'test2')
217
+ run_with_args('get', @path) do |sf|
218
+ sf.should_receive(:say).with(/ test2/)
219
+ end
220
+ end
221
+
222
+ it 'prints all the tags' do
223
+ run_with_args('set', @path, 'test2') do |sf|
224
+ sf.should_receive(:say_status).with(:success, /: test, test2/, :green)
225
+ end
226
+ end
227
+
228
+ it 'prints nothing with --quiet' do
229
+ run_with_args('set', @path, 'test2', '--quiet') do |sf|
230
+ sf.should_not_receive(:say)
231
+ sf.should_not_receive(:say_status)
232
+ end
233
+ end
234
+ end
235
+ end
236
+
237
+ describe '#unset' do
238
+ context 'with no parameters' do
239
+ it 'raises an error' do
240
+ expect {
241
+ run_with_args('unset')
242
+ }.to raise_error
243
+ end
244
+ end
245
+
246
+ context 'with just a file' do
247
+ it 'raises an error' do
248
+ expect {
249
+ run_with_args('unset', 'bad.pdf')
250
+ }.to raise_error
251
+ end
252
+ end
253
+
254
+ context 'with a good file and an invalid tag' do
255
+ it 'raises an error' do
256
+ expect {
257
+ run_with_args('unset', __FILE__, 'asdf,asdf')
258
+ }.to raise_error
259
+ end
260
+ end
261
+
262
+ context 'with a missing file and a good tag' do
263
+ it 'prints an error message' do
264
+ run_with_args('unset', 'bad.pdf', 'asdf') do |sf|
265
+ sf.should_receive(:say_status).with(:error, /bad\.pdf/, :red)
266
+ end
267
+ end
268
+
269
+ it 'does not print an error message with --quiet' do
270
+ run_with_args('unset', 'bad.pdf', 'asdf', '--quiet') do |sf|
271
+ sf.should_not_receive(:say)
272
+ sf.should_not_receive(:say_status)
273
+ end
274
+ end
275
+ end
276
+
277
+ context 'with a good file and a good tag' do
278
+ before(:each) do
279
+ @path = copy_example('c_with_tag.c')
280
+ end
281
+ after(:each) do
282
+ File.unlink(@path)
283
+ end
284
+
285
+ it 'sets the tags' do
286
+ run_with_args('unset', @path, 'test')
287
+ run_with_args('get', @path) do |sf|
288
+ sf.should_receive(:say).with(/ no tags/)
289
+ end
290
+ end
291
+
292
+ it 'prints no tags' do
293
+ run_with_args('unset', @path, 'test') do |sf|
294
+ sf.should_receive(:say_status).with(:success, /: no tags/, :green)
295
+ end
296
+ end
297
+
298
+ it 'prints nothing with --quiet' do
299
+ run_with_args('unset', @path, 'test', '--quiet') do |sf|
300
+ sf.should_not_receive(:say)
301
+ sf.should_not_receive(:say_status)
302
+ end
303
+ end
304
+ end
305
+
306
+ context 'with a file with multiple tags' do
307
+ before(:each) do
308
+ @path = copy_example('mmd_crazy_tags.mmd')
309
+ end
310
+ after(:each) do
311
+ File.unlink(@path)
312
+ end
313
+
314
+ it 'prints the remaining tags' do
315
+ run_with_args('unset', @path, 'asdf') do |sf|
316
+ sf.should_receive(:say_status).with(:success, /: sdfg/, :green)
317
+ end
318
+ end
319
+ end
320
+ end
321
+
322
+ describe '#clear' do
323
+ context 'with no parameters' do
324
+ it 'raises an error' do
325
+ expect {
326
+ run_with_args('clear')
327
+ }.to raise_error
328
+ end
329
+ end
330
+
331
+ context 'with a missing file' do
332
+ it 'prints an error message' do
333
+ run_with_args('clear', 'bad.pdf') do |sf|
334
+ sf.should_receive(:say_status).with(:error, /bad\.pdf/, :red)
335
+ end
336
+ end
337
+
338
+ it 'does not print an error message with --quiet' do
339
+ run_with_args('clear', 'bad.pdf', '--quiet') do |sf|
340
+ sf.should_not_receive(:say)
341
+ sf.should_not_receive(:say_status)
342
+ end
343
+ end
344
+
345
+ it 'does not print an error message with --force' do
346
+ run_with_args('clear', 'bad.pdf', '--force') do |sf|
347
+ sf.should_not_receive(:say)
348
+ sf.should_not_receive(:say_status)
349
+ end
350
+ end
351
+ end
352
+
353
+ context 'with a good file' do
354
+ before(:each) do
355
+ @path = copy_example('c_with_tag.c')
356
+ end
357
+ after(:each) do
358
+ File.unlink(@path)
359
+ end
360
+
361
+ it 'clears the tags' do
362
+ run_with_args('clear', @path)
363
+ run_with_args('get', @path) do |sf|
364
+ sf.should_receive(:say).with(/ no tags/)
365
+ end
366
+ end
367
+
368
+ it 'prints a success message' do
369
+ run_with_args('clear', @path) do |sf|
370
+ sf.should_receive(:say_status).with(:success, /Tags cleared for /, :green)
371
+ end
372
+ end
373
+
374
+ it 'prints nothing with --quiet' do
375
+ run_with_args('unset', @path, 'test', '--quiet') do |sf|
376
+ sf.should_not_receive(:say)
377
+ sf.should_not_receive(:say_status)
378
+ end
379
+ end
380
+ end
381
+ end
382
+
383
+ describe '#update' do
384
+ it 'updates in the current directory by default' do
385
+ run_with_args('update') do |sf|
386
+ sf.set_config(:root, '')
387
+ sf.should_receive(:update_database_from_files).with('.')
388
+ end
389
+ end
390
+
391
+ it 'updates from the configured root dir' do
392
+ run_with_args('update') do |sf|
393
+ sf.set_config(:root, '/usr/')
394
+ sf.should_receive(:update_database_from_files).with('/usr/')
395
+ end
396
+ end
397
+ end
398
+
399
+ describe '#tags' do
400
+ context 'with --quiet' do
401
+ it 'just prints all the tags, with no padding' do
402
+ run_with_args('tags', '--quiet') do |sf|
403
+ sf.update_database_from_files example_root
404
+ sf.should_receive(:say).with('asdf').once
405
+ sf.should_receive(:say).with(kind_of(String)).any_number_of_times
406
+ end
407
+ end
408
+ end
409
+
410
+ context 'without --quiet' do
411
+ it 'prints an intro message and padded tags' do
412
+ run_with_args('tags') do |sf|
413
+ sf.update_database_from_files example_root
414
+ sf.should_receive(:say).with('Tags currently in use:').once
415
+ sf.should_receive(:say).with(/ ?test/).once
416
+ sf.should_receive(:say).with(kind_of(String)).any_number_of_times
417
+ end
418
+ end
419
+ end
420
+ end
421
+
422
+ describe '#find' do
423
+ context 'with no tags' do
424
+ it 'raises an error' do
425
+ expect {
426
+ run_with_args('find')
427
+ }.to raise_error
428
+ end
429
+ end
430
+
431
+ context 'with an invalid tag' do
432
+ it 'raises an error' do
433
+ expect {
434
+ run_with_args('find', 'asdf,wut')
435
+ }.to raise_error
436
+ end
437
+ end
438
+
439
+ context 'with a missing tag' do
440
+ it 'prints a warning message' do
441
+ run_with_args('find', 'zuzzax') do |sf|
442
+ sf.update_database_from_files example_root
443
+ sf.should_receive(:say_status).with(:warning, /not present/, :yellow)
444
+ end
445
+ end
446
+
447
+ it 'prints nothing with --quiet' do
448
+ run_with_args('find', 'zuzzax', '--quiet') do |sf|
449
+ sf.update_database_from_files example_root
450
+ sf.should_not_receive(:say)
451
+ sf.should_not_receive(:say_status)
452
+ end
453
+ end
454
+ end
455
+
456
+ context 'with a bad boolean combo' do
457
+ it 'prints a warning message' do
458
+ run_with_args('find', 'test', 'asdf') do |sf|
459
+ sf.update_database_from_files example_root
460
+ sf.should_receive(:say_status).with(:warning, /not found/, :yellow)
461
+ end
462
+ end
463
+
464
+ it 'prints nothing with --quiet' do
465
+ run_with_args('find', 'test', 'asdf', '--quiet') do |sf|
466
+ sf.update_database_from_files example_root
467
+ sf.should_not_receive(:say)
468
+ sf.should_not_receive(:say_status)
469
+ end
470
+ end
471
+ end
472
+
473
+ context 'with a good tag' do
474
+ it 'prints some filenames' do
475
+ run_with_args('find', 'test') do |sf|
476
+ sf.update_database_from_files example_root
477
+ sf.should_receive(:say).with(/#{example_root}/).at_least(:once)
478
+ end
479
+ end
480
+ end
481
+ end
482
+ end
@@ -0,0 +1,3 @@
1
+ // all comments
2
+ // but no tags
3
+ //
@@ -0,0 +1,5 @@
1
+ // This is some example C++ code
2
+
3
+ int main(int argc, char *argv[]) {
4
+ return 0;
5
+ }
@@ -0,0 +1,6 @@
1
+ // SF_TAGS = test
2
+ // This is some example C++ code
3
+
4
+ int main(int argc, char *argv[]) {
5
+ return 0;
6
+ }
@@ -0,0 +1,6 @@
1
+ Author: Charles H. Pence
2
+ Description: This is a test of a key with a value
3
+ that goes on for lots and lots of
4
+ different lines and whatnot.
5
+ Date: October 8, 2012
6
+ Other: This file is all metadata, but has no tags
@@ -0,0 +1,8 @@
1
+ Author: Charles H. Pence
2
+ Description: This is a test of a key with a value
3
+ that goes on for lots and lots of
4
+ different lines and whatnot.
5
+ Tags: test
6
+ Date: October 8, 2012
7
+
8
+ This is a test MMD document.
@@ -0,0 +1,9 @@
1
+ Author: Charles H. Pence
2
+ Description: This is a test of a key with a value
3
+ that goes on for lots and lots of
4
+ different lines and whatnot.
5
+ Tags: asdf, sdfg, dfgh, fghj,
6
+ qwer
7
+ Date: October 8, 2012
8
+
9
+ This is a test MMD document.
@@ -0,0 +1 @@
1
+ This is a test MMD document.
@@ -0,0 +1,3 @@
1
+ Tags: test
2
+
3
+ This is a test MMD document.
@@ -0,0 +1,10 @@
1
+ % This is a comment
2
+ % Here's another comment
3
+
4
+ \documentclass[10pt]{article}
5
+ \begin{document}
6
+ \title{A TeX example}
7
+ \author{StickyFlag}
8
+ \date{\today}
9
+ \maketitle
10
+ \end{document}
@@ -0,0 +1,11 @@
1
+ % SF_TAGS = test
2
+ % This is a comment
3
+ % Here's another comment
4
+
5
+ \documentclass[10pt]{article}
6
+ \begin{document}
7
+ \title{A TeX example}
8
+ \author{StickyFlag}
9
+ \date{\today}
10
+ \maketitle
11
+ \end{document}
File without changes
@@ -0,0 +1,32 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'fileutils'
3
+ require 'pathname'
4
+ require 'tmpdir'
5
+
6
+ def example_root
7
+ File.expand_path(File.join(File.dirname(__FILE__), 'examples'))
8
+ end
9
+
10
+ def example_path(example)
11
+ File.expand_path(File.join(File.dirname(__FILE__), 'examples', example))
12
+ end
13
+
14
+ def copy_example(example)
15
+ path = example_path(example)
16
+ temp_path = File.expand_path(File.join(Dir.tmpdir, "temp-#{Random.rand(1000)}-#{example}"))
17
+
18
+ # If the file doesn't exist, then just return a bad file path
19
+ if File.exist? path
20
+ counter = 0
21
+ while File.exist? temp_path
22
+ temp_path = File.expand_path(File.join(Dir.tmpdir, "temp-#{Random.rand(1000)}-#{example}"))
23
+ counter += 1
24
+
25
+ raise "Cannot create temporary file" if counter >= 100
26
+ end
27
+
28
+ FileUtils.cp(path, temp_path)
29
+ end
30
+
31
+ temp_path
32
+ end
@@ -0,0 +1,36 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'thor'
3
+ require 'stickyflag'
4
+
5
+ class DatabaseHelper
6
+ def database_path
7
+ ":memory:"
8
+ end
9
+
10
+ include StickyFlag::Database
11
+ end
12
+
13
+ def run_with_args(*args)
14
+ # We want to load an in-memory database ourselves, so that we can tear it
15
+ # down in this function (there's nowhere to hook in Thor for after the
16
+ # task is completed)
17
+ dbh = DatabaseHelper.new
18
+ dbh.load_database
19
+ database = dbh.instance_variable_get(:@database)
20
+
21
+ StickyFlag::ThorApp.send(:dispatch, nil, args, nil, {}) do |instance|
22
+ # Always stub out load_ and save_config! and database_path, so that we
23
+ # don't tromp on the user's own private data.
24
+ instance.stub(:load_config!) { }
25
+ instance.stub(:save_config!) { }
26
+
27
+ # Patch in the new database
28
+ instance.instance_variable_set(:@database, database)
29
+ instance.create_tables
30
+
31
+ yield instance if block_given?
32
+ end
33
+
34
+ # Clean up
35
+ database.disconnect
36
+ end
@@ -0,0 +1,12 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ module Kernel
4
+ def silence_stream(stream)
5
+ old_stream = stream.dup
6
+ stream.reopen(RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ ? 'NUL:' : '/dev/null')
7
+ stream.sync = true
8
+ yield
9
+ ensure
10
+ stream.reopen(old_stream)
11
+ end
12
+ end