cloudmatrix/esky

View on GitHub
ChangeLog.txt

Summary

Maintainability
Test Coverage
v0.9.9dev

    * Compatability fixes for Win64; thanks Robin Dunn.
    * Edge-cases fixes in DefaultVersionFinder; thanks fingul.

v0.9.8

    * Many small fixes for Mac OSX, including compatibility with newer
      versions of py2app; thanks thomasschaff, poupas, and others.
    * Fix various unicode-handling issues on Python3; thank vkosh.
    * Use a timeout in calls to urlopen(); thanks kollivier.
    * Updates and improvements to tutorial code; thanks thomaschaaf, komola.


v0.9.7

    * Avoid a possible infinite loop during updates; thanks vkosh.


v0.9.6

    * Fix downloading of updates when there was a HTTP redirect encountered
      as part of VersionFinder.find_versions().
    * Fix win32 bootstrap version of abspath() to correctly handle UNC paths.


v0.9.5

    * Fix some env-var-handling errors on OSX; thanks Robin Dunn.
    * When using a custom win32 chainloader, be less aggressive about
      changing the current working directory on startup.
    * Clean up handling of unbuffered mode in py2exe.  (The old code
      never actually worked; the new code works most of the time but
      might give you the wrong mode if running from a partial update)
    * esky.sudo: avoid deadlocking if the helper process dies.


v0.9.4

    * Added esky.util.appexe_from_executable, a convenience method to
      find the bootstrapping exe corresponding to the running program.
    * Use "bsdiff4" module in preference to cx-bdiff if available; it's
      got a simpler API and is pip-installable.
    * Update rpython-compilation support for PyPy v1.5.
    * Better handling of non-alpha chars in app names; thanks Rafe Kettler.
    * py2exe: support the skip_archive option; thanks yflau.


v0.9.3

    * Preliminary support for a "callback" argument to Esky.auto_update,
      which is called with a dict of status info as update progresses.
    * esky.patch:  preserve file mode when patching a file.
    * DefaultVersionFinder.open_url: ensure that f.size is always an int.


v0.9.2

    * Restore compatability with python2.5, via __future__ imports.
    * esky.winres:  use ctypes.WinError throughout, to make inlining of
      code from this module more reliable.


v0.9.1

    * Fix some build issues on OSX:
        * varname typo in f_py2app.
        * undo py2app's changes to env["MACOSX_DEPLOYMENT_TARGET"] after
          it has finished its work.
        * don't let get_platform() change its value due to changes in the
          build environment; if it does the build files get corrupted.
        * correctly handle dots etc in sys.executable
    * Fix some built issues on win32:
        * the py2exe custom chainloader tried to use 'nt' module before
          it was imported, giving an UnboundLocalError.


v0.9.0

  THIS RELEASE INTRODUCES A NEW ON-DISK FILE LAYOUT - SEE BELOW FOR NOTES

    * Move the version directories, updates directory etc into an "appdata"
      subdirectory, to avoid user confusion in the top-level directory. The
      hope is that users will be much less inclined to poke around inside a
      generic "appdata" directory than inside directories named after the app.
         * to be clear, the new layout looks like this:
               myapp.exe
               appdata/
                 myapp-X.Y.X.win32/
                   myapp.exe
                   esky-files/
                 updates/
         * the "bdist_esky" command still generates zipfiles using the old 
           layout, so they can be unpacked correctly by previous versions of
           esky.  To get the new layout, pass the "enable-appdata-dir" option.
           This option will become the default (and will be removed) at the
           end of the 0.9.* series.
         * there are compatability hooks that upgrade the old file layout to
           the new layout. They will be removed at the end of the 0.9.* series.
         * therefore, if you have deployed applications using esky 0.8.* or
           lower, you MUST deploy an update using the 0.9.* series before
           migrating to any newer versions of esky.
    * Remove compatability hooks for pre-0.8.0 on-disk layout.
    * Add ability to compile the bootstrapping exes with the pypy translation
      toolchain, to reduce distribution size and increase loading speed:
          * pass the option "--compile-bootstrap-exes" to bdist_esky to
            enable the compilation step.
          * any custom bootstrapping code must be valid RPython; check the
            variable __rpython__ to determine whether you're being compiled.
          * obviously this only works if a recent version of the "pypy" package
            is installed and configured correctly.
    * Add verify() function to the bootstrap env, which is called to verify
      files before they are chainloaded.  The default implementation is empty,
      but it could be overridden to perform e.g. signature checking.
    * py2exe:  never bundle the python dll into the bootstrap executable
      unless it was bundled into the frozen app, it caused too many issues
      with unsuspecting third-party libraries.
    * Add utility functions "really_rename" and "really_rmtree", which retry
      the operation in response to certain bogus errors on win32.


