schedule_job 1.0.2 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 11be78ebaf233db44fee63212623c4e68518fa16c1853df6cb87479f7a6733c9
4
- data.tar.gz: a0d22e81142823bc94a5c0c2ee1f69677ffa2bccd536026841308d12bcc1421d
3
+ metadata.gz: 74b687e00b810539cf4895da252bb96bed4d8843265bd07cdd3c3cd3a20960de
4
+ data.tar.gz: 8f59585f2c14dfd8f7be9496b6ba4db86a43d4e2fcf81405f9d30662fc9b2f60
5
5
  SHA512:
6
- metadata.gz: 67070c26ee315c66e29833ca42b5cb2aff986b6f2c40110e30cc0e513e5a3429da8a0e7e7c8ea83c39f67bd0e478f5fe912e6b1e021ae54e981693e0cde9ee47
7
- data.tar.gz: 1598e6c9a1085a9119307c6511aa8886257e2ee617740e66a6e9377ab876899f4c84469ddf26e65395fafab1e59be90154cd1ee49e29701ebf40cff7f2b74ff3
6
+ metadata.gz: 5650b386a21d969249421e293be7935080c5177feba124497db3ae87f187a6f01529cd145f16548f2b65c66ce674e39cf3f8afa0da8276cd00d3768ab9eeca57
7
+ data.tar.gz: 7dec6a2da90eba5ab5216dc7bac5e6d6b5644547d96f090c6b5add60c0a0bd01c6f014bda62150f6e9ba4ae1e8c0c867c8da26322888ae709d72e403c40b10df
data/Gemfile CHANGED
@@ -4,9 +4,6 @@ source "https://rubygems.org"
4
4
  gemspec
5
5
 
6
6
  gem "citrus"
7
- # gem "whenever"
8
7
  gem "cronex"
9
8
  gem "parse-cron"
10
- gem "activesupport"
11
- # gem "treetop"
12
- # gem "polyglot"
9
+ gem "activesupport"
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- schedule_job (1.0.0)
4
+ schedule_job (1.0.4)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -17,64 +17,71 @@ Done installing documentation for schedule_job after 0 seconds
17
17
 
18
18
  Example usage:
