dev_flow 0.3.1 → 0.4.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.
data/bin/dw CHANGED
@@ -26,6 +26,7 @@ optparse = OptionParser.new do |opts|
26
26
  opts.separator " close : close the task as a leader"
27
27
  opts.separator " release : close a release task"
28
28
  opts.separator " clean[up] : delete local branches that already completed"
29
+ opts.separator " gantt : create gantt chart html files under docs folder"
29
30
  opts.separator ""
30
31
  opts.separator "Options:"
31
32
 
@@ -50,6 +51,11 @@ optparse = OptionParser.new do |opts|
50
51
  options[:offline] = true
51
52
  end
52
53
 
54
+ options[:docs] = 'docs'
55
+ opts.on('-d DIR', '--docs DIR', 'document directory for gantt chart') do |dir|
56
+ options[:docs] = dir
57
+ end
58
+
53
59
  opts.on('-v', '--verbose', 'print more messages') do
54
60
  options[:verbose] = true
55
61
  end
@@ -67,7 +73,7 @@ command = ARGV[0] || 'info'
67
73
  cmd_alias = {'pg' => 'progress', 'update-roadmap' => 'ur', 'clean' => 'cleanup', 's' => 'switch'}
68
74
  command = cmd_alias[command] if cmd_alias[command]
69
75
 
70
- if %w[info init complete progress close release ur update-roadmap cleanup clean switch].include? command
76
+ if %w[info init complete progress close release ur update-roadmap cleanup clean switch gantt].include? command
71
77
  options[:command] = command
72
78
  else
73
79
  puts "Unknown command #{command}".red
data/lib/dev_flow/app.rb CHANGED
@@ -27,9 +27,7 @@ module DevFlow
27
27
  info "Load local configuration from #{@config[:local_config]}"
28
28
  @config = @config.merge(YAML.load(File.open(@config[:local_config], 'r:utf-8').read))
29
29
  end
30
-
31
- error "Do not work on master branch. Please swith to develop branch." if @git.current_branch == 'master'
32
-
30
+
33
31
  # load roadmap into variable @roadmap
34
32
  load_roadmap
35
33
 
File without changes
@@ -0,0 +1,51 @@
1
+ require 'fileutils'
2
+ require 'erubis'
3
+
4
+ module DevFlow
5
+ class Gantt < App
6
+
7
+ ## fetch git log
8
+ def git_log
9
+ git_log = ''
10
+ committer = ''
11
+ last_header = ''
12
+ `git log --graph --format=email --date=relative -n 50`.split(/\n/).each do |line|
13
+ # {{{
14
+ line.chomp!
15
+ line.gsub!(">", "&gt;")
16
+ line.gsub!("<", "&lt;")
17
+ if /^(?<header_>\W+)From\s+(?<hash_code_>\w+)/ =~ line
18
+ git_log += "#{header_}<em style='color:grey'>#{hash_code_}</em>\n"
19
+ elsif /^(?<header_>\W+)From\:\s+(?<committer_>.+)$/ =~ line
20
+ committer = committer_
21
+ last_header = header_
22
+ elsif /^(?<header_>\W+)Date\:\s*(?<date_>.+)$/ =~ line
23
+ git_log += sprintf("%s<strong>%s</strong> By %s\n", last_header, DateTime.parse(date_).strftime("%F %R"), committer)
24
+ git_log += header_
25
+ elsif /^(?<header_>\W+)Subject\:\s+\[PATCH\]\s*(?<message_>.+)$/ =~ line
26
+ color = 'green'
27
+ git_log += "#{header_}<strong style='color:#{color}'>#{message_}</strong>\n"
28
+ else
29
+ git_log += line + "\n"
30
+ end
31
+ end
32
+ git_log
33
+ end
34
+
35
+ ## create gantt chart from templates
36
+ def process!
37
+ docs = @config[:docs]
38
+ html_file = "#{docs}/gantt.html"
39
+ FileUtils.mkdir_p "#{docs}" unless File.directory? "#{docs}"
40
+
41
+ tpl_dir = File.expand_path(File.dirname(__FILE__) + "/../../../templates")
42
+ FileUtils.cp_r "#{tpl_dir}/css", docs
43
+ FileUtils.cp_r "#{tpl_dir}/js", docs
44
+
45
+ wfh = File.open(html_file, "w:utf-8")
46
+ wfh.puts Erubis::Eruby.new(File.read("#{tpl_dir}/jsgantt.html.erb")).result(:rm => @roadmap, :is_roadmap => true, :git_log => git_log, :resource => nil)
47
+ wfh.close
48
+ end
49
+
50
+ end
51
+ end
@@ -19,7 +19,7 @@ module DevFlow
19
19
  end
