whenever 0.8.2 → 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 +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
|