diff --git a/.github/workflows/dev.build.yml b/.github/workflows/dev.build.yml
index e773ccf089..6edc4beec0 100644
--- a/.github/workflows/dev.build.yml
+++ b/.github/workflows/dev.build.yml
@@ -7,6 +7,7 @@ on:
env:
GMC_ENABLE_ON_PUBLISH: true
+ GMC_DEV_URL: 'https://auronen.cokoliv.eu/gmc/'
jobs:
deploy:
@@ -24,22 +25,30 @@ jobs:
with:
python-version: 3.11
cache: pip
- - name: Cache `requirements.txt`
+ - name: Process Python Cache
id: cache-requirements
uses: actions/cache@v3
with:
- path: '**/venv/*'
- key: requirements-${{ hashFiles('**/requirements*.txt') }}
- - name: Install Dependencies into `venv`
+ path: venv
+ key: requirements-${{ hashFiles('requirements*.txt') }}
+ - name: Install Uncached Requirements
if: steps.cache-requirements.outputs.cache-hit != 'true'
run: |
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
+ pip install -r requirements-deploy.txt
- name: Run prebuild tests
run: |
source venv/bin/activate
python -m unittest discover tests/ -v
+ - name: Process MkDocs Plugins & Hooks Cache
+ uses: actions/cache@v3
+ with:
+ path: .cache
+ key: mkdocs-${{ github.sha }}
+ restore-keys: |
+ mkdocs-
- name: Build and deploy site
run: |
source venv/bin/activate
diff --git a/.github/workflows/master.build.yml b/.github/workflows/master.build.yml
index eb96c37fd4..7ab67db47c 100644
--- a/.github/workflows/master.build.yml
+++ b/.github/workflows/master.build.yml
@@ -24,22 +24,30 @@ jobs:
with:
python-version: 3.11
cache: pip
- - name: Cache `requirements.txt`
+ - name: Process Python Cache
id: cache-requirements
uses: actions/cache@v3
with:
- path: '**/venv/*'
- key: requirements-${{ hashFiles('**/requirements*.txt') }}
- - name: Install Dependencies into `venv`
+ path: venv
+ key: requirements-${{ hashFiles('requirements*.txt') }}
+ - name: Install Uncached Requirements
if: steps.cache-requirements.outputs.cache-hit != 'true'
run: |
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
+ pip install -r requirements-deploy.txt
- name: Run prebuild tests
run: |
source venv/bin/activate
python -m unittest discover tests/ -v
+ - name: Process MkDocs Plugins & Hooks Cache
+ uses: actions/cache@v3
+ with:
+ path: .cache
+ key: mkdocs-${{ github.sha }}
+ restore-keys: |
+ mkdocs-
- name: Build and deploy site
run: |
source venv/bin/activate
diff --git a/.github/workflows/pull.request.yml b/.github/workflows/pull.request.yml
index 7817fee2ff..33e67a00e4 100644
--- a/.github/workflows/pull.request.yml
+++ b/.github/workflows/pull.request.yml
@@ -24,18 +24,19 @@ jobs:
with:
python-version: 3.11
cache: pip
- - name: Cache `requirements.txt`
+ - name: Process Python Cache
id: cache-requirements
uses: actions/cache@v3
with:
- path: '**/venv/*'
- key: requirements-${{ hashFiles('**/requirements*.txt') }}
- - name: Install Dependencies into `venv`
+ path: venv
+ key: requirements-${{ hashFiles('requirements*.txt') }}
+ - name: Install Uncached Requirements
if: steps.cache-requirements.outputs.cache-hit != 'true'
run: |
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
+ pip install -r requirements-deploy.txt
- name: Run prebuild tests
run: |
source venv/bin/activate
diff --git a/mkdocs.yml b/mkdocs.yml
index dc889387b6..7cfaf9b3b8 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -1,5 +1,6 @@
site_name: Gothic Modding Community
-site_url: https://gothic-modding-community.github.io/gmc/
+site_url: !ENV [GMC_DEV_URL, 'https://gothic-modding-community.github.io/gmc/']
+site_description: 'Gothic Modding Community is a collection of helpful resources for modding Gothic and Risen games.'
repo_name: Gothic-Modding-Community/gmc
repo_url: https://github.com/Gothic-Modding-Community/gmc/
@@ -11,6 +12,7 @@ watch:
hooks:
- overrides/.hooks/language_flags.py
- overrides/.hooks/git_redirects.py
+ - overrides/.hooks/social_patch.py
theme:
name: material
@@ -58,10 +60,10 @@ extra:
social:
- icon: fontawesome/brands/discord
link: https://discord.gg/mCpS5b5SUY
- name: Gothic Modding Comunity Discord Server
+ name: Gothic Modding Community Discord Server
- icon: fontawesome/brands/github
link: https://github.com/Gothic-Modding-Community/gmc
- name: Gothic Modding Comunity Github repository
+ name: Gothic Modding Community GitHub repository
@@ -135,9 +137,11 @@ plugins:
pl:
name: pl - Polski
build: true
+ site_description: 'Gothic Modding Community to zbiór pomocnych materiałów do modowania gier Gothic i Risen.'
cs:
name: cs - Čeština
build: true
+ site_description: 'Dokumentace, návody a články zaměřené na modování her Gothic a Risen.'
material_alternate: true
# Only 1 global scope, if 2 nav elements are named the same, input translation only once.
# Translate only the section/directory titles, page titles should be in the meta header of the `.md` file.
@@ -184,4 +188,6 @@ plugins:
- zengin/index*.md
- redirects:
# Empty dict to fill with the `meta_redirects.py` hook.
- redirect_maps: {}
\ No newline at end of file
+ redirect_maps: {}
+ - social:
+ cards: !ENV [GMC_ENABLE_ON_PUBLISH, False]
\ No newline at end of file
diff --git a/overrides/.hooks/git_redirects.py b/overrides/.hooks/git_redirects.py
index 82d80a7e74..3a014b979b 100644
--- a/overrides/.hooks/git_redirects.py
+++ b/overrides/.hooks/git_redirects.py
@@ -7,7 +7,9 @@
MIT Licence 2023 Kamil Krzyśków
"""
import datetime
+import json
import logging
+import os
from pathlib import Path
from typing import Dict, Optional, Set
@@ -26,6 +28,10 @@
def on_config(config: MkDocsConfig) -> Optional[Config]:
"""Main function. Check the `redirects` plugin is present and fill the redirects mapping."""
+ if not os.getenv(HOOK_VAR, False):
+ LOG.info(f"{HOOK_NAME}: {HOOK_VAR} is not set to True in the environment")
+ return None
+
if not GIT_MODULE:
LOG.warning(f"{HOOK_NAME}: The `GitPython` module is not installed")
return None
@@ -38,25 +44,47 @@ def on_config(config: MkDocsConfig) -> Optional[Config]:
LOG.warning(f"{HOOK_NAME}: The `redirects` plugin is not configured correctly")
return None
- _add_redirects_based_on_git_history(config=config)
+ if os.getenv(CACHE_VAR, False):
+ CacheHelper.setup(config=config)
+ commit_hash = _add_redirects_based_on_git_history(config=config, cache_enabled=True)
+ if commit_hash is not None and commit_hash != CacheHelper.cache_obj["commit_hash"]:
+ CacheHelper.cache_obj["commit_hash"] = commit_hash
+ CacheHelper.save(config=config)
+ else:
+ _add_redirects_based_on_git_history(config=config)
return None
-def _add_redirects_based_on_git_history(*, config: MkDocsConfig) -> None:
+def _add_redirects_based_on_git_history(
+ *, config: MkDocsConfig, cache_enabled: bool = False
+) -> Optional[str]:
"""Process the Git history looking for rename actions."""
docs_dir: Path = Path(config.get("docs_dir"))
- file_paths: Set[str] = {str(path) for path in docs_dir.glob("**/*.md")}
docs_prefix: str = docs_dir.name + "/"
project_root: Path = docs_dir.parent
+ repo = Repo(project_root)
+
+ if MAX_HASH and len(repo.commit(MAX_HASH).parents) > 1:
+ LOG.warning(f"{HOOK_NAME}: Using a Merge commit revision for 'MAX_HASH' is not supported")
+ return None
+
+ if cache_enabled and repo.head.commit.hexsha == CacheHelper.cache_obj["commit_hash"]:
+ LOG.info(f"{HOOK_NAME}: HEAD commit already cached")
+ return None
+ file_paths: Set[str] = {str(path) for path in docs_dir.glob("**/*.md")}
redirects: Dict[str, str] = config["plugins"]["redirects"].config["redirect_maps"]
+
+ if cache_enabled:
+ redirects.update(CacheHelper.cache_obj["redirects"])
+
initial_len: int = len(redirects)
- LOG.info(f"{HOOK_NAME}: Processing Git history...")
+ LOG.info(f"{HOOK_NAME}: Processing Git history with{'' if cache_enabled else 'out'} cache...")
- for commit in Repo(project_root).iter_commits(since=MAX_DATE, max_parents=1):
+ for commit in repo.iter_commits(since=MAX_DATE, max_parents=1):
if not commit.parents:
break
@@ -67,7 +95,9 @@ def _add_redirects_based_on_git_history(*, config: MkDocsConfig) -> None:
old_parts_len: int = len(old.split("/")[-1].split("."))
new_parts_len: int = len(new.split("/")[-1].split("."))
old_exists: bool = str(project_root / old) in file_paths
- old_index_exists: bool = str(project_root / old.replace(".md", "/index.md")) in file_paths
+ old_index_exists: bool = (
+ str(project_root / old.replace(".md", "/index.md")) in file_paths
+ )
type_md: bool = old.endswith(".md") and new.endswith(".md")
inside_docs: bool = old.startswith(docs_prefix) and new.startswith(docs_prefix)
@@ -91,24 +121,74 @@ def _add_redirects_based_on_git_history(*, config: MkDocsConfig) -> None:
if old_inner not in redirects:
redirects[old_inner] = new_inner
else:
- LOG.info(f"{HOOK_NAME}: '{old_inner}' already in redirects, keeping more recent one")
+ LOG.info(
+ f"{HOOK_NAME}: '{old_inner}' already in redirects, keeping more recent one"
+ )
if commit.hexsha == MAX_HASH:
break
+ if cache_enabled and commit.parents[0].hexsha == CacheHelper.cache_obj["commit_hash"]:
+ LOG.info(f"{HOOK_NAME}: Reached cached commits")
+ break
+
len_diff: int = len(redirects) - initial_len
if len_diff > 0:
LOG.info(f"{HOOK_NAME}: Created {len_diff} redirects")
+ if cache_enabled:
+ return repo.head.commit.hexsha
+
+
+class CacheHelper:
+ """Class contains variables related to caching"""
+
+ cache_dir: Optional[Path] = None
+ """Directory path to the plugin cache directory"""
+
+ cache_file: Optional[Path] = None
+ """File path where the cached redirects will be saved"""
+
+ cache_obj: Optional[Dict] = None
+ """Object, which will be saved to cache"""
+
+ @classmethod
+ def setup(cls, *, config: MkDocsConfig) -> None:
+ cls.cache_dir = Path(config.get("docs_dir")).parent / CACHE_PATH
+ formatted_date: str = (
+ MAX_DATE.isoformat().replace(":", "") if isinstance(MAX_DATE, datetime.datetime) else ""
+ )
+ cls.cache_file = cls.cache_dir / f"{formatted_date}-{MAX_HASH}.json"
+
+ if cls.cache_file.exists():
+ cls.cache_obj = json.loads(cls.cache_file.read_text(encoding="utf8"))
+ else:
+ cls.cache_obj: Dict = {"commit_hash": "", "redirects": {}}
+ cls.cache_dir.mkdir(parents=True, exist_ok=True)
+ cls.cache_file.write_text(json.dumps(cls.cache_obj), encoding="utf8")
+
+ @classmethod
+ def save(cls, *, config: MkDocsConfig) -> None:
+ cls.cache_obj["redirects"] = config["plugins"]["redirects"].config["redirect_maps"]
+ cls.cache_file.write_text(json.dumps(cls.cache_obj, indent=2), encoding="utf8")
+
# endregion
# region Constants
+CACHE_VAR: str = "GMC_ENABLE_ON_PUBLISH"
+"""Name of the environmental variable to enable caching."""
HOOK_NAME: str = "git_redirects"
"""Name of this hook. Used in logging."""
+CACHE_PATH: str = f".cache/hooks/{HOOK_NAME}"
+"""A relative path to the cache directory, based from the `config.docs_dir` parent directory."""
+
+HOOK_VAR: str = "GMC_ENABLE_ON_PUBLISH"
+"""Name of the environmental variable to enable the hook."""
+
LOG: logging.Logger = logging.getLogger(f"mkdocs.hooks.{HOOK_NAME}")
"""Logger instance for this hook."""
diff --git a/overrides/.hooks/social_patch.py b/overrides/.hooks/social_patch.py
new file mode 100644
index 0000000000..cdf5f683f2
--- /dev/null
+++ b/overrides/.hooks/social_patch.py
@@ -0,0 +1,66 @@
+"""MkDocs hook, which patches the Social plugin of the Material theme.
+
+The hook fixes a crash when using theme.font.code without theme.font.text.
+The hook overrides the `theme.logo` file lookup to use the custom_dir instead of the docs_dir.
+The hook does not override `theme.logo.icon` file lookup.
+
+MIT Licence 2023 Kamil Krzyśków
+"""
+from copy import deepcopy
+from pathlib import Path
+from typing import Optional
+
+from mkdocs import plugins
+from mkdocs.config import Config
+from mkdocs.config.defaults import MkDocsConfig
+
+
+@plugins.event_priority(100)
+def on_config(config: MkDocsConfig) -> Optional[Config]:
+ for name in {"social", "material/social"}:
+ plugin = config.plugins.get(name)
+ if plugin:
+ break
+ else:
+ print("Social-Plugin-Patch: Did not find plugin!?!?!")
+ return None
+
+ plugin._load_font = patch_font_crash(plugin._load_font)
+ plugin._load_logo = patch_custom_dir(plugin._load_logo)
+
+ return None
+
+
+class Mock:
+ ...
+
+
+def patch_font_crash(func):
+ """Patch the theme["font"]["text"] crash"""
+
+ def wrap_load_font(config):
+ theme = config.theme
+ if "font" in theme and "text" not in theme["font"]:
+ mock_config = Mock()
+ mock_config.theme = deepcopy(config.theme)
+ mock_config.theme["font"]["text"] = "Roboto"
+ return func(mock_config)
+ return func(config)
+
+ return wrap_load_font
+
+
+def patch_custom_dir(func):
+ """Patch support for paths in `custom_dir`"""
+
+ def wrap_load_logo(config):
+ mock_config = Mock()
+ mock_config.theme = config.theme
+ mock_config.docs_dir = str(Path(config.docs_dir).parent / CUSTOM_DIR_PATH)
+ return func(mock_config)
+
+ return wrap_load_logo
+
+
+CUSTOM_DIR_PATH = "overrides"
+"""A relative path to the custom directory based from the `docs_dir` parent directory."""
diff --git a/overrides/assets/stylesheets/constants.css b/overrides/assets/stylesheets/constants.css
index 0fa956a1b4..ced88015c7 100644
--- a/overrides/assets/stylesheets/constants.css
+++ b/overrides/assets/stylesheets/constants.css
@@ -8,4 +8,9 @@
--gmc-external-svg: url('data:image/svg+xml;charset=utf-8,');
/* SVG to CSS inline data converter: https://yoksel.github.io/url-encoder/ - output edited */
--md-admonition-icon--trivia: url('data:image/svg+xml;charset=utf-8,');
+}
+
+/* Color */
+:root {
+ --gmc-blue-tint: #00aafc;
}
\ No newline at end of file
diff --git a/overrides/assets/stylesheets/extra.css b/overrides/assets/stylesheets/extra.css
index b74857b6eb..4876fe9162 100644
--- a/overrides/assets/stylesheets/extra.css
+++ b/overrides/assets/stylesheets/extra.css
@@ -23,6 +23,11 @@
max-width: 75rem;
}
+/* Add left padding indent to the content */
+article > div > :is(:not(h1, h2, h3, h4)) {
+ padding-left: 1em !important;
+}
+
/* Shrink header and footer to the content size*/
.md-grid {
/* Default 61rem */
@@ -96,7 +101,7 @@ div.md-nav__link--index {
--md-accent-fg-color: #0b65b0;
}
[data-md-color-scheme=slate] {
- --md-accent-fg-color: #00aafc;
+ --md-accent-fg-color: var(--gmc-blue-tint);
}
}
@@ -110,6 +115,7 @@ div.md-nav__link--index {
.md-typeset :is(h1, h2, h3, h4, h5, h6) {
font-weight: 700;
color: var(--md-default-fg-color--light);
+ text-shadow: 0 0 0 var(--md-default-fg-color--light);
}
.md-typeset :is(h3, h4, h5, h6) {
@@ -169,8 +175,9 @@ div.md-nav__link--index {
/* override main header */
/* override tabs navigation */
@media {
+ /* Use a darker color than the --gmc-blue-tint since it is too bright */
[data-md-color-scheme="slate"] .md-header {
- border-bottom: 0.10rem solid var(--md-accent-fg-color);
+ border-bottom: .10rem solid #0084c4;
}
[data-md-color-scheme="slate"] .md-tabs__link--active {
color: var(--md-accent-fg-color);
diff --git a/requirements-deploy.txt b/requirements-deploy.txt
new file mode 100644
index 0000000000..da56ab564f
--- /dev/null
+++ b/requirements-deploy.txt
@@ -0,0 +1,3 @@
+# Deployment Requirements
+Pillow==9.5.0
+CairoSVG==2.7.0
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index a4b4283cb1..0f36f762ce 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,10 +1,10 @@
-mkdocs-material==9.1.5
+# Core Requirements
+mkdocs-material==9.1.8
mkdocs-git-revision-date-localized-plugin==1.2.0
mkdocs-video==1.5.0
mkdocs-redirects==1.2.0
mkdocs-minify-plugin==0.6.4
# mkdocs-static-i18n==0.53
-git+https://github.com/kamilkrzyskow/i18n.git@920d38313b60812e8e03dba88a856bfdd41527dc#egg=mkdocs_static_i18n
+git+https://github.com/kamilkrzyskow/i18n.git@5e286be68ad6fafed7affd44cd57d3625c0a02cc#egg=mkdocs_static_i18n
git+https://github.com/kamilkrzyskow/gothic-lexer.git@b5ee7868a7e7397cd129ff1f847daa7d39c0e416#egg=gothic_lexer
-# mkdocs-awesome-pages-plugin==2.8.0
-git+https://github.com/kamilkrzyskow/awesome-pages.git@b0c544a92733977e09ac23c7f9238d13012f4fd9#egg=mkdocs_awesome_pages_plugin
\ No newline at end of file
+mkdocs-awesome-pages-plugin==2.9.0
\ No newline at end of file