setup_extensions.py 3.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. # $Id$
  2. #
  3. # This module extends the stock distutils install_setup code to
  4. # support installation into multiple target directories, with
  5. # semantics similar to what distutils already supports for
  6. # script_files. The bulk of this code is taken directly from the
  7. # stock distutils package, with minor changes. As such, I consider
  8. # this to be a derivative work of the distutils package for copyright
  9. # purposes.
  10. from distutils.util import change_root, convert_path
  11. from distutils.command.build_scripts import build_scripts as _build_scripts
  12. from distutils.command.install_scripts import install_scripts as _install_scripts
  13. from distutils import log
  14. from stat import S_IMODE
  15. import os
  16. class build_scripts(_build_scripts):
  17. """
  18. Hacked version of distutils.build_scripts, designed to support
  19. multiple target installation directories like install_data does.
  20. [(target_directory, [list_of_source_scripts]), ...]
  21. Most of the real work is in the companion hacked install_scripts,
  22. but we need to tweak the list of source files that build_scripts
  23. pulls out of the Distribution object.
  24. """
  25. def finalize_options(self):
  26. _build_scripts.finalize_options(self)
  27. self.scripts = []
  28. for script in self.distribution.scripts:
  29. if isinstance(script, str):
  30. self.scripts.append(script)
  31. else:
  32. self.scripts.extend(script[1])
  33. class install_scripts(_install_scripts):
  34. """
  35. Hacked version of distutils.install_scripts, designed to support
  36. multiple target installation directories like install_data does.
  37. [(target_directory, [list_of_source_scripts]), ...]
  38. The code here is a tweaked combination of what the stock
  39. install_scripts and install_data classes do.
  40. """
  41. user_options = _install_scripts.user_options + [
  42. ("root=", None, "install everything relative to this alternate root directory")]
  43. def initialize_options(self):
  44. _install_scripts.initialize_options(self)
  45. self.outfiles = []
  46. self.root = None
  47. def finalize_options (self):
  48. self.set_undefined_options("build",
  49. ("build_scripts", "build_dir"))
  50. self.set_undefined_options("install",
  51. ("install_scripts", "install_dir"),
  52. ("root", "root"),
  53. ("force", "force"),
  54. ("skip_build", "skip_build"))
  55. def run(self):
  56. if not self.skip_build:
  57. self.run_command("build_scripts")
  58. for script in self.distribution.scripts:
  59. if isinstance(script, str):
  60. fn = os.path.join(self.build_dir, os.path.basename(convert_path(script)))
  61. out, _ = self.copy_file(fn, self.install_dir)
  62. self.outfiles.append(out)
  63. else:
  64. dn = convert_path(script[0])
  65. if not os.path.isabs(dn):
  66. dn = os.path.join(self.install_dir, dn)
  67. elif self.root:
  68. dn = change_root(self.root, dn)
  69. self.mkpath(dn)
  70. if not script[1]:
  71. self.outfiles.append(dn)
  72. else:
  73. for s in script[1]:
  74. fn = os.path.join(self.build_dir, os.path.basename(convert_path(s)))
  75. out, _ = self.copy_file(fn, dn)
  76. self.outfiles.append(out)
  77. if os.name == "posix":
  78. for fn in self.get_outputs():
  79. mode = S_IMODE(os.stat(fn).st_mode) | 0555
  80. log.info("changing mode of %s to %o", fn, mode)
  81. if not self.dry_run:
  82. os.chmod(fn, mode)