UNPKG

14.3 kBtext/coffeescriptView Raw
1# Description:
2# enable communication with Phabricator via Conduit api
3#
4# Dependencies:
5#
6# Configuration:
7# PHABRICATOR_URL
8# PHABRICATOR_API_KEY
9#
10# Commands:
11# hubot phab version - give the version of hubot-phabs loaded
12# hubot phab new <project>[:<template>] <name of the task> - creates a new task
13# hubot phab paste <name of the paste> - creates a new paste
14# hubot phab count <project> - counts how many tasks a project has
15# hubot phab bl <id> - blacklists an id from phabs_hear
16# hubot phab unbl <id> - removes an id from blacklist
17# hubot phab Txx - gives information about task Txx
18# hubot phab Txx + <some comment> - add a comment to task Txx
19# hubot phab Txx in <project-tag> - add a tag to task Txx
20# hubot phab Txx to [project:]<columns> - move task Txx to columns
21# hubot phab Txx is <status> - modifies task Txx status
22# hubot phab Txx is <priority> - modifies task Txx priority
23# hubot phab assign Txx to <user> - assigns task Txx to comeone
24# hubot phab Txx next [<key>] - outputs next checkbox found in task Txx
25# hubot phab Txx prev [<key>] - outputs last checked checkbox found in task Txx
26# hubot phab Txx check [<key>] - update task Txx description by checking a box
27# hubot phab Txx uncheck [<key>] - update task Txx description by unchecking a box
28# hubot phab <user> - checks if user is known or not
29# hubot phab me as <email> - makes caller known with <email>
30# hubot phab <user> = <email> - associates user to email
31# hubot phab search [all] earch terms - searches for terms in tasks ([all] to search non-open)
32# hubot phab [all] <project> search terms - searches terms in project ([all] to search non-open)
33#
34# Author:
35# mose
36
37Phabricator = require '../lib/phabricator'
38moment = require 'moment'
39path = require 'path'
40
41module.exports = (robot) ->
42
43 robot.phab ?= new Phabricator robot, process.env
44 phab = robot.phab
45
46 # hubot phab version - give the version of hubot-phabs loaded
47 robot.respond /ph(?:ab)? version *$/, (msg) ->
48 pkg = require path.join __dirname, '..', 'package.json'
49 msg.send "hubot-phabs module is version #{pkg.version}"
50 msg.finish()
51
52 # hubot phab new <project>[:<template>] <name of the task>
53 robot.respond (
54 /ph(?:ab)? new ([-_a-zA-Z0-9]+)(?::([-_a-zA-Z0-9]+))? ([^=]+)(?: = (.*))? *$/
55 ), (msg) ->
56 data = {
57 project: msg.match[1]
58 template: msg.match[2]
59 title: msg.match[3]
60 description: msg.match[4]
61 user: msg.envelope.user
62 }
63 phab.getPermission(msg.envelope.user, 'phuser')
64 .then ->
65 phab.createTask(data)
66 .then (res) ->
67 phab.recordId res.user, res.id
68 msg.send "Task T#{res.id} created = #{res.url}"
69 .catch (e) ->
70 msg.send e
71 msg.finish()
72
73 # hubot phab paste <name of the paste> - creates a new paste
74 robot.respond /ph(?:ab)? paste (.*)$/, (msg) ->
75 title = msg.match[1]
76 phab.getPermission(msg.envelope.user, 'phuser')
77 .then ->
78 phab.createPaste(msg.envelope.user, title)
79 .then (id) ->
80 url = process.env.PHABRICATOR_URL + "/paste/edit/#{id}"
81 msg.send "Paste P#{id} created = edit on #{url}"
82 .catch (e) ->
83 msg.send e
84 msg.finish()
85
86 # hubot phab count <project> - counts how many tasks a project has
87 robot.respond (/ph(?:ab)? count ([-_a-zA-Z0-9]+) *$/), (msg) ->
88 project = msg.match[1]
89 name = null
90 phab.getProject(project)
91 .then (proj) ->
92 name = proj.data.name
93 phab.listTasks(proj.data.phid)
94 .then (body) ->
95 if Object.keys(body['result']).length is 0
96 msg.send "#{name} has no tasks."
97 else
98 msg.send "#{name} has #{Object.keys(body['result']).length} tasks."
99 .catch (e) ->
100 msg.send e
101 msg.finish()
102
103 # hubot bl <id> - blacklists <id> from auto-resopnses
104 robot.respond /ph(?:ab)? bl ((?:T|F|P|M|B|Q|L|V)(?:[0-9]+)|(?:r[A-Z]+[a-f0-9]{10,}))/, (msg) ->
105 phab.getPermission(msg.envelope.user, 'phuser')
106 .then ->
107 phab.blacklist msg.match[1]
108 msg.send "Ok. #{msg.match[1]} won't react anymore to auto-detection."
109 .catch (e) ->
110 msg.send e
111 msg.finish()
112
113 # hubot bl <id> - blacklists <id> from auto-resopnses
114 robot.respond /ph(?:ab)? unbl ((?:T|F|P|M|B|Q|L|V)(?:[0-9]+)|(?:r[A-Z]+[a-f0-9]{10,}))/, (msg) ->
115 phab.getPermission(msg.envelope.user, 'phuser')
116 .then ->
117 phab.unblacklist msg.match[1]
118 msg.send "Ok. #{msg.match[1]} now will react to auto-detection."
119 .catch (e) ->
120 msg.send e
121 msg.finish()
122
123 # hubot phab Txx - gives information about task Txxx
124 robot.respond /ph(?:ab)?(?: T([0-9]+)| (last))? *$/, (msg) ->
125 what = msg.match[1] or msg.match[2]
126 id = null
127 body = null
128 phab.getId(msg.envelope.user, what)
129 .bind(id)
130 .bind(body)
131 .then (@id) ->
132 phab.getTask(@id)
133 .then (@body) ->
134 phab.getUserByPhid(@body.result.ownerPHID)
135 .then (owner) ->
136 status = @body.result.status
137 priority = @body.result.priority
138 title = @body.result.title
139 phab.recordId msg.envelope.user, @id
140 msg.send "T#{@id} - #{title} (#{status}, #{priority}, owner #{owner})"
141 .catch (e) ->
142 msg.send e
143 msg.finish()
144
145 # hubot phab Txx + <some comment> - add a comment to task Txx
146 robot.respond /ph(?:ab)?(?: T([0-9]+)| (last))? \+ (.+) *$/, (msg) ->
147 what = msg.match[1] or msg.match[2]
148 comment = msg.match[3]
149 id = null
150 phab.getPermission(msg.envelope.user, 'phuser')
151 .then ->
152 phab.getId(msg.envelope.user, what)
153 .then (id) ->
154 phab.addComment(msg.envelope.user, id, comment)
155 .then (id) ->
156 msg.send "Ok. Added comment \"#{comment}\" to T#{id}."
157 .catch (e) ->
158 msg.send e
159 msg.finish()
160
161 # hubot phab Txx <status> - modifies task Txxx status
162 robot.respond new RegExp(
163 "ph(?:ab)?(?: T([0-9]+)| (last))? (?:is )?(#{Object.keys(phab.statuses).join('|')})" +
164 '(?: (?:=|\\+) (.+))? *$'
165 ), (msg) ->
166 what = msg.match[1] or msg.match[2]
167 status = msg.match[3]
168 comment = msg.match[4]
169 phab.getPermission(msg.envelope.user, 'phuser')
170 .then ->
171 phab.getId(msg.envelope.user, what)
172 .then (id) ->
173 phab.doActions(msg.envelope.user, id, "is #{status}", comment)
174 .then (back) ->
175 if back.message? and back.message isnt ''
176 msg.send "Ok, T#{back.id} now has #{back.message}."
177 if back.notices.length > 0
178 for notice in back.notices
179 msg.send notice
180 .catch (e) ->
181 msg.send e
182 msg.finish()
183
184 # hubot phab Txx <priority> - modifies task Txxx priority
185 robot.respond new RegExp(
186 "ph(?:ab)?(?: T([0-9]+)| (last))? (?:is )?(#{Object.keys(phab.priorities).join('|')})" +
187 '(?: (?:=|\\+) (.+))? *$'
188 ), (msg) ->
189 what = msg.match[1] or msg.match[2]
190 priority = msg.match[3]
191 comment = msg.match[4]
192 phab.getPermission(msg.envelope.user, 'phuser')
193 .then ->
194 phab.getId(msg.envelope.user, what)
195 .then (id) ->
196 phab.doActions(msg.envelope.user, id, "is #{priority}", comment)
197 .then (back) ->
198 if back.message? and back.message isnt ''
199 msg.send "Ok, T#{back.id} now has #{back.message}."
200 if back.notices.length > 0
201 for notice in back.notices
202 msg.send notice
203 .catch (e) ->
204 msg.send e
205 msg.finish()
206
207 robot.respond new RegExp(
208 'ph(?:ab)?(?: T([0-9]+)| (last))?((?:' +
209 " is (?:#{Object.keys(phab.priorities).join('|')})|" +
210 " is (?:#{Object.keys(phab.statuses).join('|')})|" +
211 ' on [^ ]+|' +
212 ' for [^ ]+|' +
213 ' to [^ ]+|' +
214 ' sub [^ ]+|' +
215 ' unsub [^ ]+|' +
216 ' in [^ ]+|' +
217 ' not in [^ ]+)*)' +
218 '(?: (?:=|\\+) (.+))? *$'
219 ), (msg) ->
220 what = msg.match[1] or msg.match[2]
221 commands = msg.match[3]
222 comment = msg.match[4]
223 phab.getPermission(msg.envelope.user, 'phuser')
224 .then ->
225 phab.getId(msg.envelope.user, what)
226 .then (id) ->
227 phab.doActions(msg.envelope.user, id, commands, comment)
228 .then (back) ->
229 if back.message? and back.message isnt ''
230 msg.send "Ok, T#{back.id} now has #{back.message}."
231 if back.notices.length > 0
232 for notice in back.notices
233 msg.send notice
234 .catch (e) ->
235 msg.send e
236 msg.finish()
237
238 # hubot phab Txx next [<key>]- outputs the next checkbox in a given task
239 robot.respond /ph(?:ab)?(?: T([0-9]+)| (last))? next(?: (.+))? *$/, (msg) ->
240 what = msg.match[1] or msg.match[2]
241 key = msg.match[3]
242 id = null
243 phab.getPermission(msg.envelope.user, 'phuser')
244 .bind(id)
245 .then ->
246 phab.getId(msg.envelope.user, what)
247 .then (@id) ->
248 phab.nextCheckbox(msg.envelope.user, @id, key)
249 .then (line) ->
250 msg.send "Next on T#{@id} is: #{line}"
251 .catch (e) ->
252 msg.send e
253 msg.finish()
254
255 # hubot phab Txx prev [<key>]- outputs the last checked checkbox in a given task
256 robot.respond /ph(?:ab)?(?: T([0-9]+)| (last))? prev(?:ious)?(?: (.+))? *$/, (msg) ->
257 what = msg.match[1] or msg.match[2]
258 key = msg.match[3]
259 id = null
260 phab.getPermission(msg.envelope.user, 'phuser')
261 .bind(id)
262 .then ->
263 phab.getId(msg.envelope.user, what)
264 .then (@id) ->
265 phab.prevCheckbox(msg.envelope.user, @id, key)
266 .then (line) ->
267 msg.send "Previous on T#{@id} is: #{line}"
268 .catch (e) ->
269 msg.send e
270 msg.finish()
271
272 # hubot phab Txx check [<key>] - update task Txx description by checking a box
273 robot.respond /ph(?:ab)?(?: T([0-9]+)| (last))? check(!)?(?: ([^\+]+))?(?: \+ (.+))? *$/, (msg) ->
274 what = msg.match[1] or msg.match[2]
275 withNext = msg.match[3]
276 key = msg.match[4]
277 comment = msg.match[5]
278 id = null
279 phab.getPermission(msg.envelope.user, 'phuser')
280 .bind(id)
281 .then ->
282 phab.getId(msg.envelope.user, what)
283 .then (@id) ->
284 phab.checkCheckbox(msg.envelope.user, @id, key, withNext, comment)
285 .then (line) ->
286 msg.send "Checked on T#{@id}: #{line[0]}"
287 if line[1]?
288 msg.send "Next on T#{@id}: #{line[1]}"
289 .catch (e) ->
290 msg.send e
291 msg.finish()
292
293 # hubot phab Txx uncheck [<key>] - update task Txx description by unchecking a box
294 robot.respond /ph(?:ab)?(?: T([0-9]+)| (last))? uncheck(!)?(?: ([^\+]+))?(?: \+ (.+))? *$/
295 , (msg) ->
296 what = msg.match[1] or msg.match[2]
297 withNext = msg.match[3]
298 key = msg.match[4]
299 comment = msg.match[5]
300 id = null
301 phab.getPermission(msg.envelope.user, 'phuser')
302 .bind(id)
303 .then ->
304 phab.getId(msg.envelope.user, what)
305 .then (@id) ->
306 phab.uncheckCheckbox(msg.envelope.user, @id, key, withNext, comment)
307 .then (line) ->
308 msg.send "Unchecked on T#{@id}: #{line[0]}"
309 if line[1]?
310 msg.send "Previous on T#{@id}: #{line[1]}"
311 .catch (e) ->
312 msg.send e
313 msg.finish()
314
315 # hubot phab user <user> - checks if user is known or not
316 robot.respond /ph(?:ab)? (?:user|who) ([^ ]*) *$/, (msg) ->
317 assignee = { name: msg.match[1] }
318 phab.getPermission(msg.envelope.user, 'phuser')
319 .then ->
320 phab.getUser(msg.envelope.user, assignee)
321 .then (userPhid) ->
322 msg.send "Hey I know #{assignee.name}, he's #{userPhid}"
323 .catch (e) ->
324 msg.send e
325 msg.finish()
326
327 # hubot phab me as <email> - makes caller known with <email>
328 robot.respond /ph(?:ab)? me as (.*@.*) *$/, (msg) ->
329 email = msg.match[1]
330 phab.getPermission(msg.envelope.user, 'phuser')
331 .then ->
332 msg.envelope.user.email_address = msg.match[1]
333 phab.getUser(msg.envelope.user, msg.envelope.user)
334 .then (userPhid) ->
335 msg.send "Now I know you, you are #{userPhid}"
336 .catch (e) ->
337 msg.send e
338 msg.finish()
339
340 # hubot phab user <user> = <email> - associates user to email
341 robot.respond /ph(?:ab)? user ([^ ]*) *?= *?([^ ]*@.*) *$/, (msg) ->
342 assignee = { name: msg.match[1], email_address: msg.match[2] }
343 phab.getPermission(msg.envelope.user, 'phuser')
344 .then ->
345 phab.getUser(msg.envelope.user, assignee)
346 .then (userPhid) ->
347 msg.send "Now I know #{assignee.name}, he's #{userPhid}"
348 .catch (e) ->
349 msg.send e
350 msg.finish()
351
352 # hubot phab search [all] <project> search terms - searches for terms in project
353 robot.respond /ph(?:ab)? search( all)? (.+)$/, (msg) ->
354 status = if msg.match[1]?
355 undefined
356 else
357 'open'
358 terms = msg.match[2]
359 phab.searchAllTask(terms, status)
360 .then (payload) ->
361 if payload.result.data.length is 0
362 msg.send "There is no task matching '#{terms}'."
363 else
364 for task in payload.result.data
365 msg.send "#{process.env.PHABRICATOR_URL}/T#{task.id} - #{task.fields['name']}" +
366 " (#{task.fields.status.name})"
367 if payload.result.cursor.after?
368 msg.send '... and there is more.'
369 .catch (e) ->
370 msg.send e
371 msg.finish()
372
373 # hubot phab [all] <project> search terms - searches for terms in project
374 robot.respond /ph(?:ab)?( all)? ([^ ]+) (.+)$/, (msg) ->
375 status = if msg.match[1]?
376 undefined
377 else
378 'open'
379 project = msg.match[2]
380 terms = msg.match[3]
381 name = null
382 phab.getProject(project)
383 .then (proj) ->
384 name = proj.data.name
385 phab.searchTask(proj.data.phid, terms, status)
386 .then (payload) ->
387 if payload.result.data.length is 0
388 msg.send "There is no task matching '#{terms}' in project '#{name}'."
389 else
390 for task in payload.result.data
391 msg.send "#{process.env.PHABRICATOR_URL}/T#{task.id} - #{task.fields['name']}" +
392 " (#{task.fields.status.name})"
393 if payload.result.cursor.after?
394 msg.send '... and there is more.'
395 .catch (e) ->
396 msg.send e
397 msg.finish()
398
399 # hubot phid <phid> - returns info about an arbitrary phid
400 robot.respond /phid ([^ ]+) *$/, (msg) ->
401 item = msg.match[1]
402 if /^PHID-/.test item
403 phab.getPHID(item)
404 .then (data) ->
405 msg.send "#{item} is #{data.name} - #{data.uri} (#{data.status})"
406 .catch (e) ->
407 msg.send e
408 msg.finish()
409 else
410 phab.genericInfo(item)
411 .then (body) ->
412 if Object.keys(body.result).length < 1
413 msg.send "#{item} not found."
414 else
415 msg.send "#{item} is #{body.result[item].phid}"
416 .catch (e) ->
417 msg.send e
418 msg.finish()