import click import shutil import pyperclip from pathlib import Path from datetime import datetime from ._natural_sort import natural_sort DEVELOPER_DRIVE = Path("/mnt/e/") PATH_ISSUES = DEVELOPER_DRIVE / "Safeguard-MBP-issues" PATH_WORKBOOKS = DEVELOPER_DRIVE / "Safeguard MBP Workbooks" PATH_WIN_DESKTOP = Path("/mnt/c/Users/Holgi/Desktop") TODAY = datetime.now().strftime("%y%m%d") CRLF = "\r\n" EXCEL_CHANGELOGS = { "changes mbp {version} hyb.txt": "J1", "changes mbp {version} qc.txt": "J1", "changes mbp {version} dry-1.txt": "L1", "changes mbp {version} dry-2.txt": "L1", "changes mbp {version} reg.txt": "J1", "changes mbp {version} as.txt": "L1", } EXCEL_CHANGELOG_HEADERS = [ "Sheet\tWell\tContents\tComment", "-----\t----\t--------\t-------", "", ] WORKBOOKS_MAP = { "MBP Hyb.xlsx": "MBP {version} Hyb.xlsx", "MBP Reg.xlsx": "MBP {version} Reg.xlsx", "MBP QC.xlsx": "MBP {version} QC.xlsx", "MBP Dry-1.xlsx": "MBP {version} Dry-1.xlsx", "MBP Dry-2.xlsx": "MBP {version} Dry-2.xlsx", "MBP AS.xlsx": "MBP {version} AS.xlsx", } def _folder_content(folder): nondotted = (i for i in folder.iterdir() if not i.stem.startswith(".")) return (i for i in nondotted if not i.stem.startswith("~")) def _files_in_folder(folder, suffix): files = (f for f in _folder_content(folder) if f.is_file()) return (f for f in files if f.suffix == suffix) def get_latest_version(parent=PATH_ISSUES): folders = (i for i in _folder_content(parent) if i.is_dir()) versions = natural_sort(f.name for f in folders if f.stem.lower().startswith("v")) return versions[-1] def get_next_version(parent=PATH_ISSUES, echo_current=True): latest = get_latest_version(parent) if echo_current: print("current version:", latest) try: head, tail = latest.rsplit(".", 1) next_minor = int(tail) + 1 next_version = f"{head}.{next_minor}" except: next_version = "" return next_version def create_new_version_folder(new_version, parent=PATH_ISSUES): new_folder_path = parent / new_version if new_folder_path.exists(): print(f"Folder for version {new_version} already exists, aborting") return new_folder_path.mkdir() return new_folder_path def create_excel_changelogs(new_version, parent): for name, cell in EXCEL_CHANGELOGS.items(): new_file = parent / name.format(version=new_version) with new_file.open("w") as fh: data_line = "\t".join(["Settings", cell, new_version, ""]) content_lines = EXCEL_CHANGELOG_HEADERS + [data_line, "", ""] fh.write(CRLF.join(content_lines)) def create_changelog_entry(new_version, parent=PATH_ISSUES): textfiles = _files_in_folder(parent, ".txt") changelog = next(f for f in textfiles if f.stem.lower().startswith("change")) content = [] with changelog.open("r") as fh: stripped_lines = (line.rstrip() for line in fh) for line in stripped_lines: content.append(line) if line.startswith("----"): content.append("") content.append(f"{new_version}, work in progress:") content.append(" - The following Workbooks did not have any changes: AS, Dry-1, Dry-2, Hyb, QC, Reg") with changelog.open("w") as fh: fh.write(CRLF.join(content)) def get_changelog_path(): textfiles = _files_in_folder(PATH_ISSUES, ".txt") return next(f for f in textfiles if f.stem.lower().startswith("change")) def copy_changelog(destination, build_version): changelog = get_changelog_path() new_path = destination / f"CHANGELOG {build_version}.txt" print(changelog.name, "->", new_path) shutil.copyfile(changelog, new_path) def copy_workbook_changelogs(destination, latest, build_version): source = PATH_ISSUES / latest textfiles = _files_in_folder(source, ".txt") logs = (f for f in textfiles if f.stem.lower().startswith("change")) for log_file in logs: new_name = log_file.name.replace(latest, build_version) new_path = destination / new_name print(log_file.name, "->", new_path) shutil.copyfile(log_file, new_path) def copy_workbooks(destination, build_version): all_xls_files = _files_in_folder(PATH_WORKBOOKS, ".xlsx") mbp_files = (f for f in all_xls_files if f.name.lower().startswith("mbp")) for excel_file in mbp_files: new_name = WORKBOOKS_MAP[excel_file.name] new_path = destination / new_name.format(version=build_version) print(excel_file.name, "->", new_path) shutil.copyfile(excel_file, new_path) def collect_current_frms(build_version): all_folders = (f for f in PATH_WORKBOOKS.iterdir() if f.is_dir()) all_frms = (f for f in all_folders if "frm" in f.name.lower()) return [f for f in all_frms if f.name.endswith(build_version)] def copy_frms(destination, build_version): all_folders = (f for f in PATH_WORKBOOKS.iterdir() if f.is_dir()) all_frms = (f for f in all_folders if "frm" in f.name.lower()) current_frms = collect_current_frms(build_version) for folder in current_frms: new_path = destination / folder.name print(folder.name, "->", new_path) shutil.copytree(folder, new_path) def get_issue_numbers(build_version): for path in collect_current_frms(build_version): rest, issue_info = path.name.lower().split("issue") issue, *rest = issue_info.strip().split() yield issue.strip(" ,") def extract_changes_from_log(build_version): issue_numbers = set(get_issue_numbers(build_version)) changelog = get_changelog_path() for line in changelog.read_text().splitlines(): for issue in issue_numbers: if issue in line: yield line def get_announcement_text(dev_version, build_version, new_folder_name): if not dev_version: return "This is an official release, the message must be hand crafted" latest = get_latest_version() changes = list(extract_changes_from_log(build_version)) if len(changes) == 1: change_msg = "Only one change was introduced:" else: change_msg = "The changes made:" text = [ f"# New MBP Workbook Version {build_version}", "Good News Everyone,", f"there is a new workbook version available: {build_version}", ( f"As indicated by the letter '{dev_version}' at the end," " this version is intended for Freiburg only." ), change_msg, "\n".join(changes), "You can find this version at our Freiburg Shared Drive:", ( "Google Drive / Shared drives / Freiburg / Workbooks / MBP Workbooks /" f" {latest} /" f" {new_folder_name}" ), "Cheers,\nHolgi" ] return "\n\n".join(text) @click.command() @click.option( "-v", "--version", required=True, prompt="new version", default=get_next_version, show_default="next minor version", ) def sg_mbp_new_version(version): """ creates a new version folder, new excel changes files and modifies the overall changelog in "E:\Safeguard-MBP-issues" """ folder = create_new_version_folder(version) if folder is not None: create_excel_changelogs(version, folder) create_changelog_entry(version) @click.command() @click.option( "-d", "--dev_version", prompt="Dev version i.e. 'c'", required=True, default="", ) def sg_mbp_build(dev_version): """ Before running this command: \b - make the requiered edits to the workbooks - edit the changelog in "E:\Safeguard-MBP-issues" - create a new versions folder in "E:\Safeguard-MBP-issues", e.g. "v3.9.49" - note the changes in the excel changelogs in the created version folder The command will collect all data into one folder on the Desktop to be published """ latest = get_latest_version() build_version = f"{latest}{dev_version}" new_folder_name = f"{TODAY} {build_version}" new_folder_path = PATH_WIN_DESKTOP / new_folder_name if new_folder_path.exists(): raise IOError(f"Folder exists on desktop: {new_folder_name}") else: new_folder_path.mkdir() copy_workbooks(new_folder_path, build_version) copy_workbook_changelogs(new_folder_path, latest, build_version) copy_changelog(new_folder_path, build_version) copy_frms(new_folder_path, build_version) announcement = get_announcement_text(dev_version, build_version, new_folder_name) pyperclip.copy(announcement) print(announcement)