[Distutils] configuration files preservation

Roman Kurakin rik at inse.ru
Tue Dec 19 15:05:17 CET 2006


While working on one project I've met a problem that I can't to specify to
not touch my configuration files for python package that uses setup.py
technique. To solve this problem I've implemented the following solution
that works for me. If this idea worths it, I can make a patch relative 
needed
version of python.

Here is the patch I've done for that project (inlined here to show the 
idea).


# HG changeset patch
# Node ID 286864b5c6a30d0ebba5fc99876013c85c06ab59
# Parent  fc4dfd9ad64f477a0326995bea7cda12e33ddb39
Add 'preserve files' functionality to setup() while installation. (clean 
version)

diff -r fc4dfd9ad64f -r 286864b5c6a3 setup.py
--- a/setup.py  Wed Dec 13 12:50:46 2006 +0300
+++ b/setup.py  Mon Dec 18 14:01:34 2006 +0300
@@ -26,17 +26,66 @@
 # POSSIBILITY OF SUCH DAMAGE.
 
 from distutils.core import setup
+from distutils.command.install_data import install_data
+from distutils.util import change_root, convert_path
+from types import StringType
 
-import sys
+import sys,os
 pyver = "%d.%d" % sys.version_info[0:2]
+
+class smart_install_data(install_data):
+    def run(self):
+        # Use revers order for safe removal
+        for i in range(len(self.data_files)-1, -1, -1):
+            f = self.data_files[i]
+            if type(f) is StringType:
+                continue
+            if len(f) <= 2:
+               continue
+            # Ok, we have additional value, do some magick according it.
+            if f[2] != "preserve":
+                # Nope, we do not know it. Just ignore for now.
+                # Should we scream about it?
+                continue
+            # Check a tuple with path to install to and a list of files
+            dir = convert_path(f[0])
+            if not os.path.isabs(dir):
+                dir = os.path.join(self.install_dir, dir)
+            elif self.root:
+                dir = change_root(self.root, dir)
+
+            if f[1] == []:
+                # If there are no files listed, the user must be
+                # trying to create an empty directory, so just ignore
+                # it.
+                # Should we scream in this case?
+                continue
+
+            # Check files one by one.
+            # Use revers order for safe removal
+            for j in range(len(f[1])-1, -1, -1):
+                data=f[1][j]
+                data = convert_path(data)
+                if not os.path.isfile(data):
+                    # Again skip dirs.
+                    continue
+                dst = os.path.join(dir, os.path.basename(data))
+                if not os.path.exists(dst):
+                    continue
+                del f[1][j]
+            if len(f[1]) == 0:
+                del self.data_files[i]
+
+        return install_data.run(self)
 
 setup(name = 'usher',
       version = '0.1',
       package_dir = { 'usher':'python' },
       packages = ['usher', 'usher.ushercli', 'usher.usherlnm', 
'usher.utils', 'usher.usherctrl'],
+      cmdclass = {'install_data':smart_install_data},
       data_files = [
           ('/etc/init.d', ['initscripts/usherctrl', 
'initscripts/usherlnm']),
-          ('/etc/usher', ['configs/usherctrl.config', 
'configs/usherlnm.config', 'configs/ushercli.config']),
+          ('/etc/usher', ['configs/usherctrl.config', 
'configs/usherlnm.config', 'configs/ushercli.config'], "preserve"),
           ("/usr/lib/python%s/site-packages/usher/usherctrl" % pyver, 
['python/usherctrl/app.tac']),
           ("/usr/lib/python%s/site-packages/usher/usherlnm" % pyver, 
['python/usherlnm/app.tac'])
       ]



More information about the Distutils-SIG mailing list