Patchwork [V2] setup: build docs from setup.py

login
register
mail settings
Submitter Kevin Bullock
Date Sept. 4, 2014, 6:17 p.m.
Message ID <f882f3877921866af3da.1409854636@billings.local>
Download mbox | patch
Permalink /patch/5698/
State Changes Requested
Headers show

Comments

Kevin Bullock - Sept. 4, 2014, 6:17 p.m.
# HG changeset patch
# User Kevin Bullock <kbullock@ringworld.org>
# Date 1404923562 18000
#      Wed Jul 09 11:32:42 2014 -0500
# Node ID f882f3877921866af3da9dcf4d8502379ef7b351
# Parent  c5df4af17110838b713d6c9ec3b824fb0b6c1b33
setup: build docs from setup.py

This patch enables the use of bdist_mpkg to build a Mercurial package
for Mac OS X that includes the documentation. I've been using a version
of this locally for several years to build my own packages before the
official Mac OS X versions appear, and these packages seem to be
indistinguishable from the official ones.

This version of the patch looks for docutils and only tries to build the
documentation if it's installed, so that `make install-bin` continues to
work in the absence of docutils.
Mads Kiilerich - Sept. 4, 2014, 11:56 p.m.
On 09/04/2014 08:17 PM, Kevin Bullock wrote:
> # HG changeset patch
> # User Kevin Bullock <kbullock@ringworld.org>
> # Date 1404923562 18000
> #      Wed Jul 09 11:32:42 2014 -0500
> # Node ID f882f3877921866af3da9dcf4d8502379ef7b351
> # Parent  c5df4af17110838b713d6c9ec3b824fb0b6c1b33
> setup: build docs from setup.py
>
> This patch enables the use of bdist_mpkg to build a Mercurial package
> for Mac OS X that includes the documentation. I've been using a version
> of this locally for several years to build my own packages before the
> official Mac OS X versions appear, and these packages seem to be
> indistinguishable from the official ones.

I agree with the goal here.

> diff --git a/setup.py b/setup.py
> --- a/setup.py
> +++ b/setup.py
> @@ -168,6 +168,13 @@ def runhg(cmd, env):
>           return ''
>       return out
>   
> +try:
> +    # Only include the docs if we can build them
> +    from docutils import __version__ as docutilsver
> +    builddocs = True
> +except ImportError:
> +    builddocs = False
> +
>   version = ''
>   
>   # Execute hg out of this directory with a custom environment which
> @@ -232,8 +239,10 @@ class hgbuild(build):
>       # thinking that those modules are global and, consequently, making
>       # a mess, now that all module imports are global.
>   
> -                    ('build_ext', build.has_ext_modules),
> -                   ] + build.sub_commands
> +                    ('build_ext', build.has_ext_modules)]
> +    if builddocs:
> +        sub_commands.append(('build_doc', None))
> +    sub_commands += build.sub_commands
>   
>   class hgbuildmo(build):
>   
> @@ -322,6 +331,19 @@ class hgbuildpy(build_py):
>               else:
>                   yield module
>   
> +class hgbuilddoc(Command):
> +    description = 'Build documentation in doc/ (manpages)'
> +    user_options = []
> +
> +    def initialize_options(self):
> +        pass
> +
> +    def finalize_options(self):
> +        pass
> +
> +    def run(self):
> +        self.spawn(['make', '-C', 'doc'])

Makefile and setup.py mutually invoking each other is not exactly elegant.

It could perhaps make sense to move more of the makefiles into setup.py. 
That would also make it simpler to use on Windows.

Also, I assume that right now this will build docs twice when doing a 
normal install/build with make?

