whenever-benlangfeld 0.9.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.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +6 -0
  3. data/.travis.yml +18 -0
  4. data/CHANGELOG.md +333 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE +22 -0
  7. data/README.md +260 -0
  8. data/Rakefile +10 -0
  9. data/bin/whenever +41 -0
  10. data/bin/wheneverize +68 -0
  11. data/gemfiles/activesupport4.1.gemfile +5 -0
  12. data/gemfiles/activesupport4.2.gemfile +5 -0
  13. data/lib/whenever.rb +34 -0
  14. data/lib/whenever/capistrano.rb +7 -0
  15. data/lib/whenever/capistrano/v2/hooks.rb +8 -0
  16. data/lib/whenever/capistrano/v2/recipes.rb +48 -0
  17. data/lib/whenever/capistrano/v2/support.rb +53 -0
  18. data/lib/whenever/capistrano/v3/tasks/whenever.rake +45 -0
  19. data/lib/whenever/command_line.rb +135 -0
  20. data/lib/whenever/cron.rb +153 -0
  21. data/lib/whenever/job.rb +54 -0
  22. data/lib/whenever/job_list.rb +155 -0
  23. data/lib/whenever/numeric.rb +13 -0
  24. data/lib/whenever/numeric_seconds.rb +48 -0
  25. data/lib/whenever/os.rb +7 -0
  26. data/lib/whenever/output_redirection.rb +57 -0
  27. data/lib/whenever/setup.rb +26 -0
  28. data/lib/whenever/tasks/whenever.rake +1 -0
  29. data/lib/whenever/version.rb +3 -0
  30. data/test/functional/command_line_test.rb +331 -0
  31. data/test/functional/output_at_test.rb +207 -0
  32. data/test/functional/output_default_defined_jobs_test.rb +296 -0
  33. data/test/functional/output_defined_job_test.rb +85 -0
  34. data/test/functional/output_env_test.rb +29 -0
  35. data/test/functional/output_jobs_for_roles_test.rb +65 -0
  36. data/test/functional/output_redirection_test.rb +248 -0
  37. data/test/test_case.rb +32 -0
  38. data/test/test_helper.rb +37 -0
  39. data/test/unit/capistrano_support_test.rb +147 -0
  40. data/test/unit/cron_test.rb +244 -0
  41. data/test/unit/job_test.rb +114 -0
  42. data/whenever.gemspec +27 -0
  43. metadata +167 -0
@@ -0,0 +1,26 @@
1
+ # Environment variable defaults to RAILS_ENV
2
+ set :environment_variable, "RAILS_ENV"
3
+ # Environment defaults to production
4
+ set :environment, "production"
5
+ # Path defaults to the directory `whenever` was run from
6
+ set :path, Whenever.path
7
+
8
+ # All jobs are wrapped in this template.
9
+ # http://blog.scoutapp.com/articles/2010/09/07/rvm-and-cron-in-production
10
+ set :job_template, "/bin/bash -l -c ':job'"
11
+
12
+ set :runner_command, case
13
+ when Whenever.bin_rails?
14
+ "bin/rails runner"
15
+ when Whenever.script_rails?
16
+ "script/rails runner"
17
+ else
18
+ "script/runner"
19
+ end
20
+
21
+ set :bundle_command, Whenever.bundler? ? "bundle exec" : ""
22
+
23
+ job_type :command, ":task :output"
24
+ job_type :rake, "cd :path && :environment_variable=:environment :bundle_command rake :task --silent :output"
25
+ job_type :script, "cd :path && :environment_variable=:environment :bundle_command script/:task :output"
26
+ job_type :runner, "cd :path && :bundle_command :runner_command -e :environment ':task' :output"
@@ -0,0 +1 @@
1
+ ../capistrano/v3/tasks/whenever.rake
@@ -0,0 +1,3 @@
1
+ module Whenever
2
+ VERSION = '0.9.5'
3
+ end
@@ -0,0 +1,331 @@
1
+ require 'test_helper'
2
+
3
+ class CommandLineWriteTest < Whenever::TestCase
4
+ setup do
5
+ File.expects(:exist?).with('config/schedule.rb').returns(true)
6
+ @command = Whenever::CommandLine.new(:write => true, :identifier => 'My identifier')
7
+ @task = "#{two_hours} /my/command"
8
+ Whenever.expects(:cron).returns(@task)
9
+ end
10
+
11
+ should "output the cron job with identifier blocks" do
12
+ output = <<-EXPECTED
13
+ # Begin Whenever generated tasks for: My identifier
14
+ #{@task}
15
+ # End Whenever generated tasks for: My identifier
16
+ EXPECTED
17
+
18
+ assert_equal output, @command.send(:whenever_cron)
19
+ end
20
+
21
+ should "write the crontab when run" do
22
+ @command.expects(:write_crontab).returns(true)
23
+ assert @command.run
24
+ end
25
+ end
26
+
27
+ class CommandLineUpdateTest < Whenever::TestCase
28
+ setup do
29
+ File.expects(:exist?).with('config/schedule.rb').returns(true)
30
+ @command = Whenever::CommandLine.new(:update => true, :identifier => 'My identifier')
31
+ @task = "#{two_hours} /my/command"
32
+ Whenever.expects(:cron).returns(@task)
33
+ end
34
+
35
+ should "add the cron to the end of the file if there is no existing identifier block" do
36
+ existing = '# Existing crontab'
37
+ @command.expects(:read_crontab).at_least_once.returns(existing)
38
+
39
+ new_cron = <<-EXPECTED
40
+ #{existing}
41
+
42
+ # Begin Whenever generated tasks for: My identifier
43
+ #{@task}
44
+ # End Whenever generated tasks for: My identifier
45
+ EXPECTED
46
+
47
+ assert_equal new_cron, @command.send(:updated_crontab)
48
+
49
+ @command.expects(:write_crontab).with(new_cron).returns(true)
50
+ assert @command.run
51
+ end
52
+
53
+ should "replace an existing block if the identifier matches" do
54
+ existing = <<-EXISTING_CRON
55
+ # Something
56
+
57
+ # Begin Whenever generated tasks for: My identifier
58
+ My whenever job that was already here
59
+ # End Whenever generated tasks for: My identifier
60
+
61
+ # Begin Whenever generated tasks for: Other identifier
62
+ This shouldn't get replaced
63
+ # End Whenever generated tasks for: Other identifier
64
+ EXISTING_CRON
65
+
66
+ new_cron = <<-NEW_CRON
67
+ # Something
68
+
69
+ # Begin Whenever generated tasks for: My identifier
70
+ #{@task}
71
+ # End Whenever generated tasks for: My identifier
72
+
73
+ # Begin Whenever generated tasks for: Other identifier
74
+ This shouldn't get replaced
75
+ # End Whenever generated tasks for: Other identifier
76
+ NEW_CRON
77
+
78
+ @command.expects(:read_crontab).at_least_once.returns(existing)
79
+ assert_equal new_cron, @command.send(:updated_crontab)
80
+
81
+ @command.expects(:write_crontab).with(new_cron).returns(true)
82
+ assert @command.run
83
+ end
84
+ end
85
+
86
+ class CommandLineUpdateWithBackslashesTest < Whenever::TestCase
87
+ setup do
88
+ @existing = <<-EXISTING_CRON
89
+ # Begin Whenever generated tasks for: My identifier
90
+ script/runner -e production 'puts '\\''hello'\\'''
91
+ # End Whenever generated tasks for: My identifier
92
+ EXISTING_CRON
93
+ File.expects(:exist?).with('config/schedule.rb').returns(true)
94
+ @command = Whenever::CommandLine.new(:update => true, :identifier => 'My identifier')
95
+ @command.expects(:read_crontab).at_least_once.returns(@existing)
96
+ @command.expects(:whenever_cron).returns(@existing)
97
+ end
98
+
99
+ should "replace the existing block with the backslashes in tact" do
100
+ assert_equal @existing, @command.send(:updated_crontab)
101
+ end
102
+ end
103
+
104
+ class CommandLineUpdateToSimilarCrontabTest < Whenever::TestCase
105
+ setup do
106
+ @existing = <<-EXISTING_CRON
107
+ # Begin Whenever generated tasks for: WheneverExisting
108
+ # End Whenever generated tasks for: WheneverExisting
109
+ EXISTING_CRON
110
+ @new = <<-NEW_CRON
111
+ # Begin Whenever generated tasks for: Whenever
112
+ # End Whenever generated tasks for: Whenever
113
+ NEW_CRON
114
+ File.expects(:exist?).with('config/schedule.rb').returns(true)
115
+ @command = Whenever::CommandLine.new(:update => true, :identifier => 'Whenever')
116
+ @command.expects(:read_crontab).at_least_once.returns(@existing)
117
+ @command.expects(:whenever_cron).returns(@new)
118
+ end
119
+
120
+ should "append the similarly named command" do
121
+ assert_equal @existing + "\n" + @new, @command.send(:updated_crontab)
122
+ end
123
+ end
124
+
125
+ class CommandLineClearTest < Whenever::TestCase
126
+ setup do
127
+ File.expects(:exist?).with('config/schedule.rb').returns(true)
128
+ @command = Whenever::CommandLine.new(:clear => true, :identifier => 'My identifier')
129
+ @task = "#{two_hours} /my/command"
130
+ end
131
+
132
+ should "clear an existing block if the identifier matches" do
133
+ existing = <<-EXISTING_CRON
134
+ # Something
135
+
136
+ # Begin Whenever generated tasks for: My identifier
137
+ My whenever job that was already here
138
+ # End Whenever generated tasks for: My identifier
139
+
140
+ # Begin Whenever generated tasks for: Other identifier
141
+ This shouldn't get replaced
142
+ # End Whenever generated tasks for: Other identifier
143
+ EXISTING_CRON
144
+
145
+ @command.expects(:read_crontab).at_least_once.returns(existing)
146
+
147
+ new_cron = <<-NEW_CRON
148
+ # Something
149
+
150
+ # Begin Whenever generated tasks for: Other identifier
151
+ This shouldn't get replaced
152
+ # End Whenever generated tasks for: Other identifier
153
+ NEW_CRON
154
+
155
+ assert_equal new_cron, @command.send(:updated_crontab)
156
+
157
+ @command.expects(:write_crontab).with(new_cron).returns(true)
158
+ assert @command.run
159
+ end
160
+ end
161
+
162
+ class CommandLineClearWithNoScheduleTest < Whenever::TestCase
163
+ setup do
164
+ File.expects(:exist?).with('config/schedule.rb').returns(false)
165
+ @command = Whenever::CommandLine.new(:clear => true, :identifier => 'My identifier')
166
+ end
167
+
168
+ should "run successfully" do
169
+ @command.expects(:write_crontab).returns(true)
170
+ assert @command.run
171
+ end
172
+ end
173
+
174
+ class CommandLineUpdateWithNoIdentifierTest < Whenever::TestCase
175
+ setup do
176
+ File.expects(:exist?).with('config/schedule.rb').returns(true)
177
+ Whenever::CommandLine.any_instance.expects(:default_identifier).returns('DEFAULT')
178
+ @command = Whenever::CommandLine.new(:update => true, :file => @file)
179
+ end
180
+
181
+ should "use the default identifier" do
182
+ assert_equal "Whenever generated tasks for: DEFAULT", @command.send(:comment_base)
183
+ end
184
+ end
185
+
186
+ class CombinedParamsTest < Whenever::TestCase
187
+ setup do
188
+ Whenever::CommandLine.any_instance.expects(:exit)
189
+ Whenever::CommandLine.any_instance.expects(:warn)
190
+ File.expects(:exist?).with('config/schedule.rb').returns(true)
191
+ end
192
+
193
+ should "exit with write and clear" do
194
+ @command = Whenever::CommandLine.new(:write => true, :clear => true)
195
+ end
196
+
197
+ should "exit with write and update" do
198
+ @command = Whenever::CommandLine.new(:write => true, :update => true)
199
+ end
200
+
201
+ should "exit with update and clear" do
202
+ @command = Whenever::CommandLine.new(:update => true, :clear => true)
203
+ end
204
+ end
205
+
206
+ class RunnerOverwrittenWithSetOptionTest < Whenever::TestCase
207
+ setup do
208
+ @output = Whenever.cron :set => 'environment=serious', :string => \
209
+ <<-file
210
+ set :job_template, nil
211
+ set :environment, :silly
212
+ set :path, '/my/path'
213
+ every 2.hours do
214
+ runner "blahblah"
215
+ end
216
+ file
217
+ end
218
+
219
+ should "output the runner using the override environment" do
220
+ assert_match two_hours + %( cd /my/path && bundle exec script/runner -e serious 'blahblah'), @output
221
+ end
222
+ end
223
+
224
+
225
+ class EnvironmentAndPathOverwrittenWithSetOptionTest < Whenever::TestCase
226
+ setup do
227
+ @output = Whenever.cron :set => 'environment=serious&path=/serious/path', :string => \
228
+ <<-file
229
+ set :job_template, nil
230
+ set :environment, :silly
231
+ set :path, '/silly/path'
232
+ every 2.hours do
233
+ runner "blahblah"
234
+ end
235
+ file
236
+ end
237
+
238
+ should "output the runner using the overridden path and environment" do
239
+ assert_match two_hours + %( cd /serious/path && bundle exec script/runner -e serious 'blahblah'), @output
240
+ end
241
+ end
242
+
243
+ class EnvironmentAndPathOverwrittenWithSetOptionWithSpacesTest < Whenever::TestCase
244
+ setup do
245
+ @output = Whenever.cron :set => ' environment = serious& path =/serious/path', :string => \
246
+ <<-file
247
+ set :job_template, nil
248
+ set :environment, :silly
249
+ set :path, '/silly/path'
250
+ every 2.hours do
251
+ runner "blahblah"
252
+ end
253
+ file
254
+ end
255
+
256
+ should "output the runner using the overridden path and environment" do
257
+ assert_match two_hours + %( cd /serious/path && bundle exec script/runner -e serious 'blahblah'), @output
258
+ end
259
+ end
260
+
261
+ class EnvironmentOverwrittenWithoutValueTest < Whenever::TestCase
262
+ setup do
263
+ @output = Whenever.cron :set => ' environment=', :string => \
264
+ <<-file
265
+ set :job_template, nil
266
+ set :environment, :silly
267
+ set :path, '/silly/path'
268
+ every 2.hours do
269
+ runner "blahblah"
270
+ end
271
+ file
272
+ end
273
+
274
+ should "output the runner using the original environmnet" do
275
+ assert_match two_hours + %( cd /silly/path && bundle exec script/runner -e silly 'blahblah'), @output
276
+ end
277
+ end
278
+
279
+ class PreparingOutputTest < Whenever::TestCase
280
+ setup do
281
+ File.expects(:exist?).with('config/schedule.rb').returns(true)
282
+ end
283
+
284
+ should "not trim off the top lines of the file" do
285
+ @command = Whenever::CommandLine.new(:update => true, :identifier => 'My identifier', :cut => 0)
286
+ existing = <<-EXISTING_CRON
287
+ # Useless Comments
288
+ # at the top of the file
289
+
290
+ # Begin Whenever generated tasks for: My identifier
291
+ My whenever job that was already here
292
+ # End Whenever generated tasks for: My identifier
293
+ EXISTING_CRON
294
+
295
+ assert_equal existing, @command.send(:prepare, existing)
296
+ end
297
+
298
+ should "trim off the top lines of the file" do
299
+ @command = Whenever::CommandLine.new(:update => true, :identifier => 'My identifier', :cut => '3')
300
+ existing = <<-EXISTING_CRON
301
+ # Useless Comments
302
+ # at the top of the file
303
+
304
+ # Begin Whenever generated tasks for: My identifier
305
+ My whenever job that was already here
306
+ # End Whenever generated tasks for: My identifier
307
+ EXISTING_CRON
308
+
309
+ new_cron = <<-NEW_CRON
310
+ # Begin Whenever generated tasks for: My identifier
311
+ My whenever job that was already here
312
+ # End Whenever generated tasks for: My identifier
313
+ NEW_CRON
314
+
315
+ assert_equal new_cron, @command.send(:prepare, existing)
316
+ end
317
+
318
+ should "preserve terminating newlines in files" do
319
+ @command = Whenever::CommandLine.new(:update => true, :identifier => 'My identifier')
320
+ existing = <<-EXISTING_CRON
321
+ # Begin Whenever generated tasks for: My identifier
322
+ My whenever job that was already here
323
+ # End Whenever generated tasks for: My identifier
324
+
325
+ # A non-Whenever task
326
+ My non-whenever job that was already here
327
+ EXISTING_CRON
328
+
329
+ assert_equal existing, @command.send(:prepare, existing)
330
+ end
331
+ end
@@ -0,0 +1,207 @@
1
+ require 'test_helper'
2
+
3
+ class OutputAtTest < Whenever::TestCase
4
+ test "weekday at a (single) given time" do
5
+ output = Whenever.cron \
6
+ <<-file
7
+ set :job_template, nil
8
+ every "weekday", :at => '5:02am' do
9
+ command "blahblah"
10
+ end
11
+ file
12
+
13
+ assert_match '2 5 * * 1-5 blahblah', output
14
+ end
15
+
16
+ test "weekday at a multiple diverse times, via an array" do
17
+ output = Whenever.cron \
18
+ <<-file
19
+ set :job_template, nil
20
+ every "weekday", :at => %w(5:02am 3:52pm) do
21
+ command "blahblah"
22
+ end
23
+ file
24
+
25
+ assert_match '2 5 * * 1-5 blahblah', output
26
+ assert_match '52 15 * * 1-5 blahblah', output
27
+ end
28
+
29
+ test "weekday at a multiple diverse times, comma separated" do
30
+ output = Whenever.cron \
31
+ <<-file
32
+ set :job_template, nil
33
+ every "weekday", :at => '5:02am, 3:52pm' do
34
+ command "blahblah"
35
+ end
36
+ file
37
+
38
+ assert_match '2 5 * * 1-5 blahblah', output
39
+ assert_match '52 15 * * 1-5 blahblah', output
40
+ end
41
+
42
+ test "weekday at a multiple aligned times" do
43
+ output = Whenever.cron \
44
+ <<-file
45
+ set :job_template, nil
46
+ every "weekday", :at => '5:02am, 3:02pm' do
47
+ command "blahblah"
48
+ end
49
+ file
50
+
51
+ assert_match '2 5,15 * * 1-5 blahblah', output
52
+ end
53
+
54
+ test "various days at a various aligned times" do
55
+ output = Whenever.cron \
56
+ <<-file
57
+ set :job_template, nil
58
+ every "mon,wed,fri", :at => '5:02am, 3:02pm' do
59
+ command "blahblah"
60
+ end
61
+ file
62
+
63
+ assert_match '2 5,15 * * 1,3,5 blahblah', output
64
+ end
65
+
66
+ test "various days at a various aligned times using a runner" do
67
+ output = Whenever.cron \
68
+ <<-file
69
+ set :job_template, nil
70
+ set :path, '/your/path'
71
+ every "mon,wed,fri", :at => '5:02am, 3:02pm' do
72
+ runner "Worker.perform_async(1.day.ago)"
73
+ end
74
+ file
75
+
76
+ assert_match %(2 5,15 * * 1,3,5 cd /your/path && bundle exec script/runner -e production 'Worker.perform_async(1.day.ago)'), output
77
+ end
78
+
79
+ test "various days at a various aligned times using a rake task" do
80
+ output = Whenever.cron \
81
+ <<-file
82
+ set :job_template, nil
83
+ set :path, '/your/path'
84
+ every "mon,wed,fri", :at => '5:02am, 3:02pm' do
85
+ rake "blah:blah"
86
+ end
87
+ file
88
+
89
+ assert_match '2 5,15 * * 1,3,5 cd /your/path && RAILS_ENV=production bundle exec rake blah:blah --silent', output
90
+ end
91
+
92
+ test "A command every 1.month at very diverse times" do
93
+ output = Whenever.cron \
94
+ <<-file
95
+ set :job_template, nil
96
+ every [1.month, 1.day], :at => 'january 5:02am, june 17th at 2:22pm, june 3rd at 3:33am' do
97
+ command "blahblah"
98
+ end
99
+ file
100
+
101
+ # The 1.month commands
102
+ assert_match '2 5 1 * * blahblah', output
103
+ assert_match '22 14 17 * * blahblah', output
104
+ assert_match '33 3 3 * * blahblah', output
105
+
106
+ # The 1.day commands
107
+ assert_match '2 5 * * * blahblah', output
108
+ assert_match '22 14 * * * blahblah', output
109
+ assert_match '33 3 * * * blahblah', output
110
+ end
111
+
112
+ test "Multiple commands output every :reboot" do
113
+ output = Whenever.cron \
114
+ <<-file
115
+ set :job_template, nil
116
+ every :reboot do
117
+ command "command_1"
118
+ command "command_2"
119
+ end
120
+ file
121
+
122
+ assert_match "@reboot command_1", output
123
+ assert_match "@reboot command_2", output
124
+ end
125
+
126
+ test "Many different job types output every :day" do
127
+ output = Whenever.cron \
128
+ <<-file
129
+ set :job_template, nil
130
+ set :path, '/your/path'
131
+ every :daily do
132
+ rake "blah:blah"
133
+ runner "runner_1"
134
+ command "command_1"
135
+ runner "runner_2"
136
+ command "command_2"
137
+ end
138
+ file
139
+
140
+ assert_match '@daily cd /your/path && RAILS_ENV=production bundle exec rake blah:blah --silent', output
141
+ assert_match %(@daily cd /your/path && bundle exec script/runner -e production 'runner_1'), output
142
+ assert_match '@daily command_1', output
143
+ assert_match %(@daily cd /your/path && bundle exec script/runner -e production 'runner_2'), output
144
+ assert_match '@daily command_2', output
145
+ end
146
+
147
+ test "every 5 minutes but but starting at 1" do
148
+ output = Whenever.cron \
149
+ <<-file
150
+ set :job_template, nil
151
+ every 5.minutes, :at => 1 do
152
+ command "blahblah"
153
+ end
154
+ file
155
+
156
+ assert_match '1,6,11,16,21,26,31,36,41,46,51,56 * * * * blahblah', output
157
+ end
158
+
159
+ test "every 4 minutes but starting at 2" do
160
+ output = Whenever.cron \
161
+ <<-file
162
+ set :job_template, nil
163
+ every 4.minutes, :at => 2 do
164
+ command "blahblah"
165
+ end
166
+ file
167
+
168
+ assert_match '2,6,10,14,18,22,26,30,34,38,42,46,50,54,58 * * * * blahblah', output
169
+ end
170
+
171
+ test "every 3 minutes but starting at 7" do
172
+ output = Whenever.cron \
173
+ <<-file
174
+ set :job_template, nil
175
+ every 3.minutes, :at => 7 do
176
+ command "blahblah"
177
+ end
178
+ file
179
+
180
+
181
+ assert_match '7,10,13,16,19,22,25,28,31,34,37,40,43,46,49,52,55,58 * * * * blahblah', output
182
+ end
183
+
184
+ test "every 2 minutes but starting at 27" do
185
+ output = Whenever.cron \
186
+ <<-file
187
+ set :job_template, nil
188
+ every 2.minutes, :at => 27 do
189
+ command "blahblah"
190
+ end
191
+ file
192
+
193
+ assert_match '27,29,31,33,35,37,39,41,43,45,47,49,51,53,55,57,59 * * * * blahblah', output
194
+ end
195
+
196
+ test "using raw cron syntax" do
197
+ output = Whenever.cron \
198
+ <<-file
199
+ set :job_template, nil
200
+ every '0 0 27,31 * *' do
201
+ command "blahblah"
202
+ end
203
+ file
204
+
205
+ assert_match '0 0 27,31 * * blahblah', output
206
+ end
207
+ end