Skip to content

Commit

Permalink
Merge pull request #4 from RodrigoGonzalez/feat/add_serve_checks_7
Browse files Browse the repository at this point in the history
feat(main-check): added checks using mkdocs
  • Loading branch information
RodrigoGonzalez authored Aug 22, 2023
2 parents 1988611 + 767b1b4 commit 695093c
Show file tree
Hide file tree
Showing 6 changed files with 178 additions and 29 deletions.
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,41 @@
# check-mkdocs
Check if MkDocs is configured correctly

This is a simple .pre-commit-config.yaml hook to check if MkDocs
is configured correctly.

## Pre-Commit Usage

Add this to your `.pre-commit-config.yaml`, where `mkdocs.yml`
is the name of your MkDocs YAML configuration file:

```yaml
repos:
- repo: https://github.com/RodrigoGonzalez/check-mkdocs
rev: v1.0.0
hooks:
- id: check-mkdocs
name: check-mkdocs
args: [--config=mkdocs.yml] # Optional, mkdocs.yml is the default
```
## Usage
To run this hook, you can use the following command:
```shell
check-mkdocs --config=mkdocs.yml
```

This works as well:

```shell
check-mkdocs mkdocs.yml
```

And if mkdocs.yml is the name of your MkDocs YAML
configuration file, this works too:

```shell
check-mkdocs
```
1 change: 1 addition & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--8<-- "CHANGELOG.md"
19 changes: 19 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Welcome to Check MkDocs

This is a simple .pre-commit-config.yaml hook to check if MkDocs is configured correctly.

## Usage

Add this to your `.pre-commit-config.yaml`:

```yaml
repos:
- repo: https://github.com/RodrigoGonzalez/check-mkdocs
rev: v1.0.0
hooks:
- id: check-mkdocs
name: check-mkdocs
args: [--config-file=mkdocs.yml] # Optional, mkdocs.yml is the default
```
:::check_mkdocs
40 changes: 40 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
site_name: Check MkDocs

docs_dir: docs

theme:
name: "material"
palette:
- scheme: default
toggle:
icon: material/toggle-switch-off-outline
name: Switch to dark mode
- scheme: slate
toggle:
icon: material/toggle-switch
name: Switch to light mode
features:
# - navigation.tabs
- navigation.indexes
- navigation.instant

repo_name: RodrigoGonzalez/flake8-custom-import-rules
repo_url: https://github.com/RodrigoGonzalez/check-mkdocs

