Giter Club home page Giter Club logo

pup's Introduction

pup | Pluggable Micro Packager

pup is (in the early stages of becoming) a packaging tool for Python GUI programs.

Fundamentally, its raison d'être is producing macOS and Windows native packages for distributing the Mu Editor to 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 package Mu Editor for macOS and Windows distribution.

Capabilities

The current version of pup, while still very limited and somewhat exploratory, can package, at least, the Mu Editor and puppy into distributable:

  • Windows MSI installer files

    Minimally 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 files

    Holding the relocatable .app application 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 files

    Preliminary support: limited to Python 3.8 on x86_64 systems, with the Desktop Entry's Categories hard-coded to "Education".

As of this writing, pup should 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.
  • Is pip-installable (no need to be on PyPI, though).
  • Is launchable from the CLI with python -m <launch-module>.

No specific efforts have been put forth to ensure that that is the case, however, so YMMV.

Installation

pup is distributed via PyPI. Install it with:

$ pip install pup

Generic Usage

To package an application, run:

$ pup package <pip-install-src>

Where:

  • <pip-install-src> is the argument in the pip install <pip-install-src> command to install the application on the local Python environment.

    In general, if it's pip-installable then it's probably pup-packageable.

This usage pattern assumes that the application GUI is launchable with python -m <name>, where <name> is extracted from the metadata of a wheel created from <pip-install-src>. If that is not the case, pup can be told otherwise. Read on.

When completed, the final distributable artifact will be placed under ./dist/.

Packaging Options

  • Use --launch-module=<name> to set the module name that should be used to launch the application GUI, as with the python -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 an ICNS or PNG file 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 a PNG file which will be used as the icon for the running application.

    On Windows the file can be either an ICO or PNG file 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 -I Python launch flag (repeat for each flag to be used or set <flag> to the empty string to use none).

Signing

Signing is optional and varies slightly between platforms.

pup will only sign the application for distribution when all of the following conditions are true. On macOS, pup will 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.

macOS

  • XCode 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.

Windows

  • The Windows SDK must be installed, providing the signtool.exe utility.
  • The following environment variable must be set:
    • PUP_SIGNING_IDENTITY: cname of the code signing certificate.

Behaviour Notes

In the first run, pup downloads one or more files, which are cached locally for later use:

pup logs its progress to STDERR, with fewer per-event details when it's a TTY. The logging level defaults to INFO and can be changed with either the --log-level CLI option, or by setting the PUP_LOG_LEVEL environment variable.

Other than the locally cached files, pup creates files under:

  • ./build/pup/ containing all intermediate artifacts..
  • ./dist/ where the final distributable artifact is delivered..

Packaging the Mu Editor on Windows

Requirements for signing:

  • The Windows SDK must be installed.
  • A code signing certificate must be available under Windows' certmgr utility.

Run:

> set PUP_SIGNING_IDENTITY=<signer>

Where:

  • <signer> is the cname attribute 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 macOS

Requirements for signing and notarization:

  • Must have XCode 10.3 or later installed.
  • Must have an Apple Developer Certificate -- see this article's step 4, for guidance.
  • Must create an Application Specific Password -- see this article, for guidance.

Run:

$ export PUP_SIGNING_IDENTITY=<signer>
$ export PUP_NOTARIZE_USER=<user>
$ export PUP_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:

$ pup package \
      --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.

More

To learn more about pup refer to the online 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 at https://github.com/mu-editor/pup/.

Thanks

  • To Nicholas Tollervey, for the amazing Mu 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 inspiring BeeWare project and, in particular, for briefcase that being used as the packaging tool for Mu on macOS as of this writing, serves as a great inspiration to pup.
  • To Gregory Szorc, for the incredible Python Standalone Builds project, on top of which pup packages redistributable Python GUI applications.
  • To Donald Stufft, for letting us pick up the pup name in PyPI.
  • To Glyph Lefkowitz, for the very useful, high quality Tips And Tricks for Shipping a PyGame App on the Mac article, and for his generous hands-on involvement in the first-steps of pup's take on the subject in this issue.
  • To Alastair Houghton, for dmgbuild, that pup uses to create macOS DMG files.
  • To the WiX Toolset developers, maintainers, contributors, and sponsors: not sure how pup would go about building Windows MSI installers without it.

