Source code for pyscaffoldext.pre_commit_ruff.extension

"""Add pre-commit-ruff extension."""

from argparse import ArgumentParser
from functools import partial, reduce

from pyscaffold import structure, toml
from pyscaffold.actions import Action, ActionParams, ScaffoldOpts, Structure
from pyscaffold.extensions import Extension, include
from pyscaffold.extensions.pre_commit import PreCommit
from pyscaffold.operations import FileOp, no_overwrite
from pyscaffold.structure import (
    AbstractContent,
    Node,
    ResolvedLeaf,
    reify_leaf,
)
from pyscaffold.templates import get_template
from pyscaffold.update import ConfigUpdater

from . import templates as my_templates

PYPROJ_INSERT_AFTER = 'version_scheme = "no-guess-dev"\n'


[docs] class PreCommitRuff(Extension): """Generate pre-commit configuration file for Ruff (includes `--pre-commit`)."""
[docs] def augment_cli(self, parser: ArgumentParser): """Augments the command-line interface parser. See :obj:`~pyscaffold.extension.Extension.augment_cli`. """ parser.add_argument( self.flag, help=self.help_text, nargs=0, action=include( PreCommit(), self, ), ) return self
[docs] def activate(self, actions: list[Action]) -> list[Action]: """Activates See :obj:`pyscaffold.extension.Extension.activate`. Args: actions (list): list of actions to perform Returns: list: updated list of actions """ return self.register( actions, add_files, after="pyscaffold.extensions.pre_commit:add_files", )
[docs] def add_files(struct: Structure, opts: ScaffoldOpts) -> ActionParams: """Replace .pre-commit-config.yaml. Update setup.cfg and pyproject.toml. Add mypy section to setup.cfg. Remove flake8 section from setup.cfg. Ruff replaces flake8. Add ruff configuration to pyproject.toml. """ files: Structure = { ".pre-commit-config.yaml": ( get_template( name="pre-commit-ruff-config", relative_to=my_templates.__name__, ), no_overwrite(), ), "setup.cfg": modify_setupcfg(struct["setup.cfg"], opts), } struct = structure.modify( struct, "pyproject.toml", partial(modify_pyproject, opts), ) return structure.merge(struct, files), opts
[docs] def modify_setupcfg(definition: Node, opts: ScaffoldOpts) -> ResolvedLeaf: """Modify setup.cfg to add template settings before it is written. See :obj:`pyscaffold.operations`. """ content, action = reify_leaf(definition, opts) # pyright: ignore [reportArgumentType] setupcfg = ConfigUpdater().read_string(str(content)) modifiers = (add_setupcfg,) new_setupcfg = reduce(lambda acc, fn: fn(acc, opts), modifiers, setupcfg) return str(new_setupcfg), action
[docs] def add_setupcfg(setupcfg: ConfigUpdater, opts) -> ConfigUpdater: """Add section(s) to setup.cfg.""" template = ConfigUpdater().read_string( str( structure.reify_content( get_template( name="setup_cfg", relative_to=my_templates.__name__, ), opts, ), ) ) setupcfg.remove_section("flake8") for k in template: setupcfg["pyscaffold"].add_before.section(k) setupcfg[k] = template[k].detach() setupcfg["pyscaffold"].add_before.space(newlines=1) return setupcfg
[docs] def modify_pyproject( opts: ScaffoldOpts, content: AbstractContent, file_op: FileOp ) -> ResolvedLeaf: """Add Ruff configuration to pyproject.toml.""" pyproj_new = toml.loads( "\n".join( ( str(structure.reify_content(content, opts)), str(structure.reify_content(my_templates.pyproject_toml, opts)), ) ) ) return toml.dumps(pyproj_new), file_op