build.py 1.9 KB

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