v0.8.5:

    * FSTransaction:  better error handling, and better detection of cases
      where native transactions will fail (e.g. on a FAT32 USB device).
    * FSTransaction:  accept an optional "root" parameter, and enforce all
      operations to be inside this root.
    * bdist_esky:  accept wider variety of objects for bootstrap_code option
      and Executable.script attribute. Lists are concatenated, files are read,
      strings are raw code, and all else is passed to inspect.getsource().
    * Made bdist_esky.Executable a subclass of unicode rather than str.


v0.8.4:

    * changed to a decorator-based syntax for declaring lazy imports, it's
      cleaner and simpler.


v0.8.3:

    * implemented lazy imports, to reduce the startup time burden on frozen
      applications that must call esky.run_startup_hooks().
    * moved "files_differ" function into esky.util.
    * esky.slaveproc:  don't kill the slave process if something goes wrong
      with the monitoring process.
    * py2exe:  make sure bootstrapped code runs as __main__


v0.8.2:

    * added "pre_freeze_callback" and "pre_zip_callback" options to bdist_esky
      command.  They provide a convenient way to hook the build process with
      e.g. code signing routines.


v0.8.1:

    * added "bootstrap-code" option to bdist_esky, allowing you to specify
      custom bootstrapping code without having to put it in a module.
    * added "esky.slaveproc" module, to support automatic teardown of slave
      processes when their master process dies.
          * this is currently used for simulated execv() under win32, and
            for the helper process in esky.sudo.
    * py2exe: don't bundle files by default, as this can cause issues with
              some libraries (specifically win32ui from my experiments).


v0.8.0:

  THIS RELEASE INTRODUCES A NEW ON-DISK FILE LAYOUT - SEE BELOW FOR NOTES

    * moved all esky control files into an "esky-files" subdir, to avoid
      clutter in the top-level version dir if/when additional files are added.
         * there are compatability hooks for the old file layout, but they
           will be removed in the 0.9.* series.
         * therefore, if you have deployed applications using esky 0.7.* or
           lower, you MUST deploy an update using the 0.8.* series before
           migrating to any newer versions of esky.
    * bootstrap-manifest.txt:  always use forward-slashes in paths, even
      when building for Windows.
    * Esky.fetch_version() now accepts a "callback" argument, which will be
      called with a dictionary of download status information.  For those who
      hate callback functions, you can also use Esky.fetch_version_iter() to
      get an iterator over the download status information.


v0.7.4:

    * py2app:  ensure apps are always inside an "<appname>.app" directory,
      so they will appear correctly in finder etc.
    * esky.util:  added deep_extract_zipfile() function to extract a zipfile
      while ignoring any common directory prefix.
    * esky.finder:  allow downloaded zipfiles to have a containing folder
      around the appdir content, to allow friendlier zipfile behaviour.


v0.7.3:

    * Esky.cleanup_at_exit:  don't fail if there are no installed versions,
      just use the currently-executing script.
    * be more careful about missing files when manipulating eskys that target
      other platforms (e.g. upgrading a win32 esky on a linux box).
    * ensure that fcntl is always available in the bootstrap env.
    * updated tutorial to talk about generating patches.
    * have all executables lock the version dir at startup, even if they're
      not launched through the bootstrap env.


v0.7.2:

    * added methods Esky.needs_cleanup() and VersionFinder.needs_cleanup();
      these can be used to test whether a call to cleanup() is necessary and,
      if not, to avoid locking the appdir or escalating to root.
    * added native sudo implementation for OSX.
    * allow Esky.lock() and Esky.unlock() to be called via sudo proxy.
    * support for Python 3 on win32 (cx-freeze only).
    * fixed compatability with Python 2.5 (via __future__ imports).
    * Esky.cleanup_at_exit:  try to launch the latest version rather than
      the current version, so current version can be cleaned up.
    * DefaultVersionFinder:  when a downloaded file fails because it is
      corrupted, remove it from disk as well as from the version graph.


v0.7.1:

    * restored compatability with Python 3.
    * fixed automatic detection of gui-only scripts based on filename.
    * set variable "__esky_name__" in the bootstrapping code, and use it to
      potentially speed up application startup.


