Remove dependency on `probot-slack-status` package, and improve usability by adding Slack clients to `robot` object

This commit is contained in:
Pedro Pombeiro 2018-02-14 12:37:49 +01:00
parent da5667090c
commit b6090f36a2
No known key found for this signature in database
GPG Key ID: A65DEB11E4BBC647
10 changed files with 115 additions and 691 deletions

View File

@ -6,29 +6,20 @@
// github: "^13.1.0"
// probot-config: "^0.1.0"
// probot-scheduler: "^1.0.3"
// probot-slack-status: "^0.2.2"
//
// Author:
// PombeirP
const createScheduler = require('probot-scheduler')
const getConfig = require('probot-config')
const Slack = require('probot-slack-status')
const defaultConfig = require('../lib/config')
const gitHubHelpers = require('../lib/github-helpers')
const slackHelper = require('../lib/slack')
const botName = 'assign-approved-pr-to-test'
let slackClient = null
module.exports = robot => {
// robot.on('slack.connected', ({ slack }) => {
Slack(robot, (slack) => {
robot.log.trace(`${botName} - Connected, assigned slackClient`)
slackClient = slack
})
createScheduler(robot, { interval: 10 * 60 * 1000 })
robot.on('schedule.repository', context => checkOpenPullRequests(robot, context))
}
@ -198,10 +189,10 @@ async function assignPullRequestToCorrectColumn (github, robot, repo, pullReques
robot.log.info(`${botName} - Moved card ${existingGHCard.id} to ${dstColumn.name} for PR #${prNumber}`)
}
slackHelper.sendMessage(robot, slackClient, room, `Assigned PR to ${dstColumn.name} column\n${pullRequest.html_url}`)
slackHelper.sendMessage(robot, room, `Assigned PR to ${dstColumn.name} column\n${pullRequest.html_url}`)
} catch (err) {
robot.log.error(`${botName} - Couldn't move project card for the PR: ${err}`, srcColumn.id, dstColumn.id, pullRequest.id)
slackHelper.sendMessage(robot, slackClient, room, `I couldn't move the PR to ${dstColumn.name} column :confused:\n${pullRequest.html_url}`)
slackHelper.sendMessage(robot, room, `I couldn't move the PR to ${dstColumn.name} column :confused:\n${pullRequest.html_url}`)
}
} else {
try {

View File

@ -5,7 +5,6 @@
// Dependencies:
// github: "^13.1.0"
// probot-config: "^0.1.0"
// probot-slack-status: "^0.2.2"
//
// Author:
// PombeirP
@ -13,19 +12,11 @@
const defaultConfig = require('../lib/config')
const getConfig = require('probot-config')
const Slack = require('probot-slack-status')
const slackHelper = require('../lib/slack')
const botName = 'assign-new-pr-to-review'
let slackClient = null
module.exports = (robot) => {
// robot.on('slack.connected', ({ slack }) => {
Slack(robot, (slack) => {
robot.log.trace(`${botName} - Connected, assigned slackClient`)
slackClient = slack
})
robot.on('pull_request.opened', async context => {
// Make sure we don't listen to our own messages
if (context.isBot) { return }
@ -106,7 +97,7 @@ async function assignPullRequestToReview (context, robot) {
}
// Send message to Slack
slackHelper.sendMessage(robot, slackClient, config.slack.notification.room, `Assigned PR to ${reviewColumnName} in ${projectBoardName} project\n${payload.pull_request.html_url}`)
slackHelper.sendMessage(robot, config.slack.notification.room, `Assigned PR to ${reviewColumnName} in ${projectBoardName} project\n${payload.pull_request.html_url}`)
} catch (err) {
robot.log.error(`${botName} - Couldn't create project card for the PR: ${err}`, column.id, payload.pull_request.id)
}

View File

@ -5,7 +5,6 @@
// Dependencies:
// github: "^13.1.0"
// probot-config: "^0.1.0"
// probot-slack-status: "^0.2.2"
//
// Author:
// PombeirP
@ -15,18 +14,10 @@ const gitHubHelpers = require('../lib/github-helpers')
const defaultConfig = require('../lib/config')
const getConfig = require('probot-config')
const Slack = require('probot-slack-status')
const botName = 'assign-to-bounty-awaiting-for-approval'
let slackClient = null
module.exports = (robot) => {
// robot.on('slack.connected', ({ slack }) => {
Slack(robot, (slack) => {
robot.log.trace(`${botName} - Connected, assigned slackClient`)
slackClient = slack
})
robot.on('issues.labeled', async context => {
// Make sure we don't listen to our own messages
if (context.isBot) { return }
@ -160,6 +151,6 @@ async function assignIssueToBountyAwaitingForApproval (context, robot, assign) {
if (message && !process.env.DRY_RUN_BOUNTY_APPROVAL) {
// Send message to Slack
slackHelper.sendMessage(robot, slackClient, config.slack.notification.room, message)
slackHelper.sendMessage(robot, config.slack.notification.room, message)
}
}

View File

@ -6,12 +6,10 @@
// github: "^13.1.0"
// hashset: "0.0.6"
// probot-config: "^0.1.0"
// probot-slack-status: "^0.2.2"
//
// Author:
// Max Tyrrell (ImFeelingDucky/mac/yung_mac)
const Slack = require('probot-slack-status')
const getConfig = require('probot-config')
const HashSet = require('hashset')
@ -21,23 +19,19 @@ const slackHelper = require('../lib/slack')
const botName = 'bounty-awaiting-approval-slack-ping'
module.exports = (robot, getSlackMentionFromGitHubId) => {
Slack(robot, (slack) => {
robot.log.trace(`${botName} - Connected to Slack`)
registerForNewBounties(robot, slack, getSlackMentionFromGitHubId)
})
registerForNewBounties(robot, getSlackMentionFromGitHubId)
}
function registerForNewBounties (robot, slackClient, getSlackMentionFromGitHubId) {
function registerForNewBounties (robot, getSlackMentionFromGitHubId) {
robot.on('issues.labeled', async context => {
// Make sure we don't listen to our own messages
if (context.isBot) return null
await notifyCollaborators(context, robot, slackClient, getSlackMentionFromGitHubId)
await notifyCollaborators(context, robot, getSlackMentionFromGitHubId)
})
}
async function notifyCollaborators (context, robot, slackClient, getSlackMentionFromGitHubId) {
async function notifyCollaborators (context, robot, getSlackMentionFromGitHubId) {
const { github, payload } = context
const ownerName = payload.repository.owner.login
const repoName = payload.repository.name
@ -77,7 +71,6 @@ async function notifyCollaborators (context, robot, slackClient, getSlackMention
// Send message to Slack
slackHelper.sendMessage(
robot,
slackClient,
config.slack.notification.room,
`New bounty awaiting approval: ${payload.issue.html_url}
/cc ${slackCollaborators.values().join(', ')}`

View File

@ -5,26 +5,18 @@
// Dependencies:
// github: "^13.1.0"
// probot-config: "^0.1.0"
// probot-slack-status: "^0.2.2"
//
// Author:
// PombeirP
const getConfig = require('probot-config')
const Slack = require('probot-slack-status')
const slackHelper = require('../lib/slack')
const defaultConfig = require('../lib/config')
const botName = 'greet-new-contributor'
let slackClient = null
module.exports = (robot) => {
// robot.on('slack.connected', ({ slack }) => {
Slack(robot, (slack) => {
robot.log.trace(`${botName} - Connected, assigned slackClient`)
slackClient = slack
})
robot.on('pull_request.opened', async context => {
// Make sure we don't listen to our own messages
if (context.isBot) { return }
@ -72,8 +64,7 @@ async function greetNewContributor (context, robot) {
}
// Send message to Slack
const slackHelper = require('../lib/slack')
slackHelper.sendMessage(robot, slackClient, config.slack.notification.room, `Greeted ${payload.pull_request.user.login} on his first PR in the ${repoName} repo\n${payload.pull_request.html_url}`)
slackHelper.sendMessage(robot, config.slack.notification.room, `Greeted ${payload.pull_request.user.login} on his first PR in the ${repoName} repo\n${payload.pull_request.html_url}`)
} catch (err) {
if (err.code !== 404) {
robot.log.error(`${botName} - Couldn't create comment on PR: ${err}`, ownerName, repoName)

View File

@ -9,8 +9,6 @@
const slackHelper = require('../lib/slack')
const { WebClient } = require('@slack/client')
const slackWeb = new WebClient(process.env.SLACK_BOT_TOKEN)
const botName = 'notify-reviewers-via-slack'
module.exports = (robot, getSlackIdFromGitHubId) => {
@ -37,13 +35,13 @@ async function notifyReviewer (context, robot, getSlackIdFromGitHubId) {
return
}
slackWeb.im.open(userID).then(resp => {
robot.slackWeb.im.open(userID).then(resp => {
const dmChannelID = resp.channel.id
const msg = `New Pull Request awaiting your review: ${payload.pull_request.html_url}`
robot.log.info(`${botName} - Opened DM Channel ${dmChannelID}`)
robot.log.info(`Notifying ${userID} about review request in ${payload.pull_request.url}`)
slackWeb.chat.postMessage(dmChannelID, msg, {unfurl_links: true, as_user: slackHelper.BotUserName})
robot.slackWeb.chat.postMessage(dmChannelID, msg, {unfurl_links: true, as_user: slackHelper.BotUserName})
}).catch(error => robot.log.error('Could not open DM channel for review request notification', error))
}

View File

@ -1,10 +1,24 @@
const MemCache = require('mem-cache')
const slackGitHubCache = new MemCache({ timeoutDisabled: true })
const SlackGitHubCacheBuilder = require('./lib/retrieve-slack-github-users')
const Slack = require('./lib/slack')
module.exports = async (robot) => {
console.log('Yay, the app was loaded!')
Slack(robot, slack => {})
await new Promise((resolve, reject) => {
robot.on('slack.connected', event => {
robot.log.info(`Connected to Slack`)
// Copy Slack RTM and Slack Web clients to the robot object
robot['slack'] = event.payload.slack
robot['slackWeb'] = event.payload.slackWeb
resolve()
})
})
const slackCachePromise = SlackGitHubCacheBuilder.build(robot, slackGitHubCache)
require('./bot_scripts/assign-new-pr-to-review')(robot)

View File

@ -1,25 +1,98 @@
// Description:
// Configuration-related functionality
//
// Dependencies:
// probot-slack-status: "^0.2.2"
//
// Author:
// PombeirP
// ISC License
// Copyright (c) 2017, Tom McKenzie <tom@chillidonut.com>
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
const RtmClient = require('@slack/client').RtmClient
const WebClient = require('@slack/client').WebClient
const CLIENT_EVENTS = require('@slack/client').CLIENT_EVENTS
const RTM_EVENTS = require('@slack/client').RTM_EVENTS
const BOT_TOKEN = process.env.SLACK_BOT_TOKEN || ''
module.exports.BotUserName = 'probot'
module.exports.sendMessage = async (robot, slackClient, room, message) => {
module.exports = (robot, connectCallback) => {
if (!BOT_TOKEN) {
robot.log.error('SLACK_BOT_TOKEN missing, skipping Slack integration')
return
}
function emit (payload) {
robot.receive({
event: 'slack',
payload: {
...payload,
installation: {}, // We need to add an 'installation' property, otherwise node_modules/probot/lib/robot.js:100 will throw an exception
slack: SlackAPI,
slackWeb: SlackWebAPI
}
})
}
robot.log.trace('Slack connecting...')
// game start!
const SlackAPI = new RtmClient(BOT_TOKEN)
const SlackWebAPI = new WebClient(BOT_TOKEN)
// The client will emit an RTM.AUTHENTICATED event on successful connection, with the `rtm.start` payload
SlackAPI.on(CLIENT_EVENTS.RTM.AUTHENTICATED, (rtmStartData) => {
robot.log.trace('Slack successfully authenticated')
emit({
action: 'authenticated',
payload: rtmStartData
})
})
// you need to wait for the client to fully connect before you can send messages
SlackAPI.on(CLIENT_EVENTS.RTM.RTM_CONNECTION_OPENED, () => {
robot.log.info('Slack connected')
emit({
action: 'connected'
})
connectCallback(SlackAPI)
})
// bind to all supported events <https://api.slack.com/events>
for (const event in RTM_EVENTS) {
SlackAPI.on(event, (payload) => {
emit({
action: event,
payload
})
})
}
// now connect
SlackAPI.connect('https://slack.com/api/rtm.connect')
}
module.exports.sendMessage = async (robot, room, message) => {
// Send message to Slack
if (slackClient != null) {
if (robot.slack) {
// TODO BOUNTY migrate away from datastore:
// https://github.com/slackapi/node-slack-sdk/wiki/DataStore-v3.x-Migration-Guide
const channel = slackClient.dataStore.getChannelByName(room)
const channel = robot.slack.dataStore.getChannelByName(room)
try {
if (process.env.DRY_RUN) {
robot.log.debug(`Would have sent '${message}' to '${room}' channel`)
} else {
await slackClient.sendMessage(message, channel.id)
await robot.slack.sendMessage(message, channel.id)
}
} catch (err) {
robot.log.error(`Failed to send Slack message to '${room}' channel`)

624
package-lock.json generated
View File

@ -16,9 +16,9 @@
}
},
"@slack/client": {
"version": "3.15.0",
"resolved": "https://registry.npmjs.org/@slack/client/-/client-3.15.0.tgz",
"integrity": "sha512-MIgf5s9PrcxFaPlkJ2cFOhrfh9/KOmUKK5GG/Eka1IJK7+oBCscJFnQ6FfYnZICwIQxWkkuiXmeWYWNevZhCLg==",
"version": "3.16.0",
"resolved": "https://registry.npmjs.org/@slack/client/-/client-3.16.0.tgz",
"integrity": "sha512-CWr7a3rTVrN5Vs8GYReRAvTourbXHOqB1zglcskj05ICH4GZL5BOAza2ARai+qc3Nz0nY08Bozi1x0014KOqlg==",
"requires": {
"async": "1.5.2",
"bluebird": "3.5.1",
@ -5211,624 +5211,6 @@
"bottleneck": "1.16.0"
}
},
"probot-slack-status": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/probot-slack-status/-/probot-slack-status-0.2.2.tgz",
"integrity": "sha512-4Fh5Oq9FhhUMJ/52gBCnUYImnI4tHi/8o8o6uskN27AQnDThg6Cv5ZEgcpt0YAUTF4rfCRNGMRjw7y+09+pKsA==",
"requires": {
"@slack/client": "3.15.0",
"probot": "3.0.3"
},
"dependencies": {
"acorn": {
"version": "4.0.13",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
"integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c="
},
"acorn-globals": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz",
"integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=",
"requires": {
"acorn": "4.0.13"
}
},
"agent-base": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz",
"integrity": "sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=",
"requires": {
"extend": "3.0.1",
"semver": "5.0.3"
},
"dependencies": {
"semver": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz",
"integrity": "sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no="
}
}
},
"ansi-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
},
"babel-jest": {
"version": "21.2.0",
"resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-21.2.0.tgz",
"integrity": "sha512-O0W2qLoWu1QOoOGgxiR2JID4O6WSpxPiQanrkyi9SSlM0PJ60Ptzlck47lhtnr9YZO3zYOsxHwnyeWJ6AffoBQ==",
"requires": {
"babel-plugin-istanbul": "4.1.5",
"babel-preset-jest": "21.2.0"
}
},
"babel-plugin-jest-hoist": {
"version": "21.2.0",
"resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-21.2.0.tgz",
"integrity": "sha512-yi5QuiVyyvhBUDLP4ButAnhYzkdrUwWDtvUJv71hjH3fclhnZg4HkDeqaitcR2dZZx/E67kGkRcPVjtVu+SJfQ=="
},
"babel-preset-jest": {
"version": "21.2.0",
"resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-21.2.0.tgz",
"integrity": "sha512-hm9cBnr2h3J7yXoTtAVV0zg+3vg0Q/gT2GYuzlreTU0EPkJRtlNgKJJ3tBKEn0+VjAi3JykV6xCJkuUYttEEfA==",
"requires": {
"babel-plugin-jest-hoist": "21.2.0",
"babel-plugin-syntax-object-rest-spread": "6.13.0"
}
},
"camelcase": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
"integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0="
},
"cliui": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
"integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
"requires": {
"string-width": "1.0.2",
"strip-ansi": "3.0.1",
"wrap-ansi": "2.1.0"
},
"dependencies": {
"ansi-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
},
"string-width": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"requires": {
"code-point-at": "1.1.0",
"is-fullwidth-code-point": "1.0.0",
"strip-ansi": "3.0.1"
}
},
"strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"requires": {
"ansi-regex": "2.1.1"
}
}
}
},
"expect": {
"version": "21.2.1",
"resolved": "https://registry.npmjs.org/expect/-/expect-21.2.1.tgz",
"integrity": "sha512-orfQQqFRTX0jH7znRIGi8ZMR8kTNpXklTTz8+HGTpmTKZo3Occ6JNB5FXMb8cRuiiC/GyDqsr30zUa66ACYlYw==",
"requires": {
"ansi-styles": "3.2.0",
"jest-diff": "21.2.1",
"jest-get-type": "21.2.0",
"jest-matcher-utils": "21.2.1",
"jest-message-util": "21.2.1",
"jest-regex-util": "21.2.0"
}
},
"follow-redirects": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-0.0.7.tgz",
"integrity": "sha1-NLkLqyqRGqNHVx2pDyK9NuzYqRk=",
"requires": {
"debug": "2.6.9",
"stream-consume": "0.1.0"
}
},
"github": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/github/-/github-10.1.0.tgz",
"integrity": "sha512-9id0pjUTIkmOrcGcIgLhpZZjIsXUTRzDpQUR5hqvtIwPC93Eq6/4DfWc8iqp0/E73lr7zp38+5TOddcPvuaDKw==",
"requires": {
"follow-redirects": "0.0.7",
"https-proxy-agent": "1.0.0",
"mime": "1.4.1",
"netrc": "0.1.4"
}
},
"github-webhook-handler": {
"version": "github:rvagg/github-webhook-handler#7cfcb5b724a7735f132778cf15245cac8547ff60",
"requires": {
"bl": "1.1.2",
"buffer-equal-constant-time": "1.0.1"
}
},
"glob": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
"requires": {
"fs.realpath": "1.0.0",
"inflight": "1.0.6",
"inherits": "2.0.3",
"minimatch": "3.0.4",
"once": "1.4.0",
"path-is-absolute": "1.0.1"
}
},
"https-proxy-agent": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz",
"integrity": "sha1-NffabEjOTdv6JkiRrFk+5f+GceY=",
"requires": {
"agent-base": "2.1.1",
"debug": "2.6.9",
"extend": "3.0.1"
}
},
"jest": {
"version": "21.2.1",
"resolved": "https://registry.npmjs.org/jest/-/jest-21.2.1.tgz",
"integrity": "sha512-mXN0ppPvWYoIcC+R+ctKxAJ28xkt/Z5Js875padm4GbgUn6baeR5N4Ng6LjatIRpUQDZVJABT7Y4gucFjPryfw==",
"requires": {
"jest-cli": "21.2.1"
},
"dependencies": {
"jest-cli": {
"version": "21.2.1",
"resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-21.2.1.tgz",
"integrity": "sha512-T1BzrbFxDIW/LLYQqVfo94y/hhaj1NzVQkZgBumAC+sxbjMROI7VkihOdxNR758iYbQykL2ZOWUBurFgkQrzdg==",
"requires": {
"ansi-escapes": "3.0.0",
"chalk": "2.3.0",
"glob": "7.1.2",
"graceful-fs": "4.1.11",
"is-ci": "1.1.0",
"istanbul-api": "1.2.1",
"istanbul-lib-coverage": "1.1.1",
"istanbul-lib-instrument": "1.9.1",
"istanbul-lib-source-maps": "1.2.2",
"jest-changed-files": "21.2.0",
"jest-config": "21.2.1",
"jest-environment-jsdom": "21.2.1",
"jest-haste-map": "21.2.0",
"jest-message-util": "21.2.1",
"jest-regex-util": "21.2.0",
"jest-resolve-dependencies": "21.2.0",
"jest-runner": "21.2.1",
"jest-runtime": "21.2.1",
"jest-snapshot": "21.2.1",
"jest-util": "21.2.1",
"micromatch": "2.3.11",
"node-notifier": "5.2.1",
"pify": "3.0.0",
"slash": "1.0.0",
"string-length": "2.0.0",
"strip-ansi": "4.0.0",
"which": "1.3.0",
"worker-farm": "1.5.2",
"yargs": "9.0.1"
}
}
}
},
"jest-changed-files": {
"version": "21.2.0",
"resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-21.2.0.tgz",
"integrity": "sha512-+lCNP1IZLwN1NOIvBcV5zEL6GENK6TXrDj4UxWIeLvIsIDa+gf6J7hkqsW2qVVt/wvH65rVvcPwqXdps5eclTQ==",
"requires": {
"throat": "4.1.0"
}
},
"jest-config": {
"version": "21.2.1",
"resolved": "https://registry.npmjs.org/jest-config/-/jest-config-21.2.1.tgz",
"integrity": "sha512-fJru5HtlD/5l2o25eY9xT0doK3t2dlglrqoGpbktduyoI0T5CwuB++2YfoNZCrgZipTwPuAGonYv0q7+8yDc/A==",
"requires": {
"chalk": "2.3.0",
"glob": "7.1.2",
"jest-environment-jsdom": "21.2.1",
"jest-environment-node": "21.2.1",
"jest-get-type": "21.2.0",
"jest-jasmine2": "21.2.1",
"jest-regex-util": "21.2.0",
"jest-resolve": "21.2.0",
"jest-util": "21.2.1",
"jest-validate": "21.2.1",
"pretty-format": "21.2.1"
}
},
"jest-diff": {
"version": "21.2.1",
"resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-21.2.1.tgz",
"integrity": "sha512-E5fu6r7PvvPr5qAWE1RaUwIh/k6Zx/3OOkZ4rk5dBJkEWRrUuSgbMt2EO8IUTPTd6DOqU3LW6uTIwX5FRvXoFA==",
"requires": {
"chalk": "2.3.0",
"diff": "3.4.0",
"jest-get-type": "21.2.0",
"pretty-format": "21.2.1"
}
},
"jest-docblock": {
"version": "21.2.0",
"resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz",
"integrity": "sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw=="
},
"jest-environment-jsdom": {
"version": "21.2.1",
"resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-21.2.1.tgz",
"integrity": "sha512-mecaeNh0eWmzNrUNMWARysc0E9R96UPBamNiOCYL28k7mksb1d0q6DD38WKP7ABffjnXyUWJPVaWRgUOivwXwg==",
"requires": {
"jest-mock": "21.2.0",
"jest-util": "21.2.1",
"jsdom": "9.12.0"
}
},
"jest-environment-node": {
"version": "21.2.1",
"resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-21.2.1.tgz",
"integrity": "sha512-R211867wx9mVBVHzrjGRGTy5cd05K7eqzQl/WyZixR/VkJ4FayS8qkKXZyYnwZi6Rxo6WEV81cDbiUx/GfuLNw==",
"requires": {
"jest-mock": "21.2.0",
"jest-util": "21.2.1"
}
},
"jest-get-type": {
"version": "21.2.0",
"resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-21.2.0.tgz",
"integrity": "sha512-y2fFw3C+D0yjNSDp7ab1kcd6NUYfy3waPTlD8yWkAtiocJdBRQqNoRqVfMNxgj+IjT0V5cBIHJO0z9vuSSZ43Q=="
},
"jest-haste-map": {
"version": "21.2.0",
"resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-21.2.0.tgz",
"integrity": "sha512-5LhsY/loPH7wwOFRMs+PT4aIAORJ2qwgbpMFlbWbxfN0bk3ZCwxJ530vrbSiTstMkYLao6JwBkLhCJ5XbY7ZHw==",
"requires": {
"fb-watchman": "2.0.0",
"graceful-fs": "4.1.11",
"jest-docblock": "21.2.0",
"micromatch": "2.3.11",
"sane": "2.3.0",
"worker-farm": "1.5.2"
}
},
"jest-jasmine2": {
"version": "21.2.1",
"resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-21.2.1.tgz",
"integrity": "sha512-lw8FXXIEekD+jYNlStfgNsUHpfMWhWWCgHV7n0B7mA/vendH7vBFs8xybjQsDzJSduptBZJHqQX9SMssya9+3A==",
"requires": {
"chalk": "2.3.0",
"expect": "21.2.1",
"graceful-fs": "4.1.11",
"jest-diff": "21.2.1",
"jest-matcher-utils": "21.2.1",
"jest-message-util": "21.2.1",
"jest-snapshot": "21.2.1",
"p-cancelable": "0.3.0"
}
},
"jest-matcher-utils": {
"version": "21.2.1",
"resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-21.2.1.tgz",
"integrity": "sha512-kn56My+sekD43dwQPrXBl9Zn9tAqwoy25xxe7/iY4u+mG8P3ALj5IK7MLHZ4Mi3xW7uWVCjGY8cm4PqgbsqMCg==",
"requires": {
"chalk": "2.3.0",
"jest-get-type": "21.2.0",
"pretty-format": "21.2.1"
}
},
"jest-message-util": {
"version": "21.2.1",
"resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-21.2.1.tgz",
"integrity": "sha512-EbC1X2n0t9IdeMECJn2BOg7buOGivCvVNjqKMXTzQOu7uIfLml+keUfCALDh8o4rbtndIeyGU8/BKfoTr/LVDQ==",
"requires": {
"chalk": "2.3.0",
"micromatch": "2.3.11",
"slash": "1.0.0"
}
},
"jest-mock": {
"version": "21.2.0",
"resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-21.2.0.tgz",
"integrity": "sha512-aZDfyVf0LEoABWiY6N0d+O963dUQSyUa4qgzurHR3TBDPen0YxKCJ6l2i7lQGh1tVdsuvdrCZ4qPj+A7PievCw=="
},
"jest-regex-util": {
"version": "21.2.0",
"resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-21.2.0.tgz",
"integrity": "sha512-BKQ1F83EQy0d9Jen/mcVX7D+lUt2tthhK/2gDWRgLDJRNOdRgSp1iVqFxP8EN1ARuypvDflRfPzYT8fQnoBQFQ=="
},
"jest-resolve": {
"version": "21.2.0",
"resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-21.2.0.tgz",
"integrity": "sha512-vefQ/Lr+VdNvHUZFQXWtOqHX3HEdOc2MtSahBO89qXywEbUxGPB9ZLP9+BHinkxb60UT2Q/tTDOS6rYc6Mwigw==",
"requires": {
"browser-resolve": "1.11.2",
"chalk": "2.3.0",
"is-builtin-module": "1.0.0"
}
},
"jest-resolve-dependencies": {
"version": "21.2.0",
"resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-21.2.0.tgz",
"integrity": "sha512-ok8ybRFU5ScaAcfufIQrCbdNJSRZ85mkxJ1EhUp8Bhav1W1/jv/rl1Q6QoVQHObNxmKnbHVKrfLZbCbOsXQ+bQ==",
"requires": {
"jest-regex-util": "21.2.0"
}
},
"jest-runner": {
"version": "21.2.1",
"resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-21.2.1.tgz",
"integrity": "sha512-Anb72BOQlHqF/zETqZ2K20dbYsnqW/nZO7jV8BYENl+3c44JhMrA8zd1lt52+N7ErnsQMd2HHKiVwN9GYSXmrg==",
"requires": {
"jest-config": "21.2.1",
"jest-docblock": "21.2.0",
"jest-haste-map": "21.2.0",
"jest-jasmine2": "21.2.1",
"jest-message-util": "21.2.1",
"jest-runtime": "21.2.1",
"jest-util": "21.2.1",
"pify": "3.0.0",
"throat": "4.1.0",
"worker-farm": "1.5.2"
}
},
"jest-runtime": {
"version": "21.2.1",
"resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-21.2.1.tgz",
"integrity": "sha512-6omlpA3+NSE+rHwD0PQjNEjZeb2z+oRmuehMfM1tWQVum+E0WV3pFt26Am0DUfQkkPyTABvxITRjCUclYgSOsA==",
"requires": {
"babel-core": "6.26.0",
"babel-jest": "21.2.0",
"babel-plugin-istanbul": "4.1.5",
"chalk": "2.3.0",
"convert-source-map": "1.5.1",
"graceful-fs": "4.1.11",
"jest-config": "21.2.1",
"jest-haste-map": "21.2.0",
"jest-regex-util": "21.2.0",
"jest-resolve": "21.2.0",
"jest-util": "21.2.1",
"json-stable-stringify": "1.0.1",
"micromatch": "2.3.11",
"slash": "1.0.0",
"strip-bom": "3.0.0",
"write-file-atomic": "2.3.0",
"yargs": "9.0.1"
}
},
"jest-snapshot": {
"version": "21.2.1",
"resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-21.2.1.tgz",
"integrity": "sha512-bpaeBnDpdqaRTzN8tWg0DqOTo2DvD3StOemxn67CUd1p1Po+BUpvePAp44jdJ7Pxcjfg+42o4NHw1SxdCA2rvg==",
"requires": {
"chalk": "2.3.0",
"jest-diff": "21.2.1",
"jest-matcher-utils": "21.2.1",
"mkdirp": "0.5.1",
"natural-compare": "1.4.0",
"pretty-format": "21.2.1"
}
},
"jest-util": {
"version": "21.2.1",
"resolved": "https://registry.npmjs.org/jest-util/-/jest-util-21.2.1.tgz",
"integrity": "sha512-r20W91rmHY3fnCoO7aOAlyfC51x2yeV3xF+prGsJAUsYhKeV670ZB8NO88Lwm7ASu8SdH0S+U+eFf498kjhA4g==",
"requires": {
"callsites": "2.0.0",
"chalk": "2.3.0",
"graceful-fs": "4.1.11",
"jest-message-util": "21.2.1",
"jest-mock": "21.2.0",
"jest-validate": "21.2.1",
"mkdirp": "0.5.1"
}
},
"jest-validate": {
"version": "21.2.1",
"resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-21.2.1.tgz",
"integrity": "sha512-k4HLI1rZQjlU+EC682RlQ6oZvLrE5SCh3brseQc24vbZTxzT/k/3urar5QMCVgjadmSO7lECeGdc6YxnM3yEGg==",
"requires": {
"chalk": "2.3.0",
"jest-get-type": "21.2.0",
"leven": "2.1.0",
"pretty-format": "21.2.1"
}
},
"jsdom": {
"version": "9.12.0",
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-9.12.0.tgz",
"integrity": "sha1-6MVG//ywbADUgzyoRBD+1/igl9Q=",
"requires": {
"abab": "1.0.4",
"acorn": "4.0.13",
"acorn-globals": "3.1.0",
"array-equal": "1.0.0",
"content-type-parser": "1.0.2",
"cssom": "0.3.2",
"cssstyle": "0.2.37",
"escodegen": "1.9.0",
"html-encoding-sniffer": "1.0.2",
"nwmatcher": "1.4.3",
"parse5": "1.5.1",
"request": "2.83.0",
"sax": "1.2.4",
"symbol-tree": "3.2.2",
"tough-cookie": "2.3.3",
"webidl-conversions": "4.0.2",
"whatwg-encoding": "1.0.3",
"whatwg-url": "4.8.0",
"xml-name-validator": "2.0.1"
}
},
"load-json-file": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
"integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
"requires": {
"graceful-fs": "4.1.11",
"parse-json": "2.2.0",
"pify": "2.3.0",
"strip-bom": "3.0.0"
},
"dependencies": {
"pify": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
}
}
},
"parse-json": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
"integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
"requires": {
"error-ex": "1.3.1"
}
},
"parse5": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz",
"integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ="
},
"path-type": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
"integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=",
"requires": {
"pify": "2.3.0"
},
"dependencies": {
"pify": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
}
}
},
"pretty-format": {
"version": "21.2.1",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-21.2.1.tgz",
"integrity": "sha512-ZdWPGYAnYfcVP8yKA3zFjCn8s4/17TeYH28MXuC8vTp0o21eXjbFGcOAXZEaDaOFJjc3h2qa7HQNHNshhvoh2A==",
"requires": {
"ansi-regex": "3.0.0",
"ansi-styles": "3.2.0"
}
},
"probot": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/probot/-/probot-3.0.3.tgz",
"integrity": "sha512-MyndKMS7nuzuC7xj9eaKyC484LahF6QrKsq+edBB3FYd29MjGcs+nj3JYsBlfqGAyTwAvccfdOFk1VtAijhK0A==",
"requires": {
"bottleneck": "1.16.0",
"bunyan": "1.8.12",
"bunyan-format": "0.2.1",
"bunyan-sentry-stream": "1.2.1",
"cache-manager": "2.6.0",
"commander": "2.13.0",
"dotenv": "4.0.0",
"ejs": "2.5.7",
"express": "4.16.2",
"github": "10.1.0",
"github-webhook-handler": "github:rvagg/github-webhook-handler#7cfcb5b724a7735f132778cf15245cac8547ff60",
"jest": "21.2.1",
"js-yaml": "3.10.0",
"jsonwebtoken": "8.1.0",
"pkg-conf": "2.1.0",
"promise-events": "0.1.4",
"raven": "2.3.0",
"resolve": "1.5.0",
"semver": "5.5.0"
}
},
"read-pkg": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
"integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=",
"requires": {
"load-json-file": "2.0.0",
"normalize-package-data": "2.4.0",
"path-type": "2.0.0"
}
},
"read-pkg-up": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz",
"integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=",
"requires": {
"find-up": "2.1.0",
"read-pkg": "2.0.0"
}
},
"tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
},
"whatwg-url": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-4.8.0.tgz",
"integrity": "sha1-0pgaqRSMHgCkHFphMRZqtGg7vMA=",
"requires": {
"tr46": "0.0.3",
"webidl-conversions": "3.0.1"
},
"dependencies": {
"webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
}
}
},
"xml-name-validator": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz",
"integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU="
},
"yargs": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-9.0.1.tgz",
"integrity": "sha1-UqzCP+7Kw0BCB47njAwAf1CF20w=",
"requires": {
"camelcase": "4.1.0",
"cliui": "3.2.0",
"decamelize": "1.2.0",
"get-caller-file": "1.0.2",
"os-locale": "2.1.0",
"read-pkg-up": "2.0.0",
"require-directory": "2.1.1",
"require-main-filename": "1.0.1",
"set-blocking": "2.0.0",
"string-width": "2.1.1",
"which-module": "2.0.0",
"y18n": "3.2.1",
"yargs-parser": "7.0.0"
}
},
"yargs-parser": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz",
"integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=",
"requires": {
"camelcase": "4.1.0"
}
}
}
},
"process-nextick-args": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",

View File

@ -10,6 +10,7 @@
"test": "jest && standard"
},
"dependencies": {
"@slack/client": "^3.16.0",
"eslint": "^4.17.0",
"hashmap": "^2.3.0",
"hashset": "0.0.6",
@ -19,7 +20,6 @@
"probot-config": "^0.1.0",
"probot-gpg-status": "^0.5.4",
"probot-scheduler": "^1.0.3",
"probot-slack-status": "^0.2.2",
"unfurl": "github:probot/unfurl",
"wip-bot": "github:gr2m/wip-bot"
},