> @@ -425,6 +447,7 @@ cmdclass = {'build': hgbuild,
>               'build_mo': hgbuildmo,
>               'build_ext': hgbuildext,
>               'build_py': hgbuildpy,
> +            'build_doc': hgbuilddoc,
>               'build_hgextindex': buildhgextindex,
>               'install_scripts': hginstallscripts,
>               'build_hgexe': buildhgexe,
> @@ -498,6 +521,10 @@ datafiles = []
>   setupversion = version
>   extra = {}
>   
> +if builddocs:
> +    datafiles += [('man/man1', ['doc/hg.1']),
> +                  ('man/man5', ['doc/hgignore.5', 'doc/hgrc.5'])]

Will this create different packages for man1 and man5 (as shown by 
pkgutil --pkgs, IIRC)? It would be nice if we could avoid this. That 
might require deeper hacking of distutils.

I assume this also will "make a difference" when building on Linux or on 
OS X without bdist_mpkg. I think it would be better if it didn't.

It could also be relevant to include .txt and .html when on Windows.

For bdist_mpkg stuff like this, I wonder if it would be more elegant to 
somehow derive from or integrate it somehow instead of trying to 
influence it by tweaking setup.py .

As it is now, I don't know if I think the value is bigger than the cost. 
The help is available from the commandline anyway.

/Mads
Pierre-Yves David - Sept. 5, 2014, 7:12 a.m.
On 09/04/2014 08:17 PM, Kevin Bullock wrote:
> # HG changeset patch
> # User Kevin Bullock <kbullock@ringworld.org>
> # Date 1404923562 18000
> #      Wed Jul 09 11:32:42 2014 -0500
> # Node ID f882f3877921866af3da9dcf4d8502379ef7b351
> # Parent  c5df4af17110838b713d6c9ec3b824fb0b6c1b33
> setup: build docs from setup.py
>
> This patch enables the use of bdist_mpkg to build a Mercurial package
> for Mac OS X that includes the documentation. I've been using a version
> of this locally for several years to build my own packages before the
> official Mac OS X versions appear, and these packages seem to be
> indistinguishable from the official ones.
>
> This version of the patch looks for docutils and only tries to build the
> documentation if it's installed, so that `make install-bin` continues to
> work in the absence of docutils.
>
> diff --git a/setup.py b/setup.py
> --- a/setup.py
> +++ b/setup.py
> @@ -168,6 +168,13 @@ def runhg(cmd, env):
>           return ''
>       return out
>
> +try:
> +    # Only include the docs if we can build them
> +    from docutils import __version__ as docutilsver
> +    builddocs = True
> +except ImportError:
> +    builddocs = False
> +
>   version = ''
>
>   # Execute hg out of this directory with a custom environment which
> @@ -232,8 +239,10 @@ class hgbuild(build):
>       # thinking that those modules are global and, consequently, making
>       # a mess, now that all module imports are global.
>
> -                    ('build_ext', build.has_ext_modules),
> -                   ] + build.sub_commands
> +                    ('build_ext', build.has_ext_modules)]
> +    if builddocs:
> +        sub_commands.append(('build_doc', None))

Should we issue a warning if the documentation is skipped?

(Error should never be passed silently)
Pierre-Yves David - Sept. 18, 2014, 12:17 a.m.
On 09/04/2014 11:17 AM, Kevin Bullock wrote:
> # HG changeset patch
> # User Kevin Bullock <kbullock@ringworld.org>
> # Date 1404923562 18000
> #      Wed Jul 09 11:32:42 2014 -0500
> # Node ID f882f3877921866af3da9dcf4d8502379ef7b351
> # Parent  c5df4af17110838b713d6c9ec3b824fb0b6c1b33
> setup: build docs from setup.py

Any news of a V3?

Patch

diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -168,6 +168,13 @@  def runhg(cmd, env):
         return ''
     return out
 
+try:
+    # Only include the docs if we can build them
+    from docutils import __version__ as docutilsver
+    builddocs = True
+except ImportError:
+    builddocs = False
+
 version = ''
 
 # Execute hg out of this directory with a custom environment which
@@ -232,8 +239,10 @@  class hgbuild(build):
     # thinking that those modules are global and, consequently, making
     # a mess, now that all module imports are global.
 
-                    ('build_ext', build.has_ext_modules),
-                   ] + build.sub_commands
+                    ('build_ext', build.has_ext_modules)]
+    if builddocs:
+        sub_commands.append(('build_doc', None))
+    sub_commands += build.sub_commands
 
 class hgbuildmo(build):
 
@@ -322,6 +331,19 @@  class hgbuildpy(build_py):
             else:
                 yield module
 
+class hgbuilddoc(Command):
+    description = 'Build documentation in doc/ (manpages)'
+    user_options = []
+
+    def initialize_options(self):
+        pass
+
+    def finalize_options(self):
+        pass
+
+    def run(self):
+        self.spawn(['make', '-C', 'doc'])
+
 class buildhgextindex(Command):
     description = 'generate prebuilt index of hgext (for frozen package)'
     user_options = []
@@ -425,6 +447,7 @@  cmdclass = {'build': hgbuild,
             'build_mo': hgbuildmo,
             'build_ext': hgbuildext,
             'build_py': hgbuildpy,
+            'build_doc': hgbuilddoc,
             'build_hgextindex': buildhgextindex,
             'install_scripts': hginstallscripts,
             'build_hgexe': buildhgexe,
@@ -498,6 +521,10 @@  datafiles = []
 setupversion = version
 extra = {}
 
+if builddocs:
+    datafiles += [('man/man1', ['doc/hg.1']),
+                  ('man/man5', ['doc/hgignore.5', 'doc/hgrc.5'])]
+
 if py2exeloaded:
     extra['console'] = [
         {'script':'hg',