About

pup is in the process of being created by Tiago Montes, with the wonderful support of the Mu development team.

pup's People

Contributors

carlosperate avatar tmontes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

pup's Issues

Relaunching packaged macOS app on Catalina doesn't bring its UI to the front

See the second segment of this comment, quoted here for simplicity:

However, this strategy of using a shell (or Python or Ruby) "launcher", while a popular trick that worked in the past, seems to be breaking down on more recent macOS releases, particularly catalina. See this blog post about how one Emacs mac build's too-clever binary-selector launching script effectively broke the ability to launch the application multiple times. puppy.app seems to have the same problem - launching it from the Downloads folder while it's open doesn't bring it back to the front. By contrast, py2app applications use an executable shim and do not have this problem, since they don't re-exec; testing with my own pygame apps validates this. So you might want to figure out some way to build a C executable that invokes Python as a library.

Support plugin-driven CLI options + API args

(extracted from #9)

Motivations:

  • Support a --output-format option that triggers different plugins that, themselves, announce the support/require that CLI option.
  • Support overriding "default" Python runtime bundles.
  • There will probably be more use cases.

Simplify the standard library compilation process?

FACT:

  • As of now, the pup.install-cleanup step compiles the packaged Standard Library (and site-packages) one directory at a time.

THOUGHT:

  • Maybe we can compile everything with a single python -m compileall invocation: probably just a matter of figuring out the right CLI flags. :)

BENEFIT:

  • Simpler code.
  • Marginally faster (?) compilation due to less sub-process spawning overhead.

Produce Windows MSI artifacts

WANT NOW:

  • Produce user installable MSI artifact.
  • Should add entry to the start menu.
  • Grab WiX or whatever is needed automatically.

LATER:

  • Sign the MSI file.
  • Allow for system installable MSI.
  • Allow for GUI selectable user/system install?
  • Not doing MSI files, but EXE installers, instead.

Can we support cppyy?

(creating issue to include cppyy for future evaluation)

TO BE CONSIDERED:

  • Found this stackoverflow question about packaging applications that use cppyy.
  • Does pup handle packaging such applications?
  • If not, do we want it to? Can it be solved with a plugin?

Driving execution should be interruptible somehow

FACTS:

  • Packaging proceeds in steps, executed one after the other.
  • If a given step fails, it probably makes no sense continuing.
  • There's no way to stop other than raising an exception which will propagate to the top of the stack.

IDEA:

  • Maybe step execution can raise a specific exception, caught by the step driver, in order to stop.

Create a pluggable skeleton

Objective:

  • Identifies and initializes plugins.
  • Runs things from the CLI and from the API.
  • Supports CLI/API arguments and passes them to the proper "players".

Review packaging metadata

THOUGHTS:

  • In particular, the "Development Status" classifier, currently as "1 - Planning".
  • I guess we're past that point!

Fails packaging on Python 3.8 - No such file or directory ...

FACT:

  • After having fixed #35, pup is now failing on macOS with Python 3.8.
  • Here's a sample output, trying to package mu:
$ PUP_LOG_LEVEL=info pup package --launch-module=mu ../../Python/github.com/mu
20200916 125819 I pup 1.0.0a1 - starting with PID=36760
20200916 125819 I pup.api Package '../../Python/github.com/mu': starting.
20200916 125819 I pup.plugins.metadata Collecting metadata for '../../Python/github.com/mu'.
20200916 125822 I pup.api Step 'mac.app-bundle-template': starting.
20200916 125822 I pup.api Step 'mac.app-bundle-template': completed.
20200916 125822 I pup.api Step 'pup.python-runtime': starting.
20200916 125824 E pup Execution failure: [Errno 2] No such file or directory: '/Users/tiago.montes/Work/Python-Public/x/build/pup/mu-editor.app/Contents/Resources/Python/lib/python3.7/config-3.7m-darwin'
20200916 125824 I pup 1.0.0a1 - done

MOTIVE:

  • The quick-and-very-very-dirty "Python Runtime cleanup" is hard-coded for 3.7. :-)

PROPOSED FIX:

  • Let's drop the runtime cleanup hacks and create an issue to handle that (kind of) "properly".

Implement macOS signing and notarization

