Skip to content

Commit 36fb8f7

Browse files
authored
flake8_to_ruff: support isort options (#2082)
See: #1749.
1 parent e11cf1b commit 36fb8f7

File tree

7 files changed

+82
-38
lines changed

7 files changed

+82
-38
lines changed

flake8_to_ruff/src/main.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use std::path::PathBuf;
1818
use anyhow::Result;
1919
use clap::Parser;
2020
use configparser::ini::Ini;
21-
use ruff::flake8_to_ruff;
21+
use ruff::flake8_to_ruff::{self, ExternalConfig};
2222

2323
#[derive(Parser)]
2424
#[command(
@@ -48,14 +48,18 @@ fn main() -> Result<()> {
4848
let config = ini.load(cli.file).map_err(|msg| anyhow::anyhow!(msg))?;
4949

5050
// Read the pyproject.toml file.
51-
let black = cli
52-
.pyproject
53-
.map(flake8_to_ruff::parse_black_options)
54-
.transpose()?
55-
.flatten();
51+
let pyproject = cli.pyproject.map(flake8_to_ruff::parse).transpose()?;
52+
let external_config = pyproject
53+
.as_ref()
54+
.and_then(|pyproject| pyproject.tool.as_ref())
55+
.map(|tool| ExternalConfig {
56+
black: tool.black.as_ref(),
57+
isort: tool.isort.as_ref(),
58+
})
59+
.unwrap_or_default();
5660

5761
// Create Ruff's pyproject.toml section.
58-
let pyproject = flake8_to_ruff::convert(&config, black.as_ref(), cli.plugin)?;
62+
let pyproject = flake8_to_ruff::convert(&config, &external_config, cli.plugin)?;
5963
println!("{}", toml_edit::easy::to_string_pretty(&pyproject)?);
6064

6165
Ok(())

src/flake8_to_ruff/black.rs

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
//! Extract Black configuration settings from a pyproject.toml.
22
3-
use std::path::Path;
4-
5-
use anyhow::Result;
63
use serde::{Deserialize, Serialize};
74

85
use crate::settings::types::PythonVersion;
@@ -14,20 +11,3 @@ pub struct Black {
1411
#[serde(alias = "target-version", alias = "target_version")]
1512
pub target_version: Option<Vec<PythonVersion>>,
1613
}
17-
18-
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
19-
struct Tools {
20-
black: Option<Black>,
21-
}
22-
23-
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
24-
struct Pyproject {
25-
tool: Option<Tools>,
26-
}
27-
28-
pub fn parse_black_options<P: AsRef<Path>>(path: P) -> Result<Option<Black>> {
29-
let contents = std::fs::read_to_string(path)?;
30-
Ok(toml_edit::easy::from_str::<Pyproject>(&contents)?
31-
.tool
32-
.and_then(|tool| tool.black))
33-
}

src/flake8_to_ruff/converter.rs

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::collections::{BTreeSet, HashMap};
33
use anyhow::Result;
44
use colored::Colorize;
55

6-
use super::black::Black;
6+
use super::external_config::ExternalConfig;
77
use super::plugin::Plugin;
88
use super::{parser, plugin};
99
use crate::registry::RuleSelector;
@@ -23,7 +23,7 @@ use crate::warn_user;
2323

2424
pub fn convert(
2525
config: &HashMap<String, HashMap<String, Option<String>>>,
26-
black: Option<&Black>,
26+
external_config: &ExternalConfig,
2727
plugins: Option<Vec<Plugin>>,
2828
) -> Result<Pyproject> {
2929
// Extract the Flake8 section.
@@ -377,7 +377,7 @@ pub fn convert(
377377
}
378378

379379
// Extract any settings from the existing `pyproject.toml`.
380-
if let Some(black) = black {
380+
if let Some(black) = &external_config.black {
381381
if let Some(line_length) = &black.line_length {
382382
options.line_length = Some(*line_length);
383383
}
@@ -389,6 +389,19 @@ pub fn convert(
389389
}
390390
}
391391

392+
if let Some(isort) = &external_config.isort {
393+
if let Some(src_paths) = &isort.src_paths {
394+
match options.src.as_mut() {
395+
Some(src) => {
396+
src.extend(src_paths.clone());
397+
}
398+
None => {
399+
options.src = Some(src_paths.clone());
400+
}
401+
}
402+
}
403+
}
404+
392405
// Create the pyproject.toml.
393406
Ok(Pyproject::new(options))
394407
}
@@ -401,6 +414,7 @@ mod tests {
401414

402415
use super::super::plugin::Plugin;
403416
use super::convert;
417+
use crate::flake8_to_ruff::ExternalConfig;
404418
use crate::registry::RuleSelector;
405419
use crate::rules::pydocstyle::settings::Convention;
406420
use crate::rules::{flake8_quotes, pydocstyle};
@@ -411,7 +425,7 @@ mod tests {
411425
fn it_converts_empty() -> Result<()> {
412426
let actual = convert(
413427
&HashMap::from([("flake8".to_string(), HashMap::default())]),
414-
None,
428+
&ExternalConfig::default(),
415429
None,
416430
)?;
417431
let expected = Pyproject::new(Options {
@@ -475,7 +489,7 @@ mod tests {
475489
"flake8".to_string(),
476490
HashMap::from([("max-line-length".to_string(), Some("100".to_string()))]),
477491
)]),
478-
None,
492+
&ExternalConfig::default(),
479493
Some(vec![]),
480494
)?;
481495
let expected = Pyproject::new(Options {
@@ -539,7 +553,7 @@ mod tests {
539553
"flake8".to_string(),
540554
HashMap::from([("max_line_length".to_string(), Some("100".to_string()))]),
541555
)]),
542-
None,
556+
&ExternalConfig::default(),
543557
Some(vec![]),
544558
)?;
545559
let expected = Pyproject::new(Options {
@@ -603,7 +617,7 @@ mod tests {
603617
"flake8".to_string(),
604618
HashMap::from([("max_line_length".to_string(), Some("abc".to_string()))]),
605619
)]),
606-
None,
620+
&ExternalConfig::default(),
607621
Some(vec![]),
608622
)?;
609623
let expected = Pyproject::new(Options {
@@ -667,7 +681,7 @@ mod tests {
667681
"flake8".to_string(),
668682
HashMap::from([("inline-quotes".to_string(), Some("single".to_string()))]),
669683
)]),
670-
None,
684+
&ExternalConfig::default(),
671685
Some(vec![]),
672686
)?;
673687
let expected = Pyproject::new(Options {
@@ -739,7 +753,7 @@ mod tests {
739753
Some("numpy".to_string()),
740754
)]),
741755
)]),
742-
None,
756+
&ExternalConfig::default(),
743757
Some(vec![Plugin::Flake8Docstrings]),
744758
)?;
745759
let expected = Pyproject::new(Options {
@@ -810,7 +824,7 @@ mod tests {
810824
"flake8".to_string(),
811825
HashMap::from([("inline-quotes".to_string(), Some("single".to_string()))]),
812826
)]),
813-
None,
827+
&ExternalConfig::default(),
814828
None,
815829
)?;
816830
let expected = Pyproject::new(Options {
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
use super::black::Black;
2+
use super::isort::Isort;
3+
4+
#[derive(Default)]
5+
pub struct ExternalConfig<'a> {
6+
pub black: Option<&'a Black>,
7+
pub isort: Option<&'a Isort>,
8+
}

src/flake8_to_ruff/isort.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//! Extract isort configuration settings from a pyproject.toml.
2+
3+
use serde::{Deserialize, Serialize};
4+
5+
/// The [isort configuration](https://pycqa.github.io/isort/docs/configuration/config_files.html).
6+
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Default)]
7+
pub struct Isort {
8+
#[serde(alias = "src-paths", alias = "src_paths")]
9+
pub src_paths: Option<Vec<String>>,
10+
}

src/flake8_to_ruff/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
mod black;
22
mod converter;
3+
mod external_config;
4+
mod isort;
35
mod parser;
46
mod plugin;
7+
mod pyproject;
58

6-
pub use black::parse_black_options;
79
pub use converter::convert;
10+
pub use external_config::ExternalConfig;
811
pub use plugin::Plugin;
12+
pub use pyproject::parse;

src/flake8_to_ruff/pyproject.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
use std::path::Path;
2+
3+
use anyhow::Result;
4+
use serde::{Deserialize, Serialize};
5+
6+
use super::black::Black;
7+
use super::isort::Isort;
8+
9+
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
10+
pub struct Tools {
11+
pub black: Option<Black>,
12+
pub isort: Option<Isort>,
13+
}
14+
15+
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
16+
pub struct Pyproject {
17+
pub tool: Option<Tools>,
18+
}
19+
20+
pub fn parse<P: AsRef<Path>>(path: P) -> Result<Pyproject> {
21+
let contents = std::fs::read_to_string(path)?;
22+
let pyproject = toml_edit::easy::from_str::<Pyproject>(&contents)?;
23+
Ok(pyproject)
24+
}

0 commit comments

Comments
 (0)