Class: DevFlow::Task
- Inherits:
-
Object
- Object
- DevFlow::Task
- Defined in:
- lib/dev_flow/task.rb,
lib/dev_flow/task_js.rb,
lib/dev_flow/task_console.rb
Overview
Task object represent a single line on the Gantt chart
Instance Attribute Summary collapse
-
#branch_name ⇒ Object
which line of file defined the task.
-
#children ⇒ Object
which line of file defined the task.
-
#completed_at ⇒ Object
which line of file defined the task.
-
#dependencie_names ⇒ Object
which line of file defined the task.
-
#dependencies ⇒ Object
which line of file defined the task.
-
#display_name ⇒ Object
which line of file defined the task.
-
#end_date ⇒ Object
which line of file defined the task.
-
#file ⇒ Object
which line of file defined the task.
-
#is_deleted ⇒ Object
which line of file defined the task.
-
#is_pending ⇒ Object
which line of file defined the task.
-
#level ⇒ Object
which line of file defined the task.
-
#ln ⇒ Object
which line of file defined the task.
-
#parent ⇒ Object
which line of file defined the task.
-
#progress ⇒ Object
which line of file defined the task.
-
#resource_names ⇒ Object
which line of file defined the task.
-
#resources ⇒ Object
which line of file defined the task.
-
#start_date ⇒ Object
which line of file defined the task.
Instance Method Summary collapse
- #as_js(resource) ⇒ Object
- #as_title(header = ' ') ⇒ Object
- #caption ⇒ Object
-
#color(resource_ = nil) ⇒ Object
color reflects the status of a task, return a hex code without heading “#”.
- #dependencies_str ⇒ Object
-
#initialize(level, file = "-", ln = 0) ⇒ Task
constructor
initialize with level, file and line number.
-
#is_completable? ⇒ Boolean
a task is completable if all children complated.
- #is_completed? ⇒ Boolean
-
#is_delayed? ⇒ Boolean
usually red.
- #is_deleted? ⇒ Boolean
-
#is_milestone? ⇒ Boolean
filter methods.
- #is_parent? ⇒ Boolean
- #is_pending? ⇒ Boolean
- #is_release? ⇒ Boolean
-
#is_urgent? ⇒ Boolean
usually orange.
-
#is_workable? ⇒ Boolean
a task is workable (can be started) if all children task and dependent task are completed.
- #parent_id ⇒ Object
-
#parse(line, headers = {}) ⇒ Object
parse the line from file:ln (line number), initialize the task object.
- #resource_name ⇒ Object
- #task_id ⇒ Object
-
#validate! ⇒ Object
check whether the task is well defined, raise error otherwise.
Constructor Details
#initialize(level, file = "-", ln = 0) ⇒ Task
initialize with level, file and line number
20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/dev_flow/task.rb', line 20 def initialize level,file="-",ln=0 @level = level.to_i raise "invalid level #{level}" unless level.to_i > 0 @file, @ln = file, ln @children = Array.new @dependencies = Array.new @dependencie_names = Array.new @progress = 0 @resources = Array.new @resource_names = Array.new end |
Instance Attribute Details
#branch_name ⇒ Object
which line of file defined the task
10 11 12 |
# File 'lib/dev_flow/task.rb', line 10 def branch_name @branch_name end |
#children ⇒ Object
which line of file defined the task
10 11 12 |
# File 'lib/dev_flow/task.rb', line 10 def children @children end |
#completed_at ⇒ Object
which line of file defined the task
10 11 12 |
# File 'lib/dev_flow/task.rb', line 10 def completed_at @completed_at end |
#dependencie_names ⇒ Object
which line of file defined the task
10 11 12 |
# File 'lib/dev_flow/task.rb', line 10 def dependencie_names @dependencie_names end |
#dependencies ⇒ Object
which line of file defined the task
10 11 12 |
# File 'lib/dev_flow/task.rb', line 10 def dependencies @dependencies end |
#display_name ⇒ Object
which line of file defined the task
10 11 12 |
# File 'lib/dev_flow/task.rb', line 10 def display_name @display_name end |
#end_date ⇒ Object
which line of file defined the task
10 11 12 |
# File 'lib/dev_flow/task.rb', line 10 def end_date @end_date end |
#file ⇒ Object
which line of file defined the task
10 11 12 |
# File 'lib/dev_flow/task.rb', line 10 def file @file end |
#is_deleted ⇒ Object
which line of file defined the task
10 11 12 |
# File 'lib/dev_flow/task.rb', line 10 def is_deleted @is_deleted end |
#is_pending ⇒ Object
which line of file defined the task
10 11 12 |
# File 'lib/dev_flow/task.rb', line 10 def is_pending @is_pending end |
#level ⇒ Object
which line of file defined the task
10 11 12 |
# File 'lib/dev_flow/task.rb', line 10 def level @level end |
#ln ⇒ Object
which line of file defined the task
10 11 12 |
# File 'lib/dev_flow/task.rb', line 10 def ln @ln end |
#parent ⇒ Object
which line of file defined the task
10 11 12 |
# File 'lib/dev_flow/task.rb', line 10 def parent @parent end |
#progress ⇒ Object
which line of file defined the task
10 11 12 |
# File 'lib/dev_flow/task.rb', line 10 def progress @progress end |
#resource_names ⇒ Object
which line of file defined the task
10 11 12 |
# File 'lib/dev_flow/task.rb', line 10 def resource_names @resource_names end |
#resources ⇒ Object
which line of file defined the task
10 11 12 |
# File 'lib/dev_flow/task.rb', line 10 def resources @resources end |
#start_date ⇒ Object
which line of file defined the task
10 11 12 |
# File 'lib/dev_flow/task.rb', line 10 def start_date @start_date end |
Instance Method Details
#as_js(resource) ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/dev_flow/task_js.rb', line 59 def as_js resource is_milestone_flag = self.is_milestone? ? 1 : 0 is_parent_flag = self.is_parent? ? 1 : 0 task_str = " g.AddTaskItem(new JSGantt.TaskItem(%d,'%s','%s','%s','%s','%s',%d,'%s',%d,%d,%d,%d,'%s','%s'));\n" sprintf(task_str, self.task_id, self.display_name, self.start_date.strftime("%m/%d/%Y"), self.end_date.strftime("%m/%d/%Y"), self.color(resource), '', is_milestone_flag, self.resource_name, self.progress.to_i, is_parent_flag, self.parent_id, 1, self.dependencies_str, self.caption) end |
#as_title(header = ' ') ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# File 'lib/dev_flow/task_console.rb', line 4 def as_title header = ' ' name = self.display_name name = self.display_name.bold if self.is_workable? name = self.display_name.blue if self.progress > 0 name = self.display_name.green if self.is_completed? name = self.display_name.magenta if self.is_urgent? name = self.display_name.red if self.is_delayed? if self.progress > 0 and self.progress < 100 on_branch = sprintf "(=> %s, %02d%%)", self.branch_name.bold, self.progress end d1 = DateName.zh(self.start_date, DateTime.now.strftime("%F")).bold d2 = DateName.zh(self.end_date, DateTime.now.strftime("%F")).bold title = sprintf("%s[%s]%s (%s-%s) %s", ' '*(self.level-1), header, name, d1, d2, on_branch) end |
#caption ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/dev_flow/task_js.rb', line 46 def caption return "" if self.children.size > 0 cap = self.resource_name cap = sprintf("Pending (%s)", cap) if self.is_pending? cap = sprintf("Deleted (%s)", cap) if self.is_deleted? if self.is_completed? cap += self.completed_at.strftime("%F") else cap += sprintf(':%02d\%', self.progress) if self.progress > 0 end cap end |
#color(resource_ = nil) ⇒ Object
color reflects the status of a task, return a hex code without heading “#”
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/dev_flow/task_js.rb', line 22 def color resource_ = nil today = DateTime.now.strftime("%Y%m%d").to_i start_day = self.start_date.strftime("%Y%m%d").to_i end_day = self.end_date.strftime("%Y%m%d").to_i hex = "B0C4DE" # light steel blue as default hex = "808080" unless self.is_workable? # grey for no able to start hex = "FFFF00" if self.progress > 0 and self.progress < 100 # blue for working hex = "FFD700" if start_day == today and progress == 0 # gold for must start now hex = "FFA500" if end_day == today and self.progress < 100 # orange for master complete today hex = "008000" if self.is_completed? # green for completed hex = "FF0000" if self.progress < 100 and today > end_day # red for not completed on time hex = "FF0000" if self.progress == 0 and today > start_day # red for late start hex = "EEE8AA" if self.is_deleted? hex = "C0C0C0" if self.is_pending? # puts hex + ":" + self.progress.to_s + ";" + DateTime.now.strftime("%Y%m%d") + ":" + self.start_date.strftime("%Y%m%d") if resource_ hex = "CCCCCC" unless self.resources.include? resource_ end hex end |
#dependencies_str ⇒ Object
17 18 19 |
# File 'lib/dev_flow/task_js.rb', line 17 def dependencies_str self.dependencies.map {|d| d.task_id}.join "," end |
#is_completable? ⇒ Boolean
a task is completable if all children complated
22 23 24 25 26 27 28 |
# File 'lib/dev_flow/task_console.rb', line 22 def is_completable? return false if self.is_completed? self.children.each do |child| return false unless child.is_completed? end true end |
#is_completed? ⇒ Boolean
41 42 43 |
# File 'lib/dev_flow/task.rb', line 41 def is_completed? self.progress == 100 end |
#is_delayed? ⇒ Boolean
usually red
67 68 69 70 71 72 73 74 |
# File 'lib/dev_flow/task.rb', line 67 def is_delayed? # usually red today = DateTime.now.strftime("%Y%m%d").to_i start_day = self.start_date.strftime("%Y%m%d").to_i end_day = self.end_date.strftime("%Y%m%d").to_i return true if self.progress < 100 and today > end_day return true if self.progress == 0 and today > start_day false end |
#is_deleted? ⇒ Boolean
49 50 51 |
# File 'lib/dev_flow/task.rb', line 49 def is_deleted? self.is_deleted ? true : false end |
#is_milestone? ⇒ Boolean
filter methods
33 34 35 |
# File 'lib/dev_flow/task.rb', line 33 def is_milestone? self.branch_name =~ /^(milestone|release)\_/ ? true : false end |
#is_parent? ⇒ Boolean
53 54 55 |
# File 'lib/dev_flow/task.rb', line 53 def is_parent? self.children.size > 0 ? true : false end |
#is_pending? ⇒ Boolean
45 46 47 |
# File 'lib/dev_flow/task.rb', line 45 def is_pending? self.is_pending ? true :false end |
#is_release? ⇒ Boolean
37 38 39 |
# File 'lib/dev_flow/task.rb', line 37 def is_release? self.branch_name =~ /^release\_/ ? true : false end |
#is_urgent? ⇒ Boolean
usually orange
57 58 59 60 61 62 63 64 65 |
# File 'lib/dev_flow/task.rb', line 57 def is_urgent? # usually orange today = DateTime.now.strftime("%Y%m%d").to_i start_day = self.start_date.strftime("%Y%m%d").to_i end_day = self.end_date.strftime("%Y%m%d").to_i return true if start_day == today and progress == 0 return true if end_day == today and self.progress < 100 false end |
#is_workable? ⇒ Boolean
a task is workable (can be started) if all children task and dependent task are completed
32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/dev_flow/task_console.rb', line 32 def is_workable? # trivial: if already completed, do not start again return false if self.is_completed? return false if self.is_pending or self.is_deleted self.dependencies.each do |t| return false unless t.is_completed? end self.children.each do |t| return false unless t.is_completed? end true end |
#parent_id ⇒ Object
9 10 11 |
# File 'lib/dev_flow/task_js.rb', line 9 def parent_id self.parent ? self.parent.task_id : 0 end |
#parse(line, headers = {}) ⇒ Object
parse the line from file:ln (line number), initialize the task object
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/dev_flow/task.rb', line 93 def parse line, headers = {} line = line.strip # delete head/trailing spaces /^((?<branch_name_>[a-zA-Z0-9_\-\#\.\/]+):)?\s*(?<display_name_>.+)\s+(?<start_date_>(\d\d\d\d\/)?\d\d?\/\d\d?)(-(?<end_date_>(\d\d\d\d\/)?\d\d?\/\d\d?))?(\s+\@(?<resource_>[a-z\@\;]+))?(\:(?<status_>(P|D))?(?<progress_>[\d\/]+)?)?(\s+\-\>\s*(?<dependencies_>.+))?$/ =~ line # assign branch name and display name self.branch_name = branch_name_ self.display_name = display_name_ # assign start and end date end_date_ = start_date_ unless end_date_ raise "no valid start date found on #{self.file}:#{self.ln}" unless start_date_ and start_date_.size > 0 if headers["year"] start_date_ = headers["year"].to_s + "/" + start_date_ unless start_date_ =~ /^\d\d\d\d/ end_date_ = headers["year"].to_s + "/" + end_date_ unless end_date_ =~ /^\d\d\d\d/ end begin self.start_date = DateTime.parse(start_date_) self.end_date = DateTime.parse(end_date_) rescue Exception => e raise "invalid date on #{self.file}:#{self.ln}" end # assign for the resources (user name) unless resource_ if headers["leader"] resource_ = headers["leader"] else raise "no resource defined on #{self.file}:#{self.ln}" end end resource_.gsub!("\@", "") # @ for other user is optional resource_.split(";").each do |r| self.resources << r # if the user is listed on known members rname = r if headers["members"] and headers["members"][r] and headers["members"][r][0] rname = headers["members"][r][0] end self.resource_names << rname end if dependencies_ dependencies_.strip! dependencies_.gsub!(/;$/, "") self.dependencie_names = dependencies_.split(/;/) end # pending or deleted status if status_ if status_ == "P" self.is_pending = true elsif status_ == "D" self.is_deleted = true end end # progress if progress_ if progress_ =~ /^\d\d?$/ and progress_.to_i > 0 and progress_.to_i < 100 self.progress = progress_.to_i elsif progress_ =~ /^\d\d\d\d\/\d\d?\/\d\d?$/ self.progress = 100 self.completed_at = DateTime.parse(progress_) elsif progress_ =~ /^\d\d?\/\d\d?$/ and headers["year"] self.progress = 100 self.completed_at = DateTime.parse(headers["year"].to_s + "/" + progress_.to_s) else msg = "worng format around progress parameter '#{progress_}', on #{self.file}:#{self.ln}" msg += " (HINT: use date to complete a task, not 100)" if progress_.to_i == 100 raise msg end end self end |
#resource_name ⇒ Object
13 14 15 |
# File 'lib/dev_flow/task_js.rb', line 13 def resource_name self.resource_names.join "," end |
#task_id ⇒ Object
5 6 7 |
# File 'lib/dev_flow/task_js.rb', line 5 def task_id self.ln end |
#validate! ⇒ Object
check whether the task is well defined, raise error otherwise.
77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/dev_flow/task.rb', line 77 def validate! if self.is_milestone? unless self.level == 1 raise "you can only tag a top level task as a release, on #{self.file}:#{self.ln}" if self.branch_name =~ /^release\_/ end end raise "resource not found on #{self.file}:#{self.ln}" unless self.resources.size > 0 raise "display_name not found on #{self.file}:#{self.ln}" unless self.display_name raise "valid start_date not found on #{self.file}:#{self.ln}" unless self.start_date raise "wrong date on #{self.file}:#{self.ln}" unless self.start_date and self.end_date and self.start_date <= self.end_date self end |