mkdocs-document-dates 3.6.1__tar.gz → 3.7.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/LICENSE +1 -1
  2. mkdocs_document_dates-3.7.1/MANIFEST.in +9 -0
  3. {mkdocs_document_dates-3.6.1/mkdocs_document_dates.egg-info → mkdocs_document_dates-3.7.1}/PKG-INFO +18 -27
  4. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/README.md +11 -11
  5. mkdocs_document_dates-3.7.1/mkdocs_document_dates/__init__.py +1 -0
  6. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates/cache_manager.py +118 -18
  7. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates/hooks/pre-commit +1 -1
  8. mkdocs_document_dates-3.7.1/mkdocs_document_dates/hooks_installer.py +98 -0
  9. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates/plugin.py +93 -67
  10. mkdocs_document_dates-3.7.1/mkdocs_document_dates/static/.DS_Store +0 -0
  11. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates/static/templates/recently_updated_group.html +134 -40
  12. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates/utils.py +169 -84
  13. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1/mkdocs_document_dates.egg-info}/PKG-INFO +18 -27
  14. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates.egg-info/SOURCES.txt +1 -0
  15. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates.egg-info/entry_points.txt +1 -0
  16. mkdocs_document_dates-3.7.1/mkdocs_document_dates.egg-info/requires.txt +1 -0
  17. mkdocs_document_dates-3.7.1/pyproject.toml +51 -0
  18. mkdocs_document_dates-3.7.1/setup.py +50 -0
  19. mkdocs_document_dates-3.6.1/MANIFEST.in +0 -2
  20. mkdocs_document_dates-3.6.1/mkdocs_document_dates/__init__.py +0 -6
  21. mkdocs_document_dates-3.6.1/mkdocs_document_dates/hooks_installer.py +0 -120
  22. mkdocs_document_dates-3.6.1/mkdocs_document_dates.egg-info/requires.txt +0 -1
  23. mkdocs_document_dates-3.6.1/pyproject.toml +0 -4
  24. mkdocs_document_dates-3.6.1/setup.py +0 -69
  25. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates/static/config/user.config.css +0 -0
  26. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates/static/config/user.config.js +0 -0
  27. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates/static/core/core.css +0 -0
  28. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates/static/core/core.js +0 -0
  29. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates/static/core/default.config.js +0 -0
  30. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates/static/core/md5.min.js +0 -0
  31. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates/static/core/timeago.full.min.js +0 -0
  32. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates/static/core/timeago.min.js +0 -0
  33. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates/static/core/utils.js +0 -0
  34. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates/static/fonts/material-icons.css +0 -0
  35. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates/static/fonts/materialicons.woff2 +0 -0
  36. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates/static/templates/recently_updated_detail.html +0 -0
  37. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates/static/templates/recently_updated_grid.html +0 -0
  38. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates/static/templates/recently_updated_list.html +0 -0
  39. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates/static/tippy/backdrop.css +0 -0
  40. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates/static/tippy/light.css +0 -0
  41. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates/static/tippy/material.css +0 -0
  42. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates/static/tippy/popper.min.js +0 -0
  43. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates/static/tippy/scale.css +0 -0
  44. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates/static/tippy/shift-away.css +0 -0
  45. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates/static/tippy/tippy.css +0 -0
  46. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates/static/tippy/tippy.umd.min.js +0 -0
  47. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates.egg-info/dependency_links.txt +0 -0
  48. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/mkdocs_document_dates.egg-info/top_level.txt +0 -0
  49. {mkdocs_document_dates-3.6.1 → mkdocs_document_dates-3.7.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 Aaron Wang
3
+ Copyright (c) 2026 Aaron Wang
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -0,0 +1,9 @@
1
+ global-exclude tests/*
2
+ global-exclude tests/**/*
3
+
4
+ global-exclude .DS_Store
5
+ global-exclude __pycache__/*
6
+ global-exclude *.py[cod]
7
+
8
+ graft mkdocs_document_dates/hooks
9
+ graft mkdocs_document_dates/static
@@ -1,28 +1,19 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mkdocs-document-dates
3
- Version: 3.6.1
3
+ Version: 3.7.1
4
4
  Summary: A new generation MkDocs plugin for displaying exact creation date, last updated date, authors, email of documents
5
- Home-page: https://github.com/jaywhj/mkdocs-document-dates
6
- Author: Aaron Wang
7
- Author-email: aaronwqt@gmail.com
8
- License: MIT
5
+ Author-email: Aaron Wang <aaronwqt@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/jaywhj/mkdocs-document-dates
8
+ Project-URL: Repository, https://github.com/jaywhj/mkdocs-document-dates
9
+ Project-URL: Documentation, https://jaywhj.netlify.app/document-dates-en
9
10
  Classifier: Programming Language :: Python :: 3
10
11
  Classifier: Operating System :: OS Independent
11
12
  Requires-Python: >=3.7
12
13
  Description-Content-Type: text/markdown
13
14
  License-File: LICENSE
14
- Requires-Dist: mkdocs>=1.1.0
15
- Dynamic: author
16
- Dynamic: author-email
17
- Dynamic: classifier
18
- Dynamic: description
19
- Dynamic: description-content-type
20
- Dynamic: home-page
21
- Dynamic: license
15
+ Requires-Dist: mkdocs<=1.6.1,>=1.6
22
16
  Dynamic: license-file
23
- Dynamic: requires-dist
24
- Dynamic: requires-python
25
- Dynamic: summary
26
17
 
27
18
  # mkdocs-document-dates
28
19
 
@@ -36,7 +27,7 @@ A new generation MkDocs plugin for displaying exact **creation date, last update
36
27
 
37
28
  ## Features
38
29
 
39
- - [x] Always displays **exact** meta information of the document and works in any environment (no-Git, Git environments, Docker, all CI/CD build systems, etc.)
30
+ - [x] Works in any environment: no-Git, Git environments, Docker, all CI/CD build systems, etc.
40
31
  - [x] Support list display of recently updated documents (in descending order of update date)
41
32
  - [x] Support for manually specifying date and author in `Front Matter`
42
33
  - [x] Support for multiple date formats (date, datetime, timeago)
@@ -74,23 +65,23 @@ plugins:
74
65
  - document-dates:
75
66
  position: top # Display position: top(after title) bottom(end of document), default: top
76
67
  type: date # Date type: date datetime timeago, default: date
77
- exclude: # List of excluded files
68
+ exclude: # List of excluded files (support unix shell-style wildcards)
78
69
  - temp.md # Example: exclude the specified file
79
70
  - blog/* # Example: exclude all files in blog folder, including subfolders
71
+ - '*/index.md' # Example: exclude all index.md files in any subfolders
80
72
  ```
81
73
 
82
74
  ## Customization Settings
83
75
 
84
76
  In addition to the above basic configuration, the plug-in also provides a wealth of customization options to meet a variety of individual needs:
85
77
 
86
- - [Specify Datetime](https://jaywhj.netlify.app/document-dates-en#Specify-Datetime): Introduces the mechanism for obtaining document dates and methods for personalized customization, you can manually specify the creation date and last updated date for each document
87
- - [Specify Author](https://jaywhj.netlify.app/document-dates-en#Specify-Author): Introduces the mechanism for obtaining document authors and methods for personalized customization, you can manually specify the author information for each document, such as name, link, avatar, email, etc.
88
- - [Specify Avatar](https://jaywhj.netlify.app/document-dates-en#Specify-Avatar): You can manually specify the avatar for each author, support local file path and URL path
89
- - [Configuration Structure and Style](https://jaywhj.netlify.app/document-dates-en#Structure-and-Style): You can freely configure the plugin's display structure in mkdocs.yml or Front Matter. You can quickly set the plugin styles through preset entrances, such as icons, themes, colors, fonts, animations, dividing line and so on
90
- - [Use Template Variables](https://jaywhj.netlify.app/document-dates-en#Use-Template-Variables): Can be used to optimize `sitemap.xml` for site SEO; Can be used to re-customize plug-ins, etc.
91
- - [Add Recently Updated Module](https://jaywhj.netlify.app/document-dates-en#Add-Recently-Updated-Module): Enable list of recently updated documents (in descending order of update date), this is ideal for sites with a large number of documents, so that readers can quickly see what's new
92
- - [Add Localization Language](https://jaywhj.netlify.app/document-dates-en#Add-Localization-Language): More localization languages for `timeago` and `tooltip`
93
- - [Other Tips](https://jaywhj.netlify.app/document-dates-en#Other-Tips): Introducing the Do's of using plugin in Docker
78
+ - [Date & Time](https://jaywhj.netlify.app/document-dates-en#Date--Time): Introduces the mechanism for obtaining document dates and methods for personalized customization, support for manually specifying the creation date and last updated date for each document
79
+ - [Author](https://jaywhj.netlify.app/document-dates-en#Author): Introduces the mechanism for obtaining document authors and methods for personalized customization, support for manually specifying the author information for each document, such as name, link, avatar, email, etc.
80
+ - [Avatar](https://jaywhj.netlify.app/document-dates-en#Avatar): You can manually specify the avatar for each author, support local file path and URL path
81
+ - [Structure and Style](https://jaywhj.netlify.app/document-dates-en#Structure-and-Style): You can freely configure the plugin's display structure in mkdocs.yml or Front Matter. You can quickly set the plugin styles through preset entrances, such as icons, themes, colors, fonts, animations, dividing line and so on
82
+ - [Template Variables](https://jaywhj.netlify.app/document-dates-en#Template-Variables): Can be used to optimize `sitemap.xml` for site SEO
83
+ - [Recently Updated Module](https://jaywhj.netlify.app/document-dates-en#Recently-Updated-Module): Enable list of recently updated documents (in descending order of update date), this is ideal for sites with a large number of documents, so that readers can quickly see what's new
84
+ - [Localization Language](https://jaywhj.netlify.app/document-dates-en#Localization-Language): More localization languages for `timeago` and `tooltip`
94
85
  - [Development Stories](https://jaywhj.netlify.app/document-dates-en#Development-Stories): Describes the origin of the plug-in, the difficulties and solutions encountered in development, and the principles and directions of product design
95
86
 
96
87
  See the documentation for details: https://jaywhj.netlify.app/document-dates-en
@@ -99,7 +90,7 @@ See the documentation for details: https://jaywhj.netlify.app/document-dates-en
99
90
 
100
91
  ## Other Projects
101
92
 
102
- - [**MaterialX**](https://github.com/jaywhj/mkdocs-materialx), the next generation of mkdocs-material, is based on `mkdocs-material-9.7.0` and is named `X`. I'll be maintaining this branch continuously (since mkdocs-material will stop being maintained).
93
+ - [**MaterialX**](https://github.com/jaywhj/mkdocs-materialx), the next generation of mkdocs-material. Build beautiful sites the way you already know and love. Based on `mkdocs-material-9.7.1` and is named `X`, it provides ongoing maintenance and updates (since mkdocs-material will stop being maintained).
103
94
  Updates have been released that refactor and add a lot of new features, see https://github.com/jaywhj/mkdocs-materialx/releases/
104
95
 
105
96
  <br />
@@ -10,7 +10,7 @@ A new generation MkDocs plugin for displaying exact **creation date, last update
10
10
 
11
11
  ## Features
12
12
 
13
- - [x] Always displays **exact** meta information of the document and works in any environment (no-Git, Git environments, Docker, all CI/CD build systems, etc.)
13
+ - [x] Works in any environment: no-Git, Git environments, Docker, all CI/CD build systems, etc.
14
14
  - [x] Support list display of recently updated documents (in descending order of update date)
15
15
  - [x] Support for manually specifying date and author in `Front Matter`
16
16
  - [x] Support for multiple date formats (date, datetime, timeago)
@@ -48,23 +48,23 @@ plugins:
48
48
  - document-dates:
49
49
  position: top # Display position: top(after title) bottom(end of document), default: top
50
50
  type: date # Date type: date datetime timeago, default: date
51
- exclude: # List of excluded files
51
+ exclude: # List of excluded files (support unix shell-style wildcards)
52
52
  - temp.md # Example: exclude the specified file
53
53
  - blog/* # Example: exclude all files in blog folder, including subfolders
54
+ - '*/index.md' # Example: exclude all index.md files in any subfolders
54
55
  ```
55
56
 
56
57
  ## Customization Settings
57
58
 
58
59
  In addition to the above basic configuration, the plug-in also provides a wealth of customization options to meet a variety of individual needs:
59
60
 
60
- - [Specify Datetime](https://jaywhj.netlify.app/document-dates-en#Specify-Datetime): Introduces the mechanism for obtaining document dates and methods for personalized customization, you can manually specify the creation date and last updated date for each document
61
- - [Specify Author](https://jaywhj.netlify.app/document-dates-en#Specify-Author): Introduces the mechanism for obtaining document authors and methods for personalized customization, you can manually specify the author information for each document, such as name, link, avatar, email, etc.
62
- - [Specify Avatar](https://jaywhj.netlify.app/document-dates-en#Specify-Avatar): You can manually specify the avatar for each author, support local file path and URL path
63
- - [Configuration Structure and Style](https://jaywhj.netlify.app/document-dates-en#Structure-and-Style): You can freely configure the plugin's display structure in mkdocs.yml or Front Matter. You can quickly set the plugin styles through preset entrances, such as icons, themes, colors, fonts, animations, dividing line and so on
64
- - [Use Template Variables](https://jaywhj.netlify.app/document-dates-en#Use-Template-Variables): Can be used to optimize `sitemap.xml` for site SEO; Can be used to re-customize plug-ins, etc.
65
- - [Add Recently Updated Module](https://jaywhj.netlify.app/document-dates-en#Add-Recently-Updated-Module): Enable list of recently updated documents (in descending order of update date), this is ideal for sites with a large number of documents, so that readers can quickly see what's new
66
- - [Add Localization Language](https://jaywhj.netlify.app/document-dates-en#Add-Localization-Language): More localization languages for `timeago` and `tooltip`
67
- - [Other Tips](https://jaywhj.netlify.app/document-dates-en#Other-Tips): Introducing the Do's of using plugin in Docker
61
+ - [Date & Time](https://jaywhj.netlify.app/document-dates-en#Date--Time): Introduces the mechanism for obtaining document dates and methods for personalized customization, support for manually specifying the creation date and last updated date for each document
62
+ - [Author](https://jaywhj.netlify.app/document-dates-en#Author): Introduces the mechanism for obtaining document authors and methods for personalized customization, support for manually specifying the author information for each document, such as name, link, avatar, email, etc.
63
+ - [Avatar](https://jaywhj.netlify.app/document-dates-en#Avatar): You can manually specify the avatar for each author, support local file path and URL path
64
+ - [Structure and Style](https://jaywhj.netlify.app/document-dates-en#Structure-and-Style): You can freely configure the plugin's display structure in mkdocs.yml or Front Matter. You can quickly set the plugin styles through preset entrances, such as icons, themes, colors, fonts, animations, dividing line and so on
65
+ - [Template Variables](https://jaywhj.netlify.app/document-dates-en#Template-Variables): Can be used to optimize `sitemap.xml` for site SEO
66
+ - [Recently Updated Module](https://jaywhj.netlify.app/document-dates-en#Recently-Updated-Module): Enable list of recently updated documents (in descending order of update date), this is ideal for sites with a large number of documents, so that readers can quickly see what's new
67
+ - [Localization Language](https://jaywhj.netlify.app/document-dates-en#Localization-Language): More localization languages for `timeago` and `tooltip`
68
68
  - [Development Stories](https://jaywhj.netlify.app/document-dates-en#Development-Stories): Describes the origin of the plug-in, the difficulties and solutions encountered in development, and the principles and directions of product design
69
69
 
70
70
  See the documentation for details: https://jaywhj.netlify.app/document-dates-en
@@ -73,7 +73,7 @@ See the documentation for details: https://jaywhj.netlify.app/document-dates-en
73
73
 
74
74
  ## Other Projects
75
75
 
76
- - [**MaterialX**](https://github.com/jaywhj/mkdocs-materialx), the next generation of mkdocs-material, is based on `mkdocs-material-9.7.0` and is named `X`. I'll be maintaining this branch continuously (since mkdocs-material will stop being maintained).
76
+ - [**MaterialX**](https://github.com/jaywhj/mkdocs-materialx), the next generation of mkdocs-material. Build beautiful sites the way you already know and love. Based on `mkdocs-material-9.7.1` and is named `X`, it provides ongoing maintenance and updates (since mkdocs-material will stop being maintained).
77
77
  Updates have been released that refactor and add a lot of new features, see https://github.com/jaywhj/mkdocs-materialx/releases/
78
78
 
79
79
  <br />
@@ -0,0 +1 @@
1
+ """MkDocs Document Dates Plugin."""
@@ -1,32 +1,111 @@
1
1
  import logging
2
+ import yaml
3
+ import os
2
4
  import subprocess
3
5
  from pathlib import Path
4
- from .utils import read_jsonl_cache, write_jsonl_cache, get_file_creation_time, get_git_first_commit_time
6
+ from logging.handlers import RotatingFileHandler
7
+ from typing import Optional
8
+ from .utils import read_jsonl_cache, write_jsonl_cache, load_file_creation_date, load_git_first_commit_date
5
9
 
6
10
  logger = logging.getLogger("mkdocs.plugins.document_dates")
7
- logger.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, CRITICAL
11
+ _LOGGING_CONFIGURED = False
12
+
13
+
14
+ def _default_log_file() -> Path:
15
+ try:
16
+ git_root = Path(subprocess.check_output(
17
+ ['git', 'rev-parse', '--show-toplevel'],
18
+ env=_clean_git_env(),
19
+ encoding='utf-8'
20
+ ).strip())
21
+ base_dir = git_root
22
+ except Exception:
23
+ base_dir = Path.cwd()
24
+ return base_dir / "mkdocs_document_dates.log"
25
+
26
+ def configure_file_logging(log_file: Optional[Path] = None, level: int = logging.DEBUG) -> Optional[Path]:
27
+ global _LOGGING_CONFIGURED
28
+ if _LOGGING_CONFIGURED:
29
+ return log_file
30
+
31
+ env_log_file = os.getenv("MKDOCS_DOCUMENT_DATES_LOG_FILE")
32
+ if log_file is None and env_log_file:
33
+ log_file = Path(env_log_file).expanduser()
34
+
35
+ if log_file is None:
36
+ return None
37
+
38
+ log_file.parent.mkdir(parents=True, exist_ok=True)
39
+
40
+ handler = RotatingFileHandler(
41
+ log_file,
42
+ maxBytes=5 * 1024 * 1024,
43
+ backupCount=3,
44
+ encoding="utf-8",
45
+ )
46
+ handler.setLevel(level)
47
+ handler.setFormatter(logging.Formatter(
48
+ fmt="%(asctime)s [%(filename)s:%(lineno)d] %(message)s",
49
+ datefmt="%Y-%m-%d %H:%M:%S",
50
+ ))
51
+
52
+ logger.setLevel(level)
53
+ logger.addHandler(handler)
54
+ logger.propagate = False
55
+ _LOGGING_CONFIGURED = True
56
+ logger.debug(f"File logging enabled: {log_file}")
57
+ return log_file
58
+
59
+ def _env_truthy(name: str) -> bool:
60
+ value = os.getenv(name)
61
+ if value is None:
62
+ return False
63
+ value = value.strip().lower()
64
+ return value not in ("", "0", "false", "no", "off")
65
+
66
+
67
+ def _clean_git_env():
68
+ env = os.environ.copy()
69
+
70
+ for k in [
71
+ "GIT_DIR",
72
+ "GIT_WORK_TREE",
73
+ "GIT_COMMON_DIR",
74
+ "GIT_INDEX_FILE",
75
+ "GIT_PREFIX",
76
+ "GIT_SUPER_PREFIX",
77
+ "GIT_CEILING_DIRECTORIES",
78
+ ]:
79
+ env.pop(k, None)
80
+
81
+ env["GIT_OPTIONAL_LOCKS"] = "0"
82
+
83
+ return env
8
84
 
9
85
  def find_mkdocs_projects():
10
- projects = []
86
+ projects = set()
87
+
11
88
  try:
12
89
  git_root = Path(subprocess.check_output(
13
90
  ['git', 'rev-parse', '--show-toplevel'],
91
+ env=_clean_git_env(),
14
92
  encoding='utf-8'
15
93
  ).strip())
16
94
 
17
- # 遍历 git_root 及子目录, 寻找 mkdocs.yml 文件
18
- for config_file in git_root.rglob('mkdocs.y*ml'):
19
- if config_file.name.lower() in ('mkdocs.yml', 'mkdocs.yaml'):
20
- projects.append(config_file.parent)
95
+ target_names = {'mkdocs.yml', 'properdocs.yml'}
96
+ for config_file in git_root.rglob('*.yml'):
97
+ if config_file.name.lower() in target_names:
98
+ projects.add(config_file.parent)
21
99
 
22
100
  if not projects:
23
- logger.warning("No MkDocs projects found in the repository")
101
+ logger.warning("No MkDocs/ProperDocs projects found in the repository")
102
+
24
103
  except subprocess.CalledProcessError as e:
25
104
  logger.error(f"Failed to find the Git repository root: {e}")
26
105
  except Exception as e:
27
- logger.error(f"Unexpected error while searching for MkDocs projects: {e}")
28
-
29
- return projects
106
+ logger.error(f"Unexpected error while searching for projects: {e}")
107
+
108
+ return list(projects)
30
109
 
31
110
  def setup_gitattributes(docs_dir: Path):
32
111
  try:
@@ -39,7 +118,7 @@ def setup_gitattributes(docs_dir: Path):
39
118
  content += '\n'
40
119
  content += f"{union_merge_line}\n"
41
120
  gitattributes_path.write_text(content, encoding='utf-8')
42
- subprocess.run(["git", "add", str(gitattributes_path)], check=True)
121
+ subprocess.run(["git", "add", str(gitattributes_path)], cwd=docs_dir, env=_clean_git_env(), check=True)
43
122
  logger.info(f"Updated .gitattributes file: {gitattributes_path}")
44
123
  return True
45
124
  except (IOError, OSError) as e:
@@ -49,15 +128,36 @@ def setup_gitattributes(docs_dir: Path):
49
128
  return False
50
129
 
51
130
  def update_cache():
52
- global_updated = False
131
+ if os.getenv("MKDOCS_DOCUMENT_DATES_LOG_FILE"):
132
+ configure_file_logging()
133
+ elif _env_truthy("MKDOCS_DOCUMENT_DATES_DEBUG"):
134
+ configure_file_logging(_default_log_file())
53
135
 
136
+ global_updated = False
54
137
  for project_dir in find_mkdocs_projects():
55
138
  try:
56
139
  project_updated = False
57
140
 
58
141
  docs_dir = project_dir / 'docs'
142
+
143
+ # 从 mkdocs.yml 中读取 docs_dir 配置覆盖默认值
144
+ try:
145
+ mkdocs_yml = project_dir / "properdocs.yml"
146
+ if not mkdocs_yml.exists():
147
+ mkdocs_yml = project_dir / "mkdocs.yml"
148
+
149
+ mkdocs_config = yaml.load(
150
+ mkdocs_yml.read_text(encoding="utf-8"),
151
+ Loader=yaml.BaseLoader,
152
+ ) or {}
153
+
154
+ docs_dir_name = mkdocs_config.get("docs_dir") or "docs"
155
+ docs_dir = (project_dir / docs_dir_name).resolve(strict=False)
156
+ except (IOError, OSError, yaml.YAMLError) as e:
157
+ logger.warning(f"Failed to read docs_dir: {e}")
158
+
59
159
  if not docs_dir.exists():
60
- logger.warning(f"Document directory does not exist: {docs_dir}")
160
+ logger.info(f"Document directory does not exist: {docs_dir}")
61
161
  continue
62
162
 
63
163
  # 设置.gitattributes文件
@@ -65,7 +165,7 @@ def update_cache():
65
165
 
66
166
  # 获取docs目录下已跟踪(tracked)的markdown文件
67
167
  cmd = ["git", "ls-files", "*.md"]
68
- result = subprocess.run(cmd, cwd=docs_dir, capture_output=True, encoding='utf-8')
168
+ result = subprocess.run(cmd, cwd=docs_dir, env=_clean_git_env(), capture_output=True, encoding='utf-8')
69
169
  tracked_files = result.stdout.splitlines() if result.stdout else []
70
170
 
71
171
  if not tracked_files:
@@ -85,9 +185,9 @@ def update_cache():
85
185
 
86
186
  full_path = docs_dir / rel_path
87
187
  if full_path.exists():
88
- created_time = get_file_creation_time(full_path).astimezone()
188
+ created_time = load_file_creation_date(full_path).astimezone()
89
189
  if not jsonl_cache_file.exists():
90
- git_time = get_git_first_commit_time(full_path)
190
+ git_time = load_git_first_commit_date(full_path)
91
191
  if git_time:
92
192
  created_time = min(created_time, git_time)
93
193
  jsonl_dates_cache[rel_path] = {
@@ -115,4 +215,4 @@ def update_cache():
115
215
 
116
216
 
117
217
  if __name__ == "__main__":
118
- update_cache()
218
+ update_cache()
@@ -4,7 +4,7 @@ try:
4
4
  from mkdocs_document_dates.cache_manager import update_cache
5
5
  except Exception:
6
6
  import sys
7
- # 正常退出(0 状态码),不影响 git 的后续动作
7
+ # Normal exit (0 status code), don't affect subsequent git actions
8
8
  sys.exit(0)
9
9
 
10
10
  if __name__ == "__main__":
@@ -0,0 +1,98 @@
1
+ import os
2
+ import sys
3
+ import subprocess
4
+ from pathlib import Path
5
+
6
+ DEFAULT_HOOKS_DIRNAME = ".githooks"
7
+
8
+
9
+ class HookInstallError(Exception):
10
+ pass
11
+
12
+
13
+ def get_repo_root() -> Path:
14
+ result = subprocess.run(
15
+ ["git", "rev-parse", "--show-toplevel"],
16
+ capture_output=True,
17
+ text=True,
18
+ )
19
+ if result.returncode != 0 or not result.stdout.strip():
20
+ raise HookInstallError("This command must be run inside a Git repo. Please cd into your project directory and try again.")
21
+ return Path(result.stdout.strip())
22
+
23
+
24
+ def ensure_hooks_dir(repo_root: Path) -> Path:
25
+ hooks_dir = repo_root / DEFAULT_HOOKS_DIRNAME
26
+ try:
27
+ hooks_dir.mkdir(parents=True, exist_ok=True)
28
+ os.chmod(hooks_dir, 0o755)
29
+ except Exception as e:
30
+ raise HookInstallError(f"Failed to create hooks directory: {hooks_dir} ({e})")
31
+ return hooks_dir
32
+
33
+
34
+ def write_hooks(source_dir: Path, target_dir: Path):
35
+ if not source_dir.exists():
36
+ raise HookInstallError(f"Hooks source directory not found: {source_dir}")
37
+
38
+ shebang = f"#!{sys.executable}"
39
+
40
+ try:
41
+ for file in source_dir.iterdir():
42
+ if file.name.startswith(".") or not file.is_file():
43
+ continue
44
+
45
+ content = file.read_text(encoding="utf-8")
46
+
47
+ if content.startswith("#!"):
48
+ os.linesep
49
+ content = shebang + "\n" + content.split("\n", 1)[1]
50
+ else:
51
+ content = shebang + "\n" + content
52
+
53
+ target = target_dir / file.name
54
+ target.write_text(content, encoding="utf-8")
55
+ os.chmod(target, 0o755)
56
+
57
+ except Exception as e:
58
+ raise HookInstallError(f"Failed to write hook files: {e}")
59
+
60
+
61
+ def set_hooks_path(repo_root: Path, hooks_dir: Path):
62
+ rel_path = hooks_dir.relative_to(repo_root).as_posix()
63
+
64
+ # # 配置自定义合并驱动
65
+ # script_path = hooks_dir / 'json_merge_driver.py'
66
+ # subprocess.run(['git', 'config', 'merge.custom_json_merge.name', 'Custom JSON merge driver'], check=True)
67
+ # subprocess.run(['git', 'config', 'merge.custom_json_merge.driver', f'"{sys.executable}" "{script_path}" %O %A %B'], check=True)
68
+
69
+ result = subprocess.run(
70
+ ["git", "config", "core.hooksPath", rel_path],
71
+ cwd=repo_root,
72
+ capture_output=True,
73
+ text=True,
74
+ )
75
+ if result.returncode != 0:
76
+ raise HookInstallError(result.stderr.strip() or "Failed to set hooksPath")
77
+
78
+
79
+ def install():
80
+ try:
81
+ repo_root = get_repo_root()
82
+ hooks_dir = ensure_hooks_dir(repo_root)
83
+
84
+ source_dir = Path(__file__).parent / "hooks"
85
+
86
+ write_hooks(source_dir, hooks_dir)
87
+ set_hooks_path(repo_root, hooks_dir)
88
+
89
+ print(f"✔ Hooks installed successfully: {hooks_dir}")
90
+
91
+ except HookInstallError as e:
92
+ print(f"✖ Installation failed: {e}", file=sys.stderr)
93
+ except Exception as e:
94
+ print(f"✖ Unexpected error: {e}", file=sys.stderr)
95
+
96
+
97
+ if __name__ == "__main__":
98
+ install()