diff --git a/parse_redist.py b/parse_redist.py
index 61ada1245b0cfdf716be8645f92f587612d0a2ed..24e0449c21401aa24321aa2185b8165753c534c9 100755
--- a/parse_redist.py
+++ b/parse_redist.py
@@ -18,6 +18,7 @@ import tarfile
 import zipfile
 import sys
 import requests
+
 __version__ = "0.3.0"
 
 ARCHIVES = {}
@@ -37,214 +38,277 @@ VALIDATE = True
 UNROLLED = True
 COLLAPSE = True
 
+
 def err(msg):
-	"""Print error message and exit"""
-	print("ERROR: " + msg)
-	sys.exit(1)
+    """Print error message and exit"""
+    print("ERROR: " + msg)
+    sys.exit(1)
+
 
 def fetch_file(full_path, filename):
-	"""Download file to disk"""
-	download = requests.get(full_path)
-	if download.status_code != 200:
-		print("  -> Failed: " + filename)
-	else:
-		print(":: Fetching: " + full_path)
-		with open(filename, "wb") as file:
-			file.write(download.content)
-			print("  -> Wrote: " + filename)
+    """Download file to disk"""
+    download = requests.get(full_path)
+    if download.status_code != 200:
+        print("  -> Failed: " + filename)
+    else:
+        print(":: Fetching: " + full_path)
+        with open(filename, "wb") as file:
+            file.write(download.content)
+            print("  -> Wrote: " + filename)
+
 
 def get_hash(filename):
-	"""Calculate SHA256 checksum for file"""
-	buffer_size = 65536
-	sha256 = hashlib.sha256()
-	with open(filename, "rb") as file:
-		while True:
-			chunk = file.read(buffer_size)
-			if not chunk:
-				break
-			sha256.update(chunk)
-	return sha256.hexdigest()
+    """Calculate SHA256 checksum for file"""
+    buffer_size = 65536
+    sha256 = hashlib.sha256()
+    with open(filename, "rb") as file:
+        while True:
+            chunk = file.read(buffer_size)
+            if not chunk:
+                break
+            sha256.update(chunk)
+    return sha256.hexdigest()
+
 
 def check_hash(filename, checksum):
-	"""Compare checksum with expected"""
-	sha256 = get_hash(filename)
-	if checksum == sha256:
-		print("	 Verified sha256sum: " + sha256)
-	else:
-		print("  => Mismatch sha256sum:")
-		print("	-> Calculation: " + sha256)
-		print("	-> Expectation: " + checksum)
+    """Compare checksum with expected"""
+    sha256 = get_hash(filename)
+    if checksum == sha256:
+        print("	 Verified sha256sum: " + sha256)
+    else:
+        print("  => Mismatch sha256sum:")
+        print("	-> Calculation: " + sha256)
+        print("	-> Expectation: " + checksum)
+
 
 def flatten_tree(src, dest, tag=None):
-	if tag:
-		dest += "/" + tag
+    if tag:
+        dest += "/" + tag
+
+    """Merge hierarchy from multiple directories"""
+    try:
+        shutil.copytree(
+            src, dest, symlinks=1, dirs_exist_ok=1, ignore_dangling_symlinks=1
+        )
+    except FileExistsError:
+        pass
+    shutil.rmtree(src)
 
-	"""Merge hierarchy from multiple directories"""
-	try:
-		shutil.copytree(src, dest, symlinks=1, dirs_exist_ok=1, ignore_dangling_symlinks=1)
-	except FileExistsError:
-		pass
-	shutil.rmtree(src)
 
 def parse_artifact(parent, MANIFEST, component, platform, variant=None):
