mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 13:51:16 +00:00
[ty] Change environment.root
to accept multiple paths (#18913)
This commit is contained in:
parent
0194452928
commit
833be2e66a
4 changed files with 39 additions and 28 deletions
11
crates/ty/docs/configuration.md
generated
11
crates/ty/docs/configuration.md
generated
|
@ -134,9 +134,11 @@ python-version = "3.12"
|
||||||
|
|
||||||
#### `root`
|
#### `root`
|
||||||
|
|
||||||
The root of the project, used for finding first-party modules.
|
The root paths of the project, used for finding first-party modules.
|
||||||
|
|
||||||
If left unspecified, ty will try to detect common project layouts and initialize `src.root` accordingly:
|
Accepts a list of directory paths searched in priority order (first has highest priority).
|
||||||
|
|
||||||
|
If left unspecified, ty will try to detect common project layouts and initialize `root` accordingly:
|
||||||
|
|
||||||
* if a `./src` directory exists, include `.` and `./src` in the first party search path (src layout or flat)
|
* if a `./src` directory exists, include `.` and `./src` in the first party search path (src layout or flat)
|
||||||
* if a `./<project-name>/<project-name>` directory exists, include `.` and `./<project-name>` in the first party search path
|
* if a `./<project-name>/<project-name>` directory exists, include `.` and `./<project-name>` in the first party search path
|
||||||
|
@ -147,13 +149,14 @@ it will also be included in the first party search path.
|
||||||
|
|
||||||
**Default value**: `null`
|
**Default value**: `null`
|
||||||
|
|
||||||
**Type**: `str`
|
**Type**: `list[str]`
|
||||||
|
|
||||||
**Example usage** (`pyproject.toml`):
|
**Example usage** (`pyproject.toml`):
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[tool.ty.environment]
|
[tool.ty.environment]
|
||||||
root = "./app"
|
# Multiple directories (priority order)
|
||||||
|
root = ["./src", "./lib", "./vendor"]
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
|
@ -974,7 +974,7 @@ fn src_root_deprecation_warning_with_environment_root() -> anyhow::Result<()> {
|
||||||
root = "./src"
|
root = "./src"
|
||||||
|
|
||||||
[tool.ty.environment]
|
[tool.ty.environment]
|
||||||
root = "./app"
|
root = ["./app"]
|
||||||
"#,
|
"#,
|
||||||
),
|
),
|
||||||
("app/test.py", ""),
|
("app/test.py", ""),
|
||||||
|
@ -1014,7 +1014,7 @@ fn environment_root_takes_precedence_over_src_root() -> anyhow::Result<()> {
|
||||||
root = "./src"
|
root = "./src"
|
||||||
|
|
||||||
[tool.ty.environment]
|
[tool.ty.environment]
|
||||||
root = "./app"
|
root = ["./app"]
|
||||||
"#,
|
"#,
|
||||||
),
|
),
|
||||||
("src/test.py", "import my_module"),
|
("src/test.py", "import my_module"),
|
||||||
|
|
|
@ -146,13 +146,15 @@ impl Options {
|
||||||
let src = self.src.or_default();
|
let src = self.src.or_default();
|
||||||
|
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
let src_roots = if let Some(src_root) = self
|
let src_roots = if let Some(roots) = environment
|
||||||
.environment
|
.root
|
||||||
.as_ref()
|
.as_deref()
|
||||||
.and_then(|environment| environment.root.as_ref())
|
.or_else(|| Some(std::slice::from_ref(src.root.as_ref()?)))
|
||||||
.or_else(|| src.root.as_ref())
|
|
||||||
{
|
{
|
||||||
vec![src_root.absolute(project_root, system)]
|
roots
|
||||||
|
.iter()
|
||||||
|
.map(|root| root.absolute(project_root, system))
|
||||||
|
.collect()
|
||||||
} else {
|
} else {
|
||||||
let src = project_root.join("src");
|
let src = project_root.join("src");
|
||||||
|
|
||||||
|
@ -160,20 +162,20 @@ impl Options {
|
||||||
// Default to `src` and the project root if `src` exists and the root hasn't been specified.
|
// Default to `src` and the project root if `src` exists and the root hasn't been specified.
|
||||||
// This corresponds to the `src-layout`
|
// This corresponds to the `src-layout`
|
||||||
tracing::debug!(
|
tracing::debug!(
|
||||||
"Including `./src` in `src.root` because a `./src` directory exists"
|
"Including `.` and `./src` in `environment.root` because a `./src` directory exists"
|
||||||
);
|
);
|
||||||
vec![project_root.to_path_buf(), src]
|
vec![project_root.to_path_buf(), src]
|
||||||
} else if system.is_directory(&project_root.join(project_name).join(project_name)) {
|
} else if system.is_directory(&project_root.join(project_name).join(project_name)) {
|
||||||
// `src-layout` but when the folder isn't called `src` but has the same name as the project.
|
// `src-layout` but when the folder isn't called `src` but has the same name as the project.
|
||||||
// For example, the "src" folder for `psycopg` is called `psycopg` and the python files are in `psycopg/psycopg/_adapters_map.py`
|
// For example, the "src" folder for `psycopg` is called `psycopg` and the python files are in `psycopg/psycopg/_adapters_map.py`
|
||||||
tracing::debug!(
|
tracing::debug!(
|
||||||
"Including `./{project_name}` in `src.root` because a `./{project_name}/{project_name}` directory exists"
|
"Including `.` and `/{project_name}` in `environment.root` because a `./{project_name}/{project_name}` directory exists"
|
||||||
);
|
);
|
||||||
|
|
||||||
vec![project_root.to_path_buf(), project_root.join(project_name)]
|
vec![project_root.to_path_buf(), project_root.join(project_name)]
|
||||||
} else {
|
} else {
|
||||||
// Default to a [flat project structure](https://packaging.python.org/en/latest/discussions/src-layout-vs-flat-layout/).
|
// Default to a [flat project structure](https://packaging.python.org/en/latest/discussions/src-layout-vs-flat-layout/).
|
||||||
tracing::debug!("Defaulting `src.root` to `.`");
|
tracing::debug!("Including `.` in `environment.root`");
|
||||||
vec![project_root.to_path_buf()]
|
vec![project_root.to_path_buf()]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -186,7 +188,7 @@ impl Options {
|
||||||
{
|
{
|
||||||
// If the `tests` directory exists and is not a package, include it as a source root.
|
// If the `tests` directory exists and is not a package, include it as a source root.
|
||||||
tracing::debug!(
|
tracing::debug!(
|
||||||
"Including `./tests` in `src.root` because a `./tests` directory exists"
|
"Including `./tests` in `environment.root` because a `./tests` directory exists"
|
||||||
);
|
);
|
||||||
|
|
||||||
roots.push(tests_dir);
|
roots.push(tests_dir);
|
||||||
|
@ -248,7 +250,7 @@ impl Options {
|
||||||
let mut diagnostics = Vec::new();
|
let mut diagnostics = Vec::new();
|
||||||
let rules = self.to_rule_selection(db, &mut diagnostics);
|
let rules = self.to_rule_selection(db, &mut diagnostics);
|
||||||
|
|
||||||
let terminal_options = self.terminal.clone().unwrap_or_default();
|
let terminal_options = self.terminal.or_default();
|
||||||
let terminal = TerminalSettings {
|
let terminal = TerminalSettings {
|
||||||
output_format: terminal_options
|
output_format: terminal_options
|
||||||
.output_format
|
.output_format
|
||||||
|
@ -329,7 +331,7 @@ impl Options {
|
||||||
project_root: &SystemPath,
|
project_root: &SystemPath,
|
||||||
diagnostics: &mut Vec<OptionDiagnostic>,
|
diagnostics: &mut Vec<OptionDiagnostic>,
|
||||||
) -> Result<Vec<Override>, Box<OptionDiagnostic>> {
|
) -> Result<Vec<Override>, Box<OptionDiagnostic>> {
|
||||||
let override_options = self.overrides.as_deref().unwrap_or_default();
|
let override_options = &**self.overrides.or_default();
|
||||||
|
|
||||||
let mut overrides = Vec::with_capacity(override_options.len());
|
let mut overrides = Vec::with_capacity(override_options.len());
|
||||||
|
|
||||||
|
@ -352,9 +354,11 @@ impl Options {
|
||||||
#[serde(rename_all = "kebab-case", deny_unknown_fields)]
|
#[serde(rename_all = "kebab-case", deny_unknown_fields)]
|
||||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||||
pub struct EnvironmentOptions {
|
pub struct EnvironmentOptions {
|
||||||
/// The root of the project, used for finding first-party modules.
|
/// The root paths of the project, used for finding first-party modules.
|
||||||
///
|
///
|
||||||
/// If left unspecified, ty will try to detect common project layouts and initialize `src.root` accordingly:
|
/// Accepts a list of directory paths searched in priority order (first has highest priority).
|
||||||
|
///
|
||||||
|
/// If left unspecified, ty will try to detect common project layouts and initialize `root` accordingly:
|
||||||
///
|
///
|
||||||
/// * if a `./src` directory exists, include `.` and `./src` in the first party search path (src layout or flat)
|
/// * if a `./src` directory exists, include `.` and `./src` in the first party search path (src layout or flat)
|
||||||
/// * if a `./<project-name>/<project-name>` directory exists, include `.` and `./<project-name>` in the first party search path
|
/// * if a `./<project-name>/<project-name>` directory exists, include `.` and `./<project-name>` in the first party search path
|
||||||
|
@ -365,12 +369,13 @@ pub struct EnvironmentOptions {
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
#[option(
|
#[option(
|
||||||
default = r#"null"#,
|
default = r#"null"#,
|
||||||
value_type = "str",
|
value_type = "list[str]",
|
||||||
example = r#"
|
example = r#"
|
||||||
root = "./app"
|
# Multiple directories (priority order)
|
||||||
|
root = ["./src", "./lib", "./vendor"]
|
||||||
"#
|
"#
|
||||||
)]
|
)]
|
||||||
pub root: Option<RelativePathBuf>,
|
pub root: Option<Vec<RelativePathBuf>>,
|
||||||
|
|
||||||
/// Specifies the version of Python that will be used to analyze the source code.
|
/// Specifies the version of Python that will be used to analyze the source code.
|
||||||
/// The version should be specified as a string in the format `M.m` where `M` is the major version
|
/// The version should be specified as a string in the format `M.m` where `M` is the major version
|
||||||
|
|
9
ty.schema.json
generated
9
ty.schema.json
generated
|
@ -120,11 +120,14 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"description": "The root of the project, used for finding first-party modules.\n\nIf left unspecified, ty will try to detect common project layouts and initialize `src.root` accordingly:\n\n* if a `./src` directory exists, include `.` and `./src` in the first party search path (src layout or flat) * if a `./<project-name>/<project-name>` directory exists, include `.` and `./<project-name>` in the first party search path * otherwise, default to `.` (flat layout)\n\nBesides, if a `./tests` directory exists and is not a package (i.e. it does not contain an `__init__.py` file), it will also be included in the first party search path.",
|
"description": "The root paths of the project, used for finding first-party modules.\n\nAccepts a list of directory paths searched in priority order (first has highest priority).\n\nIf left unspecified, ty will try to detect common project layouts and initialize `root` accordingly:\n\n* if a `./src` directory exists, include `.` and `./src` in the first party search path (src layout or flat) * if a `./<project-name>/<project-name>` directory exists, include `.` and `./<project-name>` in the first party search path * otherwise, default to `.` (flat layout)\n\nBesides, if a `./tests` directory exists and is not a package (i.e. it does not contain an `__init__.py` file), it will also be included in the first party search path.",
|
||||||
"type": [
|
"type": [
|
||||||
"string",
|
"array",
|
||||||
"null"
|
"null"
|
||||||
]
|
],
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"typeshed": {
|
"typeshed": {
|
||||||
"description": "Optional path to a \"typeshed\" directory on disk for us to use for standard-library types. If this is not provided, we will fallback to our vendored typeshed stubs for the stdlib, bundled as a zip file in the binary",
|
"description": "Optional path to a \"typeshed\" directory on disk for us to use for standard-library types. If this is not provided, we will fallback to our vendored typeshed stubs for the stdlib, bundled as a zip file in the binary",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue