I'm developing a GUI app in Python. I use cx_Freeze to turn my app into .app/ / .dmg files for OS X users. So, for instance I can use python setup.py bdist_dmg to make cx_Freeze create a .dmg file that my users can use to install my app.
I now want my app to update itself automatically. Esky seems to be a promising framework for doing this. I can do python setup.py bdist_esky to create a version of my app that updates itself. It produces the following directory structure:
myappmyapp-0.1/myapp- ...
- ...
The top-level myapp is Esky's bootstrapping executable. It looks in the current directory, finds myapp-0.1/ as the latest version and then launches myapp-0.1/myapp.
How do I package this into a .dmg file which I can ship to my users? After my modifications to setup.py to get bdist_esky to work, bdist_dmg no longer works. The impression I get is that Esky is simply not meant to be used with bdist_dmg. Its documentation doesn't mention DMG files at all and I also couldn't find anything on Google.
As a first step, I tried to manually turn the files generated by Esky into an OS X .app/ bundle:
myapp.app/Contents/Info.plistMacOS/myappmyapp-0.1/myapp- ...
- ...
Info.plist contains the minimum amount of necessary information to get OS X to run myapp. When I try to run myapp.app however, I get:
Traceback (most recent call last):
File "<string>", line 318, in bootstrap
File "<string>", line 442, in get_best_version
FileNotFoundError: [Errno 2] No such file or directory: '/Users/michael/Temp/myapp.app/appdata'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<string>", line 689, in <module>
File "<string>", line 335, in bootstrap
RuntimeError: no usable frozen versions were found
Looking at Esky's source code, it appears to have some special handling for OS X bundles in its appdir_from_executable(...) function. To make Esky happy, I tried to rearrange my files so appdata/ actually exists:
myapp.app/appdata/myapp-0.1/myapp- ...
Contents/Info.plistMacOS/myapp- ...
Unfortunately, this results in another error:
Traceback (most recent call last):
File "<string>", line 689, in <module>
File "<string>", line 336, in bootstrap
File "<string>", line 363, in chainload
File "<string>", line 425, in _chainload
UnboundLocalError: local variable 'exc_value' referenced before assignment
Is this really that difficult? Am I the only one who wants to use Esky and ship files to users in the (standard) .dmg format? What am I missing?