Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

req_tracker.py 2.3KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. from __future__ import absolute_import
  2. import contextlib
  3. import errno
  4. import hashlib
  5. import logging
  6. import os
  7. from pip._internal.utils.temp_dir import TempDirectory
  8. logger = logging.getLogger(__name__)
  9. class RequirementTracker(object):
  10. def __init__(self):
  11. self._root = os.environ.get('PIP_REQ_TRACKER')
  12. if self._root is None:
  13. self._temp_dir = TempDirectory(delete=False, kind='req-tracker')
  14. self._temp_dir.create()
  15. self._root = os.environ['PIP_REQ_TRACKER'] = self._temp_dir.path
  16. logger.debug('Created requirements tracker %r', self._root)
  17. else:
  18. self._temp_dir = None
  19. logger.debug('Re-using requirements tracker %r', self._root)
  20. self._entries = set()
  21. def __enter__(self):
  22. return self
  23. def __exit__(self, exc_type, exc_val, exc_tb):
  24. self.cleanup()
  25. def _entry_path(self, link):
  26. hashed = hashlib.sha224(link.url_without_fragment.encode()).hexdigest()
  27. return os.path.join(self._root, hashed)
  28. def add(self, req):
  29. link = req.link
  30. info = str(req)
  31. entry_path = self._entry_path(link)
  32. try:
  33. with open(entry_path) as fp:
  34. # Error, these's already a build in progress.
  35. raise LookupError('%s is already being built: %s'
  36. % (link, fp.read()))
  37. except IOError as e:
  38. if e.errno != errno.ENOENT:
  39. raise
  40. assert req not in self._entries
  41. with open(entry_path, 'w') as fp:
  42. fp.write(info)
  43. self._entries.add(req)
  44. logger.debug('Added %s to build tracker %r', req, self._root)
  45. def remove(self, req):
  46. link = req.link
  47. self._entries.remove(req)
  48. os.unlink(self._entry_path(link))
  49. logger.debug('Removed %s from build tracker %r', req, self._root)
  50. def cleanup(self):
  51. for req in set(self._entries):
  52. self.remove(req)
  53. remove = self._temp_dir is not None
  54. if remove:
  55. self._temp_dir.cleanup()
  56. logger.debug('%s build tracker %r',
  57. 'Removed' if remove else 'Cleaned',
  58. self._root)
  59. @contextlib.contextmanager
  60. def track(self, req):
  61. self.add(req)
  62. yield
  63. self.remove(req)