PLAN:

  • Collect and share documentation links about the topic (many of which I've been reading as of recently).
  • Get a developer certificate from Apple.
  • Explore the process manually / via ad-hoc scripts, confirming that it seems to work.
  • Try to validate it in collaboration with someone else, running macOS Catalina or Big Sur.
  • Transpose the process into pup code.

NOTE:

  • From the investigation so far, it is a very good idea to have a properly layed out, as small as possible macOS Application Bundle to submit for notarization.
  • With that in mind, #38 becomes a relevant dependency to this issue's "correct" implementation.

Better MSI Packaging

From #82:

  • Sign the MSI file | Addressed in #97.
  • Allow for system installable MSI in #151.
  • Allow for GUI selectable user/system install? #151
  • Include license agreement | Addressed in #91.
  • Add Icon to MSI file -- the file itself can't have one, that's an OS level thing | See #103.
  • Address apprently font-related warnings when packaging Mu.

Produce macOS DMG images

IDEA:

  • Signed and notarized macOS application bundles should be packaged into commonly used DMG images.
  • DMG filename and volume name should be along the lines of <nice-application-name> <version>.

EXTRA POINTS:

  • Should include a nicely layed out link to the /Applications directory and some kind of visual arrow, guiding users to drag (copy) the distributed application bundle there, per platform conventions.

USEFUL REFERENCES:

Add support for a --preview CLI/API option

USE CASE:

  • Run pre-flight checks without actually doing the packaging.
  • Examples:
    • Network connectivity available, if needed, to download things.
    • Cached downloaded files available (thus downloading not needed).
    • Tools like macOS codesign and others found.
    • More?

POSSIBLE IMPLEMENTATION:

  • Each step's __call__ method to include a preview=False argument.

'sys.path' must not include foreign paths

CURRENT macOS FACT:

  • Packaged Mu with Python 3.7.
  • Checked the value of the bundled Python environment's sys.path with:
$ ./build/pup/mu-editor.app/Contents/Resources/Python/bin/python3 -q
>>> import sys
>>> print(*map(repr, sys.path), sep='\n')
''
'${PWD}/build/pup/mu-editor.app/Contents/Resources/Python/lib/python37.zip'
'${PWD}/build/pup/mu-editor.app/Contents/Resources/Python/lib/python3.7'
'${PWD}/build/pup/mu-editor.app/Contents/Resources/Python/lib/python3.7/lib-dynload'
'${HOME}/.local/lib/python3.7/site-packages'
'${PWD}/build/pup/mu-editor.app/Contents/Resources/Python/lib/python3.7/site-packages'
'${PWD}/build/pup/mu-editor.app/Contents/Resources/Python/lib/python3.7/site-packages/setuptools-49.6.0-py3.7.egg'
'${PWD}/build/pup/mu-editor.app/Contents/Resources/Python/lib/python3.7/site-packages/pip-20.2.2-py3.7.egg'
>>> 

NEEDS CHANGE:

  • Two entries should be eliminated from sys.path:
    • The '' empty one, corresponding to the current working directory.
    • The ${HOME}/.local/lib/python3.7/site-packages which, I suppose, holds pip --user installed packages.

WONDERING:

  • What kind of sys.path values are we getting on Windows?
  • What about Python 3.8 variations?

RELATED:

Fails packaging on Python 3.8 - no 'importlib.resources.files'

REPORTED by @tjguk, on Gitter's mu-editor/dev channel:

I gave it a go on Windows. Cloned pup; created a local venv; pip install -e.[dev]; and then ran -- from the pup directory pup package --launch-module=mu c:\work-in-progress\mu-master
It did stuff for a while (albeit with no output) and then I got an error:
20200915 072004 E pup Execution failure: module 'importlib.resources' has no attribute 'files'
This is with Python 3.8.3 on Win10

TO WHICH I RESPONDED:

Thanks for trying it @tjguk! :) Silly me trying to use 3.8 stdlib’s importlib.resources, while using PyPI’s “backported” but more capable on 3.7 - will be an easy fix. FYI, for more “noisy” output, add —log-level=info/debug between pup and package.

FACTS:

  • importlib.resources is used to "bundle" cookiecutter templates as packages within pup itself.
  • On 3.7 the PyPI backported importlib_resources package is used...
  • ...on 3.8, the standard library's importlib.resources is used instead.

CULPRIT:

  • The PyPI importlib_resources provides a files function that is not implemeted by 3.8's stdlib.

POSSIBLE FIXES:

  • Use PyPI's importlib_resources on both 3.7 and 3.8 (3.9's stdlib seems to include the files function we're using).
  • Use alternative implementation, supported by 3.8's stdlib.

Add support for a "nice" packaged name.

FACTS:

  • Python packages (and thus, pup packagable applications) tend to have a somewhat technical (-ish) name.
  • The case for Mu is mu-editor, which is what people pip-install, for instance.
    (then there's the fact that the pip-installable name is not necessarily the importable one -- see #28).

WANTED:

  • It will be nice to have Mu packaged into a distributable file called, say, Mu Editor 1.1.0.zip,
    instead of mu-editor 1.1.0.zip which would be the best pup can do from the the available metadata.

THOUGHTS:

  • I've been trying to avoid requiring a "configuration file" for pup to do its thing.
  • Given that, AFAICT, there's no way to add custom metadata to a Python distribution (wheel, sdists, etc)...
  • ...maybe we'll start off by adding a CLI option / API argument to support that (much like #28, again).

Build + Publish docs with CI

MOTIVATION:

  • There's some written words now.

OBJECTIVE:

  • Let's have GitHub actions do the Sphinx build...
  • ...and figure out a way of having the result published to readthedocs.org.

Implement an effective cleanup packaging step

MOTIVATION:

  • Keep redistributable artifact as small as reasonable.
  • The Python Runtime includes lots of things that are of no use in most (?) cases: stdlib tests, static libraries, etc.

IDEAS:

  • Remove unneeded files for running the application:
    • All the tests in the Standard Library.
    • All (most?) of the scripts/console_scripts (pip? easy_install?), including ones that may be put in place after pip-installing the application and its dependencies.
  • (Optionally?) compile the Standard Library.

Packaging fails with PyPI sourced pup

DETAILS:

  • Packaging puppy is failing with the latest PyPI-sourced pup 1.0.0a3 release.

REPRODUCTION:

  • Create a Python 3.7 venv and update pip.
  • pip install pup -- grabs 1.0.0a3 from PyPI.
  • Clone puppy source tree from https://github.com/tmontes/puppy.
  • Run pup package . on the source tree root.

RESULT (Windows):

(venv-xirro) C:\Users\test\work\github.com\puppy>pup package .
I pup 1.0.0a3 - starting with PID=3156
I Package '.': starting.
I Collecting metadata for '.'.
I About to run 'c:\\users\\test\\work\\github.com\\puppy\\venv-xirro\\scripts\\python.exe -m pip wheel --no-deps C:\\Users\\test\\work\\github.com\\puppy'.
I pip out: Processing c:\users\test\work\github.com\puppy
I pip out: Building wheels for collected packages: puppy
I pip out:   Building wheel for puppy (setup.py): started
I pip out:   Building wheel for puppy (setup.py): finished with status 'done'
I pip out:   Created wheel for puppy: filename=puppy-1.4.0-py3-none-any.whl size=8648 sha256=ff3f236e235e73f658ce6ae95e4f0786a4065d7e8515647b21a8f910a5c80590
I pip out:   Stored in directory: C:\Users\test\AppData\Local\Temp\pip-ephem-wheel-cache-vyuiro5s\wheels\17\26\43\705bd58c4b717c1af27e3ec8fb612c8da7e59b082813f42eb8
I pip out: Successfully built puppy
I Step 'win.distribution-layout': starting.
C Execution failure:
C Traceback below:
Traceback (most recent call last):
  File "c:\users\test\work\github.com\puppy\venv-xirro\lib\site-packages\pup\__main__.py", line 31, in wrapper
    exit_code = command_function(*args, **kw)
  File "c:\users\test\work\github.com\puppy\venv-xirro\lib\site-packages\pup\__main__.py", line 80, in package
    launch_module=launch_module,
  File "c:\users\test\work\github.com\puppy\venv-xirro\lib\site-packages\pup\api.py", line 41, in package
    dsp.run_pluggable_step(step)
  File "c:\users\test\work\github.com\puppy\venv-xirro\lib\site-packages\pup\dispatcher.py", line 79, in run_pluggable_step
    return self._invoke_plugin(name)
  File "c:\users\test\work\github.com\puppy\venv-xirro\lib\site-packages\pup\dispatcher.py", line 68, in _invoke_plugin
    return plugin(self._ctx, self, **kwargs)
  File "c:\users\test\work\github.com\puppy\venv-xirro\lib\site-packages\pup\plugins\win\dist_layout.py", line 63, in __call__
    result_path = generate.generate_files(tmpl_path, tmpl_data, build_dir, overwrite_if_exists=True)
  File "c:\users\test\work\github.com\puppy\venv-xirro\lib\site-packages\cookiecutter\generate.py", line 264, in generate_files
    template_dir = find_template(repo_dir)
  File "c:\users\test\work\github.com\puppy\venv-xirro\lib\site-packages\cookiecutter\find.py", line 34, in find_template
    raise NonTemplatedInputDirException
cookiecutter.exceptions.NonTemplatedInputDirException
I pup 1.0.0a3 - done

(venv-xirro) C:\Users\test\work\github.com\puppy>

RESULT (macOS):

(venv) tiago.montes (~/Temp/i77/puppy): pup package .
I pup 1.0.0a3 - starting with PID=1032
I Package '.': starting.
I Collecting metadata for '.'.
I About to run '/Users/tiago.montes/Temp/i77/venv/bin/python3.7 -m pip wheel --no-deps /Users/tiago.montes/Temp/i77/puppy'.
I pip out: Processing /Users/tiago.montes/Temp/i77/puppy
I pip out: Building wheels for collected packages: puppy
I pip out:   Building wheel for puppy (setup.py): started
I pip out:   Building wheel for puppy (setup.py): finished with status 'done'
I pip out:   Created wheel for puppy: filename=puppy-1.4.0-py3-none-any.whl size=8621 sha256=cea794985820a128e2dfdbccdb480447e05a0f63cfdb04620aea41962d15af88
I pip out:   Stored in directory: /private/var/folders/0m/xy6669f52zdbb6prv46hrghw0000gp/T/pip-ephem-wheel-cache-as8l2gbp/wheels/fe/32/0e/c92f7a965c6b69e2cc9d2076cc0dd7078458303396513efbcd
I pip out: Successfully built puppy
I Step 'mac.app-bundle-template': starting.
C Execution failure: 
C Traceback below:
Traceback (most recent call last):
  File "/Users/tiago.montes/Temp/i77/venv/lib/python3.7/site-packages/pup/__main__.py", line 31, in wrapper
    exit_code = command_function(*args, **kw)
  File "/Users/tiago.montes/Temp/i77/venv/lib/python3.7/site-packages/pup/__main__.py", line 80, in package
    launch_module=launch_module,
  File "/Users/tiago.montes/Temp/i77/venv/lib/python3.7/site-packages/pup/api.py", line 41, in package
    dsp.run_pluggable_step(step)
  File "/Users/tiago.montes/Temp/i77/venv/lib/python3.7/site-packages/pup/dispatcher.py", line 79, in run_pluggable_step
    return self._invoke_plugin(name)
  File "/Users/tiago.montes/Temp/i77/venv/lib/python3.7/site-packages/pup/dispatcher.py", line 68, in _invoke_plugin
    return plugin(self._ctx, self, **kwargs)
  File "/Users/tiago.montes/Temp/i77/venv/lib/python3.7/site-packages/pup/plugins/mac/app_bundle.py", line 65, in __call__
    result_path = generate.generate_files(tmpl_path, tmpl_data, build_dir, overwrite_if_exists=True)
  File "/Users/tiago.montes/Temp/i77/venv/lib/python3.7/site-packages/cookiecutter/generate.py", line 264, in generate_files
    template_dir = find_template(repo_dir)
  File "/Users/tiago.montes/Temp/i77/venv/lib/python3.7/site-packages/cookiecutter/find.py", line 34, in find_template
    raise NonTemplatedInputDirException
cookiecutter.exceptions.NonTemplatedInputDirException
I pup 1.0.0a3 - done
(venv) tiago.montes (~/Temp/i77/puppy): 

HOWEVER:

  • It does work when running pup from its development virtual environment.

THUS:

  • We have a meta-packaging issue.
  • pup is not properly packaged itself. :-)

