Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Add SARIF output support #9078

Merged
merged 15 commits into from
Dec 13, 2023

Conversation

C-Hipple
Copy link
Contributor

@C-Hipple C-Hipple commented Dec 10, 2023

Summary

Adds support for sarif v2.1.0 output to cli, usable via the output-format paramter.

ruff . --output-format=sarif

Includes a few changes I wasn't sure of, namely:

  • Adds a few derives for Clone & Copy, which I think could be removed with a little extra work as well.

Test Plan

I built and ran this against several large open source projects and verified that the output sarif was valid, using Microsoft's SARIF validator tool

I've also attached an output of the sarif generated by this version of ruff on the main branch of django at commit: b287af5dc9
django_main_b287af5dc9_sarif.json

Note: this needs to be regenerated with the latest changes and confirmed.

Open Points

[ ] Convert to just using all Rules all the time
[ ] Fix the issue with getting the file URI when compiling for web assembly

@C-Hipple C-Hipple changed the title add sarif output--update snapshots Feature: Add SARIF output support Dec 10, 2023
@@ -424,7 +424,7 @@ pub fn check(args: CheckCommand, log_level: LogLevel) -> Result<ExitStatus> {
if cli.statistics {
printer.write_statistics(&diagnostics, &mut summary_writer)?;
} else {
printer.write_once(&diagnostics, &mut summary_writer)?;
printer.write_once(&diagnostics, &mut summary_writer, &pyproject_config)?;
Copy link
Member

Choose a reason for hiding this comment

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

So one potential issue here is that pyproject_config isn't guaranteed to contain the correct set of enabled rules for all files. Ruff supports hierarchical configuration, so you can have different configuration files that apply to different subdirectories in your project. The pyproject_config here really just represents the settings in the current working directory.

Could we infer the set of rules from the diagnostic messages? (What is this used for on the SARIF side?)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Gotcha--thanks for that context. SARIF lists the rules applied as part of the tool description so that you can be sure you're getting an apples to apples comparison, rather than just saying both times you checked with a particular rust version.

While the field is not mandatory in the SARIF specification Section 3.19.23 rules property it is required by Github. Also see: Understand Rules and Results

I'm not exactly sure how github would handle having the rules be supplied as only the ones for which diagnostics could be found as that's not documented.

Copy link
Member

Choose a reason for hiding this comment

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

Alternatively, could we just include all rules?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Including all rules is probably the safest bet. In my experience with code scanning on github, I've never looked at what checks were done, only the findings, so this is probably closest to the SARIF expectation. My gut is that most people have most rules applied, and only turn off a handful, but I could be wrong, especially for older/larger projects.

Only downsides are if someone complains and then we change it, if others are using it in their CI, the rules set will change, which again, not sure how bad that is and that the file size will be a bit larger.

Copy link
Member

Choose a reason for hiding this comment

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

Let's try all-rules for now. You can iterate over them with Rule::iter().

rule: message.kind.rule(),
level: "error".to_string(),
message: message.kind.name.to_owned(),
uri: Url::from_file_path(message.filename()).unwrap().to_string(),
Copy link
Member

@charliermarsh charliermarsh Dec 10, 2023

Choose a reason for hiding this comment

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

If filename is relative here, would this convert it to absolute? I do think filename will always be absolute here... we pass around absolute paths, and expect callers to call relativize_path when displaying user-facing relative paths... But we may want to be defensive (call .canonicalize() or normalize_path or similar).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is what I was referring to in the PR body. It'll error if the path is relative, which is why I changed the path in the snapshot files. I'll update to safely handle relative paths, should be straight forward.

Copy link
Member

Choose a reason for hiding this comment

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

👍 I did see that, but wasn't sure how Url::from_file_path would behave if the path wasn't absolute.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah, normalize_path seems like the right call here, as .canonicalize() will fail if the file doesn't actually exist (a la in test).

Copy link
Contributor

github-actions bot commented Dec 10, 2023

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

Formatter (stable)

✅ ecosystem check detected no format changes.

Formatter (preview)

✅ ecosystem check detected no format changes.

Copy link
Member

@charliermarsh charliermarsh left a comment

Choose a reason for hiding this comment

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

I think this is probably good to merge once we change to enumerate all-rules. @C-Hipple do you plan to make that change, or would you like a hand?

@C-Hipple
Copy link
Contributor Author

C-Hipple commented Dec 13, 2023 via email

@charliermarsh
Copy link
Member

Nice, thanks @C-Hipple!

@C-Hipple
Copy link
Contributor Author

please don't merge it yet--I'm adding a few more sarif fields

@charliermarsh
Copy link
Member

@C-Hipple -- Okay, sounds good. I just removed some of the copy and clone changes since the code seems to compile without them now. I'll wait for you to mark as ready for review.

@C-Hipple
Copy link
Contributor Author

Thanks--your changes look good. Appreciate your input there as I"m relatively new to rust and was kinda using this issue as a way of getting a bit more familiar.

@charliermarsh
Copy link
Member

Any questions let me know. Sorry if I stepped on your toes, didn't realize you were planning more changes!

@C-Hipple
Copy link
Contributor Author

@C-Hipple -- Okay, sounds good. I just removed some of the copy and clone changes since the code seems to compile without them now. I'll wait for you to mark as ready for review.

Yeah, those were needed at one point with how SarifResults were copying rules into them, was also planning on backing them out but you beat me to it.

Any questions let me know. Sorry if I stepped on your toes, didn't realize you were planning more changes!

no worries!

@C-Hipple
Copy link
Contributor Author

@charliermarsh I'm happy with the PR now, but I'm really unsure of the last commit--the anyhow import was failing lint due to being unused in wasm and it was also failing lint for unnecessary wrapping, so I just ignored the errors, but open to learning if there's a more appropriate/idiomatic way

@C-Hipple C-Hipple marked this pull request as ready for review December 13, 2023 05:07
@charliermarsh
Copy link
Member

@C-Hipple -- What you have there is reasonable! But I'll play around with it and see if it can be improved.

@charliermarsh charliermarsh force-pushed the feature-add-sarif-output branch 3 times, most recently from 16d4bf0 to 3f5438b Compare December 13, 2023 05:26
@charliermarsh
Copy link
Member

@C-Hipple -- The only change I made was to use absolute references for the imports that were unused in the Wasm path. It's not a material difference, but it is nice to avoid the unused import ignore.

@charliermarsh
Copy link
Member

Unfortunately, #[allow(clippy::unnecessary_wraps)] is hard to avoid since we need the function to have the same signature on all platforms -- so if any of them return a Result, they all need to return a Result. We run into this in other parts of Ruff too.

@charliermarsh charliermarsh added the linter Related to the linter label Dec 13, 2023
@charliermarsh charliermarsh merged commit cb99815 into astral-sh:main Dec 13, 2023
16 checks passed
@C-Hipple C-Hipple deleted the feature-add-sarif-output branch December 19, 2023 20:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
linter Related to the linter
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants