taskloop 0.1.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.
- checksums.yaml +7 -0
- data/.idea/.gitignore +8 -0
- data/.idea/misc.xml +4 -0
- data/.idea/modules.xml +8 -0
- data/.idea/taskloop.iml +51 -0
- data/.idea/vcs.xml +6 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +36 -0
- data/README.md +31 -0
- data/Rakefile +4 -0
- data/exe/taskloop +16 -0
- data/lib/taskloop/command/deploy.rb +136 -0
- data/lib/taskloop/command/env.rb +134 -0
- data/lib/taskloop/command/init.rb +42 -0
- data/lib/taskloop/command/launch.rb +67 -0
- data/lib/taskloop/command/list.rb +59 -0
- data/lib/taskloop/command/log.rb +104 -0
- data/lib/taskloop/command/run.rb +106 -0
- data/lib/taskloop/command/shutdown.rb +49 -0
- data/lib/taskloop/command/undeploy.rb +46 -0
- data/lib/taskloop/command.rb +168 -0
- data/lib/taskloop/dsl/dsl.rb +63 -0
- data/lib/taskloop/extension/integer_extension.rb +25 -0
- data/lib/taskloop/extension/string_extension.rb +18 -0
- data/lib/taskloop/rules/after_scope_rule.rb +91 -0
- data/lib/taskloop/rules/before_scope_rule.rb +90 -0
- data/lib/taskloop/rules/between_scope_rule.rb +130 -0
- data/lib/taskloop/rules/date_list_rule.rb +47 -0
- data/lib/taskloop/rules/default_rule.rb +19 -0
- data/lib/taskloop/rules/interval_rule.rb +26 -0
- data/lib/taskloop/rules/loop_rule.rb +25 -0
- data/lib/taskloop/rules/rule.rb +34 -0
- data/lib/taskloop/rules/scope_rule.rb +22 -0
- data/lib/taskloop/rules/specific_rule.rb +64 -0
- data/lib/taskloop/rules/time_list_rule.rb +49 -0
- data/lib/taskloop/task/task.rb +244 -0
- data/lib/taskloop/task/task_data_file.rb +46 -0
- data/lib/taskloop/task/task_error.rb +17 -0
- data/lib/taskloop/task/task_property.rb +294 -0
- data/lib/taskloop/utils/proj_tasklist.rb +145 -0
- data/lib/taskloop/version.rb +5 -0
- data/lib/taskloop.rb +9 -0
- data/sig/taskloop.rbs +4 -0
- data/taskloop.gemspec +37 -0
- metadata +103 -0
@@ -0,0 +1,244 @@
|
|
1
|
+
module TaskLoop
|
2
|
+
class Task
|
3
|
+
require 'digest'
|
4
|
+
require 'taskloop/extension/string_extension'
|
5
|
+
require 'taskloop/extension/integer_extension'
|
6
|
+
require_relative './task_error'
|
7
|
+
require_relative './task_property'
|
8
|
+
require_relative './task_data_file'
|
9
|
+
|
10
|
+
include TaskLoop::TaskProperty
|
11
|
+
include TaskLoop::TaskDataFile
|
12
|
+
|
13
|
+
@@tasklist = []
|
14
|
+
def self.tasklist
|
15
|
+
@@tasklist
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.tasklist=(value)
|
19
|
+
@@tasklist = value
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize()
|
23
|
+
yield self
|
24
|
+
check = true
|
25
|
+
unless @name
|
26
|
+
puts "Error: task name is required.".ansi.red
|
27
|
+
puts ""
|
28
|
+
check = false
|
29
|
+
end
|
30
|
+
unless @path
|
31
|
+
puts "Error: task path is required.".ansi.red
|
32
|
+
puts ""
|
33
|
+
check = false
|
34
|
+
end
|
35
|
+
unless check
|
36
|
+
raise TaskArgumentError, "Lack of <required> arguments."
|
37
|
+
end
|
38
|
+
@@tasklist.push(self)
|
39
|
+
end
|
40
|
+
|
41
|
+
#################################
|
42
|
+
# Check and Lint
|
43
|
+
#################################
|
44
|
+
def deploy_lint?
|
45
|
+
result = true
|
46
|
+
# check task name uniqueness
|
47
|
+
@@tasklist.each do |task|
|
48
|
+
if task != self && task.name == @name
|
49
|
+
puts "Error: #{task.desc} => there are multiple tasks with the same name in the Taskfile. Please check the task name again.".ansi.red
|
50
|
+
result = false
|
51
|
+
end
|
52
|
+
# only check with the task before self
|
53
|
+
if task == self
|
54
|
+
break
|
55
|
+
end
|
56
|
+
end
|
57
|
+
# check if task path exists
|
58
|
+
unless @path && File.exists?(@path)
|
59
|
+
puts "Error: #{desc} => the file in <#{@path}> is not exist. Please check the task path again.".ansi.red
|
60
|
+
result = false
|
61
|
+
end
|
62
|
+
# check task rules conflict
|
63
|
+
unless check_rule_conflict?
|
64
|
+
puts "Error: #{desc} rule conflicts have been detected above.".ansi.red
|
65
|
+
result = false
|
66
|
+
end
|
67
|
+
unless result
|
68
|
+
puts "=============================".ansi.red
|
69
|
+
end
|
70
|
+
return result
|
71
|
+
end
|
72
|
+
|
73
|
+
def check_rule_conflict?
|
74
|
+
result = true
|
75
|
+
# check year/month/day with date, they cannot be set at the same time
|
76
|
+
if hasYMD? && hasDate?
|
77
|
+
puts "Error: #{desc} => <year/month/day> and <date> cannot be set at the same time.".ansi.red
|
78
|
+
result = false
|
79
|
+
end
|
80
|
+
|
81
|
+
# check hour/minute with time, they cannot be set at the same time
|
82
|
+
if hasHM? && hasTime?
|
83
|
+
puts "Error: #{desc} => <hour/minute> and <time> cannot be set at the same time.".ansi.red
|
84
|
+
result = false
|
85
|
+
end
|
86
|
+
|
87
|
+
# check rule type
|
88
|
+
|
89
|
+
if hasYMD? && hasHM?
|
90
|
+
# check minute/hour/day/month/year. Get the last IntervalRule, than check if there is SpecificRule or ScopeRule before
|
91
|
+
rules = [minute, hour, day, month, year]
|
92
|
+
rIdx = rules.rindex { |rule| rule.is_a?(IntervalRule) }
|
93
|
+
if rIdx != nil
|
94
|
+
rules.each_with_index do |rule, index|
|
95
|
+
if index < rIdx && (rule.is_a?(ScopeRule) || rule.is_a?(SpecificRule))
|
96
|
+
puts "Error: #{desc} => a ScopeRule or a SpecificRule is assigned to a smaller unit while a IntervalRule is assigned to a larger unit.".ansi.red
|
97
|
+
result = false
|
98
|
+
break
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
if hasYMD? && hasTime?
|
108
|
+
# check year/month/day with time, YMD can not have IntervalRule
|
109
|
+
rules = [day, month, year]
|
110
|
+
hasInterval = rules.any? { |rule| rule.is_a?(IntervalRule) }
|
111
|
+
if hasInterval
|
112
|
+
puts "Error: #{desc} => a IntervalRule is assigned to <year/month/day> while <time> is assigned. It is a conflict!".ansi.red
|
113
|
+
result = false
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
if hasDate? && hasHM?
|
118
|
+
# it's ok
|
119
|
+
end
|
120
|
+
|
121
|
+
if hasDate? && hasTime?
|
122
|
+
# it's ok
|
123
|
+
end
|
124
|
+
|
125
|
+
return result
|
126
|
+
end
|
127
|
+
|
128
|
+
def check_all_rules?
|
129
|
+
last_exec_time = last_time
|
130
|
+
|
131
|
+
result = true
|
132
|
+
result &&= check_interval_rule?(last_exec_time)
|
133
|
+
result &&= check_scope_rule?(last_exec_time)
|
134
|
+
result &&= check_specific_fule?(last_exec_time)
|
135
|
+
result &&= check_loop_rule?(last_exec_time)
|
136
|
+
return result
|
137
|
+
end
|
138
|
+
|
139
|
+
private def check_interval_rule?(last_exec_time)
|
140
|
+
result = true
|
141
|
+
min = 0
|
142
|
+
if year.is_a?(IntervalRule)
|
143
|
+
min += year.interval * YEAR_MIN
|
144
|
+
end
|
145
|
+
if month.is_a?(IntervalRule)
|
146
|
+
min += month.interval * MONTH_MIN
|
147
|
+
end
|
148
|
+
if day.is_a?(IntervalRule)
|
149
|
+
min += day.interval * DAY_MIN
|
150
|
+
end
|
151
|
+
if hour.is_a?(IntervalRule)
|
152
|
+
min += hour.interval * HOUR_MIN
|
153
|
+
end
|
154
|
+
if minute.is_a?(IntervalRule)
|
155
|
+
min += minute.interval
|
156
|
+
end
|
157
|
+
correction = 20
|
158
|
+
result &&= (Time.now.to_i - last_exec_time.to_i + correction) / 60.0 >= min
|
159
|
+
return result
|
160
|
+
end
|
161
|
+
|
162
|
+
private def check_scope_rule?(last_exec_time)
|
163
|
+
result = true
|
164
|
+
if year.is_a?(ScopeRule)
|
165
|
+
result &&= year.is_conform_rule?(last_exec_time)
|
166
|
+
end
|
167
|
+
if month.is_a?(ScopeRule)
|
168
|
+
result &&= month.is_conform_rule?(last_exec_time)
|
169
|
+
end
|
170
|
+
if day.is_a?(ScopeRule)
|
171
|
+
result &&= day.is_conform_rule?(last_exec_time)
|
172
|
+
end
|
173
|
+
if hour.is_a?(ScopeRule)
|
174
|
+
result &&= hour.is_conform_rule?(last_exec_time)
|
175
|
+
end
|
176
|
+
if minute.is_a?(ScopeRule)
|
177
|
+
result &&= minute.is_conform_rule?(last_exec_time)
|
178
|
+
end
|
179
|
+
return result
|
180
|
+
end
|
181
|
+
|
182
|
+
private def check_specific_fule?(last_exec_time)
|
183
|
+
result = true
|
184
|
+
if year.is_a?(SpecificRule)
|
185
|
+
result &&= year.is_conform_rule?(last_exec_time)
|
186
|
+
end
|
187
|
+
if month.is_a?(SpecificRule)
|
188
|
+
result &&= month.is_conform_rule?(last_exec_time)
|
189
|
+
end
|
190
|
+
if day.is_a?(SpecificRule)
|
191
|
+
result &&= day.is_conform_rule?(last_exec_time)
|
192
|
+
end
|
193
|
+
if hour.is_a?(SpecificRule)
|
194
|
+
result &&= hour.is_conform_rule?(last_exec_time)
|
195
|
+
end
|
196
|
+
if minute.is_a?(SpecificRule)
|
197
|
+
result &&= minute.is_conform_rule?(last_exec_time)
|
198
|
+
end
|
199
|
+
if time.is_a?(TimeListRule)
|
200
|
+
result &&= time.is_conform_rule?(last_exec_time)
|
201
|
+
end
|
202
|
+
if date.is_a?(DateListRule)
|
203
|
+
result &&= time.is_conform_rule?(last_exec_time)
|
204
|
+
end
|
205
|
+
return result
|
206
|
+
end
|
207
|
+
|
208
|
+
private def check_loop_rule?(last_exec_time)
|
209
|
+
count = loop_count
|
210
|
+
|
211
|
+
result = true
|
212
|
+
if loop.is_a?(LoopRule)
|
213
|
+
result = count < loop.count
|
214
|
+
end
|
215
|
+
return result
|
216
|
+
end
|
217
|
+
|
218
|
+
|
219
|
+
#################################
|
220
|
+
# Sha1 and description
|
221
|
+
#################################
|
222
|
+
def sha1
|
223
|
+
sha1_digest = Digest::SHA1.new
|
224
|
+
sha1_digest.update(@name)
|
225
|
+
return sha1_digest.hexdigest
|
226
|
+
end
|
227
|
+
|
228
|
+
def desc
|
229
|
+
"<Task.name: #{@name}, sha1: #{sha1}>"
|
230
|
+
end
|
231
|
+
|
232
|
+
#################################
|
233
|
+
# Time Seconds
|
234
|
+
#################################
|
235
|
+
|
236
|
+
YEAR_MIN = 365 * 24 * 60
|
237
|
+
|
238
|
+
MONTH_MIN = 30 * 24 * 60
|
239
|
+
|
240
|
+
DAY_MIN = 24 * 60
|
241
|
+
|
242
|
+
HOUR_MIN = 60
|
243
|
+
end
|
244
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module TaskLoop
|
2
|
+
module TaskDataFile
|
3
|
+
# ~/.taskloop/cache/<project-sha>.
|
4
|
+
attr_accessor :data_proj_dir
|
5
|
+
|
6
|
+
def logfile_path
|
7
|
+
return File.join(@data_proj_dir, logfile_name)
|
8
|
+
end
|
9
|
+
|
10
|
+
def timefile_path
|
11
|
+
return File.join(@data_proj_dir, timefile_name)
|
12
|
+
end
|
13
|
+
|
14
|
+
def loopfile_path
|
15
|
+
return File.join(@data_proj_dir, loopfile_name)
|
16
|
+
end
|
17
|
+
|
18
|
+
def logfile_name
|
19
|
+
return sha1 + "_log"
|
20
|
+
end
|
21
|
+
def timefile_name
|
22
|
+
return sha1 + "_time"
|
23
|
+
end
|
24
|
+
def loopfile_name
|
25
|
+
return sha1 + "_loop"
|
26
|
+
end
|
27
|
+
|
28
|
+
def write_to_logfile(content)
|
29
|
+
file = File.open(logfile_path, "w")
|
30
|
+
file.puts content
|
31
|
+
file.close
|
32
|
+
end
|
33
|
+
|
34
|
+
def write_to_timefile(content)
|
35
|
+
file = File.open(timefile_path, "w")
|
36
|
+
file.puts content
|
37
|
+
file.close
|
38
|
+
end
|
39
|
+
|
40
|
+
def write_to_loopfile(content)
|
41
|
+
file = File.open(loopfile_path, "w")
|
42
|
+
file.puts content
|
43
|
+
file.close
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,294 @@
|
|
1
|
+
module TaskLoop
|
2
|
+
module TaskProperty
|
3
|
+
|
4
|
+
MONTH = {
|
5
|
+
:Jan => 1,
|
6
|
+
:Feb => 2,
|
7
|
+
:Mar => 3,
|
8
|
+
:Apr => 4,
|
9
|
+
:Jun => 6,
|
10
|
+
:Jul => 7,
|
11
|
+
:Aug => 8,
|
12
|
+
:Sep => 9,
|
13
|
+
:Oct => 10,
|
14
|
+
:Nov => 11,
|
15
|
+
:Dec => 12,
|
16
|
+
:mon1 => 1,
|
17
|
+
:mon2 => 2,
|
18
|
+
:mon3 => 3,
|
19
|
+
:mon4 => 4,
|
20
|
+
:mon5 => 5,
|
21
|
+
:mon6 => 6,
|
22
|
+
:mon7 => 7,
|
23
|
+
:mon8 => 8,
|
24
|
+
:mon9 => 9,
|
25
|
+
:mon10 => 10,
|
26
|
+
:mon11 => 11,
|
27
|
+
:mon12 => 12,
|
28
|
+
}
|
29
|
+
|
30
|
+
WEEK_BASE = 10000
|
31
|
+
WEEK = {
|
32
|
+
:Sun => 10000,
|
33
|
+
:Mon => 10001,
|
34
|
+
:Tue => 10002,
|
35
|
+
:Wed => 10003,
|
36
|
+
:Thu => 10004,
|
37
|
+
:Fri => 10005,
|
38
|
+
:Sat => 10006,
|
39
|
+
}
|
40
|
+
|
41
|
+
DAY = {
|
42
|
+
:day1 => 1,
|
43
|
+
:day2 => 2,
|
44
|
+
:day3 => 3,
|
45
|
+
:day4 => 4,
|
46
|
+
:day5 => 5,
|
47
|
+
:day6 => 6,
|
48
|
+
:day7 => 7,
|
49
|
+
:day8 => 8,
|
50
|
+
:day9 => 9,
|
51
|
+
:day10 => 10,
|
52
|
+
:day11 => 11,
|
53
|
+
:day12 => 12,
|
54
|
+
:day13 => 13,
|
55
|
+
:day14 => 14,
|
56
|
+
:day15 => 15,
|
57
|
+
:day16 => 16,
|
58
|
+
:day17 => 17,
|
59
|
+
:day18 => 18,
|
60
|
+
:day19 => 19,
|
61
|
+
:day20 => 20,
|
62
|
+
:day21 => 21,
|
63
|
+
:day22 => 22,
|
64
|
+
:day23 => 23,
|
65
|
+
:day24 => 24,
|
66
|
+
:day25 => 25,
|
67
|
+
:day26 => 26,
|
68
|
+
:day27 => 27,
|
69
|
+
:day28 => 28,
|
70
|
+
:day29 => 29,
|
71
|
+
:day30 => 30,
|
72
|
+
:day31 => 31,
|
73
|
+
}
|
74
|
+
|
75
|
+
# the name of task
|
76
|
+
attr_accessor :name
|
77
|
+
# the path of task
|
78
|
+
attr_accessor :path
|
79
|
+
|
80
|
+
#################################
|
81
|
+
# Setters & Getters
|
82
|
+
#################################
|
83
|
+
# specific syntax
|
84
|
+
# - of
|
85
|
+
# - example: in 2024
|
86
|
+
# interval syntax
|
87
|
+
# - interval
|
88
|
+
# - example: interval 1.year
|
89
|
+
# scope syntax
|
90
|
+
# - before
|
91
|
+
# - example: before 2025
|
92
|
+
# - between
|
93
|
+
# - example: between 2025, 2026
|
94
|
+
# - after
|
95
|
+
# - examle: after 2023
|
96
|
+
def year=(rule)
|
97
|
+
unless rule.is_a?(Rule)
|
98
|
+
raise TypeError, "the rule of year must be a class or subclass of Rule"
|
99
|
+
end
|
100
|
+
|
101
|
+
@year = rule
|
102
|
+
@year.unit = :year
|
103
|
+
end
|
104
|
+
|
105
|
+
def year
|
106
|
+
@year ||= DefaultRule.new(:year)
|
107
|
+
end
|
108
|
+
|
109
|
+
# specific syntax
|
110
|
+
# - of
|
111
|
+
# - example: of :Jan, :Feb, :Mar, :Apr, :Jun, :Jul, :Aug, :Sep, :Oct, :Nov, :Dec;
|
112
|
+
# - example: of :month1, :month2, :month3, ....
|
113
|
+
# interval syntax
|
114
|
+
# - every
|
115
|
+
# - example: interval 1.month
|
116
|
+
# scope syntax
|
117
|
+
# - before
|
118
|
+
# - example: before 2025
|
119
|
+
# - between
|
120
|
+
# - example: between 2025, 2026
|
121
|
+
# - after
|
122
|
+
# - examle: after 2023
|
123
|
+
def month=(rule)
|
124
|
+
unless rule.is_a?(Rule)
|
125
|
+
raise TypeError, "the rule of month must be a class or subclass of Rule"
|
126
|
+
end
|
127
|
+
@month = rule
|
128
|
+
@month.unit = :month
|
129
|
+
end
|
130
|
+
|
131
|
+
def month
|
132
|
+
@month||= DefaultRule.new(:month)
|
133
|
+
end
|
134
|
+
|
135
|
+
# specific syntax
|
136
|
+
# - on
|
137
|
+
# - example: on :Mon, :Tue, :Wed, :Thu, :Fri, :Sat, :Sun;
|
138
|
+
# - example: on :day1, :day2, :day3;
|
139
|
+
# interval syntax
|
140
|
+
# - interval
|
141
|
+
# - example: interval 10.day
|
142
|
+
# scope syntax
|
143
|
+
# - before
|
144
|
+
# - example: before :day10
|
145
|
+
# - between
|
146
|
+
# - example: between :day10, :day19
|
147
|
+
# - example: between :Mon, :Fri
|
148
|
+
# - after
|
149
|
+
# - example: after :day10
|
150
|
+
def day=(rule)
|
151
|
+
unless rule.is_a?(Rule)
|
152
|
+
raise TypeError, "the rule of day must be a class or subclass of Rule"
|
153
|
+
end
|
154
|
+
@day = rule
|
155
|
+
@day.unit = :day
|
156
|
+
end
|
157
|
+
|
158
|
+
def day
|
159
|
+
@day ||= DefaultRule.new(:day)
|
160
|
+
end
|
161
|
+
|
162
|
+
# specific syntax
|
163
|
+
# - at
|
164
|
+
# - example: at 10; at 23
|
165
|
+
# interval syntax
|
166
|
+
# - interval
|
167
|
+
# - example: interval 10.hour
|
168
|
+
# scope syntax
|
169
|
+
# - before
|
170
|
+
# - example: before 9
|
171
|
+
# - between
|
172
|
+
# - example: between 10, 12
|
173
|
+
# - after
|
174
|
+
# - example: after 11
|
175
|
+
def hour=(rule)
|
176
|
+
unless rule.is_a?(Rule)
|
177
|
+
raise TypeError, "the rule of hour must be a class or subclass of Rule"
|
178
|
+
end
|
179
|
+
@hour = rule
|
180
|
+
@hour.unit = :hour
|
181
|
+
end
|
182
|
+
|
183
|
+
def hour
|
184
|
+
@hour ||= DefaultRule.new(:hour)
|
185
|
+
end
|
186
|
+
|
187
|
+
# specific syntax
|
188
|
+
# - at
|
189
|
+
# - example: at 59; at 45
|
190
|
+
# interval syntax
|
191
|
+
# - interval
|
192
|
+
# - example: interval 5.minute
|
193
|
+
def minute=(rule)
|
194
|
+
unless rule.is_a?(Rule)
|
195
|
+
raise TypeError, "the rule of minute must be a class or subclass of Rule"
|
196
|
+
end
|
197
|
+
|
198
|
+
if rule.is_a?(ScopeRule)
|
199
|
+
raise TypeError, "the rule of minute cannot be a class or subclass of ScopeRule"
|
200
|
+
end
|
201
|
+
@minute = rule
|
202
|
+
@minute.unit = :minute
|
203
|
+
end
|
204
|
+
|
205
|
+
def minute
|
206
|
+
@minute ||= DefaultRule.new(:minute)
|
207
|
+
end
|
208
|
+
|
209
|
+
# loop syntax
|
210
|
+
# - loop
|
211
|
+
# - example: loop 5.times
|
212
|
+
def loop=(rule)
|
213
|
+
unless rule.is_a?(Rule)
|
214
|
+
raise TypeError, "the rule of loop must be a class or subclass of Rule"
|
215
|
+
end
|
216
|
+
|
217
|
+
@loop = rule
|
218
|
+
@loop.unit = :loop
|
219
|
+
end
|
220
|
+
def loop
|
221
|
+
@loop ||= DefaultRule.new(:loop)
|
222
|
+
end
|
223
|
+
|
224
|
+
# time list syntax
|
225
|
+
# - time
|
226
|
+
# - example: time "10:10:30", "9:10:20", "20:10:20"
|
227
|
+
def time=(rule)
|
228
|
+
unless rule.is_a?(TimeListRule)
|
229
|
+
raise TypeError, "the rule of time must be a TimeList Rule"
|
230
|
+
end
|
231
|
+
|
232
|
+
@time = rule
|
233
|
+
@time.unit = :time
|
234
|
+
end
|
235
|
+
def time
|
236
|
+
@time ||= DefaultRule.new(:time)
|
237
|
+
end
|
238
|
+
|
239
|
+
# date list syntax
|
240
|
+
# - date
|
241
|
+
# - example: date "2023-10-10", "2013-10-11", "2023-11-10"
|
242
|
+
def date=(rule)
|
243
|
+
unless rule.is_a?(DateListRule)
|
244
|
+
raise TypeError, "the rule of time must be a DateList Rule"
|
245
|
+
end
|
246
|
+
|
247
|
+
@date = rule
|
248
|
+
@date.unit = :date
|
249
|
+
end
|
250
|
+
def date
|
251
|
+
@date ||= DefaultRule.new(:date)
|
252
|
+
end
|
253
|
+
|
254
|
+
#################################
|
255
|
+
# Help Methods
|
256
|
+
#################################
|
257
|
+
def hasDate?
|
258
|
+
!date.is_a?(DefaultRule)
|
259
|
+
end
|
260
|
+
|
261
|
+
def hasTime?
|
262
|
+
!time.is_a?(DefaultRule)
|
263
|
+
end
|
264
|
+
|
265
|
+
def hasYMD?
|
266
|
+
[year, month, day].any? { |rule| !rule.is_a?(DefaultRule) }
|
267
|
+
end
|
268
|
+
|
269
|
+
def hasHM?
|
270
|
+
[hour, minute].any? { |rule| !rule.is_a?(DefaultRule) }
|
271
|
+
end
|
272
|
+
|
273
|
+
def has_interval_rule?
|
274
|
+
rules = [year, month, day, hour, minute]
|
275
|
+
return rules.any?{ |rule| rule.is_a?(IntervalRule) }
|
276
|
+
end
|
277
|
+
|
278
|
+
def loop_count
|
279
|
+
count = 0
|
280
|
+
File.open(loopfile_path, 'r') do |file|
|
281
|
+
count = file.gets.to_i
|
282
|
+
end
|
283
|
+
return count
|
284
|
+
end
|
285
|
+
|
286
|
+
def last_time
|
287
|
+
timestamp = 0
|
288
|
+
File.open(timefile_path, 'r') do |file|
|
289
|
+
timestamp = file.gets.to_i
|
290
|
+
end
|
291
|
+
return Time.at(timestamp)
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|