[ty] ensure explicitly provided folders to the cli are fully checked

When users specify directories directly on the command line (e.g., `ty
check dir2`), they expect those directories to be fully processed even
if they're not included in pyproject.toml configuration.
This commit is contained in:
Leandro Braga 2025-08-09 08:41:30 -03:00
parent 5a116e48c3
commit 118cbfc282
3 changed files with 43 additions and 3 deletions

View File

@ -30,6 +30,7 @@ clearscreen = { workspace = true }
colored = { workspace = true } colored = { workspace = true }
crossbeam = { workspace = true } crossbeam = { workspace = true }
ctrlc = { version = "3.4.4" } ctrlc = { version = "3.4.4" }
dunce = { workspace = true }
indicatif = { workspace = true } indicatif = { workspace = true }
jiff = { workspace = true } jiff = { workspace = true }
rayon = { workspace = true } rayon = { workspace = true }

View File

@ -2,7 +2,7 @@ use crate::logging::Verbosity;
use crate::python_version::PythonVersion; use crate::python_version::PythonVersion;
use clap::error::ErrorKind; use clap::error::ErrorKind;
use clap::{ArgAction, ArgMatches, Error, Parser}; use clap::{ArgAction, ArgMatches, Error, Parser};
use ruff_db::system::SystemPathBuf; use ruff_db::system::{SystemPath, SystemPathBuf};
use ty_combine::Combine; use ty_combine::Combine;
use ty_project::metadata::options::{EnvironmentOptions, Options, SrcOptions, TerminalOptions}; use ty_project::metadata::options::{EnvironmentOptions, Options, SrcOptions, TerminalOptions};
use ty_project::metadata::value::{RangedValue, RelativeGlobPattern, RelativePathBuf, ValueSource}; use ty_project::metadata::value::{RangedValue, RelativeGlobPattern, RelativePathBuf, ValueSource};
@ -158,7 +158,7 @@ pub(crate) struct CheckCommand {
} }
impl CheckCommand { impl CheckCommand {
pub(crate) fn into_options(self) -> Options { pub(crate) fn into_options(self, project_root: &SystemPath) -> Options {
let rules = if self.rules.is_empty() { let rules = if self.rules.is_empty() {
None None
} else { } else {
@ -177,6 +177,43 @@ impl CheckCommand {
.no_respect_ignore_files .no_respect_ignore_files
.then_some(false) .then_some(false)
.or(self.respect_ignore_files); .or(self.respect_ignore_files);
// When users explicitly specify directories on the command line, adds it as "dir/**/*"
// to include, ensuring their subfolders and subfiles are checked regardless of
// `pyproject.toml` original include configuration.
let include = {
let glob_patterns: Vec<RelativeGlobPattern> = {
self.paths
.iter()
.filter_map(|path| {
let path = path.as_std_path();
if !path.is_dir() {
return None;
}
let Ok(canonical_path) = dunce::canonicalize(path) else {
return None;
};
let relative_path = canonical_path
.strip_prefix(project_root.as_std_path())
.ok()?;
let path_str = relative_path.to_str()?;
let path_str = path_str.replace('\\', "/");
let normalized_path = path_str.strip_suffix('/').unwrap_or(&path_str);
Some(RelativeGlobPattern::cli(format!("{normalized_path}/**/*")))
})
.collect()
};
if glob_patterns.is_empty() {
None
} else {
Some(RangedValue::cli(glob_patterns))
}
};
let options = Options { let options = Options {
environment: Some(EnvironmentOptions { environment: Some(EnvironmentOptions {
python_version: self python_version: self
@ -206,6 +243,7 @@ impl CheckCommand {
exclude: self.exclude.map(|excludes| { exclude: self.exclude.map(|excludes| {
RangedValue::cli(excludes.iter().map(RelativeGlobPattern::cli).collect()) RangedValue::cli(excludes.iter().map(RelativeGlobPattern::cli).collect())
}), }),
include,
..SrcOptions::default() ..SrcOptions::default()
}), }),
rules, rules,

View File

@ -124,7 +124,8 @@ fn run_check(args: CheckCommand) -> anyhow::Result<ExitStatus> {
project_metadata.apply_configuration_files(&system)?; project_metadata.apply_configuration_files(&system)?;
let project_options_overrides = ProjectOptionsOverrides::new(config_file, args.into_options()); let project_options_overrides =
ProjectOptionsOverrides::new(config_file, args.into_options(&project_path));
project_metadata.apply_overrides(&project_options_overrides); project_metadata.apply_overrides(&project_options_overrides);
let mut db = ProjectDatabase::new(project_metadata, system)?; let mut db = ProjectDatabase::new(project_metadata, system)?;