[PATCH] setup/hg: always load Mercurial from where it was installed

Dan Villiom Podlaski Christiansen danchr at gmail.com
Fri Oct 8 15:59:40 CDT 2010


# HG changeset patch
# User Dan Villiom Podlaski Christiansen <danchr at gmail.com>
# Date 1282052678 -7200
# Node ID c591f58e62cf97010891907de6adcd40c1c13f07
# Parent  cf135a1c2bd2410bd6eae18cdb59499a51088a3c
setup/hg: always load Mercurial from where it was installed.

This provides two new features:

- Mercurial may be installed into a non-standard location without
  having to set PYTHONPATH.
- Multiple installations can use Mercurial from different locations.

diff --git a/hg b/hg
--- a/hg
+++ b/hg
@@ -7,6 +7,17 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
+import os
+import sys
+
+libdir = '@LIBDIR@'
+
+if libdir != '@' 'LIBDIR' '@':
+    if not os.path.isabs(libdir):
+        libdir = os.path.join(os.path.dirname(__file__), libdir)
+        libdir = os.path.abspath(libdir)
+    sys.path.insert(0, libdir)
+
 # enable importing on demand to reduce startup time
 try:
     from mercurial import demandimport; demandimport.enable()
@@ -17,7 +28,6 @@ except ImportError:
     sys.stderr.write("(check your install and PYTHONPATH)\n")
     sys.exit(-1)
 
-import sys
 import mercurial.util
 import mercurial.dispatch
 
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -52,6 +52,7 @@ from distutils.dist import Distribution
 from distutils.command.build import build
 from distutils.command.build_ext import build_ext
 from distutils.command.build_py import build_py
+from distutils.command.install_scripts import install_scripts
 from distutils.spawn import spawn, find_executable
 from distutils.ccompiler import new_compiler
 from distutils.errors import CCompilerError
@@ -215,6 +216,7 @@ class hgbuildmo(build):
             self.mkpath(join('mercurial', modir))
             self.make_file([pofile], mobuildfile, spawn, (cmd,))
 
+
 # Insert hgbuildmo first so that files in mercurial/locale/ are found
 # when build_py is run next.
 build.sub_commands.insert(0, ('build_mo', None))
@@ -256,9 +258,52 @@ class hgbuildpy(build_py):
             else:
                 yield module
 
+class hginstallscripts(install_scripts):
+    '''
+    This is a specialization of install_scripts that replaces the @LIBDIR@ with
+    the configured directory for modules. If possible, the path is made relative
+    to the directory for scripts.
+    '''
+
+    def initialize_options(self):
+        install_scripts.initialize_options(self)
+
+        self.install_lib = None
+
+    def finalize_options(self):
+        install_scripts.finalize_options(self)
+        self.set_undefined_options('install',
+                                   ('install_lib', 'install_lib'))
+
+    def run(self):
+        install_scripts.run(self)
+
+        if (os.path.splitdrive(self.install_dir)[0] !=
+            os.path.splitdrive(self.install_lib)[0]):
+            # can't make relative paths from one drive to another, so use an
+            # absolute path instead
+            libdir = self.install_lib
+        else:
+            common = os.path.commonprefix((self.install_dir, self.install_lib))
+            rest = self.install_dir[len(common):]
+            uplevel = len([n for n in os.path.split(rest) if n])
+
+            libdir =  uplevel * ('..' + os.sep) + self.install_lib[len(common):]
+
+        for outfile in self.outfiles:
+            data = open(outfile, 'rb').read()
+
+            # skip binary files
+            if '\0' in data:
+                continue
+
+            data = data.replace('@LIBDIR@', libdir)
+            open(outfile, 'wb').write(data)
+
 cmdclass = {'build_mo': hgbuildmo,
             'build_ext': hgbuildext,
-            'build_py': hgbuildpy}
+            'build_py': hgbuildpy,
+            'install_scripts': hginstallscripts}
 
 packages = ['mercurial', 'mercurial.hgweb', 'hgext', 'hgext.convert',
             'hgext.highlight', 'hgext.zeroconf']


More information about the Mercurial-devel mailing list