From: W. Trevor King Date: Sun, 6 Mar 2011 01:18:20 +0000 (-0500) Subject: Initial work at removing the root Makefile. Ugly setup.py. Probably not worth it... X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=refs%2Fheads%2Fno-makefiles;p=be.git Initial work at removing the root Makefile. Ugly setup.py. Probably not worth it... --- diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..dd5e5b2 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,6 @@ +include AUTHORS COPYING NEWS README test.py +include doc/*.txt +include doc/*.py +include doc/man/*.txt +recursive-include interfaces * +recursive-include misc * diff --git a/doc/install.txt b/doc/install.txt index c428087..350f87f 100644 --- a/doc/install.txt +++ b/doc/install.txt @@ -29,37 +29,11 @@ BE is available as a Git repository:: $ git clone git://gitorious.org/be/be.git be -See the homepage_ for details. If you do branch the Git repo, you'll -need to run:: +See the homepage_ for details. To install the checkout, run the +standard:: - $ make + $ python setup.py install -to build some auto-generated files (e.g. :mod:`libbe._version`), and:: - - $ make install - -to install BE. By default BE will install into your home directory, -but you can tweak the ``PREFIX`` variable in ``Makefile`` to install -to another location. - -By default, ``make`` builds both a man page for ``be`` and the HTML -Sphinx documentation (:doc:`doc`). You can customize the -documentation targets by overriding_ the ``DOC`` variable. For -example, to disable all documentation during a build/install, run:: - - $ make DOC= install - -Note that ``setup.py`` (called during ``make install``) will install -the man page (``doc/man/be.1``) if it exists, so:: - - $ make - $ make DOC= install - -*will* build (first ``make``) install (second ``make``) the man page. - - -.. _homepage: http://bugseverywhere.org/ -.. _overriding: http://www.gnu.org/software/make/manual/html_node/Overriding.html#Overriding Release tarballs diff --git a/setup.py b/setup.py index b7fb839..eaef3cb 100755 --- a/setup.py +++ b/setup.py @@ -1,24 +1,251 @@ #!/usr/bin/env python -from distutils.core import setup +from distutils.core import setup, Command +from distutils.command.build import build +from distutils.command.build_py import build_py +from distutils.command.install import install +from distutils import log +import os import os.path +import sys -from libbe import _version +try: + import docutils + import docutils.core +except ImportError, e: + log.warn( + 'cannot import docutils (required to build documentation): %s' % e) + docutils = None -rev_id = _version.version_info["revision"] -rev_date = _version.version_info["date"] +try: + import sphinx +except ImportError, e: + log.warn('cannot import sphinx (required to build user guide): %s' % e) + sphinx = None -data_files = [] +from libbe.version import version +from libbe.util.subproc import invoke + + +_this_dir = os.path.dirname(__file__) + + +class _build_py (build_py): + def run(self): + target_dir = os.path.join(self.build_lib, 'libbe') + if os.path.exists('.git'): + self._generate_version(target_dir) + # distutils uses old-style classes, so no super() + build_py.run(self) + + def _generate_version(self, target_dir): + version_path = os.path.join(target_dir, '_version.py') + log.info('generate %s using git' % version_path) + if not self.dry_run: + format = ( + '"Autogenerated by make libbe/_version.py"%n' + 'version_info = {%n' + ' "date":"%cd",%n' + ' "revision":"%H",%n' + ' "committer":"%cn"}%n' + ) + status,stdout,stderr = invoke( + ['git', 'log', '-1', '--date=short', + "--pretty='format:%s'" % format]) + + +class build_doc (Command): + description = "build package documentation" + + user_options = [ + ('man', None, 'compile man page (with docutils) [default]'), + ('no-man', None, "don't compile man page"), + ('guide', None, 'compile user guide (with sphinx) [default]'), + ('no-guide', None, "don't compile user guide"), + ] + + boolean_options = ['man', 'guide'] + negative_opt = {'no-man': 'man', 'no-guide': 'guide'} + + def initialize_options(self): + self.man = True + self.guide = True + + def finalize_options(self): + pass + + def run(self): + if self.man: + self._build_man() + if self.guide: + self._build_guide() + + def _build_man(self): + if docutils == None: + log.error('cannot build man page without docutils') + return + man_dir = os.path.join(_this_dir, 'doc', 'man') + for filename in os.listdir(man_dir): + basename,extension = os.path.splitext(filename) + if extension == '.txt': + source_path = os.path.join(man_dir, filename) + destination_path = os.path.join(man_dir, basename) + log.info('converting %s -> %s' % (source_path, destination_path)) + if not self.dry_run: + docutils.core.publish_file( + source_path=source_path, + destination_path=destination_path, + writer_name='manpage') + + def _build_guide(self): + if docutils == None: + log.error('cannot build user guide without docutils') + return + if sphinx == None: + log.error('cannot build user guide without sphinx') + return + log.info('building user guide') + doc_dir = os.path.join(_this_dir, 'doc') + doctree_dir = os.path.join(doc_dir, '.build', 'doctrees') + html_dir = os.path.join(doc_dir, '.build', 'html') + log.info('generating autodoc/automodule pages for API documentation') + if not self.dry_run: + cwd = os.getcwd() + try: + os.chdir(doc_dir) + status,stdout,stderr = invoke( + [sys.executable, 'generate-libbe-txt.py']) + finally: + os.chdir(cwd) + log.info('building user guide with sphinx') + if not self.dry_run: + ret = sphinx.main([ + 'sphinx-build', '-d', doctree_dir, + '-b', 'html', doc_dir, html_dir]) + if ret != 0: + log.error('errors building user guide') + + +build.sub_commands.append(('build_doc', None)) + + +class install_doc (Command): + description = "install package documentation" + + user_options = [ + ('install-dir=', 'd', + "base directory for installing doc files " + "(default: installation base dir)"), + ('root=', None, + "install everything relative to this alternate root directory"), + ('man', None, 'install man page [default]'), + ('no-man', None, "don't install man page"), + ('man-dir=', None, 'man page installation directory'), + ('guide', None, 'install user guide [default]'), + ('no-guide', None, "don't install user guide"), + ('guide-dir=', None, 'guide installation directory'), + ] + + boolean_options = ['man', 'guide'] + negative_opt = {'no-man': 'man', 'no-guide': 'guide'} + + def initialize_options(self): + self.install_dir = None + self.root = None + self.man = True + self.man_dir = None + self.guide = True + self.guide_dir = None + self.outfiles = [] + + def finalize_options(self): + self.set_undefined_options('install', + ('install_data', 'install_dir'), + ('root', 'root'), + ) + if not self.man_dir: + self.man_dir = os.path.join( + self.install_dir, 'share', 'man') + if not self.guide_dir: + self.guide_dir = os.path.join( + self.install_dir, 'share', 'doc', 'be') + + def run(self): + if self.man: + self._install_man() + if self.guide: + self._install_guide() + + def _install_man(self): + if docutils == None: + log.error('cannot build man page without docutils') + return + man_dir = os.path.join(_this_dir, 'doc', 'man') + for filename in os.listdir(man_dir): + basename,extension = os.path.splitext(filename) + if extension == '.txt': + man_path = os.path.join(man_dir, basename) + if not os.path.exists(man_path): + log.warn('expected man page %s not found' % man_path) + continue + page,dot_section = os.path.splitext(basename) + section = dot_section.lstrip('.') + section_dir = os.path.join(self.man_dir, 'man%s' % section) + outfile = os.path.join(section_dir, basename) + self.mkpath(section_dir) + self.copy_file(infile=man_path, outfile=outfile) + self.outfiles.append(outfile) + + def _install_guide(self): + return + if docutils == None: + log.error('cannot build user guide without docutils') + return + if sphinx == None: + log.error('cannot build user guide without sphinx') + return + log.info('building user guide') + doc_dir = os.path.join(_this_dir, 'doc') + doctree_dir = os.path.join(doc_dir, '.build', 'doctrees') + html_dir = os.path.join(doc_dir, '.build', 'html') + log.info('generating autodoc/automodule pages for API documentation') + if not self.dry_run: + cwd = os.getcwd() + try: + os.chdir(doc_dir) + status,stdout,stderr = invoke( + [sys.executable, 'generate-libbe-txt.py']) + finally: + os.chdir(cwd) + log.info('building user guide with sphinx') + if not self.dry_run: + ret = sphinx.main([ + 'sphinx-build', '-d', doctree_dir, + '-b', 'html', doc_dir, html_dir]) + if ret != 0: + log.error('errors building user guide') + + + # add an entry to data_files + data_files.append(('share/doc/be/html', [html_dir])) + log.info('data files: %s' % data_files) + + def get_outputs(self): + return self.outfiles + + +install.sub_commands.append(('install_doc', None)) -man_path = os.path.join('doc', 'man', 'be.1') -if os.path.exists(man_path): - data_files.append(('share/man/man1', [man_path])) setup( name='Bugs Everywhere', - version=rev_date, + version=version(), + maintainer='Chris Ball', + maintainer_email='be-devel@bugseverywhere.org', description='Bugtracker supporting distributed revision control', + long_description=open(os.path.join(_this_dir, 'README'), 'r').read(), url='http://bugseverywhere.org/', + license='GNU GPLv2', packages=['libbe', 'libbe.command', 'libbe.storage', @@ -28,5 +255,7 @@ setup( 'libbe.ui.util', 'libbe.util'], scripts=['be'], - data_files=data_files, + data_files=[], + cmdclass={'build_py': _build_py, 'build_doc': build_doc, + 'install_doc': install_doc}, )