khronotab 1.3.2 → 1.3.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.
data/README.rdoc CHANGED
@@ -4,10 +4,6 @@ KhronoTab is a pure ruby interface to the crontab. It uses a hash
4
4
  interface to allow accessing the data of an existing crontab or the
5
5
  creation of a new one far easier.
6
6
 
7
- == Synopsis
8
- This is a sample description of the application.
9
- Blah blah blah.
10
-
11
7
  == Installation
12
8
  gem install khronotab
13
9
 
@@ -21,9 +17,9 @@ creation of a new one far easier.
21
17
 
22
18
  == Copyright
23
19
  Copyright (c) 2010 Kristofer M White. Licensed under the BSD License:
20
+ See LICENSE for details.
24
21
  http://www.opensource.org/licenses/bsd-license.html
25
22
 
26
-
27
23
  == Note on Patches/Pull Requests
28
24
 
29
25
  * Fork the project.
@@ -31,6 +27,5 @@ creation of a new one far easier.
31
27
  * Add tests for it. This is important so I don't break it in a
32
28
  future version unintentionally.
33
29
  * Commit, do not mess with rakefile, version, or history.
34
- (if you want to have your own version, that is fine but
35
- bump version in a commit by itself I can ignore when I pull)
30
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
36
31
  * Send me a pull request. Bonus points for topic branches.
data/Rakefile CHANGED
@@ -5,22 +5,23 @@ begin
5
5
  require 'jeweler'
6
6
  Jeweler::Tasks.new do |gem|
7
7
  gem.name = "khronotab"
8
- gem.summary = %Q{A pure ruby cron parser}
9
- gem.description = %Q{A pure ruby cron parser with a hash-like interface}
8
+ gem.summary = %Q{A pure ruby crontab parser with a Hash-like interface}
9
+ gem.description = %Q{A pure ruby crontab parser with a Hash-like interface}
10
10
  gem.email = "me@kmwhite.net"
11
11
  gem.homepage = "http://github.com/kmwhite/khronotab"
12
12
  gem.authors = ["Kristofer M White"]
13
- gem.rubyforge_project = %q{khronotab}
13
+ gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
14
14
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
15
  end
16
+ Jeweler::GemcutterTasks.new
16
17
  rescue LoadError
17
- puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
18
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
18
19
  end
19
20
 
20
21
  require 'rake/testtask'
21
22
  Rake::TestTask.new(:test) do |test|
22
23
  test.libs << 'lib' << 'test'
23
- test.pattern = 'test/**/*_test.rb'
24
+ test.pattern = 'test/**/test_*.rb'
24
25
  test.verbose = true
25
26
  end
26
27
 
@@ -28,7 +29,7 @@ begin
28
29
  require 'rcov/rcovtask'
29
30
  Rcov::RcovTask.new do |test|
30
31
  test.libs << 'test'
31
- test.pattern = 'test/**/*_test.rb'
32
+ test.pattern = 'test/**/test_*.rb'
32
33
  test.verbose = true
33
34
  end
34
35
  rescue LoadError
@@ -39,15 +40,36 @@ end
39
40
 
40
41
  task :test => :check_dependencies
41
42
 
43
+ begin
44
+ require 'reek/adapters/rake_task'
45
+ Reek::RakeTask.new do |t|
46
+ t.fail_on_error = true
47
+ t.verbose = false
48
+ t.source_files = 'lib/**/*.rb'
49
+ end
50
+ rescue LoadError
51
+ task :reek do
52
+ abort "Reek is not available. In order to run reek, you must: sudo gem install reek"
53
+ end
54
+ end
55
+
56
+ begin
57
+ require 'roodi'
58
+ require 'roodi_task'
59
+ RoodiTask.new do |t|
60
+ t.verbose = false
61
+ end
62
+ rescue LoadError
63
+ task :roodi do
64
+ abort "Roodi is not available. In order to run roodi, you must: sudo gem install roodi"
65
+ end
66
+ end
67
+
42
68
  task :default => :test
43
69
 
44
70
  require 'rake/rdoctask'
45
71
  Rake::RDocTask.new do |rdoc|
46
- if File.exist?('VERSION')
47
- version = File.read('VERSION')
48
- else
49
- version = ""
50
- end
72
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
51
73
 
52
74
  rdoc.rdoc_dir = 'rdoc'
53
75
  rdoc.title = "khronotab #{version}"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.3.2
1
+ 1.3.3
data/khronotab.gemspec CHANGED
@@ -5,12 +5,12 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{khronotab}
8
- s.version = "1.3.2"
8
+ s.version = "1.3.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Kristofer M White"]
12
- s.date = %q{2010-07-26}
13
- s.description = %q{A pure ruby cron parser with a hash-like interface}
12
+ s.date = %q{2010-11-09}
13
+ s.description = %q{A pure ruby crontab parser with a Hash-like interface}
14
14
  s.email = %q{me@kmwhite.net}
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE",
@@ -27,25 +27,48 @@ Gem::Specification.new do |s|
27
27
  "demo/sample.rb",
28
28
  "khronotab.gemspec",
29
29
  "lib/khronotab.rb",
30
+ "lib/khronotab/cron_comment.rb",
30
31
  "lib/khronotab/cron_job.rb",
31
32
  "lib/khronotab/cron_unit.rb",
32
- "lib/khronotab/cron_variable.rb"
33
+ "lib/khronotab/cron_variable.rb",
34
+ "test/helper.rb",
35
+ "test/tc_cron_job_command-length.rb",
36
+ "test/tc_cron_job_different-time-arguments.rb",
37
+ "test/tc_cron_job_nil-checks.rb",
38
+ "test/test_khronotab.rb",
39
+ "test/ts_cron_job.rb",
40
+ "test/ts_cron_tab.rb",
41
+ "test/ts_cron_unit.rb",
42
+ "test/ts_cron_variable.rb"
33
43
  ]
