From d53dcf0fa53de2a231463efef1182c0c52cffdb8 Mon Sep 17 00:00:00 2001 From: Lev Chelyadinov Date: Tue, 12 Nov 2024 20:07:31 +0100 Subject: [PATCH 01/17] Add a rudimentary E2E test --- .github/workflows/quality.yaml | 5 ++ .../reference-output.json | 73 +++++++++++++++++++ .../src/app/ui/App.tsx | 1 + .../src/app/ui/index.ts | 1 + .../src/entities/user/api/getUser.ts | 3 + .../tsconfig.app.json | 12 +++ .../kitchen-sink-of-fsd-issues/tsconfig.json | 5 +- 7 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 examples/kitchen-sink-of-fsd-issues/reference-output.json create mode 100644 examples/kitchen-sink-of-fsd-issues/src/app/ui/App.tsx create mode 100644 examples/kitchen-sink-of-fsd-issues/src/app/ui/index.ts create mode 100644 examples/kitchen-sink-of-fsd-issues/tsconfig.app.json diff --git a/.github/workflows/quality.yaml b/.github/workflows/quality.yaml index 8d8412f5..8436ba77 100644 --- a/.github/workflows/quality.yaml +++ b/.github/workflows/quality.yaml @@ -48,3 +48,8 @@ jobs: - name: Try building run: turbo run build + + - name: Run E2E on a real project + run: | + node ./packages/steiger/dist/cli.mjs ./examples/kitchen-sink-of-fsd-issues/src/ --reporter json > output.json + diff <(jq --sort-keys . output.json) <(jq --sort-keys . examples/kitchen-sink-of-fsd-issues/reference-output.json) diff --git a/examples/kitchen-sink-of-fsd-issues/reference-output.json b/examples/kitchen-sink-of-fsd-issues/reference-output.json new file mode 100644 index 00000000..4fa9e3af --- /dev/null +++ b/examples/kitchen-sink-of-fsd-issues/reference-output.json @@ -0,0 +1,73 @@ +[ + { + "message": "Forbidden import from higher layer \"app\".", + "location": { + "path": "/Users/illright/work/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user/api/getUser.ts" + }, + "ruleName": "fsd/forbidden-imports", + "severity": "error" + }, + { + "message": "Inconsistent pluralization of slice names. Prefer all plural names", + "fixes": [ + { + "type": "rename", + "path": "/Users/illright/work/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user", + "newName": "users" + } + ], + "location": { + "path": "/Users/illright/work/steiger/examples/kitchen-sink-of-fsd-issues/src/entities" + }, + "ruleName": "fsd/inconsistent-naming", + "severity": "error" + }, + { + "message": "This slice has no references. Consider removing it.", + "location": { + "path": "/Users/illright/work/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/users" + }, + "ruleName": "fsd/insignificant-slice", + "severity": "error" + }, + { + "message": "This slice has no references. Consider removing it.", + "location": { + "path": "/Users/illright/work/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user" + }, + "ruleName": "fsd/insignificant-slice", + "severity": "error" + }, + { + "message": "Forbidden sidestep of public API when importing from \"@/app/ui/App\".", + "location": { + "path": "/Users/illright/work/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user/api/getUser.ts" + }, + "ruleName": "fsd/no-public-api-sidestep", + "severity": "error" + }, + { + "message": "Having a folder with the name \"api\" inside a segment could be confusing because that name is commonly used for segments. Consider renaming it.", + "location": { + "path": "/Users/illright/work/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user/ui/api" + }, + "ruleName": "fsd/no-reserved-folder-names", + "severity": "error" + }, + { + "message": "Layer \"app\" should not have \"ui\" segment.", + "location": { + "path": "/Users/illright/work/steiger/examples/kitchen-sink-of-fsd-issues/src/app/ui" + }, + "ruleName": "fsd/no-ui-in-app", + "severity": "error" + }, + { + "message": "Layer \"processes\" is deprecated, avoid using it", + "location": { + "path": "/Users/illright/work/steiger/examples/kitchen-sink-of-fsd-issues/src/processes" + }, + "ruleName": "fsd/no-processes", + "severity": "error" + } +] diff --git a/examples/kitchen-sink-of-fsd-issues/src/app/ui/App.tsx b/examples/kitchen-sink-of-fsd-issues/src/app/ui/App.tsx new file mode 100644 index 00000000..8a3c0704 --- /dev/null +++ b/examples/kitchen-sink-of-fsd-issues/src/app/ui/App.tsx @@ -0,0 +1 @@ +export const App = {} diff --git a/examples/kitchen-sink-of-fsd-issues/src/app/ui/index.ts b/examples/kitchen-sink-of-fsd-issues/src/app/ui/index.ts new file mode 100644 index 00000000..5bfcd166 --- /dev/null +++ b/examples/kitchen-sink-of-fsd-issues/src/app/ui/index.ts @@ -0,0 +1 @@ +export { App } from './App' diff --git a/examples/kitchen-sink-of-fsd-issues/src/entities/user/api/getUser.ts b/examples/kitchen-sink-of-fsd-issues/src/entities/user/api/getUser.ts index e69de29b..299155c1 100644 --- a/examples/kitchen-sink-of-fsd-issues/src/entities/user/api/getUser.ts +++ b/examples/kitchen-sink-of-fsd-issues/src/entities/user/api/getUser.ts @@ -0,0 +1,3 @@ +import { App } from '@/app/ui/App' + +console.log(App) diff --git a/examples/kitchen-sink-of-fsd-issues/tsconfig.app.json b/examples/kitchen-sink-of-fsd-issues/tsconfig.app.json new file mode 100644 index 00000000..65fcfb5f --- /dev/null +++ b/examples/kitchen-sink-of-fsd-issues/tsconfig.app.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "module": "ESNext", + "jsx": "react-jsx", + "moduleResolution": "Bundler", + "baseUrl": ".", + "paths": { + "@/*": ["src/*"] + } + }, + "include": ["src"] +} diff --git a/examples/kitchen-sink-of-fsd-issues/tsconfig.json b/examples/kitchen-sink-of-fsd-issues/tsconfig.json index 0967ef42..82a8007e 100644 --- a/examples/kitchen-sink-of-fsd-issues/tsconfig.json +++ b/examples/kitchen-sink-of-fsd-issues/tsconfig.json @@ -1 +1,4 @@ -{} +{ + "files": [], + "references": [{ "path": "./tsconfig.app.json" }] +} From 454e367ba9b8943e0f8b6b70f1bcd361df21910b Mon Sep 17 00:00:00 2001 From: Lev Chelyadinov Date: Tue, 12 Nov 2024 20:07:41 +0100 Subject: [PATCH 02/17] Revert "Fix compilerOptions.paths resolution on Windows (#123)" This reverts commit 06af3dde56b757f7358024d9b904bfa9bbe0aa36. --- .changeset/spotty-yaks-listen.md | 5 ----- .../src/_lib/collect-related-ts-configs.ts | 21 +++++++++---------- 2 files changed, 10 insertions(+), 16 deletions(-) delete mode 100644 .changeset/spotty-yaks-listen.md diff --git a/.changeset/spotty-yaks-listen.md b/.changeset/spotty-yaks-listen.md deleted file mode 100644 index 6f216623..00000000 --- a/.changeset/spotty-yaks-listen.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@feature-sliced/steiger-plugin': patch ---- - -Fix path resolution on Windows diff --git a/packages/steiger-plugin-fsd/src/_lib/collect-related-ts-configs.ts b/packages/steiger-plugin-fsd/src/_lib/collect-related-ts-configs.ts index afcf1e4d..fd05c683 100644 --- a/packages/steiger-plugin-fsd/src/_lib/collect-related-ts-configs.ts +++ b/packages/steiger-plugin-fsd/src/_lib/collect-related-ts-configs.ts @@ -1,6 +1,5 @@ import { TSConfckParseResult } from 'tsconfck' -import { dirname, resolve } from 'node:path' -import { joinFromRoot } from '@steiger/toolkit' +import { dirname, posix } from 'node:path' export type CollectRelatedTsConfigsPayload = { tsconfig: TSConfckParseResult['tsconfig'] @@ -116,7 +115,7 @@ function makeRelativePathAliasesAbsolute( for (const entries of Object.entries(mergedConfig.compilerOptions.paths)) { const [key, paths] = entries as [key: string, paths: Array] absolutePaths[key] = paths.map((relativePath: string) => - resolve(dirname(firstConfigWithPaths.tsconfigFile!), relativePath), + posix.resolve(dirname(firstConfigWithPaths.tsconfigFile!), relativePath), ) } @@ -145,13 +144,13 @@ if (import.meta.vitest) { const payload: CollectRelatedTsConfigsPayload = { extended: [ { - tsconfigFile: resolve(joinFromRoot('tsconfig.json')), + tsconfigFile: '/tsconfig.json', tsconfig: { extends: './.nuxt/tsconfig.json', }, }, { - tsconfigFile: resolve(joinFromRoot('.nuxt', 'tsconfig.json')), + tsconfigFile: '/.nuxt/tsconfig.json', tsconfig: { compilerOptions: { paths: { @@ -168,7 +167,7 @@ if (import.meta.vitest) { }, }, ], - tsconfigFile: resolve(joinFromRoot('tsconfig.json')), + tsconfigFile: '/tsconfig.json', tsconfig: { extends: './.nuxt/tsconfig.json', compilerOptions: { @@ -191,8 +190,8 @@ if (import.meta.vitest) { extends: './.nuxt/tsconfig.json', compilerOptions: { paths: { - '~': [resolve(joinFromRoot())], - '~/*': [resolve(joinFromRoot('*'))], + '~': ['/'], + '~/*': ['/*'], }, strict: true, noUncheckedIndexedAccess: false, @@ -209,7 +208,7 @@ if (import.meta.vitest) { test('resolves paths independently from the current directory', () => { const payload: CollectRelatedTsConfigsPayload = { - tsconfigFile: resolve(joinFromRoot('user', 'projects', 'project-0', 'tsconfig.json')), + tsconfigFile: '/user/projects/project-0/tsconfig.json', tsconfig: { compilerOptions: { paths: { @@ -230,8 +229,8 @@ if (import.meta.vitest) { { compilerOptions: { paths: { - '~': [resolve(joinFromRoot('user', 'projects', 'project-0', 'src'))], - '~/*': [resolve(joinFromRoot('user', 'projects', 'project-0', 'src', '*'))], + '~': ['/user/projects/project-0/src'], + '~/*': ['/user/projects/project-0/src/*'], }, strict: true, noUncheckedIndexedAccess: false, From b2b084b59e8975a44a17734c8e0d62c2649ce67c Mon Sep 17 00:00:00 2001 From: Lev Chelyadinov Date: Tue, 12 Nov 2024 20:15:25 +0100 Subject: [PATCH 03/17] . --- .github/workflows/quality.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/quality.yaml b/.github/workflows/quality.yaml index 8436ba77..38938596 100644 --- a/.github/workflows/quality.yaml +++ b/.github/workflows/quality.yaml @@ -52,4 +52,5 @@ jobs: - name: Run E2E on a real project run: | node ./packages/steiger/dist/cli.mjs ./examples/kitchen-sink-of-fsd-issues/src/ --reporter json > output.json - diff <(jq --sort-keys . output.json) <(jq --sort-keys . examples/kitchen-sink-of-fsd-issues/reference-output.json) + jq --sort-keys . output.json + # diff <(jq --sort-keys . output.json) <(jq --sort-keys . examples/kitchen-sink-of-fsd-issues/reference-output.json) From 524d860f940c48f0d7da1a3042f7eccf9a059f99 Mon Sep 17 00:00:00 2001 From: Lev Chelyadinov Date: Tue, 12 Nov 2024 20:18:45 +0100 Subject: [PATCH 04/17] . --- .github/workflows/quality.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/quality.yaml b/.github/workflows/quality.yaml index 38938596..fd8bf5c9 100644 --- a/.github/workflows/quality.yaml +++ b/.github/workflows/quality.yaml @@ -50,7 +50,7 @@ jobs: run: turbo run build - name: Run E2E on a real project - run: | - node ./packages/steiger/dist/cli.mjs ./examples/kitchen-sink-of-fsd-issues/src/ --reporter json > output.json - jq --sort-keys . output.json - # diff <(jq --sort-keys . output.json) <(jq --sort-keys . examples/kitchen-sink-of-fsd-issues/reference-output.json) + run: node ./packages/steiger/dist/cli.mjs ./examples/kitchen-sink-of-fsd-issues/src/ --reporter json > output.json + + - name: Compare output + run: diff <(jq --sort-keys . output.json) <(jq --sort-keys . examples/kitchen-sink-of-fsd-issues/reference-output.json) From bf85a0b6f19ff92aa68f2ca5048c2451a28392b2 Mon Sep 17 00:00:00 2001 From: Lev Chelyadinov Date: Tue, 12 Nov 2024 20:23:04 +0100 Subject: [PATCH 05/17] oops --- .github/workflows/quality.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/quality.yaml b/.github/workflows/quality.yaml index fd8bf5c9..aca0c64b 100644 --- a/.github/workflows/quality.yaml +++ b/.github/workflows/quality.yaml @@ -51,6 +51,7 @@ jobs: - name: Run E2E on a real project run: node ./packages/steiger/dist/cli.mjs ./examples/kitchen-sink-of-fsd-issues/src/ --reporter json > output.json + continue-on-error: true - name: Compare output run: diff <(jq --sort-keys . output.json) <(jq --sort-keys . examples/kitchen-sink-of-fsd-issues/reference-output.json) From eeed7929493687013a3078f39bed7c80240fe54b Mon Sep 17 00:00:00 2001 From: Lev Chelyadinov Date: Tue, 12 Nov 2024 20:25:57 +0100 Subject: [PATCH 06/17] fix paths --- .../reference-output.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/kitchen-sink-of-fsd-issues/reference-output.json b/examples/kitchen-sink-of-fsd-issues/reference-output.json index 4fa9e3af..2e0139b9 100644 --- a/examples/kitchen-sink-of-fsd-issues/reference-output.json +++ b/examples/kitchen-sink-of-fsd-issues/reference-output.json @@ -2,7 +2,7 @@ { "message": "Forbidden import from higher layer \"app\".", "location": { - "path": "/Users/illright/work/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user/api/getUser.ts" + "path": "/home/runner/work/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user/api/getUser.ts" }, "ruleName": "fsd/forbidden-imports", "severity": "error" @@ -12,12 +12,12 @@ "fixes": [ { "type": "rename", - "path": "/Users/illright/work/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user", + "path": "/home/runner/work/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user", "newName": "users" } ], "location": { - "path": "/Users/illright/work/steiger/examples/kitchen-sink-of-fsd-issues/src/entities" + "path": "/home/runner/work/steiger/examples/kitchen-sink-of-fsd-issues/src/entities" }, "ruleName": "fsd/inconsistent-naming", "severity": "error" @@ -25,7 +25,7 @@ { "message": "This slice has no references. Consider removing it.", "location": { - "path": "/Users/illright/work/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/users" + "path": "/home/runner/work/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/users" }, "ruleName": "fsd/insignificant-slice", "severity": "error" @@ -33,7 +33,7 @@ { "message": "This slice has no references. Consider removing it.", "location": { - "path": "/Users/illright/work/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user" + "path": "/home/runner/work/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user" }, "ruleName": "fsd/insignificant-slice", "severity": "error" @@ -41,7 +41,7 @@ { "message": "Forbidden sidestep of public API when importing from \"@/app/ui/App\".", "location": { - "path": "/Users/illright/work/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user/api/getUser.ts" + "path": "/home/runner/work/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user/api/getUser.ts" }, "ruleName": "fsd/no-public-api-sidestep", "severity": "error" @@ -49,7 +49,7 @@ { "message": "Having a folder with the name \"api\" inside a segment could be confusing because that name is commonly used for segments. Consider renaming it.", "location": { - "path": "/Users/illright/work/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user/ui/api" + "path": "/home/runner/work/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user/ui/api" }, "ruleName": "fsd/no-reserved-folder-names", "severity": "error" @@ -57,7 +57,7 @@ { "message": "Layer \"app\" should not have \"ui\" segment.", "location": { - "path": "/Users/illright/work/steiger/examples/kitchen-sink-of-fsd-issues/src/app/ui" + "path": "/home/runner/work/steiger/examples/kitchen-sink-of-fsd-issues/src/app/ui" }, "ruleName": "fsd/no-ui-in-app", "severity": "error" @@ -65,7 +65,7 @@ { "message": "Layer \"processes\" is deprecated, avoid using it", "location": { - "path": "/Users/illright/work/steiger/examples/kitchen-sink-of-fsd-issues/src/processes" + "path": "/home/runner/work/steiger/examples/kitchen-sink-of-fsd-issues/src/processes" }, "ruleName": "fsd/no-processes", "severity": "error" From 0a7f7a45ca24c7178be24fd698fccf06718a4654 Mon Sep 17 00:00:00 2001 From: Lev Chelyadinov Date: Tue, 12 Nov 2024 20:31:25 +0100 Subject: [PATCH 07/17] . --- .github/workflows/quality.yaml | 2 +- ...son => reference-output-macos-latest.json} | 18 ++--- .../reference-output-ubuntu-latest.json | 73 +++++++++++++++++++ .../reference-output-windows-latest.json | 73 +++++++++++++++++++ 4 files changed, 156 insertions(+), 10 deletions(-) rename examples/kitchen-sink-of-fsd-issues/{reference-output.json => reference-output-macos-latest.json} (61%) create mode 100644 examples/kitchen-sink-of-fsd-issues/reference-output-ubuntu-latest.json create mode 100644 examples/kitchen-sink-of-fsd-issues/reference-output-windows-latest.json diff --git a/.github/workflows/quality.yaml b/.github/workflows/quality.yaml index aca0c64b..960c668c 100644 --- a/.github/workflows/quality.yaml +++ b/.github/workflows/quality.yaml @@ -54,4 +54,4 @@ jobs: continue-on-error: true - name: Compare output - run: diff <(jq --sort-keys . output.json) <(jq --sort-keys . examples/kitchen-sink-of-fsd-issues/reference-output.json) + run: diff <(jq --sort-keys . output.json) <(jq --sort-keys . examples/kitchen-sink-of-fsd-issues/reference-output-${{ matrix.os }}.json) diff --git a/examples/kitchen-sink-of-fsd-issues/reference-output.json b/examples/kitchen-sink-of-fsd-issues/reference-output-macos-latest.json similarity index 61% rename from examples/kitchen-sink-of-fsd-issues/reference-output.json rename to examples/kitchen-sink-of-fsd-issues/reference-output-macos-latest.json index 2e0139b9..53d8ef16 100644 --- a/examples/kitchen-sink-of-fsd-issues/reference-output.json +++ b/examples/kitchen-sink-of-fsd-issues/reference-output-macos-latest.json @@ -2,7 +2,7 @@ { "message": "Forbidden import from higher layer \"app\".", "location": { - "path": "/home/runner/work/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user/api/getUser.ts" + "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user/api/getUser.ts" }, "ruleName": "fsd/forbidden-imports", "severity": "error" @@ -12,12 +12,12 @@ "fixes": [ { "type": "rename", - "path": "/home/runner/work/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user", + "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user", "newName": "users" } ], "location": { - "path": "/home/runner/work/steiger/examples/kitchen-sink-of-fsd-issues/src/entities" + "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities" }, "ruleName": "fsd/inconsistent-naming", "severity": "error" @@ -25,7 +25,7 @@ { "message": "This slice has no references. Consider removing it.", "location": { - "path": "/home/runner/work/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/users" + "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/users" }, "ruleName": "fsd/insignificant-slice", "severity": "error" @@ -33,7 +33,7 @@ { "message": "This slice has no references. Consider removing it.", "location": { - "path": "/home/runner/work/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user" + "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user" }, "ruleName": "fsd/insignificant-slice", "severity": "error" @@ -41,7 +41,7 @@ { "message": "Forbidden sidestep of public API when importing from \"@/app/ui/App\".", "location": { - "path": "/home/runner/work/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user/api/getUser.ts" + "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user/api/getUser.ts" }, "ruleName": "fsd/no-public-api-sidestep", "severity": "error" @@ -49,7 +49,7 @@ { "message": "Having a folder with the name \"api\" inside a segment could be confusing because that name is commonly used for segments. Consider renaming it.", "location": { - "path": "/home/runner/work/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user/ui/api" + "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user/ui/api" }, "ruleName": "fsd/no-reserved-folder-names", "severity": "error" @@ -57,7 +57,7 @@ { "message": "Layer \"app\" should not have \"ui\" segment.", "location": { - "path": "/home/runner/work/steiger/examples/kitchen-sink-of-fsd-issues/src/app/ui" + "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/app/ui" }, "ruleName": "fsd/no-ui-in-app", "severity": "error" @@ -65,7 +65,7 @@ { "message": "Layer \"processes\" is deprecated, avoid using it", "location": { - "path": "/home/runner/work/steiger/examples/kitchen-sink-of-fsd-issues/src/processes" + "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/processes" }, "ruleName": "fsd/no-processes", "severity": "error" diff --git a/examples/kitchen-sink-of-fsd-issues/reference-output-ubuntu-latest.json b/examples/kitchen-sink-of-fsd-issues/reference-output-ubuntu-latest.json new file mode 100644 index 00000000..53d8ef16 --- /dev/null +++ b/examples/kitchen-sink-of-fsd-issues/reference-output-ubuntu-latest.json @@ -0,0 +1,73 @@ +[ + { + "message": "Forbidden import from higher layer \"app\".", + "location": { + "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user/api/getUser.ts" + }, + "ruleName": "fsd/forbidden-imports", + "severity": "error" + }, + { + "message": "Inconsistent pluralization of slice names. Prefer all plural names", + "fixes": [ + { + "type": "rename", + "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user", + "newName": "users" + } + ], + "location": { + "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities" + }, + "ruleName": "fsd/inconsistent-naming", + "severity": "error" + }, + { + "message": "This slice has no references. Consider removing it.", + "location": { + "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/users" + }, + "ruleName": "fsd/insignificant-slice", + "severity": "error" + }, + { + "message": "This slice has no references. Consider removing it.", + "location": { + "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user" + }, + "ruleName": "fsd/insignificant-slice", + "severity": "error" + }, + { + "message": "Forbidden sidestep of public API when importing from \"@/app/ui/App\".", + "location": { + "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user/api/getUser.ts" + }, + "ruleName": "fsd/no-public-api-sidestep", + "severity": "error" + }, + { + "message": "Having a folder with the name \"api\" inside a segment could be confusing because that name is commonly used for segments. Consider renaming it.", + "location": { + "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user/ui/api" + }, + "ruleName": "fsd/no-reserved-folder-names", + "severity": "error" + }, + { + "message": "Layer \"app\" should not have \"ui\" segment.", + "location": { + "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/app/ui" + }, + "ruleName": "fsd/no-ui-in-app", + "severity": "error" + }, + { + "message": "Layer \"processes\" is deprecated, avoid using it", + "location": { + "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/processes" + }, + "ruleName": "fsd/no-processes", + "severity": "error" + } +] diff --git a/examples/kitchen-sink-of-fsd-issues/reference-output-windows-latest.json b/examples/kitchen-sink-of-fsd-issues/reference-output-windows-latest.json new file mode 100644 index 00000000..53d8ef16 --- /dev/null +++ b/examples/kitchen-sink-of-fsd-issues/reference-output-windows-latest.json @@ -0,0 +1,73 @@ +[ + { + "message": "Forbidden import from higher layer \"app\".", + "location": { + "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user/api/getUser.ts" + }, + "ruleName": "fsd/forbidden-imports", + "severity": "error" + }, + { + "message": "Inconsistent pluralization of slice names. Prefer all plural names", + "fixes": [ + { + "type": "rename", + "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user", + "newName": "users" + } + ], + "location": { + "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities" + }, + "ruleName": "fsd/inconsistent-naming", + "severity": "error" + }, + { + "message": "This slice has no references. Consider removing it.", + "location": { + "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/users" + }, + "ruleName": "fsd/insignificant-slice", + "severity": "error" + }, + { + "message": "This slice has no references. Consider removing it.", + "location": { + "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user" + }, + "ruleName": "fsd/insignificant-slice", + "severity": "error" + }, + { + "message": "Forbidden sidestep of public API when importing from \"@/app/ui/App\".", + "location": { + "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user/api/getUser.ts" + }, + "ruleName": "fsd/no-public-api-sidestep", + "severity": "error" + }, + { + "message": "Having a folder with the name \"api\" inside a segment could be confusing because that name is commonly used for segments. Consider renaming it.", + "location": { + "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user/ui/api" + }, + "ruleName": "fsd/no-reserved-folder-names", + "severity": "error" + }, + { + "message": "Layer \"app\" should not have \"ui\" segment.", + "location": { + "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/app/ui" + }, + "ruleName": "fsd/no-ui-in-app", + "severity": "error" + }, + { + "message": "Layer \"processes\" is deprecated, avoid using it", + "location": { + "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/processes" + }, + "ruleName": "fsd/no-processes", + "severity": "error" + } +] From fa9b32c442f2d6c76ba5a6a7a1285c6e406aaca9 Mon Sep 17 00:00:00 2001 From: Lev Chelyadinov Date: Thu, 26 Dec 2024 20:44:40 +0100 Subject: [PATCH 08/17] Remove crap [skip ci] --- .../reference-output-macos-latest.json | 73 ------------------- .../reference-output-windows-latest.json | 73 ------------------- .../src/_lib/collect-related-ts-configs.ts | 56 ++------------ 3 files changed, 8 insertions(+), 194 deletions(-) delete mode 100644 examples/kitchen-sink-of-fsd-issues/reference-output-macos-latest.json delete mode 100644 examples/kitchen-sink-of-fsd-issues/reference-output-windows-latest.json diff --git a/examples/kitchen-sink-of-fsd-issues/reference-output-macos-latest.json b/examples/kitchen-sink-of-fsd-issues/reference-output-macos-latest.json deleted file mode 100644 index 53d8ef16..00000000 --- a/examples/kitchen-sink-of-fsd-issues/reference-output-macos-latest.json +++ /dev/null @@ -1,73 +0,0 @@ -[ - { - "message": "Forbidden import from higher layer \"app\".", - "location": { - "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user/api/getUser.ts" - }, - "ruleName": "fsd/forbidden-imports", - "severity": "error" - }, - { - "message": "Inconsistent pluralization of slice names. Prefer all plural names", - "fixes": [ - { - "type": "rename", - "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user", - "newName": "users" - } - ], - "location": { - "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities" - }, - "ruleName": "fsd/inconsistent-naming", - "severity": "error" - }, - { - "message": "This slice has no references. Consider removing it.", - "location": { - "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/users" - }, - "ruleName": "fsd/insignificant-slice", - "severity": "error" - }, - { - "message": "This slice has no references. Consider removing it.", - "location": { - "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user" - }, - "ruleName": "fsd/insignificant-slice", - "severity": "error" - }, - { - "message": "Forbidden sidestep of public API when importing from \"@/app/ui/App\".", - "location": { - "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user/api/getUser.ts" - }, - "ruleName": "fsd/no-public-api-sidestep", - "severity": "error" - }, - { - "message": "Having a folder with the name \"api\" inside a segment could be confusing because that name is commonly used for segments. Consider renaming it.", - "location": { - "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user/ui/api" - }, - "ruleName": "fsd/no-reserved-folder-names", - "severity": "error" - }, - { - "message": "Layer \"app\" should not have \"ui\" segment.", - "location": { - "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/app/ui" - }, - "ruleName": "fsd/no-ui-in-app", - "severity": "error" - }, - { - "message": "Layer \"processes\" is deprecated, avoid using it", - "location": { - "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/processes" - }, - "ruleName": "fsd/no-processes", - "severity": "error" - } -] diff --git a/examples/kitchen-sink-of-fsd-issues/reference-output-windows-latest.json b/examples/kitchen-sink-of-fsd-issues/reference-output-windows-latest.json deleted file mode 100644 index 53d8ef16..00000000 --- a/examples/kitchen-sink-of-fsd-issues/reference-output-windows-latest.json +++ /dev/null @@ -1,73 +0,0 @@ -[ - { - "message": "Forbidden import from higher layer \"app\".", - "location": { - "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user/api/getUser.ts" - }, - "ruleName": "fsd/forbidden-imports", - "severity": "error" - }, - { - "message": "Inconsistent pluralization of slice names. Prefer all plural names", - "fixes": [ - { - "type": "rename", - "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user", - "newName": "users" - } - ], - "location": { - "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities" - }, - "ruleName": "fsd/inconsistent-naming", - "severity": "error" - }, - { - "message": "This slice has no references. Consider removing it.", - "location": { - "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/users" - }, - "ruleName": "fsd/insignificant-slice", - "severity": "error" - }, - { - "message": "This slice has no references. Consider removing it.", - "location": { - "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user" - }, - "ruleName": "fsd/insignificant-slice", - "severity": "error" - }, - { - "message": "Forbidden sidestep of public API when importing from \"@/app/ui/App\".", - "location": { - "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user/api/getUser.ts" - }, - "ruleName": "fsd/no-public-api-sidestep", - "severity": "error" - }, - { - "message": "Having a folder with the name \"api\" inside a segment could be confusing because that name is commonly used for segments. Consider renaming it.", - "location": { - "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user/ui/api" - }, - "ruleName": "fsd/no-reserved-folder-names", - "severity": "error" - }, - { - "message": "Layer \"app\" should not have \"ui\" segment.", - "location": { - "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/app/ui" - }, - "ruleName": "fsd/no-ui-in-app", - "severity": "error" - }, - { - "message": "Layer \"processes\" is deprecated, avoid using it", - "location": { - "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/processes" - }, - "ruleName": "fsd/no-processes", - "severity": "error" - } -] diff --git a/packages/steiger-plugin-fsd/src/_lib/collect-related-ts-configs.ts b/packages/steiger-plugin-fsd/src/_lib/collect-related-ts-configs.ts index 342c2e30..5e42269a 100644 --- a/packages/steiger-plugin-fsd/src/_lib/collect-related-ts-configs.ts +++ b/packages/steiger-plugin-fsd/src/_lib/collect-related-ts-configs.ts @@ -1,5 +1,6 @@ import { TSConfckParseResult } from 'tsconfck' -import { dirname } from 'node:path' +import { dirname, resolve } from 'node:path' +import { joinFromRoot } from '@steiger/toolkit' export type CollectRelatedTsConfigsPayload = { tsconfig: TSConfckParseResult['tsconfig'] @@ -149,13 +150,13 @@ if (import.meta.vitest) { const payload: CollectRelatedTsConfigsPayload = { extended: [ { - tsconfigFile: '/tsconfig.json', + tsconfigFile: resolve(joinFromRoot('tsconfig.json')), tsconfig: { extends: './.nuxt/tsconfig.json', }, }, { - tsconfigFile: '/.nuxt/tsconfig.json', + tsconfigFile: resolve(joinFromRoot('.nuxt', 'tsconfig.json')), tsconfig: { compilerOptions: { paths: { @@ -172,7 +173,7 @@ if (import.meta.vitest) { }, }, ], - tsconfigFile: '/tsconfig.json', + tsconfigFile: resolve(joinFromRoot('tsconfig.json')), tsconfig: { extends: './.nuxt/tsconfig.json', compilerOptions: { @@ -195,8 +196,8 @@ if (import.meta.vitest) { extends: './.nuxt/tsconfig.json', compilerOptions: { paths: { - '~': ['/'], - '~/*': ['/*'], + '~': [resolve(joinFromRoot())], + '~/*': [resolve(joinFromRoot('*'))], }, strict: true, noUncheckedIndexedAccess: false, @@ -213,7 +214,7 @@ if (import.meta.vitest) { test('resolves paths independently from the current directory', () => { const payload: CollectRelatedTsConfigsPayload = { - tsconfigFile: '/user/projects/project-0/tsconfig.json', + tsconfigFile: resolve(joinFromRoot('user', 'projects', 'project-0', 'tsconfig.json')), tsconfig: { compilerOptions: { paths: { @@ -233,47 +234,6 @@ if (import.meta.vitest) { const expectedResult = [ { compilerOptions: { - paths: { - '~': ['/user/projects/project-0/src'], - '~/*': ['/user/projects/project-0/src/*'], - }, - strict: true, - noUncheckedIndexedAccess: false, - forceConsistentCasingInFileNames: true, - noImplicitOverride: true, - module: 'ESNext', - noEmit: true, - }, - }, - ] - - expect(collectRelatedTsConfigs(payload)).toEqual(expectedResult) - }) - - test('correctly resolves paths if baseUrl is set', () => { - const payload: CollectRelatedTsConfigsPayload = { - tsconfigFile: resolve(joinFromRoot('user', 'projects', 'project-0', 'tsconfig.json')), - tsconfig: { - compilerOptions: { - baseUrl: './src', - paths: { - '~': ['./'], - '~/*': ['./*'], - }, - strict: true, - noUncheckedIndexedAccess: false, - forceConsistentCasingInFileNames: true, - noImplicitOverride: true, - module: 'ESNext', - noEmit: true, - }, - }, - } - - const expectedResult = [ - { - compilerOptions: { - baseUrl: './src', paths: { '~': [resolve(joinFromRoot('user', 'projects', 'project-0', 'src'))], '~/*': [resolve(joinFromRoot('user', 'projects', 'project-0', 'src', '*'))], From f3f686529203da046d6bf0d6821368891cc8a3d3 Mon Sep 17 00:00:00 2001 From: Lev Chelyadinov Date: Thu, 26 Dec 2024 23:51:45 +0100 Subject: [PATCH 09/17] Rebuild the integration test into a separate package --- .../reference-output-ubuntu-latest.json | 73 ----------- integration-tests/eslint.config.mjs | 1 + integration-tests/package.json | 42 +++++++ integration-tests/reset.d.ts | 2 + .../scripts/update-windows-snapshots.mjs | 14 +++ .../__snapshots__/smoke-stderr-posix.txt | 45 +++++++ .../__snapshots__/smoke-stderr-windows.txt | 45 +++++++ integration-tests/tests/smoke.test.ts | 24 ++++ integration-tests/tsconfig.json | 7 ++ integration-tests/utils/get-bin-path.ts | 22 ++++ packages/steiger/src/app.ts | 21 ++-- pnpm-lock.yaml | 117 +++++++++++++++++- pnpm-workspace.yaml | 1 + 13 files changed, 328 insertions(+), 86 deletions(-) delete mode 100644 examples/kitchen-sink-of-fsd-issues/reference-output-ubuntu-latest.json create mode 100644 integration-tests/eslint.config.mjs create mode 100644 integration-tests/package.json create mode 100644 integration-tests/reset.d.ts create mode 100644 integration-tests/scripts/update-windows-snapshots.mjs create mode 100644 integration-tests/tests/__snapshots__/smoke-stderr-posix.txt create mode 100644 integration-tests/tests/__snapshots__/smoke-stderr-windows.txt create mode 100644 integration-tests/tests/smoke.test.ts create mode 100644 integration-tests/tsconfig.json create mode 100644 integration-tests/utils/get-bin-path.ts diff --git a/examples/kitchen-sink-of-fsd-issues/reference-output-ubuntu-latest.json b/examples/kitchen-sink-of-fsd-issues/reference-output-ubuntu-latest.json deleted file mode 100644 index 53d8ef16..00000000 --- a/examples/kitchen-sink-of-fsd-issues/reference-output-ubuntu-latest.json +++ /dev/null @@ -1,73 +0,0 @@ -[ - { - "message": "Forbidden import from higher layer \"app\".", - "location": { - "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user/api/getUser.ts" - }, - "ruleName": "fsd/forbidden-imports", - "severity": "error" - }, - { - "message": "Inconsistent pluralization of slice names. Prefer all plural names", - "fixes": [ - { - "type": "rename", - "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user", - "newName": "users" - } - ], - "location": { - "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities" - }, - "ruleName": "fsd/inconsistent-naming", - "severity": "error" - }, - { - "message": "This slice has no references. Consider removing it.", - "location": { - "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/users" - }, - "ruleName": "fsd/insignificant-slice", - "severity": "error" - }, - { - "message": "This slice has no references. Consider removing it.", - "location": { - "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user" - }, - "ruleName": "fsd/insignificant-slice", - "severity": "error" - }, - { - "message": "Forbidden sidestep of public API when importing from \"@/app/ui/App\".", - "location": { - "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user/api/getUser.ts" - }, - "ruleName": "fsd/no-public-api-sidestep", - "severity": "error" - }, - { - "message": "Having a folder with the name \"api\" inside a segment could be confusing because that name is commonly used for segments. Consider renaming it.", - "location": { - "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/entities/user/ui/api" - }, - "ruleName": "fsd/no-reserved-folder-names", - "severity": "error" - }, - { - "message": "Layer \"app\" should not have \"ui\" segment.", - "location": { - "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/app/ui" - }, - "ruleName": "fsd/no-ui-in-app", - "severity": "error" - }, - { - "message": "Layer \"processes\" is deprecated, avoid using it", - "location": { - "path": "/home/runner/work/steiger/steiger/examples/kitchen-sink-of-fsd-issues/src/processes" - }, - "ruleName": "fsd/no-processes", - "severity": "error" - } -] diff --git a/integration-tests/eslint.config.mjs b/integration-tests/eslint.config.mjs new file mode 100644 index 00000000..0cab0553 --- /dev/null +++ b/integration-tests/eslint.config.mjs @@ -0,0 +1 @@ +export { default } from '@steiger/eslint-config' diff --git a/integration-tests/package.json b/integration-tests/package.json new file mode 100644 index 00000000..9bd10227 --- /dev/null +++ b/integration-tests/package.json @@ -0,0 +1,42 @@ +{ + "private": true, + "name": "@steiger/integration-tests", + "description": "Integration tests for Steiger", + "version": "0.1.0", + "scripts": { + "test": "vitest run", + "update-windows-snapshots": "node ./scripts/update-windows-snapshots.mjs" + }, + "exports": { + ".": "./src/index.ts" + }, + "type": "module", + "license": "MIT", + "authors": [ + { + "name": "Anton Medvedev", + "email": "unordinarity@yandex.ru", + "url": "https://github.com/unordinarity" + }, + { + "name": "Lev Chelyadinov", + "email": "leva181777@gmail.com", + "url": "https://github.com/illright" + } + ], + "devDependencies": { + "@steiger/eslint-config": "workspace:*", + "@steiger/tsconfig": "workspace:*", + "@total-typescript/ts-reset": "^0.6.1", + "@types/node": "^18.11.9", + "eslint": "^9.16.0", + "get-bin-path": "^11.0.0", + "prettier": "^3.4.2", + "tinyexec": "^0.3.1", + "typescript": "^5.7.2", + "vitest": "^2.1.8" + }, + "dependencies": { + "steiger": "workspace:*" + } +} diff --git a/integration-tests/reset.d.ts b/integration-tests/reset.d.ts new file mode 100644 index 00000000..e3f32cd1 --- /dev/null +++ b/integration-tests/reset.d.ts @@ -0,0 +1,2 @@ +// Do not add any other lines of code to this file! +import '@total-typescript/ts-reset' diff --git a/integration-tests/scripts/update-windows-snapshots.mjs b/integration-tests/scripts/update-windows-snapshots.mjs new file mode 100644 index 00000000..4b151296 --- /dev/null +++ b/integration-tests/scripts/update-windows-snapshots.mjs @@ -0,0 +1,14 @@ +import * as fs from 'node:fs/promises' +import { dirname, join } from 'node:path' +import { fileURLToPath } from 'node:url' + +const snapshotsFolder = join(dirname(fileURLToPath(import.meta.url)), '../tests/__snapshots__') + +// Go through each POSIX snapshot and replace the forward slashes in diagnostic paths with backslashes +for (const file of await fs.readdir(snapshotsFolder)) { + if (file.endsWith('-posix.txt')) { + const windowsSnapshotName = file.slice(0, -'-posix.txt'.length) + '-windows.txt' + const updatedSnapshot = (await fs.readFile(join(snapshotsFolder, file), 'utf8')).replace(/(?<=┌.+)\//gm, '\\') + await fs.writeFile(join(snapshotsFolder, windowsSnapshotName), updatedSnapshot) + } +} diff --git a/integration-tests/tests/__snapshots__/smoke-stderr-posix.txt b/integration-tests/tests/__snapshots__/smoke-stderr-posix.txt new file mode 100644 index 00000000..01ebdfbc --- /dev/null +++ b/integration-tests/tests/__snapshots__/smoke-stderr-posix.txt @@ -0,0 +1,45 @@ + +┌ src/entities/user/api/getUser.ts +✘ Forbidden import from higher layer "app". +│ +└ fsd/forbidden-imports (​https://github.com/feature-sliced/steiger/tree/master/packages/steiger-plugin-fsd/src/forbidden-imports​) + +┌ src/entities +✘ Inconsistent pluralization of slice names. Prefer all plural names +✔ Auto-fixable +│ +└ fsd/inconsistent-naming (​https://github.com/feature-sliced/steiger/tree/master/packages/steiger-plugin-fsd/src/inconsistent-naming​) + +┌ src/entities/user +✘ This slice has no references. Consider removing it. +│ +└ fsd/insignificant-slice (​https://github.com/feature-sliced/steiger/tree/master/packages/steiger-plugin-fsd/src/insignificant-slice​) + +┌ src/entities/users +✘ This slice has no references. Consider removing it. +│ +└ fsd/insignificant-slice (​https://github.com/feature-sliced/steiger/tree/master/packages/steiger-plugin-fsd/src/insignificant-slice​) + +┌ src/entities/user/api/getUser.ts +✘ Forbidden sidestep of public API when importing from "@/app/ui/App". +│ +└ fsd/no-public-api-sidestep (​https://github.com/feature-sliced/steiger/tree/master/packages/steiger-plugin-fsd/src/no-public-api-sidestep​) + +┌ src/entities/user/ui/api +✘ Having a folder with the name "api" inside a segment could be confusing because that name is commonly used for segments. Consider renaming it. +│ +└ fsd/no-reserved-folder-names (​https://github.com/feature-sliced/steiger/tree/master/packages/steiger-plugin-fsd/src/no-reserved-folder-names​) + +┌ src/app/ui +✘ Layer "app" should not have "ui" segment. +│ +└ fsd/no-ui-in-app (​https://github.com/feature-sliced/steiger/tree/master/packages/steiger-plugin-fsd/src/no-ui-in-app​) + +┌ src/processes +✘ Layer "processes" is deprecated, avoid using it +│ +└ fsd/no-processes (​https://github.com/feature-sliced/steiger/tree/master/packages/steiger-plugin-fsd/src/no-processes​) + +──────────────────────────────────────────────────────── + Found 8 errors (1 can be fixed automatically with --fix) + diff --git a/integration-tests/tests/__snapshots__/smoke-stderr-windows.txt b/integration-tests/tests/__snapshots__/smoke-stderr-windows.txt new file mode 100644 index 00000000..3f123d62 --- /dev/null +++ b/integration-tests/tests/__snapshots__/smoke-stderr-windows.txt @@ -0,0 +1,45 @@ + +┌ src\entities\user\api\getUser.ts +✘ Forbidden import from higher layer "app". +│ +└ fsd/forbidden-imports (​https://github.com/feature-sliced/steiger/tree/master/packages/steiger-plugin-fsd/src/forbidden-imports​) + +┌ src\entities +✘ Inconsistent pluralization of slice names. Prefer all plural names +✔ Auto-fixable +│ +└ fsd/inconsistent-naming (​https://github.com/feature-sliced/steiger/tree/master/packages/steiger-plugin-fsd/src/inconsistent-naming​) + +┌ src\entities\user +✘ This slice has no references. Consider removing it. +│ +└ fsd/insignificant-slice (​https://github.com/feature-sliced/steiger/tree/master/packages/steiger-plugin-fsd/src/insignificant-slice​) + +┌ src\entities\users +✘ This slice has no references. Consider removing it. +│ +└ fsd/insignificant-slice (​https://github.com/feature-sliced/steiger/tree/master/packages/steiger-plugin-fsd/src/insignificant-slice​) + +┌ src\entities\user\api\getUser.ts +✘ Forbidden sidestep of public API when importing from "@/app/ui/App". +│ +└ fsd/no-public-api-sidestep (​https://github.com/feature-sliced/steiger/tree/master/packages/steiger-plugin-fsd/src/no-public-api-sidestep​) + +┌ src\entities\user\ui\api +✘ Having a folder with the name "api" inside a segment could be confusing because that name is commonly used for segments. Consider renaming it. +│ +└ fsd/no-reserved-folder-names (​https://github.com/feature-sliced/steiger/tree/master/packages/steiger-plugin-fsd/src/no-reserved-folder-names​) + +┌ src\app\ui +✘ Layer "app" should not have "ui" segment. +│ +└ fsd/no-ui-in-app (​https://github.com/feature-sliced/steiger/tree/master/packages/steiger-plugin-fsd/src/no-ui-in-app​) + +┌ src\processes +✘ Layer "processes" is deprecated, avoid using it +│ +└ fsd/no-processes (​https://github.com/feature-sliced/steiger/tree/master/packages/steiger-plugin-fsd/src/no-processes​) + +──────────────────────────────────────────────────────── + Found 8 errors (1 can be fixed automatically with --fix) + diff --git a/integration-tests/tests/smoke.test.ts b/integration-tests/tests/smoke.test.ts new file mode 100644 index 00000000..f499a304 --- /dev/null +++ b/integration-tests/tests/smoke.test.ts @@ -0,0 +1,24 @@ +import * as fs from 'node:fs/promises' +import os from 'node:os' +import { dirname, join } from 'node:path' +import { fileURLToPath } from 'node:url' +import { exec } from 'tinyexec' + +import { expect, test } from 'vitest' + +import { getSteigerBinPath } from '../utils/get-bin-path.js' + +const temporaryDirectory = await fs.realpath(os.tmpdir()) +const steiger = await getSteigerBinPath() +const kitchenSinkExample = join(dirname(fileURLToPath(import.meta.url)), '../../examples/kitchen-sink-of-fsd-issues') +const pathPlatform = os.platform() === 'win32' ? 'windows' : 'posix' + +test('basic functionality in the kitchen sink example project', async () => { + const project = join(temporaryDirectory, 'smoke') + await fs.rm(project, { recursive: true, force: true }) + await fs.cp(kitchenSinkExample, project, { recursive: true }) + + const { stderr } = await exec('node', [steiger, 'src'], { nodeOptions: { cwd: project } }) + + await expect(stderr).toMatchFileSnapshot(join('__snapshots__', `smoke-stderr-${pathPlatform}.txt`)) +}) diff --git a/integration-tests/tsconfig.json b/integration-tests/tsconfig.json new file mode 100644 index 00000000..e2b70993 --- /dev/null +++ b/integration-tests/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "@steiger/tsconfig/base.json", + "include": ["./tests", "./reset.d.ts", "utils/get-bin-path.ts"], + "compilerOptions": { + "tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json" + } +} diff --git a/integration-tests/utils/get-bin-path.ts b/integration-tests/utils/get-bin-path.ts new file mode 100644 index 00000000..871b8894 --- /dev/null +++ b/integration-tests/utils/get-bin-path.ts @@ -0,0 +1,22 @@ +import { promises as fs } from 'node:fs' +import * as process from 'node:process' +import { dirname, join } from 'node:path' +import { fileURLToPath } from 'node:url' +import { getBinPath } from 'get-bin-path' + +/** + * Resolve the full path to the built JS file of the CLI. + * + * Rejects if the file doesn't exist. + */ +export async function getSteigerBinPath() { + const steiger = (await getBinPath({ cwd: join(dirname(fileURLToPath(import.meta.url)), '../../packages/steiger') }))! + try { + await fs.stat(steiger) + } catch { + console.error('Run `npm run build` before running integration tests') + process.exit(1) + } + + return steiger +} diff --git a/packages/steiger/src/app.ts b/packages/steiger/src/app.ts index c44a8246..05687d34 100644 --- a/packages/steiger/src/app.ts +++ b/packages/steiger/src/app.ts @@ -21,12 +21,7 @@ async function runRules({ vfs, rules }: { vfs: Folder; rules: Array }) { const vfsWithoutGlobalIgnores = removeGlobalIgnoreFromVfs(vfs, getGlobalIgnores()) const ruleResults = await Promise.all(rules.map((rule) => runRule(vfsWithoutGlobalIgnores, rule))) - return ruleResults.flatMap((r, ruleResultsIndex) => { - const { diagnostics } = r - if (diagnostics.length === 0) { - return [] - } - + return ruleResults.flatMap(({ diagnostics }, ruleResultsIndex) => { const ruleName = rules[ruleResultsIndex].name const severities = calculateFinalSeverities( vfsWithoutGlobalIgnores, @@ -34,12 +29,14 @@ async function runRules({ vfs, rules }: { vfs: Folder; rules: Array }) { diagnostics.map((d) => d.location.path), ) - return diagnostics.map((d, index) => ({ - ...d, - ruleName, - getRuleDescriptionUrl, - severity: severities[index], - })) + return diagnostics + .sort((a, b) => a.location.path.localeCompare(b.location.path)) + .map((d, index) => ({ + ...d, + ruleName, + getRuleDescriptionUrl, + severity: severities[index], + })) }) } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 06f679df..585ba0df 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -33,6 +33,43 @@ importers: specifier: ^2.3.3 version: 2.3.3 + integration-tests: + dependencies: + steiger: + specifier: workspace:* + version: link:../packages/steiger + devDependencies: + '@steiger/eslint-config': + specifier: workspace:* + version: link:../tooling/eslint-config + '@steiger/tsconfig': + specifier: workspace:* + version: link:../tooling/tsconfig + '@total-typescript/ts-reset': + specifier: ^0.6.1 + version: 0.6.1 + '@types/node': + specifier: ^18.11.9 + version: 18.19.67 + eslint: + specifier: ^9.16.0 + version: 9.16.0 + get-bin-path: + specifier: ^11.0.0 + version: 11.0.0 + prettier: + specifier: ^3.4.2 + version: 3.4.2 + tinyexec: + specifier: ^0.3.1 + version: 0.3.1 + typescript: + specifier: ^5.7.2 + version: 5.7.2 + vitest: + specifier: ^2.1.8 + version: 2.1.8(@types/node@18.19.67) + packages/pretty-reporter: dependencies: chalk: @@ -1805,6 +1842,10 @@ packages: resolution: {integrity: sha512-hFM7oivtlgJ3d6XWD6G47l8Wyh/C6vFw5G24Kk1Tbq85yh5gcM8Fne5/lFhiuxB+RT6+SI7I1ThB9lG4FBh3jw==} engines: {node: '>=18'} + get-bin-path@11.0.0: + resolution: {integrity: sha512-hvX/hynZJ6sxeItamADFBZo0WmLoG/qZBlRCLRv+J+oN8USw1ZxefIGJSFPu1GGd3OHWVFJKvCCN970wmpiHzg==} + engines: {node: '>=18.18.0'} + get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} @@ -3742,7 +3783,7 @@ snapshots: debug: 4.4.0 globby: 11.1.0 is-glob: 4.0.3 - minimatch: 9.0.4 + minimatch: 9.0.5 semver: 7.6.3 ts-api-utils: 1.3.0(typescript@5.7.2) optionalDependencies: @@ -3792,6 +3833,14 @@ snapshots: chai: 5.1.2 tinyrainbow: 1.2.0 + '@vitest/mocker@2.1.8(vite@5.4.11(@types/node@18.19.67))': + dependencies: + '@vitest/spy': 2.1.8 + estree-walker: 3.0.3 + magic-string: 0.30.15 + optionalDependencies: + vite: 5.4.11(@types/node@18.19.67) + '@vitest/mocker@2.1.8(vite@5.4.11(@types/node@22.10.1))': dependencies: '@vitest/spy': 2.1.8 @@ -4433,6 +4482,10 @@ snapshots: ast-module-types: 6.0.0 node-source-walk: 7.0.0 + get-bin-path@11.0.0: + dependencies: + escalade: 3.1.2 + get-caller-file@2.0.5: {} get-east-asian-width@1.3.0: {} @@ -5362,6 +5415,24 @@ snapshots: validate-npm-package-name@5.0.1: {} + vite-node@2.1.8(@types/node@18.19.67): + dependencies: + cac: 6.7.14 + debug: 4.4.0 + es-module-lexer: 1.5.4 + pathe: 1.1.2 + vite: 5.4.11(@types/node@18.19.67) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + vite-node@2.1.8(@types/node@22.10.1): dependencies: cac: 6.7.14 @@ -5380,6 +5451,15 @@ snapshots: - supports-color - terser + vite@5.4.11(@types/node@18.19.67): + dependencies: + esbuild: 0.21.5 + postcss: 8.4.49 + rollup: 4.28.1 + optionalDependencies: + '@types/node': 18.19.67 + fsevents: 2.3.3 + vite@5.4.11(@types/node@22.10.1): dependencies: esbuild: 0.21.5 @@ -5389,6 +5469,41 @@ snapshots: '@types/node': 22.10.1 fsevents: 2.3.3 + vitest@2.1.8(@types/node@18.19.67): + dependencies: + '@vitest/expect': 2.1.8 + '@vitest/mocker': 2.1.8(vite@5.4.11(@types/node@18.19.67)) + '@vitest/pretty-format': 2.1.8 + '@vitest/runner': 2.1.8 + '@vitest/snapshot': 2.1.8 + '@vitest/spy': 2.1.8 + '@vitest/utils': 2.1.8 + chai: 5.1.2 + debug: 4.4.0 + expect-type: 1.1.0 + magic-string: 0.30.15 + pathe: 1.1.2 + std-env: 3.8.0 + tinybench: 2.9.0 + tinyexec: 0.3.1 + tinypool: 1.0.2 + tinyrainbow: 1.2.0 + vite: 5.4.11(@types/node@18.19.67) + vite-node: 2.1.8(@types/node@18.19.67) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 18.19.67 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + vitest@2.1.8(@types/node@22.10.1): dependencies: '@vitest/expect': 2.1.8 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 7104d705..ca6439c9 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,3 +1,4 @@ packages: - 'packages/*' - 'tooling/*' + - 'integration-tests' From 6393104644c957890800d0f622de4ed59b89e83c Mon Sep 17 00:00:00 2001 From: Lev Chelyadinov Date: Fri, 27 Dec 2024 00:54:48 +0100 Subject: [PATCH 10/17] Make it NO_COLOR --- integration-tests/tests/smoke.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-tests/tests/smoke.test.ts b/integration-tests/tests/smoke.test.ts index f499a304..c077c623 100644 --- a/integration-tests/tests/smoke.test.ts +++ b/integration-tests/tests/smoke.test.ts @@ -18,7 +18,7 @@ test('basic functionality in the kitchen sink example project', async () => { await fs.rm(project, { recursive: true, force: true }) await fs.cp(kitchenSinkExample, project, { recursive: true }) - const { stderr } = await exec('node', [steiger, 'src'], { nodeOptions: { cwd: project } }) + const { stderr } = await exec('node', [steiger, 'src'], { nodeOptions: { cwd: project, env: { NO_COLOR: '1' } } }) await expect(stderr).toMatchFileSnapshot(join('__snapshots__', `smoke-stderr-${pathPlatform}.txt`)) }) From 75a0ea590ae058ab26c692d2137f4f5b31edd69a Mon Sep 17 00:00:00 2001 From: Lev Chelyadinov Date: Fri, 27 Dec 2024 00:56:47 +0100 Subject: [PATCH 11/17] remove the crap --- .github/workflows/quality.yaml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/workflows/quality.yaml b/.github/workflows/quality.yaml index 960c668c..8d8412f5 100644 --- a/.github/workflows/quality.yaml +++ b/.github/workflows/quality.yaml @@ -48,10 +48,3 @@ jobs: - name: Try building run: turbo run build - - - name: Run E2E on a real project - run: node ./packages/steiger/dist/cli.mjs ./examples/kitchen-sink-of-fsd-issues/src/ --reporter json > output.json - continue-on-error: true - - - name: Compare output - run: diff <(jq --sort-keys . output.json) <(jq --sort-keys . examples/kitchen-sink-of-fsd-issues/reference-output-${{ matrix.os }}.json) From 1e1b499a3833ba2de6338b4528981b56c8ff6b89 Mon Sep 17 00:00:00 2001 From: Lev Chelyadinov Date: Fri, 27 Dec 2024 01:05:48 +0100 Subject: [PATCH 12/17] Update Windows snapshots to use fallback figures --- integration-tests/package.json | 1 + .../scripts/update-windows-snapshots.mjs | 5 ++++- .../__snapshots__/smoke-stderr-windows.txt | 18 +++++++++--------- pnpm-lock.yaml | 3 +++ 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/integration-tests/package.json b/integration-tests/package.json index 9bd10227..97eccea7 100644 --- a/integration-tests/package.json +++ b/integration-tests/package.json @@ -30,6 +30,7 @@ "@total-typescript/ts-reset": "^0.6.1", "@types/node": "^18.11.9", "eslint": "^9.16.0", + "figures": "^6.1.0", "get-bin-path": "^11.0.0", "prettier": "^3.4.2", "tinyexec": "^0.3.1", diff --git a/integration-tests/scripts/update-windows-snapshots.mjs b/integration-tests/scripts/update-windows-snapshots.mjs index 4b151296..b02f6f2c 100644 --- a/integration-tests/scripts/update-windows-snapshots.mjs +++ b/integration-tests/scripts/update-windows-snapshots.mjs @@ -1,6 +1,7 @@ import * as fs from 'node:fs/promises' import { dirname, join } from 'node:path' import { fileURLToPath } from 'node:url' +import { replaceSymbols } from 'figures' const snapshotsFolder = join(dirname(fileURLToPath(import.meta.url)), '../tests/__snapshots__') @@ -8,7 +9,9 @@ const snapshotsFolder = join(dirname(fileURLToPath(import.meta.url)), '../tests/ for (const file of await fs.readdir(snapshotsFolder)) { if (file.endsWith('-posix.txt')) { const windowsSnapshotName = file.slice(0, -'-posix.txt'.length) + '-windows.txt' - const updatedSnapshot = (await fs.readFile(join(snapshotsFolder, file), 'utf8')).replace(/(?<=┌.+)\//gm, '\\') + const updatedSnapshot = replaceSymbols(await fs.readFile(join(snapshotsFolder, file), 'utf8'), { + useFallback: true, + }).replace(/(?<=┌.+)\//gm, '\\') await fs.writeFile(join(snapshotsFolder, windowsSnapshotName), updatedSnapshot) } } diff --git a/integration-tests/tests/__snapshots__/smoke-stderr-windows.txt b/integration-tests/tests/__snapshots__/smoke-stderr-windows.txt index 3f123d62..8f942e48 100644 --- a/integration-tests/tests/__snapshots__/smoke-stderr-windows.txt +++ b/integration-tests/tests/__snapshots__/smoke-stderr-windows.txt @@ -1,42 +1,42 @@ ┌ src\entities\user\api\getUser.ts -✘ Forbidden import from higher layer "app". +× Forbidden import from higher layer "app". │ └ fsd/forbidden-imports (​https://github.com/feature-sliced/steiger/tree/master/packages/steiger-plugin-fsd/src/forbidden-imports​) ┌ src\entities -✘ Inconsistent pluralization of slice names. Prefer all plural names -✔ Auto-fixable +× Inconsistent pluralization of slice names. Prefer all plural names +√ Auto-fixable │ └ fsd/inconsistent-naming (​https://github.com/feature-sliced/steiger/tree/master/packages/steiger-plugin-fsd/src/inconsistent-naming​) ┌ src\entities\user -✘ This slice has no references. Consider removing it. +× This slice has no references. Consider removing it. │ └ fsd/insignificant-slice (​https://github.com/feature-sliced/steiger/tree/master/packages/steiger-plugin-fsd/src/insignificant-slice​) ┌ src\entities\users -✘ This slice has no references. Consider removing it. +× This slice has no references. Consider removing it. │ └ fsd/insignificant-slice (​https://github.com/feature-sliced/steiger/tree/master/packages/steiger-plugin-fsd/src/insignificant-slice​) ┌ src\entities\user\api\getUser.ts -✘ Forbidden sidestep of public API when importing from "@/app/ui/App". +× Forbidden sidestep of public API when importing from "@/app/ui/App". │ └ fsd/no-public-api-sidestep (​https://github.com/feature-sliced/steiger/tree/master/packages/steiger-plugin-fsd/src/no-public-api-sidestep​) ┌ src\entities\user\ui\api -✘ Having a folder with the name "api" inside a segment could be confusing because that name is commonly used for segments. Consider renaming it. +× Having a folder with the name "api" inside a segment could be confusing because that name is commonly used for segments. Consider renaming it. │ └ fsd/no-reserved-folder-names (​https://github.com/feature-sliced/steiger/tree/master/packages/steiger-plugin-fsd/src/no-reserved-folder-names​) ┌ src\app\ui -✘ Layer "app" should not have "ui" segment. +× Layer "app" should not have "ui" segment. │ └ fsd/no-ui-in-app (​https://github.com/feature-sliced/steiger/tree/master/packages/steiger-plugin-fsd/src/no-ui-in-app​) ┌ src\processes -✘ Layer "processes" is deprecated, avoid using it +× Layer "processes" is deprecated, avoid using it │ └ fsd/no-processes (​https://github.com/feature-sliced/steiger/tree/master/packages/steiger-plugin-fsd/src/no-processes​) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 585ba0df..9fbd8f10 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -54,6 +54,9 @@ importers: eslint: specifier: ^9.16.0 version: 9.16.0 + figures: + specifier: ^6.1.0 + version: 6.1.0 get-bin-path: specifier: ^11.0.0 version: 11.0.0 From d618d82c90de264eeed719e08f7ecf101e00c369 Mon Sep 17 00:00:00 2001 From: Lev Chelyadinov Date: Fri, 27 Dec 2024 01:14:56 +0100 Subject: [PATCH 13/17] Try fixing the bundle size workflow also --- .github/workflows/bundle-size-trusted.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/bundle-size-trusted.yaml b/.github/workflows/bundle-size-trusted.yaml index 8ff1e313..c91c7c2d 100644 --- a/.github/workflows/bundle-size-trusted.yaml +++ b/.github/workflows/bundle-size-trusted.yaml @@ -47,8 +47,8 @@ jobs: } } const fs = require('fs'); - const sizes = parseDuOutput(fs.readFileSync(`sizes-${${{ toJson(github.base_ref) }}}.txt`, 'utf8')); - const sizesPR = parseDuOutput(fs.readFileSync(`sizes-${${{ toJson(github.head_ref) }}}.txt`, 'utf8')); + const sizes = parseDuOutput(fs.readFileSync('sizes-master.txt', 'utf8')); + const sizesPR = parseDuOutput(fs.readFileSync(`sizes-${${{ toJson(github.event.workflow_run.head_branch) }}}.txt`, 'utf8')); core.summary.addHeading('📊 Package size report', '3'); core.summary.addTable([ ['Package', 'Before', 'After'].map((data) => ({ data, header: true })), From e10816217904a3b4cedd438c99f98ce1897e9ee4 Mon Sep 17 00:00:00 2001 From: Lev Chelyadinov Date: Fri, 27 Dec 2024 01:24:23 +0100 Subject: [PATCH 14/17] Clean up --- integration-tests/package.json | 6 ------ integration-tests/scripts/update-windows-snapshots.mjs | 6 ++++++ integration-tests/utils/get-bin-path.ts | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/integration-tests/package.json b/integration-tests/package.json index 97eccea7..d004c7ee 100644 --- a/integration-tests/package.json +++ b/integration-tests/package.json @@ -11,13 +11,7 @@ ".": "./src/index.ts" }, "type": "module", - "license": "MIT", "authors": [ - { - "name": "Anton Medvedev", - "email": "unordinarity@yandex.ru", - "url": "https://github.com/unordinarity" - }, { "name": "Lev Chelyadinov", "email": "leva181777@gmail.com", diff --git a/integration-tests/scripts/update-windows-snapshots.mjs b/integration-tests/scripts/update-windows-snapshots.mjs index b02f6f2c..8755a54e 100644 --- a/integration-tests/scripts/update-windows-snapshots.mjs +++ b/integration-tests/scripts/update-windows-snapshots.mjs @@ -1,3 +1,9 @@ +/** + * Run this script on Mac or Linux when you update test snapshots to port these changes over to Windows snapshots. + * + * $ pnpm run update-windows-snapshots + */ + import * as fs from 'node:fs/promises' import { dirname, join } from 'node:path' import { fileURLToPath } from 'node:url' diff --git a/integration-tests/utils/get-bin-path.ts b/integration-tests/utils/get-bin-path.ts index 871b8894..7bc8a84d 100644 --- a/integration-tests/utils/get-bin-path.ts +++ b/integration-tests/utils/get-bin-path.ts @@ -5,7 +5,7 @@ import { fileURLToPath } from 'node:url' import { getBinPath } from 'get-bin-path' /** - * Resolve the full path to the built JS file of the CLI. + * Resolve the full path to the built JS file of Steiger. * * Rejects if the file doesn't exist. */ @@ -14,7 +14,7 @@ export async function getSteigerBinPath() { try { await fs.stat(steiger) } catch { - console.error('Run `npm run build` before running integration tests') + console.error('Run `turbo build` before running integration tests') process.exit(1) } From 1faf5c597f7a5f3db7a8c2e7b81068f4570bcb9e Mon Sep 17 00:00:00 2001 From: Lev Chelyadinov Date: Fri, 27 Dec 2024 01:27:18 +0100 Subject: [PATCH 15/17] Add a changeset --- .changeset/flat-months-bow.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/flat-months-bow.md diff --git a/.changeset/flat-months-bow.md b/.changeset/flat-months-bow.md new file mode 100644 index 00000000..c402ae72 --- /dev/null +++ b/.changeset/flat-months-bow.md @@ -0,0 +1,5 @@ +--- +'steiger': patch +--- + +The diagnostics from a single rule are now sorted by path in alphabetical order From 6fc51f9b20a9f62db5bf8b2a3ae7ad50f9db76f7 Mon Sep 17 00:00:00 2001 From: Lev Chelyadinov Date: Fri, 3 Jan 2025 14:10:56 +0200 Subject: [PATCH 16/17] Fix monorepo issues --- integration-tests/package.json | 2 +- pnpm-lock.yaml | 119 ++++----------------------------- 2 files changed, 15 insertions(+), 106 deletions(-) diff --git a/integration-tests/package.json b/integration-tests/package.json index d004c7ee..3efd065a 100644 --- a/integration-tests/package.json +++ b/integration-tests/package.json @@ -29,7 +29,7 @@ "prettier": "^3.4.2", "tinyexec": "^0.3.1", "typescript": "^5.7.2", - "vitest": "^2.1.8" + "vitest": "^3.0.0-beta.2" }, "dependencies": { "steiger": "workspace:*" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 347803e7..7dea637a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -70,8 +70,8 @@ importers: specifier: ^5.7.2 version: 5.7.2 vitest: - specifier: ^2.1.8 - version: 2.1.8(@types/node@18.19.67) + specifier: ^3.0.0-beta.2 + version: 3.0.0-beta.2(@types/node@18.19.67) packages/pretty-reporter: dependencies: @@ -1316,23 +1316,9 @@ packages: resolution: {integrity: sha512-pCh/qEA8Lb1wVIqNvBke8UaRjJ6wrAWkJO5yyIbs8Yx6TNGYyfNjOo61tLv+WwLvoLPp4BQ8B7AHKijl8NGUfw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@vitest/expect@2.1.8': - resolution: {integrity: sha512-8ytZ/fFHq2g4PJVAtDX57mayemKgDR6X3Oa2Foro+EygiOJHUXhCqBAAKQYYajZpFoIfvBCF1j6R6IYRSIUFuw==} - '@vitest/expect@3.0.0-beta.2': resolution: {integrity: sha512-xdywwsqHOTZ66dBr8sQ+l3c0ZQs/wQY48fBRgLDrUqTU8OlDir6H1JMIOeV+Jb85Ov1XBGXBrSVlPDIo/fN5EQ==} - '@vitest/mocker@2.1.8': - resolution: {integrity: sha512-7guJ/47I6uqfttp33mgo6ga5Gr1VnL58rcqYKyShoRK9ebu8T5Rs6HN3s1NABiBeVTdWNrwUMcHH54uXZBN4zA==} - peerDependencies: - msw: ^2.4.9 - vite: ^5.0.0 - peerDependenciesMeta: - msw: - optional: true - vite: - optional: true - '@vitest/mocker@3.0.0-beta.2': resolution: {integrity: sha512-rSYrjKX8RwiKLw9MoZ8FDjos90C//AVphNVVYsv8QJn6brSkJLAOTFjTn13E8mF8kh3Bx8NKNgyDrx48ioJFXQ==} peerDependencies: @@ -1344,33 +1330,18 @@ packages: vite: optional: true - '@vitest/pretty-format@2.1.8': - resolution: {integrity: sha512-9HiSZ9zpqNLKlbIDRWOnAWqgcA7xu+8YxXSekhr0Ykab7PAYFkhkwoqVArPOtJhPmYeE2YHgKZlj3CP36z2AJQ==} - '@vitest/pretty-format@3.0.0-beta.2': resolution: {integrity: sha512-vMCmIdShOz2vjMCyxk+SoexZxsIbwrRc/weTctKxnQAYv3NubehpwCOaT8nhirmYQtdW+8r079wz1s7cKxNmCA==} - '@vitest/runner@2.1.8': - resolution: {integrity: sha512-17ub8vQstRnRlIU5k50bG+QOMLHRhYPAna5tw8tYbj+jzjcspnwnwtPtiOlkuKC4+ixDPTuLZiqiWWQ2PSXHVg==} - '@vitest/runner@3.0.0-beta.2': resolution: {integrity: sha512-Ytyub2tBCGrROrGfVlB8SuWdQjFYzJTTR969CGJF/xkIgdkLE9SiQzBZy4td2VidypntLXAVHYjeGr75pvw93w==} - '@vitest/snapshot@2.1.8': - resolution: {integrity: sha512-20T7xRFbmnkfcmgVEz+z3AU/3b0cEzZOt/zmnvZEctg64/QZbSDJEVm9fLnnlSi74KibmRsO9/Qabi+t0vCRPg==} - '@vitest/snapshot@3.0.0-beta.2': resolution: {integrity: sha512-6INaNxXyYBmFGHhjmSyoz+/P3F+e6sHZPXLYt2OAa6Zt1v1O91FoGUTwdNHj2ASxMQeVpK/7snxNaeyr2INVOg==} - '@vitest/spy@2.1.8': - resolution: {integrity: sha512-5swjf2q95gXeYPevtW0BLk6H8+bPlMb4Vw/9Em4hFxDcaOxS+e0LOX4yqNxoHzMR2akEB2xfpnWUzkZokmgWDg==} - '@vitest/spy@3.0.0-beta.2': resolution: {integrity: sha512-tSxQfS/wDWRtyx/a3smGuQr/YFaZk1iUsPbKkEvd6jIsrWBb747MSpdn9xfLgIhI68tXquCzruXiMQG0kHdILA==} - '@vitest/utils@2.1.8': - resolution: {integrity: sha512-dwSoui6djdwbfFmIgbIjX2ZhIoG7Ex/+xpxyiEgIGzjliY8xGkcpITKTlp6B4MgtGkF2ilvm97cPM96XZaAgcA==} - '@vitest/utils@3.0.0-beta.2': resolution: {integrity: sha512-Jkib9LoI9Xm3gmzwI+9KgEAJVZNgJQFrR1RAyqBN7k9O3qezOTUjqyYBnvyz3UcPywygP1jEjZWBxUKx4ELpxw==} @@ -2927,11 +2898,6 @@ packages: resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - vite-node@2.1.8: - resolution: {integrity: sha512-uPAwSr57kYjAUux+8E2j0q0Fxpn8M9VoyfGiRI8Kfktz9NcYMCenwY5RnZxnF1WTu3TGiYipirIzacLL3VVGFg==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - vite-node@3.0.0-beta.2: resolution: {integrity: sha512-ofTf6cfRdL30Wbl9n/BX81EyIR5s4PReLmSurrxQ+koLaWUNOEo8E0lCM53OJkb8vpa2URM2nSrxZsIFyvY1rg==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -2968,31 +2934,6 @@ packages: terser: optional: true - vitest@2.1.8: - resolution: {integrity: sha512-1vBKTZskHw/aosXqQUlVWWlGUxSJR8YtiyZDJAFeW2kPAeX6S3Sool0mjspO+kXLuxVWlEDDowBAeqeAQefqLQ==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@edge-runtime/vm': '*' - '@types/node': ^18.0.0 || >=20.0.0 - '@vitest/browser': 2.1.8 - '@vitest/ui': 2.1.8 - happy-dom: '*' - jsdom: '*' - peerDependenciesMeta: - '@edge-runtime/vm': - optional: true - '@types/node': - optional: true - '@vitest/browser': - optional: true - '@vitest/ui': - optional: true - happy-dom: - optional: true - jsdom: - optional: true - vitest@3.0.0-beta.2: resolution: {integrity: sha512-ZP0FVJ4tNJJOsjzZSuadEW0BPBgO7DMMen3mIE8TPPiPUMwz9YoS1U5bcqMYZ61r34xGsaYPe1h0l1MXt50f7g==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -3984,13 +3925,6 @@ snapshots: '@typescript-eslint/types': 8.18.0 eslint-visitor-keys: 4.2.0 - '@vitest/expect@2.1.8': - dependencies: - '@vitest/spy': 2.1.8 - '@vitest/utils': 2.1.8 - chai: 5.1.2 - tinyrainbow: 1.2.0 - '@vitest/expect@3.0.0-beta.2': dependencies: '@vitest/spy': 3.0.0-beta.2 @@ -3998,9 +3932,9 @@ snapshots: chai: 5.1.2 tinyrainbow: 1.2.0 - '@vitest/mocker@2.1.8(vite@5.4.11(@types/node@18.19.67))': + '@vitest/mocker@3.0.0-beta.2(vite@5.4.11(@types/node@18.19.67))': dependencies: - '@vitest/spy': 2.1.8 + '@vitest/spy': 3.0.0-beta.2 estree-walker: 3.0.3 magic-string: 0.30.15 optionalDependencies: @@ -4014,50 +3948,25 @@ snapshots: optionalDependencies: vite: 5.4.11(@types/node@22.10.1) - '@vitest/pretty-format@2.1.8': - dependencies: - tinyrainbow: 1.2.0 - '@vitest/pretty-format@3.0.0-beta.2': dependencies: tinyrainbow: 1.2.0 - '@vitest/runner@2.1.8': - dependencies: - '@vitest/utils': 2.1.8 - pathe: 1.1.2 - '@vitest/runner@3.0.0-beta.2': dependencies: '@vitest/utils': 3.0.0-beta.2 pathe: 1.1.2 - '@vitest/snapshot@2.1.8': - dependencies: - '@vitest/pretty-format': 2.1.8 - magic-string: 0.30.15 - pathe: 1.1.2 - '@vitest/snapshot@3.0.0-beta.2': dependencies: '@vitest/pretty-format': 3.0.0-beta.2 magic-string: 0.30.15 pathe: 1.1.2 - '@vitest/spy@2.1.8': - dependencies: - tinyspy: 3.0.2 - '@vitest/spy@3.0.0-beta.2': dependencies: tinyspy: 3.0.2 - '@vitest/utils@2.1.8': - dependencies: - '@vitest/pretty-format': 2.1.8 - loupe: 3.1.2 - tinyrainbow: 1.2.0 - '@vitest/utils@3.0.0-beta.2': dependencies: '@vitest/pretty-format': 3.0.0-beta.2 @@ -5628,7 +5537,7 @@ snapshots: validate-npm-package-name@5.0.1: {} - vite-node@2.1.8(@types/node@18.19.67): + vite-node@3.0.0-beta.2(@types/node@18.19.67): dependencies: cac: 6.7.14 debug: 4.4.0 @@ -5682,15 +5591,15 @@ snapshots: '@types/node': 22.10.1 fsevents: 2.3.3 - vitest@2.1.8(@types/node@18.19.67): + vitest@3.0.0-beta.2(@types/node@18.19.67): dependencies: - '@vitest/expect': 2.1.8 - '@vitest/mocker': 2.1.8(vite@5.4.11(@types/node@18.19.67)) - '@vitest/pretty-format': 2.1.8 - '@vitest/runner': 2.1.8 - '@vitest/snapshot': 2.1.8 - '@vitest/spy': 2.1.8 - '@vitest/utils': 2.1.8 + '@vitest/expect': 3.0.0-beta.2 + '@vitest/mocker': 3.0.0-beta.2(vite@5.4.11(@types/node@18.19.67)) + '@vitest/pretty-format': 3.0.0-beta.2 + '@vitest/runner': 3.0.0-beta.2 + '@vitest/snapshot': 3.0.0-beta.2 + '@vitest/spy': 3.0.0-beta.2 + '@vitest/utils': 3.0.0-beta.2 chai: 5.1.2 debug: 4.4.0 expect-type: 1.1.0 @@ -5702,7 +5611,7 @@ snapshots: tinypool: 1.0.2 tinyrainbow: 1.2.0 vite: 5.4.11(@types/node@18.19.67) - vite-node: 2.1.8(@types/node@18.19.67) + vite-node: 3.0.0-beta.2(@types/node@18.19.67) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 18.19.67 From bbccb4e35d0263389cff63ee5d74c94750837b68 Mon Sep 17 00:00:00 2001 From: Lev Chelyadinov Date: Fri, 3 Jan 2025 14:55:39 +0200 Subject: [PATCH 17/17] Add a README on how to write tests --- integration-tests/README.md | 10 ++++++++++ integration-tests/tsconfig.json | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 integration-tests/README.md diff --git a/integration-tests/README.md b/integration-tests/README.md new file mode 100644 index 00000000..df5b65ad --- /dev/null +++ b/integration-tests/README.md @@ -0,0 +1,10 @@ +# How to write integration tests + +> [!NOTE] +> You should develop tests on either Mac or Linux. If you have a Windows machine, consider using a [devcontainer](containers.dev). +> +> This is mainly because the Unicode symbols used in the output are always replaced by fallbacks on Windows, so converting outputs from Windows to POSIX isn't practical. + +Create a new file with the `.test.ts` extension in the `tests/` folder. Use `tests/smoke.test.ts` as a reference on how to set up a temporary folder for the project and execute Steiger. + +Store your output snapshots in `__snapshots__` with the `-posix.txt` extension. After you wrote your test, run `pnpm update-windows-snapshots` to copy over the changes in snapshots. diff --git a/integration-tests/tsconfig.json b/integration-tests/tsconfig.json index e2b70993..6c65b29b 100644 --- a/integration-tests/tsconfig.json +++ b/integration-tests/tsconfig.json @@ -1,6 +1,6 @@ { "extends": "@steiger/tsconfig/base.json", - "include": ["./tests", "./reset.d.ts", "utils/get-bin-path.ts"], + "include": ["./tests", "./utils", "./scripts", "./reset.d.ts"], "compilerOptions": { "tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json" }