Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ build/
dist/
.vscode/.ropeproject/
.cache
venv/
7 changes: 7 additions & 0 deletions .mkdocsignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
venv
.devcontainer
.github
.vscode
**/__pycache__
.git
*.egg-info
12 changes: 12 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@
"cwd": "${workspaceFolder}",
"console": "integratedTerminal"
},
{
"name": "Test: Serve Mkdocs",
"type": "python",
"request": "launch",
"program": "/home/vscode/.local/bin/mkdocs",
"args": [
"serve",
"--verbose"
],
"cwd": "${workspaceFolder}",
"console": "integratedTerminal"
},
{
// Attach a debugger to an example by running this in the example folder
"name": "Test: Current example (mkdocs-test.yml)",
Expand Down
6 changes: 6 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@
],
"problemMatcher": []
},
{
"label": "mkdocs serve (dirtyreload)",
"type": "shell",
"command": "mkdocs serve --dirtyreload",
"problemMatcher": []
},
{
"label": "clean",
"type": "shell",
Expand Down
37 changes: 19 additions & 18 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,31 @@ ENV VIRTUAL_ENV=/opt/venv
RUN python3 -m venv $VIRTUAL_ENV
ENV PATH="$VIRTUAL_ENV/bin:$PATH"

RUN \
apk add --no-cache \
git \
git-fast-import \
git-lfs \
openssh \
cairo-dev \
freetype-dev \
libffi-dev \
jpeg-dev \
libpng-dev \
zlib-dev \
&& apk add --no-cache --virtual .build gcc musl-dev \
&& apk add --no-cache --upgrade bash \
&& pip install --upgrade pip \
&& pip install --no-cache-dir mkdocs-material mike pillow cairosvg

WORKDIR /tmp
COPY mkdocs_simple_plugin mkdocs_simple_plugin
COPY README.md README.md
COPY VERSION VERSION
COPY setup.py setup.py
COPY pyproject.toml pyproject.toml

RUN \
apk add --no-cache \
git \
git-fast-import \
git-lfs \
openssh \
cairo-dev \
freetype-dev \
libffi-dev \
jpeg-dev \
libpng-dev \
zlib-dev \
&& apk add --no-cache --virtual .build gcc musl-dev \
&& apk add --no-cache --upgrade bash \
&& pip install --upgrade pip \
&& pip install --no-cache-dir mkdocs-material mike pillow cairosvg \
&& pip install --no-cache-dir . \
RUN pip install --no-cache-dir . \
&& rm -rf /tmp/*

WORKDIR /docs
Expand All @@ -42,4 +43,4 @@ COPY docker/deploy.sh /usr/local/bin/
COPY docker/entrypoint.sh /usr/local/bin/
ENTRYPOINT ["entrypoint.sh"]

CMD ["mkdocs_simple_gen", "--serve", "--", "-a", "0.0.0.0:8000"]
CMD ["mkdocs_simple_gen", "--serve", "--", "-a", "0.0.0.0:8000", "--dirtyreload"]
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

[![Test](https://github.com/athackst/mkdocs-simple-plugin/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/athackst/mkdocs-simple-plugin/actions/workflows/test.yml)
[![Docs](https://github.com/athackst/mkdocs-simple-plugin/actions/workflows/publish_docs.yml/badge.svg?branch=main)](https://github.com/athackst/mkdocs-simple-plugin/actions/workflows/publish_docs.yml)
[![Docker](https://img.shields.io/docker/pulls/althack/mkdocs-simple-plugin)](https://hub.docker.com/r/althack/mkdocs-simple-plugin)
[![pypi](https://img.shields.io/pypi/dm/mkdocs-simple-plugin?label=pypi%20downloads&color=blue)](https://pypi.org/project/mkdocs-simple-plugin/)
[![Docker](https://img.shields.io/docker/pulls/althack/mkdocs-simple-plugin)](https://hub.docker.com/r/althack/mkdocs-simple-plugin)
[![pypi](https://img.shields.io/pypi/dm/mkdocs-simple-plugin?label=pypi%20downloads&color=blue)](https://pypi.org/project/mkdocs-simple-plugin/)
[![Github Action](https://img.shields.io/badge/github%20action-download-blue)](https://github.com/marketplace/actions/mkdocs-simple-action)

# mkdocs-simple-plugin
Expand All @@ -16,7 +16,7 @@ You may be wondering why you would want to generate a static site for your proje

* **My repository is too big for a single documentation source.**

Sometimes it isn't feasible to consolidate all documentation within an upper level `docs` directory. In general, if your codebase is too large to fit well within a single `include` directory, your codebase is also too large for documentation in a single `docs` directory.
Sometimes it isn't feasible to consolidate all documentation within an upper level `docs` directory. In general, if your codebase is too large to fit well within a single `include` directory, your codebase is also too large for documentation in a single `docs` directory.

Since it's typically easier to keep documentation up to date when it lives as close to the code as possible, it is better to create multiple sources for documentation.

Expand All @@ -30,12 +30,12 @@ You may be wondering why you would want to generate a static site for your proje

Finally, you may be interested in this plugin if you have a desire for easy-to-generate stylized documentation. This plugin lets you take documentation you may already have -- either in markdown files or in your code -- and formats them into a searchable documentation website. You can keep your documentation where it is (thank you very much).

See [mkdocs-simple-plugin](https://www.althack.dev/mkdocs-simple-plugin/latest/mkdocs_simple_plugin/plugin) for usage.
See [mkdocs-simple-plugin](https://althack.dev/mkdocs-simple-plugin/latest/mkdocs_simple_plugin/plugin) for usage.

## Contributing

See the [contributing guide](https://www.althack.dev/mkdocs-simple-plugin/latest/CONTRIBUTING)
See the [contributing guide](https://althack.dev/mkdocs-simple-plugin/latest/CONTRIBUTING)

## License

This software is licensed under [Apache 2.0](https://www.althack.dev/mkdocs-simple-plugin/latest/LICENSE)
This software is licensed under [Apache 2.0](https://althack.dev/mkdocs-simple-plugin/latest/LICENSE)
51 changes: 32 additions & 19 deletions mkdocs_simple_plugin/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
import os
import shutil
import tempfile
import time
import yaml


Expand Down Expand Up @@ -255,10 +256,22 @@ class SimplePlugin(BasePlugin):
def __init__(self):
"""Set up internal variables."""
self.orig_docs_dir = None
# Create a temporary build directory, and set some options to serve it
# PY2 returns a byte string by default. The Unicode prefix ensures a
# Unicode string is returned. And it makes MkDocs temp dirs easier to
# identify.
self.tmp_build_docs_dir = tempfile.mkdtemp(prefix="mkdocs_simple_")
self.paths = None
self.dirty = False
self.last_build_time = None

def on_startup(self, *, command, dirty: bool) -> None:
"""Configure the plugin on startup."""
self.dirty = dirty

def on_config(self, config, **kwargs):
"""Update configuration to use a temporary build directory."""
# Save the config for documentation
default_config = dict((name, config_option.default)
for name, config_option in self.config_scheme)
config['mkdocs_simple_config'] = yaml.dump(
Expand All @@ -268,35 +281,32 @@ def on_config(self, config, **kwargs):
allow_unicode=True,
encoding=None)

# Create a temporary build directory, and set some options to serve it
# PY2 returns a byte string by default. The Unicode prefix ensures a
# Unicode string is returned. And it makes MkDocs temp dirs easier to
# identify.
build_docs_dir = self.config['build_docs_dir']
if not build_docs_dir:
build_docs_dir = tempfile.mkdtemp(
prefix="mkdocs_simple_" +
os.path.basename(
os.path.dirname(
config.config_file_path)))
# Read previous config first so updates don't get overwritten
config_site_dir = get_config_site_dir(config.config_file_path)

# Set the build docs dir to tmp location if not set by user
if not self.config['build_docs_dir']:
self.config['build_docs_dir'] = self.tmp_build_docs_dir

utils.log.info(
"mkdocs-simple-plugin: build_docs_dir: %s",
build_docs_dir)
self.config['build_docs_dir'] = build_docs_dir
self.config['build_docs_dir'])

# Clean out build folder on config
shutil.rmtree(build_docs_dir, ignore_errors=True)
os.makedirs(build_docs_dir, exist_ok=True)
if not self.dirty:
shutil.rmtree(self.config['build_docs_dir'], ignore_errors=True)
os.makedirs(self.config['build_docs_dir'], exist_ok=True)
# Save original docs directory location
self.orig_docs_dir = config['docs_dir']
# Update the docs_dir with our temporary one
config['docs_dir'] = build_docs_dir
config['docs_dir'] = self.config['build_docs_dir']
# Add all markdown extensions to include list
self.config['include_extensions'] = list(utils.markdown_extensions) + \
self.config['include_extensions']

# Always ignore the output paths
self.config["ignore_paths"] = [
get_config_site_dir(config.config_file_path),
config_site_dir,
config['site_dir'],
self.config['build_docs_dir']]
return config
Expand All @@ -308,15 +318,18 @@ def on_pre_build(self, *, config):

# Merge docs
if self.config["merge_docs_dir"]:
simple.merge_docs(self.orig_docs_dir)
simple.merge_docs(self.orig_docs_dir, self.dirty)
# Copy all of the valid doc files into build_docs_dir
self.paths = simple.build_docs()
# Save paths to add to watch if serving
self.paths = simple.build_docs(self.dirty, self.last_build_time)
self.last_build_time = time.time()

def on_serve(self, server, *, config, builder):
"""Add files to watch server."""
# watch the original docs/ directory
if os.path.exists(self.orig_docs_dir):
server.watch(self.orig_docs_dir)
server.watch(self.config["build_docs_dir"])

# watch all the doc files
for path in self.paths:
Expand Down
15 changes: 10 additions & 5 deletions mkdocs_simple_plugin/semiliterate.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,12 +218,9 @@ def write(self, arg: str):
if not arg:
return
if self.file_object is None:
filename = os.path.join(self.file_directory, self.file_name)
os.makedirs(self.file_directory, exist_ok=True)
self.file_object = open(
os.path.join(
self.file_directory,
self.file_name),
'a+')
self.file_object = open(filename, 'w+')
self.file_object.write(arg)

def close(self):
Expand Down Expand Up @@ -255,6 +252,9 @@ def __init__(
self.terminate = terminate
self.patterns = patterns
self.wrote_something = False
self.streams = {
output_stream.file_name: output_stream
}

def transcribe(self, text: str):
"""Write some text and record if something was written."""
Expand Down Expand Up @@ -286,8 +286,13 @@ def set_output_file(self, filename: str):
"""Set output stream from filename."""
output_stream = self.output_stream
if filename:
# If we've opened this file before, re-use its stream.
if filename in self.streams:
return self.set_output_stream(self.streams[filename])
# Otherwise, make a new one and save it to the list.
output_stream = LazyFile(
self.output_stream.file_directory, filename)
self.streams[filename] = output_stream
self.set_output_stream(output_stream)

def set_output_stream(self, stream: LazyFile):
Expand Down
59 changes: 27 additions & 32 deletions mkdocs_simple_plugin/simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import fnmatch
import shutil
import stat
import sys
import pathlib

from mkdocs import utils
Expand All @@ -23,7 +22,7 @@ def __init__(
ignore_folders: list,
ignore_hidden: bool,
ignore_paths: list,
semiliterate: dict,
semiliterate: list,
**kwargs):
"""Initialize module instance with settings.

Expand All @@ -35,7 +34,7 @@ def __init__(
ignore_folders (list): Glob of paths to exclude
ignore_hidden (bool): Whether to ignore hidden files for processing
ignore_paths (list): Absolute filepaths to exclude
semiliterate (dict): Settings for processing file content in
semiliterate (list): Settings for processing file content in
Semiliterate

"""
Expand Down Expand Up @@ -141,43 +140,39 @@ def hidden_prefix(name):

return extract

def merge_docs(self, from_dir):
def merge_docs(self, from_dir, dirty=False):
"""Merge docs directory"""
if not os.path.exists(from_dir):
return
# Copy contents of docs directory if merging
def copy_directory(from_dir: str, to_dir: str):
"""Copy all files from source to destination directory."""
if sys.version_info >= (3, 8):
# pylint: disable=unexpected-keyword-arg
shutil.copytree(from_dir, to_dir, dirs_exist_ok=True)
utils.log.debug("mkdocs-simple-plugin: %s/* --> %s/*",
from_dir, to_dir)
else:
for source_directory, _, files in os.walk(from_dir):
destination_directory = source_directory.replace(
from_dir, to_dir, 1)
os.makedirs(destination_directory, exist_ok=True)
for file_ in files:
source_file = os.path.join(source_directory, file_)
destination_file = os.path.join(destination_directory,
file_)
if os.path.exists(destination_file):
os.remove(destination_file)
shutil.copy(source_file, destination_directory)
utils.log.debug(
"mkdocs-simple-plugin: %s/* --> %s/*",
source_file, destination_file)

if os.path.exists(from_dir):
copy_directory(from_dir, self.build_dir)
self.ignore_paths.add(from_dir)

def build_docs(self) -> list:
for source_directory, _, files in os.walk(from_dir):
destination_directory = source_directory.replace(
from_dir, self.build_dir, 1)
os.makedirs(destination_directory, exist_ok=True)
for file_ in files:
source_file = os.path.join(source_directory, file_)
destination_file = os.path.join(destination_directory, file_)
if os.path.exists(destination_file):
if dirty and os.stat(source_file).st_mtime <= os.stat(
destination_file).st_mtime:
continue
os.remove(destination_file)
shutil.copy(source_file, destination_directory)
utils.log.info(
"mkdocs-simple-plugin: %s/* --> %s/*",
source_file, destination_file)
self.ignore_paths.add(from_dir)

def build_docs(self, dirty=False, last_build_time=None) -> list:
"""Build the docs directory from workspace files."""
paths = []
files = self.get_files()
for file in files:
if not os.path.isfile(file):
continue
if dirty and last_build_time and (
os.path.getmtime(file) <= last_build_time):
continue
from_dir = os.path.dirname(file)
name = os.path.basename(file)
build_prefix = os.path.normpath(
Expand Down
2 changes: 1 addition & 1 deletion tests/test_semiliterate.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def test_write(self):
lazy_file.write('second_line')
lazy_file.close()

mock.assert_called_once_with(full_path, 'a+')
mock.assert_called_once_with(full_path, 'w+')
self.assertEqual(mock.return_value.write.call_count, 2)
mock.return_value.close.assert_called_once()

Expand Down
Loading