Package: pup
pupis (in the early stages of becoming) a packaging tool for Python GUI programs.Fundamentally,
itsraison d’êtreis producing macOS and Windows native packages
for distributing theMu Editorto Python beginners around the world.
As a by-product of that,
it may very likely be effective at packaging
generic Python written GUI programs.
If that ever is the case,
then great.
Otherwise,
that’s fine too.The purpose,
again,
is to packageMu Editorfor macOS and Windows distribution.CapabilitiesThe current version ofpup,
while still very limited and somewhat exploratory,
can package,
at least,
theMu Editorandpuppyinto distributable:Windows MSI installer filesMinimally featured, user-installable,
with an optional License Agreement GUI,
adding an entry to the Windows Start Menu,
with an optional custom icon.The packaged binary files can be signed,
as well as the final MSI file.As a side-effect of the process,
a relocatable directory holding the aplication is produced,
paving the way for the creation “portable” Windows applications.macOS DMG filesHolding the relocatable.appapplication bundle,
with an optional custom icon,
properly signed and notarized as required for distribution,Including an optional License Agreement GUI
and custom volume icon.Linux AppImage filesPreliminary support:
limited to Python 3.8 on x86_64 systems,
with the Desktop Entry’s Categories hard-coded to “Education”.As of this writing,pupshould be able to package any Python GUI application that:Runs on Python 3.7, on macOS or Windows.Runs on Python 3.8, on macOS, Linux or Windows.Ispip-installable (no need to be on PyPI, though).Is launchable from the CLI withpython-m<launch-module>.No specific efforts have been put forth to ensure that that is the case,
however,
so YMMV.Installationpupis distributed viaPyPI.
Install it with:$pipinstallpupGeneric UsageTo package an application, run:$puppackage<pip-install-src>Where:<pip-install-src>is the argument
in thepip install<pip-install-src>command
to install the application on the local Python environment.In general,
if it’spip-installable then it’s probablypup-packageable.This usage pattern
assumes that the application GUI is launchable withpython-m<name>,
where<name>is extracted
from the metadata of a wheel created from<pip-install-src>.
If that is not the case,pupcan be told otherwise.
Read on.When completed,
the final distributable artifact will be placed under./dist/.Packaging OptionsUse--launch-module=<name>to set the module name
that should be used to launch the application GUI,
as with thepython-m<name>command.Use--nice-name=<name>to set a “nice name” for the application
to be used used throughout the packaging process:
in file and directory names,
for macOS’s application bundle and DMG file names,
and for the Windows Start Menu entry.When omitted,
that name is obtained from the metadata of a wheel
created from<pip-install-src>,
that very often does not match the exact product spelling,
as communicated to end-users.Use--icon-path=<icon-path>to include a custom icon in the packaging process.On macOS the given file can be either anICNSorPNGfile
which will be used as the icon for both the packaged application bundle
and the DMG file volume icon.On Linux the file should be aPNGfile
which will be used as the icon for the running application.On Windows the file can be either anICOorPNGfile
which will be used on the Windows Start Menu entry and
on the Windows Programs and Features listing.Use--license-path=<license-path>to bundle the given license text
and require users to accept it before installation
(not currently supported on Linux AppImage).The given<license-path>must be an ASCII-encoded text file.Use--launch-pyflag=<flag>to override the default-IPython launch flag(repeat for each flag to be used or set<flag>to the empty string to use none).SigningSigning is optional and varies slightly between platforms.pupwill only sign the application for distribution
when all of the following conditions are true.
On macOS,pupwill also complete the Apple required notarization process:
for that,
the packaging system must be online and
able to connect to Apple’s notarization services
over the internet.macOSXCode 10.3 or later must be installed
– the Command Line Tools are not enough.The following environment variables must be set:PUP_SIGNING_IDENTITY:
10-digit identifier on the Apple Developer Certificate.PUP_NOTARIZE_USER:
email address for the Apple Developer Account.PUP_NOTARIZE_PASSWORD:
Application Specific Password.WindowsThe Windows SDK must be installed,
providing thesigntool.exeutility.The following environment variable must be set:PUP_SIGNING_IDENTITY:cnameof the code signing certificate.Behaviour NotesIn the first run,pupdownloads one or more files,
which are cached locally for later use:A relocatable Python Runtime from thePython Build Standaloneproject.On Windows,
theWiX toolset,
used to create MSI files.puplogs its progress to STDERR,
with fewer per-event details when it’s a TTY.
The logging level defaults toINFOand can be changed
with either the--log-levelCLI option,
or by setting thePUP_LOG_LEVELenvironment variable.Other than the locally cached files,pupcreates files under:./build/pup/containing all intermediate artifacts.../dist/where the final distributable artifact is delivered..Packaging the Mu Editor on WindowsRequirements for signing:The Windows SDK must be installed.A code signing certificate must be available under Windows’certmgrutility.Run:> set PUP_SIGNING_IDENTITY=<signer>Where:<signer>is thecnameattribute of the code signing certificate.Then, assuming the current working directory is Mu Editor’s repository root, run:> pup package
      --launch-module=mu
      --nice-name="Mu Editor"
      --icon-path=.\package\icons\win_icon.ico
      --license-path=.\LICENSE
      .Note:The command is line-wrapped for readability, but must be input as a single line.One of the last packaging stages is signing.It will take a while as there are many files to be signed,
