Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Convert AutoPkg recipes to AppPkgCreator
#!/usr/bin/python
"""
Name: PkgCreator_to_AppPkgCreator.py
Description: Script for converting compatible AutoPkg "pkg" type recipes from using
PkgRootCreator-Copier-PkgCreator to using AppPkgCreator. Be sure to `cd` to
your AutoPkg recipes folder before running this script.
Author: Elliot Jordan <elliot@elliotjordan.com>
Created: 2019-02-13
Last Modified: 2019-05-19
Version: 1.1
"""
import os
import plistlib
from xml.parsers.expat import ExpatError
def evaluate(recipe, recipe_path):
"""Perform conversion to AppPkgCreator."""
if "Cannot use AppPkgCreator" in recipe.get("Description", "") + recipe.get(
"Comment", ""
):
# We've previously tried and failed to use AppPkgCreator, so skip this recipe.
return
if "Process" not in recipe:
# This recipe doesn't have a process.
return
process = recipe.get("Process")
if len(process) < 3:
# This recipe doesn't use PkgRootCreator-Copier-PkgCreator.
return
if "AppPkgCreator" in [x["Processor"] for x in process]:
# This recipe already uses AppPkgCreator.
return
old_procs = {"PkgRootCreator": -1, "Copier": -1, "PkgCreator": -1}
for old_proc in old_procs:
for idx, processor in enumerate([x["Processor"] for x in process]):
if processor == old_proc:
old_procs[old_proc] = idx
indexes = (
old_procs["PkgRootCreator"],
old_procs["Copier"],
old_procs["PkgCreator"],
)
if sorted(indexes) != list(range(min(indexes), max(indexes) + 1)):
# PkgRootCreator-Copier-PkgCreator not found in sequential order.
return
pkgrootcreator_model_args = {
"pkgdirs": {"Applications": "0775"},
"pkgroot": "%RECIPE_CACHE_DIR%/%NAME%",
}
if process[indexes[0]]["Arguments"] != pkgrootcreator_model_args:
# PkgRootCreator arguments are non-standard.
return
copier_source_path = os.path.split(
recipe["Process"][indexes[1]]["Arguments"]["source_path"]
)
if copier_source_path[0] != "%pathname%" or not copier_source_path[1].endswith(
".app"
):
# Copier arguments are non-standard.
# TODO: Might be able to use Copier source_path as the AppPkgCreator app_path in some cases.
return
if "scripts" in process[indexes[2]]["Arguments"]["pkg_request"]:
# PkgCreator includes scripts, which AppPkgCreator does not support.
return
print("Recipe {} is eligible for AppPkgCreator. Converting...".format(recipe_path))
# Remove PkgRootCreator
del recipe["Process"][indexes[0]]
# Remove Copier, which is now at the PkgRootCreator index.
del recipe["Process"][indexes[0]]
# Remove PkgCreator, which is now at the PkgRootCreator index.
del recipe["Process"][indexes[0]]
# Insert AppPkgCreator.
recipe["Process"].insert(indexes[0], {"Processor": "AppPkgCreator"})
# Update minimum AutoPkg version.
recipe["MinimumVersion"] = "1.0.0"
plistlib.writePlist(recipe, recipe_path)
def main():
"""Main process."""
# Extensions to include in converting.
target_file_exts = (".pkg.recipe",)
# Gather list of eligible files.
for root, dirs, files in os.walk("."):
dirs[:] = [d for d in dirs if not d.startswith(".")]
for filename in files:
if filename.endswith(target_file_exts):
recipe_path = os.path.join(root, filename)
try:
recipe = plistlib.readPlist(recipe_path)
evaluate(recipe, recipe_path)
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
You can’t perform that action at this time.