diff --git a/bin/patch-repos-with-validator-commit-hash.py b/bin/patch-repos-with-validator-commit-hash.py index f574f39b7..8a711b171 100644 --- a/bin/patch-repos-with-validator-commit-hash.py +++ b/bin/patch-repos-with-validator-commit-hash.py @@ -1,9 +1,10 @@ import os -import sys import time -import pkg_resources +import json +import argparse from inspect import getsourcefile + FRONT_END_ROOT_DIR = "fecfile-web-app" BACK_END_ROOT_DIR = "fecfile-web-api" VALIDATOR_ROOT_DIR = "fecfile-validate" @@ -11,29 +12,49 @@ # Get the directory three steps above the directory containing this file BASE_DIR = "/".join(FILE_PATH.split("/")[:-3]) YES_TO_ALL = False +QUICK = False -def gitpython_is_installed(): - installed_packages = pkg_resources.working_set - for package in installed_packages: - if package.key == "gitpython": - return True - return False - - -def get_commit_hash(): +def get_commit_hash_automatic(): import git os.chdir(BASE_DIR) os.chdir(VALIDATOR_ROOT_DIR) repo = git.Repo() - commit_hash = repo.head.object.hexsha + return repo.head.object.hexsha + - print("\nValidator Commit Hash:", commit_hash+"\n") - sleep(1) +def get_commit_hash_manual(skip_gitpython_install_recommendation): + if not skip_gitpython_install_recommendation: + print( + "\n\n" + "This script can optionally use the gitpython module to automatically\n" + "retrieve the most recent commit hash of your validate repo's active branch" + "\n\n" + "You can install it with: python -m pip install gitpython\n" + "\n\n" + "Alternatively:" + ) - return commit_hash + return input("Please input the commit hash: ") + + +def get_commit_hash(): + try: + print("\n\nAttempting to automatically retrieve commit hash...") + commit_hash = get_commit_hash_automatic() + + sleep(1) + print("\nValidator Commit Hash:", commit_hash+"\n") + correct = ask_true_false("Is this correct?") + if correct: + return commit_hash + else: + return get_commit_hash_manual(True) + except ModuleNotFoundError: + print("Failed to automatically retrieve commit hash") + return get_commit_hash_manual(YES_TO_ALL) def patch_app(commit_hash): @@ -44,21 +65,35 @@ def patch_app(commit_hash): print("Patching package.json...") sleep(0.5) - packages = open("package.json", "r") - package_lines = "" - for line in packages: - if "fecfile-validate" in line: - key, value = line.split(": ") - url = value.split("#")[0] - new_line = key+": "+url+"#"+commit_hash+'",\n' - package_lines += new_line + package = open("package.json", "r") + package_manifest = json.load(package) + package.close() + + package_manifest["dependencies"]["fecfile-validate"] = ( + f"https://github.com/fecgov/fecfile-validate#{commit_hash}" + ) + + allow_scripts = package_manifest["allowScripts"] + allow_script_keys = allow_scripts.keys() + + new_allowed_scripts = {} + for allow_script_key in allow_script_keys: + if "fecfile-validate" in allow_script_key: + script_name = f"github:fecgov/fecfile-validate#{commit_hash}" + new_allowed_scripts[script_name] = allow_scripts[allow_script_key] else: - package_lines += line + new_allowed_scripts[allow_script_key] = allow_scripts[allow_script_key] - packages.close() - new_packages = open("package.json", "w") - new_packages.write(package_lines) - new_packages.close() + package_manifest["allowScripts"] = new_allowed_scripts + + package = open("package.json", "w") + json.dump( + package_manifest, + package, + indent=2, + ) + package.write("\n") + package.close() print("Done!\n") sleep(0.5) @@ -91,35 +126,8 @@ def patch_api(commit_hash): sleep(0.5) -def delete_app_cache(): - print("Deleting .angular & node_modules...") - - os.chdir(BASE_DIR) - os.chdir(FRONT_END_ROOT_DIR) - os.chdir("front-end") - os.system("rm -r .angular") - os.system("rm -r node_modules") - - print("Done!\nBe sure to run `npm install`\n") - sleep(0.5) - - -def delete_api_docker_images(docker_images): - print("Deleting .angular & node_modules...") - os.chdir(BASE_DIR) - os.chdir(BACK_END_ROOT_DIR) - print("Spinning down Docker...") - os.system("docker-compose down") - for image in docker_images: - print("Removing", image, "...") - os.system("docker rmi "+image) - - print("Done!\nBe sure to run `docker-compose up`") - sleep(0.5) - - def sleep(t): - if "-q" not in sys.argv: + if not QUICK: time.sleep(t) @@ -133,7 +141,7 @@ def ask_true_false(question): return True -def check_user_is_ready(): +def check_directories_are_correct(): print("This script acts upon the active branches of the following repos:") for repo in [FRONT_END_ROOT_DIR, BACK_END_ROOT_DIR, VALIDATOR_ROOT_DIR]: padded_repo = repo+" "*(48-len(repo)) @@ -141,59 +149,55 @@ def check_user_is_ready(): return ask_true_false("\nAre these directories correct?") -def help(): - help_string = """ - This script uses the active branch of your fecfile-validate repo to - update the validator commit hashes of your local app and api repos. - Optionally, it also deletes the .angular and node_modules directories - as well as the relevant docker images. - - For this script to work, it needs to be placed in the directory - wherein each of the three repos can be found. - - Command line arguments: - -y or --yes | auto-confirm all options - """ - print(help_string) - - -def main(): - if "-h" in sys.argv or "--help" in sys.argv: - return help() - if "-y" in sys.argv or "--yes" in sys.argv: +def parse_args(): + description = ( + "This script updates the validator commit hash in fecfile-web-api's\n" + "requirements.txt file and in fecfile-web-app's package.json file.\n\n" + "If the gitpython module is installed, this script will automatically\n" + "retrieve the commit hash for the most recent commit on the working\n" + "branch of your fecfile-validate repo. Alternatively, you can enter\n" + "the commit hash manually." + ) + + parser = argparse.ArgumentParser( + prog="patch-repos-with-validator-commit-hash", + description=description, + ) + + parser.add_argument( + '-y', + '--yes', + action="store_true", + default=False, + help="auto-confirm all y/n prompts" + ) + parser.add_argument( + '-q', + '--quick', + action="store_true", + default=False, + help="Skip all sleep() calls" + ) + + args = parser.parse_args() + if args.yes: global YES_TO_ALL YES_TO_ALL = True + if args.quick: + global QUICK + QUICK = True - if not gitpython_is_installed(): - print("Please install gitpython!") - print("python -m pip install gitpython") - return - if not check_user_is_ready(): +def main(): + parse_args() + + if not check_directories_are_correct(): return commit_hash = get_commit_hash() patch_app(commit_hash) patch_api(commit_hash) - if ask_true_false( - "Would you like to delete the .angular and node_modules directories within " + - FRONT_END_ROOT_DIR - ): - delete_app_cache() - - docker_images = [ - "fecfile-db", - "fecfile-api", - "fecfile-celery-worker", - "redis:6.2-alpine" - ] - if ask_true_false( - "Would you like to delete the following docker images?\n" + - "\n".join(docker_images)+"\n" - ): - delete_api_docker_images(docker_images) - if __name__ == "__main__": main()