From b0da6f82d3c632f0b932e52f447b8da51951dbf9 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Fri, 8 Mar 2024 23:46:19 +0200 Subject: [PATCH 1/7] Fix import formatting Signed-off-by: Povilas Kanapickas --- examples/hello-python/app/web.py | 2 +- podman_compose.py | 21 ++++++++++----------- pytests/test_can_merge_build.py | 10 ++++++---- pytests/test_can_merge_cmd_ent.py | 9 ++++++--- pytests/test_normalize_final_build.py | 13 ++++++------- setup.py | 1 + tests/test_podman_compose.py | 3 ++- tests/test_podman_compose_config.py | 6 ++++-- tests/test_podman_compose_include.py | 3 +-- tests/test_podman_compose_tests.py | 1 - tests/test_podman_compose_up_down.py | 6 ++++-- 11 files changed, 41 insertions(+), 34 deletions(-) diff --git a/examples/hello-python/app/web.py b/examples/hello-python/app/web.py index 3008e692..6173ab71 100644 --- a/examples/hello-python/app/web.py +++ b/examples/hello-python/app/web.py @@ -1,7 +1,7 @@ # pylint: disable=import-error # pylint: disable=unused-import -import os import asyncio # noqa: F401 +import os import aioredis from aiohttp import web diff --git a/podman_compose.py b/podman_compose.py index e41008a8..9556ad3d 100755 --- a/podman_compose.py +++ b/podman_compose.py @@ -7,21 +7,20 @@ # https://docs.docker.com/compose/django/ # https://docs.docker.com/compose/wordpress/ # TODO: podman pod logs --color -n -f pod_testlogs -import sys -import os -import getpass import argparse -import itertools -import subprocess -import re +import asyncio.subprocess +import getpass +import glob import hashlib -import random +import itertools import json -import glob -import asyncio.subprocess -import signal - +import os +import random +import re import shlex +import signal +import subprocess +import sys from asyncio import Task try: diff --git a/pytests/test_can_merge_build.py b/pytests/test_can_merge_build.py index 86a019bb..2519da76 100644 --- a/pytests/test_can_merge_build.py +++ b/pytests/test_can_merge_build.py @@ -1,12 +1,14 @@ # SPDX-License-Identifier: GPL-2.0 -import copy -import os import argparse -import yaml +import os import unittest + +import yaml from parameterized import parameterized -from podman_compose import normalize_service, PodmanCompose + +from podman_compose import PodmanCompose +from podman_compose import normalize_service class TestMergeBuild(unittest.TestCase): diff --git a/pytests/test_can_merge_cmd_ent.py b/pytests/test_can_merge_cmd_ent.py index 2a3295de..973a6911 100644 --- a/pytests/test_can_merge_cmd_ent.py +++ b/pytests/test_can_merge_cmd_ent.py @@ -1,12 +1,15 @@ # SPDX-License-Identifier: GPL-2.0 +import argparse import copy import os -import argparse -import yaml import unittest + +import yaml from parameterized import parameterized -from podman_compose import normalize_service, PodmanCompose + +from podman_compose import PodmanCompose +from podman_compose import normalize_service test_keys = ["command", "entrypoint"] diff --git a/pytests/test_normalize_final_build.py b/pytests/test_normalize_final_build.py index 6915bbe3..98d3ad7c 100644 --- a/pytests/test_normalize_final_build.py +++ b/pytests/test_normalize_final_build.py @@ -2,16 +2,15 @@ # pylint: disable=protected-access import argparse -import copy import os -import yaml import unittest + +import yaml from parameterized import parameterized -from podman_compose import ( - normalize_final, - normalize_service_final, - PodmanCompose, -) + +from podman_compose import PodmanCompose +from podman_compose import normalize_final +from podman_compose import normalize_service_final cwd = os.path.abspath(".") diff --git a/setup.py b/setup.py index 56082e0d..8f7a4e9b 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 import os + from setuptools import setup try: diff --git a/tests/test_podman_compose.py b/tests/test_podman_compose.py index 999e2aaa..1128730f 100644 --- a/tests/test_podman_compose.py +++ b/tests/test_podman_compose.py @@ -1,8 +1,9 @@ # SPDX-License-Identifier: GPL-2.0 -from pathlib import Path import os import unittest +from pathlib import Path + from .test_utils import RunSubprocessMixin diff --git a/tests/test_podman_compose_config.py b/tests/test_podman_compose_config.py index ef383b23..1b860ff2 100644 --- a/tests/test_podman_compose_config.py +++ b/tests/test_podman_compose_config.py @@ -8,11 +8,13 @@ # pylint: disable=redefined-outer-name import os +import unittest + +from parameterized import parameterized + from .test_podman_compose import podman_compose_path from .test_podman_compose import test_path from .test_utils import RunSubprocessMixin -import unittest -from parameterized import parameterized def profile_compose_file(): diff --git a/tests/test_podman_compose_include.py b/tests/test_podman_compose_include.py index 5ca3964b..5b5044cd 100644 --- a/tests/test_podman_compose_include.py +++ b/tests/test_podman_compose_include.py @@ -1,8 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 -from pathlib import Path -import subprocess import unittest +from pathlib import Path from .test_utils import RunSubprocessMixin diff --git a/tests/test_podman_compose_tests.py b/tests/test_podman_compose_tests.py index 2f4b4d98..e4383b5c 100644 --- a/tests/test_podman_compose_tests.py +++ b/tests/test_podman_compose_tests.py @@ -8,7 +8,6 @@ # pylint: disable=redefined-outer-name import os -import time import unittest from .test_podman_compose import podman_compose_path diff --git a/tests/test_podman_compose_up_down.py b/tests/test_podman_compose_up_down.py index f7c3880e..6db820dd 100644 --- a/tests/test_podman_compose_up_down.py +++ b/tests/test_podman_compose_up_down.py @@ -8,11 +8,13 @@ # pylint: disable=redefined-outer-name import os +import unittest + +from parameterized import parameterized + from .test_podman_compose import podman_compose_path from .test_podman_compose import test_path from .test_utils import RunSubprocessMixin -from parameterized import parameterized -import unittest def profile_compose_file(): From 36139fb28266e93ab0b922a6dbf6e6526726f8af Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Fri, 8 Mar 2024 23:46:20 +0200 Subject: [PATCH 2/7] Remove unused f-string Signed-off-by: Povilas Kanapickas --- podman_compose.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/podman_compose.py b/podman_compose.py index 9556ad3d..370f7917 100755 --- a/podman_compose.py +++ b/podman_compose.py @@ -1207,7 +1207,7 @@ async def format_out(stdout): async with asyncio.timeout(10): exit_code = await p.wait() except TimeoutError: - log(f"container did not shut down after 10 seconds, killing") + log("container did not shut down after 10 seconds, killing") p.kill() exit_code = await p.wait() From 59a1fa3942d957941921bc73bd514baca1c9fe5e Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Fri, 8 Mar 2024 23:46:21 +0200 Subject: [PATCH 3/7] Use 'not in' for membership test Signed-off-by: Povilas Kanapickas --- podman_compose.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/podman_compose.py b/podman_compose.py index 370f7917..6d8ce6a0 100755 --- a/podman_compose.py +++ b/podman_compose.py @@ -1100,7 +1100,7 @@ def flat_deps(services, with_extends=False): for c in links_ls: if ":" in c: dep_name, dep_alias = c.split(":") - if not "_aliases" in services[dep_name]: + if "_aliases" not in services[dep_name]: services[dep_name]["_aliases"] = set() services[dep_name]["_aliases"].add(dep_alias) for name, srv in services.items(): From a6e009262788e11c8ed17bd029ce774d487dc98a Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Fri, 8 Mar 2024 23:46:22 +0200 Subject: [PATCH 4/7] Remove unused variable Signed-off-by: Povilas Kanapickas --- podman_compose.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/podman_compose.py b/podman_compose.py index 6d8ce6a0..29ba63e3 100755 --- a/podman_compose.py +++ b/podman_compose.py @@ -1200,8 +1200,8 @@ async def format_out(stdout): try: exit_code = await p.wait() - except asyncio.CancelledError as e: - log(f"Sending termination signal") + except asyncio.CancelledError: + log("Sending termination signal") p.terminate() try: async with asyncio.timeout(10): From 91052cb2d94ccc6b1ed3bfb82d14dd1d6ba71a8c Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Fri, 8 Mar 2024 23:46:23 +0200 Subject: [PATCH 5/7] Fix ambiguous variable name Signed-off-by: Povilas Kanapickas --- podman_compose.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/podman_compose.py b/podman_compose.py index 29ba63e3..42545756 100755 --- a/podman_compose.py +++ b/podman_compose.py @@ -1175,9 +1175,9 @@ async def run( async def format_out(stdout): while True: - l = await stdout.readline() - if l: - print(log_formatter, l.decode('utf-8'), end='') + line = await stdout.readline() + if line: + print(log_formatter, line.decode('utf-8'), end='') if stdout.at_eof(): break From 4e43606df3d5faa9fa8c814dfb2dbb344fee23e9 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Fri, 8 Mar 2024 23:46:24 +0200 Subject: [PATCH 6/7] Shorten too long lines Signed-off-by: Povilas Kanapickas --- podman_compose.py | 46 ++++++++++++++++++---------- tests/test_podman_compose.py | 4 +-- tests/test_podman_compose_config.py | 4 +-- tests/test_podman_compose_tests.py | 4 +-- tests/test_podman_compose_up_down.py | 3 +- 5 files changed, 37 insertions(+), 24 deletions(-) diff --git a/podman_compose.py b/podman_compose.py index 42545756..603bc778 100755 --- a/podman_compose.py +++ b/podman_compose.py @@ -125,7 +125,8 @@ def str_to_seconds(txt): mins = int(mins) if mins else 0 sec = float(sec) if sec else 0 # "podman stop" takes only int - # Error: invalid argument "3.0" for "-t, --time" flag: strconv.ParseUint: parsing "3.0": invalid syntax + # Error: invalid argument "3.0" for "-t, --time" flag: strconv.ParseUint: parsing "3.0": + # invalid syntax return int(mins * 60.0 + sec) @@ -388,7 +389,8 @@ async def assert_volume(compose, mount_dict): is_ext = vol.get("external", None) log(f"podman volume inspect {vol_name} || podman volume create {vol_name}") # TODO: might move to using "volume list" - # podman volume list --format '{{.Name}}\t{{.MountPoint}}' -f 'label=io.podman.compose.project=HERE' + # podman volume list --format '{{.Name}}\t{{.MountPoint}}' \ + # -f 'label=io.podman.compose.project=HERE' try: _ = (await compose.podman.output([], "volume", ["inspect", vol_name])).decode("utf-8") except subprocess.CalledProcessError as e: @@ -583,7 +585,10 @@ def get_secret_args(compose, cnt, secret): # having a custom name for the external secret # has the same problem as well ext_name = declared_secret.get("name", None) - err_str = 'ERROR: Custom name/target reference "{}" for mounted external secret "{}" is not supported' + err_str = ( + 'ERROR: Custom name/target reference "{}" ' + 'for mounted external secret "{}" is not supported' + ) if ext_name and ext_name != secret_name: raise ValueError(err_str.format(secret_name, ext_name)) if target and target != secret_name: @@ -1527,7 +1532,8 @@ def _parse_compose_file(self): files = args.file if not files: log( - "no compose.yaml, docker-compose.yml or container-compose.yml file found, pass files with -f" + "no compose.yaml, docker-compose.yml or container-compose.yml file found, " + "pass files with -f" ) sys.exit(-1) ex = map(os.path.exists, files) @@ -1617,7 +1623,8 @@ def _parse_compose_file(self): if not project_name: project_name = compose.get("name", None) if project_name is None: - # More strict then actually needed for simplicity: podman requires [a-zA-Z0-9][a-zA-Z0-9_.-]* + # More strict then actually needed for simplicity: + # podman requires [a-zA-Z0-9][a-zA-Z0-9_.-]* project_name = ( self.environ.get("COMPOSE_PROJECT_NAME", None) or dir_basename.lower() ) @@ -1740,11 +1747,11 @@ def _parse_compose_file(self): def _resolve_profiles(self, defined_services, requested_profiles=None): """ - Returns a service dictionary (key = service name, value = service config) compatible with the requested_profiles - list. + Returns a service dictionary (key = service name, value = service config) compatible with + the requested_profiles list. - The returned service dictionary contains all services which do not include/reference a profile in addition to - services that match the requested_profiles. + The returned service dictionary contains all services which do not include/reference a + profile in addition to services that match the requested_profiles. :param defined_services: The service dictionary :param requested_profiles: The profiles requested using the --profile arg. @@ -2255,8 +2262,9 @@ async def compose_up(compose: PodmanCompose, args): done, tasks = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED) if args.abort_on_container_exit: if not exiting: - # If 2 containers exit at the exact same time, the cancellation of the other ones cause the status - # to overwrite. Sleeping for 1 seems to fix this and make it match docker-compose + # If 2 containers exit at the exact same time, the cancellation of the other ones + # cause the status to overwrite. Sleeping for 1 seems to fix this and make it match + # docker-compose await asyncio.sleep(1) [_.cancel() for _ in tasks if not _.cancelling() and not _.cancelled()] t: Task @@ -2726,7 +2734,8 @@ def compose_up_parse(parser): parser.add_argument( "--no-recreate", action="store_true", - help="If containers already exist, don't recreate them. Incompatible with --force-recreate and -V.", + help="If containers already exist, don't recreate them. Incompatible with --force-recreate " + "and -V.", ) parser.add_argument( "--no-build", @@ -2751,8 +2760,8 @@ def compose_up_parse(parser): "--timeout", type=int, default=None, - help="Use this timeout in seconds for container shutdown when attached or when containers are already running. \ - (default: 10)", + help="Use this timeout in seconds for container shutdown when attached or when containers " + "are already running. (default: 10)", ) parser.add_argument( "-V", @@ -2769,14 +2778,16 @@ def compose_up_parse(parser): "--scale", metavar="SERVICE=NUM", action="append", - help="Scale SERVICE to NUM instances. Overrides the `scale` setting in the Compose file if present.", + help="Scale SERVICE to NUM instances. Overrides the `scale` setting in the Compose file if " + "present.", ) parser.add_argument( "--exit-code-from", metavar="SERVICE", type=str, default=None, - help="Return the exit code of the selected service container. Implies --abort-on-container-exit.", + help="Return the exit code of the selected service container. " + "Implies --abort-on-container-exit.", ) @@ -3018,7 +3029,8 @@ def compose_build_up_parse(parser): ) parser.add_argument( "--pull-always", - help="attempt to pull a newer version of the image, Raise an error even if the image is present locally.", + help="attempt to pull a newer version of the image, Raise an error even if the image is " + "present locally.", action="store_true", ) parser.add_argument( diff --git a/tests/test_podman_compose.py b/tests/test_podman_compose.py index 1128730f..1ad0d6e1 100644 --- a/tests/test_podman_compose.py +++ b/tests/test_podman_compose.py @@ -78,8 +78,8 @@ def test_extends_w_file_subdir(self): def test_extends_w_empty_service(self): """ Test that podman-compose can execute podman-compose -f up with extended File which - includes an empty service. (e.g. if the file is used as placeholder for more complex configurations.) - :return: + includes an empty service. (e.g. if the file is used as placeholder for more complex + configurations.) """ main_path = Path(__file__).parent.parent diff --git a/tests/test_podman_compose_config.py b/tests/test_podman_compose_config.py index 1b860ff2..e72045a9 100644 --- a/tests/test_podman_compose_config.py +++ b/tests/test_podman_compose_config.py @@ -63,8 +63,8 @@ def test_config_profiles(self, profiles, expected_services): """ Tests podman-compose :param profiles: The enabled profiles for the parameterized test. - :param expected_services: Dictionary used to model the expected "enabled" services in the profile. - Key = service name, Value = True if the service is enabled, otherwise False. + :param expected_services: Dictionary used to model the expected "enabled" services in the + profile. Key = service name, Value = True if the service is enabled, otherwise False. """ config_cmd = ["coverage", "run", podman_compose_path(), "-f", profile_compose_file()] config_cmd.extend(profiles) diff --git a/tests/test_podman_compose_tests.py b/tests/test_podman_compose_tests.py index e4383b5c..36d56f59 100644 --- a/tests/test_podman_compose_tests.py +++ b/tests/test_podman_compose_tests.py @@ -50,8 +50,8 @@ def test_run(self): out, _ = self.run_subprocess_assert_returncode(run_cmd) self.assertIn(b'127.0.0.1\tlocalhost', out) - # Run it again to make sure we can run it twice. I saw an issue where a second run, with the container left up, - # would fail + # Run it again to make sure we can run it twice. I saw an issue where a second run, with + # the container left up, would fail run_cmd = [ "coverage", "run", diff --git a/tests/test_podman_compose_up_down.py b/tests/test_podman_compose_up_down.py index 6db820dd..93b92fdd 100644 --- a/tests/test_podman_compose_up_down.py +++ b/tests/test_podman_compose_up_down.py @@ -25,7 +25,8 @@ def profile_compose_file(): class TestUpDown(unittest.TestCase, RunSubprocessMixin): def tearDown(self): """ - Ensures that the services within the "profile compose file" are removed between each test case. + Ensures that the services within the "profile compose file" are removed between each test + case. """ # run the test case From ed395233427d948891bb016a153ab66216a30af7 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Fri, 8 Mar 2024 23:47:13 +0200 Subject: [PATCH 7/7] github: Enable ruff check Signed-off-by: Povilas Kanapickas --- .github/workflows/static-checks.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/static-checks.yml b/.github/workflows/static-checks.yml index 78556ef6..c434fbfe 100644 --- a/.github/workflows/static-checks.yml +++ b/.github/workflows/static-checks.yml @@ -16,5 +16,7 @@ jobs: - uses: actions/checkout@v3 - name: Analysing the code with ruff run: | + set -e pip install -r test-requirements.txt ruff format --check + ruff check