Conversation
|
Hello! 👋 This repository uses Auto for releasing packages using PR labels. ✨ This PR can be merged. It will not be considered when calculating future versions of the npm packages and will not appear in the changelogs. |
There was a problem hiding this comment.
Pull request overview
This PR adds four filesystem validation rules to the plugin-docs-cli tool to ensure documentation follows proper naming and structure conventions. The rules check for proper file naming, directory structure, and prevent common issues that could break URL slugs or result in unnamed categories in the documentation.
Changes:
- Added four new validation rules:
no-spaces-in-names,valid-file-naming,nested-dir-has-index, andno-empty-directories - Implemented a strict mode flag (
--strict, on by default) that controls whether certain rules report as errors or warnings - Added comprehensive test coverage for all new rules and strict/non-strict modes
Reviewed changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/plugin-docs-cli/src/validation/types.ts | Added strict boolean field to ValidationInput interface |
| packages/plugin-docs-cli/src/validation/rules/filesystem.ts | Implemented four new filesystem validation rules with strict mode support |
| packages/plugin-docs-cli/src/validation/rules/filesystem.test.ts | Added comprehensive test coverage for all new validation rules |
| packages/plugin-docs-cli/src/validation/engine.test.ts | Updated test fixture to include strict field |
| packages/plugin-docs-cli/src/commands/validate.command.ts | Added strict mode option parameter to validateCommand |
| packages/plugin-docs-cli/src/bin/run.ts | Added command-line argument parsing for --strict flag |
Comments suppressed due to low confidence (2)
packages/plugin-docs-cli/src/validation/rules/filesystem.ts:61
- The asset directory check only examines the directory name, not its path. This means any directory named 'img' at any nesting level will be excluded from validation, even if it's in a subdirectory like 'docs/subdir/img'. Consider whether this is intentional behavior or if asset directories should only be excluded at the root level. If root-level only is intended, check if the directory's parentPath equals input.docsPath.
// asset directories like img/ are expected to have no markdown
if (ASSET_DIRS.has(dir.name)) {
continue;
}
packages/plugin-docs-cli/src/validation/rules/filesystem.test.ts:56
- The comment states "img/ has no .md files at all - caught by no-empty-directories instead" but this is incorrect. Since 'img' is in ASSET_DIRS, it's skipped entirely by the continue statement at line 60 in filesystem.ts, so it won't be caught by no-empty-directories either. The comment should reflect that asset directories are excluded from all validation checks, not just nested-dir-has-index.
// img/ has no .md files at all - caught by no-empty-directories instead
const finding = findings.find((f) => f.rule === 'nested-dir-has-index' && f.file?.endsWith('img'));
| recursive: true, | ||
| filter: (src) => { | ||
| const ext = extname(src).toLowerCase(); | ||
| return ext === '' || ALLOWED_EXTENSIONS.has(ext); |
There was a problem hiding this comment.
As discussed before @academo, copy inside the build cmd is now aligned with allowed file types rule
There was a problem hiding this comment.
nice! just a nit: put these in common constants (not only inside the file system rule) maybe we'll be using it in other places.
There was a problem hiding this comment.
Hmm I feel like filesystem.ts is already to right home for the ALLOWED_EXTENSIONS const.
| const result = await validate({ docsPath, strict: options.strict }, allRules); | ||
|
|
||
| console.log(JSON.stringify(result, null, 2)); | ||
| if (options.json) { |
There was a problem hiding this comment.
not for this PR but good to open an issue: make an option to output json to a file. sometimes is much easier to read an output file than stdout json output.
There was a problem hiding this comment.
An alternative is to pipe the output to a file if that would be a good enough solution?
There was a problem hiding this comment.
Yes piping could work for now! Added an issue so we can track this: https://github.com/grafana/grafana-catalog-team/issues/782
| const findings = await checkFilesystem({ docsPath: testDocsPath, strict: true }); | ||
|
|
||
| // img/ has no .md files at all - caught by no-empty-directories instead | ||
| const finding = findings.find((f) => f.rule === 'nested-dir-has-index' && f.file?.endsWith('img')); |
There was a problem hiding this comment.
sort of a nit but important to consider: you are trying to create a single set of fixtures that will let you test all situations in a single go. but it creates this test complexity where you now have extract logic for your assertions.
e.g. in this case if you had a dedicated fixture for this case you would save the possible trouble of the fixture changing in the future generating a similar nested-dir-has-index (unlikely I know but consider other cases) in an img directory
just imagine you want to test this case where the directory is in fact called img but it has a md file inside.
my recommendation is to not shy away to create several fixtures for specific situations. This is also how the plugin-validator does it
There was a problem hiding this comment.
No I think this is a good point. I'll remove this and another three tests
mckn
left a comment
There was a problem hiding this comment.
Q: regarding the description of this PR. It says something like: "the serve command will use non-strict mode so developers aren't blocked during local previews." But when viewing the code I can't see that the serve command invoke the validate parts at all, right?
packages/plugin-docs-cli/src/validation/rules/filesystem.test.ts
Outdated
Show resolved
Hide resolved
| // docsPath doesn't exist or isn't readable | ||
| } | ||
|
|
||
| const mdFiles = entries.filter((e) => e.isFile() && e.name.endsWith('.md')); |
There was a problem hiding this comment.
nit: even though probably ok this and the next 3 lines can be done a single for-each loop or reduce loop.
another possible way of doing this is loop the entries and for each entry call checkSymlink, checkDirectory, etc... and those functions can return reports you append into your report. so the logic is not spread around like this
just a different style. this also works so I leave it up to you to change it.
There was a problem hiding this comment.
I feel like readability overrules perf here, so if ok with you I'll keep the four separate loops.
| const dirPath = join(dir.parentPath, dir.name); | ||
|
|
||
| // asset directories like img/ are expected to have no markdown | ||
| if (ASSET_DIRS.has(dir.name)) { |
There was a problem hiding this comment.
do we have a specific good reason to be opinionated on how the assets folders are called? what if I like to use images instead of img? or what if I just creates assets/img and so on.
do we have a strong valid reason to force people into a folder structure like this?
There was a problem hiding this comment.
The reasoning behind this is that IF we ever decide to pull out the images from the archive before sending it to GCS, having them in a predefined folder from the start will make this a lot easier. It doesn't cost much from I DX perspective, so I think this is worth it.
There was a problem hiding this comment.
we can pull images by walking a dir and fetching mime/types. we don't need to enforce any specific dir structure for that.
… types and improve directory checks
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
What this PR does / why we need it:
This PR adds six filesystem validation rules.
A strict mode (`--strict` flag, on by default) controls whether certain rules report as errors or warnings. Serve-time validation with `strict: false` is planned in a follow-up PR.
It also adds `formatResult` for human-readable CLI output and a `--json` flag for machine-readable output, and syncs the build command's copy filter with the `allowed-file-types` rule.
Which issue(s) this PR fixes:
Part of https://github.com/issues/assigned?issue=grafana%7Cgrafana-catalog-team%7C769
Special notes for your reviewer: