From 92c984f4264e0843bd2f939fbb1359dc2f4bbfeb Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Tue, 27 Feb 2024 16:00:34 +0100 Subject: [PATCH] use pathlib --- src/mxmake/hook.py | 14 +++++----- src/mxmake/main.py | 8 +++--- src/mxmake/parser.py | 6 ++--- src/mxmake/templates.py | 41 +++++++++++++++--------------- src/mxmake/testing/__init__.py | 9 ++++--- src/mxmake/tests/test_hook.py | 7 +++-- src/mxmake/tests/test_parser.py | 3 +-- src/mxmake/tests/test_templates.py | 40 ++++++++++++++--------------- src/mxmake/tests/test_utils.py | 9 ++++--- src/mxmake/utils.py | 15 +++++++---- 10 files changed, 77 insertions(+), 75 deletions(-) diff --git a/src/mxmake/hook.py b/src/mxmake/hook.py index dc77999a..1c1c9206 100644 --- a/src/mxmake/hook.py +++ b/src/mxmake/hook.py @@ -3,10 +3,10 @@ from mxmake.utils import list_value from mxmake.utils import NAMESPACE from mxmake.utils import ns_name +from pathlib import Path import logging import mxdev -import os logger = logging.getLogger("mxmake") @@ -46,17 +46,15 @@ def generate_templates(self, state: mxdev.State): def generate_additional_sources_targets(self, state: mxdev.State): config = state.configuration additional_sources_targets = [] - sources_folder = config.settings.get("default-target", "sources") + sources_folder = Path(config.settings.get("default-target", "sources")) for package_name in config.packages: - source_folder = os.path.join(sources_folder, package_name) + source_folder = sources_folder / package_name # case new source package has been added to mx.ini - if not os.path.exists(source_folder): + if not source_folder.exists(): continue - for child in os.listdir(source_folder): + for child in source_folder.listdir(): if child in ADDITIONAL_SOURCES_TARGETS: - additional_sources_targets.append( - os.path.join(source_folder, child) - ) + additional_sources_targets.append(source_folder / child) if not additional_sources_targets: return environment = get_template_environment() diff --git a/src/mxmake/main.py b/src/mxmake/main.py index f95d2965..8b57334f 100644 --- a/src/mxmake/main.py +++ b/src/mxmake/main.py @@ -9,13 +9,13 @@ from mxmake.topics import resolve_domain_dependencies from mxmake.topics import set_domain_runtime_depends from operator import attrgetter +from pathlib import Path from textwrap import indent import argparse import inquirer import logging import mxdev -import os import sys @@ -99,10 +99,10 @@ def init_command(args: argparse.Namespace): print("#######################\n") # obtain target folder - target_folder = os.getcwd() + target_folder = Path.cwd() # parse existing makefile - parser = MakefileParser(os.path.join(target_folder, "Makefile")) + parser = MakefileParser(target_folder / "Makefile") # obtain topics to include topics = load_topics() @@ -186,7 +186,7 @@ def init_command(args: argparse.Namespace): print("Skip generation of Makefile, nothing selected") # mx ini generation - if not os.path.exists(os.path.join(target_folder, "mx.ini")): + if not (target_folder / "mx.ini").exists(): print("\n``mx.ini`` configuration file not exists. Create One?") yn = inquirer.text(message="Y/n") if yn not in ["n", "N"]: diff --git a/src/mxmake/parser.py b/src/mxmake/parser.py index 600cde9d..db85e832 100644 --- a/src/mxmake/parser.py +++ b/src/mxmake/parser.py @@ -1,6 +1,6 @@ from mxmake.topics import get_domain -import os +import pathlib import typing @@ -11,7 +11,7 @@ class SettingMissing(Exception): class MakefileParser: - def __init__(self, path: str): + def __init__(self, path: pathlib.Path): self.path = path self.fqns: typing.List = [] self.topics: typing.Dict = {} @@ -61,7 +61,7 @@ def parse_setting(self, lines: typing.List[str], name: str) -> str: return value def parse(self) -> None: - if not os.path.exists(self.path): + if not self.path.exists(): return with open(self.path) as fd: lines = [line.rstrip() for line in fd.readlines() if line.strip()] diff --git a/src/mxmake/templates.py b/src/mxmake/templates.py index df2c2e40..401498b3 100644 --- a/src/mxmake/templates.py +++ b/src/mxmake/templates.py @@ -5,11 +5,11 @@ from mxmake.utils import gh_actions_path from mxmake.utils import mxmake_files from mxmake.utils import ns_name +from pathlib import Path import abc import io import mxdev -import os import typing @@ -58,7 +58,7 @@ def __init__( self.environment = environment @abc.abstractproperty - def target_folder(self) -> str: + def target_folder(self) -> Path: """Target folder for rendered template.""" @abc.abstractproperty @@ -78,20 +78,21 @@ def write(self) -> None: if not self.environment: raise RuntimeError("Cannot write template without environment") target_folder = self.target_folder - os.makedirs(target_folder, exist_ok=True) - target_path = os.path.join(target_folder, self.target_name) + target_folder.mkdir(exist_ok=True) + target_path = target_folder / self.target_name template = self.environment.get_template(self.template_name) with open(target_path, "w") as f: f.write(template.render(**self.template_variables)) - os.chmod(target_path, self.file_mode) + target_path.chmod(self.file_mode) def remove(self) -> bool: """Remove rendered template if exists. Return bool if file existed.""" - target_path = os.path.join(self.target_folder, self.target_name) - if os.path.exists(target_path): - os.remove(target_path) - return True - return False + target_path = self.target_folder / self.target_name + try: + target_path.unlink() + except FileNotFoundError: + return False + return True class MxIniBoundTemplate(Template): @@ -141,7 +142,7 @@ def test_runner(self): return self.config.settings.get("mxmake-test-runner", "pytest") @property - def target_folder(self) -> str: + def target_folder(self) -> Path: return mxmake_files() @property @@ -208,7 +209,7 @@ class PipConf(MxIniBoundTemplate): template_name: str = "pip.conf" @property - def target_folder(self) -> str: + def target_folder(self) -> Path: return mxmake_files() @property @@ -232,11 +233,11 @@ class Makefile(Template): description: str = "Makefile" target_name = "Makefile" template_name = "Makefile" - target_folder = "" + target_folder = Path() def __init__( self, - target_folder: str, + target_folder: Path, domains: typing.List[Domain], domain_settings: typing.Dict[str, str], environment: typing.Union[Environment, None] = None, @@ -306,7 +307,7 @@ def __init__( self.additional_sources_targets = additional_sources_targets @property - def target_folder(self) -> str: + def target_folder(self) -> Path: return mxmake_files() @property @@ -324,11 +325,11 @@ class MxIni(Template): description: str = "mx configutation file" target_name = "mx.ini" template_name = "mx.ini" - target_folder = "" + target_folder = Path() def __init__( self, - target_folder: str, + target_folder: Path, domains: typing.List[Domain], environment: typing.Union[Environment, None] = None, ) -> None: @@ -357,7 +358,7 @@ class Topics(Template): description: str = "Topics documentation for sphinx" target_name = "" template_name = "topics.md" - target_folder = "" + target_folder = Path() @property def template_variables(self) -> typing.Dict[str, typing.Any]: @@ -386,7 +387,7 @@ class Dependencies(Template): description: str = "Dependencies documentation for sphinx" target_name = "" template_name = "dependencies.md" - target_folder = "" + target_folder = Path() @property def template_variables(self) -> typing.Dict[str, typing.Any]: @@ -426,7 +427,7 @@ class GHActionsTemplate(Template): template_variables = dict() @property - def target_folder(self) -> str: + def target_folder(self) -> Path: return gh_actions_path() diff --git a/src/mxmake/testing/__init__.py b/src/mxmake/testing/__init__.py index 3aaa88e3..3c3e6b87 100644 --- a/src/mxmake/testing/__init__.py +++ b/src/mxmake/testing/__init__.py @@ -4,6 +4,7 @@ import doctest import mxdev import os +import pathlib import shutil import tempfile import typing @@ -11,7 +12,7 @@ def temp_directory(fn): - tempdir = tempfile.mkdtemp() + tempdir = pathlib.Path(tempfile.mkdtemp()) def wrapper(self): try: @@ -38,9 +39,9 @@ def __init__(self, reset_registry: bool = False): def __call__(self, fn: typing.Callable): def wrapper(*a): - tempdir = tempfile.mkdtemp() - os.environ["MXMAKE_FILES"] = tempdir - os.environ["MXMAKE_GH_ACTIONS_PATH"] = tempdir + tempdir = pathlib.Path(tempfile.mkdtemp()) + os.environ["MXMAKE_FILES"] = str(tempdir) + os.environ["MXMAKE_GH_ACTIONS_PATH"] = str(tempdir) try: if self.reset_registry: with reset_template_registry(): diff --git a/src/mxmake/tests/test_hook.py b/src/mxmake/tests/test_hook.py index 13238f22..e7cf355f 100644 --- a/src/mxmake/tests/test_hook.py +++ b/src/mxmake/tests/test_hook.py @@ -2,15 +2,13 @@ from mxmake import testing import mxdev -import os -import pathlib import unittest class TestHook(unittest.TestCase): @testing.template_directory() def test_Hook(self, tempdir): - mxini = pathlib.Path(tempdir, "mx.ini") + mxini = tempdir / "mx.ini" with mxini.open("w") as fd: fd.write( "[settings]\n" "mxmake-templates = run-tests run-coverage inexistent" @@ -21,5 +19,6 @@ def test_Hook(self, tempdir): state = mxdev.State(configuration=configuration) hook_.write(state) self.assertEqual( - sorted(os.listdir(tempdir)), ["mx.ini", "run-coverage.sh", "run-tests.sh"] + [entry.name for entry in sorted(tempdir.iterdir())], + ["mx.ini", "run-coverage.sh", "run-tests.sh"], ) diff --git a/src/mxmake/tests/test_parser.py b/src/mxmake/tests/test_parser.py index 2d0b136a..50b7d6dc 100644 --- a/src/mxmake/tests/test_parser.py +++ b/src/mxmake/tests/test_parser.py @@ -3,7 +3,6 @@ from mxmake import testing from mxmake import topics -import os import unittest @@ -37,7 +36,7 @@ def test_MakefileParser(self, tempdir): template.write() - makefile_path = os.path.join(tempdir, "Makefile") + makefile_path = tempdir / "Makefile" makefile_parser = parser.MakefileParser(makefile_path) self.assertEqual( diff --git a/src/mxmake/tests/test_templates.py b/src/mxmake/tests/test_templates.py index 70236a4e..e7bfefe1 100644 --- a/src/mxmake/tests/test_templates.py +++ b/src/mxmake/tests/test_templates.py @@ -5,10 +5,9 @@ from mxmake import testing from mxmake import topics from mxmake import utils +from pathlib import Path import mxdev -import os -import pathlib import typing @@ -44,7 +43,7 @@ class Template(templates.Template): ) @testing.template_directory() - def test_Template(self, tempdir: str): + def test_Template(self, tempdir: Path): # cannot instantiate abstract template with self.assertRaises(TypeError): templates.Template() # type: ignore @@ -63,12 +62,12 @@ class Template(templates.Template): template.write() # write template - with open(os.path.join(tempdir, "target.in"), "w") as f: + with (tempdir / "target.in").open("w") as f: f.write("{{ param }}") environment = Environment(loader=FileSystemLoader(tempdir)) template = Template(environment) template.write() - with open(os.path.join(tempdir, "target.out")) as f: + with (tempdir / "target.out").open() as f: self.assertEqual(f.read(), "value") # check file mode @@ -78,7 +77,7 @@ class Template(templates.Template): # remove remplate removed = template.remove() self.assertTrue(removed) - self.assertFalse(os.path.exists(os.path.join(tempdir, "target.out"))) + self.assertFalse((tempdir / "target.out").exists()) self.assertFalse(template.remove()) @testing.template_directory() @@ -86,7 +85,7 @@ def test_MxIniBoundTemplate(self, tempdir: str): # create test template class Template(templates.MxIniBoundTemplate): name = "template" - target_folder = "" + target_folder = Path() target_name = "" template_name = "" template_variables = {} @@ -120,7 +119,7 @@ class Template(templates.EnvironmentTemplate): @testing.template_directory() def test_TestScript(self, tempdir): - mxini = pathlib.Path(tempdir, "mx.ini") + mxini = tempdir / "mx.ini" with mxini.open("w") as fd: fd.write( "[settings]\n" @@ -158,7 +157,7 @@ def test_TestScript(self, tempdir): ) template.write() - with open(os.path.join(tempdir, "run-tests.sh")) as f: + with (tempdir / "run-tests.sh").open() as f: self.checkOutput( """ #!/usr/bin/env bash @@ -202,7 +201,7 @@ def test_TestScript(self, tempdir): configuration = mxdev.Configuration(mxini, hooks=[hook.Hook()]) template = factory(configuration, templates.get_template_environment()) template.write() - with open(os.path.join(tempdir, "run-tests.sh")) as f: + with (tempdir / "run-tests.sh").open() as f: self.checkOutput( """ #!/usr/bin/env bash @@ -234,7 +233,7 @@ def test_TestScript(self, tempdir): configuration = mxdev.Configuration(mxini, hooks=[hook.Hook()]) template = factory(configuration, templates.get_template_environment()) template.write() - with open(os.path.join(tempdir, "run-tests.sh")) as f: + with (tempdir / "run-tests.sh").open() as f: self.checkOutput( """ #!/usr/bin/env bash @@ -255,7 +254,7 @@ def test_TestScript(self, tempdir): @testing.template_directory() def test_CoverageScript(self, tempdir): - mxini = pathlib.Path(tempdir, "mx.ini") + mxini = tempdir / "mx.ini" with mxini.open("w") as fd: fd.write( "[settings]\n" @@ -321,7 +320,7 @@ def test_CoverageScript(self, tempdir): ) template.write() - with open(os.path.join(tempdir, "run-coverage.sh")) as f: + with (tempdir / "run-coverage.sh").open() as f: self.checkOutput( """ #!/usr/bin/env bash @@ -388,7 +387,7 @@ def test_CoverageScript(self, tempdir): configuration = mxdev.Configuration(mxini, hooks=[hook.Hook()]) template = factory(configuration, templates.get_template_environment()) template.write() - with open(os.path.join(tempdir, "run-coverage.sh")) as f: + with (tempdir / "run-coverage.sh").open() as f: self.checkOutput( """ #!/usr/bin/env bash @@ -433,7 +432,7 @@ def test_CoverageScript(self, tempdir): configuration = mxdev.Configuration(mxini, hooks=[hook.Hook()]) template = factory(configuration, templates.get_template_environment()) template.write() - with open(os.path.join(tempdir, "run-coverage.sh")) as f: + with (tempdir / "run-coverage.sh").open() as f: self.checkOutput( """ #!/usr/bin/env bash @@ -467,7 +466,7 @@ def test_CoverageScript(self, tempdir): @testing.template_directory() def test_PipConf(self, tempdir): - mxini = pathlib.Path(tempdir, "mx.ini") + mxini = tempdir / "mx.ini" with mxini.open("w") as fd: fd.write( "[settings]\n" @@ -492,7 +491,7 @@ def test_PipConf(self, tempdir): ) template.write() - with open(os.path.join(tempdir, "pip.conf")) as f: + with (tempdir / "pip.conf").open() as f: self.checkOutput( """ [global] @@ -509,8 +508,7 @@ def test_AdditionalSourcesTargets(self, tempdir): template = factory(["a", "b"], templates.get_template_environment()) template.write() - path = os.path.join(tempdir, "additional_sources_targets.mk") - with open(path) as f: + with (tempdir / "additional_sources_targets.mk").open() as f: self.checkOutput("ADDITIONAL_SOURCES_TARGETS=$(wildcard a b)", f.read()) @testing.temp_directory @@ -540,7 +538,7 @@ def test_Makefile(self, tempdir): ) template.write() - with open(os.path.join(tempdir, "Makefile")) as f: + with (tempdir / "Makefile").open() as f: self.checkOutput( """ ############################################################################## @@ -798,7 +796,7 @@ def test_MxIni(self, tempdir): template = factory(tempdir, domains, templates.get_template_environment()) template.write() - with open(os.path.join(tempdir, "mx.ini")) as f: + with (tempdir / "mx.ini").open() as f: self.checkOutput( """ [settings] diff --git a/src/mxmake/tests/test_utils.py b/src/mxmake/tests/test_utils.py index 87e7b2e6..557fac2f 100644 --- a/src/mxmake/tests/test_utils.py +++ b/src/mxmake/tests/test_utils.py @@ -1,4 +1,5 @@ from mxmake import utils +from pathlib import Path import os import unittest @@ -9,15 +10,15 @@ def test_namespace(self): self.assertEqual(utils.NAMESPACE, "mxmake-") def test_mxmake_files(self): - self.assertEqual(utils.mxmake_files(), os.path.join(".mxmake", "files")) + self.assertEqual(utils.mxmake_files(), Path(".mxmake") / "files") os.environ["MXMAKE_FILES"] = "other" - self.assertEqual(utils.mxmake_files(), "other") + self.assertEqual(utils.mxmake_files(), Path("other")) del os.environ["MXMAKE_FILES"] def test_gh_actions_path(self): - self.assertEqual(utils.gh_actions_path(), os.path.join(".github", "workflows")) + self.assertEqual(utils.gh_actions_path(), Path(".github") / "workflows") os.environ["MXMAKE_GH_ACTIONS_PATH"] = "other" - self.assertEqual(utils.gh_actions_path(), "other") + self.assertEqual(utils.gh_actions_path(), Path("other")) del os.environ["MXMAKE_GH_ACTIONS_PATH"] def test_ns_name(self): diff --git a/src/mxmake/utils.py b/src/mxmake/utils.py index c10ac342..b6c30e88 100644 --- a/src/mxmake/utils.py +++ b/src/mxmake/utils.py @@ -1,3 +1,5 @@ +from pathlib import Path + import os import typing @@ -5,15 +7,18 @@ NAMESPACE = "mxmake-" -def mxmake_files() -> str: +def mxmake_files() -> Path: """Target folder for mxmake related file generation.""" - return os.environ.get("MXMAKE_FILES", os.path.join(".mxmake", "files")) + return Path(os.environ.get("MXMAKE_FILES", Path(".mxmake") / "files")) -def gh_actions_path() -> str: +def gh_actions_path() -> Path: """Target folder for github actions related file generation.""" - return os.environ.get( - "MXMAKE_GH_ACTIONS_PATH", os.path.join(".github", "workflows") + return Path( + os.environ.get( + "MXMAKE_GH_ACTIONS_PATH", + Path(".github") / "workflows", + ) )