whenever 1.1.2 → 1.1.3
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 +4 -4
- data/.github/workflows/ci.yml +4 -2
- data/CHANGELOG.md +12 -3
- data/README.md +8 -0
- data/lib/whenever/job.rb +3 -1
- data/lib/whenever/job_list.rb +16 -3
- data/lib/whenever/job_sequence.rb +36 -0
- data/lib/whenever/version.rb +1 -1
- data/lib/whenever.rb +1 -0
- data/test/functional/output_jobs_with_sequence_test.rb +187 -0
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 85714fb8b50231a67eca8db2f67211fc11e8bb07bbb76db5333882676f626802
|
|
4
|
+
data.tar.gz: 9523c1ec86b34bd8fcd9244ebbc37206857ef25bdcce6cbb661769e9231d3ed5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bd84f4e82fcd6aff274fef804ca4fd2e834d6817778fd09d56287a013039005e1ecaeb12e8fde657502709bcabcd8dc31bdd0d99cd163edefe1d0b8889d2a78d
|
|
7
|
+
data.tar.gz: 59728cc54eae8cd88fe0d911ff6bb2a5571fdc0f257dc93ab8564c3d7795f7583aece8c21eede62ae6b99b5a264c3b4ece7e222dac77f3a2b1401f3f3237605b
|
data/.github/workflows/ci.yml
CHANGED
|
@@ -3,6 +3,8 @@ on:
|
|
|
3
3
|
pull_request:
|
|
4
4
|
push:
|
|
5
5
|
branches: [ main ]
|
|
6
|
+
permissions:
|
|
7
|
+
contents: read
|
|
6
8
|
jobs:
|
|
7
9
|
test:
|
|
8
10
|
runs-on: ${{ matrix.os }}
|
|
@@ -23,7 +25,7 @@ jobs:
|
|
|
23
25
|
- os: macos-15-intel
|
|
24
26
|
ruby-version: '2.5'
|
|
25
27
|
steps:
|
|
26
|
-
- uses: actions/checkout@
|
|
28
|
+
- uses: actions/checkout@v7
|
|
27
29
|
name: Set up Ruby ${{ matrix.ruby-version }}
|
|
28
30
|
- uses: ruby/setup-ruby@v1
|
|
29
31
|
env:
|
|
@@ -74,7 +76,7 @@ jobs:
|
|
|
74
76
|
env:
|
|
75
77
|
BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/activesupport${{ matrix.rails-version }}.gemfile
|
|
76
78
|
steps:
|
|
77
|
-
- uses: actions/checkout@
|
|
79
|
+
- uses: actions/checkout@v7
|
|
78
80
|
name: Set up Ruby ${{ matrix.ruby-version }}
|
|
79
81
|
- uses: ruby/setup-ruby@v1
|
|
80
82
|
with:
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
### unreleased
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
### 1.1.3 / September 15, 2026
|
|
5
|
+
|
|
6
|
+
* Add support for sequential job definitions https://github.com/javan/whenever/pull/854
|
|
7
|
+
|
|
8
|
+
* CI: Bump actions/checkout from 6 to 7 https://github.com/javan/whenever/pull/876
|
|
9
|
+
|
|
10
|
+
* CI: Restrict GitHub Actions workflow permissions to contents: read https://github.com/javan/whenever/pull/875
|
|
11
|
+
|
|
12
|
+
|
|
4
13
|
### 1.1.2 / January 18, 2026
|
|
5
14
|
|
|
6
15
|
* Add description as comment in crontab https://github.com/javan/whenever/pull/776
|
|
@@ -11,7 +20,7 @@
|
|
|
11
20
|
|
|
12
21
|
* CI: Use macos-15-intel instead of macos-13 for Ruby 2.4 and 2.5 https://github.com/javan/whenever/pull/871
|
|
13
22
|
|
|
14
|
-
### 1.1.1 /
|
|
23
|
+
### 1.1.1 / December 8, 2025
|
|
15
24
|
|
|
16
25
|
* job_list `.respond_to?` updated to an instance method https://github.com/javan/whenever/pull/830
|
|
17
26
|
|
|
@@ -23,7 +32,7 @@
|
|
|
23
32
|
|
|
24
33
|
* Require MFA for gem releases https://github.com/javan/whenever/pull/867
|
|
25
34
|
|
|
26
|
-
### 1.1.0 /
|
|
35
|
+
### 1.1.0 / November 21, 2025
|
|
27
36
|
|
|
28
37
|
* Splat whenever_roles when passing to roles https://github.com/javan/whenever/pull/777
|
|
29
38
|
|
|
@@ -161,7 +170,7 @@
|
|
|
161
170
|
* Process params in job templates. [Austin Ziegler]
|
|
162
171
|
|
|
163
172
|
|
|
164
|
-
### 0.8.4 / July 22,
|
|
173
|
+
### 0.8.4 / July 22, 2013
|
|
165
174
|
|
|
166
175
|
* Don't require schedule file when clearing. [Javan Makhmali]
|
|
167
176
|
|
data/README.md
CHANGED
|
@@ -59,6 +59,14 @@ every 3.hours do # 1.minute 1.day 1.week 1.month 1.year is also supported
|
|
|
59
59
|
command "/usr/bin/my_great_command"
|
|
60
60
|
end
|
|
61
61
|
|
|
62
|
+
every 3.hours, sequential: true do
|
|
63
|
+
# Jobs in this block that don't set their own sequence will default to run in the same sequence (not in parallel)
|
|
64
|
+
runner "MyModel.some_process", halt_sequence_on_failure: true # If this job fails, subsequent jobs will not run (defaults to false)
|
|
65
|
+
rake "my:rake:task"
|
|
66
|
+
command "/usr/bin/my_great_command", sequence: nil # This job runs in parallel with other jobs that are not part of a sequence
|
|
67
|
+
runner "MyModel.task_to_run_at_four_thirty_in_the_morning", sequence: 'other' # This job runs sequentially with other jobs in the sequence called 'other'
|
|
68
|
+
end
|
|
69
|
+
|
|
62
70
|
every 1.day, at: '4:30 am' do
|
|
63
71
|
runner "MyModel.task_to_run_at_four_thirty_in_the_morning"
|
|
64
72
|
end
|
data/lib/whenever/job.rb
CHANGED
|
@@ -2,7 +2,7 @@ require 'shellwords'
|
|
|
2
2
|
|
|
3
3
|
module Whenever
|
|
4
4
|
class Job
|
|
5
|
-
attr_reader :at, :roles, :mailto, :description
|
|
5
|
+
attr_reader :at, :roles, :mailto, :description, :sequence, :halt_sequence_on_failure
|
|
6
6
|
|
|
7
7
|
def initialize(options = {})
|
|
8
8
|
@options = options
|
|
@@ -10,6 +10,8 @@ module Whenever
|
|
|
10
10
|
@template = options.delete(:template)
|
|
11
11
|
@mailto = options.fetch(:mailto, :default_mailto)
|
|
12
12
|
@job_template = options.delete(:job_template) || ":job"
|
|
13
|
+
@sequence = options.delete(:sequence)
|
|
14
|
+
@halt_sequence_on_failure = options.delete(:halt_sequence_on_failure)
|
|
13
15
|
@roles = Array(options.delete(:roles))
|
|
14
16
|
@description = options.delete(:description)
|
|
15
17
|
@options[:output] = options.has_key?(:output) ? Whenever::Output::Redirection.new(options[:output]).to_s : ''
|
data/lib/whenever/job_list.rb
CHANGED
|
@@ -48,6 +48,12 @@ module Whenever
|
|
|
48
48
|
def every(frequency, options = {})
|
|
49
49
|
@current_time_scope = frequency
|
|
50
50
|
@options = options
|
|
51
|
+
|
|
52
|
+
if @options[:sequential]
|
|
53
|
+
@default_sequence_id ||= 0
|
|
54
|
+
@options[:sequence] ||= "default_sequence_#{@default_sequence_id += 1}"
|
|
55
|
+
end
|
|
56
|
+
|
|
51
57
|
yield
|
|
52
58
|
end
|
|
53
59
|
|
|
@@ -138,10 +144,17 @@ module Whenever
|
|
|
138
144
|
def cron_jobs_of_time(time, jobs)
|
|
139
145
|
shortcut_jobs, regular_jobs = [], []
|
|
140
146
|
|
|
147
|
+
filtered_jobs = jobs.select do |job|
|
|
148
|
+
roles.empty? || roles.any? { |r| job.has_role?(r) }
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
grouped_jobs = filtered_jobs.group_by(&:sequence)
|
|
152
|
+
grouped_jobs.each do |sequence, jobs|
|
|
153
|
+
grouped_jobs[sequence] = JobSequence.new(jobs) if sequence
|
|
154
|
+
end
|
|
155
|
+
jobs = grouped_jobs.values.flatten
|
|
156
|
+
|
|
141
157
|
jobs.each do |job|
|
|
142
|
-
next unless roles.empty? || roles.any? do |r|
|
|
143
|
-
job.has_role?(r)
|
|
144
|
-
end
|
|
145
158
|
Whenever::Output::Cron.output(time, job, :chronic_options => @chronic_options) do |cron|
|
|
146
159
|
cron << "\n\n"
|
|
147
160
|
cron = (job.description.strip + "\n").gsub(/^(.*)$/, '# \1') + cron unless job.description.to_s.empty?
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require 'shellwords'
|
|
2
|
+
|
|
3
|
+
module Whenever
|
|
4
|
+
class JobSequence
|
|
5
|
+
attr_reader :at, :roles, :mailto, :description
|
|
6
|
+
|
|
7
|
+
def initialize(jobs, options = {})
|
|
8
|
+
validate!(jobs)
|
|
9
|
+
|
|
10
|
+
@jobs = jobs
|
|
11
|
+
@options = options
|
|
12
|
+
@at = options.fetch(:at, primary_job.at)
|
|
13
|
+
@mailto = options.fetch(:mailto, primary_job.mailto || :default_mailto)
|
|
14
|
+
@roles = Array(options.delete(:roles), *primary_job.roles)
|
|
15
|
+
@description = options.fetch(:description) { @jobs.map { |job| job.description.to_s.strip }.reject(&:empty?).uniq.join("\n") }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def output
|
|
19
|
+
@jobs.map { |job| [job.output, job.halt_sequence_on_failure ? ' && ' : ' ; '] }.flatten[0..-2].join
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def has_role?(role)
|
|
23
|
+
roles.empty? || roles.include?(role)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def primary_job
|
|
29
|
+
@jobs.first
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def validate!(jobs)
|
|
33
|
+
raise ArgumentError, "Jobs in a sequence don't support different `at` values" if jobs.map(&:at).uniq.count > 1
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
data/lib/whenever/version.rb
CHANGED
data/lib/whenever.rb
CHANGED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class OutputJobsWithSequenceTest < Whenever::TestCase
|
|
4
|
+
test "defined jobs with a sequence argument specified per-job" do
|
|
5
|
+
output = Whenever.cron \
|
|
6
|
+
<<-file
|
|
7
|
+
every 2.hours do
|
|
8
|
+
command "blahblah", sequence: 'backups'
|
|
9
|
+
command "foofoo", sequence: 'backups'
|
|
10
|
+
command "barbar"
|
|
11
|
+
end
|
|
12
|
+
file
|
|
13
|
+
|
|
14
|
+
output_without_empty_line = lines_without_empty_line(output.lines)
|
|
15
|
+
assert_equal two_hours + " /bin/bash -l -c 'blahblah' ; /bin/bash -l -c 'foofoo'", output_without_empty_line.shift
|
|
16
|
+
assert_equal two_hours + " /bin/bash -l -c 'barbar'", output_without_empty_line.shift
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
test "defined jobs with a sequence argument specified on the group" do
|
|
20
|
+
output = Whenever.cron \
|
|
21
|
+
<<-file
|
|
22
|
+
every 2.hours, sequence: 'backups' do
|
|
23
|
+
command "blahblah"
|
|
24
|
+
command "foofoo"
|
|
25
|
+
end
|
|
26
|
+
file
|
|
27
|
+
|
|
28
|
+
output_without_empty_line = lines_without_empty_line(output.lines)
|
|
29
|
+
assert_equal two_hours + " /bin/bash -l -c 'blahblah' ; /bin/bash -l -c 'foofoo'", output_without_empty_line.shift
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
test "defined jobs with a sequence argument and a job that halts the sequence on failure" do
|
|
33
|
+
output = Whenever.cron \
|
|
34
|
+
<<-file
|
|
35
|
+
every 2.hours, sequence: 'backups' do
|
|
36
|
+
command "blahblah", halt_sequence_on_failure: true
|
|
37
|
+
command "foofoo"
|
|
38
|
+
end
|
|
39
|
+
file
|
|
40
|
+
|
|
41
|
+
output_without_empty_line = lines_without_empty_line(output.lines)
|
|
42
|
+
assert_equal two_hours + " /bin/bash -l -c 'blahblah' && /bin/bash -l -c 'foofoo'", output_without_empty_line.shift
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
test "defined jobs with a sequences specified on the group and jobs" do
|
|
46
|
+
output = Whenever.cron \
|
|
47
|
+
<<-file
|
|
48
|
+
every 2.hours, sequence: 'backups' do
|
|
49
|
+
command "blahblah"
|
|
50
|
+
command "barbar", sequence: nil
|
|
51
|
+
command "foofoo"
|
|
52
|
+
command "bazbaz", sequence: 'bees'
|
|
53
|
+
command "buzzbuzz", sequence: 'bees'
|
|
54
|
+
end
|
|
55
|
+
file
|
|
56
|
+
|
|
57
|
+
output_without_empty_line = lines_without_empty_line(output.lines)
|
|
58
|
+
assert_equal two_hours + " /bin/bash -l -c 'blahblah' ; /bin/bash -l -c 'foofoo'", output_without_empty_line.shift
|
|
59
|
+
assert_equal two_hours + " /bin/bash -l -c 'barbar'", output_without_empty_line.shift
|
|
60
|
+
assert_equal two_hours + " /bin/bash -l -c 'bazbaz' ; /bin/bash -l -c 'buzzbuzz'", output_without_empty_line.shift
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
test "defined jobs with a multiple groups with sequences specified on the group and jobs" do
|
|
64
|
+
output = Whenever.cron \
|
|
65
|
+
<<-file
|
|
66
|
+
every 2.hours, sequence: 'backups' do
|
|
67
|
+
command "blahblah"
|
|
68
|
+
command "barbar", sequence: nil
|
|
69
|
+
command "bazbaz", sequence: 'bees'
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
every 2.hours, sequence: 'backups' do
|
|
73
|
+
command "foofoo"
|
|
74
|
+
command "buzzbuzz", sequence: 'bees'
|
|
75
|
+
end
|
|
76
|
+
file
|
|
77
|
+
|
|
78
|
+
output_without_empty_line = lines_without_empty_line(output.lines)
|
|
79
|
+
assert_equal two_hours + " /bin/bash -l -c 'blahblah' ; /bin/bash -l -c 'foofoo'", output_without_empty_line.shift
|
|
80
|
+
assert_equal two_hours + " /bin/bash -l -c 'barbar'", output_without_empty_line.shift
|
|
81
|
+
assert_equal two_hours + " /bin/bash -l -c 'bazbaz' ; /bin/bash -l -c 'buzzbuzz'", output_without_empty_line.shift
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
test "defined jobs with a multiple groups with sequences specified on the group and jobs" do
|
|
85
|
+
output = Whenever.cron \
|
|
86
|
+
<<-file
|
|
87
|
+
every 2.hours, sequence: 'backups' do
|
|
88
|
+
command "blahblah"
|
|
89
|
+
command "barbar", sequence: nil
|
|
90
|
+
command "bazbaz", sequence: 'bees'
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
every 3.hours, sequence: 'backups' do
|
|
94
|
+
command "foofoo"
|
|
95
|
+
command "buzzbuzz", sequence: 'bees'
|
|
96
|
+
end
|
|
97
|
+
file
|
|
98
|
+
|
|
99
|
+
output_without_empty_line = lines_without_empty_line(output.lines)
|
|
100
|
+
assert_equal two_hours + " /bin/bash -l -c 'blahblah'", output_without_empty_line.shift
|
|
101
|
+
assert_equal two_hours + " /bin/bash -l -c 'barbar'", output_without_empty_line.shift
|
|
102
|
+
assert_equal two_hours + " /bin/bash -l -c 'bazbaz'", output_without_empty_line.shift
|
|
103
|
+
assert_equal three_hours + " /bin/bash -l -c 'foofoo'", output_without_empty_line.shift
|
|
104
|
+
assert_equal three_hours + " /bin/bash -l -c 'buzzbuzz'", output_without_empty_line.shift
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
test "defined jobs with a multiple groups with sequences specified on the group and jobs" do
|
|
108
|
+
assert_raises ArgumentError do
|
|
109
|
+
Whenever.cron \
|
|
110
|
+
<<-file
|
|
111
|
+
every 2.hours, sequence: 'backups' do
|
|
112
|
+
command "blahblah", at: 1
|
|
113
|
+
command "barbar", at: 2
|
|
114
|
+
end
|
|
115
|
+
file
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
test "defined jobs with a sequence argument and a description on the group" do
|
|
120
|
+
output = Whenever.cron \
|
|
121
|
+
<<-file
|
|
122
|
+
every 2.hours, sequence: 'backups', description: "Nightly backups" do
|
|
123
|
+
command "blahblah"
|
|
124
|
+
command "foofoo"
|
|
125
|
+
end
|
|
126
|
+
file
|
|
127
|
+
|
|
128
|
+
assert_match "# Nightly backups\n" + two_hours + " /bin/bash -l -c 'blahblah' ; /bin/bash -l -c 'foofoo'", output
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
test "defined jobs with a sequence argument and a description on each job" do
|
|
132
|
+
output = Whenever.cron \
|
|
133
|
+
<<-file
|
|
134
|
+
every 2.hours, sequence: 'backups' do
|
|
135
|
+
command "blahblah", description: "Dump the database"
|
|
136
|
+
command "foofoo", description: "Upload the dump"
|
|
137
|
+
end
|
|
138
|
+
file
|
|
139
|
+
|
|
140
|
+
assert_match "# Dump the database\n# Upload the dump\n" + two_hours + " /bin/bash -l -c 'blahblah' ; /bin/bash -l -c 'foofoo'", output
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
test "defined jobs with a sequence argument and descriptions padded with whitespace" do
|
|
144
|
+
output = Whenever.cron \
|
|
145
|
+
<<-file
|
|
146
|
+
every 2.hours, sequence: 'backups' do
|
|
147
|
+
command "blahblah", description: " Dump the database "
|
|
148
|
+
command "foofoo", description: " Upload the dump "
|
|
149
|
+
end
|
|
150
|
+
file
|
|
151
|
+
|
|
152
|
+
assert_match "# Dump the database\n# Upload the dump\n" + two_hours, output
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def three_hours
|
|
156
|
+
"0 0,3,6,9,12,15,18,21 * * *"
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
class OutputJobsWithSequentialTest < Whenever::TestCase
|
|
161
|
+
test "defined jobs with a sequential argument" do
|
|
162
|
+
output = Whenever.cron \
|
|
163
|
+
<<-file
|
|
164
|
+
every 2.hours, sequential: true do
|
|
165
|
+
command "blahblah"
|
|
166
|
+
command "foofoo"
|
|
167
|
+
end
|
|
168
|
+
file
|
|
169
|
+
|
|
170
|
+
output_without_empty_line = lines_without_empty_line(output.lines)
|
|
171
|
+
assert_equal two_hours + " /bin/bash -l -c 'blahblah' ; /bin/bash -l -c 'foofoo'", output_without_empty_line.shift
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
test "defined jobs with a sequential argument" do
|
|
175
|
+
output = Whenever.cron \
|
|
176
|
+
<<-file
|
|
177
|
+
every 2.hours, sequential: true do
|
|
178
|
+
command "blahblah"
|
|
179
|
+
command "foofoo", sequence: false
|
|
180
|
+
end
|
|
181
|
+
file
|
|
182
|
+
|
|
183
|
+
output_without_empty_line = lines_without_empty_line(output.lines)
|
|
184
|
+
assert_equal two_hours + " /bin/bash -l -c 'blahblah'", output_without_empty_line.shift
|
|
185
|
+
assert_equal two_hours + " /bin/bash -l -c 'foofoo'", output_without_empty_line.shift
|
|
186
|
+
end
|
|
187
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: whenever
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.1.
|
|
4
|
+
version: 1.1.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Javan Makhmali
|
|
@@ -65,6 +65,7 @@ files:
|
|
|
65
65
|
- lib/whenever/cron.rb
|
|
66
66
|
- lib/whenever/job.rb
|
|
67
67
|
- lib/whenever/job_list.rb
|
|
68
|
+
- lib/whenever/job_sequence.rb
|
|
68
69
|
- lib/whenever/numeric.rb
|
|
69
70
|
- lib/whenever/numeric_seconds.rb
|
|
70
71
|
- lib/whenever/os.rb
|
|
@@ -79,6 +80,7 @@ files:
|
|
|
79
80
|
- test/functional/output_env_test.rb
|
|
80
81
|
- test/functional/output_jobs_for_roles_test.rb
|
|
81
82
|
- test/functional/output_jobs_with_mailto_test.rb
|
|
83
|
+
- test/functional/output_jobs_with_sequence_test.rb
|
|
82
84
|
- test/functional/output_redirection_test.rb
|
|
83
85
|
- test/test_case.rb
|
|
84
86
|
- test/test_helper.rb
|
|
@@ -109,7 +111,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
109
111
|
- !ruby/object:Gem::Version
|
|
110
112
|
version: '0'
|
|
111
113
|
requirements: []
|
|
112
|
-
rubygems_version: 4.0.
|
|
114
|
+
rubygems_version: 4.0.16
|
|
113
115
|
specification_version: 4
|
|
114
116
|
summary: Cron jobs in ruby.
|
|
115
117
|
test_files:
|
|
@@ -121,6 +123,7 @@ test_files:
|
|
|
121
123
|
- test/functional/output_env_test.rb
|
|
122
124
|
- test/functional/output_jobs_for_roles_test.rb
|
|
123
125
|
- test/functional/output_jobs_with_mailto_test.rb
|
|
126
|
+
- test/functional/output_jobs_with_sequence_test.rb
|
|
124
127
|
- test/functional/output_redirection_test.rb
|
|
125
128
|
- test/unit/capistrano_support_test.rb
|
|
126
129
|
- test/unit/cron_test.rb
|