aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/plugins/info/plugin.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/info/plugin.py')
-rw-r--r--src/plugins/info/plugin.py245
1 files changed, 0 insertions, 245 deletions
diff --git a/src/plugins/info/plugin.py b/src/plugins/info/plugin.py
deleted file mode 100644
index 7c6fdc17..00000000
--- a/src/plugins/info/plugin.py
+++ /dev/null
@@ -1,245 +0,0 @@
-# Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
-
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to
-# deal in the Software without restriction, including without limitation the
-# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-# sell copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-# IN THE SOFTWARE.
-
-import json
-import logging
-import os
-import platform
-import requests
-import sys
-
-from colorama import Fore, Style
-from importlib.metadata import distributions, version
-from io import BytesIO
-from markdown.extensions.toc import slugify
-from mkdocs.plugins import BasePlugin, event_priority
-from mkdocs.structure.files import get_files
-from mkdocs.utils import get_theme_dir
-from zipfile import ZipFile, ZIP_DEFLATED
-
-from .config import InfoConfig
-
-# -----------------------------------------------------------------------------
-# Classes
-# -----------------------------------------------------------------------------
-
-# Info plugin
-class InfoPlugin(BasePlugin[InfoConfig]):
-
- # Initialize plugin
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
-
- # Initialize incremental builds
- self.is_serve = False
-
- # Determine whether we're serving the site
- def on_startup(self, *, command, dirty):
- self.is_serve = command == "serve"
-
- # Create a self-contained example (run earliest) - determine all files that
- # are visible to MkDocs and are used to build the site, create an archive
- # that contains all of them, and print a summary of the archive contents.
- # The user must attach this archive to the bug report.
- @event_priority(100)
- def on_config(self, config):
- if not self.config.enabled:
- return
-
- # By default, the plugin is disabled when the documentation is served,
- # but not when it is built. This should nicely align with the expected
- # user experience when creating reproductions.
- if not self.config.enabled_on_serve and self.is_serve:
- return
-
- # Resolve latest version
- url = "https://github.com/squidfunk/mkdocs-material/releases/latest"
- res = requests.get(url, allow_redirects = False)
-
- # Check if we're running the latest version
- _, current = res.headers.get("location").rsplit("/", 1)
- present = version("mkdocs-material")
- if not present.startswith(current):
- log.error("Please upgrade to the latest version.")
- self._help_on_versions_and_exit(present, current)
-
- # Exit if archive creation is disabled
- if not self.config.archive:
- sys.exit(1)
-
- # Print message that we're creating a bug report
- log.info("Started archive creation for bug report")
-
- # Check that there are no overrides in place - we need to use a little
- # hack to detect whether the custom_dir setting was used without parsing
- # mkdocs.yml again - we check at which position the directory provided
- # by the theme resides, and if it's not the first one, abort.
- if config.theme.dirs.index(get_theme_dir(config.theme.name)):
- log.error("Please remove 'custom_dir' setting.")
- self._help_on_customizations_and_exit()
-
- # Check that there are no hooks in place - hooks can alter the behavior
- # of MkDocs in unpredictable ways, which is why they must be considered
- # being customizations. Thus, we can't offer support for debugging and
- # must abort here.
- if config.hooks:
- log.error("Please remove 'hooks' setting.")
- self._help_on_customizations_and_exit()
-
- # Create in-memory archive and prompt user to enter a short descriptive
- # name for the archive, which is also used as the directory name. Note
- # that the name is slugified for better readability and stripped of any
- # file extension that the user might have entered.
- archive = BytesIO()
- example = input("\nPlease name your bug report (2-4 words): ")
- example, _ = os.path.splitext(example)
- example = "-".join([present, slugify(example, "-")])
-
- # Create self-contained example from project
- files: list[str] = []
- with ZipFile(archive, "a", ZIP_DEFLATED, False) as f:
- for path in ["mkdocs.yml", "requirements.txt"]:
- if os.path.isfile(path):
- f.write(path, os.path.join(example, path))
-
- # Append all files visible to MkDocs
- for file in get_files(config):
- path = os.path.relpath(file.abs_src_path, os.path.curdir)
- f.write(path, os.path.join(example, path))
-
- # Add information on installed packages
- f.writestr(
- os.path.join(example, "requirements.lock.txt"),
- "\n".join(sorted([
- "==".join([package.name, package.version])
- for package in distributions()
- ]))
- )
-
- # Add information on platform
- f.writestr(
- os.path.join(example, "platform.json"),
- json.dumps(
- {
- "system": platform.platform(),
- "python": platform.python_version()
- },
- default = str,
- indent = 2
- )
- )
-
- # Retrieve list of processed files
- for a in f.filelist:
- files.append("".join([
- Fore.LIGHTBLACK_EX, a.filename, " ",
- _size(a.compress_size)
- ]))
-
- # Finally, write archive to disk
- buffer = archive.getbuffer()
- with open(f"{example}.zip", "wb") as f:
- f.write(archive.getvalue())
-
- # Print summary
- log.info("Archive successfully created:")
- print(Style.NORMAL)
-
- # Print archive file names
- files.sort()
- for file in files:
- print(f" {file}")
-
- # Print archive name
- print(Style.RESET_ALL)
- print("".join([
- " ", f.name, " ",
- _size(buffer.nbytes, 10)
- ]))
-
- # Print warning when file size is excessively large
- print(Style.RESET_ALL)
- if buffer.nbytes > 1000000:
- log.warning("Archive exceeds recommended maximum size of 1 MB")
-
- # Aaaaaand done
- sys.exit(1)
-
- # -------------------------------------------------------------------------
-
- # Print help on versions and exit
- def _help_on_versions_and_exit(self, have, need):
- print(Fore.RED)
- print(" When reporting issues, please first upgrade to the latest")
- print(" version of Material for MkDocs, as the problem might already")
- print(" be fixed in the latest version. This helps reduce duplicate")
- print(" efforts and saves us maintainers time.")
- print(Style.NORMAL)
- print(f" Please update from {have} to {need}.")
- print(Style.RESET_ALL)
- print(f" pip install --upgrade --force-reinstall mkdocs-material")
- print(Style.NORMAL)
-
- # Exit, unless explicitly told not to
- if self.config.archive_stop_on_violation:
- sys.exit(1)
-
- # Print help on customizations and exit
- def _help_on_customizations_and_exit(self):
- print(Fore.RED)
- print(" When reporting issues, you must remove all customizations")
- print(" and check if the problem persists. If not, the problem is")
- print(" caused by your overrides. Please understand that we can't")
- print(" help you debug your customizations. Please remove:")
- print(Style.NORMAL)
- print(" - theme.custom_dir")
- print(" - hooks")
- print(Fore.YELLOW)
- print(" Additionally, please remove all third-party JavaScript or")
- print(" CSS not explicitly mentioned in our documentation:")
- print(Style.NORMAL)
- print(" - extra_css")
- print(" - extra_javascript")
- print(Style.RESET_ALL)
-
- # Exit, unless explicitly told not to
- if self.config.archive_stop_on_violation:
- sys.exit(1)
-
-# -----------------------------------------------------------------------------
-# Helper functions
-# -----------------------------------------------------------------------------
-
-# Print human-readable size
-def _size(value, factor = 1):
- color = Fore.GREEN
- if value > 100000 * factor: color = Fore.RED
- elif value > 25000 * factor: color = Fore.YELLOW
- for unit in ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB"]:
- if abs(value) < 1000.0:
- return f"{color}{value:3.1f} {unit}"
- value /= 1000.0
-
-# -----------------------------------------------------------------------------
-# Data
-# -----------------------------------------------------------------------------
-
-# Set up logging
-log = logging.getLogger("mkdocs.material.info")