whenever 0.9.7 → 1.0.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.
- checksums.yaml +5 -5
- data/.travis.yml +12 -9
- data/Appraisals +19 -0
- data/CHANGELOG.md +33 -1
- data/Gemfile +1 -1
- data/LICENSE +1 -1
- data/README.md +89 -20
- data/bin/whenever +3 -0
- data/bin/wheneverize +5 -2
- data/gemfiles/activesupport4.1.gemfile +3 -1
- data/gemfiles/activesupport4.2.gemfile +3 -1
- data/gemfiles/activesupport5.0.gemfile +7 -0
- data/gemfiles/activesupport5.1.gemfile +7 -0
- data/gemfiles/activesupport5.2.gemfile +7 -0
- data/lib/whenever/capistrano/v2/recipes.rb +3 -2
- data/lib/whenever/capistrano/v3/tasks/whenever.rake +17 -4
- data/lib/whenever/command_line.rb +39 -19
- data/lib/whenever/cron.rb +43 -15
- data/lib/whenever/job.rb +2 -1
- data/lib/whenever/job_list.rb +50 -20
- data/lib/whenever/numeric.rb +1 -1
- data/lib/whenever/setup.rb +4 -0
- data/lib/whenever/version.rb +1 -1
- data/test/functional/command_line_test.rb +159 -32
- data/test/functional/output_at_test.rb +39 -0
- data/test/functional/output_jobs_with_mailto_test.rb +168 -0
- data/test/test_helper.rb +18 -8
- data/test/unit/cron_test.rb +178 -4
- data/test/unit/executable_test.rb +142 -0
- data/whenever.gemspec +1 -0
- metadata +25 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: dc5ff14e6e9d357583f5e20d31fafbcf2dfe3aea8ac756cf9103f51504674e9a
|
4
|
+
data.tar.gz: 446e8398b741a1a9a7ee262b3542efb107d1453259083fef03ea50726227d7dd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 41f396515f594a4726bd9048783653b0b203e0beb4ea65f6b95faf508061d0fd064bec0a31bbcf6dad6a23f68ec4f3364ae6e8f160eb0539ec6073a6c4960242
|
7
|
+
data.tar.gz: 4fbe2b52fc350ee272d7d03638369b8a6443c1ed6e122be511b9ccf07881c1e559d63587153259343febc89db40aa45bc4ca45cf83af885fd618fd5668ddd1d2
|
data/.travis.yml
CHANGED
@@ -1,18 +1,21 @@
|
|
1
1
|
language: ruby
|
2
|
-
script: bundle exec rake
|
3
2
|
|
4
3
|
before_install:
|
5
4
|
- gem install bundler
|
6
|
-
|
5
|
+
- unset _JAVA_OPTIONS
|
7
6
|
rvm:
|
8
|
-
-
|
9
|
-
- 2.
|
10
|
-
- 2.
|
11
|
-
-
|
12
|
-
- 2.3.0
|
13
|
-
- jruby
|
7
|
+
- 2.4.6
|
8
|
+
- 2.5.5
|
9
|
+
- 2.6.3
|
10
|
+
- jruby-9.2.6.0
|
14
11
|
|
15
12
|
gemfile:
|
16
|
-
- Gemfile
|
17
13
|
- gemfiles/activesupport4.1.gemfile
|
18
14
|
- gemfiles/activesupport4.2.gemfile
|
15
|
+
- gemfiles/activesupport5.0.gemfile
|
16
|
+
- gemfiles/activesupport5.1.gemfile
|
17
|
+
- gemfiles/activesupport5.2.gemfile
|
18
|
+
|
19
|
+
env:
|
20
|
+
global:
|
21
|
+
- JRUBY_OPTS=--debug
|
data/Appraisals
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
appraise 'activesupport4.1' do
|
2
|
+
gem "activesupport", "~> 4.1.0"
|
3
|
+
end
|
4
|
+
|
5
|
+
appraise 'activesupport4.2' do
|
6
|
+
gem "activesupport", "~> 4.2.0"
|
7
|
+
end
|
8
|
+
|
9
|
+
appraise 'activesupport5.0' do
|
10
|
+
gem "activesupport", "~> 5.0.0"
|
11
|
+
end
|
12
|
+
|
13
|
+
appraise 'activesupport5.1' do
|
14
|
+
gem "activesupport", "~> 5.1.0"
|
15
|
+
end
|
16
|
+
|
17
|
+
appraise 'activesupport5.2' do
|
18
|
+
gem "activesupport", "~> 5.2.0beta2"
|
19
|
+
end
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,36 @@
|
|
1
|
-
###
|
1
|
+
### unreleased
|
2
|
+
|
3
|
+
### 1.0.0 / Jun 13, 2019
|
4
|
+
|
5
|
+
* First stable release per SemVer.
|
6
|
+
|
7
|
+
* Removes support for versions of Ruby which are no longer supported by the Ruby project.
|
8
|
+
|
9
|
+
### 0.11.0 / April 23, 2019
|
10
|
+
|
11
|
+
* Add support for mapping Range objects to cron range syntax [Tim Craft](https://github.com/javan/whenever/pull/725)
|
12
|
+
|
13
|
+
* Bugfix: Avoid modifying Capistrano `default_env` when setting the whenever environment. [ta1kt0me](https://github.com/javan/whenever/pull/728)
|
14
|
+
|
15
|
+
* Enable to execute whenever's task independently without setting :release_path or :whenever_path [ta1kt0me](https://github.com/javan/whenever/pull/729)
|
16
|
+
|
17
|
+
* Make error message clearer when parsing cron syntax fails due to a trailing space [ignisf](https://github.com/javan/whenever/pull/744)
|
18
|
+
|
19
|
+
### 0.10.0 / November 19, 2017
|
20
|
+
|
21
|
+
* Modify wheneverize to allow for the creating of 'config' directory when not present
|
22
|
+
|
23
|
+
* Add --crontab-command to whenever binary for overriding the crontab command. [Martin Grandrath]
|
24
|
+
|
25
|
+
* Allow setting the path within which Capistrano will execute whenever. [Samuel Johnson](https://github.com/javan/whenever/pull/619)
|
26
|
+
|
27
|
+
* Allow the use of string literals for month and day-of-week in raw cron syntax.. [Potamianos Gregory](https://github.com/javan/whenever/pull/711)
|
28
|
+
|
29
|
+
* Include Capistrano default environment variables when executing Whenever. [Karl Li](https://github.com/javan/whenever/pull/719)
|
30
|
+
|
31
|
+
* Allow configuring an alternative schedule file in Capistrano. [Shinichi Okamoto](https://github.com/javan/whenever/pull/666)
|
32
|
+
|
33
|
+
* Add customizing email recipient option with the MAILTO environment variable. [Chikahiro Tokoro](https://github.com/javan/whenever/pull/678)
|
2
34
|
|
3
35
|
### 0.9.7 / June 14, 2016
|
4
36
|
|
data/Gemfile
CHANGED
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -9,7 +9,7 @@ $ gem install whenever
|
|
9
9
|
Or with Bundler in your Gemfile.
|
10
10
|
|
11
11
|
```ruby
|
12
|
-
gem 'whenever', :
|
12
|
+
gem 'whenever', require: false
|
13
13
|
```
|
14
14
|
|
15
15
|
### Getting started
|
@@ -19,7 +19,7 @@ $ cd /apps/my-great-project
|
|
19
19
|
$ wheneverize .
|
20
20
|
```
|
21
21
|
|
22
|
-
This will create an initial `config/schedule.rb` file for you.
|
22
|
+
This will create an initial `config/schedule.rb` file for you (as long as the config folder is already present in your project).
|
23
23
|
|
24
24
|
### The `whenever` command
|
25
25
|
|
@@ -34,28 +34,39 @@ This will simply show you your `schedule.rb` file converted to cron syntax. It d
|
|
34
34
|
$ whenever --update-crontab
|
35
35
|
```
|
36
36
|
|
37
|
+
Other commonly used options include:
|
38
|
+
```sh
|
39
|
+
$ whenever --user app # set a user as which to install the crontab
|
40
|
+
$ whenever --load-file config/my_schedule.rb # set the schedule file
|
41
|
+
$ whenever --crontab-command 'sudo crontab' # override the crontab command
|
42
|
+
```
|
43
|
+
|
37
44
|
You can list installed cron jobs using `crontab -l`.
|
38
45
|
|
39
|
-
Run `whenever --help` for a complete list of options for selecting the schedule to use, setting variables in the schedule,
|
46
|
+
Run `whenever --help` for a complete list of options for selecting the schedule to use, setting variables in the schedule, etc.
|
40
47
|
|
41
48
|
### Example schedule.rb file
|
42
49
|
|
43
50
|
```ruby
|
44
|
-
every 3.hours do
|
51
|
+
every 3.hours do # 1.minute 1.day 1.week 1.month 1.year is also supported
|
45
52
|
runner "MyModel.some_process"
|
46
53
|
rake "my:rake:task"
|
47
54
|
command "/usr/bin/my_great_command"
|
48
55
|
end
|
49
56
|
|
50
|
-
every 1.day, :
|
57
|
+
every 1.day, at: '4:30 am' do
|
51
58
|
runner "MyModel.task_to_run_at_four_thirty_in_the_morning"
|
52
59
|
end
|
53
60
|
|
61
|
+
every 1.day, at: ['4:30 am', '6:00 pm'] do
|
62
|
+
runner "Mymodel.task_to_run_in_two_times_every_day"
|
63
|
+
end
|
64
|
+
|
54
65
|
every :hour do # Many shortcuts available: :hour, :day, :month, :year, :reboot
|
55
66
|
runner "SomeModel.ladeeda"
|
56
67
|
end
|
57
68
|
|
58
|
-
every :sunday, :
|
69
|
+
every :sunday, at: '12pm' do # Use any day of the week or :weekend, :weekday
|
59
70
|
runner "Task.do_something_great"
|
60
71
|
end
|
61
72
|
|
@@ -65,7 +76,7 @@ end
|
|
65
76
|
|
66
77
|
# run this task only on servers with the :app role in Capistrano
|
67
78
|
# see Capistrano roles section below
|
68
|
-
every :day, :
|
79
|
+
every :day, at: '12:20am', roles: [:app] do
|
69
80
|
rake "app_server:task"
|
70
81
|
end
|
71
82
|
```
|
@@ -80,7 +91,7 @@ For example:
|
|
80
91
|
job_type :awesome, '/usr/local/bin/awesome :task :fun_level'
|
81
92
|
|
82
93
|
every 2.hours do
|
83
|
-
awesome "party", :
|
94
|
+
awesome "party", fun_level: "extreme"
|
84
95
|
end
|
85
96
|
```
|
86
97
|
|
@@ -113,6 +124,57 @@ Or set the job_template to nil to have your jobs execute normally.
|
|
113
124
|
set :job_template, nil
|
114
125
|
```
|
115
126
|
|
127
|
+
### Parsing dates and times
|
128
|
+
|
129
|
+
Whenever uses the [Chronic](https://github.com/mojombo/chronic) gem to parse the specified dates and times.
|
130
|
+
|
131
|
+
You can set your custom Chronic configuration if the defaults don't fit you.
|
132
|
+
|
133
|
+
For example, to assume a 24 hour clock instead of the default 12 hour clock:
|
134
|
+
|
135
|
+
```ruby
|
136
|
+
set :chronic_options, hours24: true
|
137
|
+
|
138
|
+
# By default this would run the job every day at 3am
|
139
|
+
every 1.day, at: '3:00' do
|
140
|
+
runner "MyModel.nightly_archive_job"
|
141
|
+
end
|
142
|
+
```
|
143
|
+
|
144
|
+
You can see a list of all available options here: <https://github.com/mojombo/chronic/blob/master/lib/chronic/parser.rb>
|
145
|
+
|
146
|
+
### Customize email recipient with the `MAILTO` environment variable
|
147
|
+
|
148
|
+
Output from the jobs is sent to the email address configured in the `MAILTO` environment variable.
|
149
|
+
|
150
|
+
There are many ways to further configure the recipient.
|
151
|
+
|
152
|
+
Example: A global configuration, overriding the environment's value:
|
153
|
+
|
154
|
+
```ruby
|
155
|
+
env 'MAILTO', 'output_of_cron@example.com'
|
156
|
+
|
157
|
+
every 3.hours do
|
158
|
+
command "/usr/bin/my_great_command"
|
159
|
+
end
|
160
|
+
```
|
161
|
+
|
162
|
+
Example: A `MAILTO` configured for all the jobs in an interval block:
|
163
|
+
|
164
|
+
```ruby
|
165
|
+
every 3.hours, mailto: 'my_super_command@example.com' do
|
166
|
+
command "/usr/bin/my_super_command"
|
167
|
+
end
|
168
|
+
```
|
169
|
+
|
170
|
+
Example: A `MAILTO` configured for a single job:
|
171
|
+
|
172
|
+
```ruby
|
173
|
+
every 3.hours do
|
174
|
+
command "/usr/bin/my_super_command", mailto: 'my_super_command_output@example.com'
|
175
|
+
end
|
176
|
+
```
|
177
|
+
|
116
178
|
### Capistrano integration
|
117
179
|
|
118
180
|
Use the built-in Capistrano recipe for easy crontab updates with deploys. For Capistrano V3, see the next section.
|
@@ -140,7 +202,7 @@ require "whenever/capistrano"
|
|
140
202
|
|
141
203
|
The capistrano variable `:stage` should be the one holding your environment name. This will make the correct `:environment` available in your `schedule.rb`.
|
142
204
|
|
143
|
-
If both your environments are on the same server you'll want to namespace them or they'll overwrite each other when you deploy:
|
205
|
+
If both your environments are on the same server you'll want to namespace them, or they'll overwrite each other when you deploy:
|
144
206
|
|
145
207
|
```ruby
|
146
208
|
set :whenever_environment, defer { stage }
|
@@ -148,6 +210,13 @@ set :whenever_identifier, defer { "#{application}_#{stage}" }
|
|
148
210
|
require "whenever/capistrano"
|
149
211
|
```
|
150
212
|
|
213
|
+
If you use a schedule at an alternative path, you may configure it like so:
|
214
|
+
|
215
|
+
```ruby
|
216
|
+
set :whenever_load_file, defer { "#{release_path}/somewhere/else/schedule.rb" }
|
217
|
+
require "whenever/capistrano"
|
218
|
+
```
|
219
|
+
|
151
220
|
### Capistrano V3 Integration
|
152
221
|
|
153
222
|
In your "Capfile" file:
|
@@ -172,10 +241,10 @@ different servers in your capistrano deployment, then you can safely stop readin
|
|
172
241
|
now and everything should just work the same way it always has.
|
173
242
|
|
174
243
|
When you define a job in your schedule.rb file, by default it will be deployed to
|
175
|
-
all servers in the whenever_roles list (which defaults to [:db]).
|
244
|
+
all servers in the whenever_roles list (which defaults to `[:db]`).
|
176
245
|
|
177
246
|
However, if you want to restrict certain jobs to only run on subset of servers,
|
178
|
-
you can add a :
|
247
|
+
you can add a `roles: [...]` argument to their definitions. **Make sure to add
|
179
248
|
that role to the whenever_roles list in your deploy.rb.**
|
180
249
|
|
181
250
|
When you run `cap deploy`, jobs with a :roles list specified will only be added to
|
@@ -184,28 +253,28 @@ the crontabs on servers with one or more of the roles in that list.
|
|
184
253
|
Jobs with no :roles argument will be deployed to all servers in the whenever_roles
|
185
254
|
list. This is to maintain backward compatibility with previous releases of whenever.
|
186
255
|
|
187
|
-
So, for example, with the default whenever_roles of [:db]
|
188
|
-
deployed to all servers with the
|
256
|
+
So, for example, with the default whenever_roles of `[:db]`, a job like this would be
|
257
|
+
deployed to all servers with the `:db` role:
|
189
258
|
|
190
259
|
```ruby
|
191
|
-
every :day, :
|
260
|
+
every :day, at: '12:20am' do
|
192
261
|
rake 'foo:bar'
|
193
262
|
end
|
194
263
|
```
|
195
264
|
|
196
|
-
If we set whenever_roles to [:db, :app] in deploy.rb, and have the following
|
265
|
+
If we set whenever_roles to `[:db, :app]` in deploy.rb, and have the following
|
197
266
|
jobs in schedule.rb:
|
198
267
|
|
199
268
|
```ruby
|
200
|
-
every :day, :
|
269
|
+
every :day, at: '1:37pm', roles: [:app] do
|
201
270
|
rake 'app:task' # will only be added to crontabs of :app servers
|
202
271
|
end
|
203
272
|
|
204
|
-
every :hour, :
|
273
|
+
every :hour, roles: [:db] do
|
205
274
|
rake 'db:task' # will only be added to crontabs of :db servers
|
206
275
|
end
|
207
276
|
|
208
|
-
every :day, :
|
277
|
+
every :day, at: '12:02am' do
|
209
278
|
command "run_this_everywhere" # will be deployed to :db and :app servers
|
210
279
|
end
|
211
280
|
```
|
@@ -253,8 +322,8 @@ It's a little bit dated now, but remains a good introduction.
|
|
253
322
|
|
254
323
|
----
|
255
324
|
|
256
|
-
[](http://travis-ci.org/javan/whenever)
|
257
326
|
|
258
327
|
----
|
259
328
|
|
260
|
-
Copyright ©
|
329
|
+
Copyright © 2017 Javan Makhmali
|
data/bin/whenever
CHANGED
@@ -35,6 +35,9 @@ OptionParser.new do |opts|
|
|
35
35
|
opts.on('-r', '--roles [role1,role2]', 'Comma-separated list of server roles to generate cron jobs for') do |roles|
|
36
36
|
options[:roles] = roles.split(',').map(&:to_sym) if roles
|
37
37
|
end
|
38
|
+
opts.on('-x', '--crontab-command [command]', 'Default: crontab') do |crontab_command|
|
39
|
+
options[:crontab_command] = crontab_command if crontab_command
|
40
|
+
end
|
38
41
|
opts.on('-v', '--version') { puts "Whenever v#{Whenever::VERSION}"; exit(0) }
|
39
42
|
end.parse!
|
40
43
|
|
data/bin/wheneverize
CHANGED
@@ -58,9 +58,12 @@ if File.exist?(file)
|
|
58
58
|
warn "[skip] `#{file}' already exists"
|
59
59
|
elsif File.exist?(file.downcase)
|
60
60
|
warn "[skip] `#{file.downcase}' exists, which could conflict with `#{file}'"
|
61
|
-
elsif !File.exist?(File.dirname(file))
|
62
|
-
warn "[skip] directory `#{File.dirname(file)}' does not exist"
|
63
61
|
else
|
62
|
+
dir = File.dirname(file)
|
63
|
+
if !File.exist?(dir)
|
64
|
+
warn "[add] creating `#{dir}'"
|
65
|
+
FileUtils.mkdir_p(dir)
|
66
|
+
end
|
64
67
|
puts "[add] writing `#{file}'"
|
65
68
|
File.open(file, "w") { |f| f.write(content) }
|
66
69
|
end
|
@@ -11,6 +11,7 @@ Capistrano::Configuration.instance(:must_exist).load do
|
|
11
11
|
_cset(:whenever_variables) { "environment=#{fetch :whenever_environment}" }
|
12
12
|
_cset(:whenever_update_flags) { "--update-crontab #{fetch :whenever_identifier} --set #{fetch :whenever_variables}" }
|
13
13
|
_cset(:whenever_clear_flags) { "--clear-crontab #{fetch :whenever_identifier}" }
|
14
|
+
_cset(:whenever_path) { fetch :latest_release }
|
14
15
|
|
15
16
|
namespace :whenever do
|
16
17
|
desc "Update application's crontab entries using Whenever"
|
@@ -18,7 +19,7 @@ Capistrano::Configuration.instance(:must_exist).load do
|
|
18
19
|
args = {
|
19
20
|
:command => fetch(:whenever_command),
|
20
21
|
:flags => fetch(:whenever_update_flags),
|
21
|
-
:path => fetch(:
|
22
|
+
:path => fetch(:whenever_path)
|
22
23
|
}
|
23
24
|
|
24
25
|
if whenever_servers.any?
|
@@ -38,7 +39,7 @@ Capistrano::Configuration.instance(:must_exist).load do
|
|
38
39
|
args = {
|
39
40
|
:command => fetch(:whenever_command),
|
40
41
|
:flags => fetch(:whenever_clear_flags),
|
41
|
-
:path => fetch(:
|
42
|
+
:path => fetch(:whenever_path)
|
42
43
|
}
|
43
44
|
|
44
45
|
whenever_run_commands(args)
|
@@ -4,7 +4,7 @@ namespace :whenever do
|
|
4
4
|
|
5
5
|
on roles fetch(:whenever_roles) do |host|
|
6
6
|
args_for_host = block_given? ? args + Array(yield(host)) : args
|
7
|
-
within
|
7
|
+
within fetch(:whenever_path) do
|
8
8
|
with fetch(:whenever_command_environment_variables) do
|
9
9
|
execute(*args_for_host)
|
10
10
|
end
|
@@ -12,17 +12,28 @@ namespace :whenever do
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
+
def load_file
|
16
|
+
file = fetch(:whenever_load_file)
|
17
|
+
if file
|
18
|
+
"-f #{file}"
|
19
|
+
else
|
20
|
+
''
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
15
24
|
desc "Update application's crontab entries using Whenever"
|
16
25
|
task :update_crontab do
|
17
26
|
setup_whenever_task do |host|
|
18
27
|
roles = host.roles_array.join(",")
|
19
|
-
[fetch(:whenever_update_flags),
|
28
|
+
[fetch(:whenever_update_flags), "--roles=#{roles}", load_file]
|
20
29
|
end
|
21
30
|
end
|
22
31
|
|
23
32
|
desc "Clear application's crontab entries using Whenever"
|
24
33
|
task :clear_crontab do
|
25
|
-
setup_whenever_task
|
34
|
+
setup_whenever_task do |host|
|
35
|
+
[fetch(:whenever_clear_flags), load_file]
|
36
|
+
end
|
26
37
|
end
|
27
38
|
|
28
39
|
after "deploy:updated", "whenever:update_crontab"
|
@@ -33,11 +44,13 @@ namespace :load do
|
|
33
44
|
task :defaults do
|
34
45
|
set :whenever_roles, ->{ :db }
|
35
46
|
set :whenever_command, ->{ [:bundle, :exec, :whenever] }
|
36
|
-
set :whenever_command_environment_variables, ->{
|
47
|
+
set :whenever_command_environment_variables, ->{ fetch(:default_env).merge(rails_env: fetch(:whenever_environment)) }
|
37
48
|
set :whenever_identifier, ->{ fetch :application }
|
38
49
|
set :whenever_environment, ->{ fetch :rails_env, fetch(:stage, "production") }
|
39
50
|
set :whenever_variables, ->{ "environment=#{fetch :whenever_environment}" }
|
51
|
+
set :whenever_load_file, ->{ nil }
|
40
52
|
set :whenever_update_flags, ->{ "--update-crontab #{fetch :whenever_identifier} --set #{fetch :whenever_variables}" }
|
41
53
|
set :whenever_clear_flags, ->{ "--clear-crontab #{fetch :whenever_identifier}" }
|
54
|
+
set :whenever_path, ->{ release_path }
|
42
55
|
end
|
43
56
|
end
|
@@ -9,9 +9,10 @@ module Whenever
|
|
9
9
|
def initialize(options={})
|
10
10
|
@options = options
|
11
11
|
|
12
|
-
@options[:
|
13
|
-
@options[:
|
14
|
-
@options[:
|
12
|
+
@options[:crontab_command] ||= 'crontab'
|
13
|
+
@options[:file] ||= 'config/schedule.rb'
|
14
|
+
@options[:cut] ||= 0
|
15
|
+
@options[:identifier] ||= default_identifier
|
15
16
|
|
16
17
|
if !File.exist?(@options[:file]) && @options[:clear].nil?
|
17
18
|
warn("[fail] Can't find file: #{@options[:file]}")
|
@@ -28,6 +29,8 @@ module Whenever
|
|
28
29
|
exit(1)
|
29
30
|
end
|
30
31
|
@options[:cut] = @options[:cut].to_i
|
32
|
+
|
33
|
+
@timestamp = Time.now.to_s
|
31
34
|
end
|
32
35
|
|
33
36
|
def run
|
@@ -55,9 +58,10 @@ module Whenever
|
|
55
58
|
end
|
56
59
|
|
57
60
|
def read_crontab
|
58
|
-
return @current_crontab if
|
61
|
+
return @current_crontab if instance_variable_defined?(:@current_crontab)
|
59
62
|
|
60
|
-
command = [
|
63
|
+
command = [@options[:crontab_command]]
|
64
|
+
command << '-l'
|
61
65
|
command << "-u #{@options[:user]}" if @options[:user]
|
62
66
|
|
63
67
|
command_results = %x[#{command.join(' ')} 2> /dev/null]
|
@@ -65,7 +69,7 @@ module Whenever
|
|
65
69
|
end
|
66
70
|
|
67
71
|
def write_crontab(contents)
|
68
|
-
command = [
|
72
|
+
command = [@options[:crontab_command]]
|
69
73
|
command << "-u #{@options[:user]}" if @options[:user]
|
70
74
|
# Solaris/SmartOS cron does not support the - option to read from stdin.
|
71
75
|
command << "-" unless OS.solaris?
|
@@ -90,19 +94,19 @@ module Whenever
|
|
90
94
|
|
91
95
|
def updated_crontab
|
92
96
|
# Check for unopened or unclosed identifier blocks
|
93
|
-
if read_crontab =~ Regexp.new("^#{
|
94
|
-
warn "[fail] Unclosed indentifier; Your crontab file contains '#{comment_open}', but no '#{comment_close}'"
|
97
|
+
if read_crontab =~ Regexp.new("^#{comment_open_regex}\s*$") && (read_crontab =~ Regexp.new("^#{comment_close_regex}\s*$")).nil?
|
98
|
+
warn "[fail] Unclosed indentifier; Your crontab file contains '#{comment_open(false)}', but no '#{comment_close(false)}'"
|
95
99
|
exit(1)
|
96
|
-
elsif (read_crontab =~ Regexp.new("^#{
|
97
|
-
warn "[fail] Unopened indentifier; Your crontab file contains '#{comment_close}', but no '#{comment_open}'"
|
100
|
+
elsif (read_crontab =~ Regexp.new("^#{comment_open_regex}\s*$")).nil? && read_crontab =~ Regexp.new("^#{comment_close_regex}\s*$")
|
101
|
+
warn "[fail] Unopened indentifier; Your crontab file contains '#{comment_close(false)}', but no '#{comment_open(false)}'"
|
98
102
|
exit(1)
|
99
103
|
end
|
100
104
|
|
101
|
-
# If an existing
|
102
|
-
if read_crontab =~ Regexp.new("^#{
|
105
|
+
# If an existing identifier block is found, replace it with the new cron entries
|
106
|
+
if read_crontab =~ Regexp.new("^#{comment_open_regex}\s*$") && read_crontab =~ Regexp.new("^#{comment_close_regex}\s*$")
|
103
107
|
# If the existing crontab file contains backslashes they get lost going through gsub.
|
104
108
|
# .gsub('\\', '\\\\\\') preserves them. Go figure.
|
105
|
-
read_crontab.gsub(Regexp.new("^#{
|
109
|
+
read_crontab.gsub(Regexp.new("^#{comment_open_regex}\s*$.+^#{comment_close_regex}\s*$", Regexp::MULTILINE), whenever_cron.chomp.gsub('\\', '\\\\\\'))
|
106
110
|
else # Otherwise, append the new cron entries after any existing ones
|
107
111
|
[read_crontab, whenever_cron].join("\n\n")
|
108
112
|
end.gsub(/\n{3,}/, "\n\n") # More than two newlines becomes just two.
|
@@ -120,16 +124,32 @@ module Whenever
|
|
120
124
|
stripped_contents.gsub!(/\s+$/, $/)
|
121
125
|
end
|
122
126
|
|
123
|
-
def comment_base
|
124
|
-
|
127
|
+
def comment_base(include_timestamp = true)
|
128
|
+
if include_timestamp
|
129
|
+
"Whenever generated tasks for: #{@options[:identifier]} at: #{@timestamp}"
|
130
|
+
else
|
131
|
+
"Whenever generated tasks for: #{@options[:identifier]}"
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def comment_open(include_timestamp = true)
|
136
|
+
"# Begin #{comment_base(include_timestamp)}"
|
137
|
+
end
|
138
|
+
|
139
|
+
def comment_close(include_timestamp = true)
|
140
|
+
"# End #{comment_base(include_timestamp)}"
|
141
|
+
end
|
142
|
+
|
143
|
+
def comment_open_regex
|
144
|
+
"#{comment_open(false)}(#{timestamp_regex}|)"
|
125
145
|
end
|
126
146
|
|
127
|
-
def
|
128
|
-
"#
|
147
|
+
def comment_close_regex
|
148
|
+
"#{comment_close(false)}(#{timestamp_regex}|)"
|
129
149
|
end
|
130
150
|
|
131
|
-
def
|
132
|
-
"
|
151
|
+
def timestamp_regex
|
152
|
+
" at: \\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2} ([+-]\\d{4}|UTC)"
|
133
153
|
end
|
134
154
|
end
|
135
155
|
end
|