diff --git a/README.md b/README.md index e25ebe4..b55e7f5 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ For any hook in this repo you wish to use, add the following to your pre-commit ```yaml - repo: https://github.com/homebysix/pre-commit-macadmin - rev: v1.3.0 + rev: v1.4.0 hooks: - id: check-plists # - id: ... @@ -114,7 +114,7 @@ When combining arguments that take lists (for example: `--required-keys`, `--cat ```yaml - repo: https://github.com/homebysix/pre-commit-macadmin - rev: v1.3.0 + rev: v1.4.0 hooks: - id: check-munki-pkgsinfo args: ['--catalogs', 'testing', 'stable', '--'] @@ -124,7 +124,7 @@ But if you also use the `--categories` argument, you would move the trailing `-- ```yaml - repo: https://github.com/homebysix/pre-commit-macadmin - rev: v1.3.0 + rev: v1.4.0 hooks: - id: check-munki-pkgsinfo args: ['--catalogs', 'testing', 'stable', '--categories', 'Design', 'Engineering', 'Web Browsers', '--'] @@ -136,7 +136,7 @@ If it looks better to your eye, feel free to use a multi-line list for long argu ```yaml - repo: https://github.com/homebysix/pre-commit-macadmin - rev: v1.3.0 + rev: v1.4.0 hooks: - id: check-munki-pkgsinfo args: [ diff --git a/pre_commit_hooks/check_autopkg_recipes.py b/pre_commit_hooks/check_autopkg_recipes.py index c0037f0..a6bf494 100755 --- a/pre_commit_hooks/check_autopkg_recipes.py +++ b/pre_commit_hooks/check_autopkg_recipes.py @@ -288,7 +288,7 @@ def validate_required_proc_for_types(process, filename): } passed = True - processors = [x["Processor"] for x in process] + processors = [x.get("Processor") for x in process] for recipe_type in required_proc_for_type: req_procs = required_proc_for_type[recipe_type] type_hint = ".{}.".format(recipe_type) @@ -323,6 +323,9 @@ def main(argv=None): if args.strict: args.ignore_min_vers_before = "0.1.0" + # Track identifiers we've seen. + seen_identifiers = [] + retval = 0 for filename in args.filenames: try: @@ -339,6 +342,13 @@ def main(argv=None): retval = 1 break # No need to continue checking this file + # Ensure the recipe identifier isn't duplicated. + if recipe["Identifier"] in seen_identifiers: + print('{}: Identifier "{}" is shared by another recipe in this repo.') + retval = 1 + else: + seen_identifiers.append(recipe["Identifier"]) + # Validate identifiers. if args.override_prefix and "Process" not in recipe: if not validate_override_prefix(recipe, filename, args.override_prefix): diff --git a/pre_commit_hooks/check_munki_pkgsinfo.py b/pre_commit_hooks/check_munki_pkgsinfo.py index 53fbf81..0bea783 100755 --- a/pre_commit_hooks/check_munki_pkgsinfo.py +++ b/pre_commit_hooks/check_munki_pkgsinfo.py @@ -126,6 +126,36 @@ def main(argv=None): ) retval = 1 + # Ensure all pkginfo scripts have a proper shebang. + shebangs = ( + "#!/bin/bash", + "#!/bin/sh", + "#!/bin/zsh", + "#!/usr/bin/osascript", + "#!/usr/bin/perl", + "#!/usr/bin/python", + "#!/usr/bin/ruby", + "#!/usr/local/munki/python", + ) + script_types = ( + "installcheck_script", + "uninstallcheck_script", + "postinstall_script", + "postuninstall_script", + "preinstall_script", + "preuninstall_script", + "uninstall_script", + ) + for script_type in script_types: + if script_type in pkginfo: + if all(not pkginfo[script_type].startswith(x + "\n") for x in shebangs): + print( + "{}: has a {} that does not start with a shebang.".format( + filename, script_type + ) + ) + retval = 1 + # Ensure the items_to_copy list does not include trailing slashes. # Credit to @bruienne for this idea. # https://gist.github.com/bruienne/9baa958ec6dbe8f09d94#file-munki_fuzzinator-py-L211-L219 diff --git a/pre_commit_hooks/check_munkipkg_buildinfo.py b/pre_commit_hooks/check_munkipkg_buildinfo.py index d2cc522..1b4d659 100755 --- a/pre_commit_hooks/check_munkipkg_buildinfo.py +++ b/pre_commit_hooks/check_munkipkg_buildinfo.py @@ -29,28 +29,24 @@ def build_argument_parser(): def validate_buildinfo_key_types(buildinfo, filename): """Ensure build-info files contain the proper types.""" - # Remap basestring in Python 3 - # Credit: https://github.com/munki/munki/blob/Munki3dev/code/client/munkilib/wrappers.py#L121-L129 - try: - _ = basestring - except NameError: - basestring = str # pylint: disable=W0622 + # Remap string type to support unicode in both Python 2 and 3 + string = basestring if sys.version_info.major == 2 else str # Pkginfo keys and their known types. Omitted keys are left unvalidated. # Source: https://github.com/munki/munki-pkg # Last updated 2019-06-27. buildinfo_types = { "distribution_style": bool, - "identifier": basestring, - "install_location": basestring, - "name": basestring, - "ownership": basestring, - "postinstall_action": basestring, + "identifier": string, + "install_location": string, + "name": string, + "ownership": string, + "postinstall_action": string, "preserve_xattr": bool, - "product id": basestring, + "product id": string, "signing_info": dict, "suppress_bundle_relocation": bool, - "version": basestring, + "version": string, } passed = True diff --git a/pre_commit_hooks/util.py b/pre_commit_hooks/util.py index c6c3a89..37ed79a 100644 --- a/pre_commit_hooks/util.py +++ b/pre_commit_hooks/util.py @@ -1,5 +1,6 @@ #!/usr/bin/python +import sys from datetime import datetime @@ -19,12 +20,8 @@ def validate_pkginfo_key_types(pkginfo, filename): Used for AutoPkg- and Munki-related hooks. """ - # Remap basestring in Python 3 - # Credit: https://github.com/munki/munki/blob/Munki3dev/code/client/munkilib/wrappers.py#L121-L129 - try: - _ = basestring - except NameError: - basestring = str # pylint: disable=W0622 + # Remap string type to support unicode in both Python 2 and 3 + string = basestring if sys.version_info.major == 2 else str # Pkginfo keys and their known types. Omitted keys are left unvalidated. # Source: https://github.com/munki/munki/wiki/Supported-Pkginfo-Keys @@ -35,58 +32,58 @@ def validate_pkginfo_key_types(pkginfo, filename): "autoremove": bool, "blocking_applications": list, "catalogs": list, - "category": basestring, + "category": string, "copy_local": bool, - "description": basestring, - "developer": basestring, - "display_name": basestring, + "description": string, + "developer": string, + "display_name": string, "force_install_after_date": datetime, "forced_install": bool, "forced_uninstall": bool, - "icon_name": basestring, - "installable_condition": basestring, + "icon_name": string, + "installable_condition": string, "installed_size": int, - "installer_item_hash": basestring, - "installer_item_location": basestring, + "installer_item_hash": string, + "installer_item_location": string, "installer_item_size": int, - "installer_type": basestring, + "installer_type": string, "installs": list, "items_to_copy": list, "installer_choices_xml": list, "installer_environment": dict, - "localized_basestrings": dict, - "minimum_munki_version": basestring, - "minimum_os_version": basestring, - "maximum_os_version": basestring, - "name": basestring, - "notes": basestring, - "PackageCompleteURL": basestring, - "PackageURL": basestring, - "package_path": basestring, - "installcheck_script": basestring, - "uninstallcheck_script": basestring, + "localized_strings": dict, + "minimum_munki_version": string, + "minimum_os_version": string, + "maximum_os_version": string, + "name": string, + "notes": string, + "PackageCompleteURL": string, + "PackageURL": string, + "package_path": string, + "installcheck_script": string, + "uninstallcheck_script": string, "OnDemand": bool, - "postinstall_script": basestring, - "postuninstall_script": basestring, + "postinstall_script": string, + "postuninstall_script": string, "precache": bool, "preinstall_alert": dict, "preuninstall_alert": dict, "preupgrade_alert": dict, - "preinstall_script": basestring, - "preuninstall_script": basestring, + "preinstall_script": string, + "preuninstall_script": string, "receipts": list, "requires": list, - "RestartAction": basestring, + "RestartAction": string, "supported_architectures": list, "suppress_bundle_relocation": bool, "unattended_install": bool, "unattended_uninstall": bool, - "uninstall_method": basestring, - "uninstall_script": basestring, - "uninstaller_item_location": basestring, + "uninstall_method": string, + "uninstall_script": string, + "uninstaller_item_location": string, "uninstallable": bool, "update_for": list, - "version": basestring, + "version": string, } passed = True diff --git a/setup.py b/setup.py index 561cab5..bf04437 100755 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ name="pre-commit-macadmin", description="Pre-commit hooks for Mac admins, client engineers, and IT consultants.", url="https://github.com/homebysix/pre-commit-macadmin", - version="1.3.0", + version="1.4.0", author="Elliot Jordan", author_email="elliot@elliotjordan.com", packages=["pre_commit_hooks"],