commands.py 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. import distlib.scripts
  2. import io
  3. import os.path as osp
  4. import shutil
  5. from zipfile import ZipFile
  6. SCRIPT_TEMPLATE = u"""# -*- coding: utf-8 -*-
  7. import sys, os
  8. import site
  9. installdir = os.path.dirname(os.path.dirname(__file__))
  10. pkgdir = os.path.join(installdir, 'pkgs')
  11. sys.path.insert(0, pkgdir)
  12. # Ensure .pth files in pkgdir are handled properly
  13. site.addsitedir(pkgdir)
  14. os.environ['PYTHONPATH'] = pkgdir + os.pathsep + os.environ.get('PYTHONPATH', '')
  15. # Allowing .dll files in Python directory to be found
  16. os.environ['PATH'] += ';' + os.path.dirname(sys.executable)
  17. {extra_preamble}
  18. if __name__ == '__main__':
  19. from {module} import {func}
  20. sys.exit({func}())
  21. """
  22. def find_exe(bitness=32):
  23. distlib_dir = osp.dirname(distlib.scripts.__file__)
  24. return osp.join(distlib_dir, 't%d.exe' % bitness)
  25. def prepare_bin_directory(target, commands, bitness=32):
  26. # Give the base launcher a .dat extension so it doesn't show up as an
  27. # executable command itself. During the installation it will be copied to
  28. # each launcher name, and the necessary data appended to it.
  29. shutil.copy(find_exe(bitness), str(target / 'launcher_exe.dat'))
  30. for name, command in commands.items():
  31. specified_preamble = command.get('extra_preamble', None)
  32. if isinstance(specified_preamble, str):
  33. # Filename
  34. extra_preamble = io.open(specified_preamble, encoding='utf-8')
  35. elif specified_preamble is None:
  36. extra_preamble = io.StringIO() # Empty
  37. else:
  38. # Passed a StringIO or similar object
  39. extra_preamble = specified_preamble
  40. module, func = command['entry_point'].split(':')
  41. script = SCRIPT_TEMPLATE.format(
  42. module=module, func=func,
  43. extra_preamble=extra_preamble.read().rstrip(),
  44. )
  45. with ZipFile(str(target / (name + '-append.zip')), 'w') as zf:
  46. zf.writestr('__main__.py', script.encode('utf-8'))