From f4ae5b27339bdea96a2f07b4c9b60d60f51b0664 Mon Sep 17 00:00:00 2001 From: GeoJulien Date: Mon, 30 Dec 2024 16:37:26 +0100 Subject: [PATCH 1/7] improve(build): replace prebuild script for latest contents with pure MkDocs config hook. Goal: use only pure Mkdocs build and serve commands without any required script --- .github/workflows/deploy.yml | 1 - .github/workflows/links_checker.yml | 1 - .github/workflows/pr_checker_build.yml | 1 - .../mkdocs/G000_load_subconfigs.py | 105 +++++++----------- mkdocs-free.yml | 1 + mkdocs-minimal.yml | 1 + mkdocs.yml | 1 + 7 files changed, 43 insertions(+), 68 deletions(-) rename scripts/050_mkdocs_populate_latest.py => hooks/mkdocs/G000_load_subconfigs.py (51%) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 32767cc5aa..5f0d8ce2dc 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -65,7 +65,6 @@ jobs: - name: Build static website run: | geotribu --help > content/toc_nav_ignored/snippets/code/geotribu_cli_help.txt - python scripts/050_mkdocs_populate_latest.py -c mkdocs.yml python scripts/100_mkdocs_config_merger.py -c mkdocs.yml mkdocs build --clean --config-file mkdocs.yml --verbose --strict env: diff --git a/.github/workflows/links_checker.yml b/.github/workflows/links_checker.yml index eb37a1265a..6585c0901d 100644 --- a/.github/workflows/links_checker.yml +++ b/.github/workflows/links_checker.yml @@ -35,7 +35,6 @@ jobs: - name: Build static website run: | - python scripts/050_mkdocs_populate_latest.py python scripts/100_mkdocs_config_merger.py -c mkdocs.yml mkdocs build --clean --config-file mkdocs.yml --quiet --strict env: diff --git a/.github/workflows/pr_checker_build.yml b/.github/workflows/pr_checker_build.yml index 26528c6df8..84f64127c6 100644 --- a/.github/workflows/pr_checker_build.yml +++ b/.github/workflows/pr_checker_build.yml @@ -77,7 +77,6 @@ jobs: export MKDOCS_SITE_URL="https://${NETLIFY_SITE_PREFIX}--${NETLIFY_SITE_NAME}.netlify.app/" # merge different configs - python scripts/050_mkdocs_populate_latest.py -c ${{ env.MKDOCS_CONFIG_FILENAME }} python scripts/100_mkdocs_config_merger.py -c ${{ env.MKDOCS_CONFIG_FILENAME }} # build diff --git a/scripts/050_mkdocs_populate_latest.py b/hooks/mkdocs/G000_load_subconfigs.py similarity index 51% rename from scripts/050_mkdocs_populate_latest.py rename to hooks/mkdocs/G000_load_subconfigs.py index bf5003c26b..5968a1b3c1 100644 --- a/scripts/050_mkdocs_populate_latest.py +++ b/hooks/mkdocs/G000_load_subconfigs.py @@ -4,16 +4,15 @@ # ########## Libraries ############# # ################################## -# standard lib -import argparse +# standard library import logging from pathlib import Path from typing import Literal # 3rd party -import yaml +import mkdocs.plugins +from mkdocs.config.defaults import MkDocsConfig from mkdocs.structure.pages import Page -from mkdocs.utils import yaml_load from mkdocs.utils.meta import get_data # ########################################################################### @@ -23,41 +22,6 @@ logger = logging.getLogger("mkdocs") - -# -- CLI -- -parser = argparse.ArgumentParser( - prog="MkDocsConfigMerger", description="Merge configuration files.", add_help=True -) -parser.add_argument( - "-c", - "--config-file", - dest="output_config_file", - type=Path, - help="Path to the configuration file to complete. Must exist.", - default="mkdocs.yml", -) -parser.add_argument( - "-i", - "--input-folder", - dest="input_config_folder", - type=Path, - help="Path to the folder where to load configurations files to merge. Must exist.", - default="./config", -) - -args = parser.parse_args() - -output_config_file = args.output_config_file -input_config_folder = args.input_config_folder - -# -- CHECKS -- - -if not output_config_file.is_file(): - raise FileNotFoundError(output_config_file) -if not input_config_folder.is_dir(): - raise FileNotFoundError(input_config_folder) - - # ########################################################################### # ########## Functions ############# # ################################## @@ -96,29 +60,40 @@ def get_latest_content( return output_contents_list -# charge la configuration -with output_config_file.open(mode="r", encoding="UTF8") as in_yaml: - mkdocs_config = yaml_load(in_yaml) - -output_dict = {"latest": {"articles": [], "rdp": []}} - -# print(get_latest_content(content_type="articles")) - -for k in output_dict.get("latest"): - output_dict["latest"][k] = get_latest_content( - content_type=k, - social_card_image_base=f"{mkdocs_config.get('site_url')}assets/images/social/", - ) - -with input_config_folder.joinpath("extra_latest.yml").open( - "w", encoding="UTF-8" -) as out_file: - yaml.safe_dump( - output_dict, - out_file, - allow_unicode=True, - default_flow_style=False, - encoding="UTF8", - # indent=4, - sort_keys=True, - ) +@mkdocs.plugins.event_priority(10) +def on_config(config: MkDocsConfig) -> MkDocsConfig: + """The config event is the first event called on build and + is run immediately after the user configuration is loaded and validated. + Any alterations to the config should be made here. + + See: https://www.mkdocs.org/user-guide/plugins/#on_config + + Args: + config (config_options.Config): global configuration object + + Raises: + FileExistsError: if the template for the RSS feed is not found + PluginError: if the 'date_from_meta.default_time' format does not comply + + Returns: + MkDocsConfig: global configuration object + """ + # determine the website flavor + if config.get("config_file_path") == "mkdocs.yml": + config["extra"]["website_flavor"] = "insiders" + elif config.get("config_file_path") == "mkdocs-free.yml": + config["extra"]["website_flavor"] = "free" + else: + config["extra"]["website_flavor"] = "minimal" + + logger.info(f"Version du site : {config.get('extra').get('website_flavor')}") + + # latest contents + latest_contents: dict = {"articles": [], "rdp": []} + for k in latest_contents: + latest_contents[k] = get_latest_content( + content_type=k, + social_card_image_base=f"{config.get('site_url')}assets/images/social/", + ) + + config["extra"]["latest"] = latest_contents diff --git a/mkdocs-free.yml b/mkdocs-free.yml index 58762b13ce..73f06ef0fa 100644 --- a/mkdocs-free.yml +++ b/mkdocs-free.yml @@ -21,6 +21,7 @@ site_dir: !ENV [MKDOCS_OUTPUT_DIR, "./build/mkdocs/site"] # Scripts pendant le build hooks: + - hooks/mkdocs/G000_load_subconfigs.py - hooks/mkdocs/G003_social_cards_adapter.py - hooks/mkdocs/G005_jinja_filters.py - hooks/mkdocs/G006_authors_block.py diff --git a/mkdocs-minimal.yml b/mkdocs-minimal.yml index e42da98320..5942af4271 100644 --- a/mkdocs-minimal.yml +++ b/mkdocs-minimal.yml @@ -16,6 +16,7 @@ site_dir: !ENV [MKDOCS_OUTPUT_DIR, "./build/mkdocs/site"] # Scripts pendant le build hooks: + - hooks/mkdocs/G000_load_subconfigs.py - hooks/mkdocs/G005_jinja_filters.py - hooks/mkdocs/G006_authors_block.py diff --git a/mkdocs.yml b/mkdocs.yml index 774540bef2..30c70bfae2 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -21,6 +21,7 @@ site_dir: !ENV [MKDOCS_OUTPUT_DIR, "./build/mkdocs/site"] # Scripts pendant le build hooks: + - hooks/mkdocs/G000_load_subconfigs.py # - hooks/mkdocs/G002_check_images_size.py - hooks/mkdocs/G003_social_cards_adapter.py - hooks/mkdocs/G005_jinja_filters.py From 01e55b518799816957d2fb7520f078d0c1e6aa54 Mon Sep 17 00:00:00 2001 From: GeoJulien Date: Mon, 30 Dec 2024 16:54:55 +0100 Subject: [PATCH 2/7] improve(build): check the Material theme flavor and handle fallback --- hooks/mkdocs/G000_load_subconfigs.py | 47 +++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/hooks/mkdocs/G000_load_subconfigs.py b/hooks/mkdocs/G000_load_subconfigs.py index 5968a1b3c1..7c524a52d0 100644 --- a/hooks/mkdocs/G000_load_subconfigs.py +++ b/hooks/mkdocs/G000_load_subconfigs.py @@ -7,10 +7,11 @@ # standard library import logging from pathlib import Path -from typing import Literal +from typing import Literal, Optional # 3rd party import mkdocs.plugins +from material import __version__ as material_version from mkdocs.config.defaults import MkDocsConfig from mkdocs.structure.pages import Page from mkdocs.utils.meta import get_data @@ -60,6 +61,25 @@ def get_latest_content( return output_contents_list +def is_mkdocs_theme_material_insiders() -> Optional[bool]: + """Check if the material theme is community or insiders edition. + + Returns: + bool: True if the theme is Insiders edition. False if community. + """ + if material_version is not None and "insiders" in material_version: + logger.debug("Material theme edition INSIDERS") + return True + else: + logger.debug("Material theme edition COMMUNITY") + return False + + +# ########################################################################### +# ########## Hooks ################# +# ################################## + + @mkdocs.plugins.event_priority(10) def on_config(config: MkDocsConfig) -> MkDocsConfig: """The config event is the first event called on build and @@ -71,10 +91,6 @@ def on_config(config: MkDocsConfig) -> MkDocsConfig: Args: config (config_options.Config): global configuration object - Raises: - FileExistsError: if the template for the RSS feed is not found - PluginError: if the 'date_from_meta.default_time' format does not comply - Returns: MkDocsConfig: global configuration object """ @@ -82,11 +98,28 @@ def on_config(config: MkDocsConfig) -> MkDocsConfig: if config.get("config_file_path") == "mkdocs.yml": config["extra"]["website_flavor"] = "insiders" elif config.get("config_file_path") == "mkdocs-free.yml": - config["extra"]["website_flavor"] = "free" + config["extra"]["website_flavor"] = "community" else: config["extra"]["website_flavor"] = "minimal" - logger.info(f"Version du site : {config.get('extra').get('website_flavor')}") + # check if insiders version is installed + if ( + config["extra"]["website_flavor"] == "insiders" + and not is_mkdocs_theme_material_insiders() + ): + logger.warning( + f"Le fichier {config.get('config_file_path')} contient des paramètres ou " + "plugins uniquement disponibles dans la version Insiders (payante) du thème " + "Material. Or c'est la version community (gratuite) qui est installée : " + f"{material_version}. C'est donc la version communautaire (gratuite) qui " + "sera utilisée pour générer le site web." + ) + config["extra"]["website_flavor"] = "community" + + logger.info( + f"Génération du site {config.get('site_name')} " + f"en version {config.get('extra').get('website_flavor').upper()}" + ) # latest contents latest_contents: dict = {"articles": [], "rdp": []} From 22540210703cfacfca7e385caac2a1a9cfc7c383 Mon Sep 17 00:00:00 2001 From: GeoJulien Date: Mon, 30 Dec 2024 19:05:31 +0100 Subject: [PATCH 3/7] fix(build): use config filename, not path --- hooks/mkdocs/G000_load_subconfigs.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hooks/mkdocs/G000_load_subconfigs.py b/hooks/mkdocs/G000_load_subconfigs.py index 7c524a52d0..17bf2886b2 100644 --- a/hooks/mkdocs/G000_load_subconfigs.py +++ b/hooks/mkdocs/G000_load_subconfigs.py @@ -95,9 +95,10 @@ def on_config(config: MkDocsConfig) -> MkDocsConfig: MkDocsConfig: global configuration object """ # determine the website flavor - if config.get("config_file_path") == "mkdocs.yml": + config_filename = Path(config.get("config_file_path")).name + if config_filename == "mkdocs.yml": config["extra"]["website_flavor"] = "insiders" - elif config.get("config_file_path") == "mkdocs-free.yml": + elif config_filename == "mkdocs-free.yml": config["extra"]["website_flavor"] = "community" else: config["extra"]["website_flavor"] = "minimal" From 201842d70c810aac4cd55934714cc92876d03dca Mon Sep 17 00:00:00 2001 From: GeoJulien Date: Mon, 30 Dec 2024 19:06:08 +0100 Subject: [PATCH 4/7] improve(build): add log prefix --- hooks/mkdocs/G000_load_subconfigs.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/hooks/mkdocs/G000_load_subconfigs.py b/hooks/mkdocs/G000_load_subconfigs.py index 17bf2886b2..f63e5c14f0 100644 --- a/hooks/mkdocs/G000_load_subconfigs.py +++ b/hooks/mkdocs/G000_load_subconfigs.py @@ -22,6 +22,7 @@ logger = logging.getLogger("mkdocs") +log_prefix = f"[{__name__}] " # ########################################################################### # ########## Functions ############# @@ -68,10 +69,10 @@ def is_mkdocs_theme_material_insiders() -> Optional[bool]: bool: True if the theme is Insiders edition. False if community. """ if material_version is not None and "insiders" in material_version: - logger.debug("Material theme edition INSIDERS") + logger.debug(log_prefix + "Material theme edition INSIDERS") return True else: - logger.debug("Material theme edition COMMUNITY") + logger.debug(log_prefix + "Material theme edition COMMUNITY") return False @@ -109,16 +110,19 @@ def on_config(config: MkDocsConfig) -> MkDocsConfig: and not is_mkdocs_theme_material_insiders() ): logger.warning( - f"Le fichier {config.get('config_file_path')} contient des paramètres ou " + log_prefix + + f"Le fichier {config.get('config_file_path')} contient des paramètres ou " "plugins uniquement disponibles dans la version Insiders (payante) du thème " - "Material. Or c'est la version community (gratuite) qui est installée : " - f"{material_version}. C'est donc la version communautaire (gratuite) qui " - "sera utilisée pour générer le site web." + "Material. Or c'est la version community (gratuite) qui est installée " + f"({material_version}). La génération va probablement échouer. Deux solutions :" + "A. Installer la version Insiders (requiert un jeton GitHub). " + "B. Utiliser la configuration basée sur la version communautaire (gratuite), " + "par exemple : 'mkdocs build -f mkdocs-free.yml'" ) config["extra"]["website_flavor"] = "community" logger.info( - f"Génération du site {config.get('site_name')} " + log_prefix + f"Génération du site {config.get('site_name')} " f"en version {config.get('extra').get('website_flavor').upper()}" ) From 012a0959a603880b4f8665de3af7728ff26977b7 Mon Sep 17 00:00:00 2001 From: GeoJulien Date: Mon, 30 Dec 2024 19:06:24 +0100 Subject: [PATCH 5/7] improve(build): rm useless config file --- config/extra_latest.yml | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 config/extra_latest.yml diff --git a/config/extra_latest.yml b/config/extra_latest.yml deleted file mode 100644 index 2cd6edfc0f..0000000000 --- a/config/extra_latest.yml +++ /dev/null @@ -1,5 +0,0 @@ -# DO NOT MANUALLY EDIT THIS FILE, IT'S FILLD BY SCRIPT: scripts/mkdocs_populate_latest.py - -latest: - articles: [] - rdp: [] From a514f0eb983a9fa9a1c1b950a24d42967bc53925 Mon Sep 17 00:00:00 2001 From: GeoJulien Date: Mon, 30 Dec 2024 19:06:47 +0100 Subject: [PATCH 6/7] update(tooling): ignore auto-generated configuration --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index bf36f4221c..6b1e3681a1 100644 --- a/.gitignore +++ b/.gitignore @@ -233,3 +233,4 @@ linkchecker_report.html # fichiers liés aux vidéos Gource gource.ini avatars/ +mkdocs-generated-configuration.yml From 67e56d75c8991de912ce9a833e6f0642c125bde4 Mon Sep 17 00:00:00 2001 From: GeoJulien Date: Tue, 31 Dec 2024 17:55:10 +0100 Subject: [PATCH 7/7] update(tooling): add log after latest contents loaded --- hooks/mkdocs/G000_load_subconfigs.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hooks/mkdocs/G000_load_subconfigs.py b/hooks/mkdocs/G000_load_subconfigs.py index f63e5c14f0..e5d748a3ea 100644 --- a/hooks/mkdocs/G000_load_subconfigs.py +++ b/hooks/mkdocs/G000_load_subconfigs.py @@ -135,3 +135,6 @@ def on_config(config: MkDocsConfig) -> MkDocsConfig: ) config["extra"]["latest"] = latest_contents + logger.info( + log_prefix + "Contenus récents ajoutés à la configuration globale du site." + )