diff --git a/index.njk b/index.njk
index 8227ee1..e351c48 100644
--- a/index.njk
+++ b/index.njk
@@ -35,6 +35,7 @@
Language |
Topics |
Open issues count |
+ Open PRs count |
Last updated |
Dependencies |
@@ -47,6 +48,7 @@
{{ repo.language }} |
{{ repo.topics | join(", ")}} |
{{ repo.openIssues }} |
+ {{ repo.openPrsCount }} |
{{ repo.updatedAt }} |
{% if repo.dependencies.length %}
diff --git a/dataScripts/fetchAllRepos.js b/utils/githubApi/fetchAllRepos.js
similarity index 68%
rename from dataScripts/fetchAllRepos.js
rename to utils/githubApi/fetchAllRepos.js
index 625ce4e..2b4e7af 100644
--- a/dataScripts/fetchAllRepos.js
+++ b/utils/githubApi/fetchAllRepos.js
@@ -1,8 +1,11 @@
-import { OctokitApp } from "../octokitApp.js";
+import { OctokitApp } from "../../octokitApp.js";
import { writeFile, mkdir } from "fs/promises";
import { mapRepoFromApiForStorage } from "../utils.js";
import path from "path";
-import { getDependenciesForRepo } from "../renovate/dependencyDashboard.js";
+import {
+ getDependenciesForRepo,
+ getOpenPRsForRepo,
+} from "../renovate/dependencyDashboard.js";
const fetchAllRepos = async () => {
const repos = [];
@@ -10,9 +13,18 @@ const fetchAllRepos = async () => {
await OctokitApp.app.eachRepository(async ({ repository, octokit }) => {
if (repository.archived) return;
- repository.dependencies = await getDependenciesForRepo({
- repository,
- octokit,
+ await Promise.all([
+ await getDependenciesForRepo({
+ repository,
+ octokit,
+ }),
+ await getOpenPRsForRepo({
+ repository,
+ octokit,
+ }),
+ ]).then(([dependencies, openPrsCount]) => {
+ repository.dependencies = dependencies;
+ repository.openPrsCount = openPrsCount;
});
repos.push(mapRepoFromApiForStorage(repository));
diff --git a/utils/githubApi/fetchOpenPrs.js b/utils/githubApi/fetchOpenPrs.js
new file mode 100644
index 0000000..18545d6
--- /dev/null
+++ b/utils/githubApi/fetchOpenPrs.js
@@ -0,0 +1,5 @@
+export const getOpenPRsForRepo = ({ octokit, repository }) => {
+ return octokit.request(repository.pulls_url).then(handlePrsApiResponse);
+};
+
+export const handlePrsApiResponse = ({ data }) => data?.length || 0;
diff --git a/utils/githubApi/fetchOpenPrs.test.js b/utils/githubApi/fetchOpenPrs.test.js
new file mode 100644
index 0000000..3902801
--- /dev/null
+++ b/utils/githubApi/fetchOpenPrs.test.js
@@ -0,0 +1,13 @@
+import { describe, it } from "node:test";
+import expect from "node:assert";
+import { handlePrsApiResponse } from "./fetchOpenPrs.js";
+
+describe("handlePrsApiResponse", () => {
+ it("returns the length of the array containing PRs", () => {
+ expect.equal(handlePrsApiResponse({ data: [1, 2, 3] }), 3);
+ });
+
+ it("returns 0 if there are no open PRs", () => {
+ expect.equal(handlePrsApiResponse({ data: undefined }), 0);
+ });
+});
diff --git a/utils.js b/utils/index.js
similarity index 99%
rename from utils.js
rename to utils/index.js
index 4a9feb7..ccf0058 100644
--- a/utils.js
+++ b/utils/index.js
@@ -94,4 +94,5 @@ export const mapRepoFromApiForStorage = (repo) => ({
topics: repo.topics,
openIssues: repo.open_issues,
dependencies: repo.dependencies,
+ openPrsCount: repo.openPrsCount,
});
diff --git a/utils.test.js b/utils/index.test.js
similarity index 99%
rename from utils.test.js
rename to utils/index.test.js
index 52988b7..48edecd 100644
--- a/utils.test.js
+++ b/utils/index.test.js
@@ -1,6 +1,6 @@
import { describe, it } from "node:test";
import expect from "node:assert";
-import { mapRepoFromStorageToUi, mapRepoFromApiForStorage } from "./utils.js";
+import { mapRepoFromStorageToUi, mapRepoFromApiForStorage } from "./index.js";
describe("mapRepoFromStorageToUi", () => {
it("converts the ISO8601 date to a human-readable date", () => {
@@ -253,6 +253,7 @@ describe("mapRepoFromStorageToUi", () => {
pull: false,
},
dependencies: repoDependencies,
+ openPrsCount: 0,
};
const repoToSave = {
@@ -270,6 +271,7 @@ describe("mapRepoFromStorageToUi", () => {
topics: ["delivery-plus", "internal", "tech-ops"],
openIssues: 2,
dependencies: repoDependencies,
+ openPrsCount: 0,
};
expect.deepEqual(mapRepoFromApiForStorage(apiRepo), repoToSave);
diff --git a/renovate/dependencyDashboard.js b/utils/renovate/dependencyDashboard.js
similarity index 73%
rename from renovate/dependencyDashboard.js
rename to utils/renovate/dependencyDashboard.js
index 6773b64..bcb2071 100644
--- a/renovate/dependencyDashboard.js
+++ b/utils/renovate/dependencyDashboard.js
@@ -25,13 +25,14 @@ const LINE_SEPARATOR_REGEX = /\r?\n|\r|\n/g;
// Group 2: ^7.20.2
const DEPENDENCY_NAME_AND_VERSION_REGEX = /`(\S+?) (.*)`/;
-const issueIsRenovateDependencyDashboard = (issue) => issue.user.login === "renovate[bot]" && issue.pull_request === undefined;
+const issueIsRenovateDependencyDashboard = (issue) =>
+ issue.user.login === "renovate[bot]" && issue.pull_request === undefined;
-const parseDependenciesFromDashboard = (issue) => issue
- .body
- .split(LINE_SEPARATOR_REGEX)
- .map(parseDependencyFromLine)
- .filter((dependency) => dependency !== null);
+const parseDependenciesFromDashboard = (issue) =>
+ issue.body
+ .split(LINE_SEPARATOR_REGEX)
+ .map(parseDependencyFromLine)
+ .filter((dependency) => dependency !== null);
const parseDependencyFromLine = (line) => {
const match = line.match(DEPENDENCY_NAME_AND_VERSION_REGEX);
@@ -41,18 +42,20 @@ const parseDependencyFromLine = (line) => {
}
return new Dependency(match[1], match[2]);
-}
+};
export const handleIssuesApiResponse = (response) => {
- const dependencyDashboardIssue = response.data.find(issueIsRenovateDependencyDashboard);
+ const dependencyDashboardIssue = response.data.find(
+ issueIsRenovateDependencyDashboard
+ );
if (!dependencyDashboardIssue) {
return [];
}
return parseDependenciesFromDashboard(dependencyDashboardIssue);
-}
+};
+
export const getDependenciesForRepo = ({ octokit, repository }) => {
return octokit.request(repository.issues_url).then(handleIssuesApiResponse);
};
-
diff --git a/renovate/dependencyDashboard.test.js b/utils/renovate/dependencyDashboard.test.js
similarity index 87%
rename from renovate/dependencyDashboard.test.js
rename to utils/renovate/dependencyDashboard.test.js
index 5d17d1f..a99d45a 100644
--- a/renovate/dependencyDashboard.test.js
+++ b/utils/renovate/dependencyDashboard.test.js
@@ -24,9 +24,9 @@ describe("handleIssuesApiResponse", () => {
user: {
login: "renovate[bot]",
},
- body: "# Dependency Dashboard\nList of dependencies:\n- `libquux v4.1.1.rc4`\n- `@xyzzy/utils \"~> 22.04 Questing Quokka\"`\n\nHere's some more:\n- `baz-framework ^0.1`",
- }
- ]
+ body: '# Dependency Dashboard\nList of dependencies:\n- `libquux v4.1.1.rc4`\n- `@xyzzy/utils "~> 22.04 Questing Quokka"`\n\nHere\'s some more:\n- `baz-framework ^0.1`',
+ },
+ ],
};
const expectedDependencies = [
@@ -37,7 +37,7 @@ describe("handleIssuesApiResponse", () => {
expect.deepEqual(
handleIssuesApiResponse(issuesApiResponse),
- expectedDependencies,
+ expectedDependencies
);
});
@@ -58,14 +58,14 @@ describe("handleIssuesApiResponse", () => {
pull_request: {},
body: "Configure Renovate",
},
- ]
+ ],
};
const expectedDependencies = [];
expect.deepEqual(
handleIssuesApiResponse(issuesApiResponse),
- expectedDependencies,
+ expectedDependencies
);
});
});