19
19
  ```
20
- ~ ❯ schedule -h
20
+ ~ ❯ schedule --help
21
21
  Usage: schedule [options] command
22
22
  -d, --dryrun Report what would happen but do not install the scheduled job.
23
23
  -l, --list List installed cron jobs.
24
24
  -r, --rm JOB_ID Remove the specified job id as indicated by --list
25
25
  -u, --user USER User that the crontab belongs to.
26
- -e, --every DURATION Run command every DURATION units of time.
26
+ -e, --every DURATION Run command every DURATION units of time (valid suffixes are m, h, d, M). DURATION may also be one of the special keywords: reboot, year, month, week, day, hour
27
27
  For example:
28
- --every 10m # meaning, every 10 minutes
29
- --every 5h # meaning, every 5 hours
30
- --every 2d # meaning, every 2 days
31
- --every 3M # meaning, every 3 months
28
+ --every 10m # every 10 minutes
29
+ --every 5h # every 5 hours
30
+ --every 2d # every 2 days
31
+ --every 3M # every 3 months
32
+
33
+ Special durations:
34
+ --every reboot # after every reboot
35
+ --every year # every year
36
+ --every month # every month
37
+ --every week # every week
38
+ --every day # every day
39
+ --every hour # every hour
32
40
 
33
41
  -c, --cron CRON Run command on the given cron schedule.
34
42
  For example:
35
- --cron "*/5 15 * * 1-5" # meaning, Every 5 minutes, at 3:00 PM, Monday through Friday
36
- --cron "0 0/30 8-9 5,20 * ?" # meaning, Every 30 minutes, between 8:00 AM and 9:59 AM, on day 5 and 20 of the month
43
+ --cron "*/5 15 * * 1-5" # Every 5 minutes, at 3:00 PM, Monday through Friday
44
+ --cron "0 0/30 8-9 5,20 * ?" # Every 30 minutes, between 8:00 AM and 9:59 AM, on day 5 and 20 of the month
37
45
 
38
46
  ~ ❯ schedule -l
39
47
  ~ ❯ schedule -d -e 10m backup.sh
40
48
  Scheduling: backup.sh Every 10 minutes
41
49
  Next three runs:
42
- 1. 2021-11-01 21:40:00 -0500
43
- 2. 2021-11-01 21:50:00 -0500
44
- 3. 2021-11-01 22:00:00 -0500
50
+ 1. 2021-11-01 21:50:00 -0500
51
+ 2. 2021-11-01 22:00:00 -0500
52
+ 3. 2021-11-01 22:10:00 -0500
45
53
  ~ ❯ schedule -l
46
54
  Jobs
47
55
  1. backup.sh Every 10 minutes
48
56
  ~ ❯ crontab -l
49
57
  */10 * * * * backup.sh
50
-
51
58
  ~ ❯ schedule -e 3M quarterly_backup.sh
52
- Scheduling: quarterly_backup.sh At 9:43 PM, on day 1 of the month, every 3 months
59
+ Scheduling: quarterly_backup.sh At 9:50 PM, on day 1 of the month, every 3 months
53
60
  Next three runs:
54
- 1. 2022-01-01 21:43:00 -0600
55
- 2. 2022-04-01 21:43:00 -0500
56
- 3. 2022-07-01 21:43:00 -0500
61
+ 1. 2022-01-01 21:50:00 -0600
62
+ 2. 2022-04-01 21:50:00 -0500
63
+ 3. 2022-07-01 21:50:00 -0500
57
64
  ~ ❯ schedule -l
58
65
  Jobs
59
66
  1. backup.sh Every 10 minutes
60
- 2. quarterly_backup.sh At 9:43 PM, on day 1 of the month, every 3 months
67
+ 2. quarterly_backup.sh At 9:50 PM, on day 1 of the month, every 3 months
61
68
  ~ ❯ crontab -l
62
69
  */10 * * * * backup.sh
63
- 43 21 1 */3 * quarterly_backup.sh
64
-
70
+ 50 21 1 */3 * quarterly_backup.sh
65
71
  ~ ❯ schedule --dryrun --rm 1
66
72
  Would remove: backup.sh Every 10 minutes
67
73
  ~ ❯ schedule --dryrun --rm 2
68
- Would remove: quarterly_backup.sh At 9:43 PM, on day 1 of the month, every 3 months
74
+ Would remove: quarterly_backup.sh At 9:50 PM, on day 1 of the month, every 3 months
69
75
  ~ ❯ schedule --rm 1
70
76
  Removing: backup.sh Every 10 minutes
71
77
  ~ ❯ schedule -l
72
78
  Jobs
73
- 1. quarterly_backup.sh At 9:43 PM, on day 1 of the month, every 3 months
79
+ 1. quarterly_backup.sh At 9:50 PM, on day 1 of the month, every 3 months
74
80
  ~ ❯ schedule --rm 1
75
- Removing: quarterly_backup.sh At 9:43 PM, on day 1 of the month, every 3 months
81
+ Removing: quarterly_backup.sh At 9:50 PM, on day 1 of the month, every 3 months
76
82
  ~ ❯ schedule -l
77
83
  ~ ❯ crontab -l
84
+ ~ ❯
78
85
  ```
79
86
 
80
87
  ## License
@@ -32,20 +32,28 @@ module ScheduleJob
32
32
  options[:crontab_user] = user
33
33
  end
34
34
 