-	if variant:
-		full_path = parent + MANIFEST[component][platform][variant]['relative_path']
-	else:
-		full_path = parent + MANIFEST[component][platform]['relative_path']
-
-	filename = os.path.basename(full_path)
-
-	if RETRIEVE and not os.path.exists(filename) and not os.path.exists(parent + filename):
-		# Download archive
-		fetch_file(full_path, filename)
-		ARCHIVES[platform].append(filename)
-	elif os.path.exists(filename):
-		print("  -> Found: " + filename)
-		ARCHIVES[platform].append(filename)
-	elif os.path.exists(parent + filename):
-		print("  -> Found: " + parent + filename)
-		ARCHIVES[platform].append(parent + filename)
-	else:
-		print("  -> Artifact: " + filename)
-
-	if VALIDATE and os.path.exists(filename):
-		if variant:
-			checksum = MANIFEST[component][platform][variant]['sha256']
-		else:
-			checksum = MANIFEST[component][platform]['sha256']
-		# Compare checksum
-		check_hash(filename, checksum)
+    if variant:
+        full_path = parent + MANIFEST[component][platform][variant]["relative_path"]
+    else:
+        full_path = parent + MANIFEST[component][platform]["relative_path"]
+
+    filename = os.path.basename(full_path)
+
+    if (
+        RETRIEVE
+        and not os.path.exists(filename)
+        and not os.path.exists(parent + filename)
+    ):
+        # Download archive
+        fetch_file(full_path, filename)
+        ARCHIVES[platform].append(filename)
+    elif os.path.exists(filename):
+        print("  -> Found: " + filename)
+        ARCHIVES[platform].append(filename)
+    elif os.path.exists(parent + filename):
+        print("  -> Found: " + parent + filename)
+        ARCHIVES[platform].append(parent + filename)
+    else:
+        print("  -> Artifact: " + filename)
+
+    if VALIDATE and os.path.exists(filename):
+        if variant:
+            checksum = MANIFEST[component][platform][variant]["sha256"]
+        else:
+            checksum = MANIFEST[component][platform]["sha256"]
+        # Compare checksum
+        check_hash(filename, checksum)
+
 
 def fetch_action(parent):
-	"""Do actions while parsing JSON"""
-	for component in MANIFEST.keys():
-		if not 'name' in MANIFEST[component]:
-			continue
+    """Do actions while parsing JSON"""
+    for component in MANIFEST.keys():
+        if not "name" in MANIFEST[component]:
+            continue
 
-		if COMPONENT is not None and component != COMPONENT:
-			continue
+        if COMPONENT is not None and component != COMPONENT:
+            continue
 
-		print("\n" + MANIFEST[component]['name'] + ": " + MANIFEST[component]['version'])
+        print(
+            "\n" + MANIFEST[component]["name"] + ": " + MANIFEST[component]["version"]
+        )
 
-		for platform in MANIFEST[component].keys():
-			if "variant" in platform:
-				continue
+        for platform in MANIFEST[component].keys():
+            if "variant" in platform:
+                continue
 
-			if not platform in ARCHIVES:
-				ARCHIVES[platform] = []
+            if not platform in ARCHIVES:
+                ARCHIVES[platform] = []
 
-			if not isinstance(MANIFEST[component][platform], str):
-				if PLATFORM is not None and platform != PLATFORM:
-					print("  -> Skipping platform: " + platform)
-					continue
+            if not isinstance(MANIFEST[component][platform], str):
+                if PLATFORM is not None and platform != PLATFORM:
+                    print("  -> Skipping platform: " + platform)
+                    continue
+
+                if not "relative_path" in MANIFEST[component][platform]:
+                    for variant in MANIFEST[component][platform].keys():
+                        parse_artifact(parent, MANIFEST, component, platform, variant)
+                else:
+                    parse_artifact(parent, MANIFEST, component, platform)
 
-				if not "relative_path" in MANIFEST[component][platform]:
-					for variant in MANIFEST[component][platform].keys():
-						parse_artifact(parent, MANIFEST, component, platform, variant)
-				else:
-					parse_artifact(parent, MANIFEST, component, platform)
 
 def post_action():
