rcronwtf 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
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
@@ -0,0 +1,8 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ module CronWTF
5
+ end
6
+
7
+ require 'rcronwtf/table'
8
+ require 'rcronwtf/entry'
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
@@ -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
@@ -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
@@ -0,0 +1,3 @@
1
+ require 'stringio'
2
+ require 'test/unit'
3
+ require File.dirname(__FILE__) + '/../lib/rcronwtf'
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