From 120ce939e4a26443b33cdfa6554b811a4157d151 Mon Sep 17 00:00:00 2001 From: Nicolas Beaussart Date: Mon, 16 Oct 2023 17:30:14 +0200 Subject: [PATCH 1/7] Add test suite for all current config loading systems --- fixtures/config/js-flat/dangling.js | 1 + fixtures/config/js-flat/index.js | 3 +++ fixtures/config/js-flat/knip.js | 3 +++ fixtures/config/js-flat/my-namespace.js | 2 ++ fixtures/config/js-flat/package.json | 3 +++ fixtures/config/json/dangling.js | 1 + fixtures/config/json/index.js | 3 +++ fixtures/config/json/knip.json | 3 +++ fixtures/config/json/my-namespace.js | 2 ++ fixtures/config/json/package.json | 3 +++ fixtures/config/mjs-flat/dangling.js | 1 + fixtures/config/mjs-flat/index.js | 3 +++ fixtures/config/mjs-flat/knip.mjs | 5 ++++ fixtures/config/mjs-flat/my-namespace.js | 2 ++ fixtures/config/mjs-flat/package.json | 3 +++ fixtures/config/package-json/dangling.js | 1 + fixtures/config/package-json/index.js | 3 +++ fixtures/config/package-json/my-namespace.js | 2 ++ fixtures/config/package-json/package.json | 6 +++++ fixtures/config/ts-flat/dangling.js | 1 + fixtures/config/ts-flat/index.js | 3 +++ fixtures/config/ts-flat/knip.ts | 7 ++++++ fixtures/config/ts-flat/my-namespace.js | 2 ++ fixtures/config/ts-flat/package.json | 3 +++ fixtures/config/ts-flat/tsconfig.json | 5 ++++ fixtures/config/yaml/dangling.js | 1 + fixtures/config/yaml/index.js | 3 +++ fixtures/config/yaml/knip.yaml | 2 ++ fixtures/config/yaml/my-namespace.js | 2 ++ fixtures/config/yaml/package.json | 3 +++ test/config/js-flat.test.ts | 23 ++++++++++++++++++ test/config/json.test.ts | 25 ++++++++++++++++++++ test/config/mjs-flat.test.ts | 23 ++++++++++++++++++ test/config/package-json.test.ts | 22 +++++++++++++++++ test/config/ts-flat.test.ts | 23 ++++++++++++++++++ test/config/yaml.test.ts | 23 ++++++++++++++++++ 36 files changed, 221 insertions(+) create mode 100644 fixtures/config/js-flat/dangling.js create mode 100644 fixtures/config/js-flat/index.js create mode 100644 fixtures/config/js-flat/knip.js create mode 100644 fixtures/config/js-flat/my-namespace.js create mode 100644 fixtures/config/js-flat/package.json create mode 100644 fixtures/config/json/dangling.js create mode 100644 fixtures/config/json/index.js create mode 100644 fixtures/config/json/knip.json create mode 100644 fixtures/config/json/my-namespace.js create mode 100644 fixtures/config/json/package.json create mode 100644 fixtures/config/mjs-flat/dangling.js create mode 100644 fixtures/config/mjs-flat/index.js create mode 100644 fixtures/config/mjs-flat/knip.mjs create mode 100644 fixtures/config/mjs-flat/my-namespace.js create mode 100644 fixtures/config/mjs-flat/package.json create mode 100644 fixtures/config/package-json/dangling.js create mode 100644 fixtures/config/package-json/index.js create mode 100644 fixtures/config/package-json/my-namespace.js create mode 100644 fixtures/config/package-json/package.json create mode 100644 fixtures/config/ts-flat/dangling.js create mode 100644 fixtures/config/ts-flat/index.js create mode 100644 fixtures/config/ts-flat/knip.ts create mode 100644 fixtures/config/ts-flat/my-namespace.js create mode 100644 fixtures/config/ts-flat/package.json create mode 100644 fixtures/config/ts-flat/tsconfig.json create mode 100644 fixtures/config/yaml/dangling.js create mode 100644 fixtures/config/yaml/index.js create mode 100644 fixtures/config/yaml/knip.yaml create mode 100644 fixtures/config/yaml/my-namespace.js create mode 100644 fixtures/config/yaml/package.json create mode 100644 test/config/js-flat.test.ts create mode 100644 test/config/json.test.ts create mode 100644 test/config/mjs-flat.test.ts create mode 100644 test/config/package-json.test.ts create mode 100644 test/config/ts-flat.test.ts create mode 100644 test/config/yaml.test.ts diff --git a/fixtures/config/js-flat/dangling.js b/fixtures/config/js-flat/dangling.js new file mode 100644 index 000000000..da3e9a39d --- /dev/null +++ b/fixtures/config/js-flat/dangling.js @@ -0,0 +1 @@ +export const unusedFile = true; diff --git a/fixtures/config/js-flat/index.js b/fixtures/config/js-flat/index.js new file mode 100644 index 000000000..b2da10dcc --- /dev/null +++ b/fixtures/config/js-flat/index.js @@ -0,0 +1,3 @@ +import * as MyNamespace from './my-namespace'; + +export const b = MyNamespace.y; diff --git a/fixtures/config/js-flat/knip.js b/fixtures/config/js-flat/knip.js new file mode 100644 index 000000000..2255bd75d --- /dev/null +++ b/fixtures/config/js-flat/knip.js @@ -0,0 +1,3 @@ +module.exports = { + ignore: ['dangling.js'] +} \ No newline at end of file diff --git a/fixtures/config/js-flat/my-namespace.js b/fixtures/config/js-flat/my-namespace.js new file mode 100644 index 000000000..185fbbd06 --- /dev/null +++ b/fixtures/config/js-flat/my-namespace.js @@ -0,0 +1,2 @@ +const x = 1; +export const y = () => x; diff --git a/fixtures/config/js-flat/package.json b/fixtures/config/js-flat/package.json new file mode 100644 index 000000000..1a0994fc4 --- /dev/null +++ b/fixtures/config/js-flat/package.json @@ -0,0 +1,3 @@ +{ + "name": "@fixtures/cli" +} diff --git a/fixtures/config/json/dangling.js b/fixtures/config/json/dangling.js new file mode 100644 index 000000000..da3e9a39d --- /dev/null +++ b/fixtures/config/json/dangling.js @@ -0,0 +1 @@ +export const unusedFile = true; diff --git a/fixtures/config/json/index.js b/fixtures/config/json/index.js new file mode 100644 index 000000000..b2da10dcc --- /dev/null +++ b/fixtures/config/json/index.js @@ -0,0 +1,3 @@ +import * as MyNamespace from './my-namespace'; + +export const b = MyNamespace.y; diff --git a/fixtures/config/json/knip.json b/fixtures/config/json/knip.json new file mode 100644 index 000000000..5ba6e3a51 --- /dev/null +++ b/fixtures/config/json/knip.json @@ -0,0 +1,3 @@ +{ + "ignore": ["dangling.js"] +} \ No newline at end of file diff --git a/fixtures/config/json/my-namespace.js b/fixtures/config/json/my-namespace.js new file mode 100644 index 000000000..185fbbd06 --- /dev/null +++ b/fixtures/config/json/my-namespace.js @@ -0,0 +1,2 @@ +const x = 1; +export const y = () => x; diff --git a/fixtures/config/json/package.json b/fixtures/config/json/package.json new file mode 100644 index 000000000..1a0994fc4 --- /dev/null +++ b/fixtures/config/json/package.json @@ -0,0 +1,3 @@ +{ + "name": "@fixtures/cli" +} diff --git a/fixtures/config/mjs-flat/dangling.js b/fixtures/config/mjs-flat/dangling.js new file mode 100644 index 000000000..da3e9a39d --- /dev/null +++ b/fixtures/config/mjs-flat/dangling.js @@ -0,0 +1 @@ +export const unusedFile = true; diff --git a/fixtures/config/mjs-flat/index.js b/fixtures/config/mjs-flat/index.js new file mode 100644 index 000000000..b2da10dcc --- /dev/null +++ b/fixtures/config/mjs-flat/index.js @@ -0,0 +1,3 @@ +import * as MyNamespace from './my-namespace'; + +export const b = MyNamespace.y; diff --git a/fixtures/config/mjs-flat/knip.mjs b/fixtures/config/mjs-flat/knip.mjs new file mode 100644 index 000000000..356e0177a --- /dev/null +++ b/fixtures/config/mjs-flat/knip.mjs @@ -0,0 +1,5 @@ +const config = { + ignore: ['dangling.js'], +}; + +export default config; diff --git a/fixtures/config/mjs-flat/my-namespace.js b/fixtures/config/mjs-flat/my-namespace.js new file mode 100644 index 000000000..185fbbd06 --- /dev/null +++ b/fixtures/config/mjs-flat/my-namespace.js @@ -0,0 +1,2 @@ +const x = 1; +export const y = () => x; diff --git a/fixtures/config/mjs-flat/package.json b/fixtures/config/mjs-flat/package.json new file mode 100644 index 000000000..1a0994fc4 --- /dev/null +++ b/fixtures/config/mjs-flat/package.json @@ -0,0 +1,3 @@ +{ + "name": "@fixtures/cli" +} diff --git a/fixtures/config/package-json/dangling.js b/fixtures/config/package-json/dangling.js new file mode 100644 index 000000000..da3e9a39d --- /dev/null +++ b/fixtures/config/package-json/dangling.js @@ -0,0 +1 @@ +export const unusedFile = true; diff --git a/fixtures/config/package-json/index.js b/fixtures/config/package-json/index.js new file mode 100644 index 000000000..b2da10dcc --- /dev/null +++ b/fixtures/config/package-json/index.js @@ -0,0 +1,3 @@ +import * as MyNamespace from './my-namespace'; + +export const b = MyNamespace.y; diff --git a/fixtures/config/package-json/my-namespace.js b/fixtures/config/package-json/my-namespace.js new file mode 100644 index 000000000..185fbbd06 --- /dev/null +++ b/fixtures/config/package-json/my-namespace.js @@ -0,0 +1,2 @@ +const x = 1; +export const y = () => x; diff --git a/fixtures/config/package-json/package.json b/fixtures/config/package-json/package.json new file mode 100644 index 000000000..bc8b9a238 --- /dev/null +++ b/fixtures/config/package-json/package.json @@ -0,0 +1,6 @@ +{ + "name": "@fixtures/cli", + "knip": { + "ignore": ["dangling.js"] + } +} diff --git a/fixtures/config/ts-flat/dangling.js b/fixtures/config/ts-flat/dangling.js new file mode 100644 index 000000000..da3e9a39d --- /dev/null +++ b/fixtures/config/ts-flat/dangling.js @@ -0,0 +1 @@ +export const unusedFile = true; diff --git a/fixtures/config/ts-flat/index.js b/fixtures/config/ts-flat/index.js new file mode 100644 index 000000000..b2da10dcc --- /dev/null +++ b/fixtures/config/ts-flat/index.js @@ -0,0 +1,3 @@ +import * as MyNamespace from './my-namespace'; + +export const b = MyNamespace.y; diff --git a/fixtures/config/ts-flat/knip.ts b/fixtures/config/ts-flat/knip.ts new file mode 100644 index 000000000..94c91c00f --- /dev/null +++ b/fixtures/config/ts-flat/knip.ts @@ -0,0 +1,7 @@ +import type { KnipConfig } from '../../../src/index'; + +const config: KnipConfig = { + ignore: ['dangling.js'], +}; + +export default config; diff --git a/fixtures/config/ts-flat/my-namespace.js b/fixtures/config/ts-flat/my-namespace.js new file mode 100644 index 000000000..185fbbd06 --- /dev/null +++ b/fixtures/config/ts-flat/my-namespace.js @@ -0,0 +1,2 @@ +const x = 1; +export const y = () => x; diff --git a/fixtures/config/ts-flat/package.json b/fixtures/config/ts-flat/package.json new file mode 100644 index 000000000..1a0994fc4 --- /dev/null +++ b/fixtures/config/ts-flat/package.json @@ -0,0 +1,3 @@ +{ + "name": "@fixtures/cli" +} diff --git a/fixtures/config/ts-flat/tsconfig.json b/fixtures/config/ts-flat/tsconfig.json new file mode 100644 index 000000000..7812f071f --- /dev/null +++ b/fixtures/config/ts-flat/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "types": ["node"] + } +} diff --git a/fixtures/config/yaml/dangling.js b/fixtures/config/yaml/dangling.js new file mode 100644 index 000000000..da3e9a39d --- /dev/null +++ b/fixtures/config/yaml/dangling.js @@ -0,0 +1 @@ +export const unusedFile = true; diff --git a/fixtures/config/yaml/index.js b/fixtures/config/yaml/index.js new file mode 100644 index 000000000..b2da10dcc --- /dev/null +++ b/fixtures/config/yaml/index.js @@ -0,0 +1,3 @@ +import * as MyNamespace from './my-namespace'; + +export const b = MyNamespace.y; diff --git a/fixtures/config/yaml/knip.yaml b/fixtures/config/yaml/knip.yaml new file mode 100644 index 000000000..3adadc659 --- /dev/null +++ b/fixtures/config/yaml/knip.yaml @@ -0,0 +1,2 @@ +ignore: + - 'dangling.js' \ No newline at end of file diff --git a/fixtures/config/yaml/my-namespace.js b/fixtures/config/yaml/my-namespace.js new file mode 100644 index 000000000..185fbbd06 --- /dev/null +++ b/fixtures/config/yaml/my-namespace.js @@ -0,0 +1,2 @@ +const x = 1; +export const y = () => x; diff --git a/fixtures/config/yaml/package.json b/fixtures/config/yaml/package.json new file mode 100644 index 000000000..1a0994fc4 --- /dev/null +++ b/fixtures/config/yaml/package.json @@ -0,0 +1,3 @@ +{ + "name": "@fixtures/cli" +} diff --git a/test/config/js-flat.test.ts b/test/config/js-flat.test.ts new file mode 100644 index 000000000..bf4f8b29a --- /dev/null +++ b/test/config/js-flat.test.ts @@ -0,0 +1,23 @@ +import assert from 'node:assert/strict'; +import { execSync } from 'node:child_process'; +import test from 'node:test'; +import { resolve } from '../../src/util/path.js'; + +const cwd = resolve('fixtures/config/js-flat'); + +const exec = (command: string) => { + try { + const output = execSync(command.replace(/^knip/, 'node ../../../dist/cli.js'), { cwd }); + return output.toString().trim(); + } catch (error) { + if (error instanceof Error && 'stdout' in error && Buffer.isBuffer(error['stdout'])) { + return error['stdout'].toString(); + } + // Unknown error + throw error; + } +}; + +test('Support loading js object files for configuration', async () => { + assert.equal(exec('knip'), ''); +}); diff --git a/test/config/json.test.ts b/test/config/json.test.ts new file mode 100644 index 000000000..d903af049 --- /dev/null +++ b/test/config/json.test.ts @@ -0,0 +1,25 @@ +import assert from 'node:assert/strict'; +import { execSync } from 'node:child_process'; +import test from 'node:test'; +import { resolve } from '../../src/util/path.js'; + + +const cwd = resolve('fixtures/config/json'); + +const exec = (command: string) => { + try { + const output = execSync(command.replace(/^knip/, 'node ../../../dist/cli.js'), { cwd }); + return output.toString().trim(); + } catch (error) { + if (error instanceof Error && 'stdout' in error && Buffer.isBuffer(error['stdout'])) { + return error['stdout'].toString(); + } + // Unknown error + throw error; + } +}; + + +test('Support loading json files for configuration', async () => { + assert.equal(exec('knip'), ''); +}); diff --git a/test/config/mjs-flat.test.ts b/test/config/mjs-flat.test.ts new file mode 100644 index 000000000..f5ece28fc --- /dev/null +++ b/test/config/mjs-flat.test.ts @@ -0,0 +1,23 @@ +import assert from 'node:assert/strict'; +import { execSync } from 'node:child_process'; +import test from 'node:test'; +import { resolve } from '../../src/util/path.js'; + +const cwd = resolve('fixtures/config/mjs-flat'); + +const exec = (command: string) => { + try { + const output = execSync(command.replace(/^knip/, 'node ../../../dist/cli.js'), { cwd }); + return output.toString().trim(); + } catch (error) { + if (error instanceof Error && 'stdout' in error && Buffer.isBuffer(error['stdout'])) { + return error['stdout'].toString(); + } + // Unknown error + throw error; + } +}; + +test('Support loading mjs object files for configuration', async () => { + assert.equal(exec('knip -c knip.mjs'), ''); +}); diff --git a/test/config/package-json.test.ts b/test/config/package-json.test.ts new file mode 100644 index 000000000..387b4d6a3 --- /dev/null +++ b/test/config/package-json.test.ts @@ -0,0 +1,22 @@ +import assert from 'node:assert/strict'; +import { execSync } from 'node:child_process'; +import test from 'node:test'; +import { resolve } from '../../src/util/path.js'; + +const cwd = resolve('fixtures/config/package-json'); + +const exec = (command: string) => { + try { + const output = execSync(command.replace(/^knip/, 'node ../../../dist/cli.js'), { cwd }); + return output.toString().trim(); + } catch (error) { + if (error instanceof Error && 'stdout' in error && Buffer.isBuffer(error['stdout'])) { + return error['stdout'].toString(); + } + // Unknown error + throw error; + } +}; +test('Support loading package.json for configuration', async () => { + assert.equal(exec('knip'), ''); +}); diff --git a/test/config/ts-flat.test.ts b/test/config/ts-flat.test.ts new file mode 100644 index 000000000..0ba0c5cbd --- /dev/null +++ b/test/config/ts-flat.test.ts @@ -0,0 +1,23 @@ +import assert from 'node:assert/strict'; +import { execSync } from 'node:child_process'; +import test from 'node:test'; +import { resolve } from '../../src/util/path.js'; + +const cwd = resolve('fixtures/config/ts-flat'); + +const exec = (command: string) => { + try { + const output = execSync(command.replace(/^knip/, 'node ../../../dist/cli.js'), { cwd }); + return output.toString().trim(); + } catch (error) { + if (error instanceof Error && 'stdout' in error && Buffer.isBuffer(error['stdout'])) { + return error['stdout'].toString(); + } + // Unknown error + throw error; + } +}; + +test('Support loading ts object files for configuration', async () => { + assert.equal(exec('knip'), ''); +}); diff --git a/test/config/yaml.test.ts b/test/config/yaml.test.ts new file mode 100644 index 000000000..5b6a19d68 --- /dev/null +++ b/test/config/yaml.test.ts @@ -0,0 +1,23 @@ +import assert from 'node:assert/strict'; +import { execSync } from 'node:child_process'; +import test from 'node:test'; +import { resolve } from '../../src/util/path.js'; + +const cwd = resolve('fixtures/config/yaml'); + +const exec = (command: string) => { + try { + const output = execSync(command.replace(/^knip/, 'node ../../../dist/cli.js'), { cwd }); + return output.toString().trim(); + } catch (error) { + if (error instanceof Error && 'stdout' in error && Buffer.isBuffer(error['stdout'])) { + return error['stdout'].toString(); + } + // Unknown error + throw error; + } +}; + +test('Support loading yaml files for configuration', async () => { + assert.equal(exec('knip -c knip.yaml'), ''); +}); From ce03ca0fbe026a52466f322d70ed4f3eed32a63a Mon Sep 17 00:00:00 2001 From: Nicolas Beaussart Date: Mon, 16 Oct 2023 20:45:09 +0200 Subject: [PATCH 2/7] Introduce async and function config factories --- README.md | 13 ++++++++++++ fixtures/config/js-async/dangling.js | 1 + fixtures/config/js-async/index.js | 3 +++ fixtures/config/js-async/knip.js | 3 +++ fixtures/config/js-async/my-namespace.js | 2 ++ fixtures/config/js-async/package.json | 3 +++ fixtures/config/mjs-async/dangling.js | 1 + fixtures/config/mjs-async/index.js | 3 +++ fixtures/config/mjs-async/knip.mjs | 5 +++++ fixtures/config/mjs-async/my-namespace.js | 2 ++ fixtures/config/mjs-async/package.json | 3 +++ fixtures/config/ts-async/dangling.js | 1 + fixtures/config/ts-async/index.js | 3 +++ fixtures/config/ts-async/knip.ts | 7 +++++++ fixtures/config/ts-async/my-namespace.js | 2 ++ fixtures/config/ts-async/package.json | 3 +++ fixtures/config/ts-async/tsconfig.json | 5 +++++ fixtures/config/ts-function/dangling.js | 1 + fixtures/config/ts-function/index.js | 3 +++ fixtures/config/ts-function/knip.ts | 7 +++++++ fixtures/config/ts-function/my-namespace.js | 2 ++ fixtures/config/ts-function/package.json | 3 +++ fixtures/config/ts-function/tsconfig.json | 5 +++++ src/ConfigurationChief.ts | 14 ++++++++++++- src/util/unwrapFunction.ts | 13 ++++++++++++ test/config/js-async.test.ts | 23 +++++++++++++++++++++ test/config/mjs-async.test.ts | 23 +++++++++++++++++++++ test/config/ts-async.test.ts | 23 +++++++++++++++++++++ test/config/ts-function.test.ts | 23 +++++++++++++++++++++ 29 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 fixtures/config/js-async/dangling.js create mode 100644 fixtures/config/js-async/index.js create mode 100644 fixtures/config/js-async/knip.js create mode 100644 fixtures/config/js-async/my-namespace.js create mode 100644 fixtures/config/js-async/package.json create mode 100644 fixtures/config/mjs-async/dangling.js create mode 100644 fixtures/config/mjs-async/index.js create mode 100644 fixtures/config/mjs-async/knip.mjs create mode 100644 fixtures/config/mjs-async/my-namespace.js create mode 100644 fixtures/config/mjs-async/package.json create mode 100644 fixtures/config/ts-async/dangling.js create mode 100644 fixtures/config/ts-async/index.js create mode 100644 fixtures/config/ts-async/knip.ts create mode 100644 fixtures/config/ts-async/my-namespace.js create mode 100644 fixtures/config/ts-async/package.json create mode 100644 fixtures/config/ts-async/tsconfig.json create mode 100644 fixtures/config/ts-function/dangling.js create mode 100644 fixtures/config/ts-function/index.js create mode 100644 fixtures/config/ts-function/knip.ts create mode 100644 fixtures/config/ts-function/my-namespace.js create mode 100644 fixtures/config/ts-function/package.json create mode 100644 fixtures/config/ts-function/tsconfig.json create mode 100644 src/util/unwrapFunction.ts create mode 100644 test/config/js-async.test.ts create mode 100644 test/config/mjs-async.test.ts create mode 100644 test/config/ts-async.test.ts create mode 100644 test/config/ts-function.test.ts diff --git a/README.md b/README.md index 6f3da4225..ff620681f 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,19 @@ const config: KnipConfig = { export default config; ``` +And if you need, you can also expose a function or an async function if you need, like so : + +```ts +import type { KnipConfig } from 'knip'; + +const config = async (): Promise => ({ + entry: ['src/index.ts'], + project: ['src/**/*.ts'], +}); + +export default config; +``` + Use `--config path/to/knip.config.json` for a different path. ### Let's Go! diff --git a/fixtures/config/js-async/dangling.js b/fixtures/config/js-async/dangling.js new file mode 100644 index 000000000..da3e9a39d --- /dev/null +++ b/fixtures/config/js-async/dangling.js @@ -0,0 +1 @@ +export const unusedFile = true; diff --git a/fixtures/config/js-async/index.js b/fixtures/config/js-async/index.js new file mode 100644 index 000000000..b2da10dcc --- /dev/null +++ b/fixtures/config/js-async/index.js @@ -0,0 +1,3 @@ +import * as MyNamespace from './my-namespace'; + +export const b = MyNamespace.y; diff --git a/fixtures/config/js-async/knip.js b/fixtures/config/js-async/knip.js new file mode 100644 index 000000000..977f2910e --- /dev/null +++ b/fixtures/config/js-async/knip.js @@ -0,0 +1,3 @@ +module.exports = async () => ({ + ignore: ['dangling.js'] +}); \ No newline at end of file diff --git a/fixtures/config/js-async/my-namespace.js b/fixtures/config/js-async/my-namespace.js new file mode 100644 index 000000000..185fbbd06 --- /dev/null +++ b/fixtures/config/js-async/my-namespace.js @@ -0,0 +1,2 @@ +const x = 1; +export const y = () => x; diff --git a/fixtures/config/js-async/package.json b/fixtures/config/js-async/package.json new file mode 100644 index 000000000..1a0994fc4 --- /dev/null +++ b/fixtures/config/js-async/package.json @@ -0,0 +1,3 @@ +{ + "name": "@fixtures/cli" +} diff --git a/fixtures/config/mjs-async/dangling.js b/fixtures/config/mjs-async/dangling.js new file mode 100644 index 000000000..da3e9a39d --- /dev/null +++ b/fixtures/config/mjs-async/dangling.js @@ -0,0 +1 @@ +export const unusedFile = true; diff --git a/fixtures/config/mjs-async/index.js b/fixtures/config/mjs-async/index.js new file mode 100644 index 000000000..b2da10dcc --- /dev/null +++ b/fixtures/config/mjs-async/index.js @@ -0,0 +1,3 @@ +import * as MyNamespace from './my-namespace'; + +export const b = MyNamespace.y; diff --git a/fixtures/config/mjs-async/knip.mjs b/fixtures/config/mjs-async/knip.mjs new file mode 100644 index 000000000..b655d548c --- /dev/null +++ b/fixtures/config/mjs-async/knip.mjs @@ -0,0 +1,5 @@ +const config = async () => ({ + ignore: ['dangling.js'], +}); + +export default config; diff --git a/fixtures/config/mjs-async/my-namespace.js b/fixtures/config/mjs-async/my-namespace.js new file mode 100644 index 000000000..185fbbd06 --- /dev/null +++ b/fixtures/config/mjs-async/my-namespace.js @@ -0,0 +1,2 @@ +const x = 1; +export const y = () => x; diff --git a/fixtures/config/mjs-async/package.json b/fixtures/config/mjs-async/package.json new file mode 100644 index 000000000..1a0994fc4 --- /dev/null +++ b/fixtures/config/mjs-async/package.json @@ -0,0 +1,3 @@ +{ + "name": "@fixtures/cli" +} diff --git a/fixtures/config/ts-async/dangling.js b/fixtures/config/ts-async/dangling.js new file mode 100644 index 000000000..da3e9a39d --- /dev/null +++ b/fixtures/config/ts-async/dangling.js @@ -0,0 +1 @@ +export const unusedFile = true; diff --git a/fixtures/config/ts-async/index.js b/fixtures/config/ts-async/index.js new file mode 100644 index 000000000..b2da10dcc --- /dev/null +++ b/fixtures/config/ts-async/index.js @@ -0,0 +1,3 @@ +import * as MyNamespace from './my-namespace'; + +export const b = MyNamespace.y; diff --git a/fixtures/config/ts-async/knip.ts b/fixtures/config/ts-async/knip.ts new file mode 100644 index 000000000..0119c954d --- /dev/null +++ b/fixtures/config/ts-async/knip.ts @@ -0,0 +1,7 @@ +import type { KnipConfig } from '../../../src/index'; + +const config = async (): Promise => ({ + ignore: ['dangling.js'], +}); + +export default config; diff --git a/fixtures/config/ts-async/my-namespace.js b/fixtures/config/ts-async/my-namespace.js new file mode 100644 index 000000000..185fbbd06 --- /dev/null +++ b/fixtures/config/ts-async/my-namespace.js @@ -0,0 +1,2 @@ +const x = 1; +export const y = () => x; diff --git a/fixtures/config/ts-async/package.json b/fixtures/config/ts-async/package.json new file mode 100644 index 000000000..1a0994fc4 --- /dev/null +++ b/fixtures/config/ts-async/package.json @@ -0,0 +1,3 @@ +{ + "name": "@fixtures/cli" +} diff --git a/fixtures/config/ts-async/tsconfig.json b/fixtures/config/ts-async/tsconfig.json new file mode 100644 index 000000000..7812f071f --- /dev/null +++ b/fixtures/config/ts-async/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "types": ["node"] + } +} diff --git a/fixtures/config/ts-function/dangling.js b/fixtures/config/ts-function/dangling.js new file mode 100644 index 000000000..da3e9a39d --- /dev/null +++ b/fixtures/config/ts-function/dangling.js @@ -0,0 +1 @@ +export const unusedFile = true; diff --git a/fixtures/config/ts-function/index.js b/fixtures/config/ts-function/index.js new file mode 100644 index 000000000..b2da10dcc --- /dev/null +++ b/fixtures/config/ts-function/index.js @@ -0,0 +1,3 @@ +import * as MyNamespace from './my-namespace'; + +export const b = MyNamespace.y; diff --git a/fixtures/config/ts-function/knip.ts b/fixtures/config/ts-function/knip.ts new file mode 100644 index 000000000..733a52e60 --- /dev/null +++ b/fixtures/config/ts-function/knip.ts @@ -0,0 +1,7 @@ +import type { KnipConfig } from '../../../src/index'; + +const config = (): KnipConfig => ({ + ignore: ['dangling.js'], +}); + +export default config; diff --git a/fixtures/config/ts-function/my-namespace.js b/fixtures/config/ts-function/my-namespace.js new file mode 100644 index 000000000..185fbbd06 --- /dev/null +++ b/fixtures/config/ts-function/my-namespace.js @@ -0,0 +1,2 @@ +const x = 1; +export const y = () => x; diff --git a/fixtures/config/ts-function/package.json b/fixtures/config/ts-function/package.json new file mode 100644 index 000000000..1a0994fc4 --- /dev/null +++ b/fixtures/config/ts-function/package.json @@ -0,0 +1,3 @@ +{ + "name": "@fixtures/cli" +} diff --git a/fixtures/config/ts-function/tsconfig.json b/fixtures/config/ts-function/tsconfig.json new file mode 100644 index 000000000..7812f071f --- /dev/null +++ b/fixtures/config/ts-function/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "types": ["node"] + } +} diff --git a/src/ConfigurationChief.ts b/src/ConfigurationChief.ts index 109b6f565..1de8d44c3 100644 --- a/src/ConfigurationChief.ts +++ b/src/ConfigurationChief.ts @@ -18,6 +18,7 @@ import { getKeysByValue } from './util/object.js'; import { join, relative, toPosix } from './util/path.js'; import { normalizePluginConfig, toCamelCase } from './util/plugin.js'; import { _require } from './util/require.js'; +import { unwrapFunction } from './util/unwrapFunction.js'; import { byPathDepth } from './util/workspace.js'; import type { SyncCompilers, AsyncCompilers } from './types/compilers.js'; import type { @@ -150,7 +151,9 @@ export class ConfigurationChief { throw new ConfigurationError(`Unable to find ${rawConfigArg} or package.json#knip`); } - this.rawConfig = this.resolvedConfigFilePath ? await _load(this.resolvedConfigFilePath) : manifest.knip; + this.rawConfig = this.resolvedConfigFilePath + ? await this.loadResolvedConfigurationFile(this.resolvedConfigFilePath) + : manifest.knip; // Have to partition compiler functions before Zod touches them const parsedConfig = this.rawConfig ? ConfigurationValidator.parse(partitionCompilers(this.rawConfig)) : {}; @@ -159,6 +162,15 @@ export class ConfigurationChief { await this.setWorkspaces(); } + private async loadResolvedConfigurationFile(configPath: string) { + const loadedValue = await _load(configPath); + try { + return await unwrapFunction(loadedValue); + } catch (e) { + throw new ConfigurationError(`Unable to run the function from the knip config file`); + } + } + public getCompilers(): [SyncCompilers, AsyncCompilers] { return [this.config.syncCompilers, this.config.asyncCompilers]; } diff --git a/src/util/unwrapFunction.ts b/src/util/unwrapFunction.ts new file mode 100644 index 000000000..0ff20b3a4 --- /dev/null +++ b/src/util/unwrapFunction.ts @@ -0,0 +1,13 @@ +import { debugLogObject } from './debug.js'; + +export const unwrapFunction = async (possibleFunction: unknown) => { + if (typeof possibleFunction === 'function') { + try { + return await possibleFunction(); + } catch (error) { + debugLogObject('Error executing function:', error); + throw error; + } + } + return possibleFunction; +}; diff --git a/test/config/js-async.test.ts b/test/config/js-async.test.ts new file mode 100644 index 000000000..2cb9bf9ad --- /dev/null +++ b/test/config/js-async.test.ts @@ -0,0 +1,23 @@ +import assert from 'node:assert/strict'; +import { execSync } from 'node:child_process'; +import test from 'node:test'; +import { resolve } from '../../src/util/path.js'; + +const cwd = resolve('fixtures/config/js-async'); + +const exec = (command: string) => { + try { + const output = execSync(command.replace(/^knip/, 'node ../../../dist/cli.js'), { cwd }); + return output.toString().trim(); + } catch (error) { + if (error instanceof Error && 'stdout' in error && Buffer.isBuffer(error['stdout'])) { + return error['stdout'].toString(); + } + // Unknown error + throw error; + } +}; + +test('Support loading js async function for configuration', async () => { + assert.equal(exec('knip'), ''); +}); diff --git a/test/config/mjs-async.test.ts b/test/config/mjs-async.test.ts new file mode 100644 index 000000000..2be0d8d06 --- /dev/null +++ b/test/config/mjs-async.test.ts @@ -0,0 +1,23 @@ +import assert from 'node:assert/strict'; +import { execSync } from 'node:child_process'; +import test from 'node:test'; +import { resolve } from '../../src/util/path.js'; + +const cwd = resolve('fixtures/config/mjs-async'); + +const exec = (command: string) => { + try { + const output = execSync(command.replace(/^knip/, 'node ../../../dist/cli.js'), { cwd }); + return output.toString().trim(); + } catch (error) { + if (error instanceof Error && 'stdout' in error && Buffer.isBuffer(error['stdout'])) { + return error['stdout'].toString(); + } + // Unknown error + throw error; + } +}; + +test('Support loading mjs async function files for configuration', async () => { + assert.equal(exec('knip -c knip.mjs'), ''); +}); diff --git a/test/config/ts-async.test.ts b/test/config/ts-async.test.ts new file mode 100644 index 000000000..3583e6757 --- /dev/null +++ b/test/config/ts-async.test.ts @@ -0,0 +1,23 @@ +import assert from 'node:assert/strict'; +import { execSync } from 'node:child_process'; +import test from 'node:test'; +import { resolve } from '../../src/util/path.js'; + +const cwd = resolve('fixtures/config/ts-async'); + +const exec = (command: string) => { + try { + const output = execSync(command.replace(/^knip/, 'node ../../../dist/cli.js'), { cwd }); + return output.toString().trim(); + } catch (error) { + if (error instanceof Error && 'stdout' in error && Buffer.isBuffer(error['stdout'])) { + return error['stdout'].toString(); + } + // Unknown error + throw error; + } +}; + +test('Support loading ts async function for configuration', async () => { + assert.equal(exec('knip'), ''); +}); diff --git a/test/config/ts-function.test.ts b/test/config/ts-function.test.ts new file mode 100644 index 000000000..c4ddfe23d --- /dev/null +++ b/test/config/ts-function.test.ts @@ -0,0 +1,23 @@ +import assert from 'node:assert/strict'; +import { execSync } from 'node:child_process'; +import test from 'node:test'; +import { resolve } from '../../src/util/path.js'; + +const cwd = resolve('fixtures/config/ts-function'); + +const exec = (command: string) => { + try { + const output = execSync(command.replace(/^knip/, 'node ../../../dist/cli.js'), { cwd }); + return output.toString().trim(); + } catch (error) { + if (error instanceof Error && 'stdout' in error && Buffer.isBuffer(error['stdout'])) { + return error['stdout'].toString(); + } + // Unknown error + throw error; + } +}; + +test('Support loading ts function for configuration', async () => { + assert.equal(exec('knip'), ''); +}); From aa5474cc779c3c620ae037d00dcd58ae22caa14c Mon Sep 17 00:00:00 2001 From: Nicolas Beaussart Date: Mon, 16 Oct 2023 20:59:33 +0200 Subject: [PATCH 3/7] Rename all fixtures config names to match folder --- fixtures/config/js-async/package.json | 2 +- fixtures/config/js-flat/package.json | 2 +- fixtures/config/json/package.json | 2 +- fixtures/config/mjs-async/package.json | 2 +- fixtures/config/mjs-flat/package.json | 2 +- fixtures/config/package-json/package.json | 2 +- fixtures/config/ts-async/package.json | 2 +- fixtures/config/ts-flat/package.json | 2 +- fixtures/config/ts-function/package.json | 2 +- fixtures/config/yaml/package.json | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/fixtures/config/js-async/package.json b/fixtures/config/js-async/package.json index 1a0994fc4..bbc0ee528 100644 --- a/fixtures/config/js-async/package.json +++ b/fixtures/config/js-async/package.json @@ -1,3 +1,3 @@ { - "name": "@fixtures/cli" + "name": "@fixtures/config-js-async" } diff --git a/fixtures/config/js-flat/package.json b/fixtures/config/js-flat/package.json index 1a0994fc4..bce57da7d 100644 --- a/fixtures/config/js-flat/package.json +++ b/fixtures/config/js-flat/package.json @@ -1,3 +1,3 @@ { - "name": "@fixtures/cli" + "name": "@fixtures/config-js-flat" } diff --git a/fixtures/config/json/package.json b/fixtures/config/json/package.json index 1a0994fc4..3a7564325 100644 --- a/fixtures/config/json/package.json +++ b/fixtures/config/json/package.json @@ -1,3 +1,3 @@ { - "name": "@fixtures/cli" + "name": "@fixtures/config-json" } diff --git a/fixtures/config/mjs-async/package.json b/fixtures/config/mjs-async/package.json index 1a0994fc4..3ed2711e6 100644 --- a/fixtures/config/mjs-async/package.json +++ b/fixtures/config/mjs-async/package.json @@ -1,3 +1,3 @@ { - "name": "@fixtures/cli" + "name": "@fixtures/config-mjs-async" } diff --git a/fixtures/config/mjs-flat/package.json b/fixtures/config/mjs-flat/package.json index 1a0994fc4..ee8bcdf52 100644 --- a/fixtures/config/mjs-flat/package.json +++ b/fixtures/config/mjs-flat/package.json @@ -1,3 +1,3 @@ { - "name": "@fixtures/cli" + "name": "@fixtures/config-mjs-flat" } diff --git a/fixtures/config/package-json/package.json b/fixtures/config/package-json/package.json index bc8b9a238..8f42c7683 100644 --- a/fixtures/config/package-json/package.json +++ b/fixtures/config/package-json/package.json @@ -1,5 +1,5 @@ { - "name": "@fixtures/cli", + "name": "@fixtures/config-package-json", "knip": { "ignore": ["dangling.js"] } diff --git a/fixtures/config/ts-async/package.json b/fixtures/config/ts-async/package.json index 1a0994fc4..051cbc0ac 100644 --- a/fixtures/config/ts-async/package.json +++ b/fixtures/config/ts-async/package.json @@ -1,3 +1,3 @@ { - "name": "@fixtures/cli" + "name": "@fixtures/config-ts-async" } diff --git a/fixtures/config/ts-flat/package.json b/fixtures/config/ts-flat/package.json index 1a0994fc4..3eeb63370 100644 --- a/fixtures/config/ts-flat/package.json +++ b/fixtures/config/ts-flat/package.json @@ -1,3 +1,3 @@ { - "name": "@fixtures/cli" + "name": "@fixtures/config-ts-flat" } diff --git a/fixtures/config/ts-function/package.json b/fixtures/config/ts-function/package.json index 1a0994fc4..900473fcf 100644 --- a/fixtures/config/ts-function/package.json +++ b/fixtures/config/ts-function/package.json @@ -1,3 +1,3 @@ { - "name": "@fixtures/cli" + "name": "@fixtures/config-ts-function" } diff --git a/fixtures/config/yaml/package.json b/fixtures/config/yaml/package.json index 1a0994fc4..54523052e 100644 --- a/fixtures/config/yaml/package.json +++ b/fixtures/config/yaml/package.json @@ -1,3 +1,3 @@ { - "name": "@fixtures/cli" + "name": "@fixtures/config-yaml" } From d96aea3ac590139bb514f23a45dac0620989e82a Mon Sep 17 00:00:00 2001 From: Nicolas Beaussart Date: Tue, 17 Oct 2023 10:45:55 +0200 Subject: [PATCH 4/7] Apply suggestions from code review Co-authored-by: Lars Kappert --- README.md | 2 +- src/ConfigurationChief.ts | 2 +- src/util/unwrapFunction.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6746a4f86..75ea3a406 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,7 @@ const config: KnipConfig = { export default config; ``` -And if you need, you can also expose a function or an async function if you need, like so : +And if you need, you can also expose an (async) function if you need, like so: ```ts import type { KnipConfig } from 'knip'; diff --git a/src/ConfigurationChief.ts b/src/ConfigurationChief.ts index 1de8d44c3..ab0c99cab 100644 --- a/src/ConfigurationChief.ts +++ b/src/ConfigurationChief.ts @@ -167,7 +167,7 @@ export class ConfigurationChief { try { return await unwrapFunction(loadedValue); } catch (e) { - throw new ConfigurationError(`Unable to run the function from the knip config file`); + throw new ConfigurationError(`Error running the function from ${configPath}`); } } diff --git a/src/util/unwrapFunction.ts b/src/util/unwrapFunction.ts index 0ff20b3a4..7044613f4 100644 --- a/src/util/unwrapFunction.ts +++ b/src/util/unwrapFunction.ts @@ -5,7 +5,7 @@ export const unwrapFunction = async (possibleFunction: unknown) => { try { return await possibleFunction(); } catch (error) { - debugLogObject('Error executing function:', error); + debugLogObject('*', 'Error executing function:', error); throw error; } } From eae10678388301d6eae61bd86c0f5a507c4bd52e Mon Sep 17 00:00:00 2001 From: Nicolas Beaussart Date: Tue, 17 Oct 2023 10:57:47 +0200 Subject: [PATCH 5/7] Refactor using a exec wrapper for tests --- test/cli-preprocessor.test.ts | 11 ++--------- test/cli-reporter.test.ts | 7 ++----- test/cli.test.ts | 7 ++----- test/config/js-async.test.ts | 15 ++------------- test/config/js-flat.test.ts | 15 ++------------- test/config/json.test.ts | 17 ++--------------- test/config/mjs-async.test.ts | 15 ++------------- test/config/mjs-flat.test.ts | 15 ++------------- test/config/package-json.test.ts | 16 +++------------- test/config/ts-async.test.ts | 15 ++------------- test/config/ts-flat.test.ts | 15 ++------------- test/config/ts-function.test.ts | 15 ++------------- test/config/yaml.test.ts | 15 ++------------- test/helpers/execKnip.ts | 16 ++++++++++++++++ 14 files changed, 43 insertions(+), 151 deletions(-) create mode 100644 test/helpers/execKnip.ts diff --git a/test/cli-preprocessor.test.ts b/test/cli-preprocessor.test.ts index 1af72ace8..07e7c9000 100644 --- a/test/cli-preprocessor.test.ts +++ b/test/cli-preprocessor.test.ts @@ -1,18 +1,11 @@ import assert from 'node:assert/strict'; -import { execSync } from 'node:child_process'; import test from 'node:test'; import { resolve } from '../src/util/path.js'; +import { execFactory } from './helpers/execKnip.js'; const cwd = resolve('fixtures/cli-preprocessor'); -const exec = (command: string) => { - try { - const output = execSync(command.replace(/^knip/, 'node ../../dist/cli.js'), { cwd }); - return output.toString().trim(); - } catch { - console.error(`Error during execution of command: ${command}`); - } -}; +const exec = execFactory(cwd, '../../dist/cli.js'); test('knip --preprocessor ./index.js', () => { assert.equal(exec('knip --preprocessor ./index.js'), 'hi from js preprocessor'); diff --git a/test/cli-reporter.test.ts b/test/cli-reporter.test.ts index 47351e11d..27ba4ed3c 100644 --- a/test/cli-reporter.test.ts +++ b/test/cli-reporter.test.ts @@ -1,14 +1,11 @@ import assert from 'node:assert/strict'; -import { execSync } from 'node:child_process'; import test from 'node:test'; import { resolve } from '../src/util/path.js'; +import { execFactory } from './helpers/execKnip.js'; const cwd = resolve('fixtures/cli-reporter'); -const exec = (command: string) => { - const output = execSync(command.replace(/^knip/, 'node ../../dist/cli.js'), { cwd }); - return output.toString().trim(); -}; +const exec = execFactory(cwd, '../../dist/cli.js'); test('knip --reporter ./index.js', () => { assert.equal(exec('knip --reporter ./index.js'), 'hi from js reporter'); diff --git a/test/cli.test.ts b/test/cli.test.ts index 49b19f89f..d28c5035d 100644 --- a/test/cli.test.ts +++ b/test/cli.test.ts @@ -1,16 +1,13 @@ import assert from 'node:assert/strict'; -import { execSync } from 'node:child_process'; import test from 'node:test'; import { helpText } from '../src/util/cli-arguments.js'; import { resolve } from '../src/util/path.js'; import { version } from '../src/version.js'; +import { execFactory } from './helpers/execKnip.js'; const cwd = resolve('fixtures/cli'); -const exec = (command: string) => { - const output = execSync(command.replace(/^knip/, 'node ../../dist/cli.js'), { cwd }); - return output.toString().trim(); -}; +const exec = execFactory(cwd, '../../dist/cli.js'); test('knip --version', () => { assert.equal(exec('knip --version'), version); diff --git a/test/config/js-async.test.ts b/test/config/js-async.test.ts index 2cb9bf9ad..b5660210f 100644 --- a/test/config/js-async.test.ts +++ b/test/config/js-async.test.ts @@ -1,22 +1,11 @@ import assert from 'node:assert/strict'; -import { execSync } from 'node:child_process'; import test from 'node:test'; import { resolve } from '../../src/util/path.js'; +import { execFactory } from '../helpers/execKnip.js'; const cwd = resolve('fixtures/config/js-async'); -const exec = (command: string) => { - try { - const output = execSync(command.replace(/^knip/, 'node ../../../dist/cli.js'), { cwd }); - return output.toString().trim(); - } catch (error) { - if (error instanceof Error && 'stdout' in error && Buffer.isBuffer(error['stdout'])) { - return error['stdout'].toString(); - } - // Unknown error - throw error; - } -}; +const exec = execFactory(cwd, '../../../dist/cli.js'); test('Support loading js async function for configuration', async () => { assert.equal(exec('knip'), ''); diff --git a/test/config/js-flat.test.ts b/test/config/js-flat.test.ts index bf4f8b29a..e0e99f9af 100644 --- a/test/config/js-flat.test.ts +++ b/test/config/js-flat.test.ts @@ -1,22 +1,11 @@ import assert from 'node:assert/strict'; -import { execSync } from 'node:child_process'; import test from 'node:test'; import { resolve } from '../../src/util/path.js'; +import { execFactory } from '../helpers/execKnip.js'; const cwd = resolve('fixtures/config/js-flat'); -const exec = (command: string) => { - try { - const output = execSync(command.replace(/^knip/, 'node ../../../dist/cli.js'), { cwd }); - return output.toString().trim(); - } catch (error) { - if (error instanceof Error && 'stdout' in error && Buffer.isBuffer(error['stdout'])) { - return error['stdout'].toString(); - } - // Unknown error - throw error; - } -}; +const exec = execFactory(cwd, '../../../dist/cli.js'); test('Support loading js object files for configuration', async () => { assert.equal(exec('knip'), ''); diff --git a/test/config/json.test.ts b/test/config/json.test.ts index d903af049..7c4e6b6dc 100644 --- a/test/config/json.test.ts +++ b/test/config/json.test.ts @@ -1,24 +1,11 @@ import assert from 'node:assert/strict'; -import { execSync } from 'node:child_process'; import test from 'node:test'; import { resolve } from '../../src/util/path.js'; - +import { execFactory } from '../helpers/execKnip.js'; const cwd = resolve('fixtures/config/json'); -const exec = (command: string) => { - try { - const output = execSync(command.replace(/^knip/, 'node ../../../dist/cli.js'), { cwd }); - return output.toString().trim(); - } catch (error) { - if (error instanceof Error && 'stdout' in error && Buffer.isBuffer(error['stdout'])) { - return error['stdout'].toString(); - } - // Unknown error - throw error; - } -}; - +const exec = execFactory(cwd, '../../../dist/cli.js'); test('Support loading json files for configuration', async () => { assert.equal(exec('knip'), ''); diff --git a/test/config/mjs-async.test.ts b/test/config/mjs-async.test.ts index 2be0d8d06..a56168e12 100644 --- a/test/config/mjs-async.test.ts +++ b/test/config/mjs-async.test.ts @@ -1,22 +1,11 @@ import assert from 'node:assert/strict'; -import { execSync } from 'node:child_process'; import test from 'node:test'; import { resolve } from '../../src/util/path.js'; +import { execFactory } from '../helpers/execKnip.js'; const cwd = resolve('fixtures/config/mjs-async'); -const exec = (command: string) => { - try { - const output = execSync(command.replace(/^knip/, 'node ../../../dist/cli.js'), { cwd }); - return output.toString().trim(); - } catch (error) { - if (error instanceof Error && 'stdout' in error && Buffer.isBuffer(error['stdout'])) { - return error['stdout'].toString(); - } - // Unknown error - throw error; - } -}; +const exec = execFactory(cwd, '../../../dist/cli.js'); test('Support loading mjs async function files for configuration', async () => { assert.equal(exec('knip -c knip.mjs'), ''); diff --git a/test/config/mjs-flat.test.ts b/test/config/mjs-flat.test.ts index f5ece28fc..6d75b5464 100644 --- a/test/config/mjs-flat.test.ts +++ b/test/config/mjs-flat.test.ts @@ -1,22 +1,11 @@ import assert from 'node:assert/strict'; -import { execSync } from 'node:child_process'; import test from 'node:test'; import { resolve } from '../../src/util/path.js'; +import { execFactory } from '../helpers/execKnip.js'; const cwd = resolve('fixtures/config/mjs-flat'); -const exec = (command: string) => { - try { - const output = execSync(command.replace(/^knip/, 'node ../../../dist/cli.js'), { cwd }); - return output.toString().trim(); - } catch (error) { - if (error instanceof Error && 'stdout' in error && Buffer.isBuffer(error['stdout'])) { - return error['stdout'].toString(); - } - // Unknown error - throw error; - } -}; +const exec = execFactory(cwd, '../../../dist/cli.js'); test('Support loading mjs object files for configuration', async () => { assert.equal(exec('knip -c knip.mjs'), ''); diff --git a/test/config/package-json.test.ts b/test/config/package-json.test.ts index 387b4d6a3..d131bbce7 100644 --- a/test/config/package-json.test.ts +++ b/test/config/package-json.test.ts @@ -1,22 +1,12 @@ import assert from 'node:assert/strict'; -import { execSync } from 'node:child_process'; import test from 'node:test'; import { resolve } from '../../src/util/path.js'; +import { execFactory } from '../helpers/execKnip.js'; const cwd = resolve('fixtures/config/package-json'); -const exec = (command: string) => { - try { - const output = execSync(command.replace(/^knip/, 'node ../../../dist/cli.js'), { cwd }); - return output.toString().trim(); - } catch (error) { - if (error instanceof Error && 'stdout' in error && Buffer.isBuffer(error['stdout'])) { - return error['stdout'].toString(); - } - // Unknown error - throw error; - } -}; +const exec = execFactory(cwd, '../../../dist/cli.js'); + test('Support loading package.json for configuration', async () => { assert.equal(exec('knip'), ''); }); diff --git a/test/config/ts-async.test.ts b/test/config/ts-async.test.ts index 3583e6757..3bfa2e1d9 100644 --- a/test/config/ts-async.test.ts +++ b/test/config/ts-async.test.ts @@ -1,22 +1,11 @@ import assert from 'node:assert/strict'; -import { execSync } from 'node:child_process'; import test from 'node:test'; import { resolve } from '../../src/util/path.js'; +import { execFactory } from '../helpers/execKnip.js'; const cwd = resolve('fixtures/config/ts-async'); -const exec = (command: string) => { - try { - const output = execSync(command.replace(/^knip/, 'node ../../../dist/cli.js'), { cwd }); - return output.toString().trim(); - } catch (error) { - if (error instanceof Error && 'stdout' in error && Buffer.isBuffer(error['stdout'])) { - return error['stdout'].toString(); - } - // Unknown error - throw error; - } -}; +const exec = execFactory(cwd, '../../../dist/cli.js'); test('Support loading ts async function for configuration', async () => { assert.equal(exec('knip'), ''); diff --git a/test/config/ts-flat.test.ts b/test/config/ts-flat.test.ts index 0ba0c5cbd..729cbe658 100644 --- a/test/config/ts-flat.test.ts +++ b/test/config/ts-flat.test.ts @@ -1,22 +1,11 @@ import assert from 'node:assert/strict'; -import { execSync } from 'node:child_process'; import test from 'node:test'; import { resolve } from '../../src/util/path.js'; +import { execFactory } from '../helpers/execKnip.js'; const cwd = resolve('fixtures/config/ts-flat'); -const exec = (command: string) => { - try { - const output = execSync(command.replace(/^knip/, 'node ../../../dist/cli.js'), { cwd }); - return output.toString().trim(); - } catch (error) { - if (error instanceof Error && 'stdout' in error && Buffer.isBuffer(error['stdout'])) { - return error['stdout'].toString(); - } - // Unknown error - throw error; - } -}; +const exec = execFactory(cwd, '../../../dist/cli.js'); test('Support loading ts object files for configuration', async () => { assert.equal(exec('knip'), ''); diff --git a/test/config/ts-function.test.ts b/test/config/ts-function.test.ts index c4ddfe23d..7b5e1ac9d 100644 --- a/test/config/ts-function.test.ts +++ b/test/config/ts-function.test.ts @@ -1,22 +1,11 @@ import assert from 'node:assert/strict'; -import { execSync } from 'node:child_process'; import test from 'node:test'; import { resolve } from '../../src/util/path.js'; +import { execFactory } from '../helpers/execKnip.js'; const cwd = resolve('fixtures/config/ts-function'); -const exec = (command: string) => { - try { - const output = execSync(command.replace(/^knip/, 'node ../../../dist/cli.js'), { cwd }); - return output.toString().trim(); - } catch (error) { - if (error instanceof Error && 'stdout' in error && Buffer.isBuffer(error['stdout'])) { - return error['stdout'].toString(); - } - // Unknown error - throw error; - } -}; +const exec = execFactory(cwd, '../../../dist/cli.js'); test('Support loading ts function for configuration', async () => { assert.equal(exec('knip'), ''); diff --git a/test/config/yaml.test.ts b/test/config/yaml.test.ts index 5b6a19d68..d7e38d971 100644 --- a/test/config/yaml.test.ts +++ b/test/config/yaml.test.ts @@ -1,22 +1,11 @@ import assert from 'node:assert/strict'; -import { execSync } from 'node:child_process'; import test from 'node:test'; import { resolve } from '../../src/util/path.js'; +import { execFactory } from '../helpers/execKnip.js'; const cwd = resolve('fixtures/config/yaml'); -const exec = (command: string) => { - try { - const output = execSync(command.replace(/^knip/, 'node ../../../dist/cli.js'), { cwd }); - return output.toString().trim(); - } catch (error) { - if (error instanceof Error && 'stdout' in error && Buffer.isBuffer(error['stdout'])) { - return error['stdout'].toString(); - } - // Unknown error - throw error; - } -}; +const exec = execFactory(cwd, '../../../dist/cli.js'); test('Support loading yaml files for configuration', async () => { assert.equal(exec('knip -c knip.yaml'), ''); diff --git a/test/helpers/execKnip.ts b/test/helpers/execKnip.ts new file mode 100644 index 000000000..deb1b9dc7 --- /dev/null +++ b/test/helpers/execKnip.ts @@ -0,0 +1,16 @@ +import { execSync } from 'node:child_process'; + +export const execFactory = (cwd: string, cliPath: string) => { + return (command: string) => { + try { + const output = execSync(command.replace(/^knip/, `node ${cliPath}`), { cwd }); + return output.toString().trim(); + } catch (error) { + if (error instanceof Error && 'stdout' in error && Buffer.isBuffer(error['stdout'])) { + return error['stdout'].toString(); + } + // Unknown error + throw error; + } + }; +}; From f6e8a155e86a424e06e87cecf36ccbe4203b6e24 Mon Sep 17 00:00:00 2001 From: Nicolas Beaussart Date: Tue, 17 Oct 2023 15:54:53 +0200 Subject: [PATCH 6/7] Add dist cli auto path detection --- test/cli-preprocessor.test.ts | 2 +- test/cli-reporter.test.ts | 2 +- test/cli.test.ts | 2 +- test/config/js-async.test.ts | 2 +- test/config/js-flat.test.ts | 2 +- test/config/json.test.ts | 2 +- test/config/mjs-async.test.ts | 2 +- test/config/mjs-flat.test.ts | 2 +- test/config/package-json.test.ts | 2 +- test/config/ts-async.test.ts | 2 +- test/config/ts-flat.test.ts | 2 +- test/config/ts-function.test.ts | 2 +- test/config/yaml.test.ts | 2 +- test/helpers/execKnip.ts | 13 ++++++++++++- 14 files changed, 25 insertions(+), 14 deletions(-) diff --git a/test/cli-preprocessor.test.ts b/test/cli-preprocessor.test.ts index 07e7c9000..b93bfc3d6 100644 --- a/test/cli-preprocessor.test.ts +++ b/test/cli-preprocessor.test.ts @@ -5,7 +5,7 @@ import { execFactory } from './helpers/execKnip.js'; const cwd = resolve('fixtures/cli-preprocessor'); -const exec = execFactory(cwd, '../../dist/cli.js'); +const exec = execFactory(cwd); test('knip --preprocessor ./index.js', () => { assert.equal(exec('knip --preprocessor ./index.js'), 'hi from js preprocessor'); diff --git a/test/cli-reporter.test.ts b/test/cli-reporter.test.ts index 27ba4ed3c..ac4b12aa7 100644 --- a/test/cli-reporter.test.ts +++ b/test/cli-reporter.test.ts @@ -5,7 +5,7 @@ import { execFactory } from './helpers/execKnip.js'; const cwd = resolve('fixtures/cli-reporter'); -const exec = execFactory(cwd, '../../dist/cli.js'); +const exec = execFactory(cwd); test('knip --reporter ./index.js', () => { assert.equal(exec('knip --reporter ./index.js'), 'hi from js reporter'); diff --git a/test/cli.test.ts b/test/cli.test.ts index d28c5035d..fa3bc3b18 100644 --- a/test/cli.test.ts +++ b/test/cli.test.ts @@ -7,7 +7,7 @@ import { execFactory } from './helpers/execKnip.js'; const cwd = resolve('fixtures/cli'); -const exec = execFactory(cwd, '../../dist/cli.js'); +const exec = execFactory(cwd); test('knip --version', () => { assert.equal(exec('knip --version'), version); diff --git a/test/config/js-async.test.ts b/test/config/js-async.test.ts index b5660210f..c369e74ea 100644 --- a/test/config/js-async.test.ts +++ b/test/config/js-async.test.ts @@ -5,7 +5,7 @@ import { execFactory } from '../helpers/execKnip.js'; const cwd = resolve('fixtures/config/js-async'); -const exec = execFactory(cwd, '../../../dist/cli.js'); +const exec = execFactory(cwd); test('Support loading js async function for configuration', async () => { assert.equal(exec('knip'), ''); diff --git a/test/config/js-flat.test.ts b/test/config/js-flat.test.ts index e0e99f9af..f40bbb049 100644 --- a/test/config/js-flat.test.ts +++ b/test/config/js-flat.test.ts @@ -5,7 +5,7 @@ import { execFactory } from '../helpers/execKnip.js'; const cwd = resolve('fixtures/config/js-flat'); -const exec = execFactory(cwd, '../../../dist/cli.js'); +const exec = execFactory(cwd); test('Support loading js object files for configuration', async () => { assert.equal(exec('knip'), ''); diff --git a/test/config/json.test.ts b/test/config/json.test.ts index 7c4e6b6dc..48a04d7a5 100644 --- a/test/config/json.test.ts +++ b/test/config/json.test.ts @@ -5,7 +5,7 @@ import { execFactory } from '../helpers/execKnip.js'; const cwd = resolve('fixtures/config/json'); -const exec = execFactory(cwd, '../../../dist/cli.js'); +const exec = execFactory(cwd); test('Support loading json files for configuration', async () => { assert.equal(exec('knip'), ''); diff --git a/test/config/mjs-async.test.ts b/test/config/mjs-async.test.ts index a56168e12..1e519c68e 100644 --- a/test/config/mjs-async.test.ts +++ b/test/config/mjs-async.test.ts @@ -5,7 +5,7 @@ import { execFactory } from '../helpers/execKnip.js'; const cwd = resolve('fixtures/config/mjs-async'); -const exec = execFactory(cwd, '../../../dist/cli.js'); +const exec = execFactory(cwd); test('Support loading mjs async function files for configuration', async () => { assert.equal(exec('knip -c knip.mjs'), ''); diff --git a/test/config/mjs-flat.test.ts b/test/config/mjs-flat.test.ts index 6d75b5464..64ce3d259 100644 --- a/test/config/mjs-flat.test.ts +++ b/test/config/mjs-flat.test.ts @@ -5,7 +5,7 @@ import { execFactory } from '../helpers/execKnip.js'; const cwd = resolve('fixtures/config/mjs-flat'); -const exec = execFactory(cwd, '../../../dist/cli.js'); +const exec = execFactory(cwd); test('Support loading mjs object files for configuration', async () => { assert.equal(exec('knip -c knip.mjs'), ''); diff --git a/test/config/package-json.test.ts b/test/config/package-json.test.ts index d131bbce7..68438d181 100644 --- a/test/config/package-json.test.ts +++ b/test/config/package-json.test.ts @@ -5,7 +5,7 @@ import { execFactory } from '../helpers/execKnip.js'; const cwd = resolve('fixtures/config/package-json'); -const exec = execFactory(cwd, '../../../dist/cli.js'); +const exec = execFactory(cwd); test('Support loading package.json for configuration', async () => { assert.equal(exec('knip'), ''); diff --git a/test/config/ts-async.test.ts b/test/config/ts-async.test.ts index 3bfa2e1d9..935d6dda6 100644 --- a/test/config/ts-async.test.ts +++ b/test/config/ts-async.test.ts @@ -5,7 +5,7 @@ import { execFactory } from '../helpers/execKnip.js'; const cwd = resolve('fixtures/config/ts-async'); -const exec = execFactory(cwd, '../../../dist/cli.js'); +const exec = execFactory(cwd); test('Support loading ts async function for configuration', async () => { assert.equal(exec('knip'), ''); diff --git a/test/config/ts-flat.test.ts b/test/config/ts-flat.test.ts index 729cbe658..21cc9dddd 100644 --- a/test/config/ts-flat.test.ts +++ b/test/config/ts-flat.test.ts @@ -5,7 +5,7 @@ import { execFactory } from '../helpers/execKnip.js'; const cwd = resolve('fixtures/config/ts-flat'); -const exec = execFactory(cwd, '../../../dist/cli.js'); +const exec = execFactory(cwd); test('Support loading ts object files for configuration', async () => { assert.equal(exec('knip'), ''); diff --git a/test/config/ts-function.test.ts b/test/config/ts-function.test.ts index 7b5e1ac9d..5af0096d2 100644 --- a/test/config/ts-function.test.ts +++ b/test/config/ts-function.test.ts @@ -5,7 +5,7 @@ import { execFactory } from '../helpers/execKnip.js'; const cwd = resolve('fixtures/config/ts-function'); -const exec = execFactory(cwd, '../../../dist/cli.js'); +const exec = execFactory(cwd); test('Support loading ts function for configuration', async () => { assert.equal(exec('knip'), ''); diff --git a/test/config/yaml.test.ts b/test/config/yaml.test.ts index d7e38d971..28041c045 100644 --- a/test/config/yaml.test.ts +++ b/test/config/yaml.test.ts @@ -5,7 +5,7 @@ import { execFactory } from '../helpers/execKnip.js'; const cwd = resolve('fixtures/config/yaml'); -const exec = execFactory(cwd, '../../../dist/cli.js'); +const exec = execFactory(cwd); test('Support loading yaml files for configuration', async () => { assert.equal(exec('knip -c knip.yaml'), ''); diff --git a/test/helpers/execKnip.ts b/test/helpers/execKnip.ts index deb1b9dc7..ba4a562d5 100644 --- a/test/helpers/execKnip.ts +++ b/test/helpers/execKnip.ts @@ -1,6 +1,17 @@ import { execSync } from 'node:child_process'; +import { fileURLToPath } from 'node:url'; +import { resolve } from '../../src/util/path.js'; -export const execFactory = (cwd: string, cliPath: string) => { +const thisFileUrl = fileURLToPath(import.meta.url); + +const cliPath = resolve( + thisFileUrl, + // Needed if run in the /tmp (like in the npm test script) to find the correct dist folder + thisFileUrl.endsWith('tmp/test/helpers/execKnip.js') ? '..' : '.', + '../../../dist/cli.js' +); + +export const execFactory = (cwd: string) => { return (command: string) => { try { const output = execSync(command.replace(/^knip/, `node ${cliPath}`), { cwd }); From 38d133cf4501a392e52d97226739a2d6e71b9f88 Mon Sep 17 00:00:00 2001 From: Lars Kappert Date: Tue, 17 Oct 2023 20:10:27 +0200 Subject: [PATCH 7/7] Use `path.resolve` to get absolute path to `dist/cli.js` --- test/helpers/execKnip.ts | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/test/helpers/execKnip.ts b/test/helpers/execKnip.ts index ba4a562d5..50ec04298 100644 --- a/test/helpers/execKnip.ts +++ b/test/helpers/execKnip.ts @@ -1,15 +1,8 @@ import { execSync } from 'node:child_process'; -import { fileURLToPath } from 'node:url'; -import { resolve } from '../../src/util/path.js'; +// eslint-disable-next-line n/no-restricted-import +import { resolve } from 'node:path'; -const thisFileUrl = fileURLToPath(import.meta.url); - -const cliPath = resolve( - thisFileUrl, - // Needed if run in the /tmp (like in the npm test script) to find the correct dist folder - thisFileUrl.endsWith('tmp/test/helpers/execKnip.js') ? '..' : '.', - '../../../dist/cli.js' -); +const cliPath = resolve('dist/cli.js'); export const execFactory = (cwd: string) => { return (command: string) => {