Skip to content

Commit bc0d39d

Browse files
authored
Merge pull request #84 from homebysix/dev
1.18.0 merge to main
2 parents dcf837e + 1af0acb commit bc0d39d

File tree

9 files changed

+134
-70
lines changed

9 files changed

+134
-70
lines changed

.pre-commit-hooks.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171

7272
- id: check-munkiadmin-scripts
7373
name: Check MunkiAdmin Scripts
74-
description: This hook ensures MunkiAdmin scripts are executable.
74+
description: This hook ensures MunkiAdmin scripts are named properly and executable.
7575
entry: check-munkiadmin-scripts
7676
language: python
7777
files: "^MunkiAdmin/scripts/"

CHANGELOG.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,15 @@ All notable changes to this project will be documented in this file. This projec
1414

1515
Nothing yet.
1616

17+
## [1.18.0] - 2025-01-04
18+
19+
### Added
20+
21+
- `check-munki-pkgsinfo` now produces an error if `uninstall_method` is set to `uninstall_script` but no uninstall script is present in the pkginfo.
22+
- `check-munki-pkgsinfo` now checks for deprecated pkginfo keys.
23+
- `check-munki-pkgsinfo` now includes checks for many possible pkginfo key typos, not just `minimum_os_version` and `maximum_os_version`. Suggestions welcome if you think of more.
24+
- `check-munkiadmin-scripts` now checks whether scripts are named correctly, not just executable.
25+
1726
## [1.17.0] - 2024-12-22
1827

1928
### Added
@@ -383,7 +392,8 @@ Nothing yet.
383392

384393
- Initial release
385394

386-
[Unreleased]: https://github.com/homebysix/pre-commit-macadmin/compare/v1.17.0...HEAD
395+
[Unreleased]: https://github.com/homebysix/pre-commit-macadmin/compare/v1.18.0...HEAD
396+
[1.18.0]: https://github.com/homebysix/pre-commit-macadmin/compare/v1.17.0...v1.18.0
387397
[1.17.0]: https://github.com/homebysix/pre-commit-macadmin/compare/v1.16.2...v1.17.0
388398
[1.16.2]: https://github.com/homebysix/pre-commit-macadmin/compare/v1.16.1...v1.16.2
389399
[1.16.1]: https://github.com/homebysix/pre-commit-macadmin/compare/v1.15.0...v1.16.1

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ For any hook in this repo you wish to use, add the following to your pre-commit
1515

1616
```yaml
1717
- repo: https://github.com/homebysix/pre-commit-macadmin
18-
rev: v1.17.0
18+
rev: v1.18.0
1919
hooks:
2020
- id: check-plists
2121
# - id: ...
@@ -144,7 +144,7 @@ When combining arguments that take lists (for example: `--required-keys`, `--cat
144144

145145
```yaml
146146
- repo: https://github.com/homebysix/pre-commit-macadmin
147-
rev: v1.17.0
147+
rev: v1.18.0
148148
hooks:
149149
- id: check-munki-pkgsinfo
150150
args: ['--catalogs', 'testing', 'stable', '--']
@@ -154,7 +154,7 @@ But if you also use the `--categories` argument, you would move the trailing `--
154154

