

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.

