[PATCH 1 of 2] extensions: extract descriptions at build time

Cédric Duval cedricduval at free.fr
Sun Jun 28 05:00:23 CDT 2009


# HG changeset patch
# User Cédric Duval <cedricduval at free.fr>
# Date 1246176984 -7200
# Node ID a61ea0b22a3f6f3a0a6bb209b58a64efeed22c01
# Parent  835a51e63c5b0e4eee4f95fcbbdaf4476629a621
extensions: extract descriptions at build time

This series of two changesets fixes issue1708, by pre-processing extensions
descriptions at build time, rather than trying to extract them at runtime.

This frees us from the quirks of the various packaging schemes, e.g. on
win32 (with py2exe) extensions are shipped inside a library.zip archive
stripped from all the py files.

This first changeset adds a python module containing the descriptions of
each extension. This module is generated at build time, and updated in case
any of the files from which descriptions are extracted has been modified.

diff --git a/.hgignore b/.hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -24,6 +24,7 @@
 doc/*.[0-9].{x,ht}ml
 MANIFEST
 patches
+mercurial/__extensions__.py
 mercurial/__version__.py
 Output/Mercurial-*.exe
 .DS_Store
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -26,7 +26,11 @@
 all: build doc
 
 local:
-	$(PYTHON) setup.py $(PURE) build_py -c -d . build_ext -i build_mo
+	$(PYTHON) setup.py $(PURE) \
+	    build_extensions_list \
+	    build_py -c -d . \
+	    build_ext -i \
+	    build_mo
 	$(PYTHON) hg version
 
 build:
@@ -39,6 +43,7 @@
 	-$(PYTHON) setup.py clean --all # ignore errors from this command
 	find . -name '*.py[cdo]' -exec rm -f '{}' ';'
 	rm -f MANIFEST mercurial/__version__.py mercurial/*.so tests/*.err
+	rm -f mercurial/__extensions__.py
 	rm -rf locale
 	$(MAKE) -C doc clean
 
@@ -63,7 +68,7 @@
 
 MANIFEST: MANIFEST-doc
 	hg manifest > MANIFEST
-	echo mercurial/__version__.py >> MANIFEST
+	echo mercurial/__version__.py mercurial/__extensions__.py >> MANIFEST
 	cat doc/MANIFEST >> MANIFEST
 
 dist:	tests dist-notests
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -161,6 +161,57 @@
                                    ('install_lib', 'install_dir'))
         install_data.finalize_options(self)
 
+class build_extensions_list(build):
+
+    description = "build the list of Mercurial extensions"
+    target = os.path.join('mercurial', '__extensions__.py')
+
+    def paths(self):
+        '''return a dict of {name: path} for all extensions'''
+        exts = {}
+        for e in os.listdir('hgext'):
+            if e.endswith('.py') and e != '__init__.py':
+                exts[e.rsplit('.', 1)[0]] = os.path.join('hgext', e)
+            else:
+                path = os.path.join('hgext', e, '__init__.py')
+                if os.path.exists(path):
+                    exts[e] = path
+        return exts
+
+    def descriptions(self):
+        '''return a dict of {name: description} for each extension'''
+
+        # XXX temporary kludge to allow importing Mercurial modules while the
+        # C modules can not be used - but help.moduledoc() is no longer used by
+        # hg anyway, and will be moved away from help.py in next changeset...
+        sys.path.append(os.path.join('mercurial', 'pure'))
+        from mercurial.help import moduledoc
+
+        exts = {}
+        for name, path in self.paths().iteritems():
+            try:
+                file = open(path)
+            except IOError:
+                continue
+            else:
+                exts[name] = moduledoc(file) or '(no help text available)'
+                file.close()
+        return exts
+
+    def generate(self):
+        '''write the descriptions dict in the target file'''
+        f = file(self.target, 'w')
+        f.write('# this file is autogenerated by setup.py\n')
+        f.write('descriptions = ' + repr(self.descriptions()) + '\n')
+        f.close()
+
+    def run(self):
+        '''(re)generate target if some extensions sources are more recent'''
+        deps = self.paths().values()
+        self.make_file(deps, self.target, self.generate, [])
+
+build.sub_commands.insert(0, ('build_extensions_list', None))
+
 class build_mo(build):
 
     description = "build translations (.mo files)"
@@ -221,6 +272,7 @@
                 yield module
 
 cmdclass = {'install_data': install_package_data,
+            'build_extensions_list': build_extensions_list,
             'build_mo': build_mo,
             'build_py': hg_build_py}
 



More information about the Mercurial-devel mailing list