Skip to content

Commit

Permalink
Support MkDocs INHERIT and plugins as a dict; resolves #59
Browse files Browse the repository at this point in the history
  • Loading branch information
jimporter committed Jul 10, 2021
1 parent 494147a commit 4be3ced
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 17 deletions.
16 changes: 11 additions & 5 deletions mike/mkdocs_utils.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import mkdocs.config
import mkdocs.utils
import os
import re
import subprocess
import yaml
from collections.abc import Iterable
from collections.abc import Iterable, Mapping
from contextlib import contextmanager
from tempfile import NamedTemporaryFile

Expand Down Expand Up @@ -33,8 +34,8 @@ def load_config(config_file=None, **kwargs):

@contextmanager
def inject_plugin(config_file):
with open(config_file) as f:
config = yaml.load(f, Loader=yaml.Loader)
with _open_config(config_file) as f:
config = mkdocs.utils.yaml_load(f)

plugins = config.setdefault('plugins', ['search'])
for i in plugins:
Expand All @@ -43,11 +44,16 @@ def inject_plugin(config_file):
yield config_file
return

plugins.insert(0, 'mike')
if isinstance(plugins, Mapping):
config['plugins'] = {'mike': {}}
config['plugins'].update(plugins)
else:
plugins.insert(0, 'mike')

with NamedTemporaryFile(mode='w', dir=os.path.dirname(config_file),
prefix='mike-mkdocs', suffix='.yml',
delete=False) as f:
yaml.dump(config, f)
yaml.dump(config, f, sort_keys=False)

try:
yield f.name
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def distribution_files(self):
packages=find_packages(exclude=['test', 'test.*']),
include_package_data=True,

install_requires=(['mkdocs >= 1.0', 'jinja2', 'pyyaml', 'verspec']),
install_requires=(['mkdocs >= 1.0', 'jinja2', 'pyyaml >= 5.1', 'verspec']),
extras_require={
'dev': ['coverage', 'flake8 >= 3.0'],
'test': ['coverage', 'flake8 >= 3.0'],
Expand Down
76 changes: 65 additions & 11 deletions test/unit/test_mkdocs_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,23 @@
from mike import mkdocs_utils


class Stream(StringIO):
def __init__(self, name, data=''):
super().__init__(data)
self.name = name

def close(self):
pass


def mock_open_files(files):
def wrapper(filename, *args, **kwargs):
name = os.path.basename(filename)
return Stream(name, files[name])

return wrapper


# This mostly just tests `load_config` from MkDocs, but we want to be sure it
# behaves as we want it.
class TestLoadConfig(unittest.TestCase):
Expand Down Expand Up @@ -68,14 +85,8 @@ def test_nonexist(self):


class TestInjectPlugin(unittest.TestCase):
class Stream(StringIO):
name = 'mike-mkdocs.yml'

def close(self):
pass

def test_no_plugins(self):
out = self.Stream()
out = Stream('mike-mkdocs.yml')
cfg = '{}'
with mock.patch('builtins.open', mock.mock_open(read_data=cfg)), \
mock.patch('mike.mkdocs_utils.NamedTemporaryFile',
Expand All @@ -89,7 +100,7 @@ def test_no_plugins(self):
self.assertEqual(newcfg, {'plugins': ['mike', 'search']})

def test_other_plugins(self):
out = self.Stream()
out = Stream('mike-mkdocs.yml')
cfg = 'plugins:\n - foo\n - bar:\n option: true'
with mock.patch('builtins.open', mock.mock_open(read_data=cfg)), \
mock.patch('mike.mkdocs_utils.NamedTemporaryFile',
Expand All @@ -101,11 +112,31 @@ def test_other_plugins(self):
mremove.assert_called_once()

self.assertEqual(newcfg, {'plugins': [
'mike', 'foo', {'bar': {'option': True}}
'mike', 'foo', {'bar': {'option': True}},
]})

def test_other_plugins_dict(self):
out = Stream('mike-mkdocs.yml')
cfg = 'plugins:\n foo: {}\n bar:\n option: true'
with mock.patch('builtins.open', mock.mock_open(read_data=cfg)), \
mock.patch('mike.mkdocs_utils.NamedTemporaryFile',
return_value=out), \
mock.patch('os.remove') as mremove: # noqa
with mkdocs_utils.inject_plugin('mkdocs.yml') as f:
self.assertEqual(f, out.name)
newcfg = yaml.load(out.getvalue(), Loader=yaml.Loader)
mremove.assert_called_once()

self.assertEqual(newcfg, {'plugins': {
'mike': {}, 'foo': {}, 'bar': {'option': True},
}})
self.assertEqual(
list(newcfg['plugins'].items()),
[('mike', {}), ('foo', {}), ('bar', {'option': True})]
)

def test_mike_plugin(self):
out = self.Stream()
out = Stream('mike-mkdocs.yml')
cfg = 'plugins:\n - mike'
with mock.patch('builtins.open', mock.mock_open(read_data=cfg)), \
mock.patch('mike.mkdocs_utils.NamedTemporaryFile',
Expand All @@ -117,7 +148,7 @@ def test_mike_plugin(self):
mremove.assert_not_called()

def test_mike_plugin_options(self):
out = self.Stream()
out = Stream('mike-mkdocs.yml')
cfg = 'plugins:\n - mike:\n option: true'
with mock.patch('builtins.open', mock.mock_open(read_data=cfg)), \
mock.patch('mike.mkdocs_utils.NamedTemporaryFile',
Expand All @@ -128,6 +159,29 @@ def test_mike_plugin_options(self):
self.assertEqual(out.getvalue(), '')
mremove.assert_not_called()

def test_inherit(self):
out = Stream('mike-mkdocs.yml')
main_cfg = 'INHERIT: mkdocs-base.yml\nplugins:\n foo: {}\n'
base_cfg = 'plugins:\n bar: {}\n'
files = {'mkdocs.yml': main_cfg, 'mkdocs-base.yml': base_cfg}
with mock.patch('builtins.open', mock_open_files(files)), \
mock.patch('mike.mkdocs_utils.NamedTemporaryFile',
return_value=out), \
mock.patch('os.path.exists', return_value=True), \
mock.patch('os.remove') as mremove: # noqa
with mkdocs_utils.inject_plugin('mkdocs.yml') as f:
self.assertEqual(f, 'mike-mkdocs.yml')
newcfg = yaml.load(out.getvalue(), Loader=yaml.Loader)
mremove.assert_called_once()

self.assertEqual(newcfg, {'plugins': {
'mike': {}, 'bar': {}, 'foo': {},
}})
self.assertEqual(
list(newcfg['plugins'].items()),
[('mike', {}), ('bar', {}), ('foo', {})]
)


class TestBuild(unittest.TestCase):
def test_build(self):
Expand Down

0 comments on commit 4be3ced

Please sign in to comment.