ruff server respects per-file-ignores configuration (#11224)

## Summary

Fixes #11185
Fixes #11214 

Document path and package information is now forwarded to the Ruff
linter, which allows `per-file-ignores` to correctly match against the
file name. This also fixes an issue where the import sorting rule didn't
distinguish between third-party and first-party packages since we didn't
pass in the package root.

## Test Plan

`per-file-ignores` should ignore files as expected. One quick way to
check is by adding this to your `pyproject.toml`:
```toml
[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["ALL"]
```

Then, confirm that no diagnostics appear when you add code to an
`__init__.py` file (besides syntax errors).

The import sorting fix can be verified by failing to reproduce the
original issue - an `I001` diagnostic should not appear in
`other_module.py`.
This commit is contained in:
Jane Lewis 2024-05-01 19:24:35 -07:00 committed by GitHub
parent 653c8d83e9
commit 4aac1d1db9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 40 additions and 11 deletions

View file

@ -1,11 +1,10 @@
//! Access to the Ruff linting API for the LSP
use std::path::Path;
use ruff_diagnostics::{Applicability, Diagnostic, DiagnosticKind, Fix};
use ruff_linter::{
directives::{extract_directives, Flags},
linter::{check_path, LinterResult, TokenSource},
packaging::detect_package_root,
registry::AsRule,
settings::{flags, LinterSettings},
source_kind::SourceKind,
@ -40,12 +39,24 @@ pub(crate) struct DiagnosticFix {
pub(crate) fn check(
document: &crate::edit::Document,
document_url: &lsp_types::Url,
linter_settings: &LinterSettings,
encoding: PositionEncoding,
) -> Vec<lsp_types::Diagnostic> {
let contents = document.contents();
let index = document.index().clone();
let document_path = document_url
.to_file_path()
.expect("document URL should be a valid file path");
let package = detect_package_root(
document_path
.parent()
.expect("a path to a document should have a parent path"),
&linter_settings.namespace_packages,
);
let source_type = PySourceType::default();
// TODO(jane): Support Jupyter Notebooks
@ -71,8 +82,8 @@ pub(crate) fn check(
data: (diagnostics, _imports),
..
} = check_path(
Path::new("<filename>"),
None,
&document_path,
package,
&locator,
&stylist,
&indexer,