-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: ✨ codefair v1 #30
Conversation
* 🐛 fix: update env var name * 🐛 fix: update folder name * 🐛 fix: update probot to esm * ✨ feat: add basic license get page --------- Co-authored-by: Dorian Portillo <wheresdorian@gmail.com>
* 🐛 fix: update env var name * 🐛 fix: update folder name * 🐛 fix: update probot to esm * ✨ feat: add basic license get page * 🚧 wip: add base ui * ✨ feat: add license ui --------- Co-authored-by: Dorian Portillo <wheresdorian@gmail.com>
* 🚧 wip: protected page * 🚧 fix: auth
* 🚧 wip: add mongoose * fix: 🐛 mongoose adapter/callback * refactor: ♻️ use mongoose on client end * chore: 🔨 remove unused code * 🚧 wip: test permissions * 🚧 wip: test permissions * 🚧 wip: test permissions * 🚧 wip: test permissions * 🚧 wip: test permissions * ✨ feat: add error sections * 🧑💻 chore: remove console.logs --------- Co-authored-by: slugb0t <wheresdorian@gmail.com>
* dev: 👷 yml file for creating probot app * wip: 🚧 dashboard issue * dev: 👷 nodemon for probot * refactor: ♻️ provide context for renderissue fn + nodemon file watch * wip: 🚧 provide localhost list depending on production * feat: ✨ provide link to PR for dashboard * feat: ✨ update dashboard on push * wip: 🚧 abstracting code * wip: 🚧 abstract functions of probot * feat: ✨ dashboard workflow for LICENSE * wip: 🚧 clean license UI * feat: ✨ help text for license UI * feat: ✨ renderer file has documentation + db update * feat: ✨ documentation for tools * feat: ✨ documentation for probot event listeners * refactor: ♻️ file name instead of just name on UI/add license page * wip: 🚧 styling for license UI Co-authored-by: Dorian Portillo <wheresdorian@gmail.com>
* wip: 🚧 background change * refactor: ♻️ update bg * refactor: ♻️ improvements on svg background blur
Thank you for submitting this pull request! We appreciate your contribution to the project. Before we can merge it, we need to review the changes you've made to ensure they align with our code standards and meet the requirements of the project. We'll get back to you as soon as we can with feedback. Thanks again! |
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
🧙 Sourcery has finished reviewing your pull request! Tips
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We've reviewed this pull request using the Sourcery rules engine. If you would also like our AI-powered code review then let us know.
if ( | ||
context.payload.issue.title === "No citation file found [codefair-app]" && | ||
context.payload.issue.title === | ||
`No citation file found [${GITHUB_APP_NAME}]` && | ||
["MEMBER", "OWNER"].includes(authorAssociation) && | ||
userComment.includes("codefair-app") | ||
userComment.includes(GITHUB_APP_NAME) | ||
) { | ||
if (userComment.includes("Yes")) { | ||
// Gather the information for the CITATION.cff file | ||
await gatherCitationInfo(context, owner, repo); | ||
await gatherCitationInfo(context, owner, repoName); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (code-quality): Merge nested if conditions (merge-nested-ifs
)
if ( | |
context.payload.issue.title === "No citation file found [codefair-app]" && | |
context.payload.issue.title === | |
`No citation file found [${GITHUB_APP_NAME}]` && | |
["MEMBER", "OWNER"].includes(authorAssociation) && | |
userComment.includes("codefair-app") | |
userComment.includes(GITHUB_APP_NAME) | |
) { | |
if (userComment.includes("Yes")) { | |
// Gather the information for the CITATION.cff file | |
await gatherCitationInfo(context, owner, repo); | |
await gatherCitationInfo(context, owner, repoName); | |
} | |
} | |
if (context.payload.issue.title === | |
`No citation file found [${GITHUB_APP_NAME}]` && | |
["MEMBER", "OWNER"].includes(authorAssociation) && | |
userComment.includes(GITHUB_APP_NAME) && userComment.includes("Yes")) { | |
await gatherCitationInfo(context, owner, repoName); | |
} | |
Explanation
Reading deeply nested conditional code is confusing, since you have to keep track of whichconditions relate to which levels. We therefore strive to reduce nesting where
possible, and the situation where two
if
conditions can be combined usingand
is an easy win.
} | ||
} | ||
|
||
async function verifyFirstIssue(context, owner, repo, title) { | ||
// If there is an issue that has been created by the bot, (either opened or closed) don't create another issue | ||
const issues = await context.octokit.issues.listForRepo({ | ||
owner, | ||
repo, | ||
creator: "codefair-app[bot]", | ||
state: "all", | ||
}); | ||
|
||
if (issues.data.length > 0) { | ||
// iterate through issues to see if there is an issue with the same title | ||
let no_issue = false; | ||
for (let i = 0; i < issues.data.length; i++) { | ||
if (issues.data[i].title === title) { | ||
console.log("Issue already exists, will not recreate"); | ||
no_issue = true; | ||
break; | ||
} | ||
} | ||
|
||
if (!no_issue) { | ||
return false; | ||
} else { | ||
return true; | ||
} | ||
} | ||
} | ||
|
||
async function checkForLicense(context, owner, repo) { | ||
console.log("checking for license"); | ||
try { | ||
await context.octokit.rest.licenses.getForRepo({ | ||
owner, | ||
repo, | ||
}); | ||
|
||
console.log("license found!"); | ||
return true; | ||
} catch (error) { | ||
console.log("no license found"); | ||
// Errors when no License is found in the repo | ||
return false; | ||
} | ||
} | ||
|
||
async function checkForCitation(context, owner, repo) { | ||
try { | ||
await context.octokit.rest.repos.getContent({ | ||
owner, | ||
repo, | ||
path: "CITATION.cff", | ||
}); | ||
|
||
return true; | ||
} catch (error) { | ||
return false; | ||
} | ||
} | ||
|
||
async function checkForCodeMeta(context, owner, repo) { | ||
try { | ||
await context.octokit.rest.repos.getContent({ | ||
owner, | ||
repo, | ||
path: "codemeta.json", | ||
}); | ||
|
||
return true; | ||
} catch (error) { | ||
return false; | ||
} | ||
} | ||
|
||
async function createIssue(context, owner, repo, title, body) { | ||
// If issue has been created, create one | ||
console.log("gathering issues"); | ||
const issue = await context.octokit.issues.listForRepo({ | ||
owner, | ||
repo: repo, | ||
state: "open", | ||
creator: "codefair-app[bot]", | ||
title: title, | ||
}); | ||
|
||
console.log("ISSUE DATA"); | ||
console.log(issue.data); | ||
|
||
if (issue.data.length > 0) { | ||
// iterate through issues to see if there is an issue with the same title | ||
let no_issue = false; | ||
for (let i = 0; i < issue.data.length; i++) { | ||
if (issue.data[i].title === title) { | ||
no_issue = true; | ||
break; | ||
await gatherCodeMetaInfo(context, owner, repoName); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (code-quality): Merge nested if conditions (merge-nested-ifs
)
if ( | |
context.payload.issue.title === | |
"No codemeta.json file found [codefair-app]" && | |
`No codemeta.json file found [${GITHUB_APP_NAME}]` && | |
["MEMBER", "OWNER"].includes(authorAssociation) && | |
userComment.includes("codefair-app") | |
userComment.includes(GITHUB_APP_NAME) | |
) { | |
if (userComment.includes("Yes")) { | |
// Gather the information for the codemeta.json file | |
await gatherCodeMetaInfo(context, owner, repo); | |
} | |
} | |
}); | |
}; | |
async function getDefaultBranch(context, owner, repo) { | |
let default_branch; | |
try { | |
default_branch = await context.octokit.repos.getBranch({ | |
owner, | |
repo, | |
branch: context.payload.repository.default_branch, | |
}); | |
return default_branch; | |
} catch (error) { | |
console.log("Error getting the default branch"); | |
console.log(error); | |
return; | |
} | |
} | |
async function closeOpenIssue(context, owner, repo, title) { | |
// Check if issue is open and close it | |
// TODO: UPDATE THE CREATOR WHEN MOVING TO PROD | |
const issue = await context.octokit.issues.listForRepo({ | |
owner, | |
repo: repo, | |
state: "open", | |
creator: "codefair-app[bot]", | |
title: title, | |
}); | |
if (issue.data.length > 0) { | |
// If title if issue is found, close the issue | |
for (let i = 0; i < issue.data.length; i++) { | |
if (issue.data[i].title === title) { | |
await context.octokit.issues.update({ | |
repo, | |
owner, | |
issue_number: issue.data[i].number, | |
state: "closed", | |
}); | |
} | |
} | |
} | |
} | |
async function verifyFirstIssue(context, owner, repo, title) { | |
// If there is an issue that has been created by the bot, (either opened or closed) don't create another issue | |
const issues = await context.octokit.issues.listForRepo({ | |
owner, | |
repo, | |
creator: "codefair-app[bot]", | |
state: "all", | |
}); | |
if (issues.data.length > 0) { | |
// iterate through issues to see if there is an issue with the same title | |
let no_issue = false; | |
for (let i = 0; i < issues.data.length; i++) { | |
if (issues.data[i].title === title) { | |
console.log("Issue already exists, will not recreate"); | |
no_issue = true; | |
break; | |
} | |
} | |
if (!no_issue) { | |
return false; | |
} else { | |
return true; | |
} | |
} | |
} | |
async function checkForLicense(context, owner, repo) { | |
console.log("checking for license"); | |
try { | |
await context.octokit.rest.licenses.getForRepo({ | |
owner, | |
repo, | |
}); | |
console.log("license found!"); | |
return true; | |
} catch (error) { | |
console.log("no license found"); | |
// Errors when no License is found in the repo | |
return false; | |
} | |
} | |
async function checkForCitation(context, owner, repo) { | |
try { | |
await context.octokit.rest.repos.getContent({ | |
owner, | |
repo, | |
path: "CITATION.cff", | |
}); | |
return true; | |
} catch (error) { | |
return false; | |
} | |
} | |
async function checkForCodeMeta(context, owner, repo) { | |
try { | |
await context.octokit.rest.repos.getContent({ | |
owner, | |
repo, | |
path: "codemeta.json", | |
}); | |
return true; | |
} catch (error) { | |
return false; | |
} | |
} | |
async function createIssue(context, owner, repo, title, body) { | |
// If issue has been created, create one | |
console.log("gathering issues"); | |
const issue = await context.octokit.issues.listForRepo({ | |
owner, | |
repo: repo, | |
state: "open", | |
creator: "codefair-app[bot]", | |
title: title, | |
}); | |
console.log("ISSUE DATA"); | |
console.log(issue.data); | |
if (issue.data.length > 0) { | |
// iterate through issues to see if there is an issue with the same title | |
let no_issue = false; | |
for (let i = 0; i < issue.data.length; i++) { | |
if (issue.data[i].title === title) { | |
no_issue = true; | |
break; | |
await gatherCodeMetaInfo(context, owner, repoName); | |
} | |
} | |
if (context.payload.issue.title === | |
`No codemeta.json file found [${GITHUB_APP_NAME}]` && | |
["MEMBER", "OWNER"].includes(authorAssociation) && | |
userComment.includes(GITHUB_APP_NAME) && userComment.includes("Yes")) { | |
await gatherCodeMetaInfo(context, owner, repoName); | |
} | |
Explanation
Reading deeply nested conditional code is confusing, since you have to keep track of whichconditions relate to which levels. We therefore strive to reduce nesting where
possible, and the situation where two
if
conditions can be combined usingand
is an easy win.
const codeMeta = { | ||
name: repoData.data.name, | ||
applicationCategory: null, | ||
authors: citationAuthors || [], | ||
codeRepository: repoData.data.html_url, | ||
continuousIntegration: "", | ||
contributors: [], | ||
creationDate: Date.parse(repoData.data.created_at) || null, | ||
currentVersion: releases.data[0]?.tag_name || "", | ||
currentVersionDownloadURL: releases.data[0]?.html_url || "", | ||
currentVersionReleaseDate: | ||
Date.parse(releases.data[0]?.published_at) || null, | ||
currentVersionReleaseNotes: releases.data[0]?.body || "", | ||
description: repoData.data.description, | ||
developmentStatus: null, | ||
firstReleaseDate: Date.parse(releases.data[0]?.published_at) || null, | ||
fundingCode: "", | ||
fundingOrganization: "", | ||
isPartOf: "", | ||
isSourceCodeOf: "", | ||
issueTracker: `https://github.com/${owner}/${repo.name}/issues`, | ||
keywords: repoData.data.topics || [], | ||
license: | ||
repoData.data.license?.spdx_id === "NOASSERTION" | ||
? null | ||
: repoData.data.license?.spdx_id || null, | ||
operatingSystem: [], | ||
otherSoftwareRequirements: [], | ||
programmingLanguages: languagesUsed || [], | ||
referencePublication: doi[1] || "", | ||
relatedLinks: [], | ||
reviewAspect: "", | ||
reviewBody: "", | ||
runtimePlatform: [], | ||
uniqueIdentifier: "", | ||
}; | ||
|
||
return codeMeta; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (code-quality): Inline variable that is immediately returned (inline-immediately-returned-variable
)
const codeMeta = { | |
name: repoData.data.name, | |
applicationCategory: null, | |
authors: citationAuthors || [], | |
codeRepository: repoData.data.html_url, | |
continuousIntegration: "", | |
contributors: [], | |
creationDate: Date.parse(repoData.data.created_at) || null, | |
currentVersion: releases.data[0]?.tag_name || "", | |
currentVersionDownloadURL: releases.data[0]?.html_url || "", | |
currentVersionReleaseDate: | |
Date.parse(releases.data[0]?.published_at) || null, | |
currentVersionReleaseNotes: releases.data[0]?.body || "", | |
description: repoData.data.description, | |
developmentStatus: null, | |
firstReleaseDate: Date.parse(releases.data[0]?.published_at) || null, | |
fundingCode: "", | |
fundingOrganization: "", | |
isPartOf: "", | |
isSourceCodeOf: "", | |
issueTracker: `https://github.com/${owner}/${repo.name}/issues`, | |
keywords: repoData.data.topics || [], | |
license: | |
repoData.data.license?.spdx_id === "NOASSERTION" | |
? null | |
: repoData.data.license?.spdx_id || null, | |
operatingSystem: [], | |
otherSoftwareRequirements: [], | |
programmingLanguages: languagesUsed || [], | |
referencePublication: doi[1] || "", | |
relatedLinks: [], | |
reviewAspect: "", | |
reviewBody: "", | |
runtimePlatform: [], | |
uniqueIdentifier: "", | |
}; | |
return codeMeta; | |
return { | |
name: repoData.data.name, | |
applicationCategory: null, | |
authors: citationAuthors || [], | |
codeRepository: repoData.data.html_url, | |
continuousIntegration: "", | |
contributors: [], | |
creationDate: Date.parse(repoData.data.created_at) || null, | |
currentVersion: releases.data[0]?.tag_name || "", | |
currentVersionDownloadURL: releases.data[0]?.html_url || "", | |
currentVersionReleaseDate: | |
Date.parse(releases.data[0]?.published_at) || null, | |
currentVersionReleaseNotes: releases.data[0]?.body || "", | |
description: repoData.data.description, | |
developmentStatus: null, | |
firstReleaseDate: Date.parse(releases.data[0]?.published_at) || null, | |
fundingCode: "", | |
fundingOrganization: "", | |
isPartOf: "", | |
isSourceCodeOf: "", | |
issueTracker: `https://github.com/${owner}/${repo.name}/issues`, | |
keywords: repoData.data.topics || [], | |
license: | |
repoData.data.license?.spdx_id === "NOASSERTION" | |
? null | |
: repoData.data.license?.spdx_id || null, | |
operatingSystem: [], | |
otherSoftwareRequirements: [], | |
programmingLanguages: languagesUsed || [], | |
referencePublication: doi[1] || "", | |
relatedLinks: [], | |
reviewAspect: "", | |
reviewBody: "", | |
runtimePlatform: [], | |
uniqueIdentifier: "", | |
}; | |
Explanation
Something that we often see in people's code is assigning to a result variableand then immediately returning it.
Returning the result directly shortens the code and removes an unnecessary
variable, reducing the mental load of reading the function.
Where intermediate variables can be useful is if they then get used as a
parameter or a condition, and the name can act like a comment on what the
variable represents. In the case where you're returning it from a function, the
function name is there to tell you what the result is, so the variable name
is unnecessary.
import { checkForLicense } from "../license/index.js"; | ||
import { gatherMetadata, convertMetadataForDB } from "../metadata/index.js"; | ||
|
||
const GITHUB_APP_NAME = process.env.GITHUB_APP_NAME; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (code-quality): Prefer object destructuring when accessing and using properties. (use-object-destructuring
)
const GITHUB_APP_NAME = process.env.GITHUB_APP_NAME; | |
const {GITHUB_APP_NAME} = process.env; |
Explanation
Object destructuring can often remove an unnecessary temporary reference, as well as making your code more succinct.From the Airbnb Javascript Style Guide
const user = useState<User | null>("user", () => null); | ||
|
||
return user; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (code-quality): Inline variable that is immediately returned (inline-immediately-returned-variable
)
const user = useState<User | null>("user", () => null); | |
return user; | |
return useState<User | null>("user", () => null); | |
Explanation
Something that we often see in people's code is assigning to a result variableand then immediately returning it.
Returning the result directly shortens the code and removes an unnecessary
variable, reducing the mental load of reading the function.
Where intermediate variables can be useful is if they then get used as a
parameter or a condition, and the name can act like a comment on what the
variable represents. In the case where you're returning it from a function, the
function name is there to tell you what the result is, so the variable name
is unnecessary.
Thanks for closing this pull request! If you have any further questions, please feel free to open a new issue. We are always happy to help! |
No description provided.