Skip to content

Commit

Permalink
flake8_to_ruff: support isort options (#2082)
Browse files Browse the repository at this point in the history
See: #1749.
  • Loading branch information
shannonrothe authored Jan 22, 2023
1 parent e11cf1b commit 36fb8f7
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 38 deletions.
18 changes: 11 additions & 7 deletions flake8_to_ruff/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use std::path::PathBuf;
use anyhow::Result;
use clap::Parser;
use configparser::ini::Ini;
use ruff::flake8_to_ruff;
use ruff::flake8_to_ruff::{self, ExternalConfig};

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

// Read the pyproject.toml file.
let black = cli
.pyproject
.map(flake8_to_ruff::parse_black_options)
.transpose()?
.flatten();
let pyproject = cli.pyproject.map(flake8_to_ruff::parse).transpose()?;
let external_config = pyproject
.as_ref()
.and_then(|pyproject| pyproject.tool.as_ref())
.map(|tool| ExternalConfig {
black: tool.black.as_ref(),
isort: tool.isort.as_ref(),
})
.unwrap_or_default();

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

Ok(())
Expand Down
20 changes: 0 additions & 20 deletions src/flake8_to_ruff/black.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
//! Extract Black configuration settings from a pyproject.toml.

use std::path::Path;

use anyhow::Result;
use serde::{Deserialize, Serialize};

use crate::settings::types::PythonVersion;
Expand All @@ -14,20 +11,3 @@ pub struct Black {
#[serde(alias = "target-version", alias = "target_version")]
pub target_version: Option<Vec<PythonVersion>>,
}

#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
struct Tools {
black: Option<Black>,
}

#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
struct Pyproject {
tool: Option<Tools>,
}

pub fn parse_black_options<P: AsRef<Path>>(path: P) -> Result<Option<Black>> {
let contents = std::fs::read_to_string(path)?;
Ok(toml_edit::easy::from_str::<Pyproject>(&contents)?
.tool
.and_then(|tool| tool.black))
}
34 changes: 24 additions & 10 deletions src/flake8_to_ruff/converter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::collections::{BTreeSet, HashMap};
use anyhow::Result;
use colored::Colorize;

use super::black::Black;
use super::external_config::ExternalConfig;
use super::plugin::Plugin;
use super::{parser, plugin};
use crate::registry::RuleSelector;
Expand All @@ -23,7 +23,7 @@ use crate::warn_user;

pub fn convert(
config: &HashMap<String, HashMap<String, Option<String>>>,
black: Option<&Black>,
external_config: &ExternalConfig,
plugins: Option<Vec<Plugin>>,
) -> Result<Pyproject> {
// Extract the Flake8 section.
Expand Down Expand Up @@ -377,7 +377,7 @@ pub fn convert(
}

// Extract any settings from the existing `pyproject.toml`.
if let Some(black) = black {
if let Some(black) = &external_config.black {
if let Some(line_length) = &black.line_length {
options.line_length = Some(*line_length);
}
Expand All @@ -389,6 +389,19 @@ pub fn convert(
}
}

if let Some(isort) = &external_config.isort {
if let Some(src_paths) = &isort.src_paths {
match options.src.as_mut() {
Some(src) => {
src.extend(src_paths.clone());
}
None => {
options.src = Some(src_paths.clone());
}
}
}
}

// Create the pyproject.toml.
Ok(Pyproject::new(options))
}
Expand All @@ -401,6 +414,7 @@ mod tests {

use super::super::plugin::Plugin;
use super::convert;
use crate::flake8_to_ruff::ExternalConfig;
use crate::registry::RuleSelector;
use crate::rules::pydocstyle::settings::Convention;
use crate::rules::{flake8_quotes, pydocstyle};
Expand All @@ -411,7 +425,7 @@ mod tests {
fn it_converts_empty() -> Result<()> {
let actual = convert(
&HashMap::from([("flake8".to_string(), HashMap::default())]),
None,
&ExternalConfig::default(),
None,
)?;
let expected = Pyproject::new(Options {
Expand Down Expand Up @@ -475,7 +489,7 @@ mod tests {
"flake8".to_string(),
HashMap::from([("max-line-length".to_string(), Some("100".to_string()))]),
)]),
None,
&ExternalConfig::default(),
Some(vec![]),
)?;
let expected = Pyproject::new(Options {
Expand Down Expand Up @@ -539,7 +553,7 @@ mod tests {
"flake8".to_string(),
HashMap::from([("max_line_length".to_string(), Some("100".to_string()))]),
)]),
None,
&ExternalConfig::default(),
Some(vec![]),
)?;
let expected = Pyproject::new(Options {
Expand Down Expand Up @@ -603,7 +617,7 @@ mod tests {
"flake8".to_string(),
HashMap::from([("max_line_length".to_string(), Some("abc".to_string()))]),
)]),
None,
&ExternalConfig::default(),
Some(vec![]),
)?;
let expected = Pyproject::new(Options {
Expand Down Expand Up @@ -667,7 +681,7 @@ mod tests {
"flake8".to_string(),
HashMap::from([("inline-quotes".to_string(), Some("single".to_string()))]),
)]),
None,
&ExternalConfig::default(),
Some(vec![]),
)?;
let expected = Pyproject::new(Options {
Expand Down Expand Up @@ -739,7 +753,7 @@ mod tests {
Some("numpy".to_string()),
)]),
)]),
None,
&ExternalConfig::default(),
Some(vec![Plugin::Flake8Docstrings]),
)?;
let expected = Pyproject::new(Options {
Expand Down Expand Up @@ -810,7 +824,7 @@ mod tests {
"flake8".to_string(),
HashMap::from([("inline-quotes".to_string(), Some("single".to_string()))]),
)]),
None,
&ExternalConfig::default(),
None,
)?;
let expected = Pyproject::new(Options {
Expand Down
8 changes: 8 additions & 0 deletions src/flake8_to_ruff/external_config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use super::black::Black;
use super::isort::Isort;

#[derive(Default)]
pub struct ExternalConfig<'a> {
pub black: Option<&'a Black>,
pub isort: Option<&'a Isort>,
}
10 changes: 10 additions & 0 deletions src/flake8_to_ruff/isort.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//! Extract isort configuration settings from a pyproject.toml.

use serde::{Deserialize, Serialize};

/// The [isort configuration](https://pycqa.github.io/isort/docs/configuration/config_files.html).
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Default)]
pub struct Isort {
#[serde(alias = "src-paths", alias = "src_paths")]
pub src_paths: Option<Vec<String>>,
}
6 changes: 5 additions & 1 deletion src/flake8_to_ruff/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
mod black;
mod converter;
mod external_config;
mod isort;
mod parser;
mod plugin;
mod pyproject;

pub use black::parse_black_options;
pub use converter::convert;
pub use external_config::ExternalConfig;
pub use plugin::Plugin;
pub use pyproject::parse;
24 changes: 24 additions & 0 deletions src/flake8_to_ruff/pyproject.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use std::path::Path;

use anyhow::Result;
use serde::{Deserialize, Serialize};

use super::black::Black;
use super::isort::Isort;

#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Tools {
pub black: Option<Black>,
pub isort: Option<Isort>,
}

#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Pyproject {
pub tool: Option<Tools>,
}

pub fn parse<P: AsRef<Path>>(path: P) -> Result<Pyproject> {
let contents = std::fs::read_to_string(path)?;
let pyproject = toml_edit::easy::from_str::<Pyproject>(&contents)?;
Ok(pyproject)
}

0 comments on commit 36fb8f7

Please sign in to comment.