Skip to content

Commit ce6bdb9

Browse files
committed
Merge branch 'workspaces'
2 parents a85e717 + 782bbfa commit ce6bdb9

File tree

23 files changed

+615
-252
lines changed

23 files changed

+615
-252
lines changed

crates/cli_args/src/lib.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use vfs::{AbsPath, SimpleLocalFS, VfsHandler};
1010

1111
use clap::Parser;
1212

13-
#[derive(Parser, Default)]
13+
#[derive(Parser, Default, Debug)]
1414
pub struct Cli {
1515
// Additional options that are not present in zmypy
1616
/// Choosing a mode sets the basic preset of flags. The default mode is typed, which is not
@@ -46,7 +46,7 @@ impl Cli {
4646
}
4747
}
4848

49-
#[derive(Parser, Clone, Default)]
49+
#[derive(Parser, Clone, Default, Debug)]
5050
pub struct MypyCli {
5151
// Running code:
5252
/// Regular expression to match file names, directory names or paths which mypy should ignore
@@ -297,6 +297,7 @@ pub fn apply_flags(
297297
cli: Cli,
298298
current_dir: Arc<AbsPath>,
299299
config_path: Option<&AbsPath>,
300+
most_probable_base: Arc<AbsPath>,
300301
) {
301302
apply_flags_detailed(
302303
vfs_handler,
@@ -306,6 +307,7 @@ pub fn apply_flags(
306307
cli,
307308
current_dir,
308309
config_path,
310+
most_probable_base,
309311
)
310312
}
311313

@@ -317,6 +319,7 @@ pub fn apply_flags_detailed(
317319
cli: Cli,
318320
current_dir: Arc<AbsPath>,
319321
config_path: Option<&AbsPath>,
322+
most_probable_base: Arc<AbsPath>,
320323
) {
321324
if let Some(mode) = cli.mode {
322325
settings.mode = mode.into();
@@ -333,7 +336,11 @@ pub fn apply_flags_detailed(
333336
cli.mypy_options,
334337
current_dir,
335338
config_path,
336-
)
339+
);
340+
341+
settings
342+
.mypy_path
343+
.push(vfs_handler.normalize_rc_path(most_probable_base));
337344
}
338345

339346
fn apply_mypy_flags(
@@ -456,8 +463,4 @@ fn apply_mypy_flags(
456463
.map(|e| &e.regex_str)
457464
.collect::<Vec<_>>()
458465
);
459-
460-
settings
461-
.mypy_path
462-
.push(vfs_handler.normalize_rc_path(current_dir));
463466
}

crates/config/src/searcher.rs

Lines changed: 57 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,39 +22,62 @@ pub struct FoundConfig {
2222
pub project_options: ProjectOptions,
2323
pub diagnostic_config: DiagnosticConfig,
2424
pub config_path: Option<Arc<AbsPath>>,
25+
pub most_probable_base: Arc<AbsPath>,
2526
}
2627

2728
pub fn find_workspace_config(
2829
vfs: &dyn VfsHandler,
29-
workspace_dir: &AbsPath,
30+
workspace_dir: Arc<AbsPath>,
3031
on_check_path: impl FnMut(&AbsPath),
3132
) -> anyhow::Result<ProjectOptions> {
32-
Ok(find_mypy_config_file_in_dir(vfs, workspace_dir, None, on_check_path)?.project_options)
33+
let config = find_mypy_config_file_in_dir(vfs, workspace_dir, None, on_check_path)?;
34+
35+
Ok(match config {
36+
Some(config) => config.project_options,
37+
None => {
38+
tracing::info!("No relevant config found");
39+
ProjectOptions::default_for_mode(Mode::Default)
40+
}
41+
})
3342
}
3443

3544
pub fn find_cli_config(
3645
vfs: &dyn VfsHandler,
37-
current_dir: &AbsPath,
46+
current_dir: Arc<AbsPath>,
3847
config_file: Option<&Path>,
3948
mode: Option<Mode>,
4049
) -> anyhow::Result<FoundConfig> {
4150
if let Some(config_file) = config_file.as_ref() {
4251
let Some(config_path) = config_file.as_os_str().to_str() else {
4352
anyhow::bail!("Expected a valid UTF-8 encoded config path")
4453
};
45-
let config_path = vfs.absolute_path(current_dir, config_path);
54+
let config_path = vfs.absolute_path(&current_dir, config_path);
4655
let s = std::fs::read_to_string(config_path.as_ref())
4756
.map_err(|err| anyhow::anyhow!("Issue while reading {config_path}: {err}"))?;
4857

49-
let result = initialize_config(vfs, current_dir, config_path, s, mode)?;
58+
let most_probable_base = Arc::from(vfs.parent_of_absolute_path(&config_path).unwrap());
59+
let result = initialize_config(vfs, &current_dir, config_path, s, mode)?;
5060
let project_options = result.0.unwrap_or_else(ProjectOptions::mypy_default);
5161
Ok(FoundConfig {
5262
project_options,
5363
diagnostic_config: result.1,
5464
config_path: Some(result.2),
65+
most_probable_base,
5566
})
5667
} else {
57-
find_mypy_config_file_in_dir(vfs, current_dir, mode, |_| ())
68+
let mut current = current_dir.clone();
69+
loop {
70+
if let Some(found) = find_mypy_config_file_in_dir(vfs, current.clone(), mode, |_| ())? {
71+
return Ok(found);
72+
}
73+
if let Some(outer) = vfs.parent_of_absolute_path(&current) {
74+
current = Arc::from(outer);
75+
} else {
76+
break;
77+
}
78+
}
79+
tracing::info!("No relevant config found");
80+
Ok(default_config(mode, None, current_dir))
5881
}
5982
}
6083

@@ -90,28 +113,28 @@ fn initialize_config(
90113

91114
fn find_mypy_config_file_in_dir(
92115
vfs: &dyn VfsHandler,
93-
dir: &AbsPath,
116+
dir: Arc<AbsPath>,
94117
mode: Option<Mode>,
95118
mut on_check_path: impl FnMut(&AbsPath),
96-
) -> anyhow::Result<FoundConfig> {
119+
) -> anyhow::Result<Option<FoundConfig>> {
97120
let mut end_result = None;
98121
let mut pyproject_toml: Option<DocumentMut> = None;
99122
for config_name in CONFIG_PATHS.iter() {
100-
let path = vfs.join(dir, config_name);
123+
let path = vfs.join(&dir, config_name);
101124
on_check_path(&path);
102125
if let Ok(mut file) = std::fs::File::open(path.as_ref()) {
103126
let mut content = String::new();
104127
if let Err(err) = file.read_to_string(&mut content) {
105128
anyhow::bail!("Issue while reading {path}: {err}");
106129
}
107-
let config_path = vfs.absolute_path(dir, config_name);
130+
let config_path = vfs.absolute_path(&dir, config_name);
108131
tracing::info!("Potential config found: {config_path}");
109132
if *config_name == PYPROJECT_TOML_NAME {
110133
let mut diagnostic_config = DiagnosticConfig::default();
111134
pyproject_toml = Some(content.parse()?);
112135
let project_options = ProjectOptions::apply_pyproject_toml_mypy_part(
113136
vfs,
114-
dir,
137+
&dir,
115138
&config_path,
116139
pyproject_toml.as_ref().unwrap(),
117140
&mut diagnostic_config,
@@ -122,11 +145,12 @@ fn find_mypy_config_file_in_dir(
122145
project_options,
123146
diagnostic_config,
124147
config_path: Some(config_path),
148+
most_probable_base: dir.clone(),
125149
});
126150
break;
127151
}
128152
} else {
129-
let result = initialize_config(vfs, dir, config_path, content, mode)?;
153+
let result = initialize_config(vfs, &dir, config_path, content, mode)?;
130154
if let Some(project_options) = result.0.or_else(|| {
131155
["mypy.ini", ".mypy.ini"].contains(config_name).then(|| {
132156
// Both mypy.ini and .mypy.ini always take precedent, even if there is no [mypy]
@@ -138,39 +162,47 @@ fn find_mypy_config_file_in_dir(
138162
project_options,
139163
diagnostic_config: result.1,
140164
config_path: Some(result.2),
165+
most_probable_base: dir.clone(),
141166
});
142167
break;
143168
}
144169
};
145170
}
146171
}
147-
let default_config = |config_path| FoundConfig {
148-
project_options: ProjectOptions::default_for_mode(mode.unwrap_or(Mode::Default)),
149-
diagnostic_config: DiagnosticConfig::default(),
150-
config_path,
151-
};
152172
if let Some(pyproject_toml) = pyproject_toml
153173
&& let Some(config) = pyproject_toml
154174
.get("tool")
155175
.and_then(|item| item.get("zuban"))
156176
{
157177
if end_result.is_none() {
158-
end_result = Some(default_config(Some(
159-
vfs.absolute_path(dir, PYPROJECT_TOML_NAME),
160-
)));
178+
end_result = Some(default_config(
179+
mode,
180+
Some(vfs.absolute_path(&dir, PYPROJECT_TOML_NAME)),
181+
dir.clone(),
182+
));
161183
}
162184
let found = end_result.as_mut().unwrap();
163185
found.project_options.apply_pyproject_table(
164186
vfs,
165-
dir,
187+
&dir,
166188
found.config_path.as_ref().unwrap(),
167189
&mut found.diagnostic_config,
168190
config,
169191
true,
170192
)?
171193
}
172-
Ok(end_result.unwrap_or_else(|| {
173-
tracing::info!("No relevant config found");
174-
default_config(None)
175-
}))
194+
Ok(end_result)
195+
}
196+
197+
fn default_config(
198+
mode: Option<Mode>,
199+
config_path: Option<Arc<AbsPath>>,
200+
current_dir: Arc<AbsPath>,
201+
) -> FoundConfig {
202+
FoundConfig {
203+
project_options: ProjectOptions::default_for_mode(mode.unwrap_or(Mode::Default)),
204+
diagnostic_config: DiagnosticConfig::default(),
205+
config_path,
206+
most_probable_base: current_dir,
207+
}
176208
}

crates/primer/src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,12 @@ fn main() -> ExitCode {
8282
let cli = cli_args::Cli::parse_from(v);
8383
let result = zmypy::with_diagnostics_from_cli(
8484
cli,
85-
pth,
85+
&pth,
8686
Some(test_utils::typeshed_path()),
8787
|mut diagnostics, config| {
8888
diagnostics.sort_issues_by_kind();
8989
for diagnostic in diagnostics.issues.iter() {
90-
println!("{}", diagnostic.as_string(config))
90+
println!("{}", diagnostic.as_string(config, None))
9191
}
9292
file_count += diagnostics.checked_files;
9393
issue_count += diagnostics.issues.len();

0 commit comments

Comments
 (0)