Skip to content

Commit

Permalink
BEHAVIOR: mege setup.cfg into pyproject.toml (#184)
Browse files Browse the repository at this point in the history
* BREAK: rename `setup_cfg` module to `project_info`
* DX: add `toml-sort` pre-commit hook
* DX: allow constructing `dict` with `dict` kwargs
* DX: rename Conda environment to `repo-maintenance`
* ENH: accept both `pyproject.toml` and `setup.cfg` in `project_info` module
* FIX: write `pyright` instead of `black`
  • Loading branch information
redeboer authored Oct 3, 2023
1 parent 908e44c commit 6b9c58c
Show file tree
Hide file tree
Showing 20 changed files with 549 additions and 150 deletions.
15 changes: 8 additions & 7 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ ci:
autoupdate_schedule: quarterly
skip:
- check-dev-files
- format-setup-cfg
- mypy
- pyright
- repoma-self-check
Expand Down Expand Up @@ -49,12 +48,6 @@ repos:
- --repo-name=repo-maintenance
- --repo-title=ComPWA Repository Maintenance

- id: format-setup-cfg
name: Format setup.cfg
entry: format-setup-cfg
language: python
files: ^setup.cfg$

- id: repoma-self-check
name: repoma-self-check
entry: repoma-self-check
Expand Down Expand Up @@ -125,3 +118,11 @@ repos:
rev: v0.8.0
hooks:
- id: taplo

- repo: https://github.com/pappasam/toml-sort
rev: v0.23.1
hooks:
- id: toml-sort
args:
- --in-place
exclude: (?x)^(labels.toml|labels-physics.toml)$
3 changes: 3 additions & 0 deletions .taplo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ exclude = [
]

[formatting]
align_comments = false
align_entries = false
allowed_blank_lines = 1
array_auto_collapse = false
array_auto_expand = true
array_trailing_comma = true
column_width = 88
compact_inline_tables = true
indent_string = " "
reorder_arrays = true
reorder_keys = true
2 changes: 1 addition & 1 deletion environment.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: repoma
name: repo-maintenance
channels:
- defaults
dependencies:
Expand Down
41 changes: 27 additions & 14 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ module = ["nbformat.*"]
ignore_missing_imports = true
module = ["pre_commit.commands.autoupdate.*"]


[tool.pyright]
exclude = [
"**/.git",
Expand Down Expand Up @@ -101,7 +100,6 @@ reportUnusedImport = true
reportUnusedVariable = true
typeCheckingMode = "strict"


[tool.pytest.ini_options]
addopts = """
--color=yes
Expand Down Expand Up @@ -153,20 +151,21 @@ extend-select = [
"YTT",
]
ignore = [
"D101", # class docstring
"D102", # method docstring
"D103", # function docstring
"D105", # magic method docstring
"D107", # init docstring
"D203", # conflicts with D211
"D213", # multi-line docstring should start at the second line
"D407", # missing dashed underline after section
"D416", # section name does not have to end with a colon
"E501", # handled by black formatting
"C408", # Unnecessary dict call - rewrite as a literal
"D101", # class docstring
"D102", # method docstring
"D103", # function docstring
"D105", # magic method docstring
"D107", # init docstring
"D203", # conflicts with D211
"D213", # multi-line docstring should start at the second line
"D407", # missing dashed underline after section
"D416", # section name does not have to end with a colon
"E501", # handled by black formatting
"PLR0913", # sympy functions
"PLW2901", # often used for xreplace
"S301", # allow pickle
"SIM108", # if-else-block-instead-of-if-exp
"S301", # allow pickle
"SIM108", # if-else-block-instead-of-if-exp
]
show-fixes = true
src = [
Expand All @@ -192,3 +191,17 @@ known-first-party = ["repoma"]

[tool.ruff.pydocstyle]
convention = "google"

[tool.tomlsort]
all = false
ignore_case = true
in_place = true
sort_first = [
"build-system",
"project",
"tool.setuptools",
"tool.setuptools_scm",
]
sort_table_keys = true
spaces_indent_inline_array = 4
trailing_comma_inline_array = true
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ setup_requires =
setuptools_scm
install_requires =
attrs >=20.1.0 # https://www.attrs.org/en/stable/changelog.html#id82
dataclasses; python_version<="3.7.0"
html2text
ini2toml
nbformat
Expand Down
2 changes: 1 addition & 1 deletion src/repoma/check_dev_files/black.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@
remove_precommit_hook,
update_single_hook_precommit_repo,
)
from repoma.utilities.project_info import get_supported_python_versions
from repoma.utilities.pyproject import (
complies_with_subset,
get_sub_table,
load_pyproject,
to_toml_array,
write_pyproject,
)
from repoma.utilities.setup_cfg import get_supported_python_versions
from repoma.utilities.vscode import (
add_extension_recommendation,
set_setting,
Expand Down
43 changes: 36 additions & 7 deletions src/repoma/check_dev_files/deprecated.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
from repoma.utilities import CONFIG_PATH
from repoma.utilities.executor import Executor
from repoma.utilities.precommit import remove_precommit_hook
from repoma.utilities.project_info import open_setup_cfg
from repoma.utilities.pyproject import load_pyproject, write_pyproject
from repoma.utilities.readme import remove_badge
from repoma.utilities.setup_cfg import open_setup_cfg
from repoma.utilities.vscode import (
remove_extension_recommendation,
remove_settings,
Expand All @@ -35,8 +35,8 @@ def _remove_flake8() -> None:
executor = Executor()
executor(__remove_configs, [".flake8"])
executor(__remove_nbqa_option, "flake8")
executor(__uninstall, "flake8", check_options=["lint", "sty"])
executor(__uninstall, "pep8-naming", check_options=["lint", "sty"])
executor(__uninstall, "flake8")
executor(__uninstall, "pep8-naming")
executor(remove_extension_recommendation, "ms-python.flake8", unwanted=True)
executor(remove_precommit_hook, "autoflake") # cspell:ignore autoflake
executor(remove_precommit_hook, "flake8")
Expand Down Expand Up @@ -115,15 +115,15 @@ def _remove_pydocstyle() -> None:
"tests/.pydocstyle",
],
)
executor(__uninstall, "pydocstyle", check_options=["lint", "sty"])
executor(__uninstall, "pydocstyle")
executor(remove_precommit_hook, "pydocstyle")
executor.finalize()


def _remove_pylint() -> None:
executor = Executor()
executor(__remove_configs, [".pylintrc"]) # cspell:ignore pylintrc
executor(__uninstall, "pylint", check_options=["lint", "sty"])
executor(__uninstall, "pylint")
executor(remove_extension_recommendation, "ms-python.pylint", unwanted=True)
executor(remove_precommit_hook, "pylint")
executor(remove_precommit_hook, "nbqa-pylint")
Expand All @@ -149,14 +149,19 @@ def __remove_file(path: str) -> None:
raise PrecommitError(msg)


def __uninstall(package: str, check_options: List[str]) -> None:
def __uninstall(package: str) -> None:
__uninstall_from_setup_cfg(package)
__uninstall_from_pyproject_toml(package)


def __uninstall_from_setup_cfg(package: str) -> None:
if not os.path.exists(CONFIG_PATH.setup_cfg):
return
cfg = open_setup_cfg()
section = "options.extras_require"
if not cfg.has_section(section):
return
for option in check_options:
for option in cfg[section]:
if not cfg.has_option(section, option):
continue
if package not in cfg.get(section, option):
Expand All @@ -165,6 +170,30 @@ def __uninstall(package: str, check_options: List[str]) -> None:
raise PrecommitError(msg)


def __uninstall_from_pyproject_toml(package: str) -> None:
if not os.path.exists(CONFIG_PATH.pyproject):
return
pyproject = load_pyproject()
project = pyproject.get("project")
if project is None:
return
updated = False
dependencies = project.get("dependencies")
if dependencies is not None and package in dependencies:
dependencies.remove(package)
updated = True
optional_dependencies = project.get("optional-dependencies")
if optional_dependencies is not None:
for values in optional_dependencies.values():
if package in values:
values.remove(package)
updated = True
if updated:
write_pyproject(pyproject)
msg = f"Removed {package} from {CONFIG_PATH.pyproject}"
raise PrecommitError(msg)


def __remove_from_gitignore(pattern: str) -> None:
gitignore_path = ".gitignore"
if not os.path.exists(gitignore_path):
Expand Down
2 changes: 1 addition & 1 deletion src/repoma/check_dev_files/github_workflows.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from repoma.utilities import CONFIG_PATH, REPOMA_DIR, write
from repoma.utilities.executor import Executor
from repoma.utilities.precommit import PrecommitConfig
from repoma.utilities.setup_cfg import get_pypi_name
from repoma.utilities.project_info import get_pypi_name
from repoma.utilities.vscode import (
add_extension_recommendation,
remove_extension_recommendation,
Expand Down
2 changes: 1 addition & 1 deletion src/repoma/check_dev_files/gitpod.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

from repoma.errors import PrecommitError
from repoma.utilities import CONFIG_PATH, REPOMA_DIR
from repoma.utilities.project_info import get_repo_url
from repoma.utilities.readme import add_badge
from repoma.utilities.setup_cfg import get_repo_url
from repoma.utilities.yaml import write_yaml

__CONSTRAINTS_FILE = ".constraints/py3.8.txt"
Expand Down
2 changes: 1 addition & 1 deletion src/repoma/check_dev_files/pyright.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,5 @@ def _update_settings() -> None:
if not complies_with_subset(settings, minimal_settings):
settings.update(minimal_settings)
write_pyproject(pyproject)
msg = f"Updated black configuration in {CONFIG_PATH.pyproject}"
msg = f"Updated pyright configuration in {CONFIG_PATH.pyproject}"
raise PrecommitError(msg)
2 changes: 1 addition & 1 deletion src/repoma/check_dev_files/pyupgrade.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
update_precommit_hook,
update_single_hook_precommit_repo,
)
from repoma.utilities.setup_cfg import get_supported_python_versions
from repoma.utilities.project_info import get_supported_python_versions


def main() -> None:
Expand Down
61 changes: 60 additions & 1 deletion src/repoma/check_dev_files/ruff.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,29 @@
"""Check `Ruff <https://ruff.rs>`_ configuration."""

import os
from copy import deepcopy
from textwrap import dedent
from typing import List, Set

from ruamel.yaml.comments import CommentedMap
from tomlkit.items import Array, Table

from repoma.check_dev_files.setup_cfg import (
has_pyproject_build_system,
has_setup_cfg_build_system,
)
from repoma.errors import PrecommitError
from repoma.utilities import CONFIG_PATH, natural_sorting
from repoma.utilities.executor import Executor
from repoma.utilities.precommit import (
update_precommit_hook,
update_single_hook_precommit_repo,
)
from repoma.utilities.project_info import (
get_project_info,
get_supported_python_versions,
open_setup_cfg,
)
from repoma.utilities.pyproject import (
complies_with_subset,
get_sub_table,
Expand All @@ -23,7 +33,6 @@
write_pyproject,
)
from repoma.utilities.readme import add_badge
from repoma.utilities.setup_cfg import get_supported_python_versions, open_setup_cfg
from repoma.utilities.vscode import add_extension_recommendation, set_setting


Expand All @@ -40,11 +49,14 @@ def main() -> None:
executor(_update_ruff_pydocstyle_settings)
executor(_update_precommit_hook)
executor(_update_precommit_nbqa_hook)
executor(_update_pyproject)
executor(_update_vscode_settings)
executor.finalize()


def _check_setup_cfg() -> None:
if not has_setup_cfg_build_system():
return
cfg = open_setup_cfg()
extras_require = "options.extras_require"
if not cfg.has_section(extras_require):
Expand Down Expand Up @@ -77,6 +89,53 @@ def _check_setup_cfg() -> None:
raise PrecommitError(msg)


def _update_pyproject() -> None:
if not has_pyproject_build_system():
return
pyproject = load_pyproject()
project_info = get_project_info(pyproject)
package = project_info.name
if package is None:
msg = (
"Please specify a [project.name] for the package in"
f" [{CONFIG_PATH.pyproject}]"
)
raise PrecommitError(msg)
project = get_sub_table(pyproject, "project", create=True)
old_dependencies = project.get("optional-dependencies")
new_dependencies = deepcopy(old_dependencies)
python_versions = project_info.supported_python_versions
if python_versions is not None and "3.6" in python_versions:
ruff = 'ruff; python_version >="3.7.0"'
else:
ruff = "ruff"
if new_dependencies is None:
new_dependencies = dict(
dev=[f"{package}[sty]"],
lint=[ruff],
sty=[f"{package}[lint]"],
)
else:
__add_package(new_dependencies, "dev", f"{package}[sty]")
__add_package(new_dependencies, "lint", ruff)
__add_package(new_dependencies, "sty", f"{package}[lint]")
if old_dependencies != new_dependencies:
project["optional-dependencies"] = new_dependencies
write_pyproject(pyproject)
msg = f"Updated [project.optional-dependencies] in {CONFIG_PATH.pyproject}"
raise PrecommitError(msg)


def __add_package(optional_dependencies: Table, key: str, package: str) -> None:
section = optional_dependencies.get(key)
if section is None:
optional_dependencies[key] = [package]
elif package not in section:
optional_dependencies[key] = to_toml_array(
sorted({package, *section}, key=lambda s: ('"' in s, s)) # Taplo sorting
)


def _update_nbqa_settings() -> None:
# cspell:ignore addopts
ruff_rules = [
Expand Down
Loading

0 comments on commit 6b9c58c

Please sign in to comment.