From 5367eaf635bd990d5dd42d1859939c67e1a75bd7 Mon Sep 17 00:00:00 2001 From: Jason Yao Date: Mon, 17 Oct 2022 01:34:40 -0400 Subject: [PATCH] feat(build): adds in the -r or --release flag to the build command, which zips up build packages Generates build package zip files of the form 'dotfiles-{os}-{profile}.zip' in the output directory fix #85 --- pydotfiles/api/__init__.py | 3 ++- pydotfiles/v4/builder/__init__.py | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/pydotfiles/api/__init__.py b/pydotfiles/api/__init__.py index 6cb83a8..0f5634d 100644 --- a/pydotfiles/api/__init__.py +++ b/pydotfiles/api/__init__.py @@ -75,6 +75,7 @@ def build(self, command_arguments: list[str]) -> None: parser = self.__get_base_parser(help_description, "build") parser.add_argument("-d", "--directory", help="Builds all/indicated profile build packages located in the passed-in directory. Defaults to the current working directory", default=getcwd()) parser.add_argument("-b", "--build-directory", help="The output directory. Defaults to pydotfiles-build in the current working directory", default=str(Path(getcwd()).joinpath("pydotfiles-build"))) + parser.add_argument("-r", "--release", help="Will generate releases (.zip) of each of the build files", action="store_true") parser.add_argument("-p", "--profiles", nargs='+', help="Indicates which profiles should be built, and how they should be composed. Defaults to all profiles being built independently") parser.add_argument("-o", "--operating-systems", nargs='+', help="Indicates which operating system build packages should be built. Defaults to all profiles being built independently") @@ -85,7 +86,7 @@ def build(self, command_arguments: list[str]) -> None: configurations = load_configuration(Path(args.directory)) - builder = Builder(configurations, Path(args.directory), Path(args.build_directory)) + builder = Builder(configurations, Path(args.directory), Path(args.build_directory), args.release) build_packages = builder.build(args.profiles, args.operating_systems) for name, build_package_path in build_packages.items(): PrettyPrint.success(f"[{name}]\tSuccessfully generated build package in: {build_package_path}") diff --git a/pydotfiles/v4/builder/__init__.py b/pydotfiles/v4/builder/__init__.py index 2f6b266..ac6f6c4 100644 --- a/pydotfiles/v4/builder/__init__.py +++ b/pydotfiles/v4/builder/__init__.py @@ -9,7 +9,9 @@ from os import path as os_path from dataclasses import dataclass from shutil import copy2 as shutil_copy2 +from shutil import rmtree as shutil_rmtree from os import chmod as os_chmod +from zipfile import ZipFile # Project imports from pydotfiles.v4.common import Configuration @@ -32,7 +34,7 @@ class Builder: without requiring users to commit to a whole dynamically updated ecosystem """ - def __init__(self, configurations: list[Configuration], base_dir: Path, output_path: Path): + def __init__(self, configurations: list[Configuration], base_dir: Path, output_path: Path, is_release: bool): # Maps from a given profile name to the file paths that are defined there self.profile_map: Dict[str, list[Path]] = defaultdict(list) self.profile_dependencies: Dict[str, list[str]] = defaultdict(list) @@ -43,6 +45,7 @@ def __init__(self, configurations: list[Configuration], base_dir: Path, output_p self.defined_os: set[OSName] = set() self.base_dir = base_dir self.output_path = output_path + self.is_release = is_release for configuration in configurations: if isinstance(configuration.data, AlphaCore): @@ -67,6 +70,10 @@ def __init__(self, configurations: list[Configuration], base_dir: Path, output_p self.profile_file_types[configuration.file_path] = AlphaDefaultSettings def build(self, profiles: Optional[list[str]], specified_oses: Optional[list[str]]) -> Dict[str, Path]: + # Clears out the current build directory + shutil_rmtree(self.output_path) + self.output_path.mkdir(parents=True, exist_ok=True) + active_profiles = self.__get_active_profiles(profiles) package_paths: Dict[str, Path] = {} @@ -143,6 +150,9 @@ def __build_package(self, build_data: list[Configuration], active_os: OSName, ac is_installation_init_written = True package_builder.build() package_builder.write_tail() + + if self.is_release: + self.__zip_dir(dirpath) return dirpath def __consolidate_requirements(self, build_data: list[Configuration]) -> list[Configuration]: @@ -221,6 +231,13 @@ def __consolidate_os_build_data(self, build_data: list[Configuration]) -> Option data=AlphaCore.from_dict(consolidated_data) ) + def __zip_dir(self, directory: Path) -> Path: + destination = Path(f"{directory}.zip") + with ZipFile(destination, mode='w') as zip_fp: + for content in directory.iterdir(): + zip_fp.write(content, content.name) + return destination + ## # Build package methods ##