rbcrontab 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +22 -0
- data/Rakefile +39 -0
- data/TODO +0 -0
- data/examples/cli_crontab.rb +36 -0
- data/lib/extensions.rb +40 -0
- data/lib/rbcrontab.rb +186 -0
- metadata +59 -0
data/README
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2008 Rob Hurring
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/testtask'
|
4
|
+
require 'rake/rdoctask'
|
5
|
+
require 'rake/gempackagetask'
|
6
|
+
|
7
|
+
spec = Gem::Specification.new do |s|
|
8
|
+
s.name = 'rbcrontab'
|
9
|
+
s.version = '0.1'
|
10
|
+
s.summary = 'Generate crontabs using ruby'
|
11
|
+
s.author = 'Rob Hurring'
|
12
|
+
s.email = 'rob@ubrio.us'
|
13
|
+
s.homepage = 'http://robhurring.com'
|
14
|
+
s.platform = Gem::Platform::RUBY
|
15
|
+
s.rubyforge_project = 'rbcrontab'
|
16
|
+
s.has_rdoc = true
|
17
|
+
s.extra_rdoc_files = [ 'README' ]
|
18
|
+
s.rdoc_options << '--main' << 'README'
|
19
|
+
s.files = Dir.glob("{examples,lib}/**/*") +
|
20
|
+
[ 'README', 'Rakefile', 'TODO' ]
|
21
|
+
end
|
22
|
+
|
23
|
+
desc 'Generate RDoc'
|
24
|
+
Rake::RDocTask.new :rdoc do |rd|
|
25
|
+
rd.rdoc_dir = 'doc'
|
26
|
+
rd.rdoc_files.add 'lib', 'README'
|
27
|
+
rd.main = 'README'
|
28
|
+
end
|
29
|
+
|
30
|
+
desc 'Build Gem'
|
31
|
+
Rake::GemPackageTask.new spec do |pkg|
|
32
|
+
pkg.need_tar = true
|
33
|
+
end
|
34
|
+
|
35
|
+
desc 'Clean up'
|
36
|
+
task :clean => [ :clobber_rdoc, :clobber_package ]
|
37
|
+
|
38
|
+
desc 'Clean up'
|
39
|
+
task :clobber => [ :clean ]
|
data/TODO
ADDED
File without changes
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env ruby -rrubygems
|
2
|
+
require 'rbcrontab'
|
3
|
+
|
4
|
+
# want to source my bash profile before certain schedules
|
5
|
+
source_bash_profile = ['source $HOME/.bash_profile']
|
6
|
+
|
7
|
+
crontab = Crontab.new do |cron|
|
8
|
+
|
9
|
+
cron.mail_to 'user@example.com'
|
10
|
+
cron.home '/home/user'
|
11
|
+
cron.path ['/home/user/bin', '/home/user/something/bin']
|
12
|
+
|
13
|
+
cron.desc 'Check for new requests every 5 minutes on weekdays'
|
14
|
+
cron.schedule(:every => 5.minutes, :on => Days::WEEKDAYS, :setup => source_bash_profile, :mail_to => 'someone@example.com') do
|
15
|
+
"rake requests:check"
|
16
|
+
end
|
17
|
+
|
18
|
+
cron.schedule(:at => Time::MIDNIGHT, :on => Days::WEEKENDS) do
|
19
|
+
"party"
|
20
|
+
end
|
21
|
+
|
22
|
+
cron.desc 'At 1:15p every 5 days in May mail my mom'
|
23
|
+
cron.schedule(:at => '13:15', :on_the => '5,10,15,20,25,30', :of => Month::MAY) do
|
24
|
+
'echo "hey mom!"|mail mom@example.com -s "your son forgot to call so hes emailing!"'
|
25
|
+
end
|
26
|
+
|
27
|
+
cron.desc 'Check hourly for new mail on weekdays in March'
|
28
|
+
cron.schedule(:every => 1.hour, :in => Month::MARCH, :on => Days::WEEKDAYS) do
|
29
|
+
'check_for_mail'
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
# this will use optparse to create 2 different options
|
35
|
+
# run this script using the '-h' option to see usage
|
36
|
+
Crontab::CLI.start! binding
|
data/lib/extensions.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# create the cron equiv of Fixnum.minutes
|
2
|
+
# Example:
|
3
|
+
# 10.minutes #=> '10/* *'
|
4
|
+
# 5.hours #=> '* 5/*'
|
5
|
+
class Fixnum
|
6
|
+
def minutes
|
7
|
+
'%s/* *' % self
|
8
|
+
end
|
9
|
+
alias_method :minute, :minutes
|
10
|
+
def hours
|
11
|
+
'* %s/*' % self
|
12
|
+
end
|
13
|
+
alias_method :hour, :hours
|
14
|
+
end
|
15
|
+
|
16
|
+
class Month
|
17
|
+
JANUARY = 1
|
18
|
+
FEBRUARY = 2
|
19
|
+
MARCH = 3
|
20
|
+
APRIL = 4
|
21
|
+
MAY = 5
|
22
|
+
JUNE = 6
|
23
|
+
JULY = 7
|
24
|
+
AUGUST = 8
|
25
|
+
SEPTEMBER = 9
|
26
|
+
OCTOBER = 10
|
27
|
+
NOVEMBER = 11
|
28
|
+
DECEMBER = 12
|
29
|
+
end
|
30
|
+
|
31
|
+
class Time
|
32
|
+
MIDNIGHT = '0:0'
|
33
|
+
NOON = '12:0'
|
34
|
+
end
|
35
|
+
|
36
|
+
class Days
|
37
|
+
EVERYDAY = '*'
|
38
|
+
WEEKDAYS = '1-5'
|
39
|
+
WEEKENDS = '0,6'
|
40
|
+
end
|
data/lib/rbcrontab.rb
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
# == About
|
2
|
+
#
|
3
|
+
# Author:: Rob Hurring <rob@ubrio.us>
|
4
|
+
# Website:: http://robhurring.com
|
5
|
+
#
|
6
|
+
# This is s a stupid simple way to make managing crontabs easier
|
7
|
+
# It allows you to write basic cron tasks in ruby and output the
|
8
|
+
# complete crontab. I find it easier with setup tasks and repetitive
|
9
|
+
# schedules and such. Really only meant as a simple cron mgt. script
|
10
|
+
#
|
11
|
+
# == License
|
12
|
+
#
|
13
|
+
# Copyright (c) 2008 Rob Hurring
|
14
|
+
#
|
15
|
+
# Permission is hereby granted, free of charge, to any person
|
16
|
+
# obtaining a copy of this software and associated documentation
|
17
|
+
# files (the "Software"), to deal in the Software without
|
18
|
+
# restriction, including without limitation the rights to use,
|
19
|
+
# copy, modify, merge, publish, distribute, sublicense, and/or sell
|
20
|
+
# copies of the Software, and to permit persons to whom the
|
21
|
+
# Software is furnished to do so, subject to the following
|
22
|
+
# conditions:
|
23
|
+
#
|
24
|
+
# The above copyright notice and this permission notice shall be
|
25
|
+
# included in all copies or substantial portions of the Software.
|
26
|
+
#
|
27
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
28
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
29
|
+
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
30
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
31
|
+
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
32
|
+
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
33
|
+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
34
|
+
# OTHER DEALINGS IN THE SOFTWARE.
|
35
|
+
require 'optparse'
|
36
|
+
require 'extensions'
|
37
|
+
# Example:
|
38
|
+
# crontab = Crontab.new do |cron|
|
39
|
+
# cron.desc 'this is my schedule description'
|
40
|
+
# cron.schedule(:every => 10.minutes, :on => Days::WEEKDAYS) { 'do something' }
|
41
|
+
# end
|
42
|
+
# puts crontab.to_crontab
|
43
|
+
#
|
44
|
+
# see the examples directory for a more verbose example
|
45
|
+
class Crontab
|
46
|
+
# can either use as a block or regular object
|
47
|
+
# Crontab.new { |cron| ... }
|
48
|
+
# crontab = Crontab.new
|
49
|
+
def initialize
|
50
|
+
@schedules = []
|
51
|
+
yield self if block_given?
|
52
|
+
end
|
53
|
+
# set the MAILTO user for the _entire_ crontab
|
54
|
+
# to set it per-schedule view the schedule :mail_to arg
|
55
|
+
def mail_to(who)
|
56
|
+
@mail_to = who
|
57
|
+
end
|
58
|
+
# set the path for the _entire_ crontab
|
59
|
+
# include_path will keep the original $PATH in there
|
60
|
+
def path(paths, include_path = true)
|
61
|
+
@paths = []
|
62
|
+
@paths << '$PATH' if include_path
|
63
|
+
@paths << paths
|
64
|
+
@paths = @paths.flatten.join(':')
|
65
|
+
end
|
66
|
+
# set your home path, probably not necessary, but why not
|
67
|
+
def home(home_path)
|
68
|
+
@home = home_path
|
69
|
+
end
|
70
|
+
# creates a schedule object from the args passes
|
71
|
+
# your command will go in the block
|
72
|
+
#
|
73
|
+
# crontab.schedule(:args => ...) { "command to run" }
|
74
|
+
def schedule(*args, &block)
|
75
|
+
args.first.merge! :description => @last_description if @last_description
|
76
|
+
@last_description = nil
|
77
|
+
@schedules << Schedule.new(*args, &block)
|
78
|
+
end
|
79
|
+
# runs the to_cron method on all schedules and dumps
|
80
|
+
# the crontab to be copied/pasted
|
81
|
+
def to_crontab
|
82
|
+
@schedules.inject(header){ |o, s| o << s.to_cron + "\n\n" }
|
83
|
+
end
|
84
|
+
# sets the description for the schedule immediately following
|
85
|
+
def desc(description)
|
86
|
+
@last_description = description
|
87
|
+
end
|
88
|
+
# lists the descriptions of all cron schedules for easy reviewing
|
89
|
+
def describe
|
90
|
+
output = "Crontabs\n" + ('-' * 40) + "\n"
|
91
|
+
descriptions = @schedules.map{ |s| s.description }.compact
|
92
|
+
descriptions.each_with_index do |d, i|
|
93
|
+
output << "##{i + 1}: #{d}\n"
|
94
|
+
end
|
95
|
+
output
|
96
|
+
end
|
97
|
+
def header #:nodoc:
|
98
|
+
headers = []
|
99
|
+
headers << "HOME=%s" % @home if @home
|
100
|
+
headers << "PATH=%s" % @paths if @paths
|
101
|
+
headers << "MAILTO=%s" % @mail_to if @mail_to
|
102
|
+
headers << "\n" unless headers.empty?
|
103
|
+
headers.join("\n")
|
104
|
+
end
|
105
|
+
# Example:
|
106
|
+
# crontab.schedule(:at => Time::MIDNIGHT, :on => Day::WEEKDAYS) { 'backup_database' }
|
107
|
+
# crontab.schedule(:every => 10.minutes, :on => Day::WEEKENDS) { 'check something' }
|
108
|
+
# crontab.schedule(:at => '18:00', :on_the => '5', :of => Month::MAY) { 'party!' }
|
109
|
+
class Schedule
|
110
|
+
attr_reader :description
|
111
|
+
# args consist of
|
112
|
+
# * :every => 1.minute, 10.minutes, 1.hour, 5.hours -- minutes or hours
|
113
|
+
# * :at => '00:00' -- 24 hour time for when to run
|
114
|
+
# * :on => '1,2,3' -- days of the _week_, or Day::CONSTANT
|
115
|
+
# * :on_the => '1,2,3' -- days of the _month_
|
116
|
+
# * :in => Month::JANUARY -- month [0..12]
|
117
|
+
# * :of => Month::JANUARY -- month [0..12] -- alias for readability
|
118
|
+
def initialize(*args, &block)
|
119
|
+
args.first.each { |k,v| instance_variable_set "@#{k}", v }
|
120
|
+
@do = yield
|
121
|
+
end
|
122
|
+
# builds the cron schedule line
|
123
|
+
def to_cron
|
124
|
+
cron_lines = []
|
125
|
+
cron_lines << cron_description if @description
|
126
|
+
cron_lines << ('MAILTO=%s' % [@mail_to]) if @mail_to
|
127
|
+
cron_lines << ("%s %s %s %s %s" % [time, days_of_month, months, weekdays, command])
|
128
|
+
cron_lines.join("\n")
|
129
|
+
end
|
130
|
+
private
|
131
|
+
def cron_description #:nodoc:
|
132
|
+
"# #{@description}" if @description
|
133
|
+
end
|
134
|
+
def command #:nodoc:
|
135
|
+
all_commands = []
|
136
|
+
all_commands << @setup if @setup
|
137
|
+
all_commands << @do
|
138
|
+
all_commands.join ' && '
|
139
|
+
end
|
140
|
+
def time #:nodoc:
|
141
|
+
@at ? (@at || '*:*').split(':').reverse.join(' ') : (@every || '* *')
|
142
|
+
end
|
143
|
+
def days_of_month #:nodoc:
|
144
|
+
@on_the || '*'
|
145
|
+
end
|
146
|
+
def months #:nodoc:
|
147
|
+
@in || @of || '*'
|
148
|
+
end
|
149
|
+
def weekdays #:nodoc:
|
150
|
+
@on || '*'
|
151
|
+
end
|
152
|
+
end
|
153
|
+
# Simple CLI class which includes basic command line options
|
154
|
+
# to the cron script
|
155
|
+
# Options:
|
156
|
+
# -h --help print the usage
|
157
|
+
# -d --describe describes the crontab
|
158
|
+
class CLI
|
159
|
+
# evaluates the necessary script to handle CLI option parsing
|
160
|
+
# it wants the current binding so inside your script you'd do
|
161
|
+
# Example:
|
162
|
+
# Crontab::CLI.start!(binding)
|
163
|
+
def self.start!(the_binding)
|
164
|
+
eval %{if $0 == __FILE__
|
165
|
+
options = {}
|
166
|
+
OptionParser.new do |opts|
|
167
|
+
opts.banner = "Usage: #{$0} [options]"
|
168
|
+
opts.on('-d', '--describe', 'Describe current cron schedules') do |d|
|
169
|
+
options[:describe] = d
|
170
|
+
end
|
171
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
172
|
+
puts opts
|
173
|
+
exit
|
174
|
+
end
|
175
|
+
end.parse!
|
176
|
+
|
177
|
+
if options[:describe]
|
178
|
+
puts crontab.describe
|
179
|
+
else
|
180
|
+
puts crontab.to_crontab
|
181
|
+
end
|
182
|
+
end
|
183
|
+
}, the_binding
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
metadata
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rbcrontab
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "0.1"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Rob Hurring
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-08-24 00:00:00 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: rob@ubrio.us
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README
|
24
|
+
files:
|
25
|
+
- examples/cli_crontab.rb
|
26
|
+
- lib/extensions.rb
|
27
|
+
- lib/rbcrontab.rb
|
28
|
+
- README
|
29
|
+
- Rakefile
|
30
|
+
- TODO
|
31
|
+
has_rdoc: true
|
32
|
+
homepage: http://robhurring.com
|
33
|
+
post_install_message:
|
34
|
+
rdoc_options:
|
35
|
+
- --main
|
36
|
+
- README
|
37
|
+
require_paths:
|
38
|
+
- lib
|
39
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: "0"
|
44
|
+
version:
|
45
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: "0"
|
50
|
+
version:
|
51
|
+
requirements: []
|
52
|
+
|
53
|
+
rubyforge_project: rbcrontab
|
54
|
+
rubygems_version: 1.2.0
|
55
|
+
signing_key:
|
56
|
+
specification_version: 2
|
57
|
+
summary: Generate crontabs using ruby
|
58
|
+
test_files: []
|
59
|
+
|