diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 0336396..3070f04 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -47,7 +47,7 @@ jobs: with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. + # By default, queries listed here will override any specified in a config file. # Prefix the list here with "+" to use these queries and those in the config file. # queries: ./path/to/local/query, your-org/your-repo/queries@main diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index 5fba034..b0e768b 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -11,7 +11,7 @@ description: This hook checks AutoPkg recipes to ensure they contain required top-level keys. entry: check-autopkg-recipes language: python - files: '\.recipe$' + files: '\.recipe(\.plist|\.yaml|\.json)?$' types: [text] - id: check-git-config-email @@ -97,7 +97,7 @@ description: This hook prevents AutoPkg overrides from being added to the repo. entry: forbid-autopkg-overrides language: python - files: '\.recipe$' + files: '\.recipe(\.plist|\.yaml|\.json)?$' types: [text] - id: forbid-autopkg-trust-info @@ -105,7 +105,7 @@ description: This hook prevents AutoPkg recipes with trust info from being added to the repo. entry: forbid-autopkg-trust-info language: python - files: '\.recipe$' + files: '\.recipe(\.plist|\.yaml|\.json)?$' types: [text] - id: munki-makecatalogs diff --git a/CHANGELOG.md b/CHANGELOG.md index 7114d69..f39c68c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,17 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [1.10.0] - 2021-02-21 + +### Added +- In anticipation of AutoPkg 2.3, now supports checking YAML recipes (must have extension `.recipe.yaml`). +- In anticipation of AutoPkg 2.3, supports additional AutoPkg plist extension `.recipe.plist`. +- Supports JSON AutoPkg recipes (must have extension `.recipe.json`). NOTE: AutoPkg itself does not yet support JSON recipes. +- Built placeholder for checking for unused AutoPkg recipe input variables in the future. Check is disabled for now. + +### Fixed +- Fixed a bug preventing display of AutoPkg recipe path and identifier if duplicate identifier is found in the repo. + ## [1.9.0] - 2021-01-18 ### Added diff --git a/README.md b/README.md index 1011165..7946791 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,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.9.0 + rev: v1.10.0 hooks: - id: check-plists # - id: ... @@ -121,7 +121,7 @@ When combining arguments that take lists (for example: `--required-keys`, `--cat ```yaml - repo: https://github.com/homebysix/pre-commit-macadmin - rev: v1.9.0 + rev: v1.10.0 hooks: - id: check-munki-pkgsinfo args: ['--catalogs', 'testing', 'stable', '--'] @@ -131,7 +131,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.9.0 + rev: v1.10.0 hooks: - id: check-munki-pkgsinfo args: ['--catalogs', 'testing', 'stable', '--categories', 'Design', 'Engineering', 'Web Browsers', '--'] @@ -143,7 +143,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.9.0 + rev: v1.10.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 09984e0..f339139 100755 --- a/pre_commit_hooks/check_autopkg_recipes.py +++ b/pre_commit_hooks/check_autopkg_recipes.py @@ -4,6 +4,7 @@ requirements.""" import argparse +import json import os import plistlib import sys @@ -11,6 +12,8 @@ from distutils.version import LooseVersion from xml.parsers.expat import ExpatError +from ruamel import yaml + from pre_commit_hooks.util import ( validate_pkginfo_key_types, validate_required_keys, @@ -280,6 +283,30 @@ def validate_no_superclass_procs(process, filename): return passed +# def validate_unused_input_vars(recipe, recipe_text, filename): +# """Warn if any input variables are not referenced in the recipe.""" + +# # List of variables that are commonly allowed to be unreferenced (lowercase). +# ignored_vars = ( +# "name", +# "pkginfo", +# ) + +# passed = True +# for input_var, _ in recipe.get("Input", {}).items(): +# if input_var.lower() in ignored_vars: +# continue +# subst = "%" + input_var + "%" +# if subst not in recipe_text: +# print( +# "{}: WARNING: Input variable {} not referenced in recipe.".format( +# filename, input_var +# ) +# ) + +# return passed + + def validate_no_var_in_app_path(process, filename): """Ensure %NAME% is not used in app paths that should be hard coded.""" @@ -458,14 +485,40 @@ def main(argv=None): retval = 0 for filename in args.filenames: - try: - with open(filename, "rb") as openfile: - recipe = plistlib.load(openfile) - except (ExpatError, ValueError) as err: - print("{}: plist parsing error: {}".format(filename, err)) - retval = 1 - break # No need to continue checking this file + if filename.endswith(".yaml"): + try: + # try to read it as yaml + with open(filename, "rb") as f: + recipe = yaml.safe_load(f) + except Exception as err: + print("{}: yaml parsing error: {}".format(filename, err)) + retval = 1 + break # No need to continue checking this file + + elif filename.endswith(".json"): + try: + # try to read it as json + with open(filename, "rb") as f: + recipe = json.load(f) + except Exception as err: + print("{}: json parsing error: {}".format(filename, err)) + retval = 1 + break # No need to continue checking this file + + else: + try: + # try to read it as a plist + with open(filename, "rb") as f: + recipe = plistlib.load(f) + except Exception as err: + print("{}: plist parsing error: {}".format(filename, err)) + retval = 1 + break # No need to continue checking this file + + # For future implementation of validate_unused_input_vars() + # with open(filename, "r") as openfile: + # recipe_text = openfile.read() # Top level keys that all AutoPkg recipes should contain. required_keys = ["Identifier"] @@ -475,7 +528,11 @@ def main(argv=None): # Ensure the recipe identifier isn't duplicated. if recipe["Identifier"] in seen_identifiers: - print('{}: Identifier "{}" is shared by another recipe in this repo.') + print( + '{}: Identifier "{}" is shared by another recipe in this repo.'.format( + filename, recipe["Identifier"] + ) + ) retval = 1 else: seen_identifiers.append(recipe["Identifier"]) @@ -494,6 +551,13 @@ def main(argv=None): ) retval = 1 + # Validate that all input variables are used. + # (Disabled for now because it's a little too opinionated, and doesn't take into account + # whether environmental variables are used in custom processors.) + # if args.strict: + # if not validate_unused_input_vars(recipe, recipe_text, filename): + # retval = 1 + # If the Input key contains a pkginfo dict, make a best effort to validate its contents. input_key = recipe.get("Input", recipe.get("input", recipe.get("INPUT"))) if input_key and "pkginfo" in input_key: diff --git a/setup.py b/setup.py index 9e13a28..42c6d8e 100755 --- a/setup.py +++ b/setup.py @@ -7,7 +7,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.9.0", + version="1.10.0", author="Elliot Jordan", author_email="elliot@elliotjordan.com", packages=["pre_commit_hooks"],