From 580d00be1362adf4f4b6f119afc9a6c14a60ac88 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 5 Mar 2024 22:14:35 +0100 Subject: [PATCH 01/31] feat(core): add history logic --- packages/core/package.json | 3 +- .../core/src/lib/history.integration.test.ts | 94 ++++++++++++ packages/core/src/lib/history.ts | 110 ++++++++++++++ packages/core/src/lib/history.unit.test.ts | 137 ++++++++++++++++++ packages/utils/src/index.ts | 2 + 5 files changed, 345 insertions(+), 1 deletion(-) create mode 100644 packages/core/src/lib/history.integration.test.ts create mode 100644 packages/core/src/lib/history.ts create mode 100644 packages/core/src/lib/history.unit.test.ts diff --git a/packages/core/package.json b/packages/core/package.json index 01bc8abfc..daf36202d 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -6,7 +6,8 @@ "@code-pushup/models": "*", "@code-pushup/utils": "*", "@code-pushup/portal-client": "^0.6.1", - "chalk": "^5.3.0" + "chalk": "^5.3.0", + "simple-git": "^3.20.0" }, "type": "commonjs", "main": "./index.cjs" diff --git a/packages/core/src/lib/history.integration.test.ts b/packages/core/src/lib/history.integration.test.ts new file mode 100644 index 000000000..5f55e811d --- /dev/null +++ b/packages/core/src/lib/history.integration.test.ts @@ -0,0 +1,94 @@ +import { mkdir, rm, writeFile } from 'node:fs/promises'; +import { join } from 'node:path'; +import { type SimpleGit, simpleGit } from 'simple-git'; +import { afterAll, beforeAll, describe, expect } from 'vitest'; +import { getHashes } from './history'; + +// we need a separate folder that is not cleaned in `global-setup.ts`, otherwise the tests can't execute in parallel +const gitTestFolder = 'git-test'; +describe('git utils in a git repo', () => { + const baseDir = join(process.cwd(), gitTestFolder); + let emptyGit: SimpleGit; + + beforeAll(async () => { + await mkdir(baseDir, { recursive: true }); + emptyGit = simpleGit(baseDir); + await emptyGit.init(); + await emptyGit.addConfig('user.name', 'John Doe'); + await emptyGit.addConfig('user.email', 'john.doe@example.com'); + }); + + afterAll(async () => { + await rm(baseDir, { recursive: true, force: true }); + }); + + describe('without a branch and commits', () => { + it('getHashes should throw', async () => { + await expect(getHashes({}, emptyGit)).rejects.toThrow( + "your current branch 'master' does not have any commits yet", + ); + }); + }); + + describe('with a branch and commits clean', () => { + const commits: string[] = []; + beforeAll(async () => { + await writeFile(join(baseDir, 'README.md'), '# hello-world\n'); + await emptyGit.add('README.md'); + await emptyGit.commit('Create README'); + // eslint-disable-next-line functional/immutable-data + commits.push((await emptyGit.log()).latest?.hash); + + await writeFile(join(baseDir, 'README.md'), '# hello-world-1\n'); + await emptyGit.add('README.md'); + await emptyGit.commit('Update README 1'); + // eslint-disable-next-line functional/immutable-data + commits.push((await emptyGit.log()).latest?.hash); + + await writeFile(join(baseDir, 'README.md'), '# hello-world-2\n'); + await emptyGit.add('README.md'); + await emptyGit.commit('Update README 2'); + // eslint-disable-next-line functional/immutable-data + commits.push((await emptyGit.log()).latest?.hash); + + await emptyGit.branch(['feature-branch']); + await emptyGit.checkout(['master']); + }); + + afterAll(async () => { + await emptyGit.checkout(['master']); + await emptyGit.deleteLocalBranch('feature-branch'); + }); + + it('getHashes should get all commits from log if no option is passed', async () => { + await expect(getHashes({}, emptyGit)).resolves.toStrictEqual(commits); + }); + + it('getHashes should get last 2 commits from log if maxCount is set to 2', async () => { + await expect(getHashes({ maxCount: 2 }, emptyGit)).resolves.toStrictEqual( + [commits[1], commits[2]], + ); + }); + + it('getHashes should get commits from log based on "from" and "to"', async () => { + await expect( + getHashes({ from: commits[2], to: commits[0] }, emptyGit), + ).resolves.toEqual([commits[1], commits[2]]); + }); + + it('getHashes should get commits from log based on "from" and "to" and "maxCount"', async () => { + await expect( + getHashes({ from: commits[2], to: commits[0], maxCount: 1 }, emptyGit), + ).resolves.toEqual([commits[2]]); + }); + + it('getHashes should throw if "from" or "to" are invalid', async () => { + await expect( + getHashes({ from: undefined, to: 'a' }, emptyGit), + ).rejects.toThrow('from has to be defined'); + await expect( + getHashes({ from: 'a', to: undefined }, emptyGit), + ).rejects.toThrow('to has to be defined'); + }); + }); +}); diff --git a/packages/core/src/lib/history.ts b/packages/core/src/lib/history.ts new file mode 100644 index 000000000..69ba2be42 --- /dev/null +++ b/packages/core/src/lib/history.ts @@ -0,0 +1,110 @@ +import { LogResult, simpleGit } from 'simple-git'; +import { + CoreConfig, + Format, + PersistConfig, + UploadConfig, + uploadConfigSchema, +} from '@code-pushup/models'; +import { getCurrentBranchOrTag, safeCheckout } from '@code-pushup/utils'; +import { collectAndPersistReports } from './collect-and-persist'; +import { GlobalOptions } from './types'; +import { upload as uploadCommandLogic } from './upload'; + +export type HistoryOnlyOptions = { + targetBranch?: string; + uploadReports?: boolean; + forceCleanStatus?: true; +}; +export type HistoryOptions = Required< + Pick & { + persist: Required; + } & { upload: Required } +> & + GlobalOptions & + HistoryOnlyOptions; + +export async function history( + config: HistoryOptions, + commits: string[], +): Promise { + const initialBranch: string = await getCurrentBranchOrTag(); + + const { uploadReports = true } = config as unknown as HistoryOptions; + if (!uploadReports) { + console.warn('Upload is skipped because uploadReports is set to false'); + } + + const reports: string[] = []; + // eslint-disable-next-line functional/no-loop-statements + for (const commit of commits) { + console.info(`Collect ${commit}`); + await safeCheckout(commit, { forceCleanStatus: config.forceCleanStatus }); + + const currentConfig: HistoryOptions = { + ...config, + persist: { + ...config.persist, + format: ['json' as Format], + filename: `${commit}-report`, + }, + }; + + await collectAndPersistReports(currentConfig); + + if (uploadReports) { + const result = uploadConfigSchema.safeParse(currentConfig.upload); + if (result.success) { + await uploadCommandLogic({ ...currentConfig, upload: result.data }); + } else { + console.error(`Collecting ${commit} failed.`); + console.error(result.error); + } + } + + // eslint-disable-next-line functional/immutable-data + reports.push(currentConfig.persist.filename); + } + + await safeCheckout(initialBranch, { + forceCleanStatus: config.forceCleanStatus, + }); + + return reports; +} + +export async function getHashes( + options: { + from?: string; + to?: string; + maxCount?: number; + } = {}, + git = simpleGit(), +): Promise { + const { from, to, maxCount } = options; + + if (from || to) { + // validate from & to + if (from === undefined || from === '') { + throw new Error('from has to be defined'); + } + if (to === undefined || to === '') { + throw new Error('to has to be defined'); + } + + const logsFromTo = await git.log({ from, to, maxCount }); + return prepareHashes(logsFromTo); + } + + const logs = await git.log(maxCount ? { maxCount } : {}); + return prepareHashes(logs); +} + +export function prepareHashes(logs: LogResult): string[] { + return ( + logs.all + .map(({ hash }) => hash) + // sort from oldest to newest + .reverse() + ); +} diff --git a/packages/core/src/lib/history.unit.test.ts b/packages/core/src/lib/history.unit.test.ts new file mode 100644 index 000000000..91ff10457 --- /dev/null +++ b/packages/core/src/lib/history.unit.test.ts @@ -0,0 +1,137 @@ +import { describe, expect, vi } from 'vitest'; +import { MINIMAL_CONFIG_MOCK } from '@code-pushup/test-utils'; +import { getCurrentBranchOrTag, safeCheckout } from '@code-pushup/utils'; +import { collectAndPersistReports } from './collect-and-persist'; +import { HistoryOptions, history, prepareHashes } from './history'; +import { upload } from './upload'; + +vi.mock('@code-pushup/utils', async () => { + const utils: object = await vi.importActual('@code-pushup/utils'); + let currentBranchOrTag = 'main'; + return { + ...utils, + safeCheckout: vi.fn().mockImplementation((branch: string) => { + currentBranchOrTag = branch; + }), + getCurrentBranchOrTag: vi.fn().mockImplementation(() => currentBranchOrTag), + }; +}); + +vi.mock('./collect-and-persist', () => ({ + collectAndPersistReports: vi.fn(), +})); + +vi.mock('./upload', () => ({ + upload: vi.fn(), +})); + +describe('history', () => { + it('should check out all passed commits and reset to initial branch or tag', async () => { + const historyOptions: HistoryOptions = { + ...(MINIMAL_CONFIG_MOCK as HistoryOptions), + }; + + await history(historyOptions, ['abc', 'def']); + + expect(getCurrentBranchOrTag).toHaveBeenCalledTimes(1); + expect(getCurrentBranchOrTag).toHaveReturnedWith('main'); + + expect(safeCheckout).toHaveBeenCalledTimes(3); + // walk commit history + expect(safeCheckout).toHaveBeenNthCalledWith(1, 'abc', { + forceCleanStatus: undefined, + }); + expect(safeCheckout).toHaveBeenNthCalledWith(2, 'def', { + forceCleanStatus: undefined, + }); + // reset + expect(safeCheckout).toHaveBeenNthCalledWith(3, 'main', { + forceCleanStatus: undefined, + }); + }); + + it('should return correct number of results', async () => { + const historyOptions: HistoryOptions = { + ...(MINIMAL_CONFIG_MOCK as HistoryOptions), + }; + + const results = await history(historyOptions, ['abc', 'def']); + + expect(results).toHaveLength(2); + expect(results).toStrictEqual(['abc-report', 'def-report']); + }); + + it('should call collect with correct filename and format', async () => { + const historyOptions: HistoryOptions = { + ...(MINIMAL_CONFIG_MOCK as HistoryOptions), + }; + + await history(historyOptions, ['abc']); + expect(collectAndPersistReports).toHaveBeenCalledTimes(1); + expect(collectAndPersistReports).toHaveBeenNthCalledWith( + 1, + expect.objectContaining({ + persist: expect.objectContaining({ + filename: 'abc-report', + format: ['json'], + }), + }), + ); + }); + + it('should call upload by default', async () => { + const historyOptions: HistoryOptions = { + ...(MINIMAL_CONFIG_MOCK as HistoryOptions), + upload: { + server: 'https://server.com/api', + project: 'cli', + apiKey: '1234', + organization: 'code-pushup', + timeout: 4000, + }, + }; + await history(historyOptions, ['abc']); + + expect(upload).toHaveBeenCalledTimes(1); + expect(upload).toHaveBeenNthCalledWith( + 1, + expect.objectContaining({ + persist: expect.objectContaining({ filename: 'abc-report' }), + }), + ); + }); + + it('should not call upload if uploadReports is set to false', async () => { + const historyOptions: HistoryOptions = { + ...(MINIMAL_CONFIG_MOCK as HistoryOptions), + upload: { + server: 'https://server.com/api', + project: 'cli', + apiKey: '1234', + organization: 'code-pushup', + timeout: 4000, + }, + uploadReports: false, + }; + await history(historyOptions, ['abc']); + + expect(upload).not.toHaveBeenCalled(); + }); + + it('should not call upload if upload config is not given', async () => { + const historyOptions: HistoryOptions = { + ...(MINIMAL_CONFIG_MOCK as HistoryOptions), + }; + await history(historyOptions, ['abc']); + + expect(upload).not.toHaveBeenCalled(); + }); +}); + +describe('prepareHashes', () => { + it('should get all commits from log if no option is passed', () => { + expect( + prepareHashes({ all: [{ hash: '1' }, { hash: '5' }] }), + ).toStrictEqual(['5', '1']); + }); +}); diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index 1d2609aa9..952da442d 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -40,6 +40,8 @@ export { getLatestCommit, toGitPath, validateCommitData, + getCurrentBranchOrTag, + safeCheckout, } from './lib/git'; export { groupByStatus } from './lib/group-by-status'; export { From 79709e9ba41394a03ca2092dee6bf14f04490868 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 5 Mar 2024 22:29:09 +0100 Subject: [PATCH 02/31] test(core): change test folder --- packages/core/src/lib/history.integration.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/lib/history.integration.test.ts b/packages/core/src/lib/history.integration.test.ts index 5f55e811d..1bc78a0e7 100644 --- a/packages/core/src/lib/history.integration.test.ts +++ b/packages/core/src/lib/history.integration.test.ts @@ -5,7 +5,7 @@ import { afterAll, beforeAll, describe, expect } from 'vitest'; import { getHashes } from './history'; // we need a separate folder that is not cleaned in `global-setup.ts`, otherwise the tests can't execute in parallel -const gitTestFolder = 'git-test'; +const gitTestFolder = 'core-history-git-test'; describe('git utils in a git repo', () => { const baseDir = join(process.cwd(), gitTestFolder); let emptyGit: SimpleGit; From f7845194ecbb9034aff6263338428c683908b6a3 Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Thu, 7 Mar 2024 19:48:02 +0100 Subject: [PATCH 03/31] Update packages/core/src/lib/history.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matěj Chalk <34691111+matejchalk@users.noreply.github.com> --- packages/core/src/lib/history.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/lib/history.ts b/packages/core/src/lib/history.ts index 69ba2be42..ccda215bb 100644 --- a/packages/core/src/lib/history.ts +++ b/packages/core/src/lib/history.ts @@ -30,7 +30,7 @@ export async function history( ): Promise { const initialBranch: string = await getCurrentBranchOrTag(); - const { uploadReports = true } = config as unknown as HistoryOptions; + const { uploadReports = true } = config; if (!uploadReports) { console.warn('Upload is skipped because uploadReports is set to false'); } From 12cc76451906b3935562be6fb3bcb443c70fd010 Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Thu, 7 Mar 2024 19:52:52 +0100 Subject: [PATCH 04/31] Update packages/core/src/lib/history.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matěj Chalk <34691111+matejchalk@users.noreply.github.com> --- packages/core/src/lib/history.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/core/src/lib/history.ts b/packages/core/src/lib/history.ts index ccda215bb..50fbabe93 100644 --- a/packages/core/src/lib/history.ts +++ b/packages/core/src/lib/history.ts @@ -19,7 +19,8 @@ export type HistoryOnlyOptions = { export type HistoryOptions = Required< Pick & { persist: Required; - } & { upload: Required } + upload: Required; + } > & GlobalOptions & HistoryOnlyOptions; From 53e4204db5622bfe5a1649305b5fd18459d89453 Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Thu, 7 Mar 2024 19:53:46 +0100 Subject: [PATCH 05/31] Update packages/core/src/lib/history.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matěj Chalk <34691111+matejchalk@users.noreply.github.com> --- packages/core/src/lib/history.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/lib/history.ts b/packages/core/src/lib/history.ts index 50fbabe93..6ad6a3ac7 100644 --- a/packages/core/src/lib/history.ts +++ b/packages/core/src/lib/history.ts @@ -14,7 +14,7 @@ import { upload as uploadCommandLogic } from './upload'; export type HistoryOnlyOptions = { targetBranch?: string; uploadReports?: boolean; - forceCleanStatus?: true; + forceCleanStatus?: boolean; }; export type HistoryOptions = Required< Pick & { From 34c5eabd0e5545e3079a247777bb414c9fff350c Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Thu, 7 Mar 2024 19:56:11 +0100 Subject: [PATCH 06/31] Update packages/core/src/lib/history.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matěj Chalk <34691111+matejchalk@users.noreply.github.com> --- packages/core/src/lib/history.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/lib/history.ts b/packages/core/src/lib/history.ts index 6ad6a3ac7..0d42a0e83 100644 --- a/packages/core/src/lib/history.ts +++ b/packages/core/src/lib/history.ts @@ -46,7 +46,7 @@ export async function history( ...config, persist: { ...config.persist, - format: ['json' as Format], + format: ['json'], filename: `${commit}-report`, }, }; From 5f63434f4379742990188bac5fdee50800f48d2c Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Thu, 7 Mar 2024 20:08:56 +0100 Subject: [PATCH 07/31] Update packages/core/src/lib/history.unit.test.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matěj Chalk <34691111+matejchalk@users.noreply.github.com> --- packages/core/src/lib/history.unit.test.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/core/src/lib/history.unit.test.ts b/packages/core/src/lib/history.unit.test.ts index 91ff10457..41cb95af2 100644 --- a/packages/core/src/lib/history.unit.test.ts +++ b/packages/core/src/lib/history.unit.test.ts @@ -27,9 +27,7 @@ vi.mock('./upload', () => ({ describe('history', () => { it('should check out all passed commits and reset to initial branch or tag', async () => { - const historyOptions: HistoryOptions = { - ...(MINIMAL_CONFIG_MOCK as HistoryOptions), - }; + const historyOptions = MINIMAL_CONFIG_MOCK as HistoryOptions; await history(historyOptions, ['abc', 'def']); From 0df036755350903ef186b296d8dcd8f4695f3943 Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Thu, 7 Mar 2024 20:09:12 +0100 Subject: [PATCH 08/31] Update packages/core/src/lib/history.unit.test.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matěj Chalk <34691111+matejchalk@users.noreply.github.com> --- packages/core/src/lib/history.unit.test.ts | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/packages/core/src/lib/history.unit.test.ts b/packages/core/src/lib/history.unit.test.ts index 41cb95af2..ffdce24f9 100644 --- a/packages/core/src/lib/history.unit.test.ts +++ b/packages/core/src/lib/history.unit.test.ts @@ -36,16 +36,10 @@ describe('history', () => { expect(safeCheckout).toHaveBeenCalledTimes(3); // walk commit history - expect(safeCheckout).toHaveBeenNthCalledWith(1, 'abc', { - forceCleanStatus: undefined, - }); - expect(safeCheckout).toHaveBeenNthCalledWith(2, 'def', { - forceCleanStatus: undefined, - }); + expect(safeCheckout).toHaveBeenNthCalledWith(1, 'abc', {}); + expect(safeCheckout).toHaveBeenNthCalledWith(2, 'def', {}); // reset - expect(safeCheckout).toHaveBeenNthCalledWith(3, 'main', { - forceCleanStatus: undefined, - }); + expect(safeCheckout).toHaveBeenNthCalledWith(3, 'main', {}); }); it('should return correct number of results', async () => { From fa026f735f155d30b5539267a57815409592a87d Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 7 Mar 2024 20:13:34 +0100 Subject: [PATCH 09/31] refactor(core): adjust history logic --- packages/core/src/lib/history.ts | 31 ++++++++-------------- packages/core/src/lib/history.unit.test.ts | 4 +-- 2 files changed, 13 insertions(+), 22 deletions(-) diff --git a/packages/core/src/lib/history.ts b/packages/core/src/lib/history.ts index 0d42a0e83..2b70c6c01 100644 --- a/packages/core/src/lib/history.ts +++ b/packages/core/src/lib/history.ts @@ -1,25 +1,19 @@ import { LogResult, simpleGit } from 'simple-git'; -import { - CoreConfig, - Format, - PersistConfig, - UploadConfig, - uploadConfigSchema, -} from '@code-pushup/models'; +import { CoreConfig, PersistConfig, UploadConfig } from '@code-pushup/models'; import { getCurrentBranchOrTag, safeCheckout } from '@code-pushup/utils'; import { collectAndPersistReports } from './collect-and-persist'; import { GlobalOptions } from './types'; -import { upload as uploadCommandLogic } from './upload'; +import { upload } from './upload'; export type HistoryOnlyOptions = { targetBranch?: string; - uploadReports?: boolean; + skipUploads?: boolean; forceCleanStatus?: boolean; }; export type HistoryOptions = Required< Pick & { persist: Required; - upload: Required; + upload?: Required; } > & GlobalOptions & @@ -31,10 +25,7 @@ export async function history( ): Promise { const initialBranch: string = await getCurrentBranchOrTag(); - const { uploadReports = true } = config; - if (!uploadReports) { - console.warn('Upload is skipped because uploadReports is set to false'); - } + const { skipUploads = false } = config; const reports: string[] = []; // eslint-disable-next-line functional/no-loop-statements @@ -53,14 +44,14 @@ export async function history( await collectAndPersistReports(currentConfig); - if (uploadReports) { - const result = uploadConfigSchema.safeParse(currentConfig.upload); - if (result.success) { - await uploadCommandLogic({ ...currentConfig, upload: result.data }); + if (!skipUploads) { + if (currentConfig?.upload) { + await upload(currentConfig); } else { - console.error(`Collecting ${commit} failed.`); - console.error(result.error); + console.warn('Upload is skipped because upload config is undefined.'); } + } else { + console.warn('Upload is skipped because skipUploads is set to true.'); } // eslint-disable-next-line functional/immutable-data diff --git a/packages/core/src/lib/history.unit.test.ts b/packages/core/src/lib/history.unit.test.ts index ffdce24f9..99745dd23 100644 --- a/packages/core/src/lib/history.unit.test.ts +++ b/packages/core/src/lib/history.unit.test.ts @@ -93,7 +93,7 @@ describe('history', () => { ); }); - it('should not call upload if uploadReports is set to false', async () => { + it('should not call upload if skipUploads is set to false', async () => { const historyOptions: HistoryOptions = { ...(MINIMAL_CONFIG_MOCK as HistoryOptions), upload: { @@ -103,7 +103,7 @@ describe('history', () => { organization: 'code-pushup', timeout: 4000, }, - uploadReports: false, + skipUploads: true, }; await history(historyOptions, ['abc']); From afd4b7b8224c9eb492d62f963f1cf4078b69010d Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Thu, 7 Mar 2024 20:18:50 +0100 Subject: [PATCH 10/31] Update packages/core/src/lib/history.unit.test.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Katka Pilátová --- packages/core/src/lib/history.unit.test.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/core/src/lib/history.unit.test.ts b/packages/core/src/lib/history.unit.test.ts index 99745dd23..0f6a5f22c 100644 --- a/packages/core/src/lib/history.unit.test.ts +++ b/packages/core/src/lib/history.unit.test.ts @@ -7,15 +7,13 @@ import { upload } from './upload'; vi.mock('@code-pushup/utils', async () => { const utils: object = await vi.importActual('@code-pushup/utils'); - let currentBranchOrTag = 'main'; return { ...utils, - safeCheckout: vi.fn().mockImplementation((branch: string) => { - currentBranchOrTag = branch; - }), - getCurrentBranchOrTag: vi.fn().mockImplementation(() => currentBranchOrTag), + safeCheckout: vi.fn(), + getCurrentBranchOrTag: vi.fn().mockReturnValue('main'), }; }); +}); vi.mock('./collect-and-persist', () => ({ collectAndPersistReports: vi.fn(), From d0c72d6f3c6e03fe7f1bfce37633dc83dedaaff6 Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Thu, 7 Mar 2024 20:19:12 +0100 Subject: [PATCH 11/31] Update packages/core/src/lib/history.unit.test.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Katka Pilátová --- packages/core/src/lib/history.unit.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/core/src/lib/history.unit.test.ts b/packages/core/src/lib/history.unit.test.ts index 0f6a5f22c..e7aa692f4 100644 --- a/packages/core/src/lib/history.unit.test.ts +++ b/packages/core/src/lib/history.unit.test.ts @@ -30,7 +30,6 @@ describe('history', () => { await history(historyOptions, ['abc', 'def']); expect(getCurrentBranchOrTag).toHaveBeenCalledTimes(1); - expect(getCurrentBranchOrTag).toHaveReturnedWith('main'); expect(safeCheckout).toHaveBeenCalledTimes(3); // walk commit history From a982f38e555da590451af70bc3108b625b439bf8 Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Thu, 7 Mar 2024 20:19:25 +0100 Subject: [PATCH 12/31] Update packages/core/src/lib/history.unit.test.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Katka Pilátová --- packages/core/src/lib/history.unit.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/core/src/lib/history.unit.test.ts b/packages/core/src/lib/history.unit.test.ts index e7aa692f4..cf3ef18cf 100644 --- a/packages/core/src/lib/history.unit.test.ts +++ b/packages/core/src/lib/history.unit.test.ts @@ -46,7 +46,6 @@ describe('history', () => { const results = await history(historyOptions, ['abc', 'def']); - expect(results).toHaveLength(2); expect(results).toStrictEqual(['abc-report', 'def-report']); }); From 2390060f65348d75c20d324ea72a428826652cc6 Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Thu, 7 Mar 2024 20:31:39 +0100 Subject: [PATCH 13/31] Update packages/core/src/lib/history.integration.test.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Katka Pilátová --- packages/core/src/lib/history.integration.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/lib/history.integration.test.ts b/packages/core/src/lib/history.integration.test.ts index 1bc78a0e7..ed3ca47ed 100644 --- a/packages/core/src/lib/history.integration.test.ts +++ b/packages/core/src/lib/history.integration.test.ts @@ -37,7 +37,7 @@ describe('git utils in a git repo', () => { await emptyGit.add('README.md'); await emptyGit.commit('Create README'); // eslint-disable-next-line functional/immutable-data - commits.push((await emptyGit.log()).latest?.hash); + commits.push((await emptyGit.log()).latest!.hash); await writeFile(join(baseDir, 'README.md'), '# hello-world-1\n'); await emptyGit.add('README.md'); From 634cde28b58b9487d2d8aafda6d48611565126d6 Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Thu, 7 Mar 2024 20:31:53 +0100 Subject: [PATCH 14/31] Update packages/core/src/lib/history.integration.test.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Katka Pilátová --- packages/core/src/lib/history.integration.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/lib/history.integration.test.ts b/packages/core/src/lib/history.integration.test.ts index ed3ca47ed..9eb28e297 100644 --- a/packages/core/src/lib/history.integration.test.ts +++ b/packages/core/src/lib/history.integration.test.ts @@ -66,7 +66,7 @@ describe('git utils in a git repo', () => { it('getHashes should get last 2 commits from log if maxCount is set to 2', async () => { await expect(getHashes({ maxCount: 2 }, emptyGit)).resolves.toStrictEqual( - [commits[1], commits[2]], + [commits.at(-2), commits.at(-1)], ); }); From 5d8cb50d8e09f6153b857be775047572285c6479 Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Thu, 7 Mar 2024 20:32:00 +0100 Subject: [PATCH 15/31] Update packages/core/src/lib/history.integration.test.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Katka Pilátová --- packages/core/src/lib/history.integration.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/lib/history.integration.test.ts b/packages/core/src/lib/history.integration.test.ts index 9eb28e297..b15e04c8a 100644 --- a/packages/core/src/lib/history.integration.test.ts +++ b/packages/core/src/lib/history.integration.test.ts @@ -6,7 +6,7 @@ import { getHashes } from './history'; // we need a separate folder that is not cleaned in `global-setup.ts`, otherwise the tests can't execute in parallel const gitTestFolder = 'core-history-git-test'; -describe('git utils in a git repo', () => { +describe('getHashes', () => { const baseDir = join(process.cwd(), gitTestFolder); let emptyGit: SimpleGit; From fb3b1dcb41ac87a237416aad621cff6df7d309ee Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Thu, 7 Mar 2024 20:32:07 +0100 Subject: [PATCH 16/31] Update packages/core/src/lib/history.integration.test.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Katka Pilátová --- packages/core/src/lib/history.integration.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/lib/history.integration.test.ts b/packages/core/src/lib/history.integration.test.ts index b15e04c8a..201c4df51 100644 --- a/packages/core/src/lib/history.integration.test.ts +++ b/packages/core/src/lib/history.integration.test.ts @@ -23,7 +23,7 @@ describe('getHashes', () => { }); describe('without a branch and commits', () => { - it('getHashes should throw', async () => { + it('should throw', async () => { await expect(getHashes({}, emptyGit)).rejects.toThrow( "your current branch 'master' does not have any commits yet", ); From b122e4df5d3aa44785ddbee5509a2afefbf0902b Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 7 Mar 2024 20:38:58 +0100 Subject: [PATCH 17/31] test(core): adjust history tests --- .../core/src/lib/history.integration.test.ts | 12 +++--- packages/core/src/lib/history.ts | 31 ++++++-------- packages/core/src/lib/history.unit.test.ts | 41 +++++++++++++++++-- 3 files changed, 56 insertions(+), 28 deletions(-) diff --git a/packages/core/src/lib/history.integration.test.ts b/packages/core/src/lib/history.integration.test.ts index 201c4df51..43b28aacf 100644 --- a/packages/core/src/lib/history.integration.test.ts +++ b/packages/core/src/lib/history.integration.test.ts @@ -4,10 +4,8 @@ import { type SimpleGit, simpleGit } from 'simple-git'; import { afterAll, beforeAll, describe, expect } from 'vitest'; import { getHashes } from './history'; -// we need a separate folder that is not cleaned in `global-setup.ts`, otherwise the tests can't execute in parallel -const gitTestFolder = 'core-history-git-test'; describe('getHashes', () => { - const baseDir = join(process.cwd(), gitTestFolder); + const baseDir = join(process.cwd(), 'tmp', 'core-history-git-test'); let emptyGit: SimpleGit; beforeAll(async () => { @@ -43,13 +41,13 @@ describe('getHashes', () => { await emptyGit.add('README.md'); await emptyGit.commit('Update README 1'); // eslint-disable-next-line functional/immutable-data - commits.push((await emptyGit.log()).latest?.hash); + commits.push((await emptyGit.log()).latest!.hash); await writeFile(join(baseDir, 'README.md'), '# hello-world-2\n'); await emptyGit.add('README.md'); await emptyGit.commit('Update README 2'); // eslint-disable-next-line functional/immutable-data - commits.push((await emptyGit.log()).latest?.hash); + commits.push((await emptyGit.log()).latest!.hash); await emptyGit.branch(['feature-branch']); await emptyGit.checkout(['master']); @@ -73,13 +71,13 @@ describe('getHashes', () => { it('getHashes should get commits from log based on "from" and "to"', async () => { await expect( getHashes({ from: commits[2], to: commits[0] }, emptyGit), - ).resolves.toEqual([commits[1], commits[2]]); + ).resolves.toEqual([commits.at(-2), commits.at(-1)]); }); it('getHashes should get commits from log based on "from" and "to" and "maxCount"', async () => { await expect( getHashes({ from: commits[2], to: commits[0], maxCount: 1 }, emptyGit), - ).resolves.toEqual([commits[2]]); + ).resolves.toEqual([commits.at(-1)]); }); it('getHashes should throw if "from" or "to" are invalid', async () => { diff --git a/packages/core/src/lib/history.ts b/packages/core/src/lib/history.ts index 2b70c6c01..d63d7cd7c 100644 --- a/packages/core/src/lib/history.ts +++ b/packages/core/src/lib/history.ts @@ -10,14 +10,11 @@ export type HistoryOnlyOptions = { skipUploads?: boolean; forceCleanStatus?: boolean; }; -export type HistoryOptions = Required< - Pick & { - persist: Required; - upload?: Required; - } -> & - GlobalOptions & - HistoryOnlyOptions; +export type HistoryOptions = Pick & { + persist: Required; + upload?: Required; +} & HistoryOnlyOptions & + GlobalOptions; export async function history( config: HistoryOptions, @@ -25,18 +22,18 @@ export async function history( ): Promise { const initialBranch: string = await getCurrentBranchOrTag(); - const { skipUploads = false } = config; + const { skipUploads = false, forceCleanStatus, persist } = config; const reports: string[] = []; // eslint-disable-next-line functional/no-loop-statements for (const commit of commits) { console.info(`Collect ${commit}`); - await safeCheckout(commit, { forceCleanStatus: config.forceCleanStatus }); + await safeCheckout(commit, { forceCleanStatus }); const currentConfig: HistoryOptions = { ...config, persist: { - ...config.persist, + ...persist, format: ['json'], filename: `${commit}-report`, }, @@ -44,23 +41,21 @@ export async function history( await collectAndPersistReports(currentConfig); - if (!skipUploads) { - if (currentConfig?.upload) { + if (skipUploads) { + console.warn('Upload is skipped because skipUploads is set to true.'); + } else { + if (currentConfig.upload) { await upload(currentConfig); } else { console.warn('Upload is skipped because upload config is undefined.'); } - } else { - console.warn('Upload is skipped because skipUploads is set to true.'); } // eslint-disable-next-line functional/immutable-data reports.push(currentConfig.persist.filename); } - await safeCheckout(initialBranch, { - forceCleanStatus: config.forceCleanStatus, - }); + await safeCheckout(initialBranch, { forceCleanStatus }); return reports; } diff --git a/packages/core/src/lib/history.unit.test.ts b/packages/core/src/lib/history.unit.test.ts index cf3ef18cf..124a2d006 100644 --- a/packages/core/src/lib/history.unit.test.ts +++ b/packages/core/src/lib/history.unit.test.ts @@ -13,7 +13,6 @@ vi.mock('@code-pushup/utils', async () => { getCurrentBranchOrTag: vi.fn().mockReturnValue('main'), }; }); -}); vi.mock('./collect-and-persist', () => ({ collectAndPersistReports: vi.fn(), @@ -119,7 +118,43 @@ describe('history', () => { describe('prepareHashes', () => { it('should get all commits from log if no option is passed', () => { expect( - prepareHashes({ all: [{ hash: '1' }, { hash: '5' }] }), - ).toStrictEqual(['5', '1']); + prepareHashes({ + all: [ + { + hash: '22287eb716a84f82b5d59e7238ffcae7147f707a', + date: 'Thu Mar 7 20:13:33 2024 +0100', + message: + 'test: replace default (buggy on Windows) with basic reporter', + refs: 'string', + body: 'string', + author_name: 'string', + author_email: 'string', + }, + { + hash: '111b284e48ddf464a498dcf22426a9ce65e2c01c', + date: 'Thu Mar 7 20:13:34 2024 +0100', + message: 'chore: exclude fixtures from ESLint', + refs: 'string', + body: 'string', + author_name: 'string', + author_email: 'string', + }, + ], + total: 2, + latest: { + hash: '22287eb716a84f82b5d59e7238ffcae7147f707a', + date: 'Thu Mar 7 20:13:33 2024 +0100', + message: + 'test: replace default (buggy on Windows) with basic reporter', + refs: 'string', + body: 'string', + author_name: 'string', + author_email: 'string', + }, + }), + ).toStrictEqual([ + '111b284e48ddf464a498dcf22426a9ce65e2c01c', + '22287eb716a84f82b5d59e7238ffcae7147f707a', + ]); }); }); From 3b1c58e3311779afedbda314c4cea1b5e2c401cb Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 7 Mar 2024 20:49:35 +0100 Subject: [PATCH 18/31] test(utils): adjust helper --- packages/core/src/lib/history.ts | 8 +++++--- packages/core/src/lib/history.unit.test.ts | 6 +++--- packages/utils/src/lib/git.integration.test.ts | 8 ++++---- packages/utils/src/lib/git.ts | 6 ++---- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/core/src/lib/history.ts b/packages/core/src/lib/history.ts index d63d7cd7c..40b4ba36e 100644 --- a/packages/core/src/lib/history.ts +++ b/packages/core/src/lib/history.ts @@ -10,7 +10,9 @@ export type HistoryOnlyOptions = { skipUploads?: boolean; forceCleanStatus?: boolean; }; -export type HistoryOptions = Pick & { +export type HistoryOptions = Required< + Pick +> & { persist: Required; upload?: Required; } & HistoryOnlyOptions & @@ -28,7 +30,7 @@ export async function history( // eslint-disable-next-line functional/no-loop-statements for (const commit of commits) { console.info(`Collect ${commit}`); - await safeCheckout(commit, { forceCleanStatus }); + await safeCheckout(commit, forceCleanStatus); const currentConfig: HistoryOptions = { ...config, @@ -55,7 +57,7 @@ export async function history( reports.push(currentConfig.persist.filename); } - await safeCheckout(initialBranch, { forceCleanStatus }); + await safeCheckout(initialBranch, forceCleanStatus); return reports; } diff --git a/packages/core/src/lib/history.unit.test.ts b/packages/core/src/lib/history.unit.test.ts index 124a2d006..e3102255c 100644 --- a/packages/core/src/lib/history.unit.test.ts +++ b/packages/core/src/lib/history.unit.test.ts @@ -32,10 +32,10 @@ describe('history', () => { expect(safeCheckout).toHaveBeenCalledTimes(3); // walk commit history - expect(safeCheckout).toHaveBeenNthCalledWith(1, 'abc', {}); - expect(safeCheckout).toHaveBeenNthCalledWith(2, 'def', {}); + expect(safeCheckout).toHaveBeenNthCalledWith(1, 'abc', undefined); + expect(safeCheckout).toHaveBeenNthCalledWith(2, 'def', undefined); // reset - expect(safeCheckout).toHaveBeenNthCalledWith(3, 'main', {}); + expect(safeCheckout).toHaveBeenNthCalledWith(3, 'main', undefined); }); it('should return correct number of results', async () => { diff --git a/packages/utils/src/lib/git.integration.test.ts b/packages/utils/src/lib/git.integration.test.ts index 99e6abb8d..61df82bc3 100644 --- a/packages/utils/src/lib/git.integration.test.ts +++ b/packages/utils/src/lib/git.integration.test.ts @@ -92,7 +92,7 @@ describe('git utils in a git repo', () => { it('safeCheckout should checkout feature-branch in clean state', async () => { await expect( - safeCheckout('feature-branch', {}, emptyGit), + safeCheckout('feature-branch', undefined, emptyGit), ).resolves.toBeUndefined(); await expect(emptyGit.branch()).resolves.toEqual( expect.objectContaining({ current: 'feature-branch' }), @@ -101,7 +101,7 @@ describe('git utils in a git repo', () => { it('safeCheckout should throw if a given branch does not exist', async () => { await expect( - safeCheckout('non-existing-branch', {}, emptyGit), + safeCheckout('non-existing-branch', undefined, emptyGit), ).rejects.toThrow( "pathspec 'non-existing-branch' did not match any file(s) known to git", ); @@ -142,7 +142,7 @@ describe('git utils in a git repo', () => { it('safeCheckout should clean local changes and check out to feature-branch', async () => { await expect( - safeCheckout('feature-branch', { forceCleanStatus: true }, emptyGit), + safeCheckout('feature-branch', true, emptyGit), ).resolves.toBeUndefined(); await expect(emptyGit.branch()).resolves.toEqual( expect.objectContaining({ current: 'feature-branch' }), @@ -153,7 +153,7 @@ describe('git utils in a git repo', () => { }); it('safeCheckout should throw if history is dirty', async () => { - await expect(safeCheckout('master', {}, emptyGit)).rejects.toThrow( + await expect(safeCheckout('master', undefined, emptyGit)).rejects.toThrow( 'Working directory needs to be clean before we you can proceed. Commit your local changes or stash them.', ); }); diff --git a/packages/utils/src/lib/git.ts b/packages/utils/src/lib/git.ts index 330a2203f..1b5e8a7ea 100644 --- a/packages/utils/src/lib/git.ts +++ b/packages/utils/src/lib/git.ts @@ -70,13 +70,11 @@ export async function getCurrentBranchOrTag( export async function safeCheckout( branchOrHash: string, - options: { - forceCleanStatus?: true; - } = {}, + forceCleanStatus = false, git = simpleGit(), ): Promise { // git requires a clean history to check out a branch - if (options.forceCleanStatus) { + if (forceCleanStatus) { await git.raw(['reset', '--hard']); await git.clean(['f', 'd']); // @TODO replace with ui().logger.info From 1b388f06584394ce51518d1d1db0c770f3c58698 Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Thu, 7 Mar 2024 21:32:48 +0100 Subject: [PATCH 19/31] Update packages/core/src/lib/history.unit.test.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Katka Pilátová --- packages/core/src/lib/history.unit.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/lib/history.unit.test.ts b/packages/core/src/lib/history.unit.test.ts index e3102255c..895f59fc5 100644 --- a/packages/core/src/lib/history.unit.test.ts +++ b/packages/core/src/lib/history.unit.test.ts @@ -116,7 +116,7 @@ describe('history', () => { }); describe('prepareHashes', () => { - it('should get all commits from log if no option is passed', () => { + it('should return commit hashes in reverse order, () => { expect( prepareHashes({ all: [ From 42f8245296bf90852a65d91cb460245081392dfb Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 7 Mar 2024 21:47:20 +0100 Subject: [PATCH 20/31] refactor(core): remove getHashed --- packages/core/src/lib/history.ts | 39 +++++--------------------------- 1 file changed, 6 insertions(+), 33 deletions(-) diff --git a/packages/core/src/lib/history.ts b/packages/core/src/lib/history.ts index 40b4ba36e..a954fa1c4 100644 --- a/packages/core/src/lib/history.ts +++ b/packages/core/src/lib/history.ts @@ -1,9 +1,9 @@ -import { LogResult, simpleGit } from 'simple-git'; -import { CoreConfig, PersistConfig, UploadConfig } from '@code-pushup/models'; -import { getCurrentBranchOrTag, safeCheckout } from '@code-pushup/utils'; -import { collectAndPersistReports } from './collect-and-persist'; -import { GlobalOptions } from './types'; -import { upload } from './upload'; +import {LogResult} from 'simple-git'; +import {CoreConfig, PersistConfig, UploadConfig} from '@code-pushup/models'; +import {getCurrentBranchOrTag, safeCheckout} from '@code-pushup/utils'; +import {collectAndPersistReports} from './collect-and-persist'; +import {GlobalOptions} from './types'; +import {upload} from './upload'; export type HistoryOnlyOptions = { targetBranch?: string; @@ -62,33 +62,6 @@ export async function history( return reports; } -export async function getHashes( - options: { - from?: string; - to?: string; - maxCount?: number; - } = {}, - git = simpleGit(), -): Promise { - const { from, to, maxCount } = options; - - if (from || to) { - // validate from & to - if (from === undefined || from === '') { - throw new Error('from has to be defined'); - } - if (to === undefined || to === '') { - throw new Error('to has to be defined'); - } - - const logsFromTo = await git.log({ from, to, maxCount }); - return prepareHashes(logsFromTo); - } - - const logs = await git.log(maxCount ? { maxCount } : {}); - return prepareHashes(logs); -} - export function prepareHashes(logs: LogResult): string[] { return ( logs.all From b7e318f742570e16ef6c2a0d5e16fe6d8e77457a Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 7 Mar 2024 22:05:05 +0100 Subject: [PATCH 21/31] refactor(core): add LogOptions to history options --- packages/core/src/lib/history.ts | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/packages/core/src/lib/history.ts b/packages/core/src/lib/history.ts index a954fa1c4..77a45afc9 100644 --- a/packages/core/src/lib/history.ts +++ b/packages/core/src/lib/history.ts @@ -1,21 +1,20 @@ -import {LogResult} from 'simple-git'; -import {CoreConfig, PersistConfig, UploadConfig} from '@code-pushup/models'; -import {getCurrentBranchOrTag, safeCheckout} from '@code-pushup/utils'; -import {collectAndPersistReports} from './collect-and-persist'; -import {GlobalOptions} from './types'; -import {upload} from './upload'; +import { LogOptions, LogResult } from 'simple-git'; +import { CoreConfig, PersistConfig, UploadConfig } from '@code-pushup/models'; +import { getCurrentBranchOrTag, safeCheckout } from '@code-pushup/utils'; +import { collectAndPersistReports } from './collect-and-persist'; +import { GlobalOptions } from './types'; +import { upload } from './upload'; export type HistoryOnlyOptions = { targetBranch?: string; skipUploads?: boolean; forceCleanStatus?: boolean; }; -export type HistoryOptions = Required< - Pick -> & { - persist: Required; - upload?: Required; -} & HistoryOnlyOptions & +export type HistoryOptions = Pick & + Required> & { + persist: Required; + upload?: Required; + } & HistoryOnlyOptions & GlobalOptions; export async function history( From 340484ee78e33790dd85aff371bd7a8b2d067a87 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 7 Mar 2024 22:08:54 +0100 Subject: [PATCH 22/31] revert --- packages/core/src/lib/history.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/core/src/lib/history.ts b/packages/core/src/lib/history.ts index 77a45afc9..784731513 100644 --- a/packages/core/src/lib/history.ts +++ b/packages/core/src/lib/history.ts @@ -1,4 +1,4 @@ -import { LogOptions, LogResult } from 'simple-git'; +import { LogResult } from 'simple-git'; import { CoreConfig, PersistConfig, UploadConfig } from '@code-pushup/models'; import { getCurrentBranchOrTag, safeCheckout } from '@code-pushup/utils'; import { collectAndPersistReports } from './collect-and-persist'; @@ -10,8 +10,7 @@ export type HistoryOnlyOptions = { skipUploads?: boolean; forceCleanStatus?: boolean; }; -export type HistoryOptions = Pick & - Required> & { +export type HistoryOptions = Required> & { persist: Required; upload?: Required; } & HistoryOnlyOptions & From ebf503500e183df1a25faea90e76934b82b3d2e9 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 7 Mar 2024 22:35:36 +0100 Subject: [PATCH 23/31] refactor(core): adjust test logic --- .../core/src/lib/history.integration.test.ts | 69 ++++++++++--------- packages/core/src/lib/history.ts | 27 ++++++-- packages/core/src/lib/history.unit.test.ts | 2 +- 3 files changed, 61 insertions(+), 37 deletions(-) diff --git a/packages/core/src/lib/history.integration.test.ts b/packages/core/src/lib/history.integration.test.ts index 43b28aacf..95344cc1b 100644 --- a/packages/core/src/lib/history.integration.test.ts +++ b/packages/core/src/lib/history.integration.test.ts @@ -6,14 +6,14 @@ import { getHashes } from './history'; describe('getHashes', () => { const baseDir = join(process.cwd(), 'tmp', 'core-history-git-test'); - let emptyGit: SimpleGit; + let gitMock: SimpleGit; beforeAll(async () => { await mkdir(baseDir, { recursive: true }); - emptyGit = simpleGit(baseDir); - await emptyGit.init(); - await emptyGit.addConfig('user.name', 'John Doe'); - await emptyGit.addConfig('user.email', 'john.doe@example.com'); + gitMock = simpleGit(baseDir); + await gitMock.init(); + await gitMock.addConfig('user.name', 'John Doe'); + await gitMock.addConfig('user.email', 'john.doe@example.com'); }); afterAll(async () => { @@ -22,7 +22,7 @@ describe('getHashes', () => { describe('without a branch and commits', () => { it('should throw', async () => { - await expect(getHashes({}, emptyGit)).rejects.toThrow( + await expect(getHashes({}, gitMock)).rejects.toThrow( "your current branch 'master' does not have any commits yet", ); }); @@ -32,61 +32,68 @@ describe('getHashes', () => { const commits: string[] = []; beforeAll(async () => { await writeFile(join(baseDir, 'README.md'), '# hello-world\n'); - await emptyGit.add('README.md'); - await emptyGit.commit('Create README'); + await gitMock.add('README.md'); + await gitMock.commit('Create README'); // eslint-disable-next-line functional/immutable-data - commits.push((await emptyGit.log()).latest!.hash); + commits.push((await gitMock.log()).latest!.hash); await writeFile(join(baseDir, 'README.md'), '# hello-world-1\n'); - await emptyGit.add('README.md'); - await emptyGit.commit('Update README 1'); + await gitMock.add('README.md'); + await gitMock.commit('Update README 1'); // eslint-disable-next-line functional/immutable-data - commits.push((await emptyGit.log()).latest!.hash); + commits.push((await gitMock.log()).latest!.hash); await writeFile(join(baseDir, 'README.md'), '# hello-world-2\n'); - await emptyGit.add('README.md'); - await emptyGit.commit('Update README 2'); + await gitMock.add('README.md'); + await gitMock.commit('Update README 2'); // eslint-disable-next-line functional/immutable-data - commits.push((await emptyGit.log()).latest!.hash); + commits.push((await gitMock.log()).latest!.hash); - await emptyGit.branch(['feature-branch']); - await emptyGit.checkout(['master']); + await gitMock.branch(['feature-branch']); + await gitMock.checkout(['master']); }); afterAll(async () => { - await emptyGit.checkout(['master']); - await emptyGit.deleteLocalBranch('feature-branch'); + await gitMock.checkout(['master']); + await gitMock.deleteLocalBranch('feature-branch'); }); it('getHashes should get all commits from log if no option is passed', async () => { - await expect(getHashes({}, emptyGit)).resolves.toStrictEqual(commits); + await expect(getHashes({}, gitMock)).resolves.toStrictEqual(commits); }); it('getHashes should get last 2 commits from log if maxCount is set to 2', async () => { - await expect(getHashes({ maxCount: 2 }, emptyGit)).resolves.toStrictEqual( - [commits.at(-2), commits.at(-1)], - ); + await expect(getHashes({ maxCount: 2 }, gitMock)).resolves.toStrictEqual([ + commits.at(-2), + commits.at(-1), + ]); + }); + + it('getHashes should get commits from log based on "from"', async () => { + await expect( + getHashes({ from: commits.at(0) }, gitMock), + ).resolves.toEqual([commits.at(-2), commits.at(-1)]); }); it('getHashes should get commits from log based on "from" and "to"', async () => { await expect( - getHashes({ from: commits[2], to: commits[0] }, emptyGit), + getHashes({ from: commits.at(-1), to: commits.at(0) }, gitMock), ).resolves.toEqual([commits.at(-2), commits.at(-1)]); }); it('getHashes should get commits from log based on "from" and "to" and "maxCount"', async () => { await expect( - getHashes({ from: commits[2], to: commits[0], maxCount: 1 }, emptyGit), + getHashes( + { from: commits.at(-1), to: commits.at(0), maxCount: 1 }, + gitMock, + ), ).resolves.toEqual([commits.at(-1)]); }); - it('getHashes should throw if "from" or "to" are invalid', async () => { - await expect( - getHashes({ from: undefined, to: 'a' }, emptyGit), - ).rejects.toThrow('from has to be defined'); + it('getHashes should throw if "from" is undefined but "to" is defined', async () => { await expect( - getHashes({ from: 'a', to: undefined }, emptyGit), - ).rejects.toThrow('to has to be defined'); + getHashes({ from: undefined, to: 'a' }, gitMock), + ).rejects.toThrow('from has to be defined if to is defined'); }); }); }); diff --git a/packages/core/src/lib/history.ts b/packages/core/src/lib/history.ts index 784731513..83631abef 100644 --- a/packages/core/src/lib/history.ts +++ b/packages/core/src/lib/history.ts @@ -1,4 +1,4 @@ -import { LogResult } from 'simple-git'; +import { LogOptions, LogResult, simpleGit } from 'simple-git'; import { CoreConfig, PersistConfig, UploadConfig } from '@code-pushup/models'; import { getCurrentBranchOrTag, safeCheckout } from '@code-pushup/utils'; import { collectAndPersistReports } from './collect-and-persist'; @@ -10,10 +10,12 @@ export type HistoryOnlyOptions = { skipUploads?: boolean; forceCleanStatus?: boolean; }; -export type HistoryOptions = Required> & { - persist: Required; - upload?: Required; - } & HistoryOnlyOptions & +export type HistoryOptions = Required< + Pick +> & { + persist: Required; + upload?: Required; +} & HistoryOnlyOptions & GlobalOptions; export async function history( @@ -60,6 +62,21 @@ export async function history( return reports; } +export async function getHashes( + options: LogOptions, + git = simpleGit(), +): Promise { + const { from, to } = options; + + // validate from & to + if (to && (from === '' || from == null)) { + throw new Error('from has to be defined if to is defined'); + } + + const logs = await git.log(options); + return prepareHashes(logs); +} + export function prepareHashes(logs: LogResult): string[] { return ( logs.all diff --git a/packages/core/src/lib/history.unit.test.ts b/packages/core/src/lib/history.unit.test.ts index 895f59fc5..0f1cd38cf 100644 --- a/packages/core/src/lib/history.unit.test.ts +++ b/packages/core/src/lib/history.unit.test.ts @@ -116,7 +116,7 @@ describe('history', () => { }); describe('prepareHashes', () => { - it('should return commit hashes in reverse order, () => { + it('should return commit hashes in reverse order', () => { expect( prepareHashes({ all: [ From 262317b728056810cef67bc82598481e775d6160 Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Fri, 8 Mar 2024 15:10:12 +0100 Subject: [PATCH 24/31] Update packages/core/src/lib/history.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matěj Chalk <34691111+matejchalk@users.noreply.github.com> --- packages/core/src/lib/history.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/lib/history.ts b/packages/core/src/lib/history.ts index 83631abef..7479f6449 100644 --- a/packages/core/src/lib/history.ts +++ b/packages/core/src/lib/history.ts @@ -69,7 +69,7 @@ export async function getHashes( const { from, to } = options; // validate from & to - if (to && (from === '' || from == null)) { + if (to && !from) { throw new Error('from has to be defined if to is defined'); } From 9e796cb8c75baf9ef8c9298b58391599ed98e195 Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Fri, 8 Mar 2024 15:10:54 +0100 Subject: [PATCH 25/31] Update packages/core/src/lib/history.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Katka Pilátová --- packages/core/src/lib/history.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/lib/history.ts b/packages/core/src/lib/history.ts index 7479f6449..95aa3fa7b 100644 --- a/packages/core/src/lib/history.ts +++ b/packages/core/src/lib/history.ts @@ -70,7 +70,7 @@ export async function getHashes( // validate from & to if (to && !from) { - throw new Error('from has to be defined if to is defined'); + throw new Error('git log command needs the "from" option defined to accept the "to" option.'); } const logs = await git.log(options); From 48327d658b21f12ae4edc82586a0ceceb137d489 Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Fri, 8 Mar 2024 15:11:06 +0100 Subject: [PATCH 26/31] Update packages/core/src/lib/history.unit.test.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Katka Pilátová --- packages/core/src/lib/history.unit.test.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/core/src/lib/history.unit.test.ts b/packages/core/src/lib/history.unit.test.ts index 0f1cd38cf..c1f11e725 100644 --- a/packages/core/src/lib/history.unit.test.ts +++ b/packages/core/src/lib/history.unit.test.ts @@ -80,8 +80,7 @@ describe('history', () => { await history(historyOptions, ['abc']); expect(upload).toHaveBeenCalledTimes(1); - expect(upload).toHaveBeenNthCalledWith( - 1, + expect(upload).toHaveBeenCalledWith( expect.objectContaining({ persist: expect.objectContaining({ filename: 'abc-report' }), }), From a4c35a1960505640409456d4f95ee357c1715b39 Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Fri, 8 Mar 2024 15:11:39 +0100 Subject: [PATCH 27/31] Update packages/core/src/lib/history.unit.test.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Katka Pilátová --- packages/core/src/lib/history.unit.test.ts | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/core/src/lib/history.unit.test.ts b/packages/core/src/lib/history.unit.test.ts index c1f11e725..5f6f0ee62 100644 --- a/packages/core/src/lib/history.unit.test.ts +++ b/packages/core/src/lib/history.unit.test.ts @@ -123,20 +123,20 @@ describe('prepareHashes', () => { hash: '22287eb716a84f82b5d59e7238ffcae7147f707a', date: 'Thu Mar 7 20:13:33 2024 +0100', message: - 'test: replace default (buggy on Windows) with basic reporter', + 'test: change test reported to basic in order to work on Windows', refs: 'string', - body: 'string', - author_name: 'string', - author_email: 'string', + body: '', + author_name: 'John Doe', + author_email: 'john.doe@gmail.com', }, { hash: '111b284e48ddf464a498dcf22426a9ce65e2c01c', date: 'Thu Mar 7 20:13:34 2024 +0100', message: 'chore: exclude fixtures from ESLint', refs: 'string', - body: 'string', - author_name: 'string', - author_email: 'string', + body: '', + author_name: 'Jane Doe', + author_email: 'jane.doe@gmail.com', }, ], total: 2, @@ -144,11 +144,11 @@ describe('prepareHashes', () => { hash: '22287eb716a84f82b5d59e7238ffcae7147f707a', date: 'Thu Mar 7 20:13:33 2024 +0100', message: - 'test: replace default (buggy on Windows) with basic reporter', + 'test: change test reported to basic in order to work on Windows', refs: 'string', - body: 'string', - author_name: 'string', - author_email: 'string', + body: '', + author_name: 'John Doe', + author_email: 'john.doe@gmail.com', }, }), ).toStrictEqual([ From b6f62bdf6525f741cb4eb3ba2b9a6d4b142c7b37 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 8 Mar 2024 15:21:17 +0100 Subject: [PATCH 28/31] test(plugin-lighthouse): adjust tests --- packages/core/src/lib/history.ts | 8 +++---- packages/core/src/lib/history.unit.test.ts | 23 ++++++------------- .../src/lib/utils/minimal-config.mock.ts | 9 ++++++++ 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/packages/core/src/lib/history.ts b/packages/core/src/lib/history.ts index 95aa3fa7b..d1f617e10 100644 --- a/packages/core/src/lib/history.ts +++ b/packages/core/src/lib/history.ts @@ -10,13 +10,11 @@ export type HistoryOnlyOptions = { skipUploads?: boolean; forceCleanStatus?: boolean; }; -export type HistoryOptions = Required< - Pick -> & { +export type HistoryOptions = Pick & { persist: Required; upload?: Required; } & HistoryOnlyOptions & - GlobalOptions; + Partial; export async function history( config: HistoryOptions, @@ -68,7 +66,7 @@ export async function getHashes( ): Promise { const { from, to } = options; - // validate from & to + // validate that if to is given also from needs to be given if (to && !from) { throw new Error('git log command needs the "from" option defined to accept the "to" option.'); } diff --git a/packages/core/src/lib/history.unit.test.ts b/packages/core/src/lib/history.unit.test.ts index 5f6f0ee62..1abe6d4a3 100644 --- a/packages/core/src/lib/history.unit.test.ts +++ b/packages/core/src/lib/history.unit.test.ts @@ -1,5 +1,5 @@ import { describe, expect, vi } from 'vitest'; -import { MINIMAL_CONFIG_MOCK } from '@code-pushup/test-utils'; +import { MINIMAL_HISTORY_CONFIG_MOCK } from '@code-pushup/test-utils'; import { getCurrentBranchOrTag, safeCheckout } from '@code-pushup/utils'; import { collectAndPersistReports } from './collect-and-persist'; import { HistoryOptions, history, prepareHashes } from './history'; @@ -24,9 +24,7 @@ vi.mock('./upload', () => ({ describe('history', () => { it('should check out all passed commits and reset to initial branch or tag', async () => { - const historyOptions = MINIMAL_CONFIG_MOCK as HistoryOptions; - - await history(historyOptions, ['abc', 'def']); + await history(MINIMAL_HISTORY_CONFIG_MOCK, ['abc', 'def']); expect(getCurrentBranchOrTag).toHaveBeenCalledTimes(1); @@ -39,9 +37,7 @@ describe('history', () => { }); it('should return correct number of results', async () => { - const historyOptions: HistoryOptions = { - ...(MINIMAL_CONFIG_MOCK as HistoryOptions), - }; + const historyOptions: HistoryOptions = MINIMAL_HISTORY_CONFIG_MOCK; const results = await history(historyOptions, ['abc', 'def']); @@ -49,9 +45,7 @@ describe('history', () => { }); it('should call collect with correct filename and format', async () => { - const historyOptions: HistoryOptions = { - ...(MINIMAL_CONFIG_MOCK as HistoryOptions), - }; + const historyOptions: HistoryOptions = MINIMAL_HISTORY_CONFIG_MOCK; await history(historyOptions, ['abc']); expect(collectAndPersistReports).toHaveBeenCalledTimes(1); @@ -68,7 +62,7 @@ describe('history', () => { it('should call upload by default', async () => { const historyOptions: HistoryOptions = { - ...(MINIMAL_CONFIG_MOCK as HistoryOptions), + ...MINIMAL_HISTORY_CONFIG_MOCK, upload: { server: 'https://server.com/api', project: 'cli', @@ -89,7 +83,7 @@ describe('history', () => { it('should not call upload if skipUploads is set to false', async () => { const historyOptions: HistoryOptions = { - ...(MINIMAL_CONFIG_MOCK as HistoryOptions), + ...MINIMAL_HISTORY_CONFIG_MOCK, upload: { server: 'https://server.com/api', project: 'cli', @@ -105,10 +99,7 @@ describe('history', () => { }); it('should not call upload if upload config is not given', async () => { - const historyOptions: HistoryOptions = { - ...(MINIMAL_CONFIG_MOCK as HistoryOptions), - }; - await history(historyOptions, ['abc']); + await history(MINIMAL_HISTORY_CONFIG_MOCK, ['abc']); expect(upload).not.toHaveBeenCalled(); }); diff --git a/testing/test-utils/src/lib/utils/minimal-config.mock.ts b/testing/test-utils/src/lib/utils/minimal-config.mock.ts index 9a14245f0..f83afd59c 100644 --- a/testing/test-utils/src/lib/utils/minimal-config.mock.ts +++ b/testing/test-utils/src/lib/utils/minimal-config.mock.ts @@ -49,3 +49,12 @@ export const MINIMAL_PLUGIN_CONFIG_MOCK: PluginConfig = { export const MINIMAL_CONFIG_MOCK: CoreConfig = { plugins: [MINIMAL_PLUGIN_CONFIG_MOCK], }; + +export const MINIMAL_HISTORY_CONFIG_MOCK = { + persist: { + outputDir: '.code-pushup', + filename: 'history-report', + format: ['json'], + }, + plugins: [MINIMAL_PLUGIN_CONFIG_MOCK], +} satisfies CoreConfig; From 913a545b9b520dcd99c7d9734cfe01fde747692f Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 8 Mar 2024 15:22:33 +0100 Subject: [PATCH 29/31] test(plugin-lighthouse): adjust tests --- packages/core/src/lib/history.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/core/src/lib/history.ts b/packages/core/src/lib/history.ts index d1f617e10..78b7e9ca5 100644 --- a/packages/core/src/lib/history.ts +++ b/packages/core/src/lib/history.ts @@ -68,7 +68,9 @@ export async function getHashes( // validate that if to is given also from needs to be given if (to && !from) { - throw new Error('git log command needs the "from" option defined to accept the "to" option.'); + throw new Error( + 'git log command needs the "from" option defined to accept the "to" option.', + ); } const logs = await git.log(options); From dcd5ff9b6989682934390207f96db051ec99c40c Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 8 Mar 2024 16:10:05 +0100 Subject: [PATCH 30/31] refactor: adjust typing --- packages/core/src/lib/collect-and-persist.ts | 2 +- packages/core/src/lib/history.integration.test.ts | 4 +++- packages/core/src/lib/history.ts | 4 +++- packages/core/src/lib/implementation/collect.ts | 2 +- packages/core/src/lib/implementation/execute-plugin.ts | 2 +- packages/core/src/lib/upload.ts | 2 +- 6 files changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/core/src/lib/collect-and-persist.ts b/packages/core/src/lib/collect-and-persist.ts index f15a8d5dc..7b9a7cc21 100644 --- a/packages/core/src/lib/collect-and-persist.ts +++ b/packages/core/src/lib/collect-and-persist.ts @@ -10,7 +10,7 @@ import { GlobalOptions } from './types'; export type CollectAndPersistReportsOptions = Required< Pick -> & { persist: Required } & GlobalOptions; +> & { persist: Required } & Partial; export async function collectAndPersistReports( options: CollectAndPersistReportsOptions, diff --git a/packages/core/src/lib/history.integration.test.ts b/packages/core/src/lib/history.integration.test.ts index 95344cc1b..d31d412fb 100644 --- a/packages/core/src/lib/history.integration.test.ts +++ b/packages/core/src/lib/history.integration.test.ts @@ -93,7 +93,9 @@ describe('getHashes', () => { it('getHashes should throw if "from" is undefined but "to" is defined', async () => { await expect( getHashes({ from: undefined, to: 'a' }, gitMock), - ).rejects.toThrow('from has to be defined if to is defined'); + ).rejects.toThrow( + 'git log command needs the "from" option defined to accept the "to" option.', + ); }); }); }); diff --git a/packages/core/src/lib/history.ts b/packages/core/src/lib/history.ts index 78b7e9ca5..4e2a51904 100644 --- a/packages/core/src/lib/history.ts +++ b/packages/core/src/lib/history.ts @@ -10,7 +10,9 @@ export type HistoryOnlyOptions = { skipUploads?: boolean; forceCleanStatus?: boolean; }; -export type HistoryOptions = Pick & { +export type HistoryOptions = Required< + Pick +> & { persist: Required; upload?: Required; } & HistoryOnlyOptions & diff --git a/packages/core/src/lib/implementation/collect.ts b/packages/core/src/lib/implementation/collect.ts index 067fd9b06..1ed43c0cd 100644 --- a/packages/core/src/lib/implementation/collect.ts +++ b/packages/core/src/lib/implementation/collect.ts @@ -7,7 +7,7 @@ import { executePlugins } from './execute-plugin'; export type CollectOptions = Required< Pick > & - GlobalOptions; + Partial; /** * Run audits, collect plugin output and aggregate it into a JSON object diff --git a/packages/core/src/lib/implementation/execute-plugin.ts b/packages/core/src/lib/implementation/execute-plugin.ts index 6633889d4..b3c542ef1 100644 --- a/packages/core/src/lib/implementation/execute-plugin.ts +++ b/packages/core/src/lib/implementation/execute-plugin.ts @@ -118,7 +118,7 @@ export async function executePlugin( */ export async function executePlugins( plugins: PluginConfig[], - options?: { progress: boolean }, + options?: { progress?: boolean }, ): Promise { const { progress = false } = options ?? {}; diff --git a/packages/core/src/lib/upload.ts b/packages/core/src/lib/upload.ts index 2144e5335..168566eb0 100644 --- a/packages/core/src/lib/upload.ts +++ b/packages/core/src/lib/upload.ts @@ -9,7 +9,7 @@ import { GlobalOptions } from './types'; export type UploadOptions = { upload?: UploadConfig } & { persist: Required; -} & GlobalOptions; +} & Partial; /** * Uploads collected audits to the portal From c9aaa3a78ec855a202c76edf3a89037ded813dc2 Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Mon, 11 Mar 2024 12:36:18 +0100 Subject: [PATCH 31/31] Update minimal-config.mock.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matěj Chalk <34691111+matejchalk@users.noreply.github.com> --- testing/test-utils/src/lib/utils/minimal-config.mock.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testing/test-utils/src/lib/utils/minimal-config.mock.ts b/testing/test-utils/src/lib/utils/minimal-config.mock.ts index f83afd59c..8416632d4 100644 --- a/testing/test-utils/src/lib/utils/minimal-config.mock.ts +++ b/testing/test-utils/src/lib/utils/minimal-config.mock.ts @@ -50,11 +50,11 @@ export const MINIMAL_CONFIG_MOCK: CoreConfig = { plugins: [MINIMAL_PLUGIN_CONFIG_MOCK], }; -export const MINIMAL_HISTORY_CONFIG_MOCK = { +export const MINIMAL_HISTORY_CONFIG_MOCK: CoreConfig = { persist: { outputDir: '.code-pushup', filename: 'history-report', format: ['json'], }, plugins: [MINIMAL_PLUGIN_CONFIG_MOCK], -} satisfies CoreConfig; +};