Skip to content

Commit

Permalink
Add (optional) drawio_args option
Browse files Browse the repository at this point in the history
This allows easily passing the --no-sandbox option to the Draw.io
executable during export, thus making it much easier to run in
containerised environments.

Fixes #12
  • Loading branch information
LukeCarrier committed Apr 18, 2020
1 parent 1c9a481 commit 377a862
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 13 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 0.6.0: ease containerisation

* New `drawio_args` option allows passing additional args to the Draw.io CLI

## 0.5.0: support MkDocs 1.1

* Make dependency upgrades a little easier
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ plugins:
# We'll look for it on your system's PATH, then default installation
# paths. If we can't find it we'll warn you.
drawio_executable: null
# Additional Draw.io CLI args
drawio_args: []
# Output format (see draw.io --help | grep format)
format: svg
# Glob pattern for matching source files
Expand Down
11 changes: 8 additions & 3 deletions mkdocsdrawioexporter/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,13 +189,14 @@ def filter_cache_files(self, files, cache_dir):
"""
return [f for f in files if not f.abs_src_path.startswith(cache_dir)]

def ensure_file_cached(self, source, source_rel, page_index, drawio_executable, cache_dir, format):
def ensure_file_cached(self, source, source_rel, page_index, drawio_executable, drawio_args, cache_dir, format):
"""Ensure cached copy of output exists.
:param str source: Source path, absolute.
:param str source_rel: Source path, relative to docs directory.
:param int page_index: Page index, numbered from zero.
:param str drawio_executable: Path to the configured Draw.io executable.
:param list(str) drawio_args: Additional arguments to append to the Draw.io export command.
:param str cache_dir: Export cache directory.
:param str format: Desired export format.
:return str: Cached export filename.
Expand All @@ -209,7 +210,9 @@ def ensure_file_cached(self, source, source_rel, page_index, drawio_executable,
self.log.debug('Source file appears unchanged; using cached copy from "{}"'.format(cache_filename))
else:
self.log.debug('Exporting "{}" to "{}"'.format(source, cache_filename))
exit_status = self.export_file(source, page_index, cache_filename, drawio_executable, format)
exit_status = self.export_file(
source, page_index, cache_filename,
drawio_executable, drawio_args, format)
if exit_status != 0:
self.log.error('Export failed with exit status {}'.format(exit_status))
return
Expand Down Expand Up @@ -238,13 +241,14 @@ def use_cached_file(self, source, cache_filename):
return os.path.exists(cache_filename) \
and os.path.getmtime(cache_filename) >= os.path.getmtime(source)

def export_file(self, source, page_index, dest, drawio_executable, format):
def export_file(self, source, page_index, dest, drawio_executable, drawio_args, format):
"""Export an individual file.
:param str source: Source path, absolute.
:param int page_index: Page index, numbered from zero.
:param str dest: Destination path, within cache.
:param str drawio_executable: Path to the configured Draw.io executable.
:param list(str) drawio_args: Additional arguments to append to the Draw.io export command.
:param str format: Desired export format.
:return int: The Draw.io exit status.
"""
Expand All @@ -255,6 +259,7 @@ def export_file(self, source, page_index, dest, drawio_executable, format):
'--output', dest,
'--format', format,
]
cmd += drawio_args

