rcronwtf 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.
- data/.document +5 -0
- data/.gitignore +5 -0
- data/LICENSE +20 -0
- data/README.rdoc +17 -0
- data/Rakefile +81 -0
- data/VERSION +1 -0
- data/lib/rcronwtf/entry.rb +114 -0
- data/lib/rcronwtf/table.rb +24 -0
- data/lib/rcronwtf.rb +8 -0
- data/rcronwtf.gemspec +51 -0
- data/test/entry_test.rb +111 -0
- data/test/table_test.rb +39 -0
- data/test/test_helper.rb +3 -0
- metadata +70 -0
data/.document
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Darrin Holst
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
== DESCRIPTION:
|
2
|
+
|
3
|
+
a ruby port of http://github.com/technoweenie/cronwtf that translates
|
4
|
+
cron tables and/or entries to human readable text
|
5
|
+
|
6
|
+
== SYNOPSIS:
|
7
|
+
|
8
|
+
CronWTF::Table.new(`crontab -l`).to_s
|
9
|
+
CronWTF::Entry.new("*/10 * * * * /usr/bin/some_command").to_s
|
10
|
+
|
11
|
+
== INSTALL:
|
12
|
+
|
13
|
+
sudo gem install rcronwtf
|
14
|
+
|
15
|
+
== Copyright
|
16
|
+
|
17
|
+
Copyright (c) 2009 Darrin Holst. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "rcronwtf"
|
8
|
+
gem.summary = %Q{translate cron entries into human readable form}
|
9
|
+
gem.email = "darrinholst@gmail.com"
|
10
|
+
gem.homepage = "http://github.com/darrinholst/rcronwtf"
|
11
|
+
gem.authors = ["Darrin Holst"]
|
12
|
+
gem.rubyforge_project = 'rcronwtf'
|
13
|
+
end
|
14
|
+
rescue LoadError
|
15
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
16
|
+
end
|
17
|
+
|
18
|
+
begin
|
19
|
+
require 'rake/contrib/sshpublisher'
|
20
|
+
namespace :rubyforge do
|
21
|
+
|
22
|
+
desc "Release gem and RDoc documentation to RubyForge"
|
23
|
+
task :release => ["rubyforge:release:gem", "rubyforge:release:docs"]
|
24
|
+
|
25
|
+
namespace :release do
|
26
|
+
desc "Publish RDoc to RubyForge."
|
27
|
+
task :docs => [:rdoc] do
|
28
|
+
config = YAML.load(
|
29
|
+
File.read(File.expand_path('~/.rubyforge/user-config.yml'))
|
30
|
+
)
|
31
|
+
|
32
|
+
host = "#{config['username']}@rubyforge.org"
|
33
|
+
remote_dir = "/var/www/gforge-projects/the-perfect-gem/"
|
34
|
+
local_dir = 'rdoc'
|
35
|
+
|
36
|
+
Rake::SshDirPublisher.new(host, remote_dir, local_dir).upload
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
rescue LoadError
|
41
|
+
puts "Rake SshDirPublisher is unavailable or your rubyforge environment is not configured."
|
42
|
+
end
|
43
|
+
|
44
|
+
require 'rake/testtask'
|
45
|
+
Rake::TestTask.new(:test) do |test|
|
46
|
+
test.libs << 'lib' << 'test'
|
47
|
+
test.pattern = 'test/**/*_test.rb'
|
48
|
+
test.verbose = true
|
49
|
+
end
|
50
|
+
|
51
|
+
begin
|
52
|
+
require 'rcov/rcovtask'
|
53
|
+
Rcov::RcovTask.new do |test|
|
54
|
+
test.libs << 'test'
|
55
|
+
test.pattern = 'test/**/*_test.rb'
|
56
|
+
test.verbose = true
|
57
|
+
end
|
58
|
+
rescue LoadError
|
59
|
+
task :rcov do
|
60
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
task :default => :test
|
66
|
+
|
67
|
+
require 'rake/rdoctask'
|
68
|
+
Rake::RDocTask.new do |rdoc|
|
69
|
+
if File.exist?('VERSION.yml')
|
70
|
+
config = YAML.load(File.read('VERSION.yml'))
|
71
|
+
version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
|
72
|
+
else
|
73
|
+
version = ""
|
74
|
+
end
|
75
|
+
|
76
|
+
rdoc.rdoc_dir = 'rdoc'
|
77
|
+
rdoc.title = "rcronwtf #{version}"
|
78
|
+
rdoc.rdoc_files.include('README*')
|
79
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
80
|
+
end
|
81
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0.0
|
@@ -0,0 +1,114 @@
|
|
1
|
+
class CronWTF::Entry
|
2
|
+
attr_reader :minutes, :hours, :days, :months, :week_days, :command, :is_comment
|
3
|
+
|
4
|
+
def initialize(entry)
|
5
|
+
@is_comment = (entry.nil? or entry.strip.empty? or entry.match /^#/) ? true : false
|
6
|
+
@entry = entry.strip.gsub(/\s+/, " ")
|
7
|
+
parse unless is_comment
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_s
|
11
|
+
return @entry if is_comment
|
12
|
+
|
13
|
+
msg = []
|
14
|
+
|
15
|
+
%w(minute hour day month week_day).each do |attribute|
|
16
|
+
key = (attribute + "s")
|
17
|
+
prev = msg[msg.length - 1]
|
18
|
+
values = self.send(key)
|
19
|
+
|
20
|
+
if(values == '*')
|
21
|
+
if(!prev || !prev.match(/^every/))
|
22
|
+
msg << "every #{attribute.gsub('_', ' ')}"
|
23
|
+
end
|
24
|
+
else
|
25
|
+
msg << send("#{key}_message", values)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
"Runs `#{@command}` #{msg.join(', ')}."
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
|
35
|
+
WEEK_DAYS = ['Sun', 'Mon', "Tue", 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
|
36
|
+
|
37
|
+
def parse
|
38
|
+
pieces = @entry.split(/\s+/)
|
39
|
+
@minutes = parse_attribute(pieces[0], 60)
|
40
|
+
@hours = parse_attribute(pieces[1], 24)
|
41
|
+
@days = parse_attribute(pieces[2], 31)
|
42
|
+
@months = parse_attribute(pieces[3], 12)
|
43
|
+
@week_days = parse_attribute(pieces[4], 8)
|
44
|
+
@command = pieces.slice(5, pieces.length).join(" ")
|
45
|
+
end
|
46
|
+
|
47
|
+
def parse_attribute(value, upper_bound)
|
48
|
+
return value if value.eql? '*'
|
49
|
+
|
50
|
+
if(value.match(/^\*\/\d+$/))
|
51
|
+
step = value.match(/^\*\/(\d+)$/)[1].to_i
|
52
|
+
range = []
|
53
|
+
|
54
|
+
for i in (0...upper_bound)
|
55
|
+
range << i if i % step == 0
|
56
|
+
end
|
57
|
+
|
58
|
+
return range
|
59
|
+
end
|
60
|
+
|
61
|
+
if(value.match(/^\d+\-\d+$/))
|
62
|
+
matches = value.match(/^(\d+)\-(\d+)$/)
|
63
|
+
lower = matches[1]
|
64
|
+
upper = matches[2]
|
65
|
+
range = []
|
66
|
+
|
67
|
+
for i in (lower..upper)
|
68
|
+
range << i.to_i
|
69
|
+
end
|
70
|
+
|
71
|
+
return range
|
72
|
+
end
|
73
|
+
|
74
|
+
return value.split(",").map{|v| v.to_i}
|
75
|
+
end
|
76
|
+
|
77
|
+
def minutes_message(values)
|
78
|
+
v = []
|
79
|
+
|
80
|
+
values.each do |value|
|
81
|
+
v << ":#{value.to_s.length == 1 ? '0' : ''}#{value}"
|
82
|
+
end
|
83
|
+
|
84
|
+
"at minute#{values.length > 1 ? 's' : ''} #{v.join(', ')}"
|
85
|
+
end
|
86
|
+
|
87
|
+
def hours_message(values)
|
88
|
+
"on hour#{values.length > 1 ? 's' : ''} #{values.join(', ')}"
|
89
|
+
end
|
90
|
+
|
91
|
+
def days_message(values)
|
92
|
+
"on day#{values.length > 1 ? 's' : ''} #{values.join(', ')}"
|
93
|
+
end
|
94
|
+
|
95
|
+
def months_message(values)
|
96
|
+
v = []
|
97
|
+
|
98
|
+
values.each do |value|
|
99
|
+
v << MONTHS[value]
|
100
|
+
end
|
101
|
+
|
102
|
+
"in #{v.join(', ')}"
|
103
|
+
end
|
104
|
+
|
105
|
+
def week_days_message(values)
|
106
|
+
v = []
|
107
|
+
|
108
|
+
values.each do |value|
|
109
|
+
v << WEEK_DAYS[value]
|
110
|
+
end
|
111
|
+
|
112
|
+
"on #{v.join(', ')}"
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class CronWTF::Table
|
2
|
+
attr_reader :entries
|
3
|
+
|
4
|
+
def initialize(table)
|
5
|
+
@entries = parse(table)
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_s
|
9
|
+
entries.map{|e| e.to_s}.join("\n")
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def parse(table)
|
15
|
+
lines = []
|
16
|
+
|
17
|
+
table.split("\n").each do |line|
|
18
|
+
entry = CronWTF::Entry.new(line)
|
19
|
+
lines << entry unless entry.is_comment
|
20
|
+
end
|
21
|
+
|
22
|
+
lines
|
23
|
+
end
|
24
|
+
end
|
data/lib/rcronwtf.rb
ADDED
data/rcronwtf.gemspec
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{rcronwtf}
|
5
|
+
s.version = "1.0.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Darrin Holst"]
|
9
|
+
s.date = %q{2009-05-15}
|
10
|
+
s.email = %q{darrinholst@gmail.com}
|
11
|
+
s.extra_rdoc_files = [
|
12
|
+
"LICENSE",
|
13
|
+
"README.rdoc"
|
14
|
+
]
|
15
|
+
s.files = [
|
16
|
+
".document",
|
17
|
+
".gitignore",
|
18
|
+
"LICENSE",
|
19
|
+
"README.rdoc",
|
20
|
+
"Rakefile",
|
21
|
+
"VERSION",
|
22
|
+
"lib/rcronwtf.rb",
|
23
|
+
"lib/rcronwtf/entry.rb",
|
24
|
+
"lib/rcronwtf/table.rb",
|
25
|
+
"rcronwtf.gemspec",
|
26
|
+
"test/entry_test.rb",
|
27
|
+
"test/table_test.rb",
|
28
|
+
"test/test_helper.rb"
|
29
|
+
]
|
30
|
+
s.homepage = %q{http://github.com/darrinholst/rcronwtf}
|
31
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
32
|
+
s.require_paths = ["lib"]
|
33
|
+
s.rubyforge_project = %q{rcronwtf}
|
34
|
+
s.rubygems_version = %q{1.3.3}
|
35
|
+
s.summary = %q{translate cron entries into human readable form}
|
36
|
+
s.test_files = [
|
37
|
+
"test/entry_test.rb",
|
38
|
+
"test/table_test.rb",
|
39
|
+
"test/test_helper.rb"
|
40
|
+
]
|
41
|
+
|
42
|
+
if s.respond_to? :specification_version then
|
43
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
44
|
+
s.specification_version = 3
|
45
|
+
|
46
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
47
|
+
else
|
48
|
+
end
|
49
|
+
else
|
50
|
+
end
|
51
|
+
end
|
data/test/entry_test.rb
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
|
3
|
+
class TestEntry < Test::Unit::TestCase
|
4
|
+
def test_that_it_does_not_parse_comments
|
5
|
+
assert_equal(true, CronWTF::Entry.new('# * * * * *').is_comment)
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_that_it_parses_command
|
9
|
+
assert_equal('foo bar baz > wat', CronWTF::Entry.new("1 1,2 3-4 */5 * foo bar baz > wat").command)
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_that_it_parses_infinite_minutes
|
13
|
+
assert_equal('*', CronWTF::Entry.new("* * * * * foo").minutes)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_that_it_parses_minute
|
17
|
+
assert_equal([1], CronWTF::Entry.new("1 * * * * bar").minutes)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_that_it_parses_minute_list
|
21
|
+
assert_equal([1,2], CronWTF::Entry.new("1,2 * * * * bar").minutes)
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_that_it_parses_minute_range
|
25
|
+
assert_equal([1,2,3,4,5], CronWTF::Entry.new("1-5 * * * * bar").minutes)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_that_it_parses_minute_step
|
29
|
+
assert_equal([0,10,20,30,40,50], CronWTF::Entry.new("*/10 * * * * bar").minutes)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_that_it_parses_infinite_hours
|
33
|
+
assert_equal('*', CronWTF::Entry.new("1 * * * * foo").hours)
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_that_it_parses_hour
|
37
|
+
assert_equal([1], CronWTF::Entry.new("2 1 * * * bar").hours)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_that_it_parses_hour_list
|
41
|
+
assert_equal([1,2], CronWTF::Entry.new("1 1,2 * * * bar").hours)
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_that_it_parses_hour_range
|
45
|
+
assert_equal([1,2,3,4,5], CronWTF::Entry.new("1 1-5 * * * bar").hours)
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_that_it_parses_hour_step
|
49
|
+
assert_equal([0,3,6,9,12,15,18,21], CronWTF::Entry.new("1 */3 * * bar").hours)
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_that_it_parses_infinite_days
|
53
|
+
assert_equal('*', CronWTF::Entry.new("1 2 * * * foo").days)
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_that_it_parses_day
|
57
|
+
assert_equal([1], CronWTF::Entry.new("2 2 1 * * bar").days)
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_that_it_parses_day_list
|
61
|
+
assert_equal([1,2], CronWTF::Entry.new("1 1 1,2 * * bar").days)
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_that_it_parses_day_range
|
65
|
+
assert_equal([1,2,3,4,5], CronWTF::Entry.new("1 1 1-5 * * bar").days)
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_that_it_parses_day_step
|
69
|
+
assert_equal([0,3,6,9,12,15,18,21,24,27,30], CronWTF::Entry.new("1 1 */3 * * bar").days)
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_that_it_parses_infinite_months
|
73
|
+
assert_equal('*', CronWTF::Entry.new("1 2 3 * * foo").months)
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_that_it_parses_month
|
77
|
+
assert_equal([1], CronWTF::Entry.new("2 2 2 1 * bar").months)
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_that_it_parses_month_list
|
81
|
+
assert_equal([1,2], CronWTF::Entry.new("1 1 1 1,2 * bar").months)
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_that_it_parses_month_range
|
85
|
+
assert_equal([1,2,3,4,5], CronWTF::Entry.new("1 1 1 1-5 * bar").months)
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_that_it_parses_month_step
|
89
|
+
assert_equal([0,3,6,9], CronWTF::Entry.new("1 1 1 */3 * bar").months)
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_that_it_parses_infinite_week_days
|
93
|
+
assert_equal('*', CronWTF::Entry.new("1 2 3 4 * foo").week_days)
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_that_it_parses_week_day
|
97
|
+
assert_equal([1], CronWTF::Entry.new("2 2 2 2 1 bar").week_days)
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_that_it_parses_week_day_list
|
101
|
+
assert_equal([1,2], CronWTF::Entry.new("1 1 1 1 1,2 bar").week_days)
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_that_it_parses_week_day_range
|
105
|
+
assert_equal([1,2,3,4,5], CronWTF::Entry.new("1 1 1 1 1-5 bar").week_days)
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_that_it_parses_week_day_step
|
109
|
+
assert_equal([0,3,6], CronWTF::Entry.new("1 1 1 1 */3 bar").week_days)
|
110
|
+
end
|
111
|
+
end
|
data/test/table_test.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
|
3
|
+
class TestTable < Test::Unit::TestCase
|
4
|
+
def test_that_it_parses_multiple_lines
|
5
|
+
assert_table(["Runs `foo` every minute.", "Runs `bar` every minute."], "* * * * * foo\n* * * * * bar")
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_that_it_parses_mixed_whitespace
|
9
|
+
assert_table(["Runs `foo` every minute."], "\n * * * * * foo \n\n")
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_that_it_ignores_comments
|
13
|
+
assert_table([], "# mm hh jj MMM JJJ\n \n")
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_that_it_parses_10_minute_cron
|
17
|
+
assert_table(["Runs `foo` at minutes :00, :10, :20, :30, :40, :50, every hour."], "*/10 * * * * foo")
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_that_it_parses_6_hour_cron
|
21
|
+
assert_table(["Runs `foo` at minute :00, on hours 0, 6, 12, 18, every day."], "0 */6 * * * foo")
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_that_it_parses_by_daily_cron
|
25
|
+
assert_table(["Runs `foo` at minute :00, on hour 0, on days 0, 10, 20, 30, every month."], "0 0 */10 * * foo")
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_that_it_parses_seasonal_cron
|
29
|
+
assert_table(["Runs `foo` at minute :00, on hour 0, every day, in Jan, Feb, Mar, Dec, every week day."], "0 0 * 0,1,2,11 * foo")
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_that_it_parses_seasonal_cron_on_certain_week_days
|
33
|
+
assert_table(["Runs `foo` at minute :00, on hour 0, every day, in Jan, Feb, Mar, Dec, on Mon, Wed, Fri."], "0 0 * 0,1,2,11 1,3,5 foo")
|
34
|
+
end
|
35
|
+
|
36
|
+
def assert_table(expected, input)
|
37
|
+
assert_equal(expected.join("\n"), CronWTF::Table.new(input).to_s)
|
38
|
+
end
|
39
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rcronwtf
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Darrin Holst
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-05-15 00:00:00 -05:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: darrinholst@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- LICENSE
|
24
|
+
- README.rdoc
|
25
|
+
files:
|
26
|
+
- .document
|
27
|
+
- .gitignore
|
28
|
+
- LICENSE
|
29
|
+
- README.rdoc
|
30
|
+
- Rakefile
|
31
|
+
- VERSION
|
32
|
+
- lib/rcronwtf.rb
|
33
|
+
- lib/rcronwtf/entry.rb
|
34
|
+
- lib/rcronwtf/table.rb
|
35
|
+
- rcronwtf.gemspec
|
36
|
+
- test/entry_test.rb
|
37
|
+
- test/table_test.rb
|
38
|
+
- test/test_helper.rb
|
39
|
+
has_rdoc: true
|
40
|
+
homepage: http://github.com/darrinholst/rcronwtf
|
41
|
+
licenses: []
|
42
|
+
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options:
|
45
|
+
- --charset=UTF-8
|
46
|
+
require_paths:
|
47
|
+
- lib
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: "0"
|
53
|
+
version:
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: "0"
|
59
|
+
version:
|
60
|
+
requirements: []
|
61
|
+
|
62
|
+
rubyforge_project: rcronwtf
|
63
|
+
rubygems_version: 1.3.3
|
64
|
+
signing_key:
|
65
|
+
specification_version: 3
|
66
|
+
summary: translate cron entries into human readable form
|
67
|
+
test_files:
|
68
|
+
- test/entry_test.rb
|
69
|
+
- test/table_test.rb
|
70
|
+
- test/test_helper.rb
|