summaryrefslogtreecommitdiffstats
path: root/setup.py
diff options
context:
space:
mode:
authorChris St. Pierre <stpierreca@ornl.gov>2011-01-27 14:50:51 -0600
committerSol Jerome <sol.jerome@gmail.com>2011-01-27 14:50:51 -0600
commita193b1edeebc0f96cc15e9702af97a0480cd9c4b (patch)
tree02f3b923c8b41ef0058fb003713404a3ac2f32ef /setup.py
parent48d88b48a08091340f16add2f505101948c8a9d9 (diff)
downloadbcfg2-a193b1edeebc0f96cc15e9702af97a0480cd9c4b.tar.gz
bcfg2-a193b1edeebc0f96cc15e9702af97a0480cd9c4b.tar.bz2
bcfg2-a193b1edeebc0f96cc15e9702af97a0480cd9c4b.zip
schemas: Build DTD docs, provide -doc subpackage in RPM (Resolves #984)
From the ticket: I've attached a patch that does two things: 1. Uses xs3p (http://xml.fiforms.org/xs3p/), an XSLT stylesheet, to do transforms on the Bcfg2 DTD and automatically generates documentation on the DTD. I added a build_dtddoc command to setup.py that performs the transforms using lxml.etree and puts the resulting HTML in build/dtd. I also added some documentation to bundle.xsd; it's not much, but should demonstrate the ease with which the DTD can be documented with this system in use. 2. I added both build_sphinx and build_dtddoc commands to the RPM specfile, and added a -doc subpackage to put the resulting HTML in. The specfile builds successfully on CentOS 5 and Fedora 13. There are a couple of known issues: 1. The output from xs3p uses pop-ups to present documentation on non-global components, which, due to the way the Bcfg2 DTD is written, is most of them. This is ugly. It could be improved by modifying the XSLT, but I'm not a web designer and wasn't sure the best way to present that information. Either way, this is a start. 2. The python-sphinx10 package in EPEL 5 apparently has a bug where it fails to add itself to sys.path after installing. There's some ugliness in the spec file to get around that. Signed-off-by: Sol Jerome <sol.jerome@gmail.com>
Diffstat (limited to 'setup.py')
-rw-r--r--setup.py108
1 files changed, 105 insertions, 3 deletions
diff --git a/setup.py b/setup.py
index ad2fa7331..9eaa6f626 100644
--- a/setup.py
+++ b/setup.py
@@ -1,12 +1,114 @@
#!/usr/bin/env python
from distutils.core import setup
+from distutils.core import Command
+from fnmatch import fnmatch
+from glob import glob
+import os.path
+import lxml.etree
+
+class BuildDTDDoc (Command):
+ """Build DTD documentation"""
+
+ description = "Build DTD documentation"
+
+ # List of option tuples: long name, short name (None if no short
+ # name), and help string.
+ user_options = [
+ ('links-file=', 'l', 'Links file'),
+ ('source-dir=', 's', 'Source directory'),
+ ('build-dir=', None, 'Build directory'),
+ ('xslt=', None, 'XSLT file'),
+ ]
+
+ def initialize_options(self):
+ """Set default values for all the options that this command
+ supports."""
+
+ self.build_links = False
+ self.links_file = None
+ self.source_dir = None
+ self.build_dir = None
+ self.xslt = None
+
+ def finalize_options(self):
+ """Set final values for all the options that this command
+ supports."""
+ if self.source_dir is None:
+ if os.path.isdir('schemas'):
+ for root, dirnames, filenames in os.walk('schemas'):
+ for filename in filenames:
+ if fnmatch(filename, '*.xsd'):
+ self.source_dir = root
+ self.announce('Using source directory %s' % root)
+ break
+ self.ensure_dirname('source_dir')
+ self.source_dir = os.path.abspath(self.source_dir)
+
+ if self.build_dir is None:
+ build = self.get_finalized_command('build')
+ self.build_dir = os.path.join(build.build_base, 'dtd')
+ self.mkpath(self.build_dir)
+
+ if self.links_file is None:
+ self.links_file = "links.xml"
+ if os.path.isfile(os.path.join(self.source_dir, "links.xml")):
+ self.announce("Using linksFile links.xml")
+ else:
+ self.build_links = True
+
+ if self.xslt is None:
+ xsl_files = glob(os.path.join(self.source_dir, '*.xsl'))
+ if xsl_files:
+ self.xslt = xsl_files[0]
+ self.announce("Using XSLT file %s" % self.xslt)
+ self.ensure_filename('xslt')
+
+ def run (self):
+ """Perform XSLT transforms, writing output to self.build_dir"""
+
+ xslt = lxml.etree.parse(self.xslt).getroot()
+ transform = lxml.etree.XSLT(xslt)
+
+ if self.build_links:
+ self.announce("Building linksFile %s" % self.links_file)
+ links_xml = \
+ lxml.etree.Element('links',
+ attrib={'xmlns':"http://titanium.dstc.edu.au/xml/xs3p"})
+ for filename in glob(os.path.join(self.source_dir, '*.xsd')):
+ attrib = {'file-location':os.path.basename(filename),
+ 'docfile-location':os.path.splitext(os.path.basename(filename))[0] + ".html"}
+ links_xml.append(lxml.etree.Element('schema', attrib=attrib))
+ open(os.path.join(self.source_dir, self.links_file),
+ "w").write(lxml.etree.tostring(links_xml))
+
+ # build parameter dict
+ params = {'printLegend':"'false'",
+ 'printGlossary':"'false'",
+ 'sortByComponent':"'false'",}
+ if self.links_file is not None:
+ params['linksFile'] = "'%s'" % self.links_file
+ params['searchIncludedSchemas'] = "'true'"
+
+ for filename in glob(os.path.join(self.source_dir, '*.xsd')):
+ outfile = \
+ os.path.join(self.build_dir,
+ os.path.splitext(os.path.basename(filename))[0] +
+ ".html")
+ self.announce("Transforming %s to %s" % (filename, outfile))
+ xml = lxml.etree.parse(filename).getroot()
+ xhtml = str(transform(xml, **params))
+ open(outfile, 'w').write(xhtml)
+
+cmdclass = {}
+
try:
from sphinx.setup_command import BuildDoc
- cmdclass = {'build_sphinx': BuildDoc}
+ cmdclass['build_sphinx'] = BuildDoc
except ImportError:
- cmdclass = {}
-from glob import glob
+ pass
+
+cmdclass['build_dtddoc'] = BuildDTDDoc
setup(cmdclass=cmdclass,
name="Bcfg2",