Skip to content

Commit

Permalink
Merge branch 'next' into changes-from-master
Browse files Browse the repository at this point in the history
  • Loading branch information
illright committed Jan 4, 2025
2 parents b98e8b9 + 66d6f40 commit 62bfd6b
Show file tree
Hide file tree
Showing 34 changed files with 699 additions and 437 deletions.
5 changes: 5 additions & 0 deletions .changeset/beige-coins-cough.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@feature-sliced/steiger-plugin': minor
---

Add the forgotten `import-locality` rule
5 changes: 5 additions & 0 deletions .changeset/eighty-steaks-grow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@feature-sliced/steiger-plugin': patch
---

Refactor test cases to nest FSD roots
7 changes: 7 additions & 0 deletions .changeset/two-dragons-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@feature-sliced/steiger-plugin': minor
'steiger': minor
'@steiger/types': minor
---

Move getRuleDescriptionUrl from Steiger core to plugins
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ Currently, Steiger is not extendable with more rules, though that will change in
<tr> <td><a href="./packages/steiger-plugin-fsd/src/shared-lib-grouping/README.md"><code>fsd/shared-lib-grouping</code></a></td> <td>Forbid having too many ungrouped modules in <code>shared/lib</code>.</td> </tr>
<tr> <td><a href="./packages/steiger-plugin-fsd/src/typo-in-layer-name/README.md"><code>fsd/typo-in-layer-name</code></a></td> <td>Ensure that all layers are named without any typos.</td> </tr>
<tr> <td><a href="./packages/steiger-plugin-fsd/src/no-processes/README.md"><code>fsd/no-processes</code></a></td> <td>Discourage the use of the deprecated Processes layer.</td> </tr>
<tr> <td><a href="./packages/steiger-plugin-fsd/src/import-locality/README.md"><code>fsd/import-locality</code></a></td> <td>Require that imports from the same slice be relative and imports from one slice to another be absolute.</td> </tr>
</tbody>
</table>

Expand Down
8 changes: 6 additions & 2 deletions packages/pretty-reporter/example/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,12 @@ reportPretty(
severity: 'error',
getRuleDescriptionUrl,
},
{
message: 'Example of a diagnostic without a description URL',
ruleName: 'dummy/rule-name',
location: { path: '/home/user/project/src/pages' },
severity: 'error',
},
],
'/home/user/project',
)

