File: issue-claiming.rb

package info (click to toggle)
ditz 0.5-1
  • links: PTS
  • area: main
  • in suites: squeeze, wheezy
  • size: 356 kB
  • ctags: 489
  • sloc: ruby: 3,664; sh: 15; makefile: 12
file content (174 lines) | stat: -rw-r--r-- 5,287 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
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
172
173
174
## issue-claiming ditz plugin
## 
## This plugin allows people to claim issues. This is useful for avoiding
## duplication of work---you can check to see if someone's claimed an
## issue before starting to work on it, and you can let people know what
## you're working on.
##
## Commands added:
##   ditz claim: claim an issue for yourself
##   ditz unclaim: unclaim a claimed issue
##   ditz mine: show all issues claimed by you
##   ditz claimed: show all claimed issues, by developer
##   ditz unclaimed: show all unclaimed issues
##
## Usage:
##   1. add a line "- issue-claiming" to the .ditz-plugins file in the project
##      root
##   2. use the above commands to abandon

module Ditz
class Issue
  field :claimer, :ask => false

  def claim who, comment, force=false
    raise Error, "already claimed by #{claimer}" if claimer && !force
    log "issue claimed", who, comment
    self.claimer = who
  end

  def unclaim who, comment, force=false
    raise Error, "not claimed" unless claimer
    raise Error, "can only be unclaimed by #{claimer}" unless claimer == who || force
    if claimer == who
      log "issue unclaimed", who, comment
    else
      log "unassigned from #{claimer}", who, comment
    end
    self.claimer = nil
  end

  def claimed?; claimer end
  def unclaimed?; !claimed? end
end

class ScreenView
  add_to_view :issue_summary do |issue, config|
    " Claimed by: #{issue.claimer || 'none'}\n"
  end
end

class HtmlView
  add_to_view :issue_summary do |issue, config|
    next unless issue.claimer
    [<<EOS, { :issue => issue }]
<tr>
  <td class='attrname'>Claimed by:</td>
  <td class='attrval'><%= h(issue.claimer) %></td>
</tr>
EOS
  end
end

class Operator
  alias :__issue_claiming_start :start
  def start project, config, opts, issue
    if issue.claimed? && issue.claimer != config.user
      raise Error, "issue #{issue.name} claimed by #{issue.claimer}"
    else
      __issue_claiming_start project, config, opts, issue
    end
  end

  alias :__issue_claiming_stop :stop
  def stop project, config, opts, issue
    if issue.claimed? && issue.claimer != config.user
      raise Error, "issue #{issue.name} claimed by #{issue.claimer}"
    else
      __issue_claiming_stop project, config, opts, issue
    end
  end

  alias :__issue_claiming_close :close
  def close project, config, opts, issue
    if issue.claimed? && issue.claimer != config.user
      raise Error, "issue #{issue.name} claimed by #{issue.claimer}"
    else
      __issue_claiming_close project, config, opts, issue
    end
  end

  operation :claim, "Claim an issue for yourself", :issue do
    opt :force, "Claim this issue even if someone else has claimed it", :default => false
  end
  def claim project, config, opts, issue
    puts "Claiming issue #{issue.name}: #{issue.title}."
    comment = ask_multiline "Comments" unless $opts[:no_comment]
    issue.claim config.user, comment, opts[:force]
    puts "Issue #{issue.name} marked as claimed by #{config.user}"
  end

  operation :unclaim, "Unclaim a claimed issue", :issue do
    opt :force, "Unclaim this issue even if it's claimed by someone else", :default => false
  end
  def unclaim project, config, opts, issue
    puts "Unclaiming issue #{issue.name}: #{issue.title}."
    comment = ask_multiline "Comments" unless $opts[:no_comment]
    issue.unclaim config.user, comment, opts[:force]
    puts "Issue #{issue.name} marked as unclaimed."
  end

  operation :mine, "Show all issues claimed by you", :maybe_release do
    opt :all, "Show all issues, not just open ones"
  end
  def mine project, config, opts, releases
    releases ||= project.unreleased_releases + [:unassigned]
    releases = [*releases]

    issues = project.issues.select do |i|
      r = project.release_for(i.release) || :unassigned
      releases.member?(r) && i.claimer == config.user && (opts[:all] || i.open?)
    end
    if issues.empty?
      puts "No issues."
    else
      print_todo_list_by_release_for project, issues
    end
  end

  operation :claimed, "Show claimed issues by claimer", :maybe_release do
    opt :all, "Show all issues, not just open ones"
  end
  def claimed project, config, opts, releases
    releases ||= project.unreleased_releases + [:unassigned]
    releases = [*releases]

    issues = project.issues.inject({}) do |h, i|
      r = project.release_for(i.release) || :unassigned
      if i.claimed? && (opts[:all] || i.open?) && releases.member?(r)
        (h[i.claimer] ||= []) << i
      end
      h
    end

    if issues.empty?
      puts "No issues."
    else
      issues.keys.sort.each do |c|
        puts "#{c}:"
        puts todo_list_for(issues[c], :show_release => true)
        puts
      end
    end
  end

  operation :unclaimed, "Show all unclaimed issues", :maybe_release do
    opt :all, "Show all issues, not just open ones"
  end
  def unclaimed project, config, opts, releases
    releases ||= project.unreleased_releases + [:unassigned]
    releases = [*releases]

    issues = project.issues.select do |i|
      r = project.release_for(i.release) || :unassigned
      releases.member?(r) && i.claimer.nil? && (opts[:all] || i.open?)
    end
    if issues.empty?
      puts "No issues."
    else
      print_todo_list_by_release_for project, issues
    end
  end
end

end