20
20
 
21
21
  def title
22
- @config[:title]
22
+ @config["title"]
23
23
  end
24
24
 
25
25
  def team_member_names
@@ -0,0 +1,71 @@
1
+ module DevFlow
2
+
3
+ class Task
4
+
5
+ def task_id
6
+ self.ln
7
+ end
8
+
9
+ def parent_id
10
+ self.parent ? self.parent.task_id : 0
11
+ end
12
+
13
+ def resource_name
14
+ self.resource_names.join ","
15
+ end
16
+
17
+ def dependencies_str
18
+ self.dependencies.map {|d| d.task_id}.join ","
19
+ end
20
+
21
+ ## color reflects the status of a task, return a hex code without heading "#"
22
+ def color resource_ = nil
23
+ today = DateTime.now.strftime("%Y%m%d").to_i
24
+ start_day = self.start_date.strftime("%Y%m%d").to_i
25
+ end_day = self.end_date.strftime("%Y%m%d").to_i
26
+ hex = "B0C4DE" # light steel blue as default
27
+ hex = "808080" unless self.is_workable? # grey for no able to start
28
+ hex = "FFD700" if start_day == today and progress == 0 # gold for must start now
29
+ hex = "FFFF00" if self.progress > 0 and self.progress < 100 # blue for working
30
+ hex = "FFA500" if end_day == today and self.progress < 100 # orange for master complete today
31
+
32
+ if resource_
33
+ hex = "CCCCCC" unless self.resources.include? resource_
34
+ end
35
+
36
+ hex = "008000" if self.is_completed? # green for completed
37
+ hex = "FF0000" if self.progress < 100 and today > end_day # red for not completed on time
38
+ hex = "FF0000" if self.progress == 0 and today > start_day # red for late start
39
+ hex = "EEE8AA" if self.is_deleted?
40
+ hex = "C0C0C0" if self.is_pending?
41
+ # puts hex + ":" + self.progress.to_s + ";" + DateTime.now.strftime("%Y%m%d") + ":" + self.start_date.strftime("%Y%m%d")
42
+ hex
43
+ end
44
+
45
+ def caption
46
+ return "" if self.children.size > 0
47
+ cap = self.resource_name
48
+ cap = sprintf("Pending (%s)", cap) if self.is_pending?
49
+ cap = sprintf("Deleted (%s)", cap) if self.is_deleted?
50
+ if self.is_completed?
51
+ cap += self.completed_at.strftime("%F")
52
+ else
53
+ cap += sprintf(':%02d\%', self.progress) if self.progress > 0
54
+ end
55
+ cap
56
+ end
57
+
58
+ def as_js resource
59
+ is_milestone_flag = self.is_milestone? ? 1 : 0
60
+ is_parent_flag = self.is_parent? ? 1 : 0
61
+ task_str = " g.AddTaskItem(new JSGantt.TaskItem(%d,'%s','%s','%s','%s','%s',%d,'%s',%d,%d,%d,%d,'%s','%s'));\n"
62
+ sprintf(task_str, self.task_id, self.display_name,
63
+ self.start_date.strftime("%m/%d/%Y"),
64
+ self.end_date.strftime("%m/%d/%Y"),
65
+ self.color(resource), '', is_milestone_flag,
66
+ self.resource_name, self.progress.to_i, is_parent_flag,
67
+ self.parent_id, 1, self.dependencies_str, self.caption)
68
+ end
69
+ end
70
+
71
+ end
@@ -1,3 +1,3 @@
1
1
  module DevFlow
2
- VERSION = '0.3.1'
2
+ VERSION = '0.4.0'
3
3
  end
data/lib/dev_flow.rb CHANGED
@@ -9,6 +9,7 @@ require 'dev_flow/member'
9
9
 
10
10
  # presenter
11
11
  require 'dev_flow/task_console'
12
+ require 'dev_flow/task_js'
12
13
 
13
14
  # application and commands
14
15
  require 'dev_flow/app'