but progress is continuously displayed,
with the defaul log level.Once completed:The resulting MSI file will be./dist/Mu Editor<version>.msi.A by-product of that is the./build/pup/Mu Editor <version>/relocatable directory,
containing a GUI-clickable script that launches Mu.
Creating a ZIP file from it for distribution
results in a minimally working “portable” Windows application.Packaging the Mu Editor on macOSRequirements for signing and notarization:Must have XCode 10.3 or later installed.Must have an Apple Developer Certificate –
seethis article’s step 4,
for guidance.Must create an Application Specific Password –
seethis article,
for guidance.Run:$exportPUP_SIGNING_IDENTITY=<signer>$exportPUP_NOTARIZE_USER=<user>$exportPUP_NOTARIZE_PASSWORD=<asp>Where:<signer>is the 10-digit identifier on your Apple Developer Certificate’s cname.<user>is the email address associated to you Apple Developer Account.<asp>is the Application Specific Password.Then, assuming the current working directory is Mu Editor’s repository root, run:$puppackage\--launch-module=mu\--nice-name="Mu Editor"\--icon-path=./package/icons/mac_icon.icns\--license-path=./LICENSE\.Note:One of the last packaging stages is notarization.It will take a while –
no less than 3 minutes,
IME,
sometimes 10-15 minutes.The logged messages should help understand that the “thing” is not hung.Just be patient, I guess! :)Once completed:The resulting DMG file will be./dist/<name><version>.dmg.A by-product of that is
the./build/pup/Mu Editor.app/relocatable application bundle.
Archiving it into a ZIP file, for distribution, should be perfectly fine.MoreTo learn more aboutpuprefer to theonline documentation:
at this early stage,
it is mostly a collection
of thoughts and ideas
around behaviour,
requirements,
and very very rough internal design.Development moves forward
on GitHub athttps://github.com/mu-editor/pup/.ThanksTo Nicholas Tollervey, for the amazingMu Editor.To the Mu Editor contributors
I’ve been having the privilege of working more directly with,
Carlos Pereira Atencio, Martin Dybdal, and Tim Golden, as well as the others
whom I haven’t met yet but whose contributions I highly respect.To Russell Keith-Magee, for the inspiringBeeWareproject
and, in particular, forbriefcasethat
being used as the packaging tool for Mu on macOS as of this writing, serves as a
great inspiration topup.To Gregory Szorc, for the incrediblePython Standalone Buildsproject,
on top of whichpuppackages redistributable Python GUI applications.To Donald Stufft,
for letting us pick up thepupname inPyPI.To Glyph Lefkowitz, for the very useful,
high qualityTips And Tricks for Shipping a PyGame App on the Macarticle,
and for his generous hands-on involvement in the first-steps ofpup’s take
on the subjectin this issue.To Alastair Houghton, fordmgbuild,
thatpupuses to create macOS DMG files.To theWiX Toolsetdevelopers, maintainers,
contributors, and sponsors:
not sure howpupwould go about building Windows MSI installers without it.Aboutpupis in the process of being created by Tiago Montes,
with the wonderful support of the Mu development team.