|
4 | 4 | import path from 'node:path' |
5 | 5 | import { minimatch } from 'minimatch' |
6 | 6 | import { isTestFile } from '../utils/import-boundaries.js' |
| 7 | +import { createCheckedDirsGetter } from '../utils/global-state.js' |
7 | 8 |
|
8 | 9 | // Default configuration based on Vue project modules blueprint |
9 | 10 | const defaultOptions = { |
@@ -358,6 +359,9 @@ export default { |
358 | 359 | ...(context.options[0] || {}), |
359 | 360 | } |
360 | 361 |
|
| 362 | + // Initialize global state to track reported subdirectories |
| 363 | + const getReportedSubdirs = createCheckedDirsGetter('no-orphaned-files-subdirs') |
| 364 | + |
361 | 365 | const filename = context.filename || context.getFilename() |
362 | 366 |
|
363 | 367 | // Skip files outside of src |
@@ -394,6 +398,20 @@ export default { |
394 | 398 | const orphanError = checkOrphanedFile(fileInfo, options.allowedDirectories, options.allowedRootFiles) |
395 | 399 |
|
396 | 400 | if (orphanError) { |
| 401 | + // For flat structure violations, only report once per subdirectory |
| 402 | + if (orphanError.message.includes('should have a flat structure')) { |
| 403 | + const subdirKey = `${fileInfo.category}/${fileInfo.subcategory}` |
| 404 | + const reportedSubdirs = getReportedSubdirs() |
| 405 | + |
| 406 | + if (reportedSubdirs.has(subdirKey)) { |
| 407 | + // Already reported this subdirectory, skip |
| 408 | + return |
| 409 | + } |
| 410 | + |
| 411 | + // Mark this subdirectory as reported |
| 412 | + reportedSubdirs.add(subdirKey) |
| 413 | + } |
| 414 | + |
397 | 415 | // Report main error |
398 | 416 | context.report({ |
399 | 417 | loc: { line: 1, column: 0 }, |
|
0 commit comments