import os import re import shutil import sys component_subdirs = ["extras", "docker-data"] components = {% set components = cookiecutter.__component_list_slug.split(',') -%} [ {%- for component in components -%} "{{ component }}" {%- if not loop.last -%} , {%- endif %} {%- endfor -%} ] project_dir = os.getcwd() build_context_dir_name = "build-context" build_ctx_dir_abs = os.path.join(project_dir, build_context_dir_name) base_dockerfile_abs = os.path.join(build_ctx_dir_abs, "Dockerfile") base_dockerfile_rel = os.path.relpath(base_dockerfile_abs, project_dir) re_string_component = "~~component~~" re_pattern_component = re.compile(re_string_component, re.IGNORECASE) re_string_component_upper = "~~component_upper~~" re_pattern_component_upper = re.compile(re_string_component_upper, re.IGNORECASE) def render_dockerfile(arg_dockerfile_abs: str, arg_component: str) -> None: dockerfile_abs = arg_dockerfile_abs component = arg_component try: with open(dockerfile_abs, 'r+') as dockerfile: text = dockerfile.read() text = re.sub(re_pattern_component, component, text) text = re.sub(re_pattern_component_upper, component.upper(), text) dockerfile.seek(0) dockerfile.write(text) dockerfile.truncate() except OSError: print(f"Unable to open Dockerfile './{component_dockerfile_rel}'. Aborting and exiting 5 ...") sys.exit(5) for component in components: if len(components) > 1: component_dir_abs = os.path.join(build_ctx_dir_abs, component) else: component_dir_abs = build_ctx_dir_abs component_dir_rel = os.path.relpath(component_dir_abs, project_dir) try: os.makedirs(component_dir_abs, exist_ok=True) except FileExistsError: print(f"Dir './{component_dir_rel}' already exists when it shouldn't. Aborting and exiting 1 ...") sys.exit(1) for component_subdir_name in component_subdirs: component_subdir_abs = os.path.join(component_dir_abs, component_subdir_name) try: os.mkdir(component_subdir_abs) except FileExistsError: print(f"Dir '{component_subdir_name}' inside './{component_dir_rel}' exists when it shouldn't. " f"Aborting and exiting 1 ...") sys.exit(1) for root, subdirs, filelist in os.walk(project_dir): for subdir_name in subdirs: if subdir_name in component_subdirs: subdir_abs = os.path.join(root, subdir_name) gitkeep_file_abs = os.path.join(subdir_abs, ".gitkeep") gitkeep_file_rel = os.path.relpath(gitkeep_file_abs, project_dir) try: with open(gitkeep_file_abs, mode='a'): pass except IOError: print(f"Can't write './{gitkeep_file_rel}'. Aborting and exiting 2 ...") sys.exit(2) if len(components) > 1: if subdir_name in components: component_dir_abs = os.path.join(root, subdir_name) component_dockerfile_abs = os.path.join(component_dir_abs, "Dockerfile") component_dockerfile_rel = os.path.relpath(component_dockerfile_abs, project_dir) try: shutil.copyfile(base_dockerfile_abs, component_dockerfile_abs) render_dockerfile(component_dockerfile_abs, subdir_name) except shutil.SameFileError: print(f"Unable to copy base_dockerfile_abs ('{base_dockerfile_abs}') to " f"component_dockerfile_abs ('{component_dockerfile_abs}'). They're the same file. " f"Aborting and exiting 4 ...") sys.exit(4) except shutil.SpecialFileError: print(f"Unable to copy base_dockerfile_abs ('{base_dockerfile_abs}') to " f"component_dockerfile_abs ('{component_dockerfile_abs}'). Source is a named pipe. " f"Aborting and exiting 4 ...") sys.exit(4) except FileNotFoundError: print(f"Unable to copy base_dockerfile_abs ('{base_dockerfile_abs}') to " f"component_dockerfile_abs ('{component_dockerfile_abs}'). Destination dir does not exist. " f"Aborting and exiting 4 ...") sys.exit(4) except OSError: print(f"Unable to copy base_dockerfile_abs ('{base_dockerfile_abs}') to " f"component_dockerfile_abs ('{component_dockerfile_abs}'). Source file likely does not exist. " f"Aborting and exiting 4 ...") sys.exit(4) else: render_dockerfile(base_dockerfile_abs, components[0]) if len(components) > 1: try: os.remove(base_dockerfile_abs) except OSError: print(f"Unable to delete original template Dockerfile at './{base_dockerfile_rel}'. " f"Aborting and exiting 6 ...") sys.exit(6)