From 65072f7346a29bc53a9aec5cb7d7faa6554c0ab5 Mon Sep 17 00:00:00 2001 From: Robin Syl Date: Mon, 11 Mar 2024 23:39:46 +0100 Subject: [PATCH] run black formatter Signed-off-by: Robin Syl --- podman_compose.py | 341 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 240 insertions(+), 101 deletions(-) mode change 100755 => 100644 podman_compose.py diff --git a/podman_compose.py b/podman_compose.py old mode 100755 new mode 100644 index b7bd3ca8..cb60a686 --- a/podman_compose.py +++ b/podman_compose.py @@ -51,7 +51,11 @@ def is_dict(dict_object): def is_list(list_object): - return not is_str(list_object) and not is_dict(list_object) and hasattr(list_object, "__iter__") + return ( + not is_str(list_object) + and not is_dict(list_object) + and hasattr(list_object, "__iter__") + ) # identity filter @@ -159,7 +163,9 @@ def parse_short_mount(mount_str, basedir): # User-relative path # - ~/configs:/etc/configs/:ro mount_type = "bind" - mount_src = os.path.abspath(os.path.join(basedir, os.path.expanduser(mount_src))) + mount_src = os.path.abspath( + os.path.join(basedir, os.path.expanduser(mount_src)) + ) else: # Named volume # - datavolume:/var/lib/mysql @@ -212,11 +218,13 @@ def fix_mount_dict(compose, mount_dict, proj_name, srv_name): # handle anonymous or implied volume if not source: # missing source - vol["name"] = "_".join([ - proj_name, - srv_name, - hashlib.sha256(mount_dict["target"].encode("utf-8")).hexdigest(), - ]) + vol["name"] = "_".join( + [ + proj_name, + srv_name, + hashlib.sha256(mount_dict["target"].encode("utf-8")).hexdigest(), + ] + ) elif not name: external = vol.get("external", None) if isinstance(external, dict): @@ -367,7 +375,9 @@ async def assert_volume(compose, mount_dict): if mount_dict["type"] == "bind": basedir = os.path.realpath(compose.dirname) mount_src = mount_dict["source"] - mount_src = os.path.realpath(os.path.join(basedir, os.path.expanduser(mount_src))) + mount_src = os.path.realpath( + os.path.join(basedir, os.path.expanduser(mount_src)) + ) if not os.path.exists(mount_src): try: os.makedirs(mount_src, exist_ok=True) @@ -384,7 +394,9 @@ async def assert_volume(compose, mount_dict): # 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") + _ = (await compose.podman.output([], "volume", ["inspect", vol_name])).decode( + "utf-8" + ) except subprocess.CalledProcessError as e: if is_ext: raise RuntimeError(f"External volume [{vol_name}] does not exists") from e @@ -406,10 +418,14 @@ async def assert_volume(compose, mount_dict): args.extend(["--opt", f"{opt}={value}"]) args.append(vol_name) await compose.podman.output([], "volume", args) - _ = (await compose.podman.output([], "volume", ["inspect", vol_name])).decode("utf-8") + _ = (await compose.podman.output([], "volume", ["inspect", vol_name])).decode( + "utf-8" + ) -def mount_desc_to_mount_args(compose, mount_desc, srv_name, cnt_name): # pylint: disable=unused-argument +def mount_desc_to_mount_args( + compose, mount_desc, srv_name, cnt_name +): # pylint: disable=unused-argument mount_type = mount_desc.get("type", None) vol = mount_desc.get("_vol", None) if mount_type == "volume" else None source = vol["name"] if vol else mount_desc.get("source", None) @@ -457,7 +473,9 @@ def container_to_ulimit_args(cnt, podman_args): podman_args.extend(["--ulimit", i]) -def mount_desc_to_volume_args(compose, mount_desc, srv_name, cnt_name): # pylint: disable=unused-argument +def mount_desc_to_volume_args( + compose, mount_desc, srv_name, cnt_name +): # pylint: disable=unused-argument mount_type = mount_desc["type"] if mount_type not in ("bind", "volume"): raise ValueError("unknown mount type:" + mount_type) @@ -468,9 +486,13 @@ def mount_desc_to_volume_args(compose, mount_desc, srv_name, cnt_name): # pylin target = mount_desc["target"] opts = [] - propagations = set(filteri(mount_desc.get(mount_type, {}).get("propagation", "").split(","))) + propagations = set( + filteri(mount_desc.get(mount_type, {}).get("propagation", "").split(",")) + ) if mount_type != "bind": - propagations.update(filteri(mount_desc.get("bind", {}).get("propagation", "").split(","))) + propagations.update( + filteri(mount_desc.get("bind", {}).get("propagation", "").split(",")) + ) opts.extend(propagations) # --volume, -v[=[[SOURCE-VOLUME|HOST-DIR:]CONTAINER-DIR[:OPTIONS]]] # [rw|ro] @@ -530,7 +552,9 @@ async def get_mount_args(compose, cnt, volume): def get_secret_args(compose, cnt, secret): secret_name = secret if is_str(secret) else secret.get("source", None) if not secret_name or secret_name not in compose.declared_secrets.keys(): - raise ValueError(f'ERROR: undeclared secret: "{secret}", service: {cnt["_service"]}') + raise ValueError( + f'ERROR: undeclared secret: "{secret}", service: {cnt["_service"]}' + ) declared_secret = compose.declared_secrets[secret_name] source_file = declared_secret.get("file", None) @@ -551,7 +575,9 @@ def get_secret_args(compose, cnt, secret): else: dest_file = target basedir = compose.dirname - source_file = os.path.realpath(os.path.join(basedir, os.path.expanduser(source_file))) + source_file = os.path.realpath( + os.path.join(basedir, os.path.expanduser(source_file)) + ) volume_ref = ["--volume", f"{source_file}:{dest_file}:ro,rprivate,rbind"] if uid or gid or mode: sec = target if target else secret_name @@ -598,7 +624,9 @@ def get_secret_args(compose, cnt, secret): return ["--secret", "{}{}".format(secret_name, secret_opts)] raise ValueError( - 'ERROR: unparsable secret: "{}", service: "{}"'.format(secret_name, cnt["_service"]) + 'ERROR: unparsable secret: "{}", service: "{}"'.format( + secret_name, cnt["_service"] + ) ) @@ -623,27 +651,35 @@ def container_to_res_args(cnt, podman_args): # add args cpus = cpus_limit_v3 or cpus_limit_v2 if cpus: - podman_args.extend(( - "--cpus", - str(cpus), - )) + podman_args.extend( + ( + "--cpus", + str(cpus), + ) + ) if cpu_shares_v2: - podman_args.extend(( - "--cpu-shares", - str(cpu_shares_v2), - )) + podman_args.extend( + ( + "--cpu-shares", + str(cpu_shares_v2), + ) + ) mem = mem_limit_v3 or mem_limit_v2 if mem: - podman_args.extend(( - "-m", - str(mem).lower(), - )) + podman_args.extend( + ( + "-m", + str(mem).lower(), + ) + ) mem_res = mem_res_v3 or mem_res_v2 if mem_res: - podman_args.extend(( - "--memory-reservation", - str(mem_res).lower(), - )) + podman_args.extend( + ( + "--memory-reservation", + str(mem_res).lower(), + ) + ) def port_dict_to_str(port_desc): @@ -744,12 +780,16 @@ async def assert_cnt_nets(compose, cnt): is_ext = net_desc.get("external", None) ext_desc = is_ext if is_dict(is_ext) else {} default_net_name = net if is_ext else f"{proj_name}_{net}" - net_name = ext_desc.get("name", None) or net_desc.get("name", None) or default_net_name + net_name = ( + ext_desc.get("name", None) or net_desc.get("name", None) or default_net_name + ) try: await compose.podman.output([], "network", ["exists", net_name]) except subprocess.CalledProcessError as e: if is_ext: - raise RuntimeError(f"External network [{net_name}] does not exists") from e + raise RuntimeError( + f"External network [{net_name}] does not exists" + ) from e args = get_network_create_args(net_desc, proj_name, net_name) await compose.podman.output([], "network", args) await compose.podman.output([], "network", ["exists", net_name]) @@ -816,10 +856,12 @@ def get_net_args(compose, cnt): if not ip6: ip6 = net_value.get("ipv6_address", None) net_priority = net_value.get("priority", 0) - prioritized_cnt_nets.append(( - net_priority, - net_key, - )) + prioritized_cnt_nets.append( + ( + net_priority, + net_key, + ) + ) # sort dict by priority prioritized_cnt_nets.sort(reverse=True) cnt_nets = [net_key for _, net_key in prioritized_cnt_nets] @@ -830,7 +872,9 @@ def get_net_args(compose, cnt): is_ext = net_desc.get("external", None) ext_desc = is_ext if is_dict(is_ext) else {} default_net_name = net if is_ext else f"{proj_name}_{net}" - net_name = ext_desc.get("name", None) or net_desc.get("name", None) or default_net_name + net_name = ( + ext_desc.get("name", None) or net_desc.get("name", None) or default_net_name + ) net_names.append(net_name) net_names_str = ",".join(net_names) @@ -843,7 +887,11 @@ def get_net_args(compose, cnt): is_ext = net_desc.get("external", None) ext_desc = is_ext if is_dict(is_ext) else {} default_net_name = net_ if is_ext else f"{proj_name}_{net_}" - net_name = ext_desc.get("name", None) or net_desc.get("name", None) or default_net_name + net_name = ( + ext_desc.get("name", None) + or net_desc.get("name", None) + or default_net_name + ) ipv4 = multiple_nets[net_].get("ipv4_address", None) ipv6 = multiple_nets[net_].get("ipv6_address", None) @@ -855,7 +903,9 @@ def get_net_args(compose, cnt): net_args.extend(["--network", f"{net_name}:ip={ipv4}"]) else: if is_bridge: - net_args.extend(["--net", net_names_str, "--network-alias", ",".join(aliases)]) + net_args.extend( + ["--net", net_names_str, "--network-alias", ",".join(aliases)] + ) if ip: net_args.append(f"--ip={ip}") if ip6: @@ -1182,7 +1232,9 @@ async def output(self, podman_args, cmd="", cmd_args=None): if p.returncode == 0: return stdout_data - raise subprocess.CalledProcessError(p.returncode, " ".join(cmd_ls), stderr_data) + raise subprocess.CalledProcessError( + p.returncode, " ".join(cmd_ls), stderr_data + ) def exec( self, @@ -1220,12 +1272,14 @@ async def format_out(stdout): while True: line = await stdout.readline() if line: - print(log_formatter, line.decode('utf-8'), end='') + print(log_formatter, line.decode("utf-8"), end="") if stdout.at_eof(): break p = await asyncio.create_subprocess_exec( - *cmd_ls, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE + *cmd_ls, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, ) # pylint: disable=consider-using-with # This is hacky to make the tasks not get garbage collected @@ -1239,7 +1293,9 @@ async def format_out(stdout): err_t.add_done_callback(task_reference.discard) else: - p = await asyncio.create_subprocess_exec(*cmd_ls) # pylint: disable=consider-using-with + p = await asyncio.create_subprocess_exec( + *cmd_ls + ) # pylint: disable=consider-using-with try: exit_code = await p.wait() @@ -1336,7 +1392,9 @@ def normalize_service_final(service: dict, project_dir: str) -> dict: context = build if is_str(build) else build.get("context", ".") context = os.path.normpath(os.path.join(project_dir, context)) dockerfile = ( - "Dockerfile" if is_str(build) else service["build"].get("dockerfile", "Dockerfile") + "Dockerfile" + if is_str(build) + else service["build"].get("dockerfile", "Dockerfile") ) if not is_dict(service["build"]): service["build"] = {} @@ -1378,13 +1436,17 @@ def rec_merge_one(target, source): if not isinstance(value2, type(value)): value_type = type(value) value2_type = type(value2) - raise ValueError(f"can't merge value of [{key}] of type {value_type} and {value2_type}") + raise ValueError( + f"can't merge value of [{key}] of type {value_type} and {value2_type}" + ) if is_list(value2): if key == "volumes": # clean duplicate mount targets pts = {v.split(":", 2)[1] for v in value2 if ":" in v} del_ls = [ - ix for (ix, v) in enumerate(value) if ":" in v and v.split(":", 2)[1] in pts + ix + for (ix, v) in enumerate(value) + if ":" in v and v.split(":", 2)[1] in pts ] for ix in reversed(del_ls): del value[ix] @@ -1526,14 +1588,16 @@ async def run(self): if args.dry_run is False: log.fatal("Binary %s has not been found.", podman_path) sys.exit(1) - self.podman = Podman(self, podman_path, args.dry_run, asyncio.Semaphore(args.parallel)) + self.podman = Podman( + self, podman_path, args.dry_run, asyncio.Semaphore(args.parallel) + ) if not args.dry_run: # just to make sure podman is running try: - self.podman_version = (await self.podman.output(["--version"], "", [])).decode( - "utf-8" - ).strip() or "" + self.podman_version = ( + await self.podman.output(["--version"], "", []) + ).decode("utf-8").strip() or "" self.podman_version = (self.podman_version.split() or [""])[-1] except subprocess.CalledProcessError: self.podman_version = None @@ -1600,18 +1664,24 @@ def _parse_compose_file(self): # TODO: remove next line os.chdir(dirname) - os.environ.update({ - key: value for key, value in dotenv_dict.items() if key.startswith("PODMAN_") - }) + os.environ.update( + { + key: value + for key, value in dotenv_dict.items() + if key.startswith("PODMAN_") + } + ) self.environ = dict(os.environ) self.environ.update(dotenv_dict) # see: https://docs.docker.com/compose/reference/envvars/ # see: https://docs.docker.com/compose/env-file/ - self.environ.update({ - "COMPOSE_PROJECT_DIR": dirname, - "COMPOSE_FILE": pathsep.join(relative_files), - "COMPOSE_PATH_SEPARATOR": pathsep, - }) + self.environ.update( + { + "COMPOSE_PROJECT_DIR": dirname, + "COMPOSE_FILE": pathsep.join(relative_files), + "COMPOSE_PATH_SEPARATOR": pathsep, + } + ) compose = {} # Iterate over files primitively to allow appending to files in-loop files_iter = iter(files) @@ -1627,7 +1697,8 @@ def _parse_compose_file(self): # log(filename, json.dumps(content, indent = 2)) if not isinstance(content, dict): sys.stderr.write( - "Compose file does not contain a top level object: %s\n" % filename + "Compose file does not contain a top level object: %s\n" + % filename ) sys.exit(1) content = normalize(content) @@ -1644,7 +1715,9 @@ def _parse_compose_file(self): # Solution is to remove 'include' key from compose obj. This doesn't break # having `include` present and correctly processed in included files del compose["include"] - resolved_services = self._resolve_profiles(compose.get("services", {}), set(args.profile)) + resolved_services = self._resolve_profiles( + compose.get("services", {}), set(args.profile) + ) compose["services"] = resolved_services if not getattr(args, "no_normalize", None): compose = normalize_final(compose, self.dirname) @@ -1663,11 +1736,14 @@ def _parse_compose_file(self): # 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() + self.environ.get("COMPOSE_PROJECT_NAME", None) + or dir_basename.lower() ) project_name = norm_re.sub("", project_name) if not project_name: - raise RuntimeError(f"Project name [{dir_basename}] normalized to empty") + raise RuntimeError( + f"Project name [{dir_basename}] normalized to empty" + ) self.project_name = project_name self.environ.update({"COMPOSE_PROJECT_NAME": self.project_name}) @@ -1681,11 +1757,15 @@ def _parse_compose_file(self): # NOTE: maybe add "extends.service" to _deps at this stage flat_deps(services, with_extends=True) - service_names = sorted([(len(srv["_deps"]), name) for name, srv in services.items()]) + service_names = sorted( + [(len(srv["_deps"]), name) for name, srv in services.items()] + ) service_names = [name for _, name in service_names] resolve_extends(services, service_names, self.environ) flat_deps(services) - service_names = sorted([(len(srv["_deps"]), name) for name, srv in services.items()]) + service_names = sorted( + [(len(srv["_deps"]), name) for name, srv in services.items()] + ) service_names = [name for _, name in service_names] nets = compose.get("networks", None) or {} if not nets: @@ -1701,7 +1781,9 @@ def _parse_compose_file(self): allnets = set() for name, srv in services.items(): srv_nets = srv.get("networks", None) or default_net - srv_nets = list(srv_nets.keys()) if is_dict(srv_nets) else norm_as_list(srv_nets) + srv_nets = ( + list(srv_nets.keys()) if is_dict(srv_nets) else norm_as_list(srv_nets) + ) allnets.update(srv_nets) given_nets = set(nets.keys()) missing_nets = allnets - given_nets @@ -1752,10 +1834,12 @@ def _parse_compose_file(self): labels = norm_as_list(cnt.get("labels", None)) cnt["ports"] = norm_ports(cnt.get("ports", None)) labels.extend(podman_compose_labels) - labels.extend([ - f"com.docker.compose.container-number={num}", - "com.docker.compose.service=" + service_name, - ]) + labels.extend( + [ + f"com.docker.compose.container-number={num}", + "com.docker.compose.service=" + service_name, + ] + ) cnt["labels"] = labels cnt["_service"] = service_name cnt["_project"] = project_name @@ -1769,7 +1853,9 @@ def _parse_compose_file(self): and mnt_dict["source"] not in self.vols ): vol_name = mnt_dict["source"] - raise RuntimeError(f"volume [{vol_name}] not defined in top level") + raise RuntimeError( + f"volume [{vol_name}] not defined in top level" + ) self.container_names_by_service = container_names_by_service self.all_services = set(container_names_by_service.keys()) container_by_name = {c["name"]: c for c in given_containers} @@ -1800,7 +1886,9 @@ def _resolve_profiles(self, defined_services, requested_profiles=None): for name, config in defined_services.items(): service_profiles = set(config.get("profiles", [])) - if not service_profiles or requested_profiles.intersection(service_profiles): + if not service_profiles or requested_profiles.intersection( + service_profiles + ): services[name] = config return services @@ -1810,7 +1898,9 @@ def _parse_args(self): subparsers = parser.add_subparsers(title="command", dest="command") subparser = subparsers.add_parser("help", help="show help") for cmd_name, cmd in self.commands.items(): - subparser = subparsers.add_parser(cmd_name, help=cmd.desc) # pylint: disable=protected-access + subparser = subparsers.add_parser( + cmd_name, help=cmd.desc + ) # pylint: disable=protected-access for cmd_parser in cmd._parse_args: # pylint: disable=protected-access cmd_parser(subparser) self.global_args = parser.parse_args() @@ -1906,7 +1996,9 @@ def _init_global_parser(parser): action="store_true", ) parser.add_argument( - "--parallel", type=int, default=os.environ.get("COMPOSE_PARALLEL_LIMIT", sys.maxsize) + "--parallel", + type=int, + default=os.environ.get("COMPOSE_PARALLEL_LIMIT", sys.maxsize), ) parser.add_argument( "--verbose", @@ -2159,10 +2251,12 @@ async def build_one(compose, args, cnt): args_list = norm_as_list(build_desc.get("args", {})) for build_arg in args_list + args.build_arg: - build_args.extend(( - "--build-arg", - build_arg, - )) + build_args.extend( + ( + "--build-arg", + build_arg, + ) + ) build_args.append(ctx) status = await compose.podman.run([], "build", build_args) return status @@ -2221,7 +2315,9 @@ def get_excluded(compose, args): return excluded -@cmd_run(podman_compose, "up", "Create and start the entire stack or some of its services") +@cmd_run( + podman_compose, "up", "Create and start the entire stack or some of its services" +) async def compose_up(compose: PodmanCompose, args): proj_name = compose.project_name excluded = get_excluded(compose, args) @@ -2279,12 +2375,16 @@ async def compose_up(compose: PodmanCompose, args): max_service_length = 0 for cnt in compose.containers: curr_length = len(cnt["_service"]) - max_service_length = curr_length if curr_length > max_service_length else max_service_length + max_service_length = ( + curr_length if curr_length > max_service_length else max_service_length + ) tasks = set() loop = asyncio.get_event_loop() - loop.add_signal_handler(signal.SIGINT, lambda: [t.cancel("User exit") for t in tasks]) + loop.add_signal_handler( + signal.SIGINT, lambda: [t.cancel("User exit") for t in tasks] + ) for i, cnt in enumerate(compose.containers): # Add colored service prefix to output by piping output through sed @@ -2298,7 +2398,9 @@ async def compose_up(compose: PodmanCompose, args): tasks.add( asyncio.create_task( - compose.podman.run([], "start", ["-a", cnt["name"]], log_formatter=log_formatter), + compose.podman.run( + [], "start", ["-a", cnt["name"]], log_formatter=log_formatter + ), name=cnt["_service"], ) ) @@ -2371,7 +2473,8 @@ async def compose_down(compose, args): podman_stop_args.extend(["-t", str(timeout)]) down_tasks.append( asyncio.create_task( - compose.podman.run([], "stop", [*podman_stop_args, cnt["name"]]), name=cnt["name"] + compose.podman.run([], "stop", [*podman_stop_args, cnt["name"]]), + name=cnt["name"], ) ) await asyncio.gather(*down_tasks) @@ -2467,7 +2570,10 @@ async def compose_run(compose, args): await compose.commands["up"](compose, up_args) build_args = argparse.Namespace( - services=[args.service], if_not_exists=(not args.build), build_arg=[], **args.__dict__ + services=[args.service], + if_not_exists=(not args.build), + build_arg=[], + **args.__dict__, ) await compose.commands["build"](compose, build_args) @@ -2484,7 +2590,9 @@ async def compose_run(compose, args): def compose_run_update_container_from_args(compose, cnt, args): # adjust one-off container options - name0 = "{}_{}_tmp{}".format(compose.project_name, args.service, random.randrange(0, 65536)) + name0 = "{}_{}_tmp{}".format( + compose.project_name, args.service, random.randrange(0, 65536) + ) cnt["name"] = args.name or name0 if args.entrypoint: cnt["entrypoint"] = args.entrypoint @@ -2494,7 +2602,9 @@ def compose_run_update_container_from_args(compose, cnt, args): cnt["working_dir"] = args.workdir env = dict(cnt.get("environment", {})) if args.env: - additional_env_vars = dict(map(lambda each: each.split("=", maxsplit=1), args.env)) + additional_env_vars = dict( + map(lambda each: each.split("=", maxsplit=1), args.env) + ) env.update(additional_env_vars) cnt["environment"] = env if not args.service_ports: @@ -2540,7 +2650,12 @@ def compose_exec_args(cnt, container_name, args): env = dict(cnt.get("environment", {})) if args.env: additional_env_vars = dict( - map(lambda each: each.split("=", maxsplit=1) if "=" in each else (each, None), args.env) + map( + lambda each: ( + each.split("=", maxsplit=1) if "=" in each else (each, None) + ), + args.env, + ) ) env.update(additional_env_vars) for name, value in env.items(): @@ -2578,7 +2693,9 @@ async def transfer_service_status(compose, args, action): timeout = str_to_seconds(timeout_str) if timeout is not None: podman_args.extend(["-t", str(timeout)]) - tasks.append(asyncio.create_task(compose.podman.run([], action, podman_args + [target]))) + tasks.append( + asyncio.create_task(compose.podman.run([], action, podman_args + [target])) + ) await asyncio.gather(*tasks) @@ -2687,7 +2804,9 @@ async def compose_unpause(compose, args): await compose.podman.run([], "unpause", targets) -@cmd_run(podman_compose, "kill", "Kill one or more running containers with a specific signal") +@cmd_run( + podman_compose, "kill", "Kill one or more running containers with a specific signal" +) async def compose_kill(compose, args): # to ensure that the user did not execute the command by mistake if not args.services and not args.all: @@ -2780,13 +2899,17 @@ def compose_up_parse(parser): help="Detached mode: Run container in the background, print new container name. \ Incompatible with --abort-on-container-exit.", ) - parser.add_argument("--no-color", action="store_true", help="Produce monochrome output.") + parser.add_argument( + "--no-color", action="store_true", help="Produce monochrome output." + ) parser.add_argument( "--quiet-pull", action="store_true", help="Pull without printing progress information.", ) - parser.add_argument("--no-deps", action="store_true", help="Don't start linked services.") + parser.add_argument( + "--no-deps", action="store_true", help="Don't start linked services." + ) parser.add_argument( "--force-recreate", action="store_true", @@ -2885,7 +3008,9 @@ def compose_run_parse(parser): action="store_true", help="Detached mode: Run container in the background, print new container name.", ) - parser.add_argument("--name", type=str, default=None, help="Assign a name to the container") + parser.add_argument( + "--name", type=str, default=None, help="Assign a name to the container" + ) parser.add_argument( "--entrypoint", type=str, @@ -2909,7 +3034,9 @@ def compose_run_parse(parser): parser.add_argument( "-u", "--user", type=str, default=None, help="Run as specified username or uid" ) - parser.add_argument("--no-deps", action="store_true", help="Don't start linked services") + parser.add_argument( + "--no-deps", action="store_true", help="Don't start linked services" + ) parser.add_argument( "--rm", action="store_true", @@ -3035,15 +3162,21 @@ def compose_logs_parse(parser): action="store_true", help="Output the container name in the log", ) - parser.add_argument("--since", help="Show logs since TIMESTAMP", type=str, default=None) - parser.add_argument("-t", "--timestamps", action="store_true", help="Show timestamps.") + parser.add_argument( + "--since", help="Show logs since TIMESTAMP", type=str, default=None + ) + parser.add_argument( + "-t", "--timestamps", action="store_true", help="Show timestamps." + ) parser.add_argument( "--tail", help="Number of lines to show from the end of the logs for each " "container.", type=str, default="all", ) - parser.add_argument("--until", help="Show logs until TIMESTAMP", type=str, default=None) + parser.add_argument( + "--until", help="Show logs until TIMESTAMP", type=str, default=None + ) parser.add_argument( "services", metavar="services", nargs="*", default=None, help="service names" ) @@ -3068,7 +3201,9 @@ def compose_pull_parse(parser): default=False, help="Also pull unprefixed images for services which have a build section", ) - parser.add_argument("services", metavar="services", nargs="*", help="services to pull") + parser.add_argument( + "services", metavar="services", nargs="*", help="services to pull" + ) @cmd_parse(podman_compose, "push") @@ -3078,12 +3213,16 @@ def compose_push_parse(parser): action="store_true", help="Push what it can and ignores images with push failures. (not implemented)", ) - parser.add_argument("services", metavar="services", nargs="*", help="services to push") + parser.add_argument( + "services", metavar="services", nargs="*", help="services to push" + ) @cmd_parse(podman_compose, "ps") def compose_ps_parse(parser): - parser.add_argument("-q", "--quiet", help="Only display container IDs", action="store_true") + parser.add_argument( + "-q", "--quiet", help="Only display container IDs", action="store_true" + ) @cmd_parse(podman_compose, ["build", "up"])