From 118cbfc2822649aaf25314964e681a88b873eb48 Mon Sep 17 00:00:00 2001 From: Leandro Braga <18340809+leandrobbraga@users.noreply.github.com> Date: Sat, 9 Aug 2025 08:41:30 -0300 Subject: [PATCH 1/2] [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. --- crates/ty/Cargo.toml | 1 + crates/ty/src/args.rs | 42 ++++++++++++++++++++++++++++++++++++++++-- crates/ty/src/lib.rs | 3 ++- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/crates/ty/Cargo.toml b/crates/ty/Cargo.toml index 4189758bb1..3ccd55c3cc 100644 --- a/crates/ty/Cargo.toml +++ b/crates/ty/Cargo.toml @@ -30,6 +30,7 @@ clearscreen = { workspace = true } colored = { workspace = true } crossbeam = { workspace = true } ctrlc = { version = "3.4.4" } +dunce = { workspace = true } indicatif = { workspace = true } jiff = { workspace = true } rayon = { workspace = true } diff --git a/crates/ty/src/args.rs b/crates/ty/src/args.rs index f518e028db..4d14f78486 100644 --- a/crates/ty/src/args.rs +++ b/crates/ty/src/args.rs @@ -2,7 +2,7 @@ use crate::logging::Verbosity; use crate::python_version::PythonVersion; use clap::error::ErrorKind; use clap::{ArgAction, ArgMatches, Error, Parser}; -use ruff_db::system::SystemPathBuf; +use ruff_db::system::{SystemPath, SystemPathBuf}; use ty_combine::Combine; use ty_project::metadata::options::{EnvironmentOptions, Options, SrcOptions, TerminalOptions}; use ty_project::metadata::value::{RangedValue, RelativeGlobPattern, RelativePathBuf, ValueSource}; @@ -158,7 +158,7 @@ pub(crate) struct 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() { None } else { @@ -177,6 +177,43 @@ impl CheckCommand { .no_respect_ignore_files .then_some(false) .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 = { + 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 { environment: Some(EnvironmentOptions { python_version: self @@ -206,6 +243,7 @@ impl CheckCommand { exclude: self.exclude.map(|excludes| { RangedValue::cli(excludes.iter().map(RelativeGlobPattern::cli).collect()) }), + include, ..SrcOptions::default() }), rules, diff --git a/crates/ty/src/lib.rs b/crates/ty/src/lib.rs index f16192bcd5..23a6727ad6 100644 --- a/crates/ty/src/lib.rs +++ b/crates/ty/src/lib.rs @@ -124,7 +124,8 @@ fn run_check(args: CheckCommand) -> anyhow::Result { 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); let mut db = ProjectDatabase::new(project_metadata, system)?; From f1aeeaa40cf820d9772864b8e2b3e84f075e2633 Mon Sep 17 00:00:00 2001 From: Leandro Braga <18340809+leandrobbraga@users.noreply.github.com> Date: Sun, 10 Aug 2025 14:41:50 -0300 Subject: [PATCH 2/2] [ty] use SystemPath::absolute instead of dunce::canonicalize --- crates/ty/Cargo.toml | 1 - crates/ty/src/args.rs | 19 ++++++------------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/crates/ty/Cargo.toml b/crates/ty/Cargo.toml index 3ccd55c3cc..4189758bb1 100644 --- a/crates/ty/Cargo.toml +++ b/crates/ty/Cargo.toml @@ -30,7 +30,6 @@ clearscreen = { workspace = true } colored = { workspace = true } crossbeam = { workspace = true } ctrlc = { version = "3.4.4" } -dunce = { workspace = true } indicatif = { workspace = true } jiff = { workspace = true } rayon = { workspace = true } diff --git a/crates/ty/src/args.rs b/crates/ty/src/args.rs index 4d14f78486..bab9f5f3ee 100644 --- a/crates/ty/src/args.rs +++ b/crates/ty/src/args.rs @@ -186,23 +186,16 @@ impl CheckCommand { self.paths .iter() .filter_map(|path| { - let path = path.as_std_path(); - if !path.is_dir() { + if !path.as_std_path().is_dir() { return None; } - let Ok(canonical_path) = dunce::canonicalize(path) else { - return None; - }; + let path = SystemPath::absolute(path, project_root); + let path = path.strip_prefix(project_root).ok()?; + let path = path.to_string().replace('\\', "/"); + let path = path.strip_suffix('/').unwrap_or(&path); - 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}/**/*"))) + Some(RelativeGlobPattern::cli(format!("{path}/**/*"))) }) .collect() };