diff --git a/pyproject.toml b/pyproject.toml index 5124c97d..d878626d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -95,6 +95,7 @@ include = [ "CONTRIBUTING.md", "SECURITY.md", "package", + "subpackages.py", "web.png", ] exclude = [ diff --git a/src/ahriman/application/ahriman.py b/src/ahriman/application/ahriman.py index 63ed92c1..ffd486d8 100644 --- a/src/ahriman/application/ahriman.py +++ b/src/ahriman/application/ahriman.py @@ -105,11 +105,11 @@ def run() -> int: Returns: int: application status code """ - args_parser = _parser() - args = args_parser.parse_args() + parser = _parser() + args = parser.parse_args() if args.command is None: # in case of empty command we would like to print help message - args_parser.exit(status=2, message=args_parser.format_help()) + parser.exit(status=2, message=parser.format_help()) handler: Handler = args.handler return handler.execute(args) diff --git a/src/ahriman/core/utils.py b/src/ahriman/core/utils.py index bf50f9e5..cce8518e 100644 --- a/src/ahriman/core/utils.py +++ b/src/ahriman/core/utils.py @@ -478,7 +478,6 @@ def utcnow() -> datetime.datetime: def walk(directory_path: Path) -> Generator[Path, None, None]: """ list all file paths in given directory - Credits to https://stackoverflow.com/a/64915960 Args: directory_path(Path): root directory path @@ -487,18 +486,13 @@ def walk(directory_path: Path) -> Generator[Path, None, None]: Path: all found files in given directory with full path Examples: - Since the :mod:`pathlib` module does not provide an alternative to :func:`os.walk()`, this wrapper - can be used instead:: + Wrapper around :func:`pathlib.Path.walk`, which emits all files in the directory:: >>> from pathlib import Path >>> >>> for file_path in walk(Path.cwd()): >>> print(file_path) - - Note, however, that unlike the original method, it does not yield directories. """ - for element in directory_path.iterdir(): - if element.is_dir(): - yield from walk(element) - continue - yield element + for root, _, files in directory_path.walk(): + for file in files: + yield root / file diff --git a/subpackages.py b/subpackages.py new file mode 100644 index 00000000..85a022bc --- /dev/null +++ b/subpackages.py @@ -0,0 +1,86 @@ +# +# Copyright (c) 2021-2024 ahriman team. +# +# This file is part of ahriman +# (see https://github.com/arcan1s/ahriman). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +import argparse +import shutil +import site + +from pathlib import Path + + +site_packages = Path(site.getsitepackages()[0]).relative_to("/") +SUBPACKAGES = { + "ahriman": [ + site_packages / "ahriman", + ], + "ahriman-web": [ + site_packages / "ahriman" / "application" / "handlers" / "web.py", + site_packages / "ahriman" / "web", + ], +} + + +def process(root: Path, include: list[Path], exclude: list[Path]) -> None: + """ + remove files based on patterns + + Args: + root(Path): root directory + include(list[Path]): list of files to include to the subpackage + exclude(list[Path]): list of files to exclude from the subpackage + """ + for subdirectory, _, files in root.walk(top_down=False): + for file in files: + full_path = subdirectory / file + relative_path = full_path.relative_to(root) + + if not any(relative_path.is_relative_to(path) for path in include): + full_path.unlink() + elif any(relative_path.is_relative_to(path) for path in exclude): + full_path.unlink() + + content = list(subdirectory.iterdir()) + if not content: + shutil.rmtree(subdirectory) + + +def run() -> None: + """ + run application + """ + parser = argparse.ArgumentParser(description="Split package into subpackages") + parser.add_argument("root", help="package root", type=Path) + parser.add_argument("subpackage", help="subpackage name", choices=SUBPACKAGES.keys()) + + args = parser.parse_args() + + include = SUBPACKAGES[args.subpackage] + exclude = [ + path + for subpackage, portion in SUBPACKAGES.items() + if subpackage != args.subpackage + for path in portion + if not any(include_path.is_relative_to(path) for include_path in include) + ] + + process(args.root, include, exclude) + + +if __name__ == "__main__": + run()