diff --git a/dataScripts/allOwners.js b/dataScripts/allOwners.js new file mode 100644 index 0000000..4d553b8 --- /dev/null +++ b/dataScripts/allOwners.js @@ -0,0 +1,12 @@ +import { getReposFromJson } from "../utils.js"; + +const allOwners = async () => { + const { repos } = await getReposFromJson("./data/repos.json"); + + repos + .map((repo) => { + console.log(repo.topics); + }) + .flat(); +}; +await allOwners(); diff --git a/dataScripts/fetchAllRepos.js b/dataScripts/fetchAllRepos.js index 625ce4e..d5d6c25 100644 --- a/dataScripts/fetchAllRepos.js +++ b/dataScripts/fetchAllRepos.js @@ -2,7 +2,10 @@ 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/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/renovate/dependencyDashboard.js b/renovate/dependencyDashboard.js index 6773b64..a7ec873 100644 --- a/renovate/dependencyDashboard.js +++ b/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,26 @@ 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 handlePrsApiResponse = ({ data }) => data?.length || 0; + export const getDependenciesForRepo = ({ octokit, repository }) => { return octokit.request(repository.issues_url).then(handleIssuesApiResponse); }; +export const getOpenPRsForRepo = ({ octokit, repository }) => { + return octokit.request(repository.pulls_url).then(handlePrsApiResponse); +}; diff --git a/renovate/dependencyDashboard.test.js b/renovate/dependencyDashboard.test.js index 5d17d1f..b19516a 100644 --- a/renovate/dependencyDashboard.test.js +++ b/renovate/dependencyDashboard.test.js @@ -1,6 +1,10 @@ import { describe, it } from "node:test"; import expect from "node:assert"; -import { Dependency, handleIssuesApiResponse } from "./dependencyDashboard.js"; +import { + Dependency, + handleIssuesApiResponse, + handlePrsApiResponse, +} from "./dependencyDashboard.js"; describe("handleIssuesApiResponse", () => { it("should extract dependency version information from the Renovate Dependency Dashboard if it exists", async () => { @@ -24,9 +28,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 +41,7 @@ describe("handleIssuesApiResponse", () => { expect.deepEqual( handleIssuesApiResponse(issuesApiResponse), - expectedDependencies, + expectedDependencies ); }); @@ -58,14 +62,24 @@ describe("handleIssuesApiResponse", () => { pull_request: {}, body: "Configure Renovate", }, - ] + ], }; const expectedDependencies = []; expect.deepEqual( handleIssuesApiResponse(issuesApiResponse), - expectedDependencies, + expectedDependencies ); }); + + 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.js index c8aa7b3..5fcbefe 100644 --- a/utils.js +++ b/utils.js @@ -32,4 +32,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.test.js index 52988b7..0eaf171 100644 --- a/utils.test.js +++ b/utils.test.js @@ -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);