try:
self.log.debug('Using export command {}'.format(cmd))
Expand Down
10 changes: 6 additions & 4 deletions mkdocsdrawioexporter/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class DrawIoExporterPlugin(mkdocs.plugins.BasePlugin):
config_scheme = (
('cache_dir', config_options.Type(str)),
('drawio_executable', config_options.Type(str)),
('drawio_args', config_options.Type(list, default=[])),
('format', config_options.Type(str, default='svg')),
('image_re', config_options.Type(str, default='(<img[^>]+src=")([^">]+)("\s*\/?>)')),
('sources', config_options.Type(str, default='*.drawio')),
Expand All @@ -46,8 +47,9 @@ def on_config(self, config):
os.makedirs(self.config['cache_dir'], exist_ok=True)
self.image_re = re.compile(self.config['image_re'])

log.debug('Using Draw.io executable "{}", cache directory "{}" and image regular expression "{}"'.format(
self.config['drawio_executable'], self.config['cache_dir'], self.config['image_re']))
log.debug('Using Draw.io executable "{}", arguments {}, cache directory "{}" and image regular expression "{}"'.format(
self.config['drawio_executable'], self.config['drawio_args'],
self.config['cache_dir'], self.config['image_re']))

def on_post_page(self, output_content, page, **kwargs):
output_content, content_sources = self.exporter.rewrite_image_embeds(
Expand Down Expand Up @@ -78,8 +80,8 @@ def on_post_build(self, config):
abs_dest_path = os.path.join(config['site_dir'], dest_rel_path)
cache_filename = self.exporter.ensure_file_cached(
abs_src_path, source.source_rel, source.page_index,
self.config['drawio_executable'], self.config['cache_dir'],
self.config['format'])
self.config['drawio_executable'], self.config['drawio_args'],
self.config['cache_dir'], self.config['format'])

try:
copy_file(cache_filename, abs_dest_path)
Expand Down
34 changes: 28 additions & 6 deletions mkdocsdrawioexporter/tests/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def test_ensure_file_cached(self):
self.exporter.export_file.return_value = 0

result = self.exporter.ensure_file_cached(
source, source_rel, 0, drawio_executable, cache_dir, 'svg')
source, source_rel, 0, drawio_executable, [], cache_dir, 'svg')
assert result == self.exporter.make_cache_filename.return_value

def test_ensure_file_cached_aborts_if_drawio_executable_unavailable(self):
Expand All @@ -125,7 +125,7 @@ def test_ensure_file_cached_aborts_if_drawio_executable_unavailable(self):
self.log.warn = MagicMock()

result = self.exporter.ensure_file_cached(
source, source_rel, 0, drawio_executable, cache_dir, 'svg')
source, source_rel, 0, drawio_executable, [], cache_dir, 'svg')

assert result == None
self.log.warn.assert_called_once()
Expand All @@ -146,7 +146,7 @@ def test_ensure_file_cached_skips_export_if_cache_fresh(self):
self.exporter.export_file.return_value = 0

result = self.exporter.ensure_file_cached(
source, source_rel, 0, drawio_executable, cache_dir, 'svg')
source, source_rel, 0, drawio_executable, [], cache_dir, 'svg')

assert result == self.exporter.make_cache_filename.return_value
self.exporter.use_cached_file.assert_called_once()
Expand All @@ -170,7 +170,7 @@ def test_ensure_file_cached_logs_error_if_export_fails(self):
self.log.error = MagicMock()

result = self.exporter.ensure_file_cached(
source, source_rel, 0, drawio_executable, cache_dir, 'svg')
source, source_rel, 0, drawio_executable, [], cache_dir, 'svg')

assert result == None
self.log.error.assert_called_once()
Expand Down Expand Up @@ -217,7 +217,7 @@ def test_export_file(self, call_mock):
call_mock.return_value = 0

result = self.exporter.export_file(
source, 0, dest, drawio_executable, 'svg')
source, 0, dest, drawio_executable, [], 'svg')

assert result == 0
call_mock.assert_called_once()
Expand All @@ -233,12 +233,34 @@ def test_export_file_logs_exc_on_raise(self, call_mock):
self.log.exception = MagicMock()

result = self.exporter.export_file(
source, 0, dest, drawio_executable, 'svg')
source, 0, dest, drawio_executable, [], 'svg')

assert result == None
self.log.exception.assert_called_once()
call_mock.assert_called_once()

@patch('subprocess.call')
def test_export_file_honours_drawio_args(self, call_mock):
source = sep + join('docs', 'diagram.drawio')
page_index = 0
dest = sep + join('docs', 'diagram.drawio-0.svg')
drawio_executable = sep + join('bin', 'drawio')
format = 'svg'

def test_drawio_args(drawio_args):
self.exporter.export_file(
source, page_index, dest, drawio_executable, drawio_args, format)
call_mock.assert_called_with([
drawio_executable,
'--export', source,
'--page-index', str(page_index),
'--output', dest,
'--format', format,
] + drawio_args)

test_drawio_args([])
test_drawio_args(['--no-sandbox'])


if __name__ == '__main__':
unittest.main()

0 comments on commit 377a862

Please sign in to comment.