develop.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. from setuptools.command.easy_install import easy_install
  2. from distutils.util import convert_path, subst_vars
  3. from pkg_resources import Distribution, PathMetadata, normalize_path
  4. from distutils import log
  5. from distutils.errors import DistutilsError, DistutilsOptionError
  6. import os, sys, setuptools, glob
  7. class develop(easy_install):
  8. """Set up package for development"""
  9. description = "install package in 'development mode'"
  10. user_options = easy_install.user_options + [
  11. ("uninstall", "u", "Uninstall this source package"),
  12. ("egg-path=", None, "Set the path to be used in the .egg-link file"),
  13. ]
  14. boolean_options = easy_install.boolean_options + ['uninstall']
  15. command_consumes_arguments = False # override base
  16. def run(self):
  17. if self.uninstall:
  18. self.multi_version = True
  19. self.uninstall_link()
  20. else:
  21. self.install_for_development()
  22. self.warn_deprecated_options()
  23. def initialize_options(self):
  24. self.uninstall = None
  25. self.egg_path = None
  26. easy_install.initialize_options(self)
  27. self.setup_path = None
  28. self.always_copy_from = '.' # always copy eggs installed in curdir
  29. def finalize_options(self):
  30. ei = self.get_finalized_command("egg_info")
  31. if ei.broken_egg_info:
  32. raise DistutilsError(
  33. "Please rename %r to %r before using 'develop'"
  34. % (ei.egg_info, ei.broken_egg_info)
  35. )
  36. self.args = [ei.egg_name]
  37. easy_install.finalize_options(self)
  38. self.expand_basedirs()
  39. self.expand_dirs()
  40. # pick up setup-dir .egg files only: no .egg-info
  41. self.package_index.scan(glob.glob('*.egg'))
  42. self.egg_link = os.path.join(self.install_dir, ei.egg_name+'.egg-link')
  43. self.egg_base = ei.egg_base
  44. if self.egg_path is None:
  45. self.egg_path = os.path.abspath(ei.egg_base)
  46. target = normalize_path(self.egg_base)
  47. if normalize_path(os.path.join(self.install_dir, self.egg_path)) != target:
  48. raise DistutilsOptionError(
  49. "--egg-path must be a relative path from the install"
  50. " directory to "+target
  51. )
  52. # Make a distribution for the package's source
  53. self.dist = Distribution(
  54. target,
  55. PathMetadata(target, os.path.abspath(ei.egg_info)),
  56. project_name = ei.egg_name
  57. )
  58. p = self.egg_base.replace(os.sep,'/')
  59. if p!= os.curdir:
  60. p = '../' * (p.count('/')+1)
  61. self.setup_path = p
  62. p = normalize_path(os.path.join(self.install_dir, self.egg_path, p))
  63. if p != normalize_path(os.curdir):
  64. raise DistutilsOptionError(
  65. "Can't get a consistent path to setup script from"
  66. " installation directory", p, normalize_path(os.curdir))
  67. def install_for_development(self):
  68. if sys.version_info >= (3,) and getattr(self.distribution, 'use_2to3', False):
  69. # If we run 2to3 we can not do this inplace:
  70. # Ensure metadata is up-to-date
  71. self.reinitialize_command('build_py', inplace=0)
  72. self.run_command('build_py')
  73. bpy_cmd = self.get_finalized_command("build_py")
  74. build_path = normalize_path(bpy_cmd.build_lib)
  75. # Build extensions
  76. self.reinitialize_command('egg_info', egg_base=build_path)
  77. self.run_command('egg_info')
  78. self.reinitialize_command('build_ext', inplace=0)
  79. self.run_command('build_ext')
  80. # Fixup egg-link and easy-install.pth
  81. ei_cmd = self.get_finalized_command("egg_info")
  82. self.egg_path = build_path
  83. self.dist.location = build_path
  84. self.dist._provider = PathMetadata(build_path, ei_cmd.egg_info) # XXX
  85. else:
  86. # Without 2to3 inplace works fine:
  87. self.run_command('egg_info')
  88. # Build extensions in-place
  89. self.reinitialize_command('build_ext', inplace=1)
  90. self.run_command('build_ext')
  91. self.install_site_py() # ensure that target dir is site-safe
  92. if setuptools.bootstrap_install_from:
  93. self.easy_install(setuptools.bootstrap_install_from)
  94. setuptools.bootstrap_install_from = None
  95. # create an .egg-link in the installation dir, pointing to our egg
  96. log.info("Creating %s (link to %s)", self.egg_link, self.egg_base)
  97. if not self.dry_run:
  98. f = open(self.egg_link,"w")
  99. f.write(self.egg_path + "\n" + self.setup_path)
  100. f.close()
  101. # postprocess the installed distro, fixing up .pth, installing scripts,
  102. # and handling requirements
  103. self.process_distribution(None, self.dist, not self.no_deps)
  104. def uninstall_link(self):
  105. if os.path.exists(self.egg_link):
  106. log.info("Removing %s (link to %s)", self.egg_link, self.egg_base)
  107. egg_link_file = open(self.egg_link)
  108. contents = [line.rstrip() for line in egg_link_file]
  109. egg_link_file.close()
  110. if contents not in ([self.egg_path], [self.egg_path, self.setup_path]):
  111. log.warn("Link points to %s: uninstall aborted", contents)
  112. return
  113. if not self.dry_run:
  114. os.unlink(self.egg_link)
  115. if not self.dry_run:
  116. self.update_pth(self.dist) # remove any .pth link to us
  117. if self.distribution.scripts:
  118. # XXX should also check for entry point scripts!
  119. log.warn("Note: you must uninstall or replace scripts manually!")
  120. def install_egg_scripts(self, dist):
  121. if dist is not self.dist:
  122. # Installing a dependency, so fall back to normal behavior
  123. return easy_install.install_egg_scripts(self,dist)
  124. # create wrapper scripts in the script dir, pointing to dist.scripts
  125. # new-style...
  126. self.install_wrapper_scripts(dist)
  127. # ...and old-style
  128. for script_name in self.distribution.scripts or []:
  129. script_path = os.path.abspath(convert_path(script_name))
  130. script_name = os.path.basename(script_path)
  131. f = open(script_path,'rU')
  132. script_text = f.read()
  133. f.close()
  134. self.install_script(dist, script_name, script_text, script_path)