Skip to content
This repository
Fetching contributors…

Cannot retrieve contributors at this time

file 95 lines (85 sloc) 3.84 kb
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
# Description:
# Show open issues from a Github repository
#
# Dependencies:
# "underscore": "1.3.3"
# "underscore.string": "2.1.1"
# "githubot": "0.2.0"
#
# Configuration:
# HUBOT_GITHUB_TOKEN
# HUBOT_GITHUB_USER
# HUBOT_GITHUB_REPO
# HUBOT_GITHUB_USER_(.*)
#
# Commands:
# hubot show [me] [<limit> [of]] [<assignee>'s|my] [<label>] issues [for <user/repo>] [about <query>] -- Shows open GitHub issues for repo.
# hubot show [me] issues for <repo> -- List all issues for given repo IFF HUBOT_GITHUB_USER configured
# hubot show [me] issues for <user/repo> -- List all issues for given repo
# hubot show [me] issues -- Lists all issues IFF HUBOT_GITHUB_REPO configured
# hubot show <chat user's> issues -- Lists all issues for chat user IFF HUBOT_GITHUB_USER_(.*) configured
#
# Notes:
# If, for example, HUBOT_GITHUB_USER_JOHN is set to GitHub user login
# 'johndoe1', you can ask `show john's issues` instead of `show johndoe1's
# issues`. This is useful for mapping chat handles to GitHub logins.
#
# Author:
# davidsiegel

_ = require("underscore")
_s = require("underscore.string")

ASK_REGEX = ///
show\s # Start's with 'show'
(me)?\s* # Optional 'me'
(\d+|\d+\sof)?\s* # 'N of' -- 'of' is optional but ambiguous unless assignee is named
(\S+'s|my)?\s* # Assignee's name or 'my'
(\S+)?\s* # Optional label name
issues\s* # 'issues'
(for\s\S+)?\s* # Optional 'for <repo>'
(about\s.+)? # Optional 'about <query>'
///i

# Given the text sent to robot.respond (e.g. 'hubot show me...'), parse the
# criteria used for filtering issues.
parse_criteria = (message) ->
  [me, limit, assignee, label, repo, query] = message.match(ASK_REGEX)[1..]
  me: me,
  limit: parseInt limit.replace(" of", "") if limit?,
  assignee: assignee.replace("'s", "") if assignee?,
  label: label,
  repo: repo.replace("for ", "") if repo?,
  query: query.replace("about ", "") if query?

# Filter the issue list by criteria; most of the filtering is handled as part
# of the Issues API, but limit and query paramaters are not part of the API.
filter_issues = (issues, {limit, query}) ->
  if query?
    issues = _.filter issues, (i) -> _.any [i.body, i.title], (s) -> _s.include s.toLowerCase(), query.toLowerCase()
  if limit?
    issues = _.first issues, limit
  issues

# Resolve assignee name to a potential GitHub username using sender
# information and/or environment variables.
complete_assignee = (msg, name) ->
  name = msg.message.user.name if name is "my"
  name = name.replace("@", "")
  # Try resolving the name to a GitHub username using full, then first name:
  resolve = (n) -> process.env["HUBOT_GITHUB_USER_#{n.replace(/\s/g, '_').toUpperCase()}"]
  resolve(name) or resolve(name.split(' ')[0]) or name

module.exports = (robot) ->
  github = require("githubot")(robot)
  robot.respond ASK_REGEX, (msg) ->
    criteria = parse_criteria msg.message.text
    criteria.repo = github.qualified_repo criteria.repo
    criteria.assignee = complete_assignee msg, criteria.assignee if criteria.assignee?

    query_params = state: "open", sort: "created"
    query_params.labels = criteria.label if criteria.label?
    query_params.assignee = criteria.assignee if criteria.assignee?

    github.get "https://api.github.com/repos/#{criteria.repo}/issues", query_params, (issues) ->
      issues = filter_issues issues, criteria

      if _.isEmpty issues
          msg.send "No issues found."
      else
        for issue in issues
          labels = ("##{label.name}" for label in issue.labels).join(" ")
          assignee = if issue.assignee then " (#{issue.assignee.login})" else ""
          msg.send "[#{issue.number}] #{issue.title} #{labels}#{assignee} = #{issue.html_url}"

# require('../../test/scripts/github-issues_test').test parse_criteria
Something went wrong with that request. Please try again.