Skip to content

feat: multi file lint rule codegen support#3052

Merged
arendjr merged 6 commits into
biomejs:mainfrom
ryan-m-walker:feat/multi-file-lint-documentation
Sep 10, 2025
Merged

feat: multi file lint rule codegen support#3052
arendjr merged 6 commits into
biomejs:mainfrom
ryan-m-walker:feat/multi-file-lint-documentation

Conversation

@ryan-m-walker

Copy link
Copy Markdown
Contributor

Summary

This PR modifies the website codgen process to utilize the file=<path> code block annotation for setting rendered block filenames as suggested in this comment and also adds support for rendering multi-file lint rule diagnostics. Much of the functionality is similar to this PR but ported to this repo.

The approach here is a bit different from the one in the main Biome repo, opting instead run a second parse pass to collect all files for the file system if we detect the need for it. This seemed like the better approach here since with the codegen process we are dealing with writers that write while we parse making the deferred evaluation approach used in the other PR much less practical or performant. File system parsing is run lazily though only when we detect the need for it so should hopefully add very little extra overhead. I'm open to exploring other approaches if there are any suggestions though.

@arendjr I mostly just copied over the get_test_services function over from the other repo with your changes as well. Maybe it would make sense to add this to the biome_test_utils package in the main repo? If it would be helpful I could do so in a follow up PR if you would like.

Example:

Screenshot 2025-09-05 at 11 09 46 PM

@netlify

netlify Bot commented Sep 6, 2025

Copy link
Copy Markdown

Deploy Preview for biomejs ready!

Name Link
🔨 Latest commit fa45f16
🔍 Latest deploy log https://app.netlify.com/projects/biomejs/deploys/68c119f17bbd1b00086e25c1
😎 Deploy Preview https://deploy-preview-3052--biomejs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Comment thread codegen/src/lintdoc.rs
@ryan-m-walker ryan-m-walker force-pushed the feat/multi-file-lint-documentation branch from d4f75fc to 9b63a72 Compare September 6, 2025 05:46

@ematipico ematipico left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a few questions, but overall it's looking amazing!

Comment thread codegen/src/lintdoc.rs
Comment thread codegen/src/lintdoc.rs
if let Some(file_path) = &test.file_path {
normalize_file_path(file_path)
} else {
format!("code-block.{}", test.tag)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't validate if the file has or doesn't have an extension. Do we check for that in the main repository ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah that isn't in the main repro but is a good idea, I can add in a follow up both here and the other repo if you would like

Comment thread codegen/src/lintdoc.rs
/// file system to a markdown section. This allows lint rules to access
/// multiple related files within the same documentation section while
/// keeping different examples isolated.
fn parse_file_system(docs: &'static str) -> Result<HashMap<usize, HashMap<String, String>>> {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not very clear what a "section" is. You might want to clarify that.

Also, it would be great if we explain the business logic of the parsing somewhere

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to improve the documentation to be more clear. Let me know if you think it's better or could be improved more

<pre class="language-text"><code class="language-text"><a href="file:///async-fn.ts">/async-fn.ts</a>:4:1 <a href="https://biomejs.dev/linter/rules/no-floating-promises">lint/nursery/noFloatingPromises</a> ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━<br /><br /> <strong><span style="color: lightgreen;">ℹ</span></strong> <span style="color: lightgreen;">A &quot;floating&quot; Promise was found, meaning it is not properly handled and could lead to ignored errors or unexpected behavior.</span><br /> <br /> <strong>2 │ </strong> return 'value';<br /> <strong>3 │ </strong>&#125;<br /> <strong><span style="color: Tomato;">&gt;</span></strong> <strong>4 │ </strong>returnsPromise().then(() =&gt; &#123;&#125;);<br /> <strong> │ </strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><br /> <strong>5 │ </strong><br /> <br /> <strong><span style="color: lightgreen;">ℹ</span></strong> <span style="color: lightgreen;">This happens when a Promise is not awaited, lacks a `.catch` or `.then` rejection handler, or is not explicitly ignored using the `void` operator.</span><br /> <br /></code></pre>

```file=async-fn2.ts
```ts title='async-fn2.ts'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great improvement!!

@arendjr arendjr left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work!

Indeed it would be nice if you could expose get_test_services() from biome_test_utils so we don't need to duplicate it here, but it's fine if you do that in a separate PR 👍

@ematipico

ematipico commented Sep 10, 2025

Copy link
Copy Markdown
Member

After reading the business logic and looking at the final result https://deploy-preview-3052--biomejs.netlify.app/linter/rules/no-import-cycles/#invalid , I have the following question: do we need headings for each file? They seem redundant if you look at the web page, because the file name are already part of code block

@ryan-m-walker

Copy link
Copy Markdown
Contributor Author

@ematipico I opened a small clean up PR here that would remove the filenames in favor of the file=<path> attributes instead and remove the redundant header in the UI. Those headers shouldn't be needed and are just left over from before the file path stuff was set up. Does that cover your concern?

@ematipico ematipico left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Happy to merge after the conflicts have been resolved

@ryan-m-walker ryan-m-walker force-pushed the feat/multi-file-lint-documentation branch from 0af1dbf to fa45f16 Compare September 10, 2025 06:25
@ryan-m-walker

Copy link
Copy Markdown
Contributor Author

@ematipico merge conflicts resolved!

@arendjr arendjr merged commit e149b09 into biomejs:main Sep 10, 2025
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants