mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-26 20:10:09 +00:00
Extract line length from pyproject.toml
Black section (#1317)
This commit is contained in:
parent
3b02da9d7b
commit
07dba46039
7 changed files with 258 additions and 18 deletions
65
flake8_to_ruff/examples/cryptography/pyproject.toml
Normal file
65
flake8_to_ruff/examples/cryptography/pyproject.toml
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
[build-system]
|
||||||
|
requires = [
|
||||||
|
# The minimum setuptools version is specific to the PEP 517 backend,
|
||||||
|
# and may be stricter than the version required in `setup.cfg`
|
||||||
|
"setuptools>=40.6.0,!=60.9.0",
|
||||||
|
"wheel",
|
||||||
|
# Must be kept in sync with the `install_requirements` in `setup.cfg`
|
||||||
|
"cffi>=1.12; platform_python_implementation != 'PyPy'",
|
||||||
|
"setuptools-rust>=0.11.4",
|
||||||
|
]
|
||||||
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
|
[tool.black]
|
||||||
|
line-length = 79
|
||||||
|
target-version = ["py36"]
|
||||||
|
|
||||||
|
[tool.pytest.ini_options]
|
||||||
|
addopts = "-r s --capture=no --strict-markers --benchmark-disable"
|
||||||
|
markers = [
|
||||||
|
"skip_fips: this test is not executed in FIPS mode",
|
||||||
|
"supported: parametrized test requiring only_if and skip_message",
|
||||||
|
]
|
||||||
|
|
||||||
|
[tool.mypy]
|
||||||
|
show_error_codes = true
|
||||||
|
check_untyped_defs = true
|
||||||
|
no_implicit_reexport = true
|
||||||
|
warn_redundant_casts = true
|
||||||
|
warn_unused_ignores = true
|
||||||
|
warn_unused_configs = true
|
||||||
|
strict_equality = true
|
||||||
|
|
||||||
|
[[tool.mypy.overrides]]
|
||||||
|
module = [
|
||||||
|
"pretend"
|
||||||
|
]
|
||||||
|
ignore_missing_imports = true
|
||||||
|
|
||||||
|
[tool.coverage.run]
|
||||||
|
branch = true
|
||||||
|
relative_files = true
|
||||||
|
source = [
|
||||||
|
"cryptography",
|
||||||
|
"tests/",
|
||||||
|
]
|
||||||
|
|
||||||
|
[tool.coverage.paths]
|
||||||
|
source = [
|
||||||
|
"src/cryptography",
|
||||||
|
"*.tox/*/lib*/python*/site-packages/cryptography",
|
||||||
|
"*.tox\\*\\Lib\\site-packages\\cryptography",
|
||||||
|
"*.tox/pypy/site-packages/cryptography",
|
||||||
|
]
|
||||||
|
tests =[
|
||||||
|
"tests/",
|
||||||
|
"*tests\\",
|
||||||
|
]
|
||||||
|
|
||||||
|
[tool.coverage.report]
|
||||||
|
exclude_lines = [
|
||||||
|
"@abc.abstractmethod",
|
||||||
|
"@abc.abstractproperty",
|
||||||
|
"@typing.overload",
|
||||||
|
"if typing.TYPE_CHECKING",
|
||||||
|
]
|
91
flake8_to_ruff/examples/cryptography/setup.cfg
Normal file
91
flake8_to_ruff/examples/cryptography/setup.cfg
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
[metadata]
|
||||||
|
name = cryptography
|
||||||
|
version = attr: cryptography.__version__
|
||||||
|
description = cryptography is a package which provides cryptographic recipes and primitives to Python developers.
|
||||||
|
long_description = file: README.rst
|
||||||
|
long_description_content_type = text/x-rst
|
||||||
|
license = BSD-3-Clause OR Apache-2.0
|
||||||
|
url = https://github.com/pyca/cryptography
|
||||||
|
author = The Python Cryptographic Authority and individual contributors
|
||||||
|
author_email = cryptography-dev@python.org
|
||||||
|
project_urls =
|
||||||
|
Documentation=https://cryptography.io/
|
||||||
|
Source=https://github.com/pyca/cryptography/
|
||||||
|
Issues=https://github.com/pyca/cryptography/issues
|
||||||
|
Changelog=https://cryptography.io/en/latest/changelog/
|
||||||
|
classifiers =
|
||||||
|
Development Status :: 5 - Production/Stable
|
||||||
|
Intended Audience :: Developers
|
||||||
|
License :: OSI Approved :: Apache Software License
|
||||||
|
License :: OSI Approved :: BSD License
|
||||||
|
Natural Language :: English
|
||||||
|
Operating System :: MacOS :: MacOS X
|
||||||
|
Operating System :: POSIX
|
||||||
|
Operating System :: POSIX :: BSD
|
||||||
|
Operating System :: POSIX :: Linux
|
||||||
|
Operating System :: Microsoft :: Windows
|
||||||
|
Programming Language :: Python
|
||||||
|
Programming Language :: Python :: 3
|
||||||
|
Programming Language :: Python :: 3 :: Only
|
||||||
|
Programming Language :: Python :: 3.6
|
||||||
|
Programming Language :: Python :: 3.7
|
||||||
|
Programming Language :: Python :: 3.8
|
||||||
|
Programming Language :: Python :: 3.9
|
||||||
|
Programming Language :: Python :: 3.10
|
||||||
|
Programming Language :: Python :: 3.11
|
||||||
|
Programming Language :: Python :: Implementation :: CPython
|
||||||
|
Programming Language :: Python :: Implementation :: PyPy
|
||||||
|
Topic :: Security :: Cryptography
|
||||||
|
|
||||||
|
[options]
|
||||||
|
python_requires = >=3.6
|
||||||
|
include_package_data = True
|
||||||
|
zip_safe = False
|
||||||
|
package_dir =
|
||||||
|
=src
|
||||||
|
packages = find:
|
||||||
|
# `install_requires` must be kept in sync with `pyproject.toml`
|
||||||
|
install_requires =
|
||||||
|
cffi >=1.12
|
||||||
|
|
||||||
|
[options.packages.find]
|
||||||
|
where = src
|
||||||
|
exclude =
|
||||||
|
_cffi_src
|
||||||
|
_cffi_src.*
|
||||||
|
|
||||||
|
[options.extras_require]
|
||||||
|
test =
|
||||||
|
pytest>=6.2.0
|
||||||
|
pytest-benchmark
|
||||||
|
pytest-cov
|
||||||
|
pytest-subtests
|
||||||
|
pytest-xdist
|
||||||
|
pretend
|
||||||
|
iso8601
|
||||||
|
pytz
|
||||||
|
hypothesis>=1.11.4,!=3.79.2
|
||||||
|
docs =
|
||||||
|
sphinx >= 1.6.5,!=1.8.0,!=3.1.0,!=3.1.1,!=5.2.0,!=5.2.0.post0
|
||||||
|
sphinx_rtd_theme
|
||||||
|
docstest =
|
||||||
|
pyenchant >= 1.6.11
|
||||||
|
twine >= 1.12.0
|
||||||
|
sphinxcontrib-spelling >= 4.0.1
|
||||||
|
sdist =
|
||||||
|
setuptools_rust >= 0.11.4
|
||||||
|
pep8test =
|
||||||
|
black
|
||||||
|
flake8
|
||||||
|
flake8-import-order
|
||||||
|
pep8-naming
|
||||||
|
# This extra is for OpenSSH private keys that use bcrypt KDF
|
||||||
|
# Versions: v3.1.3 - ignore_few_rounds, v3.1.5 - abi3
|
||||||
|
ssh =
|
||||||
|
bcrypt >= 3.1.5
|
||||||
|
|
||||||
|
[flake8]
|
||||||
|
ignore = E203,E211,W503,W504,N818
|
||||||
|
exclude = .tox,*.egg,.git,_build,.hypothesis
|
||||||
|
select = E,W,F,N,I
|
||||||
|
application-import-names = cryptography,cryptography_vectors,tests
|
32
flake8_to_ruff/src/black.rs
Normal file
32
flake8_to_ruff/src/black.rs
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
//! Extract Black configuration settings from a pyproject.toml.
|
||||||
|
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
|
use ruff::settings::types::PythonVersion;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Default)]
|
||||||
|
pub struct Black {
|
||||||
|
#[serde(alias = "line-length", alias = "line_length")]
|
||||||
|
pub line_length: Option<usize>,
|
||||||
|
#[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::from_str::<Pyproject>(&contents)?
|
||||||
|
.tool
|
||||||
|
.and_then(|tool| tool.black))
|
||||||
|
}
|
|
@ -11,13 +11,20 @@ use ruff::{
|
||||||
pep8_naming,
|
pep8_naming,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::black::Black;
|
||||||
use crate::plugin::Plugin;
|
use crate::plugin::Plugin;
|
||||||
use crate::{parser, plugin};
|
use crate::{parser, plugin};
|
||||||
|
|
||||||
pub fn convert(
|
pub fn convert(
|
||||||
flake8: &HashMap<String, Option<String>>,
|
config: &HashMap<String, HashMap<String, Option<String>>>,
|
||||||
|
black: Option<&Black>,
|
||||||
plugins: Option<Vec<Plugin>>,
|
plugins: Option<Vec<Plugin>>,
|
||||||
) -> Result<Pyproject> {
|
) -> Result<Pyproject> {
|
||||||
|
// Extract the Flake8 section.
|
||||||
|
let flake8 = config
|
||||||
|
.get("flake8")
|
||||||
|
.expect("Unable to find flake8 section in INI file");
|
||||||
|
|
||||||
// Extract all referenced check code prefixes, to power plugin inference.
|
// Extract all referenced check code prefixes, to power plugin inference.
|
||||||
let mut referenced_codes: BTreeSet<CheckCodePrefix> = BTreeSet::default();
|
let mut referenced_codes: BTreeSet<CheckCodePrefix> = BTreeSet::default();
|
||||||
for (key, value) in flake8 {
|
for (key, value) in flake8 {
|
||||||
|
@ -236,6 +243,19 @@ pub fn convert(
|
||||||
options.pep8_naming = Some(pep8_naming);
|
options.pep8_naming = Some(pep8_naming);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Extract any settings from the existing `pyproject.toml`.
|
||||||
|
if let Some(black) = black {
|
||||||
|
if let Some(line_length) = &black.line_length {
|
||||||
|
options.line_length = Some(*line_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(target_version) = &black.target_version {
|
||||||
|
if let Some(target_version) = target_version.iter().min() {
|
||||||
|
options.target_version = Some(*target_version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Create the pyproject.toml.
|
// Create the pyproject.toml.
|
||||||
Ok(Pyproject::new(options))
|
Ok(Pyproject::new(options))
|
||||||
}
|
}
|
||||||
|
@ -255,7 +275,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn it_converts_empty() -> Result<()> {
|
fn it_converts_empty() -> Result<()> {
|
||||||
let actual = convert(&HashMap::from([]), None)?;
|
let actual = convert(&HashMap::from([]), None, None)?;
|
||||||
let expected = Pyproject::new(Options {
|
let expected = Pyproject::new(Options {
|
||||||
allowed_confusables: None,
|
allowed_confusables: None,
|
||||||
dummy_variable_rgx: None,
|
dummy_variable_rgx: None,
|
||||||
|
@ -303,7 +323,11 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn it_converts_dashes() -> Result<()> {
|
fn it_converts_dashes() -> Result<()> {
|
||||||
let actual = convert(
|
let actual = convert(
|
||||||
&HashMap::from([("max-line-length".to_string(), Some("100".to_string()))]),
|
&HashMap::from([(
|
||||||
|
"flake8".to_string(),
|
||||||
|
HashMap::from([("max-line-length".to_string(), Some("100".to_string()))]),
|
||||||
|
)]),
|
||||||
|
None,
|
||||||
Some(vec![]),
|
Some(vec![]),
|
||||||
)?;
|
)?;
|
||||||
let expected = Pyproject::new(Options {
|
let expected = Pyproject::new(Options {
|
||||||
|
@ -353,7 +377,11 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn it_converts_underscores() -> Result<()> {
|
fn it_converts_underscores() -> Result<()> {
|
||||||
let actual = convert(
|
let actual = convert(
|
||||||
&HashMap::from([("max_line_length".to_string(), Some("100".to_string()))]),
|
&HashMap::from([(
|
||||||
|
"flake8".to_string(),
|
||||||
|
HashMap::from([("max_line_length".to_string(), Some("100".to_string()))]),
|
||||||
|
)]),
|
||||||
|
None,
|
||||||
Some(vec![]),
|
Some(vec![]),
|
||||||
)?;
|
)?;
|
||||||
let expected = Pyproject::new(Options {
|
let expected = Pyproject::new(Options {
|
||||||
|
@ -403,7 +431,11 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn it_ignores_parse_errors() -> Result<()> {
|
fn it_ignores_parse_errors() -> Result<()> {
|
||||||
let actual = convert(
|
let actual = convert(
|
||||||
&HashMap::from([("max_line_length".to_string(), Some("abc".to_string()))]),
|
&HashMap::from([(
|
||||||
|
"flake8".to_string(),
|
||||||
|
HashMap::from([("max_line_length".to_string(), Some("abc".to_string()))]),
|
||||||
|
)]),
|
||||||
|
None,
|
||||||
Some(vec![]),
|
Some(vec![]),
|
||||||
)?;
|
)?;
|
||||||
let expected = Pyproject::new(Options {
|
let expected = Pyproject::new(Options {
|
||||||
|
@ -453,7 +485,11 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn it_converts_plugin_options() -> Result<()> {
|
fn it_converts_plugin_options() -> Result<()> {
|
||||||
let actual = convert(
|
let actual = convert(
|
||||||
&HashMap::from([("inline-quotes".to_string(), Some("single".to_string()))]),
|
&HashMap::from([(
|
||||||
|
"flake8".to_string(),
|
||||||
|
HashMap::from([("inline-quotes".to_string(), Some("single".to_string()))]),
|
||||||
|
)]),
|
||||||
|
None,
|
||||||
Some(vec![]),
|
Some(vec![]),
|
||||||
)?;
|
)?;
|
||||||
let expected = Pyproject::new(Options {
|
let expected = Pyproject::new(Options {
|
||||||
|
@ -509,9 +545,13 @@ mod tests {
|
||||||
fn it_converts_docstring_conventions() -> Result<()> {
|
fn it_converts_docstring_conventions() -> Result<()> {
|
||||||
let actual = convert(
|
let actual = convert(
|
||||||
&HashMap::from([(
|
&HashMap::from([(
|
||||||
|
"flake8".to_string(),
|
||||||
|
HashMap::from([(
|
||||||
"docstring-convention".to_string(),
|
"docstring-convention".to_string(),
|
||||||
Some("numpy".to_string()),
|
Some("numpy".to_string()),
|
||||||
)]),
|
)]),
|
||||||
|
)]),
|
||||||
|
None,
|
||||||
Some(vec![Plugin::Flake8Docstrings]),
|
Some(vec![Plugin::Flake8Docstrings]),
|
||||||
)?;
|
)?;
|
||||||
let expected = Pyproject::new(Options {
|
let expected = Pyproject::new(Options {
|
||||||
|
@ -597,7 +637,11 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn it_infers_plugins_if_omitted() -> Result<()> {
|
fn it_infers_plugins_if_omitted() -> Result<()> {
|
||||||
let actual = convert(
|
let actual = convert(
|
||||||
&HashMap::from([("inline-quotes".to_string(), Some("single".to_string()))]),
|
&HashMap::from([(
|
||||||
|
"flake8".to_string(),
|
||||||
|
HashMap::from([("inline-quotes".to_string(), Some("single".to_string()))]),
|
||||||
|
)]),
|
||||||
|
None,
|
||||||
None,
|
None,
|
||||||
)?;
|
)?;
|
||||||
let expected = Pyproject::new(Options {
|
let expected = Pyproject::new(Options {
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
clippy::too_many_lines
|
clippy::too_many_lines
|
||||||
)]
|
)]
|
||||||
|
|
||||||
|
pub mod black;
|
||||||
pub mod converter;
|
pub mod converter;
|
||||||
mod parser;
|
mod parser;
|
||||||
pub mod plugin;
|
pub mod plugin;
|
||||||
|
|
|
@ -17,6 +17,7 @@ use std::path::PathBuf;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use configparser::ini::Ini;
|
use configparser::ini::Ini;
|
||||||
|
use flake8_to_ruff::black::parse_black_options;
|
||||||
use flake8_to_ruff::converter;
|
use flake8_to_ruff::converter;
|
||||||
use flake8_to_ruff::plugin::Plugin;
|
use flake8_to_ruff::plugin::Plugin;
|
||||||
|
|
||||||
|
@ -26,10 +27,14 @@ use flake8_to_ruff::plugin::Plugin;
|
||||||
long_about = None
|
long_about = None
|
||||||
)]
|
)]
|
||||||
struct Cli {
|
struct Cli {
|
||||||
/// Path to the Flake8 configuration file (e.g., 'setup.cfg', 'tox.ini', or
|
/// Path to the Flake8 configuration file (e.g., `setup.cfg`, `tox.ini`, or
|
||||||
/// '.flake8').
|
/// `.flake8`).
|
||||||
#[arg(required = true)]
|
#[arg(required = true)]
|
||||||
file: PathBuf,
|
file: PathBuf,
|
||||||
|
/// Optional path to a `pyproject.toml` file, used to ensure compatibility
|
||||||
|
/// with Black.
|
||||||
|
#[arg(long)]
|
||||||
|
pyproject: Option<PathBuf>,
|
||||||
/// List of plugins to enable.
|
/// List of plugins to enable.
|
||||||
#[arg(long, value_delimiter = ',')]
|
#[arg(long, value_delimiter = ',')]
|
||||||
plugin: Option<Vec<Plugin>>,
|
plugin: Option<Vec<Plugin>>,
|
||||||
|
@ -43,13 +48,15 @@ fn main() -> Result<()> {
|
||||||
ini.set_multiline(true);
|
ini.set_multiline(true);
|
||||||
let config = ini.load(cli.file).map_err(|msg| anyhow::anyhow!(msg))?;
|
let config = ini.load(cli.file).map_err(|msg| anyhow::anyhow!(msg))?;
|
||||||
|
|
||||||
// Extract the Flake8 section.
|
// Read the pyproject.toml file.
|
||||||
let flake8 = config
|
let black = cli
|
||||||
.get("flake8")
|
.pyproject
|
||||||
.expect("Unable to find flake8 section in INI file");
|
.map(parse_black_options)
|
||||||
|
.transpose()?
|
||||||
|
.flatten();
|
||||||
|
|
||||||
// Create the pyproject.toml.
|
// Create Ruff's pyproject.toml section.
|
||||||
let pyproject = converter::convert(flake8, cli.plugin)?;
|
let pyproject = converter::convert(&config, black.as_ref(), cli.plugin)?;
|
||||||
println!("{}", toml::to_string_pretty(&pyproject)?);
|
println!("{}", toml::to_string_pretty(&pyproject)?);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -13,7 +13,7 @@ use crate::checks::CheckCode;
|
||||||
use crate::checks_gen::CheckCodePrefix;
|
use crate::checks_gen::CheckCodePrefix;
|
||||||
use crate::fs;
|
use crate::fs;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialOrd, PartialEq, Eq, Serialize, Deserialize, Hash)]
|
#[derive(Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq, Serialize, Deserialize, Hash)]
|
||||||
#[serde(rename_all = "lowercase")]
|
#[serde(rename_all = "lowercase")]
|
||||||
pub enum PythonVersion {
|
pub enum PythonVersion {
|
||||||
Py33,
|
Py33,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue