build.py 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. import os
  2. import platform
  3. import re
  4. import subprocess
  5. import sys
  6. from ..utils.compat import decode
  7. from ..utils.deps import APPIMAGETOOL, ensure_appimagetool
  8. from ..utils.docker import docker_run
  9. from ..utils.fs import copy_tree
  10. from ..utils.log import debug, log
  11. from ..utils.tmp import TemporaryDirectory
  12. __all__ = ['build_appimage']
  13. def build_appimage(appdir=None, destination=None):
  14. '''Build an AppImage from an AppDir
  15. '''
  16. if appdir is None:
  17. appdir = 'AppDir'
  18. log('BUILD', appdir)
  19. ensure_appimagetool()
  20. arch = platform.machine()
  21. cmd = ['ARCH=' + arch, APPIMAGETOOL, '--no-appstream', appdir]
  22. if destination is not None:
  23. cmd.append(destination)
  24. cmd = ' '.join(cmd)
  25. debug('SYSTEM', cmd)
  26. p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
  27. stderr=subprocess.STDOUT)
  28. appimage_pattern = re.compile('should be packaged as ([^ ]+[.]AppImage)')
  29. stdout, appimage = [], None
  30. while True:
  31. out = decode(p.stdout.readline())
  32. stdout.append(out)
  33. if out == '' and p.poll() is not None:
  34. break
  35. elif out:
  36. out = out.replace('%', '%%')[:-1]
  37. for line in out.split(os.linesep):
  38. if line.startswith('WARNING'):
  39. log('WARNING', line[9:])
  40. elif line.startswith('Error'):
  41. raise RuntimeError(line)
  42. else:
  43. if destination is None:
  44. match = appimage_pattern.search(line)
  45. if match is not None:
  46. destination = match.group(1)
  47. debug('APPIMAGE', line)
  48. rc = p.poll()
  49. if rc != 0 and not os.path.exists(destination):
  50. print(''.join(stdout))
  51. sys.stdout.flush()
  52. raise RuntimeError('Could not build AppImage')