comparison setup.py @ 41850:d80d48928eb1

setup: define build_doc command Currently, various processes for packaging Mercurial state to manually invoke `make -C doc` in order to generate the documentation. This Makefile merely invokes `gendoc.py` and `runrst` to produce man pages and HTML pages. Not all environments may have the ability to easily run Makefiles. Windows is notably in this set. This commit ports the man page and HTML generation logic from doc/Makefile to setup.py. We introduce a new build_doc command which generates documentation by calling gendoc.py and runrst. The documentation can now be built via pure Python by running `python setup.py build_doc`. We don't implement dependency tracking because IMO it is more effort than it is worth. We could potentially remove the duplicated functionality in doc/Makefile. But I'm not sure what all is depending on it. So I plan to keep it around. # no-check-commit because forced foo_bar function names Differential Revision: https://phab.mercurial-scm.org/D6063
author Gregory Szorc <gregory.szorc@gmail.com>
date Sun, 03 Mar 2019 10:31:23 -0800
parents aaad36b88298
children ed35057421ae
comparison
equal deleted inserted replaced
41849:d22198b4b3dd 41850:d80d48928eb1
238 # import py2exe's patched Distribution class 238 # import py2exe's patched Distribution class
239 from distutils.core import Distribution 239 from distutils.core import Distribution
240 except ImportError: 240 except ImportError:
241 py2exeloaded = False 241 py2exeloaded = False
242 242
243 def runcmd(cmd, env): 243 def runcmd(cmd, env, cwd=None):
244 p = subprocess.Popen(cmd, stdout=subprocess.PIPE, 244 p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
245 stderr=subprocess.PIPE, env=env) 245 stderr=subprocess.PIPE, env=env, cwd=cwd)
246 out, err = p.communicate() 246 out, err = p.communicate()
247 return p.returncode, out, err 247 return p.returncode, out, err
248 248
249 class hgcommand(object): 249 class hgcommand(object):
250 def __init__(self, cmd, env): 250 def __init__(self, cmd, env):
700 @property 700 @property
701 def hgexepath(self): 701 def hgexepath(self):
702 dir = os.path.dirname(self.get_ext_fullpath('dummy')) 702 dir = os.path.dirname(self.get_ext_fullpath('dummy'))
703 return os.path.join(self.build_temp, dir, 'hg.exe') 703 return os.path.join(self.build_temp, dir, 'hg.exe')
704 704
705 class hgbuilddoc(Command):
706 description = 'build documentation'
707 user_options = [
708 ('man', None, 'generate man pages'),
709 ('html', None, 'generate html pages'),
710 ]
711
712 def initialize_options(self):
713 self.man = None
714 self.html = None
715
716 def finalize_options(self):
717 # If --man or --html are set, only generate what we're told to.
718 # Otherwise generate everything.
719 have_subset = self.man is not None or self.html is not None
720
721 if have_subset:
722 self.man = True if self.man else False
723 self.html = True if self.html else False
724 else:
725 self.man = True
726 self.html = True
727
728 def run(self):
729 def normalizecrlf(p):
730 with open(p, 'rb') as fh:
731 orig = fh.read()
732
733 if b'\r\n' not in orig:
734 return
735
736 log.info('normalizing %s to LF line endings' % p)
737 with open(p, 'wb') as fh:
738 fh.write(orig.replace(b'\r\n', b'\n'))
739
740 def gentxt(root):
741 txt = 'doc/%s.txt' % root
742 log.info('generating %s' % txt)
743 res, out, err = runcmd(
744 [sys.executable, 'gendoc.py', root],
745 os.environ,
746 cwd='doc')
747 if res:
748 raise SystemExit('error running gendoc.py: %s' %
749 '\n'.join([out, err]))
750
751 with open(txt, 'wb') as fh:
752 fh.write(out)
753
754 def gengendoc(root):
755 gendoc = 'doc/%s.gendoc.txt' % root
756
757 log.info('generating %s' % gendoc)
758 res, out, err = runcmd(
759 [sys.executable, 'gendoc.py', '%s.gendoc' % root],
760 os.environ,
761 cwd='doc')
762 if res:
763 raise SystemExit('error running gendoc: %s' %
764 '\n'.join([out, err]))
765
766 with open(gendoc, 'wb') as fh:
767 fh.write(out)
768
769 def genman(root):
770 log.info('generating doc/%s' % root)
771 res, out, err = runcmd(
772 [sys.executable, 'runrst', 'hgmanpage', '--halt', 'warning',
773 '--strip-elements-with-class', 'htmlonly',
774 '%s.txt' % root, root],
775 os.environ,
776 cwd='doc')
777 if res:
778 raise SystemExit('error running runrst: %s' %
779 '\n'.join([out, err]))
780
781 normalizecrlf('doc/%s' % root)
782
783 def genhtml(root):
784 log.info('generating doc/%s.html' % root)
785 res, out, err = runcmd(
786 [sys.executable, 'runrst', 'html', '--halt', 'warning',
787 '--link-stylesheet', '--stylesheet-path', 'style.css',
788 '%s.txt' % root, '%s.html' % root],
789 os.environ,
790 cwd='doc')
791 if res:
792 raise SystemExit('error running runrst: %s' %
793 '\n'.join([out, err]))
794
795 normalizecrlf('doc/%s.html' % root)
796
797 # This logic is duplicated in doc/Makefile.
798 sources = {f for f in os.listdir('mercurial/help')
799 if re.search('[0-9]\.txt$', f)}
800
801 # common.txt is a one-off.
802 gentxt('common')
803
804 for source in sorted(sources):
805 assert source[-4:] == '.txt'
806 root = source[:-4]
807
808 gentxt(root)
809 gengendoc(root)
810
811 if self.man:
812 genman(root)
813 if self.html:
814 genhtml(root)
815
705 class hginstall(install): 816 class hginstall(install):
706 817
707 user_options = install.user_options + [ 818 user_options = install.user_options + [
708 ('old-and-unmanageable', None, 819 ('old-and-unmanageable', None,
709 'noop, present for eggless setuptools compat'), 820 'noop, present for eggless setuptools compat'),
825 data = data.replace(b'@LIBDIR@', libdir.encode(libdir_escape)) 936 data = data.replace(b'@LIBDIR@', libdir.encode(libdir_escape))
826 with open(outfile, 'wb') as fp: 937 with open(outfile, 'wb') as fp:
827 fp.write(data) 938 fp.write(data)
828 939
829 cmdclass = {'build': hgbuild, 940 cmdclass = {'build': hgbuild,
941 'build_doc': hgbuilddoc,
830 'build_mo': hgbuildmo, 942 'build_mo': hgbuildmo,
831 'build_ext': hgbuildext, 943 'build_ext': hgbuildext,
832 'build_py': hgbuildpy, 944 'build_py': hgbuildpy,
833 'build_scripts': hgbuildscripts, 945 'build_scripts': hgbuildscripts,
834 'build_hgextindex': buildhgextindex, 946 'build_hgextindex': buildhgextindex,