-	"""Extract archives and merge directories"""
-	if len(ARCHIVES) == 0:
-		return
-
-	print("\nArchives:")
-	if not os.path.exists(OUTPUT):
-		os.makedirs(OUTPUT)
-
-	for platform in ARCHIVES:
-		for archive in ARCHIVES[platform]:
-			try:
-				binTag = archive.split("-")[3].split("_")[1]
-				print(platform, binTag)
-			except:
-				binTag = None
-
-			# Tar files
-			if UNROLLED and re.search(r"\.tar\.", archive):
-				print(":: tar: " + archive)
-				tarball = tarfile.open(archive)
-				topdir = os.path.commonprefix(tarball.getnames())
-				tarball.extractall()
-				tarball.close()
-				print("  -> Extracted: " + topdir + "/")
-				if COLLAPSE:
-					flatten_tree(topdir, OUTPUT + "/" + platform, binTag)
-
-			# Zip files
-			elif UNROLLED and re.search(r"\.zip", archive):
-				print(":: zip: " + archive)
-				with zipfile.ZipFile(archive) as zippy:
-					topdir = os.path.commonprefix(zippy.namelist())
-					zippy.extractall()
-				zippy.close()
-
-				print("  -> Extracted: " + topdir)
-				if COLLAPSE:
-					flatten_tree(topdir, OUTPUT + "/" + platform, binTag)
-
-	print("\nOutput: " + OUTPUT + "/")
-	for item in sorted(os.listdir(OUTPUT)):
-		if os.path.isdir(OUTPUT + "/" + item):
-			print(" - " + item + "/")
-		elif os.path.isfile(OUTPUT + "/" + item):
-			print(" - " + item)
+    """Extract archives and merge directories"""
+    if len(ARCHIVES) == 0:
+        return
+
+    print("\nArchives:")
+    if not os.path.exists(OUTPUT):
+        os.makedirs(OUTPUT)
+
+    for platform in ARCHIVES:
+        for archive in ARCHIVES[platform]:
+            try:
+                binTag = archive.split("-")[3].split("_")[1]
+                print(platform, binTag)
+            except:
+                binTag = None
+
+            # Tar files
+            if UNROLLED and re.search(r"\.tar\.", archive):
+                print(":: tar: " + archive)
+                tarball = tarfile.open(archive)
+                topdir = os.path.commonprefix(tarball.getnames())
+                tarball.extractall()
+                tarball.close()
+                print("  -> Extracted: " + topdir + "/")
+                if COLLAPSE:
+                    flatten_tree(topdir, OUTPUT + "/" + platform, binTag)
+
+            # Zip files
+            elif UNROLLED and re.search(r"\.zip", archive):
+                print(":: zip: " + archive)
+                with zipfile.ZipFile(archive) as zippy:
+                    topdir = os.path.commonprefix(zippy.namelist())
+                    zippy.extractall()
+                zippy.close()
+
+                print("  -> Extracted: " + topdir)
+                if COLLAPSE:
+                    flatten_tree(topdir, OUTPUT + "/" + platform, binTag)
+
+    print("\nOutput: " + OUTPUT + "/")
+    for item in sorted(os.listdir(OUTPUT)):
+        if os.path.isdir(OUTPUT + "/" + item):
+            print(" - " + item + "/")
+        elif os.path.isfile(OUTPUT + "/" + item):
+            print(" - " + item)
+
 
 # If running standalone
-if __name__ == '__main__':
-	# Parse CLI arguments
-	PARSER = argparse.ArgumentParser()
-	# Input options
-	PARSER_GROUP = PARSER.add_mutually_exclusive_group(required=True)
-	PARSER_GROUP.add_argument('-u', '--url', dest='url', help='URL to manifest')
-	PARSER_GROUP.add_argument('-l', '--label', dest='label', help='Release label version')
-	PARSER.add_argument('-p', '--product', dest='product', help='Product name')
-	PARSER.add_argument('-o', '--output', dest='output', help='Output directory')
-	# Filter options
-	PARSER.add_argument('--component', dest='component', help='Component name')
-	PARSER.add_argument('--os', dest='os', help='Operating System')
-	PARSER.add_argument('--arch', dest='arch', help='Architecture')
-	# Toggle actions
-	PARSER.add_argument('-w', '--download', dest='retrieve', action='store_true', \
-		 help='Download archives', default=True)
-	PARSER.add_argument('-W', '--no-download', dest='retrieve', action='store_false', \
-		 help='Parse manifest without downloads')
-	PARSER.add_argument('-s', '--checksum', dest='validate', action='store_true', \
-		 help='Verify SHA256 checksum', default=True)
-	PARSER.add_argument('-S', '--no-checksum', dest='validate', action='store_false', \
-		 help='Skip SHA256 checksum validation')
-	PARSER.add_argument('-x', '--extract', dest='unrolled', action='store_true', \
-		 help='Extract archives', default=True)
-	PARSER.add_argument('-X', '--no-extract', dest='unrolled', action='store_false', \
-		 help='Do not extract archives')
-	PARSER.add_argument('-f', '--flatten', dest='collapse', action='store_true', \
-		 help='Collapse directories', default=True)
-	PARSER.add_argument('-F', '--no-flatten', dest='collapse', action='store_false', \
-		 help='Do not collapse directories')
-
-	ARGS = PARSER.parse_args()
-	#print(ARGS)
-	RETRIEVE = ARGS.retrieve
-	VALIDATE = ARGS.validate
-	UNROLLED = ARGS.unrolled
-	COLLAPSE = ARGS.collapse
-
-	# Define variables
-	if ARGS.label is not None:
-		LABEL = ARGS.label
-	if ARGS.product is not None:
-		PRODUCT = ARGS.product
-	if ARGS.url is not None:
-		URL = ARGS.url
-	if ARGS.output is not None:
-		OUTPUT = ARGS.output
-	if ARGS.component is not None:
-		COMPONENT = ARGS.component
-	if ARGS.os is not None:
-		OS = ARGS.os
-	if ARGS.arch is not None:
-		ARCH = ARGS.arch
+if __name__ == "__main__":
+    # Parse CLI arguments
+    PARSER = argparse.ArgumentParser()
+    # Input options
+    PARSER_GROUP = PARSER.add_mutually_exclusive_group(required=True)
+    PARSER_GROUP.add_argument("-u", "--url", dest="url", help="URL to manifest")
+    PARSER_GROUP.add_argument(
+        "-l", "--label", dest="label", help="Release label version"
+    )
+    PARSER.add_argument("-p", "--product", dest="product", help="Product name")
+    PARSER.add_argument("-o", "--output", dest="output", help="Output directory")
+    # Filter options
+    PARSER.add_argument("--component", dest="component", help="Component name")
+    PARSER.add_argument("--os", dest="os", help="Operating System")
+    PARSER.add_argument("--arch", dest="arch", help="Architecture")
+    # Toggle actions
+    PARSER.add_argument(
+        "-w",
+        "--download",
+        dest="retrieve",
+        action="store_true",
+        help="Download archives",
+        default=True,
+    )
+    PARSER.add_argument(
+        "-W",
+        "--no-download",
+        dest="retrieve",
+        action="store_false",
+        help="Parse manifest without downloads",
+    )
+    PARSER.add_argument(
+        "-s",
+        "--checksum",
+        dest="validate",
+        action="store_true",
+        help="Verify SHA256 checksum",
+        default=True,
+    )
+    PARSER.add_argument(
+        "-S",
+        "--no-checksum",
+        dest="validate",
+        action="store_false",
+        help="Skip SHA256 checksum validation",
+    )
+    PARSER.add_argument(
+        "-x",
+        "--extract",
+        dest="unrolled",
+        action="store_true",
+        help="Extract archives",
+        default=True,
+    )
+    PARSER.add_argument(
+        "-X",
+        "--no-extract",
+        dest="unrolled",
+        action="store_false",
+        help="Do not extract archives",
+    )
+    PARSER.add_argument(
+        "-f",
+        "--flatten",
+        dest="collapse",
+        action="store_true",
+        help="Collapse directories",
+        default=True,
+    )
+    PARSER.add_argument(
+        "-F",
+        "--no-flatten",
+        dest="collapse",
+        action="store_false",
+        help="Do not collapse directories",
+    )
+
+    ARGS = PARSER.parse_args()
+    # print(ARGS)
+    RETRIEVE = ARGS.retrieve
+    VALIDATE = ARGS.validate
+    UNROLLED = ARGS.unrolled
+    COLLAPSE = ARGS.collapse
+
+    # Define variables
+    if ARGS.label is not None:
+        LABEL = ARGS.label
+    if ARGS.product is not None:
+        PRODUCT = ARGS.product
+    if ARGS.url is not None:
+        URL = ARGS.url
+    if ARGS.output is not None:
+        OUTPUT = ARGS.output
+    if ARGS.component is not None:
+        COMPONENT = ARGS.component
+    if ARGS.os is not None:
+        OS = ARGS.os
+    if ARGS.arch is not None:
+        ARCH = ARGS.arch
 
 
 #
