ursm-ditz 0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,92 @@
1
+ module Ditz
2
+ class Issue
3
+ field :claimer, :ask => false
4
+
5
+ def claim who, comment, force=false
6
+ raise Error, "already claimed by #{claimer}" if claimer && !force
7
+ log "issue claimed", who, comment
8
+ self.claimer = who
9
+ end
10
+
11
+ def unclaim who, comment, force=false
12
+ raise Error, "not claimed" unless claimer
13
+ raise Error, "can only be unclaimed by #{claimer}" unless claimer == who || force
14
+ if claimer == who
15
+ log "issue unclaimed", who, comment
16
+ else
17
+ log "unassigned from #{claimer}", who, comment
18
+ end
19
+ self.claimer = nil
20
+ end
21
+
22
+ def claimed?; claimer end
23
+ def unclaimed?; !claimed? end
24
+ end
25
+
26
+ class ScreenView
27
+ add_to_view :issue_summary do |issue, config|
28
+ " Claimed by: #{issue.claimer || 'none'}\n"
29
+ end
30
+ end
31
+
32
+ class HtmlView
33
+ add_to_view :issue_summary do |issue, config|
34
+ next unless issue.git_branch
35
+ [<<EOS, { :issue => issue, :url_prefix => config.git_branch_url_prefix }]
36
+ <tr>
37
+ <td class='attrname'>Claimed by:</td>
38
+ <td class='attrval'>h(issue.claimer) %></td>
39
+ </tr>
40
+ EOS
41
+ end
42
+ end
43
+
44
+ class Operator
45
+ operation :claim, "Claim an issue for yourself", :issue do
46
+ opt :force, "Claim this issue even if someone else has claimed it", :default => false
47
+ end
48
+ def claim project, config, opts, issue
49
+ puts "Claiming issue #{issue.name}: #{issue.title}."
50
+ comment = ask_multiline "Comments" unless $opts[:no_comment]
51
+ issue.claim config.user, comment, opts[:force]
52
+ puts "Issue #{issue.name} marked as claimed by #{config.user}"
53
+ end
54
+
55
+ operation :unclaim, "Unclaim a claimed issue", :issue do
56
+ opt :force, "Unclaim this issue even if it's claimed by someone else", :default => false
57
+ end
58
+ def unclaim project, config, opts, issue
59
+ puts "Unclaiming issue #{issue.name}: #{issue.title}."
60
+ comment = ask_multiline "Comments" unless $opts[:no_comment]
61
+ issue.unclaim config.user, comment, opts[:force]
62
+ puts "Issue #{issue.name} marked as unclaimed."
63
+ end
64
+
65
+ operation :claimed, "Show all issues claimed by you" do
66
+ opt :all, "Show all issues, not just open ones"
67
+ end
68
+ def claimed project, config, opts
69
+ puts "#{opts[:all] ? "All" : "Open"} issues claimed by you:"
70
+ issues = project.issues.select { |i| i.claimer == config.user && (opts[:all] || i.open?) }
71
+ if issues.empty?
72
+ puts "No issues."
73
+ else
74
+ print_todo_list_by_release_for project, issues
75
+ end
76
+ end
77
+
78
+ operation :unclaimed, "Show all unclaimed issues" do
79
+ opt :all, "Show all issues, not just open ones"
80
+ end
81
+ def unclaimed project, config, opts
82
+ puts "Unclaimed#{opts[:all] ? "" : ", open"} issues:"
83
+ issues = project.issues.select { |i| i.claimer.nil? && (opts[:all] || i.open?) }
84
+ if issues.empty?
85
+ puts "No issues."
86
+ else
87
+ print_todo_list_by_release_for project, issues
88
+ end
89
+ end
90
+ end
91
+
92
+ end
data/lib/release.rhtml ADDED
@@ -0,0 +1,69 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
+
4
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
5
+ <head>
6
+ <title><%= project.name %> release <%= release.name %></title>
7
+ <meta http-equiv="Content-Type" content="text/html; charset=utf8" />
8
+ <link rel="stylesheet" href="style.css" type="text/css" />
9
+ </head>
10
+ <body>
11
+
12
+ <div><%= link_to "index", "&laquo; #{project.name} project page" %></div>
13
+
14
+ <h1><%= project.name %> release <%= release.name %></h1>
15
+
16
+ <table>
17
+ <tr>
18
+ <td class="attrname">Status:</td>
19
+ <td class="attrval"><%= release.status %></td>
20
+ </tr>
21
+ <% if release.released? %>
22
+ <tr>
23
+ <td class="attrname">Release time:</td>
24
+ <td class="attrval"><%= release.release_time %></td>
25
+ </tr>
26
+ <% end %>
27
+ <tr>
28
+ <%
29
+ num_done = issues.count_of { |i| i.closed? }
30
+ pct_done = issues.size == 0 ? 100 : (100.0 * num_done / issues.size)
31
+ %>
32
+ <td class="attrname">Completion:</td>
33
+ <td class="attrval"><%= sprintf "%.0f%%", pct_done %></td>
34
+ </tr>
35
+ </table>
36
+
37
+ <h2>Issues</h2>
38
+ <% if issues.empty? %>
39
+ <p>No issues assigned to this release.</p>
40
+ <% else %>
41
+ <%= render "issue_table", :show_component => false, :show_release => false %>
42
+ <% end %>
43
+
44
+ <h2>Release log</h2>
45
+ <table>
46
+ <% release.log_events.each_with_index do |(time, who, what, comment), i| %>
47
+ <% if i % 2 == 0 %>
48
+ <tr class="logentryeven">
49
+ <% else %>
50
+ <tr class="logentryodd">
51
+ <% end %>
52
+ <td class="logtime"><%=h time %></td>
53
+ <td class="logwho"><%=obscured_email who %></td>
54
+ <td class="logwhat"><%=h what %></td>
55
+ </tr>
56
+ <tr><td colspan="3" class="logcomment">
57
+ <% if comment.empty? %>
58
+ <% else %>
59
+ <%= link_issue_names project, p(comment) %>
60
+ <% end %>
61
+ </td></tr>
62
+ <% end %>
63
+ </table>
64
+
65
+ <p class="footer">Generated by <a
66
+ href="http://ditz.rubyforge.org/">ditz</a>.</p>
67
+
68
+ </body>
69
+ </html>
data/lib/style.css ADDED
@@ -0,0 +1,127 @@
1
+ body {
2
+ background: white;
3
+ color: #202020;
4
+ margin-bottom: 2em;
5
+ margin-left: auto;
6
+ margin-right: auto;
7
+ width: 90%;
8
+ }
9
+
10
+ div.wrapper {
11
+ }
12
+
13
+ div.footer {
14
+ }
15
+
16
+ a, a:visited {
17
+ border-bottom: 1px dotted #03c;
18
+ background: inherit;
19
+ text-decoration: none;
20
+ color: #03c;
21
+ }
22
+
23
+ ul {
24
+ list-style-type: none;
25
+ padding: 0;
26
+ }
27
+
28
+ p {
29
+ width: 40em;
30
+ }
31
+
32
+ .dimmed {
33
+ color: #bbb;
34
+ }
35
+
36
+ div.on-the-left {
37
+ float: left;
38
+ width: 39%;
39
+ }
40
+
41
+ div.on-the-right {
42
+ float: right;
43
+ width: 59%;
44
+ }
45
+
46
+ table {
47
+ border-style: none;
48
+ border-spacing: 0;
49
+ }
50
+
51
+ td {
52
+ border-width: 0;
53
+ border-style: none;
54
+ padding-right: 0.5em;
55
+ padding-left: 0.5em;
56
+ }
57
+
58
+ tr {
59
+ padding-bottom: 5em;
60
+ }
61
+
62
+ h1 {
63
+ padding: 0.2em;
64
+ margin-left: -1em;
65
+ margin-right: 1em;
66
+ background: #abc;
67
+ }
68
+
69
+ .attrname {
70
+ text-align: right;
71
+ }
72
+
73
+ .issuestatus_closed {
74
+ background-color: #afa;
75
+ text-align: center;
76
+ }
77
+
78
+ .issuestatus_in_progress {
79
+ background-color: #ffa;
80
+ text-align: center;
81
+ }
82
+
83
+ .issuestatus_paused {
84
+ background-color: #ffa;
85
+ text-align: center;
86
+ }
87
+
88
+ .issuestatus_unstarted {
89
+ background-color: #faa;
90
+ text-align: center;
91
+ }
92
+
93
+ .issuestatus_closed a {
94
+ color: #202020;
95
+ }
96
+
97
+ .issuestatus_in_progress a {
98
+ color: #202020;
99
+ }
100
+
101
+ .issuestatus_paused a {
102
+ color: #202020;
103
+ }
104
+
105
+ .issuestatus_unstarted a {
106
+ color: #202020;
107
+ }
108
+
109
+ .logwhat {
110
+ }
111
+
112
+ .logentryeven {
113
+ background: #eee;
114
+ }
115
+
116
+ .logentryodd {
117
+ background: #eee;
118
+ }
119
+
120
+ .logcomment {
121
+ padding-left: 3em;
122
+ }
123
+
124
+ p.footer {
125
+ font-size: small;
126
+ }
127
+