winever 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +6 -5
- data/Rakefile +10 -0
- data/lib/winever.rb +9 -2
- data/lib/winever/cron_entry.rb +8 -32
- data/lib/winever/cron_time.rb +44 -0
- data/lib/winever/task_manager.rb +3 -1
- data/lib/winever/version.rb +1 -1
- data/lib/winever/whenever_interface.rb +23 -0
- data/test/test_helper.rb +3 -0
- data/test/unit/cron_time_test.rb +41 -0
- data/winever.gemspec +3 -2
- metadata +29 -8
data/README.md
CHANGED
@@ -51,16 +51,17 @@ end
|
|
51
51
|
```
|
52
52
|
|
53
53
|
The pipes (|) are important, so make sure not to remove any.
|
54
|
-
If your
|
54
|
+
If your job_type doesn't need to be run in the folder of your application (like the existing job_type "command" of Whenever),
|
55
55
|
then remove the :path (leaving the pipes around it intact).
|
56
56
|
|
57
57
|
As of right now the only type of schedule that is supported are the daily ones (run once per day, at a specific time, every day).
|
58
|
-
Pull requests welcomed to add more,
|
58
|
+
Pull requests welcomed to add more, cron_time.rb and test_cron_time.rb should be the only files needing edit for that.
|
59
59
|
|
60
60
|
## Contributing
|
61
61
|
|
62
62
|
1. Fork it
|
63
63
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
64
|
-
3.
|
65
|
-
4.
|
66
|
-
5.
|
64
|
+
3. Run test (`bundle install` followed by `rake`).
|
65
|
+
4. Commit your changes (`git commit -am 'Add some feature'`)
|
66
|
+
5. Push to the branch (`git push origin my-new-feature`)
|
67
|
+
6. Create new Pull Request
|
data/Rakefile
CHANGED
data/lib/winever.rb
CHANGED
@@ -1,13 +1,19 @@
|
|
1
1
|
require 'winever/version'
|
2
2
|
require 'whenever'
|
3
3
|
|
4
|
-
# A very tiny monkey patch of
|
4
|
+
# A very tiny monkey patch of Whenever, adding some helper functions in the schedule.
|
5
5
|
module Whenever
|
6
6
|
class JobList
|
7
|
-
# We are running from winever
|
7
|
+
# We are running from winever? If you need tasks only on your Windows or your Linux servers, you can use #winever?
|
8
8
|
def winever?
|
9
9
|
Winever::WheneverInterface.run_from_winever?
|
10
10
|
end
|
11
|
+
|
12
|
+
# If transitionning to Winever and you already have scheduled tasks that you also want removed when installing
|
13
|
+
# your Winever schedule, you can give their paths to this functions and Winever will take care of it!
|
14
|
+
def remove_existing_tasks *names
|
15
|
+
Winever::WheneverInterface.remove_existing_tasks *names
|
16
|
+
end
|
11
17
|
end
|
12
18
|
end
|
13
19
|
|
@@ -15,6 +21,7 @@ end
|
|
15
21
|
module Winever
|
16
22
|
autoload :CommandLine, 'winever/command_line'
|
17
23
|
autoload :CronEntry, 'winever/cron_entry'
|
24
|
+
autoload :CronTime, 'winever/cron_time'
|
18
25
|
autoload :TaskManager, 'winever/task_manager'
|
19
26
|
autoload :WheneverInterface, 'winever/whenever_interface'
|
20
27
|
end
|
data/lib/winever/cron_entry.rb
CHANGED
@@ -8,51 +8,27 @@ module Winever
|
|
8
8
|
entries
|
9
9
|
end
|
10
10
|
|
11
|
-
def triggers
|
12
|
-
# For now, we don't support anything other than specific time.
|
13
|
-
# But it is possible to handle almost all cron schedule options in the task scheduler of Windows.
|
14
|
-
# It doesn't help that win32-taskscheduler also seems to only support one trigger per task.
|
15
|
-
return [] unless valid_triggers?
|
16
|
-
|
17
|
-
cron_minute, cron_hour, cron_day, cron_month, cron_dow = @cron_time_parts
|
18
|
-
trigger = {
|
19
|
-
:start_year => Date.today.year,
|
20
|
-
:start_month => Date.today.month,
|
21
|
-
:start_day => Date.today.day,
|
22
|
-
:start_hour => cron_hour.to_i,
|
23
|
-
:start_minute => cron_minute.to_i,
|
24
|
-
:trigger_type => Win32::TaskScheduler::TASK_TIME_TRIGGER_DAILY
|
25
|
-
}
|
26
|
-
|
27
|
-
[trigger]
|
28
|
-
end
|
29
|
-
|
30
11
|
def initialize(cron_line)
|
31
12
|
@cron_line = cron_line
|
32
13
|
@cron_parts = cron_line.split("|", 5)
|
33
|
-
|
34
|
-
@
|
14
|
+
cron_time_string, @task_folder, @task_name, @working_directory, @parameters = @cron_parts
|
15
|
+
@cron_time = Winever::CronTime.new(cron_time_string)
|
35
16
|
end
|
36
17
|
|
37
|
-
def
|
38
|
-
|
18
|
+
def triggers
|
19
|
+
@cron_time.triggers
|
39
20
|
end
|
40
21
|
|
41
|
-
def
|
42
|
-
|
43
|
-
cron_minute, cron_hour, cron_day, cron_month, cron_dow = @cron_time_parts
|
44
|
-
|
45
|
-
return false if [cron_day, cron_month, cron_dow].detect{|v| v != '*'}
|
46
|
-
return false if [cron_minute, cron_hour].detect{|v| (v =~ /^\d+$/).nil? }
|
47
|
-
|
48
|
-
true
|
22
|
+
def valid?
|
23
|
+
invalid_reason.nil?
|
49
24
|
end
|
50
25
|
|
51
26
|
def invalid_reason
|
52
27
|
return "Doesn't match the Winever format" unless @cron_parts.length == 5
|
53
28
|
return "Doesn't have a task_name specified" unless @task_name.present?
|
54
|
-
return "
|
29
|
+
return "Problem with schedule: #{@cron_time.unsupported_reason}" unless @cron_time.supported?
|
55
30
|
nil
|
56
31
|
end
|
32
|
+
|
57
33
|
end
|
58
34
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Winever
|
2
|
+
class CronTime
|
3
|
+
attr_accessor :string, :parts, :minute, :hour, :day, :month, :dow
|
4
|
+
|
5
|
+
def initialize cron_time_string
|
6
|
+
@string = cron_time_string
|
7
|
+
|
8
|
+
@parts = Array.new(5, '')
|
9
|
+
string_parts = cron_time_string.split(/ +/)
|
10
|
+
@parts[0...string_parts.size] = string_parts
|
11
|
+
|
12
|
+
@minute, @hour, @day, @month, @dow = @parts
|
13
|
+
end
|
14
|
+
|
15
|
+
def triggers
|
16
|
+
# For now, we don't support anything other than specific time.
|
17
|
+
# But it is possible to handle almost all cron schedule options in the task scheduler of Windows.
|
18
|
+
# It doesn't help that win32-taskscheduler also seems to only support one trigger per task.
|
19
|
+
|
20
|
+
return [] unless supported?
|
21
|
+
trigger = {
|
22
|
+
:start_year => Date.today.year,
|
23
|
+
:start_month => Date.today.month,
|
24
|
+
:start_day => Date.today.day,
|
25
|
+
:start_hour => hour.to_i,
|
26
|
+
:start_minute => minute.to_i,
|
27
|
+
:trigger_type => Win32::TaskScheduler::TASK_TIME_TRIGGER_DAILY
|
28
|
+
}
|
29
|
+
|
30
|
+
[trigger]
|
31
|
+
end
|
32
|
+
|
33
|
+
def supported?
|
34
|
+
unsupported_reason.nil?
|
35
|
+
end
|
36
|
+
|
37
|
+
def unsupported_reason
|
38
|
+
return "Need 5 parts delimited by spaces" if parts.select(&:present?).length != 5
|
39
|
+
return "Only '*' is supported for day, month and day or week parts" if [day, month, dow].detect{|v| v != '*'}
|
40
|
+
return "Only single number is supported for minute and hour parts" if [minute, hour].detect{|v| (v =~ /^\d+$/).nil? }
|
41
|
+
nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/winever/task_manager.rb
CHANGED
@@ -79,9 +79,11 @@ module Winever
|
|
79
79
|
def clear_tasks_except keep_tasks=[]
|
80
80
|
ts = Win32::TaskScheduler.new
|
81
81
|
task_names = ts.tasks.select{|tn| tn.end_with?('.' + identifier)}
|
82
|
+
task_names.concat(Winever::WheneverInterface::existing_tasks_to_remove)
|
83
|
+
|
82
84
|
task_names = task_names.reject{|tn| keep_tasks.include?(tn)}
|
83
85
|
|
84
|
-
task_names.each{|tn| ts.delete(tn)}
|
86
|
+
task_names.each{|tn| ts.delete(tn) if ts.exists?(tn)}
|
85
87
|
end
|
86
88
|
|
87
89
|
def create_task cron_entry
|
data/lib/winever/version.rb
CHANGED
@@ -4,6 +4,15 @@ module Winever
|
|
4
4
|
@run_from_winever || false
|
5
5
|
end
|
6
6
|
|
7
|
+
def self.remove_existing_tasks *names
|
8
|
+
@existing_tasks_to_remove ||= []
|
9
|
+
@existing_tasks_to_remove.concat(names.flatten)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.existing_tasks_to_remove
|
13
|
+
@existing_tasks_to_remove ||= []
|
14
|
+
end
|
15
|
+
|
7
16
|
def self.raw_cron options={}
|
8
17
|
# The output of whenever with the custom job_types and job_template.
|
9
18
|
options[:file] ||= 'config/schedule.rb'
|
@@ -36,6 +45,7 @@ module Winever
|
|
36
45
|
end
|
37
46
|
|
38
47
|
def self.cron options={}
|
48
|
+
# Content of a printable cron in internal Winever format. Also displays entry that are not handled and why.
|
39
49
|
entries = all_cron_entries(options)
|
40
50
|
valid_entries = entries.select(&:valid?)
|
41
51
|
invalid_entries = entries.reject(&:valid?)
|
@@ -56,6 +66,19 @@ module Winever
|
|
56
66
|
output << "#{invalid_entry.cron_line}\n\n"
|
57
67
|
end
|
58
68
|
end
|
69
|
+
|
70
|
+
if existing_tasks_to_remove.present?
|
71
|
+
if existing_tasks_to_remove.size <= 15
|
72
|
+
output << "\n# Additionnal task names that will be removed if they exist:\n"
|
73
|
+
existing_tasks_to_remove.each do |path|
|
74
|
+
output << "# - #{path}\n"
|
75
|
+
end
|
76
|
+
else
|
77
|
+
output << "\n# Additionnal task names that will be removed if they exist:\n"
|
78
|
+
output << "# (More than #{15} task names, not displaying.)\n"
|
79
|
+
end
|
80
|
+
output << "\n"
|
81
|
+
end
|
59
82
|
output
|
60
83
|
end
|
61
84
|
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Winever::CronTime do
|
4
|
+
|
5
|
+
it "must support daily jobs with single specific time" do
|
6
|
+
Winever::CronTime.new('12 10 * * *').supported?.must_equal true
|
7
|
+
end
|
8
|
+
|
9
|
+
it "must only support 5 time parts" do
|
10
|
+
Winever::CronTime.new('12 10 * *').supported?.must_equal false
|
11
|
+
Winever::CronTime.new('12 10 * * * *').supported?.must_equal false
|
12
|
+
end
|
13
|
+
|
14
|
+
it "must return a trigger" do
|
15
|
+
skip unless windows?
|
16
|
+
Winever::CronTime.new('12 10 * * *').triggers.size.must_equal 1
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "current limitations" do
|
20
|
+
it "doesn't currently support daily jobs without single specific time" do
|
21
|
+
Winever::CronTime.new('12 10,20 * * *').supported?.must_equal false
|
22
|
+
Winever::CronTime.new('*/2 10 * * *').supported?.must_equal false
|
23
|
+
end
|
24
|
+
|
25
|
+
it "doesn't support jobs that are not daily" do
|
26
|
+
Winever::CronTime.new('12 10 1 * *').supported?.must_equal false
|
27
|
+
Winever::CronTime.new('12 10 */2 * *').supported?.must_equal false
|
28
|
+
Winever::CronTime.new('12 10 3,4,5 * *').supported?.must_equal false
|
29
|
+
|
30
|
+
Winever::CronTime.new('12 10 * 1 *').supported?.must_equal false
|
31
|
+
Winever::CronTime.new('12 10 * */2 *').supported?.must_equal false
|
32
|
+
Winever::CronTime.new('12 10 * 3,4,5 *').supported?.must_equal false
|
33
|
+
|
34
|
+
Winever::CronTime.new('12 10 * * 1').supported?.must_equal false
|
35
|
+
Winever::CronTime.new('12 10 * * */2').supported?.must_equal false
|
36
|
+
Winever::CronTime.new('12 10 * * 3,4,5').supported?.must_equal false
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
end
|
data/winever.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = Winever::VERSION
|
9
9
|
spec.authors = ["Maxime Handfield Lapointe"]
|
10
10
|
spec.email = ["hunter_spawn@hotmail.com"]
|
11
|
-
spec.description = %q{
|
12
|
-
spec.summary = %q{
|
11
|
+
spec.description = %q{Clean ruby syntax for writing and deploying tasks in Windows' task scheduler. Extension of gem whenever.}
|
12
|
+
spec.summary = %q{Add tasks in Windows' task scheduler from a ruby configuration file.}
|
13
13
|
spec.homepage = ""
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
@@ -23,4 +23,5 @@ Gem::Specification.new do |spec|
|
|
23
23
|
|
24
24
|
spec.add_development_dependency "bundler", "~> 1.3"
|
25
25
|
spec.add_development_dependency "rake"
|
26
|
+
spec.add_development_dependency "minitest"
|
26
27
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: winever
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-07-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: whenever
|
@@ -75,8 +75,24 @@ dependencies:
|
|
75
75
|
- - ! '>='
|
76
76
|
- !ruby/object:Gem::Version
|
77
77
|
version: '0'
|
78
|
-
|
79
|
-
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: minitest
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
description: Clean ruby syntax for writing and deploying tasks in Windows' task scheduler.
|
95
|
+
Extension of gem whenever.
|
80
96
|
email:
|
81
97
|
- hunter_spawn@hotmail.com
|
82
98
|
executables:
|
@@ -93,10 +109,13 @@ files:
|
|
93
109
|
- lib/winever.rb
|
94
110
|
- lib/winever/command_line.rb
|
95
111
|
- lib/winever/cron_entry.rb
|
112
|
+
- lib/winever/cron_time.rb
|
96
113
|
- lib/winever/setup_schedule.rb
|
97
114
|
- lib/winever/task_manager.rb
|
98
115
|
- lib/winever/version.rb
|
99
116
|
- lib/winever/whenever_interface.rb
|
117
|
+
- test/test_helper.rb
|
118
|
+
- test/unit/cron_time_test.rb
|
100
119
|
- winever.gemspec
|
101
120
|
homepage: ''
|
102
121
|
licenses:
|
@@ -113,7 +132,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
113
132
|
version: '0'
|
114
133
|
segments:
|
115
134
|
- 0
|
116
|
-
hash: -
|
135
|
+
hash: -1691464168230782844
|
117
136
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
137
|
none: false
|
119
138
|
requirements:
|
@@ -122,11 +141,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
122
141
|
version: '0'
|
123
142
|
segments:
|
124
143
|
- 0
|
125
|
-
hash: -
|
144
|
+
hash: -1691464168230782844
|
126
145
|
requirements: []
|
127
146
|
rubyforge_project:
|
128
147
|
rubygems_version: 1.8.25
|
129
148
|
signing_key:
|
130
149
|
specification_version: 3
|
131
|
-
summary:
|
132
|
-
test_files:
|
150
|
+
summary: Add tasks in Windows' task scheduler from a ruby configuration file.
|
151
|
+
test_files:
|
152
|
+
- test/test_helper.rb
|
153
|
+
- test/unit/cron_time_test.rb
|