Default to grabbing the latest build from Python Standalone Builds

MOTIVATION:

  • The currently hard-coded approach is a proof-of-concept, not sustainable.

THOUGHTS:

  • Be slightly more clever and take platform, architecture, bitness (and more?) into consideration bringing in support for:
    • 64 and 32 bit Windows
    • GLIBC and MUSL Linux
    • ...more?
  • Don't grab if there's a compatible but older version in cache?
  • Allow overriding default behaviour by specifying a specific relocatable Python Runtime (URL? File?) -- implemented in #125.

Add minimal usage docs

FACTS:

  • About to release 1.0.0a3 that actually does package, sign, and notarize Mu Editor on macOS.
  • Usage is simple, but non-trivial.
  • At least document that so as to simplify gathering feedback from early users/tests.

Re-use wheel from 'metadata collect' step in 'pip install' step?

FACTS:

  • Source package metadata is collected with pkginfo from a wheel file produced with pip wheel --no-deps <src>, which is queried and then thrown away (deleted).
  • At a later stage, the source package is pip-installed into the relocatable Python environment.

IDEA:

Maybe re-using the wheel could:

  • Make things go (ever so slightly) faster?
  • Save some compute cycles (and thus, be environmentally friendlier)?
  • ...just make sense?

Windows packaging must minimaly work