@@ -253,22 +317,22 @@ if __name__ == '__main__':
 
 # Sanity check
 if not UNROLLED:
-	COLLAPSE = False
+    COLLAPSE = False
 
 # Short-hand
 if LABEL:
-	if PRODUCT:
-		URL = f"{DOMAIN}/compute/{PRODUCT}/redist/redistrib_{LABEL}.json"
-	else:
-		err("Must pass --product argument")
+    if PRODUCT:
+        URL = f"{DOMAIN}/compute/{PRODUCT}/redist/redistrib_{LABEL}.json"
+    else:
+        err("Must pass --product argument")
 
 # Concatentate
 if ARCH is not None and OS is not None:
-	PLATFORM = f"{OS}-{ARCH}"
+    PLATFORM = f"{OS}-{ARCH}"
 elif ARCH is not None and OS is None:
-	err("Must pass --os argument")
+    err("Must pass --os argument")
 elif OS is not None and ARCH is None:
-	err("Must pass --arch argument")
+    err("Must pass --arch argument")
 
 #
 # Run
@@ -276,19 +340,19 @@ elif OS is not None and ARCH is None:
 
 # Parse JSON
 if os.path.isfile(URL):
-	with open(URL, "rb") as f:
-		MANIFEST = json.load(f)
+    with open(URL, "rb") as f:
+        MANIFEST = json.load(f)
 else:
-	try:
-		MANIFEST = requests.get(URL).json()
-	except json.decoder.JSONDecodeError:
-		err("redistrib JSON manifest file not found")
+    try:
+        MANIFEST = requests.get(URL).json()
+    except json.decoder.JSONDecodeError:
+        err("redistrib JSON manifest file not found")
 
 print(":: Parsing JSON: " + URL)
 
 # Do stuff
 fetch_action(os.path.dirname(URL) + "/")
 if UNROLLED:
-	post_action()
+    post_action()
 
 ### END ###