155155
```yaml
156156
- repo: https://github.com/homebysix/pre-commit-macadmin
157-
rev: v1.17.0
157+
rev: v1.18.0
158158
hooks:
159159
- id: check-munki-pkgsinfo
160160
args: ['--catalogs', 'testing', 'stable', '--categories', 'Design', 'Engineering', 'Web Browsers', '--']
@@ -166,7 +166,7 @@ If it looks better to your eye, feel free to use a multi-line list for long argu
166166

167167
```yaml
168168
- repo: https://github.com/homebysix/pre-commit-macadmin
169-
rev: v1.17.0
169+
rev: v1.18.0
170170
hooks:
171171
- id: check-munki-pkgsinfo
172172
args: [

pre_commit_hooks/check_autopkg_recipes.py

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
from packaging.version import Version
1111

1212
from pre_commit_hooks.util import (
13+
detect_deprecated_keys,
14+
detect_typoed_keys,
1315
load_autopkg_recipe,
1416
validate_pkginfo_key_types,
1517
validate_required_keys,
@@ -611,24 +613,10 @@ def main(argv=None):
611613
retval = 1
612614
if not validate_restart_action_key(input_key["pkginfo"], filename):
613615
retval = 1
614-
615-
# Check for common mistakes in min/max OS version keys
616-
os_vers_corrections = {
617-
"min_os": "minimum_os_version",
618-
"max_os": "maximum_os_version",
619-
"min_os_vers": "minimum_os_version",
620-
"max_os_vers": "maximum_os_version",
621-
"minimum_os": "minimum_os_version",
622-
"maximum_os": "maximum_os_version",
623-
"minimum_os_vers": "minimum_os_version",
624-
"maximum_os_vers": "maximum_os_version",
625-
}
626-
for os_vers_key in os_vers_corrections:
627-
if os_vers_key in input_key["pkginfo"]:
628-
print(
629-
f"{filename}: You used {os_vers_key} when you probably meant {os_vers_corrections[os_vers_key]}."
630-
)
631-
retval = 1
616+
if not detect_deprecated_keys(input_key["pkginfo"], filename):
617+
retval = 1
618+
if not detect_typoed_keys(input_key["pkginfo"], filename):
619+
retval = 1
632620

633621
# TODO: Additional pkginfo checks here.
634622

pre_commit_hooks/check_munki_pkgsinfo.py

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
from xml.parsers.expat import ExpatError
99

1010
from pre_commit_hooks.util import (
11+
detect_deprecated_keys,
12+
detect_typoed_keys,
1113
validate_pkginfo_key_types,
1214
validate_required_keys,
1315
validate_restart_action_key,
@@ -114,23 +116,13 @@ def main(argv=None):
114116
if not validate_restart_action_key(pkginfo, filename):
115117
retval = 1
116118

117-
# Check for common mistakes in min/max OS version keys.
118-
os_vers_corrections = {
119-
"min_os": "minimum_os_version",
120-
"max_os": "maximum_os_version",
121-
"min_os_vers": "minimum_os_version",
122-
"max_os_vers": "maximum_os_version",
123-
"minimum_os": "minimum_os_version",
124-
"maximum_os": "maximum_os_version",
125-
"minimum_os_vers": "minimum_os_version",
126-
"maximum_os_vers": "maximum_os_version",
127-
}
128-
for os_vers_key in os_vers_corrections:
129-
if os_vers_key in pkginfo:
130-
print(
131-
f"{filename}: You used {os_vers_key} when you probably meant {os_vers_corrections[os_vers_key]}."
132-
)
133-
retval = 1
119+
# Check for deprecated pkginfo keys.
120+
if not detect_deprecated_keys(pkginfo, filename):
121+
retval = 1
122+
123+
# Check for common mistakes key names.
124+
if not detect_typoed_keys(pkginfo, filename):
125+
retval = 1
134126

135127
# Check for rogue categories.
136128
if args.categories and pkginfo.get("category") not in args.categories:
@@ -202,12 +194,19 @@ def main(argv=None):
202194
retval = 1
203195

204196
# Ensure uninstall method is set correctly if uninstall_script exists.
205-
if "uninstall_script" in pkginfo:
206-
if pkginfo.get("uninstall_method") != "uninstall_script":
207-
print(
208-
f'{filename}: has uninstall script, but the uninstall method is set to "{pkginfo.get("uninstall_method")}"'
209-
)
210-
retval = 1
197+
uninst_method = pkginfo.get("uninstall_method")
198+
if "uninstall_script" in pkginfo and uninst_method != "uninstall_script":
199+
print(
200+
f"{filename}: has an uninstall script, but the uninstall "
201+
f'method is set to "{uninst_method}"'
202+
)
203+
retval = 1
204+
elif "uninstall_script" not in pkginfo and uninst_method == "uninstall_script":
205+
print(
206+
f"{filename}: uninstall_method is set to uninstall_script, "
207+
'but no uninstall script is present"'
208+
)
209+
retval = 1
211210

212211
# Ensure all pkginfo scripts have a proper shebang.
213212
script_types = (

pre_commit_hooks/check_munkiadmin_scripts.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,15 @@ def main(argv=None):
2727
retval = 0
2828
for filename in args.filenames:
2929

30+
# Ensure scripts are named properly.
31+
# https://github.com/hjuutilainen/munkiadmin/blob/4f4e96da1f1c7a4dfe7da59d88f1ef68ee02b8f2/MunkiAdmin/Singletons/MAMunkiRepositoryManager.m#L23
32+
prefixes = ["manifest", "pkginfo", "repository"]
33+
actions = ["custom", "postopen", "postsave", "presave"]
34+
ma_script_prefixes = [f"{p}-{a}" for p in prefixes for a in actions]
35+
if not any(filename.startswith(prefix) for prefix in ma_script_prefixes):
36+
print(f"{filename}: does not start with a valid MunkiAdmin script prefix")
37+
retval = 1
38+
3039
# Ensure scripts are executable
3140
if not os.access(filename, os.X_OK):
3241
print(f"{filename}: not executable")

pre_commit_hooks/check_munkipkg_buildinfo.py

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import argparse
55
import json
66
import plistlib
7-
import sys
87
from xml.parsers.expat import ExpatError
98

109
import ruamel.yaml
@@ -32,25 +31,21 @@ def build_argument_parser():
3231
def validate_buildinfo_key_types(buildinfo, filename):
3332
"""Ensure build-info files contain the proper types."""
3433

35-
# Remap string type to support unicode in both Python 2 and 3
36-
# DEPRECATED: Python 2 support will be removed in the future
37-
string = basestring if sys.version_info.major == 2 else str
38-
3934
# Pkginfo keys and their known types. Omitted keys are left unvalidated.
4035
# Source: https://github.com/munki/munki-pkg
4136
# Last updated 2019-06-27.
4237
buildinfo_types = {
4338
"distribution_style": bool,
44-
"identifier": string,
45-
"install_location": string,
46-
"name": string,
47-
"ownership": string,
48-
"postinstall_action": string,
39+
"identifier": str,
40+
"install_location": str,
41+
"name": str,
42+
"ownership": str,
43+
"postinstall_action": str,
4944
"preserve_xattr": bool,
50-
"product id": string,
45+
"product id": str,
5146
"signing_info": dict,
5247
"suppress_bundle_relocation": bool,
53-
"version": string,
48+
"version": str,
5449
}
5550

5651
passed = True

pre_commit_hooks/util.py

Lines changed: 73 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,69 @@ def validate_required_keys(input_dict, filename, required_keys):
7777
return passed
7878

7979

80+
def detect_deprecated_keys(input_dict, filename):
81+
"""Verifies that no deprecated keys are present in dictionary."""
82+
# List from: https://github.com/munki/munki/wiki/Supported-Pkginfo-Keys
83+
deprecated_keys = (
84+
"suppress_bundle_relocation",
85+
"forced_install",
86+
"forced_uninstall",
87+
)
88+
passed = True
89+
for dep_key in deprecated_keys:
90+
if input_dict.get(dep_key):
91+
print(f"{filename}: {dep_key} key is deprecated")
92+
passed = False
93+
return passed
94+
95+
96+
def detect_typoed_keys(input_dict, filename):
97+
"""Verifies that specific key name typos are not present in dictionary."""
98+
key_corrections = {
99+
"appleitem": "apple_item",
100+
"blocking_apps": "blocking_applications",
101+
"blockingapplications": "blocking_applications",
102+
"choices_xml": "installer_choices_xml",
103+
"icon": "icon_name",
104+
"install_check_script": "installcheck_script",
105+
"installer_choices": "installer_choices_xml",
106+
"max_os_vers": "maximum_os_version",
107+
"max_os": "maximum_os_version",
108+
"maximum_os_vers": "maximum_os_version",
109+
"maximum_os": "maximum_os_version",
110+
"min_munki_vers": "minimum_munki_version",
111+
"min_munki": "minimum_munki_version",
112+
"min_os_vers": "minimum_os_version",
113+
"min_os": "minimum_os_version",
114+
"minimum_munki_vers": "minimum_munki_version",
115+
"minimum_munki": "minimum_munki_version",
116+
"minimum_os_vers": "minimum_os_version",
117+
"minimum_os": "minimum_os_version",
118+
"on_demand": "OnDemand",
119+
"post_install_script": "postinstall_script",
120+
"post_uninstall_script": "postuninstall_script",
121+
"pre_cache": "precache",
122+
"pre_install_alert": "preinstall_alert",
123+
"pre_install_script": "preinstall_script",
124+
"pre_uninstall_alert": "preuninstall_alert",
125+
"pre_uninstall_script": "preuninstall_script",
126+
"pre_upgrade_alert": "preupgrade_alert",
127+
"receipt": "receipts",
128+
"require": "requires",
129+
"supported_architecture": "supported_architectures",
130+
"uninstall_check_script": "uninstallcheck_script",
131+
}
132+
passed = True
133+
for found_key, expected_key in key_corrections.items():
134+
if found_key in input_dict:
135+
print(
136+
f"{filename}: You used {found_key} when you "
137+
f"probably meant {expected_key}."
138+
)
139+
passed = False
140+
return passed
141+
142+
80143
def validate_restart_action_key(pkginfo, filename):
81144
"""Verifies that required_keys are present in pkginfo dictionary."""
82145
passed = True
@@ -121,35 +184,34 @@ def validate_pkginfo_key_types(pkginfo, filename):
121184
"forced_uninstall": bool,
122185
"icon_name": str,
123186
"installable_condition": str,
187+
"installcheck_script": str,
124188
"installed_size": int,
189+
"installer_choices_xml": list,
190+
"installer_environment": dict,
125191
"installer_item_hash": str,
126192
"installer_item_location": str,
127193
"installer_item_size": int,
128194
"installer_type": str,
129195
"installs": list,
130196
"items_to_copy": list,
131-
"installer_choices_xml": list,
132-
"installer_environment": dict,
133197
"localized_strings": dict,
198+
"maximum_os_version": str,
134199
"minimum_munki_version": str,
135200
"minimum_os_version": str,
136-
"maximum_os_version": str,
137201
"name": str,
138202
"notes": str,
203+
"OnDemand": bool,
204+
"package_path": str,
139205
"PackageCompleteURL": str,
140206
"PackageURL": str,
141-
"package_path": str,
142-
"installcheck_script": str,
143-
"uninstallcheck_script": str,
144-
"OnDemand": bool,
145207
"postinstall_script": str,
146208
"postuninstall_script": str,
147209
"precache": bool,
148210
"preinstall_alert": dict,
149-
"preuninstall_alert": dict,
150-
"preupgrade_alert": dict,
151211
"preinstall_script": str,
212+
"preuninstall_alert": dict,
152213
"preuninstall_script": str,
214+
"preupgrade_alert": dict,
153215
"receipts": list,
154216
"requires": list,
155217
"RestartAction": str,
@@ -159,8 +221,9 @@ def validate_pkginfo_key_types(pkginfo, filename):
159221
"unattended_uninstall": bool,
160222
"uninstall_method": str,
161223
"uninstall_script": str,
162-
"uninstaller_item_location": str,
163224
"uninstallable": bool,
225+
"uninstallcheck_script": str,
226+
"uninstaller_item_location": str,
164227
"update_for": list,
165228
"version": str,
166229
}

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
name="pre-commit-macadmin",
77
description="Pre-commit hooks for Mac admins, client engineers, and IT consultants.",
88
url="https://github.com/homebysix/pre-commit-macadmin",
9-
version="1.17.0",
9+
version="1.18.0",
1010
author="Elliot Jordan",
1111
author_email="[email protected]",
1212
packages=["pre_commit_hooks"],

0 commit comments

Comments
 (0)