FACTS:

  • macOS packaging is minimally working: pup package --launch-module=mu .../mu-repository-root results in an apparently working packaged and redistributable mu-editor.app application bundle.

WANT:

  • The same command should result in a directory/zip-file that also apparently works on Windows.

Live log sub-process (pip and more) output?

FACTS:

  • Current output (STDOUT/STDERR) from sub-processes is logged in an "all-at-once" approach when the sub-process ends.
  • Also, STDOUT is logged at DEBUG level.
  • Some such runs may be somewhat long-ish (many seconds, few minutes).

IDEA:

  • Given that we prefer not to let sub-processes "just" output to STDOUT/STDERR directly...
  • ...maybe we could live log such output as it is produced, prefixing it with something like 'pip stdout/stderr'?

THOUGHTS:

  • Given that subprocess.run seems to block, not sure how to achieve that.
  • Maybe a thread or two are in order? :-)

Rename pup

FACTS:

  • pup started off as Python Mu Packager, which makes sense given its original motivation.
  • Per the design and initial results I feel very confident that it will indeed support more applications that just the Mu Editor, with no additional effort.

THOUGHTS:

  • Having "Python" in the name feels redundant -- it's on PyPI, what should it be related to?!
  • Having "Mu" in the name feels like it is scoped too narrow -- it does (and will) package other applications.

THUS:

Let's call it Pluggable Micro Packager instead:

  • Still abbreviated as pup (of course!), taking the u as an ASCII simplification of the µ (mu) Greek letter, a common symbol for the word "micro" -- retaining the relation with the original motivation, the Mu Editor.
  • Highlights one of its features: pluggability (which will need to be much better designed and implemented, but that's a whole other story).

Complete preliminary design section on the docs

Address, at least:

  • Context object: what information does it convey? how is it populated? is it mutable?
  • Dispatcher: which criteria can/should it use to do its job? does it include a "registry" is will that be a different thing?

Then, maybe:

  • Figure out a way that "pluggable behaviours" can get "parameters" from their callers and wire that nicely to both the pup API and the CLI usage.

Cleanup stage: remove __pycache__ directories.

FACTS:

  • As of now, due to the way that the packaged Standard Library is compiled -- in legacy (pre-PEP3147) mode -- the packaging process produces some redundant pyc files living inside __pycache__ directories.
  • These probably result from python -m pip execution within the distributable Python environment.

OBJECTIVE:

  • Let's remove those __pycache__ directories, shall we?

BENEFIT:

  • Smaller distributable artifact.
  • ...zero doubts about what is available and imported from where. :)

Change default log level to logging.INFO

MOTIVATION:

  • For the time being, during development, avoid the need to use the --log-level=info CLI arg (or setting the PUP_LOG_LEVEL environment variable).
  • Should simplify initial testing/exploration by others and gathering their feedback.

THOUGHT:

  • Maybe later consider changing it back to logging.WARNING.

Release 1.0.0a2

MOTIVATION:

  • Share with the Mu development team.
  • Test with current master.
  • Get early feedback.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.