import os from pathlib import Path import re from typing import List import platform import sys import traceback from io import FileIO def exit_with_err(err: Exception, logfile: FileIO=None): """ Exit the current step and display the err. :param: err, the error/exception encountered. """ if logfile: traceback.print_exc(file=logfile) else: traceback.print_exc() sys.exit(1) def set_env_var(key: str, value: str, delimiter: str='~'): """ Set the GitHub env variable of 'key' to 'value' using the method specified here: https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-an-environment-variable Support both Windows and Ubuntu machines provided by GitHub Actions. :param: key, the name of the env variable. :param: value, the value of the env variable. :param: delimiter, the delimiter that you want to use to write to the file. Only applicable if the 'value' contains '\n' character aka a multiline string. """ if platform.system() == "Windows": if "\n" in value: os.system(f'echo "{key}<<{delimiter}" >> %GITHUB_ENV%') os.system(f'echo "{value}" >> %GITHUB_ENV%') os.system(f'echo "{delimiter}" >> %GITHUB_ENV%') else: os.system(f'echo "{key}={value}" >> %GITHUB_ENV%') elif platform.system() == "Linux": if "\n" in value: os.system(f'echo "{key}<<{delimiter}" >> $GITHUB_ENV') os.system(f'echo "{value}" >> $GITHUB_ENV') os.system(f'echo "{delimiter}" >> $GITHUB_ENV') else: os.system(f'echo "{key}={value}" >> $GITHUB_ENV') else: raise Exception("This function doesn't support this platform: " + platform.system()) def find_object_added_in_pr(icons: List[dict], pr_title: str): """ Find the icon name from the PR title. :param icons, a list of the font objects found in the devicon.json. :pr_title, the title of the PR that this workflow was called on. :return a dictionary with the "name" entry's value matching the name in the pr_title. :raise If no object can be found, raise an Exception. """ try: pattern = re.compile(r"(?<=^new icon: )\w+ (?=\(.+\))|(?<=^update icon: )\w+ (?=\(.+\))", re.I) icon_name_index = 0 icon_name = pattern.findall(pr_title)[icon_name_index].lower().strip() # should only have one match icon = [icon for icon in icons if icon["name"] == icon_name][0] return icon except IndexError as e: # there are no match in the findall() print(e) message = "util.find_object_added_in_pr: Couldn't find an icon matching the name in the PR title.\n" \ f"PR title is: '{pr_title}'" raise Exception(message) def is_svg_in_font_attribute(svg_file_path: Path, devicon_object: dict): """ Check if svg is in devicon.json's font attribute. :param svg_file_path, the path to a single svg icon :devicon_object, an object for a single icon inside devicon.json :return true if the svg exists in the devicon_object's font attribute, false if it doesn't """ icon_version = Path(svg_file_path).stem.split('-', 1)[1] font_object = devicon_object["versions"]["font"] return icon_version in font_object valid_svg_filename_pattern = re.compile(r"-(original|plain|line)(-wordmark)?\.svg$") def is_svg_name_valid(filename: str): return valid_svg_filename_pattern.search(filename) is not None valid_svg_version_pattern = re.compile(r"^(original|plain|line)(-wordmark)?$") def is_svg_version_valid(version): return valid_svg_version_pattern.search(version) is not None