pth.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #!/usr/bin/env python
  2. # Licensed to Cloudera, Inc. under one
  3. # or more contributor license agreements. See the NOTICE file
  4. # distributed with this work for additional information
  5. # regarding copyright ownership. Cloudera, Inc. licenses this file
  6. # to you under the Apache License, Version 2.0 (the
  7. # "License"); you may not use this file except in compliance
  8. # with the License. You may obtain a copy of the License at
  9. #
  10. # http://www.apache.org/licenses/LICENSE-2.0
  11. #
  12. # Unless required by applicable law or agreed to in writing, software
  13. # distributed under the License is distributed on an "AS IS" BASIS,
  14. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. # See the License for the specific language governing permissions and
  16. # limitations under the License.
  17. """
  18. Tools to manipulate the .pth file in the virtualenv.
  19. """
  20. import glob
  21. import logging
  22. import os
  23. import common
  24. LOG = logging.getLogger(__name__)
  25. PTH_SYMLINK = 'hue.link.pth'
  26. PTH_FILE = 'hue.pth'
  27. def _get_pth_symlink():
  28. """
  29. _get_pth_symlink -> Path to the .pth symlink.
  30. May raise SystemError if the virtual env is absent.
  31. """
  32. return os.path.join(common._get_python_site_packages_dir(), PTH_SYMLINK)
  33. def _get_pth_filename():
  34. """
  35. _get_pth_filename -> Path to the .pth file.
  36. Location can be defined via HUE_PTH_DIR environment variable.
  37. May raise SystemError if the virtual env is absent.
  38. """
  39. pth_dir = os.environ.get('HUE_PTH_DIR', None)
  40. if pth_dir:
  41. return os.path.join(pth_dir, PTH_FILE)
  42. else:
  43. return os.path.join(common._get_python_site_packages_dir(), PTH_FILE)
  44. class PthFile(object):
  45. def __init__(self):
  46. """May raise SystemError if the virtual env is absent"""
  47. self._symlink_path = _get_pth_symlink()
  48. self._path = _get_pth_filename()
  49. self._entries = [ ]
  50. self._read()
  51. def _read(self):
  52. if os.path.exists(self._path):
  53. self._entries = set(file(self._path).read().split('\n'))
  54. def add(self, app):
  55. """
  56. Add the app and its ext eggs into the pth file
  57. """
  58. module_path = os.path.join(app.path, 'src')
  59. LOG.debug('Add to %s: %s' % (self._path, module_path))
  60. self._entries.add(module_path)
  61. # Eggs could be in ext-py/<pkg>/dist/*.egg
  62. ext_pys = app.find_ext_pys()
  63. for py in ext_pys:
  64. ext_egg = glob.glob(os.path.join(py, 'dist', '*.egg'))
  65. LOG.debug('Add to %s: %s' % (self._path, ext_egg))
  66. self._entries.update(ext_egg)
  67. # And eggs could also be in ext-eggs/*.egg
  68. for egg_file in glob.glob(os.path.join(app.path, 'ext-eggs', '*.egg')):
  69. LOG.debug('Add to %s: %s' % (self._path, egg_file))
  70. self._entries.add(egg_file)
  71. def remove(self, app):
  72. """
  73. Remove the app and its ext eggs from the pth file
  74. """
  75. for path in self._entries.copy():
  76. if path.startswith(app.path):
  77. self._entries.remove(path)
  78. def save(self):
  79. """
  80. Save the pth file
  81. Create a symlink to the path if it does not already exist.
  82. """
  83. tmp_path = self._path + '.new'
  84. file(tmp_path, 'w').write('\n'.join(sorted(self._entries)))
  85. os.rename(tmp_path, self._path)
  86. LOG.info('=== Saved %s' % (self._path,))
  87. if not os.path.exists(self._symlink_path):
  88. os.symlink(self._path, self._symlink_path)
  89. def sync(self, apps):
  90. """Sync the .pth file with the installed apps"""
  91. self._entries = set()
  92. for app in apps:
  93. self.add(app)