whenever 0.8.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/.travis.yml +20 -7
- data/Appraisals +19 -0
- data/CHANGELOG.md +116 -3
- data/Gemfile +3 -3
- data/LICENSE +2 -2
- data/README.md +133 -32
- data/Rakefile +3 -10
- data/bin/whenever +3 -0
- data/bin/wheneverize +8 -5
- data/gemfiles/activesupport4.1.gemfile +7 -0
- data/gemfiles/activesupport4.2.gemfile +7 -0
- 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/hooks.rb +8 -0
- data/lib/whenever/capistrano/{recipes.rb → v2/recipes.rb} +7 -13
- data/lib/whenever/capistrano/{support.rb → v2/support.rb} +12 -0
- data/lib/whenever/capistrano/v3/tasks/whenever.rake +56 -0
- data/lib/whenever/capistrano.rb +5 -6
- data/lib/whenever/command_line.rb +69 -48
- data/lib/whenever/cron.rb +54 -25
- data/lib/whenever/job.rb +13 -14
- data/lib/whenever/job_list.rb +54 -24
- data/lib/whenever/numeric.rb +13 -0
- data/lib/whenever/numeric_seconds.rb +48 -0
- data/lib/whenever/os.rb +7 -0
- data/lib/whenever/output_redirection.rb +1 -0
- data/lib/whenever/setup.rb +19 -15
- data/lib/whenever/version.rb +2 -2
- data/lib/whenever.rb +19 -14
- data/test/functional/command_line_test.rb +379 -243
- data/test/functional/output_at_test.rb +227 -249
- data/test/functional/output_default_defined_jobs_test.rb +251 -193
- data/test/functional/output_defined_job_test.rb +65 -91
- data/test/functional/output_env_test.rb +22 -26
- data/test/functional/output_jobs_for_roles_test.rb +46 -65
- data/test/functional/output_jobs_with_mailto_test.rb +168 -0
- data/test/functional/output_redirection_test.rb +232 -291
- data/test/test_case.rb +32 -0
- data/test/test_helper.rb +44 -15
- data/test/unit/capistrano_support_test.rb +128 -134
- data/test/unit/cron_test.rb +373 -208
- data/test/unit/executable_test.rb +142 -0
- data/test/unit/job_test.rb +111 -117
- data/whenever.gemspec +7 -4
- metadata +63 -44
data/lib/whenever/job_list.rb
CHANGED
@@ -30,10 +30,17 @@ module Whenever
|
|
30
30
|
return if @pre_set_variables[variable]
|
31
31
|
|
32
32
|
instance_variable_set("@#{variable}".to_sym, value)
|
33
|
-
self.class.send(:attr_reader, variable.to_sym)
|
34
33
|
@set_variables[variable] = value
|
35
34
|
end
|
36
35
|
|
36
|
+
def method_missing(name, *args, &block)
|
37
|
+
@set_variables.has_key?(name) ? @set_variables[name] : super
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.respond_to?(name, include_private = false)
|
41
|
+
@set_variables.has_key?(name) || super
|
42
|
+
end
|
43
|
+
|
37
44
|
def env(variable, value)
|
38
45
|
@env[variable.to_s] = value
|
39
46
|
end
|
@@ -45,18 +52,21 @@ module Whenever
|
|
45
52
|
end
|
46
53
|
|
47
54
|
def job_type(name, template)
|
48
|
-
class_eval do
|
55
|
+
singleton_class.class_eval do
|
49
56
|
define_method(name) do |task, *args|
|
50
57
|
options = { :task => task, :template => template }
|
51
58
|
options.merge!(args[0]) if args[0].is_a? Hash
|
52
59
|
|
60
|
+
options[:mailto] ||= @options.fetch(:mailto, :default_mailto)
|
61
|
+
|
53
62
|
# :cron_log was an old option for output redirection, it remains for backwards compatibility
|
54
63
|
options[:output] = (options[:cron_log] || @cron_log) if defined?(@cron_log) || options.has_key?(:cron_log)
|
55
64
|
# :output is the newer, more flexible option.
|
56
65
|
options[:output] = @output if defined?(@output) && !options.has_key?(:output)
|
57
66
|
|
58
|
-
@jobs[
|
59
|
-
@jobs[@current_time_scope]
|
67
|
+
@jobs[options.fetch(:mailto)] ||= {}
|
68
|
+
@jobs[options.fetch(:mailto)][@current_time_scope] ||= []
|
69
|
+
@jobs[options.fetch(:mailto)][@current_time_scope] << Whenever::Job.new(@options.merge(@set_variables).merge(options))
|
60
70
|
end
|
61
71
|
end
|
62
72
|
end
|
@@ -73,13 +83,13 @@ module Whenever
|
|
73
83
|
# Only works for setting values as strings.
|
74
84
|
#
|
75
85
|
def pre_set(variable_string = nil)
|
76
|
-
return if variable_string.
|
86
|
+
return if variable_string.nil? || variable_string == ""
|
77
87
|
|
78
88
|
pairs = variable_string.split('&')
|
79
89
|
pairs.each do |pair|
|
80
90
|
next unless pair.index('=')
|
81
91
|
variable, value = *pair.split('=')
|
82
|
-
unless variable.
|
92
|
+
unless variable.nil? || variable == "" || value.nil? || value == ""
|
83
93
|
variable = variable.strip.to_sym
|
84
94
|
set(variable, value.strip)
|
85
95
|
@pre_set_variables[variable] = value
|
@@ -92,7 +102,7 @@ module Whenever
|
|
92
102
|
|
93
103
|
output = []
|
94
104
|
@env.each do |key, val|
|
95
|
-
output << "#{key}=#{val.
|
105
|
+
output << "#{key}=#{val.nil? || val == "" ? '""' : val}\n"
|
96
106
|
end
|
97
107
|
output << "\n"
|
98
108
|
|
@@ -125,31 +135,51 @@ module Whenever
|
|
125
135
|
entries.map { |entry| entry.join(' ') }
|
126
136
|
end
|
127
137
|
|
138
|
+
def cron_jobs_of_time(time, jobs)
|
139
|
+
shortcut_jobs, regular_jobs = [], []
|
140
|
+
|
141
|
+
jobs.each do |job|
|
142
|
+
next unless roles.empty? || roles.any? do |r|
|
143
|
+
job.has_role?(r)
|
144
|
+
end
|
145
|
+
Whenever::Output::Cron.output(time, job, :chronic_options => @chronic_options) do |cron|
|
146
|
+
cron << "\n\n"
|
147
|
+
|
148
|
+
if cron[0,1] == "@"
|
149
|
+
shortcut_jobs << cron
|
150
|
+
else
|
151
|
+
regular_jobs << cron
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
shortcut_jobs.join + combine(regular_jobs).join
|
157
|
+
end
|
158
|
+
|
128
159
|
def cron_jobs
|
129
160
|
return if @jobs.empty?
|
130
161
|
|
131
|
-
|
132
|
-
regular_jobs = []
|
162
|
+
output = []
|
133
163
|
|
134
|
-
|
135
|
-
@jobs.each do |time, jobs|
|
136
|
-
|
137
|
-
|
138
|
-
job.has_role?(r)
|
139
|
-
end
|
140
|
-
Whenever::Output::Cron.output(time, job) do |cron|
|
141
|
-
cron << "\n\n"
|
164
|
+
# jobs with default mailto's must be output before the ones with non-default mailto's.
|
165
|
+
@jobs.delete(:default_mailto) { Hash.new }.each do |time, jobs|
|
166
|
+
output << cron_jobs_of_time(time, jobs)
|
167
|
+
end
|
142
168
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
end
|
169
|
+
@jobs.each do |mailto, time_and_jobs|
|
170
|
+
output_jobs = []
|
171
|
+
|
172
|
+
time_and_jobs.each do |time, jobs|
|
173
|
+
output_jobs << cron_jobs_of_time(time, jobs)
|
149
174
|
end
|
175
|
+
|
176
|
+
output_jobs.reject! { |output_job| output_job.empty? }
|
177
|
+
|
178
|
+
output << "MAILTO=#{mailto}\n\n" unless output_jobs.empty?
|
179
|
+
output << output_jobs
|
150
180
|
end
|
151
181
|
|
152
|
-
|
182
|
+
output.join
|
153
183
|
end
|
154
184
|
end
|
155
185
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Numeric.class_eval do
|
2
|
+
def respond_to?(method, include_private = false)
|
3
|
+
super || Whenever::NumericSeconds.public_method_defined?(method)
|
4
|
+
end
|
5
|
+
|
6
|
+
def method_missing(method, *args, &block)
|
7
|
+
if Whenever::NumericSeconds.public_method_defined?(method)
|
8
|
+
Whenever::NumericSeconds.new(self).send(method)
|
9
|
+
else
|
10
|
+
super
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Whenever
|
2
|
+
class NumericSeconds
|
3
|
+
attr_reader :number
|
4
|
+
|
5
|
+
def self.seconds(number, units)
|
6
|
+
new(number).send(units)
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(number)
|
10
|
+
@number = number.to_i
|
11
|
+
end
|
12
|
+
|
13
|
+
def seconds
|
14
|
+
number
|
15
|
+
end
|
16
|
+
alias :second :seconds
|
17
|
+
|
18
|
+
def minutes
|
19
|
+
number * 60
|
20
|
+
end
|
21
|
+
alias :minute :minutes
|
22
|
+
|
23
|
+
def hours
|
24
|
+
number * 3_600
|
25
|
+
end
|
26
|
+
alias :hour :hours
|
27
|
+
|
28
|
+
def days
|
29
|
+
number * 86_400
|
30
|
+
end
|
31
|
+
alias :day :days
|
32
|
+
|
33
|
+
def weeks
|
34
|
+
number * 604_800
|
35
|
+
end
|
36
|
+
alias :week :weeks
|
37
|
+
|
38
|
+
def months
|
39
|
+
number * 2_592_000
|
40
|
+
end
|
41
|
+
alias :month :months
|
42
|
+
|
43
|
+
def years
|
44
|
+
number * 31_557_600
|
45
|
+
end
|
46
|
+
alias :year :years
|
47
|
+
end
|
48
|
+
end
|
data/lib/whenever/os.rb
ADDED
data/lib/whenever/setup.rb
CHANGED
@@ -1,26 +1,30 @@
|
|
1
|
+
# Environment variable defaults to RAILS_ENV
|
2
|
+
set :environment_variable, "RAILS_ENV"
|
1
3
|
# Environment defaults to production
|
2
4
|
set :environment, "production"
|
3
5
|
# Path defaults to the directory `whenever` was run from
|
4
6
|
set :path, Whenever.path
|
5
7
|
|
8
|
+
# Custom Chronic configuration for time parsing, empty by default
|
9
|
+
# Full list of options at: https://github.com/mojombo/chronic/blob/master/lib/chronic/parser.rb
|
10
|
+
set :chronic_options, {}
|
11
|
+
|
6
12
|
# All jobs are wrapped in this template.
|
7
13
|
# http://blog.scoutapp.com/articles/2010/09/07/rvm-and-cron-in-production
|
8
14
|
set :job_template, "/bin/bash -l -c ':job'"
|
9
15
|
|
10
|
-
|
16
|
+
set :runner_command, case
|
17
|
+
when Whenever.bin_rails?
|
18
|
+
"bin/rails runner"
|
19
|
+
when Whenever.script_rails?
|
20
|
+
"script/rails runner"
|
21
|
+
else
|
22
|
+
"script/runner"
|
23
|
+
end
|
11
24
|
|
12
|
-
|
13
|
-
if Whenever.bundler?
|
14
|
-
job_type :rake, "cd :path && RAILS_ENV=:environment bundle exec rake :task --silent :output"
|
15
|
-
job_type :script, "cd :path && RAILS_ENV=:environment bundle exec script/:task :output"
|
16
|
-
else
|
17
|
-
job_type :rake, "cd :path && RAILS_ENV=:environment rake :task --silent :output"
|
18
|
-
job_type :script, "cd :path && RAILS_ENV=:environment script/:task :output"
|
19
|
-
end
|
25
|
+
set :bundle_command, Whenever.bundler? ? "bundle exec" : ""
|
20
26
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
job_type :runner, "cd :path && script/runner -e :environment ':task' :output"
|
26
|
-
end
|
27
|
+
job_type :command, ":task :output"
|
28
|
+
job_type :rake, "cd :path && :environment_variable=:environment :bundle_command rake :task --silent :output"
|
29
|
+
job_type :script, "cd :path && :environment_variable=:environment :bundle_command script/:task :output"
|
30
|
+
job_type :runner, "cd :path && :bundle_command :runner_command -e :environment ':task' :output"
|
data/lib/whenever/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module Whenever
|
2
|
-
VERSION = '0.
|
3
|
-
end
|
2
|
+
VERSION = '1.0.0'
|
3
|
+
end
|
data/lib/whenever.rb
CHANGED
@@ -1,29 +1,34 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
1
|
+
require 'whenever/numeric'
|
2
|
+
require 'whenever/numeric_seconds'
|
3
|
+
require 'whenever/job_list'
|
4
|
+
require 'whenever/job'
|
5
|
+
require 'whenever/command_line'
|
6
|
+
require 'whenever/cron'
|
7
|
+
require 'whenever/output_redirection'
|
8
|
+
require 'whenever/os'
|
3
9
|
|
4
10
|
module Whenever
|
5
|
-
autoload :JobList, 'whenever/job_list'
|
6
|
-
autoload :Job, 'whenever/job'
|
7
|
-
autoload :CommandLine, 'whenever/command_line'
|
8
|
-
|
9
|
-
module Output
|
10
|
-
autoload :Cron, 'whenever/cron'
|
11
|
-
autoload :Redirection, 'whenever/output_redirection'
|
12
|
-
end
|
13
|
-
|
14
11
|
def self.cron(options)
|
15
12
|
Whenever::JobList.new(options).generate_cron_output
|
16
13
|
end
|
17
14
|
|
15
|
+
def self.seconds(number, units)
|
16
|
+
Whenever::NumericSeconds.seconds(number, units)
|
17
|
+
end
|
18
|
+
|
18
19
|
def self.path
|
19
20
|
Dir.pwd
|
20
21
|
end
|
21
22
|
|
22
|
-
def self.
|
23
|
-
File.
|
23
|
+
def self.bin_rails?
|
24
|
+
File.exist?(File.join(path, 'bin', 'rails'))
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.script_rails?
|
28
|
+
File.exist?(File.join(path, 'script', 'rails'))
|
24
29
|
end
|
25
30
|
|
26
31
|
def self.bundler?
|
27
|
-
File.
|
32
|
+
File.exist?(File.join(path, 'Gemfile'))
|
28
33
|
end
|
29
34
|
end
|