// reportPretty([], '/home/user/project')
12 changes: 7 additions & 5 deletions packages/pretty-reporter/src/format-single-diagnostic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ export function formatSingleDiagnostic(d: Diagnostic, cwd: string): string {
const message = pc.reset(d.message)
const autofixable = d.fixes !== undefined && d.fixes.length > 0 ? pc.green(`${figures.tick} Auto-fixable`) : null
const location = pc.underline(formatLocation(d.location, cwd))
const ruleName = pc.blue(
terminalLink(d.ruleName, d.getRuleDescriptionUrl(d.ruleName).toString(), {
fallback: (text, url) => `${pc.reset(text)}: ${pc.blue(url)}`,
}),
)
const ruleName = d.getRuleDescriptionUrl
? pc.blue(
terminalLink(d.ruleName, d.getRuleDescriptionUrl(d.ruleName).toString(), {
fallback: (text, url) => `${pc.reset(text)}: ${pc.blue(url)}`,
}),
)
: pc.reset(d.ruleName)

return `
${s} ${location}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,13 @@ if (import.meta.vitest) {
const payload: CollectRelatedTsConfigsPayload = {
extended: [
{
tsconfigFile: resolve(joinFromRoot('tsconfig.json')),
tsconfigFile: resolve(joinFromRoot('user', 'projects', 'project-0', 'src', 'tsconfig.json')),
tsconfig: {
extends: './.nuxt/tsconfig.json',
},
},
{
tsconfigFile: resolve(joinFromRoot('.nuxt', 'tsconfig.json')),
tsconfigFile: resolve(joinFromRoot('user', 'projects', 'project-0', 'src', '.nuxt', 'tsconfig.json')),
tsconfig: {
compilerOptions: {
paths: {
Expand All @@ -173,7 +173,7 @@ if (import.meta.vitest) {
},
},
],
tsconfigFile: resolve(joinFromRoot('tsconfig.json')),
tsconfigFile: resolve(joinFromRoot('user', 'projects', 'project-0', 'src', 'tsconfig.json')),
tsconfig: {
extends: './.nuxt/tsconfig.json',
compilerOptions: {
Expand All @@ -196,8 +196,8 @@ if (import.meta.vitest) {
extends: './.nuxt/tsconfig.json',
compilerOptions: {
paths: {
'~': [resolve(joinFromRoot())],
'~/*': [resolve(joinFromRoot('*'))],
'~': [resolve(joinFromRoot('user', 'projects', 'project-0', 'src'))],
'~/*': [resolve(joinFromRoot('user', 'projects', 'project-0', 'src', '*'))],
},
strict: true,
noUncheckedIndexedAccess: false,
Expand Down
59 changes: 31 additions & 28 deletions packages/steiger-plugin-fsd/src/_lib/index-source-files.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ export function indexSourceFiles(root: Folder): Record<string, SourceFile> {
if (import.meta.vitest) {
const { test, expect } = import.meta.vitest
test('indexSourceFiles', () => {
const root = parseIntoFsdRoot(`
const root = parseIntoFsdRoot(
`
📂 shared
📂 ui
📄 styles.ts
Expand All @@ -80,120 +81,122 @@ if (import.meta.vitest) {
📄 index.ts
📄 root.ts
📄 index.ts
`)
`,
joinFromRoot('users', 'user', 'project', 'src'),
)

expect(indexSourceFiles(root)).toEqual({
[joinFromRoot('features', 'comments', 'index.ts')]: {
[joinFromRoot('users', 'user', 'project', 'src', 'features', 'comments', 'index.ts')]: {
file: {
path: joinFromRoot('features', 'comments', 'index.ts'),
path: joinFromRoot('users', 'user', 'project', 'src', 'features', 'comments', 'index.ts'),
type: 'file',
},
layerName: 'features',
segmentName: null,
sliceName: 'comments',
},
[joinFromRoot('features', 'comments', 'ui', 'CommentCard.tsx')]: {
[joinFromRoot('users', 'user', 'project', 'src', 'features', 'comments', 'ui', 'CommentCard.tsx')]: {
file: {
path: joinFromRoot('features', 'comments', 'ui', 'CommentCard.tsx'),
path: joinFromRoot('users', 'user', 'project', 'src', 'features', 'comments', 'ui', 'CommentCard.tsx'),
type: 'file',
},
layerName: 'features',
segmentName: 'ui',
sliceName: 'comments',
},
[joinFromRoot('pages', 'editor', 'index.ts')]: {
[joinFromRoot('users', 'user', 'project', 'src', 'pages', 'editor', 'index.ts')]: {
file: {
path: joinFromRoot('pages', 'editor', 'index.ts'),
path: joinFromRoot('users', 'user', 'project', 'src', 'pages', 'editor', 'index.ts'),
type: 'file',
},
layerName: 'pages',
segmentName: null,
sliceName: 'editor',
},
[joinFromRoot('pages', 'editor', 'ui', 'Editor.tsx')]: {
[joinFromRoot('users', 'user', 'project', 'src', 'pages', 'editor', 'ui', 'Editor.tsx')]: {
file: {
path: joinFromRoot('pages', 'editor', 'ui', 'Editor.tsx'),
path: joinFromRoot('users', 'user', 'project', 'src', 'pages', 'editor', 'ui', 'Editor.tsx'),
type: 'file',
},
layerName: 'pages',
segmentName: 'ui',
sliceName: 'editor',
},
[joinFromRoot('pages', 'editor', 'ui', 'EditorPage.tsx')]: {
[joinFromRoot('users', 'user', 'project', 'src', 'pages', 'editor', 'ui', 'EditorPage.tsx')]: {
file: {
path: joinFromRoot('pages', 'editor', 'ui', 'EditorPage.tsx'),
path: joinFromRoot('users', 'user', 'project', 'src', 'pages', 'editor', 'ui', 'EditorPage.tsx'),
type: 'file',
},
layerName: 'pages',
segmentName: 'ui',
sliceName: 'editor',
},
[joinFromRoot('pages', 'editor', 'ui', 'styles.ts')]: {
[joinFromRoot('users', 'user', 'project', 'src', 'pages', 'editor', 'ui', 'styles.ts')]: {
file: {
path: joinFromRoot('pages', 'editor', 'ui', 'styles.ts'),
path: joinFromRoot('users', 'user', 'project', 'src', 'pages', 'editor', 'ui', 'styles.ts'),
type: 'file',
},
layerName: 'pages',
segmentName: 'ui',
sliceName: 'editor',
},
[joinFromRoot('shared', 'ui', 'Button.tsx')]: {
[joinFromRoot('users', 'user', 'project', 'src', 'shared', 'ui', 'Button.tsx')]: {
file: {
path: joinFromRoot('shared', 'ui', 'Button.tsx'),
path: joinFromRoot('users', 'user', 'project', 'src', 'shared', 'ui', 'Button.tsx'),
type: 'file',
},
layerName: 'shared',
segmentName: 'ui',
sliceName: null,
},
[joinFromRoot('shared', 'ui', 'TextField.tsx')]: {
[joinFromRoot('users', 'user', 'project', 'src', 'shared', 'ui', 'TextField.tsx')]: {
file: {
path: joinFromRoot('shared', 'ui', 'TextField.tsx'),
path: joinFromRoot('users', 'user', 'project', 'src', 'shared', 'ui', 'TextField.tsx'),
type: 'file',
},
layerName: 'shared',
segmentName: 'ui',
sliceName: null,
},
[joinFromRoot('shared', 'ui', 'index.ts')]: {
[joinFromRoot('users', 'user', 'project', 'src', 'shared', 'ui', 'index.ts')]: {
file: {
path: joinFromRoot('shared', 'ui', 'index.ts'),
path: joinFromRoot('users', 'user', 'project', 'src', 'shared', 'ui', 'index.ts'),
type: 'file',
},
layerName: 'shared',
segmentName: 'ui',
sliceName: null,
},
[joinFromRoot('shared', 'ui', 'styles.ts')]: {
[joinFromRoot('users', 'user', 'project', 'src', 'shared', 'ui', 'styles.ts')]: {
file: {
path: joinFromRoot('shared', 'ui', 'styles.ts'),
path: joinFromRoot('users', 'user', 'project', 'src', 'shared', 'ui', 'styles.ts'),
type: 'file',
},
layerName: 'shared',
segmentName: 'ui',
sliceName: null,
},
[joinFromRoot('app', 'ui', 'index.ts')]: {
[joinFromRoot('users', 'user', 'project', 'src', 'app', 'ui', 'index.ts')]: {
file: {
path: joinFromRoot('app', 'ui', 'index.ts'),
path: joinFromRoot('users', 'user', 'project', 'src', 'app', 'ui', 'index.ts'),
type: 'file',
},
layerName: 'app',
segmentName: 'ui',
sliceName: null,
},
[joinFromRoot('app', 'root.ts')]: {
[joinFromRoot('users', 'user', 'project', 'src', 'app', 'root.ts')]: {
file: {
path: joinFromRoot('app', 'root.ts'),
path: joinFromRoot('users', 'user', 'project', 'src', 'app', 'root.ts'),
type: 'file',
},
layerName: 'app',
segmentName: 'root',
sliceName: null,
},
[joinFromRoot('app', 'index.ts')]: {
[joinFromRoot('users', 'user', 'project', 'src', 'app', 'index.ts')]: {
file: {
path: joinFromRoot('app', 'index.ts'),
path: joinFromRoot('users', 'user', 'project', 'src', 'app', 'index.ts'),
type: 'file',
},
layerName: 'app',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import ambiguousSliceNames from './index.js'
import { joinFromRoot, parseIntoFolder as parseIntoFsdRoot } from '@steiger/toolkit'

it('reports no errors on a project without slice names that match some segment name in Shared', () => {
const root = parseIntoFsdRoot(`
const root = parseIntoFsdRoot(
`
📂 shared
📂 ui
📄 index.ts
Expand All @@ -20,13 +21,16 @@ it('reports no errors on a project without slice names that match some segment n
📂 home
📂 ui
📄 index.ts
`)
`,
joinFromRoot('users', 'user', 'project', 'src'),
)

expect(ambiguousSliceNames.check(root)).toEqual({ diagnostics: [] })
})

it('reports errors on a project with slice names that match some segment name in Shared', () => {
const root = parseIntoFsdRoot(`
const root = parseIntoFsdRoot(
`
📂 shared
📂 ui
📄 index.ts
Expand All @@ -45,19 +49,22 @@ it('reports errors on a project with slice names that match some segment name in
📂 home
📂 ui
📄 index.ts
`)
`,
joinFromRoot('users', 'user', 'project', 'src'),
)

const diagnostics = ambiguousSliceNames.check(root).diagnostics
expect(diagnostics).toEqual([
{
message: 'Slice "i18n" could be confused with a segment from Shared with the same name',
location: { path: joinFromRoot('features', 'i18n') },
location: { path: joinFromRoot('users', 'user', 'project', 'src', 'features', 'i18n') },
},
])
})

it('works for slice groups and grouped slices', () => {
const root = parseIntoFsdRoot(`
const root = parseIntoFsdRoot(
`
📂 shared
📂 ui
📄 index.ts
Expand All @@ -78,17 +85,19 @@ it('works for slice groups and grouped slices', () => {
📂 home
📂 ui
📄 index.ts
`)
`,
joinFromRoot('users', 'user', 'project', 'src'),
)

const diagnostics = ambiguousSliceNames.check(root).diagnostics
expect(diagnostics).toEqual([
{
message: 'Slice group "i18n" could be confused with a segment "i18n" from Shared',
location: { path: joinFromRoot('features', 'i18n') },
location: { path: joinFromRoot('users', 'user', 'project', 'src', 'features', 'i18n') },
},
{
message: `Slice "${join('test', 'store')}" could be confused with a segment "store" from Shared`,
location: { path: joinFromRoot('features', 'test', 'store') },
location: { path: joinFromRoot('users', 'user', 'project', 'src', 'features', 'test', 'store') },
},
])
})
Loading

0 comments on commit 62bfd6b

Please sign in to comment.