diff --git a/index.js b/index.js index 210c3e7..46ad80d 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,5 @@ const { handleNewPitch, handleNewScope, getProjectNodeItem } = require('./lib/onboarding') -const { parseIssueDescription, addScopeToBet } = require('./lib/scopes') +const { parseIssueDescription, addScopeToBet, handleScopeCommand } = require('./lib/scopes') const { handleProgress } = require('./lib/progress') const ITEM_ISSUE_TYPE = "Issue" @@ -45,5 +45,6 @@ module.exports = (app) => { const owner = context.payload.repository.owner.login const repo = context.payload.repository.name await handleProgress(context, owner, repo, issueNumber) + await handleScopeCommand(context) }) }; diff --git a/lib/progress.js b/lib/progress.js index c045491..0e40af9 100644 --- a/lib/progress.js +++ b/lib/progress.js @@ -41,7 +41,7 @@ function _getStatus(comment = '') { const matches = comment.match(/^\/progress[\s]+[\d\n]+(.*)/s) if (matches && matches.length === 2) return matches[1] return null - } +} exports.handleProgress = handleProgress \ No newline at end of file diff --git a/lib/scopes.js b/lib/scopes.js index f3cedff..64d03c7 100644 --- a/lib/scopes.js +++ b/lib/scopes.js @@ -1,4 +1,5 @@ const { trackedIssuesQuery, updateIssueMutation } = require('./queries') +const { minimizeComment } = require('./comments') const parseIssueDescription = async(context) => { let resultMatch = null @@ -61,6 +62,53 @@ const addScopeToBet = async(context, description) => { } } +const handleScopeCommand = async(context) => { + const comment = context.payload.comment + const issueNodeId = context.payload.issue.node_id + const body = context.payload.issue.body + const regex = /###?\sScope([^-]+)((-\s+\[[\sX|x]\]\s*#?.+\s*)+)/ + const match = body.match(regex) + const commentNodeId = context.payload.comment.node_id + if (!match) { + false + } + const currentScope = match[2].trim() + + if (comment.body.includes('/scope') && !comment.user.login.endsWith('[bot]')) { + const parseCommand = _parseScopeCommand(context, comment.body) + if (!parseCommand) { + return false + } + const { operation, scopeTaskNumber, uri, reason} = parseCommand + const newTask = `- [ ] ${uri}` + if (currentScope.includes(newTask) && operation === 'add') { + return false + } + const newScope = `${currentScope}\n${newTask}` + let newBody = body + if (operation === 'add') { + newBody = body.replace(currentScope, newScope) + } else if (operation === 'remove') { + newBody = body.replace(`${newTask}\r\n`, '') + newBody = newBody.replace(`${newTask}\n`, '') + } + const variables = { + input : { + id: issueNodeId, + body: newBody + } + } + try { + await context.octokit.graphql(updateIssueMutation, variables) + await minimizeComment(context, commentNodeId) + return true + } catch (error) { + console.log(`Failed mutation for issue #${issueNodeId}`, error) + return false + } + } +} + const matchLocalIssue = (context, body) => { const regex = /(Related\sto\s+(\S+)?#(\d+))/ const match = regex.exec(body) @@ -97,6 +145,38 @@ const matchRelatedIssue = (context, body) => { return matchLocalIssue(context, body) || matchRemoteIssue(body) } +function _parseScopeCommand(context, comment = '') { + const matches = comment.match(/^\/scope[\s]+(remove|add)[\s]+(?:#([\d]+))?(?:(https:\/\/(?:\S)*github\.com\/([\w,\-,\_]+)\/([\w,\-,\_]+)\/issues\/([\d]+)))?[\d\n\r]*(.*)/s) + console.log(`comment`, comment) + console.log(`matches -> `, JSON.stringify(matches, null, 4)) + if (matches && matches.length === 8) { + if (matches[2]) { + // match local issues + return { + operation: matches[1], + owner: context.payload.repository.owner.login, + repo: context.payload.repository.name, + scopeTaskNumber: matches[2], + reason: matches[7].replace('\r', '').replace('\n', '').trim(), + uri: `#${matches[2]}` + } + } + else { + // match remote issues + return { + operation: matches[1], + owner: matches[4], + repo: matches[5], + scopeTaskNumber: matches[6], + reason: matches[7].replace('\r', '').replace('\n', '').trim(), + uri: matches[3] + } + } + } + return null +} + exports.parseIssueDescription = parseIssueDescription exports.addScopeToBet = addScopeToBet -exports.matchRelatedIssue = matchRelatedIssue \ No newline at end of file +exports.matchRelatedIssue = matchRelatedIssue +exports.handleScopeCommand = handleScopeCommand \ No newline at end of file