setup_util.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import re
  2. import os
  3. import sys
  4. import subprocess
  5. from threading import Thread
  6. from Queue import Queue, Empty
  7. class NonBlockingStreamReader:
  8. '''
  9. Enables calling readline in a non-blocking manner with a blocking stream,
  10. such as the ones returned from subprocess.Popen
  11. Originally written by Eyal Arubas, who granted permission to use this inside TFB
  12. See http://eyalarubas.com/python-subproc-nonblock.html
  13. '''
  14. def __init__(self, stream, eof_message=None):
  15. '''
  16. stream: the stream to read from.
  17. Usually a process' stdout or stderr.
  18. eof_message: A message to print to stdout as soon
  19. as the stream's end is reached. Useful if you
  20. want to track the exact moment a stream terminates
  21. '''
  22. self._s = stream
  23. self._q = Queue()
  24. self._eof_message = eof_message
  25. self._poisonpill = 'MAGIC_POISONPILL_STRING'
  26. def _populateQueue(stream, queue):
  27. while True:
  28. line = stream.readline()
  29. if line: # 'data\n' or '\n'
  30. queue.put(line)
  31. else: # '' e.g. EOF
  32. if self._eof_message:
  33. sys.stdout.write(self._eof_message + '\n')
  34. queue.put(self._poisonpill)
  35. return
  36. self._t = Thread(target=_populateQueue, args=(self._s, self._q))
  37. self._t.daemon = True
  38. self._t.start()
  39. def readline(self, timeout=None):
  40. try:
  41. line = self._q.get(block=timeout is not None, timeout=timeout)
  42. if line == self._poisonpill:
  43. raise EndOfStream
  44. return line
  45. except Empty:
  46. return None
  47. class EndOfStream(Exception):
  48. pass
  49. # Replaces all text found using the regular expression to_replace with the supplied replacement.
  50. def replace_text(file, to_replace, replacement):
  51. with open(file, "r") as conf:
  52. contents = conf.read()
  53. replaced_text = re.sub(to_replace, replacement, contents)
  54. with open(file, "w") as f:
  55. f.write(replaced_text)
  56. # Queries the shell for the value of FWROOT
  57. def get_fwroot():
  58. if os.getenv('FWROOT'):
  59. return os.environ['FWROOT']
  60. else:
  61. return os.getcwd()
  62. # Turns absolute path into path relative to FWROOT
  63. # Assumes path is underneath FWROOT, not above
  64. #
  65. # Useful for clean presentation of paths
  66. # e.g. /foo/bar/benchmarks/go/install.sh
  67. # v.s. FWROOT/go/install.sh
  68. def path_relative_to_root(path):
  69. # Requires bash shell parameter expansion
  70. return subprocess.check_output(
  71. "D=%s && printf \"${D#%s}\"" % (path, get_fwroot()),
  72. shell=True,
  73. executable='/bin/bash')