34
44
  s.homepage = %q{http://github.com/kmwhite/khronotab}
35
45
  s.rdoc_options = ["--charset=UTF-8"]
36
46
  s.require_paths = ["lib"]
37
- s.rubyforge_project = %q{khronotab}
38
- s.rubygems_version = %q{1.3.5}
39
- s.summary = %q{A pure ruby cron parser}
47
+ s.rubygems_version = %q{1.3.7}
48
+ s.summary = %q{A pure ruby crontab parser with a Hash-like interface}
49
+ s.test_files = [
50
+ "test/tc_cron_job_nil-checks.rb",
51
+ "test/ts_cron_variable.rb",
52
+ "test/ts_cron_job.rb",
53
+ "test/test_khronotab.rb",
54
+ "test/tc_cron_job_different-time-arguments.rb",
55
+ "test/tc_cron_job_command-length.rb",
56
+ "test/ts_cron_unit.rb",
57
+ "test/ts_cron_tab.rb",
58
+ "test/helper.rb"
59
+ ]
40
60
 
41
61
  if s.respond_to? :specification_version then
42
62
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
43
63
  s.specification_version = 3
44
64
 
45
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
65
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
66
+ s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
46
67
  else
68
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
47
69
  end
48
70
  else
71
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
49
72
  end
50
73
  end
51
74
 
@@ -0,0 +1,17 @@
1
+ class CronComment < String
2
+
3
+ COMMENT_REGEX=%r{\s*#.*}i
4
+
5
+ def self.matches?(cron_entry)
6
+ !!COMMENT_REGEX.match(cron_entry)
7
+ end
8
+
9
+ def to_s
10
+ puts self
11
+ end
12
+
13
+ def to_line
14
+ puts self
15
+ end
16
+
17
+ end
@@ -9,9 +9,8 @@ class CronJob
9
9
 
10
10
  JOB_REGEX=/([0-9\*\/\-,]+)\s+([0-9\*\/\-,]+)\s+([0-9\*\/\-,]+)\s+([0-9\*\/\-,]+)\s+([0-9\*\/\-,]+)\s+(\S+)\s+(.+)/
11
11
 
12
- def self.matches?(ce)
13
- return false if ce=~/^[\s]*$/ or ce=~/^\s*#/
14
- !!JOB_REGEX.match(ce)
12
+ def self.matches?(cron_entry)
13
+ !!JOB_REGEX.match(cron_entry)
15
14
  end
16
15
 
17
16
  def self.add_new(cron_entry)
@@ -29,31 +28,28 @@ class CronJob
29
28
  )
30
29
  end
31
30
 
32
- def [] ac
31
+ def [](ac)
33
32
  return self.send(ac) if self.respond_to?(ac)
34
33
  raise 'Unknown key!'
35
34
  end
36
35
 
37
- def []= k,v
38
- return self.send("#{k}=",v) if self.respond_to?(k)
36
+ def []=(key,value)
37
+ return self.send("#{key}=", value) if self.respond_to?(key)
39
38
  raise 'Unknown key!'
40
39
  end
41
40
 
42
- def expand_times(date = Date.today, type = :day)
43
- case type
44
- when :day
45
- return [] unless runs_on?(date)
46
- time_list = []
47
- hours.expanded_form.map do |hour|
48
- minutes.expanded_form.map do |minute|
49
- time_list << "%02i-%02i-%02i %02i:%02i:%02i" % [date.year, date.month, date.day, hour, minute, 0]
50
- end
41
+ def expand_times(date = Date.today)
42
+ return [] unless runs_on?(date)
43
+ time_list = []
44
+ hours.expanded_form.map do |hour|
45
+ minutes.expanded_form.map do |minute|
46
+ time_list << "%02i-%02i-%02i %02i:%02i:%02i" % [date.year, date.month, date.day, hour, minute, 0]
51
47
  end
52
- return time_list
53
- end
48
+ end
49
+ return time_list
54
50
  end
55
51
 
56
- def initialize(data)
52
+ def initialize(data = {})
57
53
  @minutes = CronUnit.new(data[:minutes], 0, 59)
58
54
  @hours = CronUnit.new(data[:hours], 0, 23)
59
55
  @days_of_month = CronUnit.new(data[:days_of_month], 1, 31)
@@ -11,33 +11,43 @@ class CronUnit
11
11
  expanded_form.include?(value)
12
12
  end
13
13
 
14
+ def expand_range(segment)
15
+ range = segment.split('-').map! { |x| x.to_i }
16
+ (range[0] .. range[1]).to_a
17
+ end
18
+
19
+ def expand_interval(segment)
20
+ counter = 0
21
+ times = []
22
+ interval = segment.split('/').map! { |x|
23
+ if x == '*'
24
+ x = @maximum
25
+ else
26
+ x.to_i
27
+ end
28
+ }
29
+ while counter < interval[0]
30
+ times.push(counter)
31
+ counter += interval[1]
32
+ end
33
+ times
34
+ end
35
+
14
36
  def expanded_form
15
- values = Array.new
37
+ values = []
16
38
  @cron_form.split(',').each do |segment|
17
39
  case segment
18
40
  when /-/ #range
19
- range = segment.split('-').map! { |x| x.to_i }
20
- values.concat((range[0] .. range[1]).to_a)
41
+ values.concat(expand_range(segment))
21
42
  when /\// #interval
22
- counter = 0
23
- interval = segment.split('/').map! { |x|
24
- if x == '*'
25
- x = @maximum
26
- else
27
- x.to_i
28
- end
29
- }
30
- while counter < interval[0]
31
- values.push(counter)
32
- counter += interval[1]
33
- end
43
+ values.concat(expand_interval(segment))
34
44
  when /[*]/
35
45
  values.concat((@minimum .. @maximum).to_a)
36
46
  else
37
47
  values << segment.to_i
38
48
  end
39
49
  end
40
- return values.sort.uniq
50
+ values.sort.uniq
41
51
  end
42
52
 
43
53
  def to_s
@@ -4,19 +4,18 @@ class CronVariable < Hash
4
4
 
5
5
  VAR_REGEX=%r{(^\s*[^#]\w+)=(.+)}i
6
6
 
7
- def [] ac
7
+ def [](ac)
8
8
  return self.send(ac) if self.respond_to?(ac)
9
9
  raise 'Unknown key!'
10
10
  end
11
11
 
12
- def []= k,v
13
- return self.send("#{k}=",v) if self.respond_to?(k)
12
+ def []=(key,value)
13
+ return self.send("#{key}=", value) if self.respond_to?(key)
14
14
  raise 'Unknown key!'
15
15
  end
16
16
 
17
- def self.matches?(ce)
18
- return false if ce=~/^[\s]*$/ or ce=~/^\s*#/
19
- !!VAR_REGEX.match(ce)
17
+ def self.matches?(cron_entry)
18
+ !!VAR_REGEX.match(cron_entry)
20
19
  end
21
20
 
22
21
  def self.add_new(cron_entry)
data/lib/khronotab.rb CHANGED
@@ -4,13 +4,17 @@ module Khronotab
4
4
  class CronTab
5
5
 
6
6
  require 'khronotab/cron_variable'
7
+ require 'khronotab/cron_comment'
7
8
  require 'khronotab/cron_job'
8
9
 
9
10
  VERSION = '1.3.2'
10
11
 
11
- attr_accessor :jobs, :variables
12
+ attr_accessor :jobs, :variables, :comments
12
13
 
13
- def initialize opt={}
14
+ def initialize(opt={})
15
+ @variables ||= []
16
+ @jobs ||= []
17
+ @comments ||= []
14
18
  self.read_from_file(opt[:file]) if opt[:file]
15
19
  end
16
20
 
@@ -19,19 +23,19 @@ module Khronotab
19
23
  end
20
24
 
21
25
  def read_from_file(filename)
22
- @variables ||= []
23
- @jobs ||= []
24
- File.open(filename, 'r').readlines.each do |line|
25
- if CronVariable.matches?(line)
26
- @variables << CronVariable.add_new(line)
27
- elsif CronJob.matches?(line)
28
- @jobs << CronJob.add_new(line)
29
- else
30
- STDERR.puts("Warning: Line is not a valid variable or job!")
31
- end
26
+ File.open(filename, 'r').readlines.each do |line|
27
+ if CronVariable.matches?(line)
28
+ @variables << CronVariable.add_new(line)
29
+ elsif CronJob.matches?(line)
30
+ @jobs << CronJob.add_new(line)
31
+ elsif CronComment.matches?(line)
32
+ @comments << line
33
+ else
34
+ STDERR.puts("Warning: Line is not valid!(#{line.chomp})")
32
35
  end
33
- self
34
- end
36
+ end
37
+ self
38
+ end
35
39
 
36
40
  def write_to_file(filename)
37
41
  #TODO: Have this validate a file or append to the file if there
data/test/helper.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'khronotab'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -0,0 +1,29 @@
1
+ class CronJobTest < Test::Unit::TestCase
2
+
3
+ context "a CronJob with a single-arg cmd" do
4
+ setup do
5
+ @cronjob = CronJob.add_new('0 0 0 0 0 root ls')
6
+ end
7
+
8
+ should "parse user and cmd correctly" do
9
+ assert_equal('root', @cronjob.user,
10
+ 'User parsed incorrectly') &&
11
+ assert_equal('ls', @cronjob.command,
12
+ 'Command parsed incorrectly')
13
+ end
14
+ end
15
+
16
+ context "a CronJob with a multi-arg cmd" do
17
+ setup do
18
+ @cronjob = CronJob.add_new('0 0 0 0 0 root grep foo /var/log/bar | cut -d\':\' -f 3 | sort | uniq')
19
+ end
20
+
21
+ should "handle complex, multi command lines" do
22
+ assert_equal('root', @cronjob.user,
23
+ 'User parsed incorrectly') &&
24
+ assert_equal('grep foo /var/log/bar | cut -d\':\' -f 3 | sort | uniq', @cronjob.command,
25
+ 'Command parsed incorrectly')
26
+ end
27
+ end
28
+ end
29
+
@@ -0,0 +1,56 @@
1
+ class CronJobTest < Test::Unit::TestCase
2
+
3
+ context "a CronJob with range time args" do
4
+ setup do
5
+ @cronjob = CronJob.add_new('0-9 0-9 0-9 0-9 0-4 root ls')
6
+ end
7
+
8
+ should "should have correct user and command" do
9
+ assert_equal('root', @cronjob.user,
10
+ 'User parsed incorrectly') &&
11
+ assert_equal('ls', @cronjob.command,
12
+ 'Command parsed incorrectly')
13
+ end
14
+ end
15
+
16
+ context "a CronJob with interval time args" do
17
+ setup do
18
+ @cronjob = CronJob.add_new('6/2 6/2 6/2 6/2 6/2 root ls')
19
+ end
20
+
21
+ should "should have correct user and command" do
22
+ assert_equal('root', @cronjob.user,
23
+ 'User parsed incorrectly') &&
24
+ assert_equal('ls', @cronjob.command,
25
+ 'Command parsed incorrectly')
26
+ end
27
+ end
28
+
29
+ context "a CronJob with asterisk time args" do
30
+ setup do
31
+ @cronjob = CronJob.add_new('* * * * * root ls')
32
+ end
33
+
34
+ should "should have correct user and command" do
35
+ assert_equal('root', @cronjob.user,
36
+ 'User parsed incorrectly') &&
37
+ assert_equal('ls', @cronjob.command,
38
+ 'Command parsed incorrectly')
39
+ end
40
+ end
41
+
42
+ context "a CronJob with mixed time args" do
43
+ setup do
44
+ @cronjob = CronJob.add_new('* 6/2 0-9 0 0 root ls')
45
+ end
46
+
47
+ should "should have correct user and command" do
48
+ assert_equal('root', @cronjob.user,
49
+ 'User parsed incorrectly') &&
50
+ assert_equal('ls', @cronjob.command,
51
+ 'Command parsed incorrectly')
52
+ end
53
+ end
54
+
55
+ end
56
+
@@ -0,0 +1,38 @@
1
+ class CronJobTest < Test::Unit::TestCase
2
+
3
+ context "a CronJob" do
4
+ setup do
5
+ @cronjob = CronJob.new
6
+ end
7
+
8
+ should "have a nil minutes" do
9
+ assert_nil @cronjob.minutes.cron_form
10
+ end
11
+
12
+ should "have a nil hours" do
13
+ assert_nil @cronjob.hours.cron_form
14
+ end
15
+
16
+ should "have a nil days_of_month" do
17
+ assert_nil @cronjob.days_of_month.cron_form
18
+ end
19
+
20
+ should "have a nil month" do
21
+ assert_nil @cronjob.month.cron_form
22
+ end
23
+
24
+ should "have a nil days_of_week" do
25
+ assert_nil @cronjob.days_of_week.cron_form
26
+ end
27
+
28
+ should "have a nil user" do
29
+ assert_nil @cronjob.user
30
+ end
31
+
32
+ should "have a nil command" do
33
+ assert_nil @cronjob.command
34
+ end
35
+
36
+ end
37
+ end
38
+
@@ -0,0 +1,12 @@
1
+ require 'helper'
2
+
3
+ require 'ts_cron_tab'
4
+ require 'ts_cron_job'
5
+ require 'ts_cron_unit'
6
+ require 'ts_cron_variable'
7
+
8
+ class TestKhronotab < Test::Unit::TestCase
9
+ should "probably rename this file and start testing for real" do
10
+ # flunk "hey buddy, you should probably rename this file and start testing for real"
11
+ end
12
+ end
@@ -0,0 +1,4 @@
1
+ require 'test/unit'
2
+ require 'tc_cron_job_nil-checks'
3
+ require 'tc_cron_job_different-time-arguments'
4
+ require 'tc_cron_job_command-length'
@@ -0,0 +1 @@
1
+ require 'test/unit'
@@ -0,0 +1 @@
1
+ require 'test/unit'
@@ -0,0 +1 @@
1
+ require 'test/unit'
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: khronotab
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.2
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 3
9
+ - 3
10
+ version: 1.3.3
5
11
  platform: ruby
6
12
  authors:
7
13
  - Kristofer M White
@@ -9,11 +15,24 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2010-07-26 00:00:00 -05:00
18
+ date: 2010-11-09 00:00:00 -06:00
13
19
  default_executable:
14
- dependencies: []
15
-
16
- description: A pure ruby cron parser with a hash-like interface
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: thoughtbot-shoulda
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :development
34
+ version_requirements: *id001
35
+ description: A pure ruby crontab parser with a Hash-like interface
17
36
  email: me@kmwhite.net
18
37
  executables: []
19
38
 
@@ -33,9 +52,19 @@ files:
33
52
  - demo/sample.rb
34
53
  - khronotab.gemspec
35
54
  - lib/khronotab.rb
55
+ - lib/khronotab/cron_comment.rb
36
56
  - lib/khronotab/cron_job.rb
37
57
  - lib/khronotab/cron_unit.rb
38
58
  - lib/khronotab/cron_variable.rb
59
+ - test/helper.rb
60
+ - test/tc_cron_job_command-length.rb
61
+ - test/tc_cron_job_different-time-arguments.rb
62
+ - test/tc_cron_job_nil-checks.rb
63
+ - test/test_khronotab.rb
64
+ - test/ts_cron_job.rb
65
+ - test/ts_cron_tab.rb
66
+ - test/ts_cron_unit.rb
67
+ - test/ts_cron_variable.rb
39
68
  has_rdoc: true
40
69
  homepage: http://github.com/kmwhite/khronotab
41
70
  licenses: []
@@ -46,23 +75,37 @@ rdoc_options:
46
75
  require_paths:
47
76
  - lib
48
77
  required_ruby_version: !ruby/object:Gem::Requirement
78
+ none: false
49
79
  requirements:
50
80
  - - ">="
51
81
  - !ruby/object:Gem::Version
82
+ hash: 3
83
+ segments:
84
+ - 0
52
85
  version: "0"
53
- version:
54
86
  required_rubygems_version: !ruby/object:Gem::Requirement
87
+ none: false
55
88
  requirements:
56
89
  - - ">="
57
90
  - !ruby/object:Gem::Version
91
+ hash: 3
92
+ segments:
93
+ - 0
58
94
  version: "0"
59
- version:
60
95
  requirements: []
61
96
 
62
- rubyforge_project: khronotab
63
- rubygems_version: 1.3.5
97
+ rubyforge_project:
98
+ rubygems_version: 1.3.7
64
99
  signing_key:
65
100
  specification_version: 3
66
- summary: A pure ruby cron parser
67
- test_files: []
68
-
101
+ summary: A pure ruby crontab parser with a Hash-like interface
102
+ test_files:
103
+ - test/tc_cron_job_nil-checks.rb
104
+ - test/ts_cron_variable.rb
105
+ - test/ts_cron_job.rb
106
+ - test/test_khronotab.rb
107
+ - test/tc_cron_job_different-time-arguments.rb
108
+ - test/tc_cron_job_command-length.rb
109
+ - test/ts_cron_unit.rb
110
+ - test/ts_cron_tab.rb
111
+ - test/helper.rb