Skip to content

Commit

Permalink
Get GitHub issues from dependency repo
Browse files Browse the repository at this point in the history
  • Loading branch information
JerryHue committed Mar 24, 2022
1 parent 244ed69 commit dba5de0
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 1 deletion.
2 changes: 2 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/api/dependency-discovery/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
},
"homepage": "https://github.com/Seneca-CDOT/telescope#readme",
"dependencies": {
"@octokit/request": "5.6.3",
"@senecacdot/satellite": "^1.27.0",
"query-registry": "2.2.0",
"supertest": "6.1.6"
Expand Down
8 changes: 8 additions & 0 deletions src/api/dependency-discovery/src/dependency-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const { readFile } = require('fs/promises');
const { join } = require('path');
const { cwd } = require('process');
const { getPackument } = require('query-registry');
const { requestGitHubInfo } = require('./github');

const getDependencies = (function () {
let dependencies = null;
Expand Down Expand Up @@ -51,8 +52,15 @@ async function getNpmPackageInfo(packageName) {
return dependencies[packageName];
}

async function getGitHubIssues(packageName) {
const npmPackage = await getNpmPackageInfo(packageName);

return requestGitHubInfo(packageName, npmPackage.gitRepository.url);
}

module.exports = {
getDependencyList,
getNpmPackageInfo,
isPackageDependency,
getGitHubIssues,
};
66 changes: 66 additions & 0 deletions src/api/dependency-discovery/src/github.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
const { request } = require('@octokit/request');

// Check whether a specific time has reached the GitHub time limit.
// @param {Date} datetime - a Date object representing a moment in the past
// @returns {Boolean}
const hasGitHubExpired = (dateTime) => new Date() - dateTime > 60 * 60 * 1000;

const gitHubInformationRequestor = {};

async function constructGitHubRequest(gitHubUrl) {
const labels = ['hacktoberfest', 'good first issue', 'help wanted'];

const [owner, repo] = new URL(gitHubUrl).pathname.substring(1).split('/');

const requestPromises = labels.map((label) => {
return request('GET /repos/{owner}/{repo}/issues{?assignee,state,labels}', {
owner,
repo,
assignee: 'none',
state: 'open',
labels: label,
});
});

// A single request might look like a response in
// https://docs.github.com/en/rest/reference/issues#list-repository-issues
const responses = await Promise.all(requestPromises);

return responses
.filter((response) => response.status === 200)
.flatMap((response) =>
response.data.map((issue) => {
return {
htmlUrl: issue.html_url,
title: issue.title,
body: issue.body,
createdAt: issue.created_at,
};
})
)
.filter((issue, index, array) => array.findIndex((i) => i.htmlUrl === issue.htmlUrl) === index);
}

function requestGitHubInfo(packageName, gitHubUrl) {
const cachedRequest = gitHubInformationRequestor[packageName];

if (cachedRequest && !hasGitHubExpired(cachedRequest.expireAt)) {
return cachedRequest.request;
}

const newRequest = constructGitHubRequest(gitHubUrl);

const now = new Date();
now.setHours(now.getHours() + 1);

gitHubInformationRequestor[packageName] = {
expireAt: now,
request: newRequest,
};

return newRequest;
}

module.exports = {
requestGitHubInfo,
};
24 changes: 23 additions & 1 deletion src/api/dependency-discovery/src/router.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
const { Router } = require('@senecacdot/satellite');
const { getDependencyList, getNpmPackageInfo, isPackageDependency } = require('./dependency-list');
const {
getDependencyList,
getNpmPackageInfo,
getGitHubIssues,
isPackageDependency,
} = require('./dependency-list');

const router = Router();

Expand Down Expand Up @@ -33,4 +38,21 @@ router.get('/projects/:namespace/:name?', async (req, res, next) => {
}
});

router.get('/github/:namespace/:name?', async (req, res, next) => {
const { namespace, name } = req.params;
const packageName = name ? `${namespace}/${name}` : namespace;

try {
if (!(await isPackageDependency(packageName))) {
res.status(404).json({ msg: `${packageName} is not a Telescope dependency` });
next();
} else {
res.set('Cache-Control', 'max-age=3600');
res.status(200).json(await getGitHubIssues(packageName));
}
} catch (err) {
next(err);
}
});

module.exports = router;

0 comments on commit dba5de0

Please sign in to comment.