From c3308421b665e5d8dcb70b78acf137541a026555 Mon Sep 17 00:00:00 2001 From: crupest Date: Mon, 11 Nov 2024 01:12:29 +0800 Subject: HALF WORK: 2024.1.7 --- crupest-words.txt | 5 +- tools/cru-py/.flake8 | 4 - tools/cru-py/cru/service/_base.py | 1 + tools/cru-py/cru/service/_config.py | 4 + tools/cru-py/cru/service/_template.py | 54 +++++++-- tools/cru-py/cru/template.py | 135 +++++++++------------- tools/cru-py/poetry.lock | 209 +--------------------------------- tools/cru-py/pyproject.toml | 10 +- 8 files changed, 108 insertions(+), 314 deletions(-) delete mode 100644 tools/cru-py/.flake8 diff --git a/crupest-words.txt b/crupest-words.txt index b0a9936..6b9961b 100644 --- a/crupest-words.txt +++ b/crupest-words.txt @@ -1,7 +1,3 @@ -# debian -# secret -# software -# university 2fauth aarch64 buildpackage @@ -32,3 +28,4 @@ userid ustc vmess vnext +yuqian diff --git a/tools/cru-py/.flake8 b/tools/cru-py/.flake8 deleted file mode 100644 index a77cb08..0000000 --- a/tools/cru-py/.flake8 +++ /dev/null @@ -1,4 +0,0 @@ -[flake8] -max-line-length = 80 -extend-select = B950 -extend-ignore = E203,E501,E701 diff --git a/tools/cru-py/cru/service/_base.py b/tools/cru-py/cru/service/_base.py index f91eadd..98eed89 100644 --- a/tools/cru-py/cru/service/_base.py +++ b/tools/cru-py/cru/service/_base.py @@ -10,6 +10,7 @@ from cru import CruException, CruInternalError, CruPath _F = TypeVar("_F") +OWNER_NAME = "crupest" class InternalAppException(CruInternalError): pass diff --git a/tools/cru-py/cru/service/_config.py b/tools/cru-py/cru/service/_config.py index a387ef7..63b73b3 100644 --- a/tools/cru-py/cru/service/_config.py +++ b/tools/cru-py/cru/service/_config.py @@ -12,3 +12,7 @@ class ConfigManager(AppFeatureProvider): @property def config_path(self) -> AppFeaturePath: return self._config_path + + @property + def config_map(self) -> dict[str, str]: + raise NotImplementedError() diff --git a/tools/cru-py/cru/service/_template.py b/tools/cru-py/cru/service/_template.py index fcc5658..5f0252a 100644 --- a/tools/cru-py/cru/service/_template.py +++ b/tools/cru-py/cru/service/_template.py @@ -1,18 +1,23 @@ from argparse import ArgumentParser, Namespace +from cru import CruIterator from cru.template import TemplateTree -from ._base import AppCommandFeatureProvider, AppFeaturePath +from ._base import AppCommandFeatureProvider, AppFeaturePath, OWNER_NAME +from ._config import ConfigManager class TemplateManager(AppCommandFeatureProvider): - def __init__(self, prefix: str = "CRUPEST"): + def __init__(self, prefix: str = OWNER_NAME.upper()): super().__init__("template-manager") + self._prefix = prefix self._templates_dir = self.app.add_path("templates", True) self._generated_dir = self.app.add_path("generated", True) - self._template_tree = TemplateTree( - prefix, self._templates_dir.full_path_str, self._generated_dir.full_path_str - ) + self._template_tree: TemplateTree | None = None + + @property + def prefix(self) -> str: + return self._prefix @property def templates_dir(self) -> AppFeaturePath: @@ -22,9 +27,42 @@ class TemplateManager(AppCommandFeatureProvider): def generated_dir(self) -> AppFeaturePath: return self._generated_dir + @property + def template_tree(self) -> TemplateTree: + if self._template_tree is None: + return self.reload() + return self._template_tree + + def reload(self) -> TemplateTree: + self._template_tree = TemplateTree( + self.prefix, self.templates_dir.full_path_str + ) + return self._template_tree + + def list_files(self) -> list[str]: + return ( + CruIterator(self.template_tree.templates) + .transform(lambda t: t[0]) + .to_list() + ) + + def print_file_lists(self) -> None: + for file in self.list_files(): + print(file) + + def generate_files(self) -> None: + config_manager = self.app.get_feature(ConfigManager) + self.template_tree.generate_to( + self.generated_dir.full_path_str, config_manager.config_map + ) + def add_arg_parser(self, arg_parser: ArgumentParser) -> None: subparsers = arg_parser.add_subparsers(dest="template_command") - list_parser = subparsers.add_parser("list", help="List templates.") - generate_parser = subparsers.add_parser("generate", help="Generate template.") + _list_parser = subparsers.add_parser("list", help="List templates.") + _generate_parser = subparsers.add_parser("generate", help="Generate template.") - def run_command(self, args: Namespace) -> None: ... + def run_command(self, args: Namespace) -> None: + if args.template_command == "list": + self.print_file_lists() + elif args.template_command == "generate": + self.generate_files() diff --git a/tools/cru-py/cru/template.py b/tools/cru-py/cru/template.py index ccb3ad8..a02ea0e 100644 --- a/tools/cru-py/cru/template.py +++ b/tools/cru-py/cru/template.py @@ -1,4 +1,4 @@ -from collections.abc import Iterable, Mapping +from collections.abc import Mapping import os import os.path from string import Template @@ -27,7 +27,7 @@ class CruTemplate: return self._prefix @property - def real_template(self) -> Template: + def py_template(self) -> Template: return self._template @property @@ -39,8 +39,16 @@ class CruTemplate: return self._all_variables @property - def has_no_variables(self) -> bool: - return len(self._variables) == 0 + def has_variables(self) -> bool: + """ + If the template does not has any variables that starts with the given prefix, + it returns False. This usually indicates that the template is not a real + template and should be copied as is. Otherwise, it returns True. + + This can be used as a guard to prevent invalid templates created accidentally + without notice. + """ + return len(self.variables) > 0 def generate(self, mapping: Mapping[str, str], allow_extra: bool = True) -> str: values = dict(mapping) @@ -51,118 +59,79 @@ class CruTemplate: return self._template.safe_substitute(values) -class CruTemplateFile(CruTemplate): - def __init__(self, prefix: str, source: str, destination_path: str): - self._source = source - self._destination = destination_path - with open(source, "r") as f: - super().__init__(prefix, f.read()) - - @property - def source(self) -> str: - return self._source - - @property - def destination(self) -> str | None: - return self._destination - - def generate_to_destination( - self, mapping: Mapping[str, str], allow_extra: bool = True - ) -> None: - with open(self._destination, "w") as f: - f.write(self.generate(mapping, allow_extra)) - - class TemplateTree: def __init__( self, prefix: str, source: str, - destination: str, - exclude: Iterable[str] | None = None, - template_file_suffix: str = ".template", + template_file_suffix: str | None = ".template", ): + """ + If template_file_suffix is not None, the files will be checked according to the + suffix of the file name. If the suffix matches, the file will be regarded as a + template file. Otherwise, it will be regarded as a non-template file. + Content of template file must contain variables that need to be replaced, while + content of non-template file may not contain any variables. + If either case is false, it generally means whether the file is a template is + wrongly handled. + """ self._prefix = prefix - self._files: list[CruTemplateFile] | None = None + self._files: list[tuple[str, CruTemplate]] = [] self._source = source - self._destination = destination - self._exclude = [os.path.normpath(p) for p in exclude or []] self._template_file_suffix = template_file_suffix + self._load() @property def prefix(self) -> str: return self._prefix @property - def files(self) -> list[CruTemplateFile]: - if self._files is None: - self.reload() - return self._files # type: ignore - - @property - def template_files(self) -> list[CruTemplateFile]: - return ( - CruIterator(self.files).filter(lambda f: not f.has_no_variables).to_list() - ) - - @property - def non_template_files(self) -> list[CruTemplateFile]: - return CruIterator(self.files).filter(lambda f: f.has_no_variables).to_list() + def templates(self) -> list[tuple[str, CruTemplate]]: + return self._files @property def source(self) -> str: return self._source @property - def destination(self) -> str: - return self._destination - - @property - def exclude(self) -> list[str]: - return self._exclude - - @property - def template_file_suffix(self) -> str: + def template_file_suffix(self) -> str | None: return self._template_file_suffix @staticmethod - def _scan_files(root_path: str, exclude: list[str]) -> Iterable[str]: + def _scan_files(root_path: str) -> list[str]: + files: list[str] = [] for root, _dirs, files in os.walk(root_path): for file in files: path = os.path.join(root, file) path = os.path.relpath(path, root_path) - is_exclude = False - for exclude_path in exclude: - if path.startswith(exclude_path): - is_exclude = True - break - if not is_exclude: - yield path - - def reload(self, strict=True) -> None: - self._files = [] - file_names = self._scan_files(self.source, self.exclude) - for file_name in file_names: - source = os.path.join(self.source, file_name) - destination = os.path.join(self.destination, file_name) - file = CruTemplateFile(self._prefix, source, destination) - if file_name.endswith(self.template_file_suffix): - if strict and file.has_no_variables: + files.append(path) + return files + + def _load(self) -> None: + files = self._scan_files(self.source) + for file_path in files: + template_file = os.path.join(self.source, file_path) + with open(template_file, "r") as f: + content = f.read() + template = CruTemplate(self.prefix, content) + if self.template_file_suffix is not None: + should_be_template = file_path.endswith(self.template_file_suffix) + if should_be_template and not template.has_variables: raise CruTemplateError( - f"Template file {file_name} has no variables." + f"Template file {file_path} has no variables." ) - else: - if strict and not file.has_no_variables: - raise CruTemplateError(f"Non-template {file_name} has variables.") - self._files.append(file) + elif not should_be_template and template.has_variables: + raise CruTemplateError(f"Non-template {file_path} has variables.") + self._files.append((file_path, template)) @property def variables(self) -> set[str]: s = set() - for file in self.files: - s.update(file.variables) + for _, template in self.templates: + s.update(template.variables) return s - def generate_to_destination(self, variables: Mapping[str, str]) -> None: - for file in self.files: - file.generate_to_destination(variables) + def generate_to(self, destination: str, variables: Mapping[str, str]) -> None: + for file, template in self.templates: + with open(os.path.join(destination, file), "w") as f: + f.write(template.generate(variables)) diff --git a/tools/cru-py/poetry.lock b/tools/cru-py/poetry.lock index f0d3507..305aaee 100644 --- a/tools/cru-py/poetry.lock +++ b/tools/cru-py/poetry.lock @@ -1,152 +1,5 @@ # This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. -[[package]] -name = "attrs" -version = "24.3.0" -description = "Classes Without Boilerplate" -optional = false -python-versions = ">=3.8" -files = [ - {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, - {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, -] - -[package.extras] -benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] - -[[package]] -name = "black" -version = "24.10.0" -description = "The uncompromising code formatter." -optional = false -python-versions = ">=3.9" -files = [ - {file = "black-24.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6668650ea4b685440857138e5fe40cde4d652633b1bdffc62933d0db4ed9812"}, - {file = "black-24.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1c536fcf674217e87b8cc3657b81809d3c085d7bf3ef262ead700da345bfa6ea"}, - {file = "black-24.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:649fff99a20bd06c6f727d2a27f401331dc0cc861fb69cde910fe95b01b5928f"}, - {file = "black-24.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:fe4d6476887de70546212c99ac9bd803d90b42fc4767f058a0baa895013fbb3e"}, - {file = "black-24.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5a2221696a8224e335c28816a9d331a6c2ae15a2ee34ec857dcf3e45dbfa99ad"}, - {file = "black-24.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f9da3333530dbcecc1be13e69c250ed8dfa67f43c4005fb537bb426e19200d50"}, - {file = "black-24.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4007b1393d902b48b36958a216c20c4482f601569d19ed1df294a496eb366392"}, - {file = "black-24.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:394d4ddc64782e51153eadcaaca95144ac4c35e27ef9b0a42e121ae7e57a9175"}, - {file = "black-24.10.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b5e39e0fae001df40f95bd8cc36b9165c5e2ea88900167bddf258bacef9bbdc3"}, - {file = "black-24.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d37d422772111794b26757c5b55a3eade028aa3fde43121ab7b673d050949d65"}, - {file = "black-24.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:14b3502784f09ce2443830e3133dacf2c0110d45191ed470ecb04d0f5f6fcb0f"}, - {file = "black-24.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:30d2c30dc5139211dda799758559d1b049f7f14c580c409d6ad925b74a4208a8"}, - {file = "black-24.10.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cbacacb19e922a1d75ef2b6ccaefcd6e93a2c05ede32f06a21386a04cedb981"}, - {file = "black-24.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1f93102e0c5bb3907451063e08b9876dbeac810e7da5a8bfb7aeb5a9ef89066b"}, - {file = "black-24.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ddacb691cdcdf77b96f549cf9591701d8db36b2f19519373d60d31746068dbf2"}, - {file = "black-24.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:680359d932801c76d2e9c9068d05c6b107f2584b2a5b88831c83962eb9984c1b"}, - {file = "black-24.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:17374989640fbca88b6a448129cd1745c5eb8d9547b464f281b251dd00155ccd"}, - {file = "black-24.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:63f626344343083322233f175aaf372d326de8436f5928c042639a4afbbf1d3f"}, - {file = "black-24.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfa1d0cb6200857f1923b602f978386a3a2758a65b52e0950299ea014be6800"}, - {file = "black-24.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:2cd9c95431d94adc56600710f8813ee27eea544dd118d45896bb734e9d7a0dc7"}, - {file = "black-24.10.0-py3-none-any.whl", hash = "sha256:3bb2b7a1f7b685f85b11fed1ef10f8a9148bceb49853e47a294a3dd963c1dd7d"}, - {file = "black-24.10.0.tar.gz", hash = "sha256:846ea64c97afe3bc677b761787993be4991810ecc7a4a937816dd6bddedc4875"}, -] - -[package.dependencies] -click = ">=8.0.0" -mypy-extensions = ">=0.4.3" -packaging = ">=22.0" -pathspec = ">=0.9.0" -platformdirs = ">=2" - -[package.extras] -colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.10)"] -jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] -uvloop = ["uvloop (>=0.15.2)"] - -[[package]] -name = "click" -version = "8.1.8" -description = "Composable command line interface toolkit" -optional = false -python-versions = ">=3.7" -files = [ - {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, - {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -files = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] - -[[package]] -name = "flake8" -version = "7.1.1" -description = "the modular source code checker: pep8 pyflakes and co" -optional = false -python-versions = ">=3.8.1" -files = [ - {file = "flake8-7.1.1-py2.py3-none-any.whl", hash = "sha256:597477df7860daa5aa0fdd84bf5208a043ab96b8e96ab708770ae0364dd03213"}, - {file = "flake8-7.1.1.tar.gz", hash = "sha256:049d058491e228e03e67b390f311bbf88fce2dbaa8fa673e7aea87b7198b8d38"}, -] - -[package.dependencies] -mccabe = ">=0.7.0,<0.8.0" -pycodestyle = ">=2.12.0,<2.13.0" -pyflakes = ">=3.2.0,<3.3.0" - -[[package]] -name = "flake8-bugbear" -version = "24.12.12" -description = "A plugin for flake8 finding likely bugs and design problems in your program. Contains warnings that don't belong in pyflakes and pycodestyle." -optional = false -python-versions = ">=3.8.1" -files = [ - {file = "flake8_bugbear-24.12.12-py3-none-any.whl", hash = "sha256:1b6967436f65ca22a42e5373aaa6f2d87966ade9aa38d4baf2a1be550767545e"}, - {file = "flake8_bugbear-24.12.12.tar.gz", hash = "sha256:46273cef0a6b6ff48ca2d69e472f41420a42a46e24b2a8972e4f0d6733d12a64"}, -] - -[package.dependencies] -attrs = ">=22.2.0" -flake8 = ">=6.0.0" - -[package.extras] -dev = ["coverage", "hypothesis", "hypothesmith (>=0.2)", "pre-commit", "pytest", "tox"] - -[[package]] -name = "isort" -version = "5.13.2" -description = "A Python utility / library to sort Python imports." -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, - {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, -] - -[package.extras] -colors = ["colorama (>=0.4.6)"] - -[[package]] -name = "mccabe" -version = "0.7.0" -description = "McCabe checker, plugin for flake8" -optional = false -python-versions = ">=3.6" -files = [ - {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, - {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, -] - [[package]] name = "mypy" version = "1.14.0" @@ -210,66 +63,6 @@ files = [ {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] -[[package]] -name = "packaging" -version = "24.2" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, - {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, -] - -[[package]] -name = "pathspec" -version = "0.12.1" -description = "Utility library for gitignore style pattern matching of file paths." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, - {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, -] - -[[package]] -name = "platformdirs" -version = "4.3.6" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -optional = false -python-versions = ">=3.8" -files = [ - {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, - {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, -] - -[package.extras] -docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] -type = ["mypy (>=1.11.2)"] - -[[package]] -name = "pycodestyle" -version = "2.12.1" -description = "Python style guide checker" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pycodestyle-2.12.1-py2.py3-none-any.whl", hash = "sha256:46f0fb92069a7c28ab7bb558f05bfc0110dac69a0cd23c61ea0040283a9d78b3"}, - {file = "pycodestyle-2.12.1.tar.gz", hash = "sha256:6838eae08bbce4f6accd5d5572075c63626a15ee3e6f842df996bf62f6d73521"}, -] - -[[package]] -name = "pyflakes" -version = "3.2.0" -description = "passive checker of Python programs" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pyflakes-3.2.0-py2.py3-none-any.whl", hash = "sha256:84b5be138a2dfbb40689ca07e2152deb896a65c3a3e24c251c5c62489568074a"}, - {file = "pyflakes-3.2.0.tar.gz", hash = "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f"}, -] - [[package]] name = "typing-extensions" version = "4.12.2" @@ -284,4 +77,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "3c8ab8fb983214158a2f8628056f049759bc453240b3c2dc5524b7a501e3c213" +content-hash = "34a84c9f444021c048be3a70dbb3246bb73c4e7e8f0cc980b8050debcf21a6f9" diff --git a/tools/cru-py/pyproject.toml b/tools/cru-py/pyproject.toml index 76c2d79..15da910 100644 --- a/tools/cru-py/pyproject.toml +++ b/tools/cru-py/pyproject.toml @@ -11,15 +11,11 @@ readme = "README.md" python = "^3.11" [tool.poetry.group.dev.dependencies] -black = "^24.10.0" -isort = "^5.13.2" -flake8 = "^7.1.1" -flake8-bugbear = "^24.10.31" mypy = "^1.13.0" +[tool.ruff.lint] +select = ["E", "F", "B"] + [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" - -[tool.isort] -profile = "black" -- cgit v1.2.3