Skip to content
204 changes: 104 additions & 100 deletions bin/patch-repos-with-validator-commit-hash.py
Original file line number Diff line number Diff line change
@@ -1,39 +1,60 @@
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"
FILE_PATH = os.path.abspath(getsourcefile(lambda: 0))
# 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):
Expand All @@ -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)
Expand Down Expand Up @@ -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)


Expand All @@ -133,67 +141,63 @@ 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))
print(padded_repo+BASE_DIR+"/"+repo)
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()