35
- opts.on("-e", "--every DURATION", "Run command every DURATION units of time.
35
+ opts.on("-e", "--every DURATION", "Run command every DURATION units of time (valid suffixes are m, h, d, M). DURATION may also be one of the special keywords: reboot, year, month, week, day, hour
36
36
  For example:
37
- --every 10m # meaning, every 10 minutes
38
- --every 5h # meaning, every 5 hours
39
- --every 2d # meaning, every 2 days
40
- --every 3M # meaning, every 3 months
37
+ --every 10m # every 10 minutes
38
+ --every 5h # every 5 hours
39
+ --every 2d # every 2 days
40
+ --every 3M # every 3 months
41
+
42
+ Special durations:
43
+ --every reboot # after every reboot
44
+ --every year # every year
45
+ --every month # every month
46
+ --every week # every week
47
+ --every day # every day
48
+ --every hour # every hour
41
49
  ") do |every|
42
50
  options[:every] = every
43
51
  end
44
52
 
45
53
  opts.on("-c", "--cron CRON", "Run command on the given cron schedule.
46
54
  For example:
47
- --cron \"*/5 15 * * 1-5\" # meaning, Every 5 minutes, at 3:00 PM, Monday through Friday
48
- --cron \"0 0/30 8-9 5,20 * ?\" # meaning, Every 30 minutes, between 8:00 AM and 9:59 AM, on day 5 and 20 of the month
55
+ --cron \"*/5 15 * * 1-5\" # Every 5 minutes, at 3:00 PM, Monday through Friday
56
+ --cron \"0 0/30 8-9 5,20 * ?\" # Every 30 minutes, between 8:00 AM and 9:59 AM, on day 5 and 20 of the month
49
57
  ") do |cron_schedule|
50
58
  options[:cron] = cron_schedule
51
59
  end
@@ -90,13 +98,14 @@ module ScheduleJob
90
98
  Cron::Job.new(cron_schedule, command)
91
99
  when args[:every]
92
100
  duration = args[:every]
93
- match = duration.match(/(\d+)(m|h|d|M)/)
94
- if match
101
+ if match = duration.match(/(\d+)(m|h|d|M)/)
95
102
  qty = match[1].to_i
96
103
  unit_of_time = match[2].to_s
97
104
  Cron::Job.every(qty, unit_of_time, command)
105
+ elsif duration.match(/reboot|year|month|week|day|hour/)
106
+ Cron::Job.every_simple_duration(duration, command)
98
107
  else
99
- puts "'#{duration}' is an invalid duration. The duration must be specified as: integer followed immediately by m (minutes), h (hours), d (days), M (months) (e.g. 10m)"
108
+ puts "'#{duration}' is an invalid duration. The duration must be specified as either (1) integer followed immediately by m (minutes), h (hours), d (days), M (months) (e.g. 10m) or (2) reboot, year, month, week, day, hour"
100
109
  exit(1)
101
110
  end
102
111
  end
@@ -50,12 +50,6 @@ module ScheduleJob
50
50
 
51
51
  raise("Unable to read crontab: #{error_output}") if !exit_status.success? && !no_crontab
52
52
 
53
- # puts "read_crontab()"
54
- # puts "stdout:"
55
- # puts stdout
56
- # puts "stderr:"
57
- # puts stderr
58
-
59
53
  crontab_output
60
54
  end
61
55
 
@@ -63,16 +57,8 @@ module ScheduleJob
63
57
  def parse_crontab(user_crontab)
64
58
  parser = TableParser.new(user_crontab)
65
59
 
66
- # user_crontab.each_line do |line|
67
- # puts line
68
- # puts "valid? #{LineParser.valid?(line)}"
69
- # puts LineParser.parse(line)
70
- # end
71
-
72
60
  return [], [] unless parser.valid?
73
61
 
74
- # puts "valid!"
75
-
76
62
  environment_vars = parser.environment_vars&.map do |env_directive|
77
63
  name = env_directive[:var].to_s
78
64
  expr = env_directive[:expr].to_s
@@ -108,7 +94,6 @@ module ScheduleJob
108
94
 
109
95
  def install_cron_job(job)
110
96
  job_spec = job.specification
111
- # puts "Installing new cron job: #{job_spec}"
112
97
 
113
98
  new_crontab = [read_crontab(@user).strip, job_spec.strip].reject(&:empty?).join("\n")
114
99
  new_crontab << "\n" # add a trailing newline
@@ -136,21 +121,12 @@ module ScheduleJob
136
121
  end
137
122
 
138
123
  def write_crontab(new_crontab, user = @user)
124
+ # overwrite crontab interactively, per https://stackoverflow.com/questions/610839/how-can-i-programmatically-create-a-new-cron-job
139
125
  command = ["crontab"]
140
126
  command << "-u #{user}" if user
141
127
  command << "-"
142
128
  command = command.join(" ")
143
129
 
144
- # command = "(crontab -l ; echo \"#{job_spec}\") | crontab -" # add new job to bottom of crontab, per https://stackoverflow.com/questions/610839/how-can-i-programmatically-create-a-new-cron-job
145
- # puts "writing new crontab:"
146
- # puts new_crontab
147
- # puts "*" * 80
148
-
149
- # puts "write_crontab:"
150
- # puts "command: #{command}"
151
- # puts "new crontab:"
152
- # puts new_crontab
153
-
154
130
  stdout, stderr, exit_status = Open3.capture3(command, stdin_data: new_crontab)
155
131
  crontab_output = stdout
156
132
  error_output = stderr
@@ -197,6 +173,25 @@ module ScheduleJob
197
173
  self.new(schedule_spec, command)
198
174
  end
199
175
 
176
+ # duration is one of: reboot, year, month, week, day, hour
177
+ def self.every_simple_duration(duration, command)
178
+ schedule_spec = case duration
179
+ when "reboot"
180
+ "@reboot"
181
+ when "year"
182
+ "@yearly"
183
+ when "month"
184
+ "@monthly"
185
+ when "week"
186
+ "@weekly"
187
+ when "day"
188
+ "@daily"
189
+ when "hour"
190
+ "@hourly"
191
+ end
192
+ self.new(schedule_spec, command)
193
+ end
194
+
200
195
  attr_reader :schedule_spec
201
196
  attr_reader :line_number
202
197
 
@@ -17,10 +17,6 @@ end
17
17
 
18
18
  Citrus.require("schedule_job/cron")
19
19
 
20
- # require "polyglot"
21
- # require "treetop"
22
- # require "schedule_job/cron.treetop"
23
-
24
20
  module ScheduleJob
25
21
  module Cron
26
22
  Grammar = ScheduleCronParser
@@ -34,7 +30,6 @@ module ScheduleJob
34
30
 
35
31
  def self.parse(user_crontab_string)
36
32
  Grammar.parse(user_crontab_string, root: :user_crontab)
37
- # ::CrontabParser.new.parse(user_crontab_string, root: :user_crontab)
38
33
  end
39
34
 
40
35
  def initialize(user_crontab_string)
@@ -55,17 +50,10 @@ module ScheduleJob
55
50
 
56
51
  def environment_vars
57
52
  @user_crontab&.capture(:environment)&.captures(:directive)
58
- # puts @user_crontab.methods.sort.inspect
59
- # puts @user_crontab.inspect
60
- # puts "*" * 80
61
- # puts @user_crontab.environment_spec.inspect
62
- # exit()
63
- # @user_crontab&.environment&.directive
64
53
  end
65
54
 
66
55
  def job_specs
67
56
  @user_crontab&.capture(:jobspecs)&.captures(:jobspec)
68
- # @user_crontab&.jobspecs&.jobspec
69
57
  end
70
58
  end
71
59
 
@@ -78,7 +66,6 @@ module ScheduleJob
78
66
 
79
67
  def self.parse(cron_line)
80
68
  Grammar.parse(cron_line, root: :jobspec, consume: false)
81
- # ::CrontabParser.new.parse(cron_line, root: :jobspec, consume_all_input: false)
82
69
  end
83
70
  end
84
71
  end
@@ -1,3 +1,3 @@
1
1
  module ScheduleJob
2
- VERSION = "1.0.2"
2
+ VERSION = "1.0.4"
3
3
  end
data/schedule_job.gemspec CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.description = "job scheduler"
11
11
  spec.homepage = "https://github.com/davidkellis/scheduler"
12
12
  spec.license = "MIT"
13
- spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
13
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
14
14
 
15
15
  spec.files = Dir["**/**"].
16
16
  grep_v(/.gem$/).
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: schedule_job
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Ellis
@@ -69,7 +69,6 @@ files:
69
69
  - lib/schedule_job/cli.rb
70
70
  - lib/schedule_job/cron.citrus
71
71
  - lib/schedule_job/cron.rb
72
- - lib/schedule_job/cron.treetop
73
72
  - lib/schedule_job/cron_parser.rb
74
73
  - lib/schedule_job/version.rb
75
74
  - schedule_job.gemspec
@@ -85,7 +84,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
85
84
  requirements:
86
85
  - - ">="
87
86
  - !ruby/object:Gem::Version
88
- version: 2.7.0
87
+ version: 2.5.0
89
88
  required_rubygems_version: !ruby/object:Gem::Requirement
90
89
  requirements:
91
90
  - - ">="
@@ -1,167 +0,0 @@
1
- grammar Crontab
2
- rule user_crontab
3
- sep?
4
- environment_spec:(environment sep)?
5
- jobspecs?
6
- sep?
7
- end
8
-
9
- rule environment
10
- head:directive tail:(sep directive)*
11
- end
12
-
13
- rule directive
14
- var space "=" space expr
15
- end
16
-
17
- rule var
18
- alpha alphanumeric?
19
- end
20
-
21
- rule expr
22
- command
23
- end
24
-
25
- rule jobspecs
26
- head:jobspec tail:(sep jobspec)*
27
- end
28
-
29
- rule jobspec
30
- schedule_spec space command ws*
31
- end
32
-
33
- rule schedule_spec
34
- standard / special
35
- end
36
-
37
- rule standard
38
- minute space hour space dayofmonth space month space dayofweek
39
- end
40
-
41
- rule special
42
- "@" ("yearly" / "annually" / "monthly" / "weekly" / "daily" / "hourly" / "reboot")
43
- end
44
-
45
- rule minute
46
- step
47
- end
48
-
49
- rule hour
50
- step
51
- end
52
-
53
- rule dayofmonthtypes
54
- step
55
- end
56
-
57
- rule monthtypes
58
- step / altmonths
59
- end
60
-
61
- rule dayofweektypes
62
- step / altdays
63
- end
64
-
65
- rule dayofmonth
66
- dayofmonthtypes ("," dayofmonthtypes)*
67
- end
68
-
69
- rule month
70
- monthtypes ("," monthtypes)*
71
- end
72
-
73
- rule dayofweek
74
- dayofweektypes ("," dayofweektypes)*
75
- end
76
-
77
- rule command
78
- quoted_string
79
- / (!("\n" / comment) .)+
80
- end
81
-
82
- rule step
83
- common ("/" int)?
84
- end
85
-
86
- rule common
87
- range / int / any
88
- end
89
-
90
- rule range
91
- int "-" int
92
- end
93
-
94
- rule altdays
95
- days ("," days)*
96
- end
97
-
98
- rule altmonths
99
- months ("," months)*
100
- end
101
-
102
- rule days
103
- "MON" / "TUE" / "WED" / "THU" / "FRI" / "SAT" / "SUN"
104
- end
105
-
106
- rule months
107
- "JAN" / "FEB" / "MAR" / "APR" / "MAY" / "JUN" / "JUL" / "AUG" / "SEP" / "OCT" / "NOV" / "DEC"
108
- end
109
-
110
- rule any
111
- "*"
112
- end
113
-
114
- rule int
115
- [0-9]+
116
- end
117
-
118
- rule alpha
119
- [a-zA-Z]+
120
- end
121
-
122
- rule alphanumeric
123
- [a-zA-Z0-9]+
124
- end
125
-
126
- rule sep
127
- (ws* nl)+
128
- end
129
-
130
- rule ws
131
- space / comment
132
- end
133
-
134
- rule space
135
- [ \t]+
136
- end
137
-
138
- rule nl
139
- [\n]+
140
- end
141
-
142
- rule comment
143
- "#" (!"\n" .)*
144
- end
145
-
146
- rule quoted_string
147
- "\"" ( (!("\"" / "\\") .) / escape)* "\""
148
- / "'" ( (!("'" / "\\") .) / escape)* "'"
149
- end
150
-
151
- rule escape
152
- "\\" escape_sequence
153
- end
154
-
155
- rule escape_sequence
156
- "'"
157
- / "\""
158
- / "\\"
159
- / "b"
160
- / "f"
161
- / "n"
162
- / "r"
163
- / "t"
164
- / "v"
165
- end
166
-
167
- end