diff --git a/sphinx/builders/applehelp.py b/sphinx/builders/applehelp.py index 0fa68935f..7dbc58d14 100644 --- a/sphinx/builders/applehelp.py +++ b/sphinx/builders/applehelp.py @@ -19,6 +19,7 @@ from os import path from sphinx.builders.html import StandaloneHTMLBuilder from sphinx.util.osutil import copyfile, ensuredir, os_path from sphinx.util.console import bold +from sphinx.util.pycompat import htmlescape from sphinx.errors import SphinxError import plistlib @@ -49,8 +50,11 @@ access_page_template = '''\ class AppleHelpIndexerFailed(SphinxError): - def __str__(self): - return 'Help indexer failed' + category = 'Help indexer failed' + + +class AppleHelpCodeSigningFailed(SphinxError): + category = 'Code signing failed' class AppleHelpBuilder(StandaloneHTMLBuilder): @@ -84,6 +88,11 @@ class AppleHelpBuilder(StandaloneHTMLBuilder): (self.config.language or 'en') + '.lproj') def handle_finish(self): + super(AppleHelpBuilder, self).handle_finish() + + self.finish_tasks.add_task(self.build_helpbook) + + def build_helpbook(self): contents_dir = path.join(self.bundle_path, 'Contents') resources_dir = path.join(contents_dir, 'Resources') language_dir = path.join(resources_dir, @@ -149,8 +158,8 @@ class AppleHelpBuilder(StandaloneHTMLBuilder): f = codecs.open(path.join(language_dir, '_access.html'), 'w') try: f.write(access_page_template % { - 'toc': toc, - 'title': self.config.applehelp_title + 'toc': htmlescape(toc, quote=True), + 'title': htmlescape(self.config.applehelp_title) }) finally: f.close() @@ -164,7 +173,7 @@ class AppleHelpBuilder(StandaloneHTMLBuilder): '-Cf', path.join(language_dir, 'search.helpindex'), language_dir - ] + ] if self.config.applehelp_index_anchors is not None: args.append('-a') @@ -177,11 +186,40 @@ class AppleHelpBuilder(StandaloneHTMLBuilder): if self.config.applehelp_locale is not None: args += ['-l', self.config.applehelp_locale] - - result = subprocess.call(args) - if result != 0: - raise AppleHelpIndexerFailed + p = subprocess.Popen(args, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + + output = p.communicate()[0] + + if p.returncode != 0: + raise AppleHelpIndexerFailed(output) else: self.info('done') + + # If we've been asked to, sign the bundle + if self.config.applehelp_codesign_identity is not None: + self.info(bold('signing help book... '), nonl=True) + + args = [ + '/usr/bin/codesign', + '-s', self.config.applehelp_codesign_identity, + '-f' + ] + + args += self.config.applehelp_codesign_flags + + args.append(self.bundle_path) + + p = subprocess.Popen(args, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + + output = p.communicate()[0] + + if p.returncode != 0: + raise AppleHelpCodeSigningFailed(output) + else: + self.info('done') diff --git a/sphinx/config.py b/sphinx/config.py index f7c0cefe8..955b356f0 100644 --- a/sphinx/config.py +++ b/sphinx/config.py @@ -10,7 +10,8 @@ """ import re -from os import path +from os import path, environ +import shlex from six import PY3, iteritems, string_types, binary_type, integer_types @@ -129,7 +130,7 @@ class Config(object): # Devhelp only options devhelp_basename = (lambda self: make_filename(self.project), None), - # Apple help only options + # Apple help options applehelp_bundle_name = (lambda self: make_filename(self.project), 'applehelp'), applehelp_bundle_id = (lambda self: 'com.mycompany.%s.help' \ @@ -147,6 +148,14 @@ class Config(object): applehelp_stopwords = (lambda self: self.language or 'en', 'applehelp'), applehelp_locale = (lambda self: self.language or 'en_us', 'applehelp'), applehelp_title = (lambda self: self.project + ' Help', 'applehelp'), + applehelp_codesign_identity = (lambda self: + environ.get('CODE_SIGN_IDENTITY', None), + 'applehelp'), + applehelp_codesign_flags = (lambda self: + shlex.split( + environ.get('OTHER_CODE_SIGN_FLAGS', + '')), + 'applehelp'), # Epub options epub_basename = (lambda self: make_filename(self.project), None), diff --git a/sphinx/quickstart.py b/sphinx/quickstart.py index 049cc477a..522f5f936 100644 --- a/sphinx/quickstart.py +++ b/sphinx/quickstart.py @@ -86,6 +86,7 @@ QUICKSTART_CONF += u'''\ import sys import os +import shlex # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the @@ -310,6 +311,15 @@ htmlhelp_basename = '%(project_fn)sdoc' # Locale for indexing #applehelp_locale = %(language)r +# If you call Sphinx from Xcode, the default settings for code signing +# will apply automatically. + +# The code signing identity to use (if None, the bundle is not signed) +#applehelp_codesign_identity = os.environ.get('CODE_SIGN_IDENTITY', None) + +# Code signing flags to pass (as a list) +#applehelp_codesign_flags = shlex.split(os.environ.get('OTHER_CODE_SIGN_FLAGS', '')) + # -- Options for LaTeX output --------------------------------------------- latex_elements = { @@ -601,6 +611,9 @@ applehelp: \t$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp \t@echo \t@echo "Build finished. The help book is in $(BUILDDIR)/applehelp." +\t@echo "N.B. You won't be able to view it unless you put it in" \\ +\t "~/Library/Documentation/Help or install it in your application" \\ +\t "bundle." devhelp: \t$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp