From ab1c0cdc46e0010279f891ebe13fde3f754fbcd0 Mon Sep 17 00:00:00 2001 From: Maxime Golfier <25312957+maxgfr@users.noreply.github.com> Date: Tue, 11 Jul 2023 18:21:51 +0200 Subject: [PATCH] fix(alert-cli): change `diff` by replacing `github-api` by a local diff (#972) --- targets/alert-cli/package.json | 3 + .../src/APIs/__tests__/api.diff.test.ts | 100 ------------------ targets/alert-cli/src/APIs/api.ts | 31 +----- .../src/diff/__tests__/get-diff.test.ts | 11 ++ targets/alert-cli/src/diff/get-diff.ts | 46 ++++++++ yarn.lock | 28 ++++- 6 files changed, 89 insertions(+), 130 deletions(-) delete mode 100644 targets/alert-cli/src/APIs/__tests__/api.diff.test.ts create mode 100644 targets/alert-cli/src/diff/__tests__/get-diff.test.ts create mode 100644 targets/alert-cli/src/diff/get-diff.ts diff --git a/targets/alert-cli/package.json b/targets/alert-cli/package.json index b1ae32e5c..3089e9100 100644 --- a/targets/alert-cli/package.json +++ b/targets/alert-cli/package.json @@ -13,9 +13,11 @@ "@socialgouv/cdtn-slugify": "4.52.1", "@socialgouv/cdtn-sources": "4.52.1", "@socialgouv/dila-api-client": "1.2.4", + "diff": "^5.1.0", "memoizee": "0.4.15", "p-map": "4", "semver": "7.3.5", + "simple-git": "^3.19.1", "unist-util-parents": "1.0.3", "unist-util-select": "4.0.1" }, @@ -27,6 +29,7 @@ "@socialgouv/fiches-travail-data-types": "4.191.0", "@socialgouv/kali-data-types": "2.127.0", "@socialgouv/legi-data-types": "2.73.1", + "@types/diff": "^5.0.3", "@types/jest": "27.4.0", "@types/memoizee": "0.4.6", "@types/node": "16.11.11", diff --git a/targets/alert-cli/src/APIs/__tests__/api.diff.test.ts b/targets/alert-cli/src/APIs/__tests__/api.diff.test.ts deleted file mode 100644 index a0c5f940e..000000000 --- a/targets/alert-cli/src/APIs/__tests__/api.diff.test.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { GithubApi } from "../api"; - -const apiResponse = { - files: [ - { - sha: "sha1", - filename: "file1.txt", - status: "added", - }, - { - sha: "sha2", - filename: "file2.txt", - status: "removed", - }, - { - sha: "sha3", - filename: "file3.txt", - status: "modified", - }, - ], -}; - -const apiResponsePage2 = { - files: [ - { - sha: "sha1", - filename: "file4.txt", - status: "added", - }, - { - sha: "sha2", - filename: "file5.txt", - status: "removed", - }, - { - sha: "sha3", - filename: "file6.txt", - status: "modified", - }, - ], -}; - -global.fetch = jest.fn().mockImplementation((url) => { - switch (url) { - case "https://api.github.com/repos/socialgouv/kali-data/compare/v1.4.0...v1.5.0?per_page=100&page=1": - return { - ok: true, - json: async () => Promise.resolve(apiResponse), - }; - case "https://api.github.com/repos/socialgouv/kali-data/compare/v1.4.0...v1.5.0?per_page=100&page=2": - return { - ok: true, - json: async () => Promise.resolve(apiResponsePage2), - }; - case "https://api.github.com/repos/socialgouv/kali-data/compare/v1.4.0...v1.5.0?per_page=100&page=3": - return { - ok: true, - json: async () => Promise.resolve([]), - }; - } -}); - -describe("Github API: list diff", () => { - const api = new GithubApi(""); - it("should return file diff between two versions", async () => { - const diff = await api.diff( - "socialgouv/kali-data", - { ref: "v1.4.0", commit: { date: new Date() } }, - { ref: "v1.5.0", commit: { date: new Date() } } - ); - expect(diff.from.ref).toStrictEqual("v1.4.0"); - expect(diff.to.ref).toStrictEqual("v1.5.0"); - expect(diff.files).toStrictEqual([ - { - filename: "file1.txt", - status: "added", - }, - { - filename: "file2.txt", - status: "removed", - }, - { - filename: "file3.txt", - status: "modified", - }, - { - filename: "file4.txt", - status: "added", - }, - { - filename: "file5.txt", - status: "removed", - }, - { - filename: "file6.txt", - status: "modified", - }, - ]); - }); -}); diff --git a/targets/alert-cli/src/APIs/api.ts b/targets/alert-cli/src/APIs/api.ts index d421d2afd..7c7c0dd55 100644 --- a/targets/alert-cli/src/APIs/api.ts +++ b/targets/alert-cli/src/APIs/api.ts @@ -1,5 +1,6 @@ import { Commit, GitTagData } from "../types"; import { Diff } from "../diff/type"; +import { getDiff } from "../diff/get-diff"; export type Tags = GitTagData[]; @@ -17,10 +18,6 @@ export interface GithubDiffFile { status: "added" | "modified" | "removed"; } -interface GithubResponse { - files?: GithubDiffFile[]; -} - interface CommitGithubResponse { commit: { author: { @@ -72,14 +69,7 @@ export class GithubApi { } async diff(project: string, from: GitTagData, to: GitTagData): Promise { - let page = 1; - let allDiffs: GithubDiffFile[] = []; - let diffs: GithubDiffFile[] = []; - do { - diffs = await this._diff(project, from.ref, to.ref, page); - allDiffs = allDiffs.concat(diffs); - page = page + 1; - } while (diffs.length > 0); + const allDiffs: GithubDiffFile[] = await getDiff(project, from.ref, to.ref); return { from, to, @@ -87,23 +77,6 @@ export class GithubApi { }; } - private async _diff( - project: string, - from: string, - to: string, - page = 1, - limit = 100 - ): Promise { - const url = `https://api.github.com/repos/${project}/compare/${from}...${to}?per_page=${limit}&page=${page}`; - const diffs = await this.fetchJson(url); - return ( - diffs.files?.map((diff) => ({ - filename: diff.filename, - status: diff.status, - })) ?? [] - ); - } - async raw(project: string, path: string, tag: GitTagData): Promise { const url = `https://raw.githubusercontent.com/${project}/${tag.ref}/${path}`; const data = await this.fetchText(url); diff --git a/targets/alert-cli/src/diff/__tests__/get-diff.test.ts b/targets/alert-cli/src/diff/__tests__/get-diff.test.ts new file mode 100644 index 000000000..0513ed547 --- /dev/null +++ b/targets/alert-cli/src/diff/__tests__/get-diff.test.ts @@ -0,0 +1,11 @@ +import { getDiff } from "../get-diff"; + +describe("getDiff", () => { + it("should return an empty array if the project does not exist", async () => { + const project = "does-not-exist-blabla"; + const fromTag = "v1.0.0"; + const toTag = "v2.0.0"; + const diff = await getDiff(project, fromTag, toTag); + expect(diff).toEqual([]); + }); +}); diff --git a/targets/alert-cli/src/diff/get-diff.ts b/targets/alert-cli/src/diff/get-diff.ts new file mode 100644 index 000000000..8fea791a3 --- /dev/null +++ b/targets/alert-cli/src/diff/get-diff.ts @@ -0,0 +1,46 @@ +import { GithubDiffFile } from "../APIs/api"; +import { simpleGit } from "simple-git"; +import { parsePatch } from "diff"; +import fs from "fs"; + +export async function getDiff( + project: string, + fromTag: string, + toTag: string +): Promise { + const repoPath = `/tmp/${project}`; + try { + if (fs.existsSync(repoPath)) { + // remove the repo if it already exists + fs.rmdirSync(repoPath, { recursive: true }); + } + await simpleGit().clone(`https://github.com/${project}`); + const diffString = await simpleGit(repoPath).diff([ + `${fromTag}...${toTag}`, + ]); + const diffDetail = parsePatch(diffString); + const result: GithubDiffFile[] = []; + diffDetail.forEach((file) => { + if (file.newFileName && !file.oldFileName) { + result.push({ + filename: file.newFileName, + status: "added", + }); + } else if (file.newFileName && file.oldFileName) { + result.push({ + filename: file.newFileName, + status: "modified", + }); + } else if (!file.newFileName && file.oldFileName) { + result.push({ + filename: file.oldFileName, + status: "removed", + }); + } + }); + return result; + } catch (error) { + console.error(error); + return []; + } +} diff --git a/yarn.lock b/yarn.lock index 08a7b7ec3..ade5a565e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2135,6 +2135,18 @@ methods "^1.1.2" path-to-regexp "^6.1.0" +"@kwsites/file-exists@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@kwsites/file-exists/-/file-exists-1.1.1.tgz#ad1efcac13e1987d8dbaf235ef3be5b0d96faa99" + integrity sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw== + dependencies: + debug "^4.1.1" + +"@kwsites/promise-deferred@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz#8ace5259254426ccef57f3175bc64ed7095ed919" + integrity sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw== + "@lerna/add@5.6.2": version "5.6.2" resolved "https://registry.yarnpkg.com/@lerna/add/-/add-5.6.2.tgz#d0e25fd4900b6f8a9548f940cc016ce8a3e2d2ba" @@ -4661,6 +4673,11 @@ dependencies: "@types/node" "*" +"@types/diff@^5.0.3": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@types/diff/-/diff-5.0.3.tgz#1f89e49ff83b5d200d78964fb896c68498ce1828" + integrity sha512-amrLbRqTU9bXMCc6uX0sWpxsQzRIo9z6MJPkH1pkez/qOxuqSZVuryJAWoBRq94CeG8JxY+VK4Le9HtjQR5T9A== + "@types/express-serve-static-core@^4.17.33": version "4.17.35" resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz#c95dd4424f0d32e525d23812aa8ab8e4d3906c4f" @@ -8115,7 +8132,7 @@ diff@^4.0.1: resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== -diff@^5.0.0: +diff@^5.0.0, diff@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/diff/-/diff-5.1.0.tgz#bc52d298c5ea8df9194800224445ed43ffc87e40" integrity sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw== @@ -16374,6 +16391,15 @@ signal-exit@^4.0.1: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.0.2.tgz#ff55bb1d9ff2114c13b400688fa544ac63c36967" integrity sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q== +simple-git@^3.19.1: + version "3.19.1" + resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-3.19.1.tgz#ff9c021961a3d876a1b115b1893bed9a28855d30" + integrity sha512-Ck+rcjVaE1HotraRAS8u/+xgTvToTuoMkT9/l9lvuP5jftwnYUp6DwuJzsKErHgfyRk8IB8pqGHWEbM3tLgV1w== + dependencies: + "@kwsites/file-exists" "^1.1.1" + "@kwsites/promise-deferred" "^1.1.1" + debug "^4.3.4" + simple-oauth2@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/simple-oauth2/-/simple-oauth2-4.3.0.tgz#8b8c28a7f7145a77a2a03086b1adb1e9ba5abc98"