Skip to content

Rewrite munkipkg in Perl so it runs on stock macOS (no Python required)#82

Open
keeleysam wants to merge 1 commit into
munki:mainfrom
keeleysam:perl-port
Open

Rewrite munkipkg in Perl so it runs on stock macOS (no Python required)#82
keeleysam wants to merge 1 commit into
munki:mainfrom
keeleysam:perl-port

Conversation

@keeleysam

Copy link
Copy Markdown
Member

Why

Recent macOS releases no longer ship a Python interpreter. Today munkipkg requires each user to install and maintain their own Python 3 (via python.org, Homebrew, Munki's bundled Python, etc.) before they can build a package. This rewrites munkipkg as a single Perl script that runs against the Perl that ships with stock macOS (currently 5.34), with no dependencies to install.

It's a drop-in replacement — nobody should notice the change

The only difference anyone should experience is that they no longer need to install Python. Everything else is unchanged:

  • Same command name, options, and --help / --version / usage text.
  • Same munkipkg: … stdout messages, the same ERROR: / WARNING: stderr text, and the same exit codes.
  • Same build-info formats (plist, json, yaml) and the same project layout.
  • Existing package projects and AutoPkg recipes work unchanged — including projects whose own pre/postinstall scripts are written in Python, since those run via pkgbuild regardless of language.

The Perl mirrors the previous Python function-for-function (same names, order, and comments) so the change is straightforward to review side by side.

Tested and verified compatible

I verified parity against the current Python tool directly:

  • The three in-repo sample projects (SuppressSetupAssistant, TurnOffBluetooth, munki_kickstart) build to byte-identical expanded package contentsPackageInfo, Bom, and Distribution — compared to the Python tool, across both component and distribution-style packages.
  • --create, --import (flat component + distribution), and --sync all produce byte-identical output vs the Python tool.
  • Property-list output is byte-identical to plistlib, and --create --json matches the Python JSON output including key order.

And now there are tests

This adds a Perl test suite (tests/, using the core Test::More) covering the CLI surface, plist/JSON/YAML serialization, build-info handling, pkgbuild/productbuild/notarytool argv construction, bundle import, end-to-end package builds, and --sync. Run with prove tests/.

Implementation notes

  • Property lists are read and written through the macOS Foundation Objective-C bridge (PerlObjCBridge, ships with macOS), so plist handling is native rather than shelling out.
  • JSON uses the core JSON::PP; YAML build-info uses the system YAML module when present (optional, exactly as PyYAML was before).
  • The tool never shells out except to the Apple packaging binaries it wraps (pkgbuild, productbuild, pkgutil, lsbom, ditto, xcrun), all invoked in list form (no shell); even package removal is native Perl.

macOS no longer ships a Python interpreter, so the Python munkipkg required
users to install and maintain their own Python. This rewrites munkipkg as a
single Perl script that runs against the Perl bundled with stock macOS (5.34)
with no required dependencies.

It is a faithful, drop-in replacement: same command name, options, --help /
--version / usage text, stdout/stderr messages, exit codes, build-info
formats (plist/json/yaml), and project layouts. Existing package projects and
AutoPkg recipes work unchanged, including projects whose own pre/postinstall
scripts are written in Python (those run via pkgbuild regardless of language).

Implementation notes:
- Property lists are read and written through the macOS Foundation ObjC
  bridge (PerlObjCBridge), producing XML plists byte-identical to plistlib
  and preserving booleans and string-vs-number types.
- JSON build-info uses core JSON::PP with Python-matching formatting and key
  order; YAML build-info uses the system YAML module when present (optional,
  as before).
- The tool never shells out except to the Apple packaging binaries it wraps
  (pkgbuild, productbuild, pkgutil, lsbom, ditto, xcrun), all invoked in
  list form; even package removal is native Perl rather than /bin/rm.
- The Perl mirrors the previous Python structure function-for-function to
  keep the change reviewable.

Verified: the three in-repo sample projects build to byte-identical expanded
package contents (PackageInfo, Bom, Distribution) versus the Python tool, and
--create / --import / --sync produce byte-identical output. Adds a Perl-only
test suite (Test::More) covering CLI, serialization, build-info, argv/auth
construction, bundle import, end-to-end build, and sync.

Signed-off-by: Samuel Keeley <samuel@keeley.net>
@gregneagle

Copy link
Copy Markdown
Contributor

Claude/Codex/ChatGPT can be amazing little robots.

I personally don't want to maintain Perl code. I did a fair amount of Perl coding 15-20 years ago and that was plenty. The tool does have a lot of potential value, so if you are serious about this, consider creating your own GitHub repo (and probably renaming the tool -- there's really no reason to refer to Munki at all, as it is a general-purpose packaging tool).

For this repo and tool, I think one of two things are likely to happen: 1) Ported to Swift, or 2) Archived as read-only and abandoned.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants