mkdocs-document-dates 3.1.1__tar.gz → 3.1.3__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 (52) hide show
  1. {mkdocs_document_dates-3.1.1 → mkdocs_document_dates-3.1.3}/PKG-INFO +26 -10
  2. {mkdocs_document_dates-3.1.1 → mkdocs_document_dates-3.1.3}/README.md +21 -9
  3. {mkdocs_document_dates-3.1.1 → mkdocs_document_dates-3.1.3}/mkdocs_document_dates/cache_manager.py +100 -98
  4. mkdocs_document_dates-3.1.3/mkdocs_document_dates/hooks/pre-commit +11 -0
  5. {mkdocs_document_dates-3.1.1 → mkdocs_document_dates-3.1.3}/mkdocs_document_dates/hooks_installer.py +3 -3
  6. {mkdocs_document_dates-3.1.1 → mkdocs_document_dates-3.1.3}/mkdocs_document_dates/plugin.py +115 -147
  7. {mkdocs_document_dates-3.1.1 → mkdocs_document_dates-3.1.3}/mkdocs_document_dates/static/config/user.config.js +35 -0
  8. mkdocs_document_dates-3.1.3/mkdocs_document_dates/static/core/timeago-load.js +5 -0
  9. mkdocs_document_dates-3.1.3/mkdocs_document_dates/static/core/timeago.full.min.js +1 -0
  10. mkdocs_document_dates-3.1.3/mkdocs_document_dates/static/core/timeago.min.js +1 -0
  11. mkdocs_document_dates-3.1.3/mkdocs_document_dates/static/languages/ar.json +6 -0
  12. mkdocs_document_dates-3.1.3/mkdocs_document_dates/static/languages/de.json +6 -0
  13. mkdocs_document_dates-3.1.3/mkdocs_document_dates/static/languages/en.json +6 -0
  14. mkdocs_document_dates-3.1.3/mkdocs_document_dates/static/languages/es.json +6 -0
  15. mkdocs_document_dates-3.1.3/mkdocs_document_dates/static/languages/fr.json +6 -0
  16. mkdocs_document_dates-3.1.3/mkdocs_document_dates/static/languages/ja.json +6 -0
  17. mkdocs_document_dates-3.1.3/mkdocs_document_dates/static/languages/ko.json +6 -0
  18. mkdocs_document_dates-3.1.3/mkdocs_document_dates/static/languages/ru.json +6 -0
  19. mkdocs_document_dates-3.1.3/mkdocs_document_dates/static/languages/zh.json +6 -0
  20. mkdocs_document_dates-3.1.3/mkdocs_document_dates/static/languages/zh_TW.json +6 -0
  21. {mkdocs_document_dates-3.1.1 → mkdocs_document_dates-3.1.3}/mkdocs_document_dates.egg-info/PKG-INFO +26 -10
  22. {mkdocs_document_dates-3.1.1 → mkdocs_document_dates-3.1.3}/mkdocs_document_dates.egg-info/SOURCES.txt +4 -1
  23. {mkdocs_document_dates-3.1.1 → mkdocs_document_dates-3.1.3}/setup.py +3 -1
  24. mkdocs_document_dates-3.1.1/mkdocs_document_dates/hooks/pre-commit +0 -16
  25. mkdocs_document_dates-3.1.1/mkdocs_document_dates/static/languages/ar.json +0 -20
  26. mkdocs_document_dates-3.1.1/mkdocs_document_dates/static/languages/de.json +0 -20
  27. mkdocs_document_dates-3.1.1/mkdocs_document_dates/static/languages/en.json +0 -20
  28. mkdocs_document_dates-3.1.1/mkdocs_document_dates/static/languages/es.json +0 -20
  29. mkdocs_document_dates-3.1.1/mkdocs_document_dates/static/languages/fr.json +0 -20
  30. mkdocs_document_dates-3.1.1/mkdocs_document_dates/static/languages/ja.json +0 -20
  31. mkdocs_document_dates-3.1.1/mkdocs_document_dates/static/languages/ko.json +0 -20
  32. mkdocs_document_dates-3.1.1/mkdocs_document_dates/static/languages/ru.json +0 -20
  33. mkdocs_document_dates-3.1.1/mkdocs_document_dates/static/languages/zh.json +0 -20
  34. mkdocs_document_dates-3.1.1/mkdocs_document_dates/static/languages/zh_tw.json +0 -20
  35. {mkdocs_document_dates-3.1.1 → mkdocs_document_dates-3.1.3}/LICENSE +0 -0
  36. {mkdocs_document_dates-3.1.1 → mkdocs_document_dates-3.1.3}/mkdocs_document_dates/__init__.py +0 -0
  37. {mkdocs_document_dates-3.1.1 → mkdocs_document_dates-3.1.3}/mkdocs_document_dates/static/config/user.config.css +0 -0
  38. {mkdocs_document_dates-3.1.1 → mkdocs_document_dates-3.1.3}/mkdocs_document_dates/static/core/core.css +0 -0
  39. {mkdocs_document_dates-3.1.1 → mkdocs_document_dates-3.1.3}/mkdocs_document_dates/static/core/core.js +0 -0
  40. {mkdocs_document_dates-3.1.1 → mkdocs_document_dates-3.1.3}/mkdocs_document_dates/static/tippy/backdrop.css +0 -0
  41. {mkdocs_document_dates-3.1.1 → mkdocs_document_dates-3.1.3}/mkdocs_document_dates/static/tippy/light.css +0 -0
  42. {mkdocs_document_dates-3.1.1 → mkdocs_document_dates-3.1.3}/mkdocs_document_dates/static/tippy/material.css +0 -0
  43. {mkdocs_document_dates-3.1.1 → mkdocs_document_dates-3.1.3}/mkdocs_document_dates/static/tippy/popper.min.js +0 -0
  44. {mkdocs_document_dates-3.1.1 → mkdocs_document_dates-3.1.3}/mkdocs_document_dates/static/tippy/scale.css +0 -0
  45. {mkdocs_document_dates-3.1.1 → mkdocs_document_dates-3.1.3}/mkdocs_document_dates/static/tippy/shift-away.css +0 -0
  46. {mkdocs_document_dates-3.1.1 → mkdocs_document_dates-3.1.3}/mkdocs_document_dates/static/tippy/tippy.css +0 -0
  47. {mkdocs_document_dates-3.1.1 → mkdocs_document_dates-3.1.3}/mkdocs_document_dates/static/tippy/tippy.umd.min.js +0 -0
  48. {mkdocs_document_dates-3.1.1 → mkdocs_document_dates-3.1.3}/mkdocs_document_dates.egg-info/dependency_links.txt +0 -0
  49. {mkdocs_document_dates-3.1.1 → mkdocs_document_dates-3.1.3}/mkdocs_document_dates.egg-info/entry_points.txt +0 -0
  50. {mkdocs_document_dates-3.1.1 → mkdocs_document_dates-3.1.3}/mkdocs_document_dates.egg-info/requires.txt +0 -0
  51. {mkdocs_document_dates-3.1.1 → mkdocs_document_dates-3.1.3}/mkdocs_document_dates.egg-info/top_level.txt +0 -0
  52. {mkdocs_document_dates-3.1.1 → mkdocs_document_dates-3.1.3}/setup.cfg +0 -0
@@ -1,9 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mkdocs-document-dates
3
- Version: 3.1.1
3
+ Version: 3.1.3
4
4
  Summary: An easy-to-use, lightweight MkDocs plugin for displaying the exact creation time, last modification time and author info of markdown documents.
5
5
  Home-page: https://github.com/jaywhj/mkdocs-document-dates
6
6
  Author: Aaron Wang
7
+ Author-email: aaronwqt@gmail.com
8
+ License: MIT
7
9
  Classifier: Programming Language :: Python :: 3
8
10
  Classifier: License :: OSI Approved :: MIT License
9
11
  Classifier: Operating System :: OS Independent
@@ -12,10 +14,12 @@ Description-Content-Type: text/markdown
12
14
  License-File: LICENSE
13
15
  Requires-Dist: mkdocs>=1.0.0
14
16
  Dynamic: author
17
+ Dynamic: author-email
15
18
  Dynamic: classifier
16
19
  Dynamic: description
17
20
  Dynamic: description-content-type
18
21
  Dynamic: home-page
22
+ Dynamic: license
19
23
  Dynamic: license-file
20
24
  Dynamic: requires-dist
21
25
  Dynamic: requires-python
@@ -70,15 +74,15 @@ plugins:
70
74
  - document-dates:
71
75
  position: top # Display position: top (after title) bottom (end of document), default: bottom
72
76
  type: date # Date type: date datetime timeago, default: date
73
- locale: en # Localization: zh zh_tw en es fr de ar ja ko ru, default: en
74
- date_format: '%Y-%m-%d' # Date format, Supports all Python datetime format strings, e.g., %Y-%m-%d, %b %d, %Y, etc
77
+ locale: en # Localization: zh zh_TW en es fr de ar ja ko ru, default: en
78
+ date_format: '%Y-%m-%d' # Date format, supports all python datetime format strings, e.g., %Y-%m-%d, %b %d, %Y, etc
75
79
  time_format: '%H:%M:%S' # Time format (valid only if type=datetime)
76
80
  exclude: # List of excluded files
77
81
  - temp.md # Exclude specific file
78
82
  - private/* # Exclude all files in private directory, including subdirectories
79
83
  - drafts/*.md # Exclude all markdown files in the current directory drafts, but not subdirectories
80
84
 
81
- show_author: true # Whether to display author: true false, default: true
85
+ show_author: true # Show author or not: true false, default: true
82
86
 
83
87
  ```
84
88
 
@@ -125,13 +129,21 @@ The plugin supports deep customization, such as icon style, font style, theme co
125
129
  - Style & Theme: `docs/assets/document_dates/user.config.css`
126
130
  - Properties & Animations: `docs/assets/document_dates/user.config.js`
127
131
  - Localized languages: `docs/assets/document_dates/languages/` , refer to the template file `en.json` for any additions or modifications
132
+ - timeago.js localization: `timeago.min.js` only contains English and Chinese by default, if you need to load other languages, you can configure it as below (choose one):
133
+ - In `user.config.js`, refer to [the demo commented out](https://github.com/jaywhj/mkdocs-document-dates/blob/main/mkdocs_document_dates/static/config/user.config.js) at the bottom, translate it into your local language
134
+ - In `mkdocs.yml`, add the following two lines to configure the full version of `timeago.full.min.js` to load all languages at once
135
+ ```yaml
136
+ extra_javascript:
137
+ - assets/document_dates/core/timeago.full.min.js
138
+ - assets/document_dates/core/timeago-load.js
139
+ ```
128
140
 
129
141
  ## Other Tips
130
142
 
131
143
  - In order to get the exact creation time, a separate cache file is used to store the creation time of the file, located in the doc folder (hidden by default), please don't delete it:
132
144
  - `docs/.dates_cache.jsonl`, cache file
133
- - `docs/.gitattributes`, merge mechanism for cache file in case of multi-person collaboration
134
- - The Git Hooks mechanism is used to automatically trigger the storing of the cache (every time executes a git commit), and the cached file is automatically committed along with it. In addition, the installation of Git Hooks is automatically triggered when the plugin is installed, without any manual intervention!
145
+ - `docs/.gitattributes`, merge mechanism for cache file
146
+ - The Git Hooks mechanism is used to automatically trigger the storing of the cache (on each git commit), and the cached file is automatically committed along with it. In addition, the installation of Git Hooks is automatically triggered when the plugin is installed, without any manual intervention!
135
147
 
136
148
  <br />
137
149
 
@@ -147,9 +159,13 @@ A dispensable, insignificant little plug-in, friends who have time can take a lo
147
159
  - Method 2: You can cache the original time, and then read the cache subsequently. The cache can be in Front Matter of the source document or in a separate file, I chose the latter. Storing in Front Matter makes sense and is simple, but this will modify the source content of the document, although it doesn't have any impact on the body, but I still want to ensure the originality of the data!
148
160
  - **Difficulty**:
149
161
  1. When to read and store original time? This is just a plugin for mkdocs, with very limited access and permissions, mkdocs provides only build and serve, so in case a user commits directly without executing build or serve (e.g., when using a CI/CD build system), then you won't be able to retrieve the time information of the file, not to mention caching it!
150
- - Let's take a straight shot: the Git Hooks mechanism was found, prompted by the AI, which can trigger a custom script when a specific action occurs, such as every time commit is performed
151
- 2. How can I ensure that a single cache file does not conflict when collaborating with multi-person?
152
- - My solution: use JSONL (JSON Lines) instead of JSON, and with the merge strategy 'merge=union'
162
+ - Let's take a straight shot: the Git Hooks mechanism was found, prompted by the AI, which can trigger a custom script when a specific git action occurs, such as every time commit is performed
163
+ 2. How to install Git Hooks automatically? When and how are they triggered? Installing packages from PyPI via pip doesn't have a standard post-install hook mechanism
164
+ - Workaround: After analyzing the flow of pip installing packages from PyPI, I found that when compiling and installing through the source package (sdist), setuptools will be called to handle it, so we can find a way to implant the installation script in the process of setuptools, i.e., we can add a custom script in setup.py
165
+ 3. How to design a cross-platform hook? To execute a python script, we need to explicitly specify the python interpreter, and the user's python environment varies depending on the operating system, the way python is installed, and the configuration, so how can we ensure that it works properly in all environments?
166
+ - Solution: I considered using a shell script, but since I'd have to call back to python eventually, it's easier to use a python script. We can detect the user's python environment when the hook is installed, and then dynamically set the hook's shebang line to set the correct python interpreter
167
+ 4. How can I ensure that a single cache file does not conflict when collaborating with multi-person?
168
+ - Workaround: use JSONL (JSON Lines) instead of JSON, and with the merge strategy 'merge=union'
153
169
  - **Improve**:
154
170
  - Since it has been re-developed, it will be designed in the direction of **excellent products**, and the pursuit of the ultimate **ease of use, simplicity and personalization**
155
171
  - Ease of use: don't let users do things manually if you can, e.g., auto-install Git Hooks, auto-cache, auto-commit, provide customized templates, etc
@@ -157,4 +173,4 @@ A dispensable, insignificant little plug-in, friends who have time can take a lo
157
173
  - Personalization: almost everything can be customized, whether it's icons, styles, themes, or features, it's all fully customizable
158
174
  - In addition, it has good compatibility and extensibility, and works well in WIN7, mobile devices, old Safari, etc
159
175
  - **The Last Secret**:
160
- - I'm not a programmer, my main job is marketing, can you believe it? (Feel free to leave a comment)
176
+ - Programming is a hobby, and I'm a marketer of 8 years (Feel free to leave a comment)
@@ -47,15 +47,15 @@ plugins:
47
47
  - document-dates:
48
48
  position: top # Display position: top (after title) bottom (end of document), default: bottom
49
49
  type: date # Date type: date datetime timeago, default: date
50
- locale: en # Localization: zh zh_tw en es fr de ar ja ko ru, default: en
51
- date_format: '%Y-%m-%d' # Date format, Supports all Python datetime format strings, e.g., %Y-%m-%d, %b %d, %Y, etc
50
+ locale: en # Localization: zh zh_TW en es fr de ar ja ko ru, default: en
51
+ date_format: '%Y-%m-%d' # Date format, supports all python datetime format strings, e.g., %Y-%m-%d, %b %d, %Y, etc
52
52
  time_format: '%H:%M:%S' # Time format (valid only if type=datetime)
53
53
  exclude: # List of excluded files
54
54
  - temp.md # Exclude specific file
55
55
  - private/* # Exclude all files in private directory, including subdirectories
56
56
  - drafts/*.md # Exclude all markdown files in the current directory drafts, but not subdirectories
57
57
 
58
- show_author: true # Whether to display author: true false, default: true
58
+ show_author: true # Show author or not: true false, default: true
59
59
 
60
60
  ```
61
61
 
@@ -102,13 +102,21 @@ The plugin supports deep customization, such as icon style, font style, theme co
102
102
  - Style & Theme: `docs/assets/document_dates/user.config.css`
103
103
  - Properties & Animations: `docs/assets/document_dates/user.config.js`
104
104
  - Localized languages: `docs/assets/document_dates/languages/` , refer to the template file `en.json` for any additions or modifications
105
+ - timeago.js localization: `timeago.min.js` only contains English and Chinese by default, if you need to load other languages, you can configure it as below (choose one):
106
+ - In `user.config.js`, refer to [the demo commented out](https://github.com/jaywhj/mkdocs-document-dates/blob/main/mkdocs_document_dates/static/config/user.config.js) at the bottom, translate it into your local language
107
+ - In `mkdocs.yml`, add the following two lines to configure the full version of `timeago.full.min.js` to load all languages at once
108
+ ```yaml
109
+ extra_javascript:
110
+ - assets/document_dates/core/timeago.full.min.js
111
+ - assets/document_dates/core/timeago-load.js
112
+ ```
105
113
 
106
114
  ## Other Tips
107
115
 
108
116
  - In order to get the exact creation time, a separate cache file is used to store the creation time of the file, located in the doc folder (hidden by default), please don't delete it:
109
117
  - `docs/.dates_cache.jsonl`, cache file
110
- - `docs/.gitattributes`, merge mechanism for cache file in case of multi-person collaboration
111
- - The Git Hooks mechanism is used to automatically trigger the storing of the cache (every time executes a git commit), and the cached file is automatically committed along with it. In addition, the installation of Git Hooks is automatically triggered when the plugin is installed, without any manual intervention!
118
+ - `docs/.gitattributes`, merge mechanism for cache file
119
+ - The Git Hooks mechanism is used to automatically trigger the storing of the cache (on each git commit), and the cached file is automatically committed along with it. In addition, the installation of Git Hooks is automatically triggered when the plugin is installed, without any manual intervention!
112
120
 
113
121
  <br />
114
122
 
@@ -124,9 +132,13 @@ A dispensable, insignificant little plug-in, friends who have time can take a lo
124
132
  - Method 2: You can cache the original time, and then read the cache subsequently. The cache can be in Front Matter of the source document or in a separate file, I chose the latter. Storing in Front Matter makes sense and is simple, but this will modify the source content of the document, although it doesn't have any impact on the body, but I still want to ensure the originality of the data!
125
133
  - **Difficulty**:
126
134
  1. When to read and store original time? This is just a plugin for mkdocs, with very limited access and permissions, mkdocs provides only build and serve, so in case a user commits directly without executing build or serve (e.g., when using a CI/CD build system), then you won't be able to retrieve the time information of the file, not to mention caching it!
127
- - Let's take a straight shot: the Git Hooks mechanism was found, prompted by the AI, which can trigger a custom script when a specific action occurs, such as every time commit is performed
128
- 2. How can I ensure that a single cache file does not conflict when collaborating with multi-person?
129
- - My solution: use JSONL (JSON Lines) instead of JSON, and with the merge strategy 'merge=union'
135
+ - Let's take a straight shot: the Git Hooks mechanism was found, prompted by the AI, which can trigger a custom script when a specific git action occurs, such as every time commit is performed
136
+ 2. How to install Git Hooks automatically? When and how are they triggered? Installing packages from PyPI via pip doesn't have a standard post-install hook mechanism
137
+ - Workaround: After analyzing the flow of pip installing packages from PyPI, I found that when compiling and installing through the source package (sdist), setuptools will be called to handle it, so we can find a way to implant the installation script in the process of setuptools, i.e., we can add a custom script in setup.py
138
+ 3. How to design a cross-platform hook? To execute a python script, we need to explicitly specify the python interpreter, and the user's python environment varies depending on the operating system, the way python is installed, and the configuration, so how can we ensure that it works properly in all environments?
139
+ - Solution: I considered using a shell script, but since I'd have to call back to python eventually, it's easier to use a python script. We can detect the user's python environment when the hook is installed, and then dynamically set the hook's shebang line to set the correct python interpreter
140
+ 4. How can I ensure that a single cache file does not conflict when collaborating with multi-person?
141
+ - Workaround: use JSONL (JSON Lines) instead of JSON, and with the merge strategy 'merge=union'
130
142
  - **Improve**:
131
143
  - Since it has been re-developed, it will be designed in the direction of **excellent products**, and the pursuit of the ultimate **ease of use, simplicity and personalization**
132
144
  - Ease of use: don't let users do things manually if you can, e.g., auto-install Git Hooks, auto-cache, auto-commit, provide customized templates, etc
@@ -134,4 +146,4 @@ A dispensable, insignificant little plug-in, friends who have time can take a lo
134
146
  - Personalization: almost everything can be customized, whether it's icons, styles, themes, or features, it's all fully customizable
135
147
  - In addition, it has good compatibility and extensibility, and works well in WIN7, mobile devices, old Safari, etc
136
148
  - **The Last Secret**:
137
- - I'm not a programmer, my main job is marketing, can you believe it? (Feel free to leave a comment)
149
+ - Programming is a hobby, and I'm a marketer of 8 years (Feel free to leave a comment)
@@ -1,5 +1,4 @@
1
1
  import os
2
- import sys
3
2
  import json
4
3
  import logging
5
4
  import platform
@@ -14,13 +13,13 @@ logging.basicConfig(
14
13
  )
15
14
 
16
15
  def find_mkdocs_projects():
16
+ projects = []
17
17
  try:
18
18
  git_root = Path(subprocess.check_output(
19
19
  ['git', 'rev-parse', '--show-toplevel'],
20
20
  text=True, encoding='utf-8'
21
21
  ).strip())
22
22
 
23
- projects = []
24
23
  # 遍历 git_root 及子目录, 寻找 mkdocs.yml 文件
25
24
  for config_file in git_root.rglob('mkdocs.y*ml'):
26
25
  if config_file.name.lower() in ('mkdocs.yml', 'mkdocs.yaml'):
@@ -28,13 +27,12 @@ def find_mkdocs_projects():
28
27
 
29
28
  if not projects:
30
29
  logging.info("No MkDocs projects found in the repository")
31
- return projects
32
30
  except subprocess.CalledProcessError as e:
33
31
  logging.error(f"Failed to find the Git repository root: {e}")
34
- return []
35
32
  except Exception as e:
36
33
  logging.error(f"Unexpected error while searching for MkDocs projects: {e}")
37
- return []
34
+
35
+ return projects
38
36
 
39
37
  def get_file_creation_time(file_path):
40
38
  try:
@@ -66,29 +64,30 @@ def get_git_first_commit_time(file_path):
66
64
  return None
67
65
 
68
66
  def setup_gitattributes(docs_dir):
69
- gitattributes_path = docs_dir / '.gitattributes'
70
- union_config_line = ".dates_cache.jsonl merge=union"
71
67
  updated = False
72
-
73
- if gitattributes_path.exists():
74
- with open(gitattributes_path, 'r', encoding='utf-8') as f:
75
- content = f.read()
76
-
77
- if union_config_line not in content:
78
- with open(gitattributes_path, 'a', encoding='utf-8') as f:
79
- f.write(f"\n{union_config_line}\n")
68
+ try:
69
+ gitattributes_path = docs_dir / '.gitattributes'
70
+ union_config_line = ".dates_cache.jsonl merge=union"
71
+ if gitattributes_path.exists():
72
+ with open(gitattributes_path, 'r', encoding='utf-8') as f:
73
+ content = f.read()
74
+
75
+ if union_config_line not in content:
76
+ with open(gitattributes_path, 'a', encoding='utf-8') as f:
77
+ f.write(f"\n{union_config_line}\n")
78
+ updated = True
79
+ else:
80
+ with open(gitattributes_path, 'w', encoding='utf-8') as f:
81
+ f.write(f"{union_config_line}\n")
80
82
  updated = True
81
- else:
82
- with open(gitattributes_path, 'w', encoding='utf-8') as f:
83
- f.write(f"{union_config_line}\n")
84
- updated = True
85
-
86
- if updated:
87
- try:
83
+
84
+ if updated:
88
85
  subprocess.run(["git", "add", str(gitattributes_path)], check=True)
89
86
  logging.info(f"Updated .gitattributes file: {gitattributes_path}")
90
- except subprocess.CalledProcessError as e:
91
- logging.error(f"Failed to add .gitattributes to git: {e}")
87
+ except (IOError, OSError) as e:
88
+ logging.error(f"Failed to read/write .gitattributes file: {e}")
89
+ except Exception as e:
90
+ logging.error(f"Failed to add .gitattributes to git: {e}")
92
91
 
93
92
  return updated
94
93
 
@@ -145,87 +144,90 @@ def write_jsonl_cache(jsonl_file, dates_cache, tracked_files):
145
144
 
146
145
  def update_cache():
147
146
  global_updated = False
148
- for project_dir in find_mkdocs_projects():
149
- project_updated = False
150
-
151
- docs_dir = project_dir / 'docs'
152
- if not docs_dir.exists():
153
- logging.error(f"Document directory does not exist: {docs_dir}")
154
- continue
147
+ try:
148
+ for project_dir in find_mkdocs_projects():
149
+ try:
150
+ project_updated = False
155
151
 
156
- # 设置.gitattributes文件
157
- gitattributes_updated = setup_gitattributes(docs_dir)
158
- if gitattributes_updated:
159
- global_updated = True
152
+ docs_dir = project_dir / 'docs'
153
+ if not docs_dir.exists():
154
+ logging.error(f"Document directory does not exist: {docs_dir}")
155
+ continue
160
156
 
161
- try:
162
- # 获取docs目录下已跟踪(tracked)的markdown文件
163
- cmd = ["git", "ls-files", "*.md"]
164
- result = subprocess.run(cmd, cwd=docs_dir, capture_output=True, text=True, check=True)
165
- tracked_files = result.stdout.splitlines() if result.stdout else []
166
-
167
- if not tracked_files:
168
- logging.info(f"No tracked markdown files found in {docs_dir}")
169
- continue
170
-
171
- # 读取旧的JSON缓存文件(如果存在)
172
- json_cache_file = docs_dir / '.dates_cache.json'
173
- json_dates_cache = read_json_cache(json_cache_file)
157
+ # 设置.gitattributes文件
158
+ gitattributes_updated = setup_gitattributes(docs_dir)
159
+ if gitattributes_updated:
160
+ global_updated = True
174
161
 
175
- # 读取新的JSONL缓存文件(如果存在)
176
- jsonl_cache_file = docs_dir / '.dates_cache.jsonl'
177
- jsonl_dates_cache = read_jsonl_cache(jsonl_cache_file)
178
-
179
- # 根据 git已跟踪的文件来更新
180
- for file_path in tracked_files:
181
- try:
182
- rel_path = file_path
183
- full_path = docs_dir / rel_path
184
-
185
- # 如果文件已在JSONL缓存中,跳过
186
- if rel_path in jsonl_dates_cache:
162
+ # 获取docs目录下已跟踪(tracked)的markdown文件
163
+ cmd = ["git", "ls-files", "*.md"]
164
+ result = subprocess.run(cmd, cwd=docs_dir, capture_output=True, text=True, check=True)
165
+ tracked_files = result.stdout.splitlines() if result.stdout else []
166
+
167
+ if not tracked_files:
168
+ logging.info(f"No tracked markdown files found in {docs_dir}")
169
+ continue
170
+
171
+ # 读取旧的JSON缓存文件(如果存在)
172
+ json_cache_file = docs_dir / '.dates_cache.json'
173
+ json_dates_cache = read_json_cache(json_cache_file)
174
+
175
+ # 读取新的JSONL缓存文件(如果存在)
176
+ jsonl_cache_file = docs_dir / '.dates_cache.jsonl'
177
+ jsonl_dates_cache = read_jsonl_cache(jsonl_cache_file)
178
+
179
+ # 根据 git已跟踪的文件来更新
180
+ for file_path in tracked_files:
181
+ try:
182
+ rel_path = file_path
183
+ full_path = docs_dir / rel_path
184
+
185
+ # 如果文件已在JSONL缓存中,跳过
186
+ if rel_path in jsonl_dates_cache:
187
+ continue
188
+
189
+ # 处理新文件或迁移旧JSON缓存
190
+ if rel_path in json_dates_cache:
191
+ jsonl_dates_cache[rel_path] = json_dates_cache[rel_path]
192
+ project_updated = True
193
+ elif full_path.exists():
194
+ created_time = get_file_creation_time(full_path)
195
+ if not jsonl_cache_file.exists() and not json_cache_file.exists():
196
+ git_time = get_git_first_commit_time(full_path)
197
+ if git_time is not None:
198
+ created_time = min(created_time, git_time)
199
+ jsonl_dates_cache[rel_path] = {
200
+ "created": created_time.isoformat()
201
+ }
202
+ project_updated = True
203
+ except Exception as e:
204
+ logging.error(f"Error processing file {file_path}: {e}")
187
205
  continue
188
-
189
- # 处理新文件或迁移旧JSON缓存
190
- if rel_path in json_dates_cache:
191
- jsonl_dates_cache[rel_path] = json_dates_cache[rel_path]
192
- project_updated = True
193
- elif full_path.exists():
194
- created_time = get_file_creation_time(full_path)
195
- if not jsonl_cache_file.exists() and not json_cache_file.exists():
196
- git_time = get_git_first_commit_time(full_path)
197
- if git_time is not None:
198
- created_time = min(created_time, git_time)
199
- jsonl_dates_cache[rel_path] = {
200
- "created": created_time.isoformat()
201
- }
202
- project_updated = True
203
- except Exception as e:
204
- logging.error(f"Error processing file {file_path}: {e}")
205
-
206
- # 标记删除不再跟踪的文件
207
- files_to_remove = set(jsonl_dates_cache.keys()) - set(tracked_files)
208
- if files_to_remove:
209
- project_updated = True
210
- logging.info(f"Removing {len(files_to_remove)} untracked files from cache")
211
-
212
- # 如果有更新,写入JSONL缓存文件
213
- if project_updated or not jsonl_cache_file.exists():
214
- if write_jsonl_cache(jsonl_cache_file, jsonl_dates_cache, tracked_files):
215
- global_updated = True
216
- else:
217
- logging.info(f"No updates needed for {jsonl_cache_file}")
218
206
 
219
- except subprocess.CalledProcessError as e:
220
- logging.error(f"Failed to execute git command: {e}")
221
- continue
207
+ # 标记删除不再跟踪的文件
208
+ files_to_remove = set(jsonl_dates_cache.keys()) - set(tracked_files)
209
+ if files_to_remove:
210
+ project_updated = True
211
+ logging.info(f"Removing {len(files_to_remove)} untracked files from cache")
212
+
213
+ # 如果有更新,写入JSONL缓存文件
214
+ if project_updated or not jsonl_cache_file.exists():
215
+ if write_jsonl_cache(jsonl_cache_file, jsonl_dates_cache, tracked_files):
216
+ global_updated = True
217
+ else:
218
+ logging.info(f"No updates needed for {jsonl_cache_file}")
219
+ except subprocess.CalledProcessError as e:
220
+ logging.error(f"Failed to execute git command: {e}")
221
+ continue
222
+ except Exception as e:
223
+ logging.error(f"Error processing project directory {project_dir}: {e}")
224
+ continue
225
+
226
+ except Exception as e:
227
+ logging.error(f"Unexpected error in update_cache: {e}")
222
228
 
223
229
  return global_updated
224
230
 
225
231
 
226
232
  if __name__ == "__main__":
227
- try:
228
- update_cache()
229
- except Exception as e:
230
- logging.error(f"Hook execution failed: {e}")
231
- sys.exit(1)
233
+ update_cache()
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env python3
2
+
3
+ try:
4
+ from mkdocs_document_dates.cache_manager import update_cache
5
+ except Exception:
6
+ import sys
7
+ # 正常退出(0 状态码),不影响 git 的后续动作
8
+ sys.exit(0)
9
+
10
+ if __name__ == "__main__":
11
+ update_cache()
@@ -23,7 +23,7 @@ def check_python_version(interpreter):
23
23
  [interpreter, "-c", "import sys; print(sys.version_info >= (3, 7))"],
24
24
  capture_output=True, text=True, check=False
25
25
  )
26
- if result.returncode == 0 and result.stdout.strip() == 'True':
26
+ if result.returncode == 0 and result.stdout.strip().lower() == 'true':
27
27
  return True
28
28
  else:
29
29
  logging.warning(f"Low python version, requires python_requires >=3.7")
@@ -47,7 +47,7 @@ def check_git_available():
47
47
  try:
48
48
  subprocess.run(['git', '--version'], check=True, capture_output=True, encoding='utf-8')
49
49
  return True
50
- except (subprocess.CalledProcessError, FileNotFoundError):
50
+ except Exception:
51
51
  logging.warning("Git not detected, skip hooks installation")
52
52
  return False
53
53
 
@@ -95,7 +95,7 @@ def configure_git_hooks(hooks_dir):
95
95
  )
96
96
  logging.info(f"Git hooks successfully installed in: {hooks_dir}")
97
97
  return True
98
- except subprocess.CalledProcessError as e:
98
+ except Exception as e:
99
99
  logging.error(f"Failed to set git hooks path: {str(e)}")
100
100
  return False
101
101