ursm-ditz 0.4
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/Changelog +35 -0
- data/README.txt +127 -0
- data/Rakefile +33 -0
- data/ReleaseNotes +50 -0
- data/bin/ditz +213 -0
- data/contrib/completion/_ditz.zsh +29 -0
- data/contrib/completion/ditz.bash +22 -0
- data/lib/component.rhtml +22 -0
- data/lib/ditz.rb +56 -0
- data/lib/hook.rb +67 -0
- data/lib/html.rb +69 -0
- data/lib/index.rhtml +113 -0
- data/lib/issue.rhtml +111 -0
- data/lib/issue_table.rhtml +33 -0
- data/lib/lowline.rb +202 -0
- data/lib/model-objects.rb +314 -0
- data/lib/model.rb +208 -0
- data/lib/operator.rb +549 -0
- data/lib/plugins/git.rb +114 -0
- data/lib/plugins/issue-claiming.rb +92 -0
- data/lib/release.rhtml +69 -0
- data/lib/style.css +127 -0
- data/lib/trollop.rb +518 -0
- data/lib/unassigned.rhtml +31 -0
- data/lib/util.rb +57 -0
- data/lib/vendor/yaml_waml.rb +28 -0
- data/lib/view.rb +16 -0
- data/lib/views.rb +136 -0
- data/man/ditz.1 +38 -0
- metadata +90 -0
@@ -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", "« #{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
|
+
|