|
9 | 9 | import re
|
10 | 10 | import os
|
11 | 11 | import time
|
| 12 | +import multiprocessing |
12 | 13 |
|
13 | 14 | from mkdocs import __version__ as mkdocs_version
|
14 | 15 | from mkdocs.config import config_options
|
15 | 16 | from mkdocs.plugins import BasePlugin
|
16 | 17 | from mkdocs.structure.nav import Page
|
17 | 18 | from mkdocs.utils import copy_file
|
18 | 19 | from mkdocs.exceptions import ConfigurationError
|
| 20 | +from mkdocs.config.defaults import MkDocsConfig |
| 21 | +from mkdocs.structure.files import Files |
19 | 22 |
|
20 | 23 | from mkdocs_git_revision_date_localized_plugin.util import Util
|
21 | 24 | from mkdocs_git_revision_date_localized_plugin.exclude import exclude
|
@@ -47,8 +50,14 @@ class GitRevisionDateLocalizedPlugin(BasePlugin):
|
47 | 50 | ("strict", config_options.Type(bool, default=True)),
|
48 | 51 | ("enable_git_follow", config_options.Type(bool, default=True)),
|
49 | 52 | ("ignored_commits_file", config_options.Type(str, default=None)),
|
| 53 | + ("enable_parallel_processing", config_options.Type(bool, default=True)), |
50 | 54 | )
|
51 | 55 |
|
| 56 | + def __init__(self): |
| 57 | + super().__init__() |
| 58 | + self.last_revision_commits = {} |
| 59 | + self.created_commits = {} |
| 60 | + |
52 | 61 | def on_config(self, config: config_options.Config, **kwargs) -> Dict[str, Any]:
|
53 | 62 | """
|
54 | 63 | Determine which locale to use.
|
@@ -135,6 +144,42 @@ def on_config(self, config: config_options.Config, **kwargs) -> Dict[str, Any]:
|
135 | 144 |
|
136 | 145 | return config
|
137 | 146 |
|
| 147 | + |
| 148 | + def parallel_compute_commit_timestamps(self, files, docs_dir, is_first_commit=False): |
| 149 | + pool = multiprocessing.Pool(processes=min(10, multiprocessing.cpu_count())) |
| 150 | + results = [] |
| 151 | + for file in files: |
| 152 | + if file.is_documentation_page(): |
| 153 | + abs_src_path = os.path.join(docs_dir, file.src_uri) |
| 154 | + result = pool.apply_async( |
| 155 | + self.util.get_git_commit_timestamp, args=(abs_src_path, is_first_commit) |
| 156 | + ) |
| 157 | + results.append((abs_src_path, result)) |
| 158 | + pool.close() |
| 159 | + pool.join() |
| 160 | + if is_first_commit: |
| 161 | + for src_uri, result in results: |
| 162 | + self.created_commits[src_uri] = result.get() |
| 163 | + else: |
| 164 | + for src_uri, result in results: |
| 165 | + self.last_revision_commits[src_uri] = result.get() |
| 166 | + |
| 167 | + def on_files(self, files: Files, config: MkDocsConfig): |
| 168 | + """ |
| 169 | + Compute commit timestamps for all files in parallel. |
| 170 | + """ |
| 171 | + if not self.config.get("enabled") or not self.config.get("enable_parallel_processing"): |
| 172 | + return |
| 173 | + # Some plugins like TechDocs/monorepo copies docs_dir to a tmp dir and we need the real git path. |
| 174 | + real_docs_dir = os.path.join( |
| 175 | + os.path.dirname(config["config_file_path"]), "docs" |
| 176 | + ) |
| 177 | + if not self.last_revision_commits: |
| 178 | + self.parallel_compute_commit_timestamps(files=files, docs_dir=real_docs_dir, is_first_commit=False) |
| 179 | + if not self.created_commits: |
| 180 | + self.parallel_compute_commit_timestamps(files=files, docs_dir=real_docs_dir, is_first_commit=True) |
| 181 | + |
| 182 | + |
138 | 183 | def on_page_markdown(self, markdown: str, page: Page, config: config_options.Config, files, **kwargs) -> str:
|
139 | 184 | """
|
140 | 185 | Replace jinja2 tags in markdown and templates with the localized dates.
|
@@ -189,10 +234,12 @@ def on_page_markdown(self, markdown: str, page: Page, config: config_options.Con
|
189 | 234 | if getattr(page.file, "generated_by", None):
|
190 | 235 | last_revision_hash, last_revision_timestamp = "", int(time.time())
|
191 | 236 | else:
|
192 |
| - last_revision_hash, last_revision_timestamp = self.util.get_git_commit_timestamp( |
193 |
| - path=page.file.abs_src_path, |
194 |
| - is_first_commit=False, |
195 |
| - ) |
| 237 | + last_revision_hash, last_revision_timestamp = self.last_revision_commits.get(page.file.abs_src_path, (None, None)) |
| 238 | + if last_revision_timestamp is None: |
| 239 | + last_revision_hash, last_revision_timestamp = self.util.get_git_commit_timestamp( |
| 240 | + path=page.file.abs_src_path, |
| 241 | + is_first_commit=False, |
| 242 | + ) |
196 | 243 |
|
197 | 244 | # Last revision date
|
198 | 245 | revision_dates = self.util.get_date_formats_for_timestamp(
|
@@ -261,10 +308,12 @@ def on_page_markdown(self, markdown: str, page: Page, config: config_options.Con
|
261 | 308 | if getattr(page.file, "generated_by", None):
|
262 | 309 | first_revision_hash, first_revision_timestamp = "", int(time.time())
|
263 | 310 | else:
|
264 |
| - first_revision_hash, first_revision_timestamp = self.util.get_git_commit_timestamp( |
265 |
| - path=page.file.abs_src_path, |
266 |
| - is_first_commit=True, |
267 |
| - ) |
| 311 | + first_revision_hash, first_revision_timestamp = self.created_commits.get(page.file.abs_src_path, (None, None)) |
| 312 | + if first_revision_timestamp is None: |
| 313 | + first_revision_hash, first_revision_timestamp = self.util.get_git_commit_timestamp( |
| 314 | + path=page.file.abs_src_path, |
| 315 | + is_first_commit=True, |
| 316 | + ) |
268 | 317 |
|
269 | 318 | if first_revision_timestamp > last_revision_timestamp:
|
270 | 319 | # See also https://github.com/timvink/mkdocs-git-revision-date-localized-plugin/issues/111
|
|
0 commit comments