commit python-sphinxcontrib-plantuml for openSUSE:Factory
Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-sphinxcontrib-plantuml for openSUSE:Factory checked in at 2021-06-29 22:43:34 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-sphinxcontrib-plantuml (Old) and /work/SRC/openSUSE:Factory/.python-sphinxcontrib-plantuml.new.2625 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "python-sphinxcontrib-plantuml" Tue Jun 29 22:43:34 2021 rev:4 rq:903060 version:0.21 Changes: -------- --- /work/SRC/openSUSE:Factory/python-sphinxcontrib-plantuml/python-sphinxcontrib-plantuml.changes 2020-04-23 18:38:41.365034923 +0200 +++ /work/SRC/openSUSE:Factory/.python-sphinxcontrib-plantuml.new.2625/python-sphinxcontrib-plantuml.changes 2021-06-29 22:44:16.890954554 +0200 @@ -1,0 +2,6 @@ +Tue Jun 29 08:58:05 UTC 2021 - Linnaea Lavia <obs@lavia.moe> + +- Version update to 0.21, drops python2 + * py3-for-tests.patch: refreshed + +------------------------------------------------------------------- Old: ---- sphinxcontrib-plantuml-0.18.tar.gz New: ---- sphinxcontrib-plantuml-0.21.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-sphinxcontrib-plantuml.spec ++++++ --- /var/tmp/diff_new_pack.ol2J3m/_old 2021-06-29 22:44:17.302955098 +0200 +++ /var/tmp/diff_new_pack.ol2J3m/_new 2021-06-29 22:44:17.302955098 +0200 @@ -16,9 +16,11 @@ # -%{?!python_module:%define python_module() python-%{**} python3-%{**}} +%define skip_python2 1 +%{?!python_module:%define python_module() python3-%{**}} + Name: python-sphinxcontrib-plantuml -Version: 0.18 +Version: 0.21 Release: 0 Summary: Sphinx API for Web Apps License: BSD-2-Clause @@ -26,9 +28,8 @@ URL: https://github.com/sphinx-contrib/plantuml/ Source: https://github.com/sphinx-contrib/plantuml/archive/%{version}.tar.gz#/sphinxcontrib-plantuml-%{version}.tar.gz Patch0: py3-for-tests.patch -BuildRequires: %{python_module Sphinx >= 1.1} +BuildRequires: %{python_module Sphinx >= 2} BuildRequires: %{python_module Sphinx-latex} -BuildRequires: %{python_module nose} BuildRequires: %{python_module pytest} BuildRequires: %{python_module setuptools} BuildRequires: fdupes @@ -37,7 +38,7 @@ BuildRequires: texlive-epstopdf BuildRequires: tox Requires: plantuml -Requires: python-Sphinx >= 1.1 +Requires: python-Sphinx >= 2 BuildArch: noarch %python_subpackages ++++++ py3-for-tests.patch ++++++ --- /var/tmp/diff_new_pack.ol2J3m/_old 2021-06-29 22:44:17.326955129 +0200 +++ /var/tmp/diff_new_pack.ol2J3m/_new 2021-06-29 22:44:17.326955129 +0200 @@ -2,13 +2,8 @@ =================================================================== --- plantuml-0.18.orig/tests/fakecmd.py +++ plantuml-0.18/tests/fakecmd.py -@@ -1,7 +1,7 @@ +@@ -1,3 +1,3 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import sys - # embed as PostScript comment --print '%', ' '.join(sys.argv) -+print('%', ' '.join(sys.argv)) - for line in sys.stdin: - sys.stdout.write('% ' + line) ++++++ sphinxcontrib-plantuml-0.18.tar.gz -> sphinxcontrib-plantuml-0.21.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/plantuml-0.18/Makefile new/plantuml-0.21/Makefile --- old/plantuml-0.18/Makefile 2020-01-01 02:34:22.000000000 +0100 +++ new/plantuml-0.21/Makefile 2021-05-11 12:04:36.000000000 +0200 @@ -1,9 +1,10 @@ -PYTHON = python +FAKEROOT = fakeroot +PYTHON = python3 TWINE = twine .PHONY: dist dist: - $(PYTHON) setup.py sdist + $(FAKEROOT) $(PYTHON) setup.py sdist .PHONY: upload upload: dist @@ -11,7 +12,7 @@ .PHONY: check check: - $(PYTHON) `which nosetests` + $(PYTHON) -m pytest .PHONY: clean clean: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/plantuml-0.18/README.rst new/plantuml-0.21/README.rst --- old/plantuml-0.18/README.rst 2020-01-01 02:34:22.000000000 +0100 +++ new/plantuml-0.21/README.rst 2021-05-11 12:04:36.000000000 +0200 @@ -1,36 +1,49 @@ PlantUML for Sphinx =================== +Installation +------------ + +.. code-block:: + + pip install sphinxcontrib-plantuml + Usage ----- -Once you enable this extension, -:: +Add ``sphinxcontrib.plantuml`` to your extensions list in your ``conf.py``: + + +.. code-block:: python - # Add any Sphinx extension module names here, as strings. They can be extensions - # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. - extensions = ['sphinxcontrib.plantuml'] + extensions = [ + 'sphinxcontrib.plantuml', + ] -you may need to specify plantuml command in your conf.py:: +You may also need to specify the plantuml command in your **conf.py**: - plantuml = 'java -jar /path/to/plantuml.jar' +.. code-block:: python -Instead, you can install a wrapper script in your PATH:: + plantuml = 'java -jar /path/to/plantuml.jar' - % cat <<EOT > /usr/local/bin/plantuml - #!/bin/sh -e - java -jar /path/to/plantuml.jar "$@" - EOT - % chmod +x /usr/local/bin/plantuml +Instead, you can install a wrapper script in your PATH: -Then, write PlantUML text under ``.. uml::`` directive:: +.. code-block:: console + + % cat <<EOT > /usr/local/bin/plantuml + #!/bin/sh -e + java -jar /path/to/plantuml.jar "$@" + EOT + % chmod +x /usr/local/bin/plantuml + +Then, write PlantUML text under the ``.. uml::`` directive:: .. uml:: Alice -> Bob: Hi! Alice <- Bob: How are you? -or specify path to external PlantUML file:: +or specify path to an external PlantUML file:: .. uml:: external.uml @@ -42,7 +55,7 @@ Foo <|-- Bar -You can specify a caption:: +You can also specify a caption:: .. uml:: :caption: Caption with **bold** and *italic* @@ -92,3 +105,16 @@ plantuml_syntax_error_image Should plantuml generate images with render errors. (default: False) + +plantuml_cache_path + Directory where image cache is stored. (default: '_plantuml') + +plantuml_batch_size + **(EXPERIMENTAL)** + Run plantuml command per the specified number of images. (default: 1) + + If enabled, plantuml documents will be first written to the cache directory, + and rendered in batches. This eliminates bootstrapping overhead of Java + runtime and allows plantuml to leverage multiple CPU cores. + + To enable batch rendering, set the size to 100-1000. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/plantuml-0.18/setup.py new/plantuml-0.21/setup.py --- old/plantuml-0.18/setup.py 2020-01-01 02:34:22.000000000 +0100 +++ new/plantuml-0.21/setup.py 2021-05-11 12:04:36.000000000 +0200 @@ -4,11 +4,11 @@ long_desc = open('README.rst').read() -requires = ['Sphinx>=1.1'] +requires = ['Sphinx>=1.6'] setup( name='sphinxcontrib-plantuml', - version='0.18', + version='0.21', url='https://github.com/sphinx-contrib/plantuml/', download_url='https://pypi.python.org/pypi/sphinxcontrib-plantuml', license='BSD', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/plantuml-0.18/sphinxcontrib/plantuml.py new/plantuml-0.21/sphinxcontrib/plantuml.py --- old/plantuml-0.18/sphinxcontrib/plantuml.py 2020-01-01 02:34:22.000000000 +0100 +++ new/plantuml-0.21/sphinxcontrib/plantuml.py 2021-05-11 12:04:36.000000000 +0200 @@ -15,17 +15,23 @@ import os import re import shlex +import shutil import subprocess from contextlib import contextmanager from docutils import nodes from docutils.parsers.rst import directives from docutils.parsers.rst import Directive + +from sphinx import util from sphinx.errors import SphinxError +from sphinx.util import ( + i18n, + logging, +) from sphinx.util.nodes import set_source_info from sphinx.util.osutil import ( ensuredir, - ENOENT, ) try: @@ -33,20 +39,21 @@ except ImportError: Image = None -try: - from sphinx.util.i18n import search_image_for_language -except ImportError: # Sphinx < 1.4 - def search_image_for_language(filename, env): - return filename -try: - from sphinx.util import logging - logger = logging.getLogger(__name__) - def _warn(self, msg): - logger.warning(msg) -except (AttributeError, ImportError): # Sphinx < 1.6 - def _warn(self, msg): - self.builder.warn(msg) +logger = logging.getLogger(__name__) + + +if os.name == 'nt': + def rename(src, dst): + try: + os.rename(src, dst) + except OSError as err: + if err.errno != errno.EEXIST: + raise + os.unlink(dst) + os.rename(src, dst) +else: + rename = os.rename class PlantUmlError(SphinxError): @@ -105,7 +112,7 @@ return [warning('uml directive cannot have both content and ' 'a filename argument', line=self.lineno)] if self.arguments: - fn = search_image_for_language(self.arguments[0], env) + fn = i18n.search_image_for_language(self.arguments[0], env) relfn, absfn = env.relfn2path(fn) env.note_dependency(relfn) try: @@ -152,13 +159,17 @@ fp.close() -def generate_name(self, node, fileformat): +def hash_plantuml_node(node): h = hashlib.sha1() # may include different file relative to doc h.update(node['incdir'].encode('utf-8')) h.update(b'\0') h.update(node['uml'].encode('utf-8')) - key = h.hexdigest() + return h.hexdigest() + + +def generate_name(self, node, fileformat): + key = hash_plantuml_node(node) fname = 'plantuml-%s.%s' % (key, fileformat) imgpath = getattr(self.builder, 'imgpath', None) if imgpath: @@ -203,30 +214,12 @@ refname, outfname = generate_name(self, node, fileformat) if os.path.exists(outfname): return refname, outfname # don't regenerate - absincdir = os.path.join(self.builder.srcdir, node['incdir']) + + cachefname = self.builder.plantuml_builder.render(node, fileformat) ensuredir(os.path.dirname(outfname)) - f = open(outfname, 'wb') - try: - try: - p = subprocess.Popen(generate_plantuml_args(self, node, - fileformat), - stdout=f, stdin=subprocess.PIPE, - stderr=subprocess.PIPE, - cwd=absincdir) - except OSError as err: - if err.errno != ENOENT: - raise - raise PlantUmlError('plantuml command %r cannot be run' - % self.builder.config.plantuml) - serr = p.communicate(node['uml'].encode('utf-8'))[1] - if p.returncode != 0: - if self.builder.config.plantuml_syntax_error_image: - _warn(self, 'error while running plantuml\n\n%s' % serr) - else: - raise PlantUmlError('error while running plantuml\n\n%s' % serr) - return refname, outfname - finally: - f.close() + # TODO: optionally do symlink/link + shutil.copyfile(cachefname, outfname) + return refname, outfname def render_plantuml_inline(self, node, fileformat): @@ -238,7 +231,7 @@ stderr=subprocess.PIPE, cwd=absincdir) except OSError as err: - if err.errno != ENOENT: + if err.errno != errno.ENOENT: raise raise PlantUmlError('plantuml command %r cannot be run' % self.builder.config.plantuml) @@ -248,6 +241,135 @@ return sout.decode('utf-8') +class PlantumlBuilder(object): + def __init__(self, builder): + # for compatibility with existing functions which expect self.builder + # TODO: remove self.builder + self.builder = builder + + self.batch_size = builder.config.plantuml_batch_size + self.cache_dir = os.path.join(builder.outdir, + builder.config.plantuml_cache_path) + + self._base_cmdargs = _split_cmdargs(builder.config.plantuml) + self._base_cmdargs.extend(['-charset', 'utf-8']) + + self.image_formats = [] + if builder.format == 'html': + fmt = builder.config.plantuml_output_format + if fmt != 'none': + fileformats, _gettag = _lookup_html_format(fmt) + self.image_formats = list(fileformats) + elif builder.format == 'latex': + fmt = builder.config.plantuml_latex_output_format + if fmt != 'none': + fileformat, _postproc = _lookup_latex_format(fmt) + self.image_formats = [fileformat] + + self._known_keys = set() + self._pending_keys = [] + + def collect_nodes(self, doctree): + for node in doctree.traverse(plantuml): + key = hash_plantuml_node(node) + if key in self._known_keys: + continue + self._known_keys.add(key) + + doc = node['uml'].encode('utf-8') + if b'!include' in doc or b'%filename' in doc: + # Heuristic to work around the path/filename issue. There's no + # easy way to specify the cwd of the doc without using -pipe. + continue + + outdir = os.path.join(self.cache_dir, key[:2]) + outfbase = os.path.join(outdir, key) + if all(os.path.exists('%s.%s' % (outfbase, sfx)) + for sfx in ['puml'] + self.image_formats): + continue + + ensuredir(outdir) + with open(outfbase + '.puml', 'wb') as f: + # @startuml/enduml is mandatory in non-pipe mode. For backward + # compatibility, we do wrap the document only if @startXYZ is + # not specified. + started = doc.lstrip().startswith(b'@start') + if not started: + f.write(b'@startuml\n') + f.write(doc) + if not started: + f.write(b'\n@enduml\n') + + self._pending_keys.append(key) + + def render_batches(self): + pending_keys = sorted(self._pending_keys) + for fileformat in self.image_formats: + for i in range(0, len(pending_keys), self.batch_size): + keys = pending_keys[i:i + self.batch_size] + with util.progress_message( + 'rendering plantuml diagrams [%d..%d/%d]' + % (i, i + len(keys), len(pending_keys))): + self._render_files(keys, fileformat) + + del self._pending_keys[:] + + def _render_files(self, keys, fileformat): + cmdargs = self._base_cmdargs[:] + cmdargs.extend(_ARGS_BY_FILEFORMAT[fileformat]) + cmdargs.extend(os.path.join(k[:2], '%s.puml' % k) for k in keys) + try: + p = subprocess.Popen(cmdargs, stderr=subprocess.PIPE, + cwd=self.cache_dir) + except OSError as err: + if err.errno != errno.ENOENT: + raise + raise PlantUmlError('plantuml command %r cannot be run' + % self.builder.config.plantuml) + serr = p.communicate()[1] + if p.returncode != 0: + if self.builder.config.plantuml_syntax_error_image: + logger.warning('error while running plantuml\n\n%s' % serr) + else: + raise PlantUmlError('error while running plantuml\n\n%s' % serr) + + def render(self, node, fileformat): + key = hash_plantuml_node(node) + outdir = os.path.join(self.cache_dir, key[:2]) + outfname = os.path.join(outdir, '%s.%s' % (key, fileformat)) + if os.path.exists(outfname): + return outfname + + ensuredir(outdir) + absincdir = os.path.join(self.builder.srcdir, node['incdir']) + with open(outfname + '.new', 'wb') as f: + try: + p = subprocess.Popen(generate_plantuml_args(self, node, + fileformat), + stdout=f, stdin=subprocess.PIPE, + stderr=subprocess.PIPE, + cwd=absincdir) + except OSError as err: + if err.errno != errno.ENOENT: + raise + raise PlantUmlError('plantuml command %r cannot be run' + % self.builder.config.plantuml) + serr = p.communicate(node['uml'].encode('utf-8'))[1] + if p.returncode != 0: + if self.builder.config.plantuml_syntax_error_image: + logger.warning('error while running plantuml\n\n%s' % serr) + else: + raise PlantUmlError('error while running plantuml\n\n%s' + % serr) + + rename(outfname + '.new', outfname) + return outfname + + +def _render_batches_on_vist(self): + self.builder.plantuml_builder.render_batches() + + def _get_png_tag(self, fnames, node): refname, outfname = fnames['png'] alt = node.get('alt', node['uml']) @@ -256,9 +378,9 @@ # process images prior to html_vist. scale_attrs = [k for k in ('scale', 'width', 'height') if k in node] if scale_attrs and Image is None: - _warn(self, ('plantuml: unsupported scaling attributes: %s ' - '(install PIL or Pillow)' - % ', '.join(scale_attrs))) + logger.warning(('plantuml: unsupported scaling attributes: %s ' + '(install PIL or Pillow)' + % ', '.join(scale_attrs))) if not scale_attrs or Image is None: return ('<img src="%s" alt="%s"/>\n' % (self.encode(refname), self.encode(alt))) @@ -289,7 +411,7 @@ styles.extend('%s: %s%s' % (a, w * scale / 100, 'px') for a, w in zip(['width', 'height'], im.size)) except (IOError, OSError) as err: - _warn(self, 'plantuml: failed to get image size: %s' % err) + logger.warning('plantuml: failed to get image size: %s' % err) return ('<a href="%s"><img src="%s" alt="%s" style="%s"/>' '</a>\n' @@ -352,27 +474,29 @@ } +def _lookup_html_format(fmt): + try: + return _KNOWN_HTML_FORMATS[fmt] + except KeyError: + raise PlantUmlError( + 'plantuml_output_format must be one of %s, but is %r' + % (', '.join(map(repr, _KNOWN_HTML_FORMATS)), fmt)) + + @contextmanager def _prepare_html_render(self, fmt): if fmt == 'none': raise nodes.SkipNode try: - try: - fileformats, gettag = _KNOWN_HTML_FORMATS[fmt] - except KeyError: - raise PlantUmlError( - 'plantuml_output_format must be one of %s, but is %r' - % (', '.join(map(repr, _KNOWN_HTML_FORMATS)), fmt)) - - yield fileformats, gettag - + yield _lookup_html_format(fmt) except PlantUmlError as err: - _warn(self, str(err)) + logger.warning(str(err)) raise nodes.SkipNode def html_visit_plantuml(self, node): + _render_batches_on_vist(self) if 'html_format' in node: fmt = node['html_format'] else: @@ -403,13 +527,13 @@ p = subprocess.Popen(['bash'] + args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) except OSError as err: - if err.errno != ENOENT: + if err.errno != errno.ENOENT: raise raise PlantUmlError('epstopdf command %r cannot be run' % self.builder.config.plantuml_epstopdf) serr = p.communicate()[1] if p.returncode != 0: - raise PlantUmlError('error while running epstopdf\n\n' + serr) + raise PlantUmlError('error while running epstopdf\n\n%s' % serr) return refname[:-4] + '.pdf', fname[:-4] + '.pdf' @@ -420,7 +544,17 @@ } +def _lookup_latex_format(fmt): + try: + return _KNOWN_LATEX_FORMATS[fmt] + except KeyError: + raise PlantUmlError( + 'plantuml_latex_output_format must be one of %s, but is %r' + % (', '.join(map(repr, _KNOWN_LATEX_FORMATS)), fmt)) + + def latex_visit_plantuml(self, node): + _render_batches_on_vist(self) if 'latex_format' in node: fmt = node['latex_format'] else: @@ -428,16 +562,11 @@ if fmt == 'none': raise nodes.SkipNode try: - try: - fileformat, postproc = _KNOWN_LATEX_FORMATS[fmt] - except KeyError: - raise PlantUmlError( - 'plantuml_latex_output_format must be one of %s, but is %r' - % (', '.join(map(repr, _KNOWN_LATEX_FORMATS)), fmt)) + fileformat, postproc = _lookup_latex_format(fmt) refname, outfname = render_plantuml(self, node, fileformat) refname, outfname = postproc(self, refname, outfname) except PlantUmlError as err: - _warn(self, str(err)) + logger.warning(str(err)) raise nodes.SkipNode # put node representing rendered image @@ -453,34 +582,27 @@ def confluence_visit_plantuml(self, node): + _render_batches_on_vist(self) fmt = self.builder.config.plantuml_output_format with _prepare_html_render(self, fmt) as (fileformats, _): _, outfname = render_plantuml(self, node, fileformats[0]) - # Create a new image node in the document - img_node = nodes.image(uri=outfname, **node.attributes) - img_node.delattr('uml') - img_node.document = node.document - img_node.parent = node.parent - node.parent.children.insert(node.parent.children.index(node), img_node) - if not img_node.hasattr('alt'): - img_node['alt'] = node['uml'] + # put node representing rendered image + img_node = nodes.image(uri=outfname, alt=node.get('alt', node['uml'])) + node.replace_self(img_node) + self.visit_image(img_node) - # Confluence builder needs to be aware of the new asset - from sphinxcontrib.confluencebuilder import ConfluenceLogger - ConfluenceLogger.info('re-scanning for assets... ', nonl=0) - self.assets.process(list(self.assets.env.all_docs.keys())) - ConfluenceLogger.info('done\n') - # Handle the new node as a regular image - return self.visit_image(img_node) +def confluence_depart_plantuml(self, node): + pass def text_visit_plantuml(self, node): + _render_batches_on_vist(self) try: text = render_plantuml_inline(self, node, 'txt') except PlantUmlError as err: - _warn(self, str(err)) + logger.warning(str(err)) text = node['uml'] # fall back to uml text, which is still readable self.new_state() @@ -490,18 +612,19 @@ def pdf_visit_plantuml(self, node): + _render_batches_on_vist(self) try: refname, outfname = render_plantuml(self, node, 'eps') refname, outfname = _convert_eps_to_pdf(self, refname, outfname) except PlantUmlError as err: - _warn(self, str(err)) + logger.warning(str(err)) raise nodes.SkipNode rep = nodes.image(uri=outfname, alt=node.get('alt', node['uml'])) node.parent.replace(node, rep) def unsupported_visit_plantuml(self, node): - _warn(self, 'plantuml: unsupported output format (node skipped)') + logger.warning('plantuml: unsupported output format (node skipped)') raise nodes.SkipNode @@ -511,10 +634,30 @@ 'man': (unsupported_visit_plantuml, None), # TODO 'texinfo': (unsupported_visit_plantuml, None), # TODO 'text': (text_visit_plantuml, None), - 'confluence': (confluence_visit_plantuml, None), + 'confluence': (confluence_visit_plantuml, confluence_depart_plantuml), + 'singleconfluence': (confluence_visit_plantuml, confluence_depart_plantuml), } +def _on_builder_inited(app): + app.builder.plantuml_builder = PlantumlBuilder(app.builder) + + +def _on_doctree_read(app, doctree): + # Collect as many static nodes as possible prior to start building. + if app.builder.plantuml_builder.batch_size > 1: + app.builder.plantuml_builder.collect_nodes(doctree) + + +def _on_doctree_resolved(app, doctree, docname): + # Dynamically generated nodes will be collected here, which will be + # batched at node visitor. Since 'doctree-resolved' and node visits + # can be intermixed, there's no way to batch rendering of dynamic nodes + # at once. + if app.builder.plantuml_builder.batch_size > 1: + app.builder.plantuml_builder.collect_nodes(doctree) + + def setup(app): app.add_node(plantuml, **_NODE_VISITORS) app.add_directive('uml', UmlDirective) @@ -528,6 +671,11 @@ app.add_config_value('plantuml_epstopdf', 'epstopdf', '') app.add_config_value('plantuml_latex_output_format', 'png', '') app.add_config_value('plantuml_syntax_error_image', False, '') + app.add_config_value('plantuml_cache_path', '_plantuml', '') + app.add_config_value('plantuml_batch_size', 1, '') + app.connect('builder-inited', _on_builder_inited) + app.connect('doctree-read', _on_doctree_read) + app.connect('doctree-resolved', _on_doctree_resolved) # imitate what app.add_node() does if 'rst2pdf.pdfbuilder' in app.config.extensions: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/plantuml-0.18/tests/fakecmd.py new/plantuml-0.21/tests/fakecmd.py --- old/plantuml-0.18/tests/fakecmd.py 2020-01-01 02:34:22.000000000 +0100 +++ new/plantuml-0.21/tests/fakecmd.py 2021-05-11 12:04:36.000000000 +0200 @@ -1,7 +1,18 @@ #!/usr/bin/env python import sys -# embed as PostScript comment -print '%', ' '.join(sys.argv) -for line in sys.stdin: - sys.stdout.write('% ' + line) +def dump(fout, fin): + # embed as PostScript comment + fout.write('% ' + ' '.join(sys.argv) + '\n') + for line in fin: + fout.write('% ' + line) + +if '-pipe' in sys.argv: + dump(sys.stdout, sys.stdin) +else: + for fname in sys.argv[1:]: + if not fname.endswith('.puml'): + continue + with open(fname[:-5] + '.png', 'w') as fout: + with open(fname, 'r') as fin: + dump(fout, fin) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/plantuml-0.18/tests/fixture/hello.puml new/plantuml-0.21/tests/fixture/hello.puml --- old/plantuml-0.18/tests/fixture/hello.puml 1970-01-01 01:00:00.000000000 +0100 +++ new/plantuml-0.21/tests/fixture/hello.puml 2021-05-11 12:04:36.000000000 +0200 @@ -0,0 +1,3 @@ +@startuml +Hello +@enduml diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/plantuml-0.18/tests/test_functional.py new/plantuml-0.21/tests/test_functional.py --- old/plantuml-0.18/tests/test_functional.py 2020-01-01 02:34:22.000000000 +0100 +++ new/plantuml-0.21/tests/test_functional.py 2021-05-11 12:04:36.000000000 +0200 @@ -1,18 +1,15 @@ import glob -import nose import os import re import tempfile import shutil import sys +import unittest from sphinx.application import Sphinx -from nose.tools import * - _fixturedir = os.path.join(os.path.dirname(__file__), 'fixture') _fakecmd = os.path.join(os.path.dirname(__file__), 'fakecmd.py') -_fakeepstopdf = os.path.join(os.path.dirname(__file__), 'fakeepstopdf.py') def setup(): global _tempdir, _srcdir, _outdir @@ -42,7 +39,7 @@ app.build() def with_runsphinx(builder, **kwargs): - confoverrides = {'plantuml': _fakecmd} + confoverrides = {'plantuml': [sys.executable, _fakecmd]} confoverrides.update(kwargs) def wrapfunc(func): def test(): @@ -51,7 +48,7 @@ import rst2pdf rst2pdf.__file__ except ImportError: - raise nose.SkipTest + raise unittest.SkipTest src = '\n'.join(l[4:] for l in func.__doc__.splitlines()[2:]) os.mkdir(_outdir) try: @@ -82,10 +79,10 @@ pngcontent = readfile(pngfiles[0]).splitlines() assert b'-pipe' in pngcontent[0] - assert_equals(b'Hello', pngcontent[1][2:]) + assert pngcontent[1][2:] == b'Hello' svgcontent = readfile(svgfiles[0]).splitlines() assert b'-tsvg' in svgcontent[0] - assert_equals(b'Hello', svgcontent[1][2:]) + assert svgcontent[1][2:] == b'Hello' @with_runsphinx('html', plantuml_output_format='none') def test_buildhtml_no_output(): @@ -148,7 +145,7 @@ Hello """ - assert b'<div class="figure" id="label">' in readfile('index.html') + re.search(br'<div class="figure[^"]*" id="label">', readfile('index.html')) @with_runsphinx('html') def test_buildhtml_nonascii(): @@ -161,7 +158,47 @@ files = glob.glob(os.path.join(_outdir, '_images', 'plantuml-*.png')) content = readfile(files[0]).splitlines() assert b'-charset utf-8' in content[0] - assert_equals(u'\u3042', content[1][2:].decode('utf-8')) + assert content[1][2:].decode('utf-8') == u'\u3042' + +@with_runsphinx('html', plantuml_batch_size=2) +def test_buildhtml_in_batches(): + """Render in batches + + .. uml:: + + Hello + + .. uml:: + + Hello! + + .. uml:: + + @startuml + Hello!! + @enduml + + .. uml:: + + !include seq.ja.uml + """ + puml_files = glob.glob(os.path.join(_outdir, '_plantuml', '*', '*.puml')) + assert len(puml_files) == 3 + puml_contents = [readfile(f).splitlines() for f in puml_files] + assert all(len(lines) == 3 for lines in puml_contents) + assert all(lines[0] == b'@startuml' for lines in puml_contents) + assert all(lines[-1] == b'@enduml' for lines in puml_contents) + assert (sorted(lines[1] for lines in puml_contents) + == [b'Hello', b'Hello!', b'Hello!!']) + + # batches: [2, 1], excluded: 1 + png_files = glob.glob(os.path.join(_outdir, '_plantuml', '*', '*.png')) + assert len(png_files) == 4 + png_commands = [readfile(f).splitlines()[0] for f in png_files] + assert len(set(png_commands)) == 3 + assert sum(b'-pipe' in cmd for cmd in set(png_commands)) == 1 + assert sorted(sum(c.endswith(b'.puml') for c in cmd.split()) + for cmd in set(png_commands)) == [0, 1, 2] @with_runsphinx('latex') def test_buildlatex_simple(): @@ -178,7 +215,7 @@ content = readfile(files[0]).splitlines() assert b'-pipe' in content[0] - assert_equals(b'Hello', content[1][2:]) + assert content[1][2:] == b'Hello' @with_runsphinx('latex', plantuml_latex_output_format='eps') def test_buildlatex_simple_with_eps(): @@ -195,7 +232,7 @@ content = readfile(files[0]).splitlines() assert b'-teps' in content[0] - assert_equals(b'Hello', content[1][2:]) + assert content[1][2:] == b'Hello' @with_runsphinx('latex', plantuml_latex_output_format='pdf') def test_buildlatex_simple_with_pdf(): @@ -214,7 +251,7 @@ epscontent = readfile(epsfiles[0]).splitlines() assert b'-teps' in epscontent[0] - assert_equals(b'Hello', epscontent[1][2:]) + assert epscontent[1][2:] == b'Hello' @with_runsphinx('latex', plantuml_latex_output_format='none') def test_buildlatex_no_output(): @@ -269,4 +306,4 @@ epscontent = readfile(epsfiles[0]).splitlines() assert b'-teps' in epscontent[0] - assert_equals(b'Hello', epscontent[1][2:]) + assert epscontent[1][2:] == b'Hello' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/plantuml-0.18/tests/test_svgstyle.py new/plantuml-0.21/tests/test_svgstyle.py --- old/plantuml-0.18/tests/test_svgstyle.py 2020-01-01 02:34:22.000000000 +0100 +++ new/plantuml-0.21/tests/test_svgstyle.py 2021-05-11 12:04:36.000000000 +0200 @@ -2,8 +2,6 @@ import shutil import tempfile -from nose.tools import * - from sphinxcontrib import plantuml def setup(): @@ -28,4 +26,4 @@ '<svg xmlns="http://www.w3.org/2000/svg" height="147pt" ' 'style="width:115px;height:147px;" version="1.1" viewBox="0 0 115 147" ' 'width="115pt"><defs/>') - assert_equals('width:115px;height:147px;', plantuml._get_svg_style(fname)) + assert plantuml._get_svg_style(fname) == 'width:115px;height:147px;' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/plantuml-0.18/tox.ini new/plantuml-0.21/tox.ini --- old/plantuml-0.18/tox.ini 2020-01-01 02:34:22.000000000 +0100 +++ new/plantuml-0.21/tox.ini 2021-05-11 12:04:36.000000000 +0200 @@ -3,6 +3,6 @@ [testenv] deps = - nose + pytest rst2pdf -commands = nosetests +commands = pytest
participants (1)
-
Source-Sync