data/tags CHANGED
File without changes
@@ -0,0 +1,53 @@
1
+
2
+ // These are the class/styles used by various objects in GanttChart. However, Firefox has problems deciphering class style when DIVs are embedded in other DIVs.
3
+
4
+ // GanttChart makes heavy use of embedded DIVS, thus the style are often embedded directly in the objects html. If this could be resolved with Firefox, it would
5
+
6
+ // make alot of the code look simpleer/cleaner without all the embedded styles
7
+
8
+
9
+
10
+ ..gantt { font-family:tahoma, arial, verdana; font-size:10px;}
11
+
12
+ ..gdatehead { BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid; HEIGHT: 18px }
13
+
14
+ ..ghead { BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid; WIDTH: 24px; HEIGHT: 20px }
15
+
16
+ ..gname { BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; WIDTH: 18px; HEIGHT: 18px }
17
+
18
+ ..ghead A { FONT-SIZE: 10px; COLOR: #000000; TEXT-DECORATION: none }
19
+
20
+ ..gheadwkend A { FONT-SIZE: 10px; COLOR: #000000; TEXT-DECORATION: none }
21
+
22
+ ..gheadwkend { BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid; WIDTH: 24px; HEIGHT: 20px; background-color: #cfcfcf }
23
+
24
+ ..gfiller { BORDER-TOP: #efefef 1px solid; BORDER-LEFT: #efefef 1px solid; WIDTH: 18px; HEIGHT: 18px }
25
+
26
+ ..gfillerwkend { BORDER-LEFT: #efefef 1px solid; WIDTH: 18px; HEIGHT: 18px; BACKGROUND-COLOR: #cfcfcf }
27
+
28
+ ..gitem { BORDER-TOP: #cccccc 1px solid; WIDTH: 18px; HEIGHT: 18px }
29
+
30
+ ..gitemwkend { BORDER-TOP: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; WIDTH: 18px; HEIGHT: 18px }
31
+
32
+ ..gmilestone { BORDER-TOP: #efefef 1px solid; FONT-SIZE: 14px; OVERFLOW: hidden; BORDER-LEFT: #efefef 1px solid; WIDTH: 18px; HEIGHT: 18px}
33
+
34
+ ..gmilestonewkend { BORDER-TOP: #efefef 1px solid; BORDER-LEFT: #cccccc 1px solid; WIDTH: 18px; HEIGHT: 18px}
35
+
36
+ ..btn { BORDER-RIGHT: #ffffff; BORDER-TOP: #ffffff; FONT-WEIGHT: bold; FONT-SIZE: 10px; BORDER-LEFT: #ffffff; WIDTH: 12px; COLOR: #cccccc; BORDER-BOTTOM: #ffffff; BACKGROUND-COLOR: #ffffff }
37
+
38
+ ..hrcomplete { BORDER-RIGHT: #000000 2px solid; PADDING-RIGHT: 0px; BORDER-TOP: #000000 2px solid; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; BORDER-LEFT: #000000 2px solid; WIDTH: 20px; COLOR: #000000; PADDING-TOP: 0px; BORDER-BOTTOM: #000000 2px solid; HEIGHT: 4px }
39
+
40
+ ..hrhalfcomplete { BORDER-RIGHT: #000000 2px solid; BORDER-TOP: #000000 2px solid; BORDER-LEFT: #000000 2px solid; WIDTH: 9px; COLOR: #000000; BORDER-BOTTOM: #000000 2px solid; HEIGHT: 4px }
41
+
42
+ ..gweekend { font-family:tahoma, arial, verdana; font-size:11px; background-color:#EEEEEE; text-align:center; }
43
+
44
+ ..gtask { font-family:tahoma, arial, verdana; font-size:11px; background-color:#00FF00; text-align:center; }
45
+
46
+ ..gday { font-family:tahoma, arial, verdana; font-size:11px; text-align:center; }
47
+
48
+ ..gcomplete { background-color:black; height:5px; overflow: auto; margin-top:4px; }
49
+
50
+ DIV.scroll { BORDER-RIGHT: #efefef 1px solid; PADDING-RIGHT: 0px; BORDER-TOP: #efefef 1px solid; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; OVERFLOW: hidden; BORDER-LEFT: #efefef 1px solid; WIDTH: 420px; PADDING-TOP: 0px; BORDER-BOTTOM: #efefef 1px solid; BACKGROUND-COLOR: #ffffff }
51
+
52
+ DIV.scroll2 { position:relative; PADDING-RIGHT: 0px; overflow:auto ;overflow-x:scroll;overflow-y:hidden; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; WIDTH: 482px; PADDING-TOP: 0px; BACKGROUND-COLOR: #ffffff }
53
+