From 3cabbfc77cfb0440f69e57964c128bc84a924687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Nison?= Date: Thu, 26 Oct 2023 14:58:19 +0200 Subject: [PATCH 1/5] Adds tests for the pack list --- .../sources/commands/pack.test.js | 139 +++++++++++++++++- packages/yarnpkg-core/sources/miscUtils.ts | 5 + 2 files changed, 141 insertions(+), 3 deletions(-) diff --git a/packages/acceptance-tests/pkg-tests-specs/sources/commands/pack.test.js b/packages/acceptance-tests/pkg-tests-specs/sources/commands/pack.test.js index 3840d7f226de..d668497d1bb0 100644 --- a/packages/acceptance-tests/pkg-tests-specs/sources/commands/pack.test.js +++ b/packages/acceptance-tests/pkg-tests-specs/sources/commands/pack.test.js @@ -1,9 +1,142 @@ -import {xfs, npath} from '@yarnpkg/fslib'; -import {fs as fsUtils} from 'pkg-tests-core'; -import tar from 'tar'; +import {miscUtils} from '@yarnpkg/core'; +import {xfs, npath, ppath} from '@yarnpkg/fslib'; +import {fs as fsUtils} from 'pkg-tests-core'; +import tar from 'tar'; describe(`Commands`, () => { describe(`pack`, () => { + describe(`pack list`, () => { + const files = [ + `fileX`, + `fileY`, + `folderA/fileX`, + `folderA/fileY`, + `folderA/folderU/fileX`, + `folderA/folderU/fileY`, + `folderA/folderV/fileX`, + `folderA/folderV/fileY`, + `folderB/fileX`, + `folderB/fileY`, + `folderB/folderU/fileX`, + `folderB/folderU/fileY`, + `folderB/folderV/fileX`, + `folderB/folderV/fileY`, + ]; + + const tests = [{ + gitignore: [ + ], + expected: [ + `fileX`, + `fileY`, + `folderA/fileX`, + `folderA/fileY`, + `folderA/folderU/fileX`, + `folderA/folderU/fileY`, + `folderA/folderV/fileX`, + `folderA/folderV/fileY`, + `folderB/fileX`, + `folderB/fileY`, + `folderB/folderU/fileX`, + `folderB/folderU/fileY`, + `folderB/folderV/fileX`, + `folderB/folderV/fileY`, + `package.json`, + ], + }, { + gitignore: [ + `*X`, + ], + expected: [ + `fileY`, + `folderA/fileY`, + `folderA/folderU/fileY`, + `folderA/folderV/fileY`, + `folderB/fileY`, + `folderB/folderU/fileY`, + `folderB/folderV/fileY`, + `package.json`, + ], + }, { + gitignore: [ + `file*`, + `!fileX`, + ], + expected: [ + `fileX`, + `folderA/fileX`, + `folderA/folderU/fileX`, + `folderA/folderV/fileX`, + `folderB/fileX`, + `folderB/folderU/fileX`, + `folderB/folderV/fileX`, + `package.json`, + ], + }, { + gitignore: [ + `file*`, + `!/fileX`, + ], + expected: [ + `fileX`, + `package.json`, + ], + }, { + gitignore: [ + `**/fileX`, + ], + expected: [ + `fileX`, // TODO: Should be ignored + `fileY`, + `folderA/fileY`, + `folderA/folderU/fileY`, + `folderA/folderV/fileY`, + `folderB/fileY`, + `folderB/folderU/fileY`, + `folderB/folderV/fileY`, + `package.json`, + ], + }, { + gitignore: [ + `*`, + `!**/fileX`, + ], + expected: [ + // `fileX`, // TODO: Should not be ignored + `folderA/fileX`, + `folderA/folderU/fileX`, + `folderA/folderV/fileX`, + `folderB/fileX`, + `folderB/folderU/fileX`, + `folderB/folderV/fileX`, + `package.json`, + ], + }]; + + for (const test of tests) { + it(`should return the expected pack list (${test.gitignore.join(`,`)})`, makeTemporaryEnv({}, async ({path, run, source}) => { + await xfs.writeFilePromise(ppath.join(path, `.gitignore`), test.gitignore.join(`\n`)); + + for (const entry of files) { + await xfs.mkdirPromise(ppath.join(path, ppath.dirname(entry)), {recursive: true}); + await xfs.writeFilePromise(ppath.join(path, entry), ``); + } + + await run(`install`); + + const {stdout} = await run(`pack`, `--dry-run`, `--json`); + + const locations = miscUtils.parseJsonStream(stdout).map(entry => { + return entry.location; + }).filter(location => { + return !!location; + }); + + expect(locations).toEqual(test.expected); + })); + } + }); + test( `it should list all the files in a package`, makeTemporaryEnv({}, async ({path, run, source}) => { diff --git a/packages/yarnpkg-core/sources/miscUtils.ts b/packages/yarnpkg-core/sources/miscUtils.ts index 98dcf1f1015c..d75a296e520b 100644 --- a/packages/yarnpkg-core/sources/miscUtils.ts +++ b/packages/yarnpkg-core/sources/miscUtils.ts @@ -598,3 +598,8 @@ export function groupBy, K extends keyof T>(items: export function parseInt(val: string | number) { return typeof val === `string` ? Number.parseInt(val, 10) : val; } + +/** @internal */ +export function parseJsonStream(stream: string) { + return stream.split(/\n/g).filter(line => line.trim() !== ``).map(line => JSON.parse(line)); +} From dd587aaea2c0e9b71d6811c7d3414f3bfb94dc68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Nison?= Date: Thu, 26 Oct 2023 14:58:49 +0200 Subject: [PATCH 2/5] Adds tests for the pack list generation --- .yarn/versions/5452f3ea.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .yarn/versions/5452f3ea.yml diff --git a/.yarn/versions/5452f3ea.yml b/.yarn/versions/5452f3ea.yml new file mode 100644 index 000000000000..a66c07743806 --- /dev/null +++ b/.yarn/versions/5452f3ea.yml @@ -0,0 +1,2 @@ +declined: + - "@yarnpkg/core" From af64fe0ee704c3565a29e280308835bcb905dc68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Nison?= Date: Thu, 26 Oct 2023 16:13:43 +0200 Subject: [PATCH 3/5] Updates the tests --- .../sources/commands/pack.test.js | 287 ++++++++++-------- 1 file changed, 155 insertions(+), 132 deletions(-) diff --git a/packages/acceptance-tests/pkg-tests-specs/sources/commands/pack.test.js b/packages/acceptance-tests/pkg-tests-specs/sources/commands/pack.test.js index d668497d1bb0..d4681944c776 100644 --- a/packages/acceptance-tests/pkg-tests-specs/sources/commands/pack.test.js +++ b/packages/acceptance-tests/pkg-tests-specs/sources/commands/pack.test.js @@ -3,140 +3,18 @@ import {xfs, npath, ppath} from '@yarnpkg/fslib'; import {fs as fsUtils} from 'pkg-tests-core'; import tar from 'tar'; -describe(`Commands`, () => { - describe(`pack`, () => { - describe(`pack list`, () => { - const files = [ - `fileX`, - `fileY`, - `folderA/fileX`, - `folderA/fileY`, - `folderA/folderU/fileX`, - `folderA/folderU/fileY`, - `folderA/folderV/fileX`, - `folderA/folderV/fileY`, - `folderB/fileX`, - `folderB/fileY`, - `folderB/folderU/fileX`, - `folderB/folderU/fileY`, - `folderB/folderV/fileX`, - `folderB/folderV/fileY`, - ]; - - const tests = [{ - gitignore: [ - ], - expected: [ - `fileX`, - `fileY`, - `folderA/fileX`, - `folderA/fileY`, - `folderA/folderU/fileX`, - `folderA/folderU/fileY`, - `folderA/folderV/fileX`, - `folderA/folderV/fileY`, - `folderB/fileX`, - `folderB/fileY`, - `folderB/folderU/fileX`, - `folderB/folderU/fileY`, - `folderB/folderV/fileX`, - `folderB/folderV/fileY`, - `package.json`, - ], - }, { - gitignore: [ - `*X`, - ], - expected: [ - `fileY`, - `folderA/fileY`, - `folderA/folderU/fileY`, - `folderA/folderV/fileY`, - `folderB/fileY`, - `folderB/folderU/fileY`, - `folderB/folderV/fileY`, - `package.json`, - ], - }, { - gitignore: [ - `file*`, - `!fileX`, - ], - expected: [ - `fileX`, - `folderA/fileX`, - `folderA/folderU/fileX`, - `folderA/folderV/fileX`, - `folderB/fileX`, - `folderB/folderU/fileX`, - `folderB/folderV/fileX`, - `package.json`, - ], - }, { - gitignore: [ - `file*`, - `!/fileX`, - ], - expected: [ - `fileX`, - `package.json`, - ], - }, { - gitignore: [ - `**/fileX`, - ], - expected: [ - `fileX`, // TODO: Should be ignored - `fileY`, - `folderA/fileY`, - `folderA/folderU/fileY`, - `folderA/folderV/fileY`, - `folderB/fileY`, - `folderB/folderU/fileY`, - `folderB/folderV/fileY`, - `package.json`, - ], - }, { - gitignore: [ - `*`, - `!**/fileX`, - ], - expected: [ - // `fileX`, // TODO: Should not be ignored - `folderA/fileX`, - `folderA/folderU/fileX`, - `folderA/folderV/fileX`, - `folderB/fileX`, - `folderB/folderU/fileX`, - `folderB/folderV/fileX`, - `package.json`, - ], - }]; - - for (const test of tests) { - it(`should return the expected pack list (${test.gitignore.join(`,`)})`, makeTemporaryEnv({}, async ({path, run, source}) => { - await xfs.writeFilePromise(ppath.join(path, `.gitignore`), test.gitignore.join(`\n`)); - - for (const entry of files) { - await xfs.mkdirPromise(ppath.join(path, ppath.dirname(entry)), {recursive: true}); - await xfs.writeFilePromise(ppath.join(path, entry), ``); - } - - await run(`install`); +async function genPackList(run) { + const {stdout} = await run(`pack`, `--dry-run`, `--json`); - const {stdout} = await run(`pack`, `--dry-run`, `--json`); - - const locations = miscUtils.parseJsonStream(stdout).map(entry => { - return entry.location; - }).filter(location => { - return !!location; - }); - - expect(locations).toEqual(test.expected); - })); - } - }); + return miscUtils.parseJsonStream(stdout).map(entry => { + return entry.location; + }).filter(location => { + return !!location; + }); +} +describe(`Commands`, () => { + describe(`pack`, () => { test( `it should list all the files in a package`, makeTemporaryEnv({}, async ({path, run, source}) => { @@ -449,6 +327,151 @@ describe(`Commands`, () => { }), ); + test( + `it should support gitignore patterns (*)`, + makeTemporaryEnv({}, async ({path, run, source}) => { + await fsUtils.writeFile(`${path}/x.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/y.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/foo/x.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/foo/y.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/.gitignore`, `x.js\n`); + + await run(`install`); + + await expect(genPackList(run)).resolves.toEqual([ + `foo/y.js`, + `package.json`, + `y.js`, + ]); + }), + ); + + test( + `it should allow to explicitly add back a file excluded by a gitignore`, + makeTemporaryEnv({}, async ({path, run, source}) => { + await fsUtils.writeFile(`${path}/x.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/y.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/foo/x.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/foo/y.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/.gitignore`, `*.js\n!x.js\n`); + + await run(`install`); + + await expect(genPackList(run)).resolves.toEqual([ + `foo/x.js`, + `package.json`, + `x.js`, + ]); + }), + ); + + test( + `it should allow to explicitly add back a single file excluded by a gitignore`, + makeTemporaryEnv({}, async ({path, run, source}) => { + await fsUtils.writeFile(`${path}/x.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/y.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/foo/x.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/foo/y.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/.gitignore`, `*.js\n!/x.js\n`); + + await run(`install`); + + await expect(genPackList(run)).resolves.toEqual([ + `package.json`, + `x.js`, + ]); + }), + ); + + test( + `it should support gitignore patterns (**)`, + makeTemporaryEnv({}, async ({path, run, source}) => { + await fsUtils.writeFile(`${path}/x.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/y.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/foo/x.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/foo/y.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/foo/bar/x.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/foo/bar/y.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/.gitignore`, `**/x.js\n`); + + await run(`install`); + + await expect(genPackList(run)).resolves.toEqual([ + `foo/bar/y.js`, + `foo/y.js`, + `package.json`, + `x.js`, // TODO: This shouldn't be here; https://github.com/yarnpkg/berry/issues/5872 + `y.js`, + ]); + }), + ); + + test( + `it should keep digging inside excluded folders (unlike gitignore!)`, + makeTemporaryEnv({}, async ({path, run, source}) => { + await fsUtils.writeFile(`${path}/x.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/y.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/foo/x.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/foo/y.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/foo/bar/x.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/foo/bar/y.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/.gitignore`, `*\n!x.js\n`); + + await run(`install`); + + await expect(genPackList(run)).resolves.toEqual([ + `foo/bar/x.js`, + `foo/x.js`, + `package.json`, + `x.js`, + ]); + }), + ); + + test( + `it should keep digging inside excluded folders (unlike gitignore!)`, + makeTemporaryEnv({}, async ({path, run, source}) => { + await fsUtils.writeFile(`${path}/x.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/y.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/foo/x.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/foo/y.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/foo/bar/x.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/foo/bar/y.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/.gitignore`, `*\n!x.js\n`); + + await run(`install`); + + await expect(genPackList(run)).resolves.toEqual([ + `foo/bar/x.js`, + `foo/x.js`, + `package.json`, + `x.js`, + ]); + }), + ); + + // TODO: https://github.com/yarnpkg/berry/issues/5872 + test.skip( + `it should be possible to re-exclude something which got not-excluded`, + makeTemporaryEnv({}, async ({path, run, source}) => { + await fsUtils.writeFile(`${path}/x.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/y.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/foo/x.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/foo/y.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/foo/bar/x.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/foo/bar/y.js`, `module.exports = 42;\n`); + await fsUtils.writeFile(`${path}/.gitignore`, `*\n!x.js\nfoo/bar\n`); + + await run(`install`); + + await expect(genPackList(run)).resolves.toEqual([ + `foo/x.js`, + `package.json`, + `x.js`, + ]); + }), + ); + test( `it should override fields in the packed manifest`, makeTemporaryEnv({ From f1875e628b0da1686588307c3bfac4af4317fc63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Nison?= Date: Thu, 26 Oct 2023 16:18:41 +0200 Subject: [PATCH 4/5] Fixes lint --- .../pkg-tests-specs/sources/commands/pack.test.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/acceptance-tests/pkg-tests-specs/sources/commands/pack.test.js b/packages/acceptance-tests/pkg-tests-specs/sources/commands/pack.test.js index d4681944c776..a20cefaab7ac 100644 --- a/packages/acceptance-tests/pkg-tests-specs/sources/commands/pack.test.js +++ b/packages/acceptance-tests/pkg-tests-specs/sources/commands/pack.test.js @@ -1,7 +1,7 @@ -import {miscUtils} from '@yarnpkg/core'; -import {xfs, npath, ppath} from '@yarnpkg/fslib'; -import {fs as fsUtils} from 'pkg-tests-core'; -import tar from 'tar'; +import {miscUtils} from '@yarnpkg/core'; +import {xfs, npath} from '@yarnpkg/fslib'; +import {fs as fsUtils} from 'pkg-tests-core'; +import tar from 'tar'; async function genPackList(run) { const {stdout} = await run(`pack`, `--dry-run`, `--json`); From 2df47cb2a6face9aa322819cd9df4a6ae61cfc18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Nison?= Date: Thu, 26 Oct 2023 16:24:07 +0200 Subject: [PATCH 5/5] Removes a duplicate util --- .../pkg-tests-specs/sources/commands/pack.test.js | 13 +++++-------- packages/yarnpkg-core/sources/miscUtils.ts | 5 ----- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/packages/acceptance-tests/pkg-tests-specs/sources/commands/pack.test.js b/packages/acceptance-tests/pkg-tests-specs/sources/commands/pack.test.js index a20cefaab7ac..8cefaf95e194 100644 --- a/packages/acceptance-tests/pkg-tests-specs/sources/commands/pack.test.js +++ b/packages/acceptance-tests/pkg-tests-specs/sources/commands/pack.test.js @@ -1,16 +1,13 @@ -import {miscUtils} from '@yarnpkg/core'; -import {xfs, npath} from '@yarnpkg/fslib'; -import {fs as fsUtils} from 'pkg-tests-core'; -import tar from 'tar'; +import {xfs, npath} from '@yarnpkg/fslib'; +import {fs as fsUtils, misc} from 'pkg-tests-core'; +import tar from 'tar'; async function genPackList(run) { const {stdout} = await run(`pack`, `--dry-run`, `--json`); - return miscUtils.parseJsonStream(stdout).map(entry => { + return misc.parseJsonStream(stdout).map(entry => { return entry.location; - }).filter(location => { - return !!location; - }); + }).filter(location => !!location); } describe(`Commands`, () => { diff --git a/packages/yarnpkg-core/sources/miscUtils.ts b/packages/yarnpkg-core/sources/miscUtils.ts index d75a296e520b..98dcf1f1015c 100644 --- a/packages/yarnpkg-core/sources/miscUtils.ts +++ b/packages/yarnpkg-core/sources/miscUtils.ts @@ -598,8 +598,3 @@ export function groupBy, K extends keyof T>(items: export function parseInt(val: string | number) { return typeof val === `string` ? Number.parseInt(val, 10) : val; } - -/** @internal */ -export function parseJsonStream(stream: string) { - return stream.split(/\n/g).filter(line => line.trim() !== ``).map(line => JSON.parse(line)); -}