diff options
| author | crupest <crupest@outlook.com> | 2024-11-11 01:12:29 +0800 | 
|---|---|---|
| committer | Yuqian Yang <crupest@crupest.life> | 2025-01-07 21:38:21 +0800 | 
| commit | 149760a315b6724577e279b4ef5264d992f637a2 (patch) | |
| tree | 398740ccf1ee9b079c6357694385d0da08547807 | |
| parent | 633fef27cb149d94fa2e819e8bd04a4f6a872ec3 (diff) | |
| download | crupest-149760a315b6724577e279b4ef5264d992f637a2.tar.gz crupest-149760a315b6724577e279b4ef5264d992f637a2.tar.bz2 crupest-149760a315b6724577e279b4ef5264d992f637a2.zip | |
HALF WORK: 2024.1.7
| -rw-r--r-- | crupest-words.txt | 5 | ||||
| -rw-r--r-- | tools/cru-py/.flake8 | 4 | ||||
| -rw-r--r-- | tools/cru-py/cru/service/_base.py | 1 | ||||
| -rw-r--r-- | tools/cru-py/cru/service/_config.py | 4 | ||||
| -rw-r--r-- | tools/cru-py/cru/service/_template.py | 54 | ||||
| -rw-r--r-- | tools/cru-py/cru/template.py | 135 | ||||
| -rw-r--r-- | tools/cru-py/poetry.lock | 209 | ||||
| -rw-r--r-- | tools/cru-py/pyproject.toml | 10 | 
8 files changed, 108 insertions, 314 deletions
| 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,153 +1,6 @@  # 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"
  description = "Optional static typing for Python"
 @@ -211,66 +64,6 @@ files = [  ]
  [[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"
  description = "Backported and Experimental Type Hints for Python 3.8+"
 @@ -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" | 