v0.7.0:

    * Renamed "esky.helper" to "esky.sudo" along with much refactoring:
        * @esky.use_helper_app is now @esky.allow_from_sudo() and is used to 
          declare a type signature.
        * Esky.helper_app is now Esky.sudo_proxy and is always an instance
          of esky.sudo.SudoProxy.
        * added Esky.drop_root() method to drop root privileges.
        * implemented multiple safeguards against malicious input when running
          with root privileges.
    * Cause all scripts to automagically call esky.run_startup_hooks() on
      startup.  Currently this:
        * detects the --esky-spawn-sudo option and runs the sudo helper.
        * detects the --esky-spawn-cleanup option and runs the cleanup helper.
    * Have Esky.auto_update() call Esky.cleanup() automatically (mostly so it
      can immediately drop any root privileges it has acquired).
    * Use a separate file "esky-lockfile.txt" for version locking.  This
      will help protect against strange behaviour when fcntl.flock is
      simulated using fcntl.lockf (which released the lock when *any* handle
      to the file is closed).
    * Try to load correctly if executed from a temporary backup file
      (e.g. running from "prog.old.exe" instead of "prog.exe").
    * Allow direct overwriting of existing bootstrap files on win32 (instead
      of renaming the old version out of the way) but only in very special
      circumstances:
        * currently only for executables where the icon or version info
          has changed but the rest of the exe has not.
        * may require spawning a new copy of the process at shutdown, to
          overwrite any in-use bootstrap exes. Use Esky.cleanup_at_exit().
    * Several improvements to py2exe support:
        * implemented "optimize" and "unbuffered" settings in the custom
          bootstrap code.
        * more robust support for the various bundle_files options.


v0.6.0:

    * Added Esky.get_root() method, which can escalate to root privileges by
      spawning a separate helper process.
        * use Esky.has_root() to check if it already has root privileges.
        * escalation can use a variety of "sudo" frontends on Unix, and
          the "runas" functionality on win32 when UAC is enabled.
        * Esky.auto_update() will escalate automatically if it encounters
          a permission error.


v0.5.3:

    * DefaultVersionFinder: make search for update links case-insensitive.
    * py2exe chainloader: execute scripts in the context of the __main__ module.
    * reduce number of stat() calls during bootstrap process.
    * better cleanup of "*.old.*" files from the bootstrap env.
    * use fcntl.flock() for version locking; it's slightly less portable but
      has much better semantics for what we want.


v0.5.2:

    * more robust error-handling in esky.bootstrap.exists()


v0.5.1:

    * only delete files from the top-level app dir if they explicitly belong
      to a version that is being removed.


v0.5.0:

    * implemented preliminary support for freezing with py2app.
    * added module esky.patch for diffing and patching frozen apps:
       * provides a generic file format for diffing/patching directories.
           * can recurse into compressed zipfiles, giving patches an order
             of magnitude smaller than produced by naively applying bsdiff.
       * individual files are diffed via bsdiff if cx-bsdiff is installed.
       * bsdiff-based patches can be applied with no external dependencies.
    * added support for differential updates in DefaultVersionFinder.
    * added "bdist_esky_patch" distutils command for producing differential
      updates in the format expected by DefaultVersionFinder.
    * added filesystem-level locking to protect in-use versions from removal.
    * added attribute Esky.active_version, which is non-None when the esky
      refers to the currently-running application.


v0.4.0:

    * some backwards-incompatible API changes:
       * replace Esky.install_update(v) with Esky.auto_update().
       * new utility methods Esky.install_version(v)/Esky.uninstall_version(v).
       * rename Esky.fetch_update(v) to Esky.fetch_version(v)
       * merge VersionFinder.prepare_version into VersionFinder.fetch_version
    * made all VersionFinder methods take the target esky as first argument
      (in preparation for differential update support in a later version).
    * added support for freezing with cx_Freeze.
    * improved support for freezing with py2exe:
       * added a few well-known hacks to get it to play nice with common
         third-party packages (win32com, wxPython).
       * implemented a custom chainload() function to avoid using execv().
    * added ability to set the icon on each executable, for freezer
      modules that support it (currently py2exe and cx_Freeze on win32).
    * added more version-handling utility functions: get_all_versions,
      is_version_dir, is_installed_version_dir.
    * made Esky.cleanup() catch and ignore common errors.
    * added support for Python 3 (via distribute's "use_2to3" flag)
    * added a brief tutorial and example application


v0.3.0:

    * added ability to bundle MSVCRT as a private assembly (this is off
      by default, since you must have a valid license to redistribute it).
    * refactored to support multiple freezing backends.
        * added support for freezing with py2exe.