plugins:
- search:
- mkdocstrings:
default_handler: python
handlers:
python:
rendering:
show_signature_annotations: true
show_source: true
paths: [src/check_mkdocs/*/]

watch:
- src/check_mkdocs

nav:
- Introduction: "index.md"
- changelog.md
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[tool.poetry]
name = "check_mkdocs"
version = "0.1.0"
description = ""
description = "Simple check/command-line tool that parses, validates and loads configuration, builds the mkdocs project documentation, and serves it via a web server"
readme = "README.md"
authors = ["Rodrigo Gonzalez <[email protected]>"]
repository = "https://github.com/RodrigoGonzalez/check-mkdocs"
Expand Down
106 changes: 78 additions & 28 deletions src/check_mkdocs/check_mkdocs.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@
import os
import platform
import sys
import tempfile
import traceback

import yaml
from mkdocs.commands.build import build
from mkdocs.commands.serve import serve
from mkdocs.config import load_config
from mkdocs.exceptions import ConfigurationError


def main(argv: None = None) -> int:
Expand All @@ -31,71 +36,116 @@ def main(argv: None = None) -> int:
-----------
The main function creates an argument parser object using the
`argparse.ArgumentParser()` class. It adds a positional argument
`config_file` to the parser, which represents the path to the
configuration file.
The `nargs='?'` option specifies that the argument is optional and can be
omitted.
`config` to the parser, which represents the path to the
configuration file. The `nargs='?'` option specifies that the argument is
optional and can be omitted.
The `default='mkdocs.yml'` option specifies the default value of the
argument if it is not provided.
Additionally, it adds a keyword argument `--config` to the parser. This
argument also represents the path to the configuration file. If both the
positional and keyword arguments are provided, the keyword argument will
take precedence.
The function parses the command-line arguments using the
`parser.parse_args(argv)` method, which returns an object containing the
parsed arguments.
The function retrieves the value of the `config_file` argument from the
The function retrieves the value of the `config` argument from the
parsed arguments.
If the specified config file does not exist, the function raises a
`FileNotFoundError` with a descriptive error message.
The function initializes a variable `retval` with value 0.
The function then attempts to open the config file in read mode using the
`open(config_file, 'r')` function. If successful, it reads the contents of
the file and loads them as a YAML object using the `yaml.safe_load(f)`
function.
The function checks if the 'site_name' key is present in the loaded YAML.
If not, it prints an error message.
The function then loads the configuration using the
`load_config(config_file=config_file)` function. If there is an error in
the configuration file, it prints an error message.
The function attempts to open the config file in read mode using the
`open(filename, 'r')` function.
If successful, it reads the contents of the file and loads them as a YAML
object using the `yaml.safe_load(f)` function.
If an exception occurs during this process, the function prints an error
message indicating the file name and the error.
It also sets the value of `retval` to 1 to indicate an error.
The function then attempts to build the documentation using the
`build(config)` function. If there is an error during the build process,
it returns a user-friendly error message.
Finally, the function returns the value of `retval`.
The function then attempts to start the server using the
`serve(config_file=config_file)` function. If there is an error during the
server start process, it returns a user-friendly error message.
Finally, the function returns 0 if all the above processes are successful.
"""
parser = argparse.ArgumentParser()
parser.add_argument("config_file", nargs="?", default="mkdocs.yml")
parser.add_argument("config", nargs="?", default="mkdocs.yml")
parser.add_argument("--config", dest="config_opt")
args = parser.parse_args(argv)

filename = args.config_file
if not os.path.exists(filename):
config_file = args.config_opt if args.config_opt else args.config

config_file = args.config
if not os.path.exists(config_file):
raise FileNotFoundError(
f"Config file '{filename}' not found. Please specify a config file."
f"Config file '{config_file}' not found. Please specify a " f"config file."
)

retval = 0
# Load the YAML to check initial errors
try:
with open(filename, "r") as f:
with open(config_file, "r") as f:
config = yaml.safe_load(f)

# Check if 'site_name' key is present in the loaded YAML
if "site_name" not in config:
print(
f"{filename}: Missing site_name field. This is a required "
f"{config_file}: Missing site_name field. This is a required "
f"field. See: https://www.mkdocs.org/user-guide/configuration/"
)
retval = 1

except Exception as e:
retval = _generate_user_friendly_yaml_load_error(filename, e)
return retval
return _generate_user_friendly_error_message(config_file, "Error loading YAML", e)

# Load the configuration
try:
config = load_config(config_file=config_file)
except ConfigurationError as e:
print(f"Error in configuration file: {e}")
return _generate_user_friendly_error_message(config_file, "Error in configuration file", e)

# Build the documentation in a temporary directory
try:
with tempfile.TemporaryDirectory() as temp_dir:
config["site_dir"] = temp_dir
build(config)
# Start the server
try:
server = serve(config)
except Exception as e:
return _generate_user_friendly_error_message(
config_file, "Error starting the server", e
)
finally:
server.stop()
except Exception as e:
return _generate_user_friendly_error_message(
config_file, "Error building the documentation", e
)

return 0


def _generate_user_friendly_yaml_load_error(filename: str, e: Exception) -> int:
def _generate_user_friendly_error_message(
config_file: str, errror_message: str, e: Exception
) -> int:
"""
Generates a user-friendly error message for when there is an error loading
a YAML file.
Parameters
----------
filename : str
config_file : str
The name of the YAML file that failed to load.
e : Exception
The exception that was raised when trying to load the YAML file.
Expand All @@ -108,7 +158,7 @@ def _generate_user_friendly_yaml_load_error(filename: str, e: Exception) -> int:

impl = platform.python_implementation()
version = sys.version.split()[0]
print(f"{filename}: Error loading YAML with {impl} {version}: {e}")
print(f"{config_file}: {errror_message} with {impl} {version}: {e}")
tb = " " + traceback.format_exc().replace("\n", "\n ")
print(f"\n{tb}")
return 1
Expand Down

0 comments on commit 695093c

Please sign in to comment.