nsiswriter.py 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. import itertools
  2. from operator import itemgetter
  3. import os
  4. import ntpath
  5. import sys
  6. import jinja2
  7. _PKGDIR = os.path.abspath(os.path.dirname(__file__))
  8. PY2 = sys.version_info[0] == 2
  9. class NSISFileWriter(object):
  10. """Write an .nsi script file by filling in a template.
  11. """
  12. def __init__(self, template_file, installerbuilder, definitions=None):
  13. """Instantiate an NSISFileWriter
  14. :param str template_file: Path to the .nsi template
  15. :param dict definitions: Mapping of name to value (values will be quoted)
  16. """
  17. env = jinja2.Environment(loader=jinja2.FileSystemLoader([
  18. _PKGDIR,
  19. os.getcwd()
  20. ]),
  21. # Change template markers from {}, which NSIS uses, to [], which it
  22. # doesn't much, so it's easier to distinguishing our templating from
  23. # NSIS preprocessor variables.
  24. block_start_string="[%",
  25. block_end_string="%]",
  26. variable_start_string="[[",
  27. variable_end_string="]]",
  28. comment_start_string="[#",
  29. comment_end_string="#]",
  30. # Trim whitespace around block tags, so formatting works as I expect
  31. trim_blocks=True,
  32. lstrip_blocks=True,
  33. )
  34. self.template = env.get_template(template_file)
  35. self.installerbuilder = installerbuilder
  36. # Group files by their destination directory
  37. grouped_files = [(dest, [x[0] for x in group]) for (dest, group) in
  38. itertools.groupby(self.installerbuilder.install_files, itemgetter(1))
  39. ]
  40. license_file = None
  41. if installerbuilder.license_file:
  42. license_file = os.path.basename(installerbuilder.license_file)
  43. self.namespace = {
  44. 'ib': installerbuilder,
  45. 'grouped_files': grouped_files,
  46. 'icon': os.path.basename(installerbuilder.icon),
  47. 'arch_tag': '.amd64' if (installerbuilder.py_bitness==64) else '',
  48. 'pjoin': ntpath.join,
  49. 'single_shortcut': len(installerbuilder.shortcuts) == 1,
  50. 'pynsist_pkg_dir': _PKGDIR,
  51. 'has_commands': len(installerbuilder.commands) > 0,
  52. 'python': '"$INSTDIR\\Python\\python"',
  53. 'license_file': license_file,
  54. }
  55. def write(self, target):
  56. """Fill out the template and write the result to 'target'.
  57. :param str target: Path to the file to be written
  58. """
  59. with open(target, 'w') as fout:
  60. fout.write(self.template.render(self.namespace))