Created
January 4, 2021 02:11
-
-
Save homebysix/1428e8b31cc6dc676ba822f4b1d376d0 to your computer and use it in GitHub Desktop.
URLMover
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/local/autopkg/python | |
# encoding: utf-8 | |
# URLMover | |
# Copyright 2019-2021 Elliot Jordan | |
# | |
# Licensed under the Apache License, Version 2.0 (the "License"); | |
# you may not use this file except in compliance with the License. | |
# You may obtain a copy of the License at | |
# | |
# http://www.apache.org/licenses/LICENSE-2.0 | |
# | |
# Unless required by applicable law or agreed to in writing, software | |
# distributed under the License is distributed on an "AS IS" BASIS, | |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
# See the License for the specific language governing permissions and | |
# limitations under the License. | |
"""url_mover.py. | |
Script for moving URLs from input variables into processor arguments in | |
AutoPkg recipes. | |
""" | |
import argparse | |
import os | |
import plistlib | |
from xml.parsers.expat import ExpatError | |
def build_argument_parser(): | |
"""Build and return the argument parser.""" | |
parser = argparse.ArgumentParser( | |
description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter | |
) | |
parser.add_argument("repo_path", help="Path to search for AutoPkg recipes.") | |
parser.add_argument( | |
"--auto", | |
action="store_true", | |
default=False, | |
help="Automatically apply suggested changes to recipes. Only recommended " | |
"for repos you manage or are submitting a pull request to. (Applying " | |
"changes to repos added using `autopkg repo-add` may result in failure " | |
"to update the repo in the future.)", | |
) | |
parser.add_argument( | |
"-v", | |
"--verbose", | |
action="count", | |
default=0, | |
help="Print additional output useful for " | |
"troubleshooting. (Can be specified multiple times.)", | |
) | |
return parser | |
def evaluate(recipe, recipe_path, args): | |
"""Evaluate whether a recipe is eligible to move URL from Input keys into | |
processor arguments.""" | |
if args.verbose > 0: | |
print("Evaluating %s..." % (recipe_path)) | |
if "Process" not in recipe: | |
if args.verbose > 1: | |
print(" Skipping: This recipe has no process.") | |
return | |
url_map = { | |
"DOWNLOAD_URL": ("URLDownloader", "url"), | |
"GITHUB_REPO": ("GitHubReleasesInfoProvider", "github_repo"), | |
"SPARKLE_FEED_URL": ("SparkleUpdateInfoProvider", "appcast_url"), | |
} | |
process = recipe.get("Process") | |
for url_src, url_dest in url_map.items(): | |
if url_src not in recipe.get("Input", {}): | |
continue | |
proc_idx = [ | |
idx for idx, x in enumerate(process) if x["Processor"] == url_dest[0] | |
] | |
if len(proc_idx) != 1: | |
continue | |
proc_idx = proc_idx[0] | |
if not args.auto: | |
print( | |
"✨ Recipe %s is eligible for moving %s to %s arguments." | |
% (recipe_path, url_src, url_dest[0]) | |
) | |
else: | |
print( | |
"✨ Recipe %s: moving %s to %s arguments." | |
% (recipe_path, url_src, url_dest[0]) | |
) | |
# Save the URL value and remove from Input. | |
url_value = recipe["Input"][url_src] | |
del recipe["Input"][url_src] | |
# Replace the processor arguments. | |
recipe["Process"][proc_idx]["Arguments"][url_dest[1]] = url_value | |
with open(recipe_path, "wb") as openfile: | |
plistlib.dump(recipe, openfile) | |
def main(): | |
"""Main process.""" | |
# Parse command line arguments. | |
argparser = build_argument_parser() | |
args = argparser.parse_args() | |
# Extensions to include in converting. | |
target_file_exts = (".download.recipe",) | |
# Gather list of eligible files. | |
for root, dirs, files in os.walk(os.path.expanduser(args.repo_path)): | |
dirs[:] = [d for d in dirs if not d.startswith(".")] | |
for idx, filename in enumerate(files): | |
if filename.endswith(target_file_exts): | |
recipe_path = os.path.join(root, filename) | |
try: | |
with open(recipe_path, "rb") as openfile: | |
recipe = plistlib.load(openfile) | |
evaluate(recipe, recipe_path, args) | |
except ExpatError: | |
print("[ERROR] Unable to read %s", recipe_path) | |
continue | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment