-
Notifications
You must be signed in to change notification settings - Fork 150
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
528 additions
and
208 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,6 @@ | ||
module.exports = { | ||
extends: ['@tophat', '@tophat/eslint-config/jest'] | ||
extends: ['@tophat', '@tophat/eslint-config/jest'], | ||
rules: { | ||
camelcase: 0 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/* | ||
* Queues all replies, and sends in one message | ||
*/ | ||
class CommentReply { | ||
constructor({ context }) { | ||
this.context = context | ||
this.message = '' | ||
} | ||
|
||
replyingToWho() { | ||
return this.context.payload.comment.user.login | ||
} | ||
|
||
replyingToWhere() { | ||
return this.context.payload.comment.html_url | ||
} | ||
|
||
reply(message) { | ||
this.message = `\n\n${message}` | ||
} | ||
|
||
async send() { | ||
const fromUser = this.replyingToWho() | ||
const body = `@${fromUser} ${this.message}` | ||
const issueComment = this.context.issue({ body }) | ||
return this.context.github.issues.createComment(issueComment) | ||
} | ||
} | ||
|
||
module.exports = CommentReply |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
const { generate: generateContentFile } = require('all-contributors-cli') | ||
|
||
/* | ||
* Fetches, stores, generates, and updates the readme content files for the contributors list | ||
*/ | ||
class ContentFiles { | ||
constructor({ context, repository }) { | ||
this.context = context | ||
this.repository = repository | ||
this.contentFilesByPath = null | ||
} | ||
|
||
async fetch(optionsConfig) { | ||
const options = optionsConfig.get() | ||
if (Array.isArray(options.files)) { | ||
this.contentFilesByPath = this.repository.getMultipleFileContents( | ||
options.files, | ||
) | ||
} else { | ||
this.contentFilesByPath = this.repository.getMultipleFileContents([ | ||
'README.md', | ||
]) | ||
} | ||
} | ||
|
||
async generate(optionsConfig) { | ||
const options = optionsConfig.get() | ||
const newReadmeFileContentsByPath = {} | ||
Object.entires(this.contentFilesByPath).forEach( | ||
([filePath, fileContents]) => { | ||
const newFileContents = generateContentFile( | ||
options, | ||
options.contributors, | ||
fileContents, | ||
) | ||
newReadmeFileContentsByPath[filePath] = newFileContents | ||
}, | ||
) | ||
this.contentFilesByPath = newReadmeFileContentsByPath | ||
} | ||
} | ||
|
||
module.exports = ContentFiles |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
const ALL_CONTRIBUTORS_RC = '.all-contributorsrc' | ||
|
||
const { addContributorWithDetails } = require('all-contributors-cli') | ||
|
||
const { ResourceNotFoundError } = require('../utils/errors') | ||
|
||
class OptionsConfig { | ||
constructor({ context, repository, commentReply }) { | ||
this.context = context | ||
this.repository = repository | ||
this.commentReply = commentReply | ||
this.options = null | ||
} | ||
|
||
async fetch() { | ||
try { | ||
const rawOptionsFileContent = await this.repository.getFileContents( | ||
ALL_CONTRIBUTORS_RC, | ||
) | ||
try { | ||
const optionsConfig = JSON.parse(rawOptionsFileContent) | ||
this.options = optionsConfig | ||
return optionsConfig | ||
} catch (error) { | ||
if (error instanceof SyntaxError) { | ||
this.commentReply.reply( | ||
`This project's configuration file has malformed JSON: ${ALL_CONTRIBUTORS_RC}. Error:: ${ | ||
error.message | ||
}`, | ||
) | ||
this.context.log(error) | ||
error.handled = true | ||
throw error | ||
} | ||
} | ||
} catch (error) { | ||
if (error instanceof ResourceNotFoundError) { | ||
this.commentReply | ||
.reply(`This project is not yet setup for [all-contributors](https://github.com/all-contributors/all-contributors).\n | ||
You will need to first setup [${ | ||
this.repository.repo | ||
}](https://github.com/${this.repository.getFullname()}) using the [all-contributors-cli](https://github.com/all-contributors/all-contributors-cli) tool.`) | ||
error.handled = true | ||
throw error | ||
} | ||
} | ||
} | ||
|
||
get() { | ||
return this.options | ||
} | ||
|
||
getRaw() { | ||
return JSON.stringify(this.options) | ||
} | ||
|
||
getPath() { | ||
return ALL_CONTRIBUTORS_RC | ||
} | ||
|
||
async addContributor({ login, contributions, name, avatar_url, profile }) { | ||
const newContributorsList = await addContributorWithDetails({ | ||
options: this.options, | ||
login, | ||
contributions, | ||
name, | ||
avatar_url, | ||
profile, | ||
}) | ||
const newOptions = { | ||
...this.options, | ||
contributors: newContributorsList, | ||
} | ||
this.options = newOptions | ||
return newOptions | ||
} | ||
} | ||
|
||
module.exports = OptionsConfig |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,189 +1,10 @@ | ||
/* eslint-disable camelcase */ | ||
|
||
const { | ||
addContributorWithDetails, | ||
generate: generateContentFile, | ||
} = require('all-contributors-cli') | ||
|
||
const { Repository, ResourceNotFoundError } = require('./repository') | ||
// const parseComment = require('./parse-comment') | ||
|
||
const GIHUB_BOT_NAME = '@AllContributorsBot' | ||
const ALL_CONTRIBUTORS_RC = '.all-contributorsrc' | ||
|
||
async function createComment({ context, body }) { | ||
const issueComment = context.issue({ body }) | ||
return context.github.issues.createComment(issueComment) | ||
} | ||
|
||
async function getReadmeFileContentsByPath({ repository, files }) { | ||
if (Array.isArray(files)) { | ||
return repository.getMultipleFileContents(files) | ||
} else { | ||
// default 'files' is ['README.md'] | ||
return repository.getMultipleFileContents(['README.md']) | ||
} | ||
} | ||
|
||
async function getUserDetials({ context, username }) { | ||
// TODO: optimzation, if commenting user is the user we're adding we can avoid an api call | ||
// const commentUser = context.payload.comment.user.login | ||
// if (user === commentUser) { | ||
// return { | ||
// name: context.payload.comment.user.name | ||
// avatarUrl: context.payload.comment.avatar_url | ||
// profile: | ||
// } | ||
// } | ||
|
||
const result = await context.github.users.getByUsername({ username }) | ||
const { avatar_url, blog, html_url, name } = result.data | ||
|
||
return { | ||
name: name || username, | ||
avatar_url, | ||
profile: blog || html_url, | ||
} | ||
} | ||
|
||
async function addContributor({ | ||
options, | ||
login, | ||
contributions, | ||
name, | ||
avatar_url, | ||
profile, | ||
}) { | ||
const newContributorsList = await addContributorWithDetails({ | ||
options, | ||
login, | ||
contributions, | ||
name, | ||
avatar_url, | ||
profile, | ||
}) | ||
return { ...options, contributors: newContributorsList } | ||
} | ||
|
||
async function generateContentFiles({ options, readmeFileContentsByPath }) { | ||
const newReadmeFileContentsByPath = {} | ||
Object.entires(readmeFileContentsByPath).forEach( | ||
([filePath, fileContents]) => { | ||
const newFileContents = generateContentFile( | ||
options, | ||
options.contributors, | ||
fileContents, | ||
) | ||
newReadmeFileContentsByPath[filePath] = newFileContents | ||
}, | ||
) | ||
return newReadmeFileContentsByPath | ||
} | ||
|
||
async function processNewIssueComment(context) { | ||
if (context.isBot) { | ||
context.log('From a bot, exiting') | ||
return | ||
} | ||
|
||
const fromUser = context.payload.comment.user.login | ||
const commentBody = context.payload.comment.body | ||
const hasMentionedBotName = commentBody.includes(GIHUB_BOT_NAME) | ||
|
||
if (!hasMentionedBotName) { | ||
context.log('Message not for us, exiting') | ||
return | ||
} | ||
|
||
const repository = new Repository(context) | ||
|
||
let optionsFileContent | ||
try { | ||
const rawOptionsFileContent = await repository.getFileContents( | ||
ALL_CONTRIBUTORS_RC, | ||
) | ||
optionsFileContent = JSON.parse(rawOptionsFileContent) | ||
// TODO: if JSON has error report that | ||
} catch (error) { | ||
if (error instanceof ResourceNotFoundError) { | ||
await createComment({ | ||
context, | ||
body: `@${fromUser} This project is not yet setup for [all-contributors](https://github.com/all-contributors/all-contributors).\n | ||
You will need to first setup [${ | ||
repository.repo | ||
}](https://github.com/${repository.getFullname()}) using the [all-contributors-cli](https://github.com/all-contributors/all-contributors-cli) tool.`, | ||
}) | ||
context.log(error) | ||
return | ||
} | ||
} | ||
context.log('Options Content') | ||
context.log(optionsFileContent) | ||
|
||
// TODO parse comment and gain intentions | ||
// const { who, contributions } = parseComment(commentBody) | ||
// We had trouble reading your comment. Basic usage:\n\n\`@${GIHUB_BOT_NAME} please add jakebolam for code\` | ||
const who = 'jakebolam' | ||
const contributions = ['code'] | ||
|
||
const { name, avatar_url, profile } = await getUserDetials({ | ||
context, | ||
username: who, | ||
}) | ||
|
||
const newOptionsContent = await addContributor({ | ||
options: optionsFileContent, | ||
login: who, | ||
contributions, | ||
name, | ||
avatar_url, | ||
profile, | ||
}) | ||
context.log('New Options Content') | ||
context.log(newOptionsContent) | ||
|
||
const readmeFileContentsByPath = await getReadmeFileContentsByPath({ | ||
repository, | ||
files: optionsFileContent.files, | ||
}) | ||
|
||
context.log('Readme file contents by path') | ||
context.log(readmeFileContentsByPath) | ||
|
||
const newReadmeFileContentsByPath = await generateContentFiles({ | ||
options: newOptionsContent, | ||
readmeFileContentsByPath, | ||
}) | ||
context.log('New readme file contents by path') | ||
context.log(newReadmeFileContentsByPath) | ||
|
||
// TODO: Create branch, update files | ||
// GET master state when we read files | ||
// https://octokit.github.io/rest.js/#api-Git-createRef | ||
// https://octokit.github.io/rest.js/#api-Repos-updateFile | ||
|
||
// TODO: post pull request | ||
// https://octokit.github.io/rest.js/#api-Pulls-createFromIssue | ||
|
||
// TODO: Comment back with link to pull request | ||
} | ||
const processIssueComment = require('./processIssueComment') | ||
|
||
module.exports = app => { | ||
// issueComment.edited | ||
// Issue comments and PR comments both create issue_comment events | ||
app.on('issue_comment.created', async context => { | ||
try { | ||
await processNewIssueComment(context) | ||
} catch (error) { | ||
await createComment({ | ||
context, | ||
body: `@${ | ||
context.payload.comment.user.login | ||
} we had trouble processing your request. \n\nError: ${ | ||
error.message | ||
}`, | ||
}) | ||
throw error | ||
} | ||
app.log(context) | ||
await processIssueComment(context) | ||
}) | ||
} |
Oops, something went wrong.