mkdocs-document-dates 3.1__tar.gz → 3.1.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 (40) hide show
  1. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/PKG-INFO +10 -12
  2. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/README.md +9 -11
  3. mkdocs_document_dates-3.1.1/mkdocs_document_dates/__init__.py +6 -0
  4. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates/cache_manager.py +16 -0
  5. mkdocs_document_dates-3.1.1/mkdocs_document_dates/hooks_installer.py +126 -0
  6. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates/plugin.py +24 -22
  7. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates.egg-info/PKG-INFO +10 -12
  8. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/setup.py +28 -2
  9. mkdocs_document_dates-3.1/mkdocs_document_dates/__init__.py +0 -11
  10. mkdocs_document_dates-3.1/mkdocs_document_dates/hooks_installer.py +0 -128
  11. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/LICENSE +0 -0
  12. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates/hooks/pre-commit +0 -0
  13. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates/static/config/user.config.css +0 -0
  14. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates/static/config/user.config.js +0 -0
  15. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates/static/core/core.css +0 -0
  16. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates/static/core/core.js +0 -0
  17. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates/static/languages/ar.json +0 -0
  18. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates/static/languages/de.json +0 -0
  19. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates/static/languages/en.json +0 -0
  20. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates/static/languages/es.json +0 -0
  21. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates/static/languages/fr.json +0 -0
  22. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates/static/languages/ja.json +0 -0
  23. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates/static/languages/ko.json +0 -0
  24. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates/static/languages/ru.json +0 -0
  25. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates/static/languages/zh.json +0 -0
  26. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates/static/languages/zh_tw.json +0 -0
  27. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates/static/tippy/backdrop.css +0 -0
  28. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates/static/tippy/light.css +0 -0
  29. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates/static/tippy/material.css +0 -0
  30. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates/static/tippy/popper.min.js +0 -0
  31. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates/static/tippy/scale.css +0 -0
  32. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates/static/tippy/shift-away.css +0 -0
  33. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates/static/tippy/tippy.css +0 -0
  34. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates/static/tippy/tippy.umd.min.js +0 -0
  35. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates.egg-info/SOURCES.txt +0 -0
  36. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates.egg-info/dependency_links.txt +0 -0
  37. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates.egg-info/entry_points.txt +0 -0
  38. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates.egg-info/requires.txt +0 -0
  39. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/mkdocs_document_dates.egg-info/top_level.txt +0 -0
  40. {mkdocs_document_dates-3.1 → mkdocs_document_dates-3.1.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mkdocs-document-dates
3
- Version: 3.1
3
+ Version: 3.1.1
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
@@ -120,35 +120,33 @@ email: e-name@gmail.com
120
120
 
121
121
  ## Customization
122
122
 
123
- The plugin supports deep customization, such as icon style, font style, theme color, animation type, dividing line, etc. All of it can be customized by modifying the code in the corresponding file (I've already written the code and comments, you just need to turn on the switch and change the value, it's super easy):
123
+ The plugin supports deep customization, such as icon style, font style, theme color, animation type, dividing line, etc. All of it can be customized by modifying the code in the corresponding file (I've already written the code and comments, you just need to turn on the switch and change the value):
124
124
 
125
125
  - Style & Theme: `docs/assets/document_dates/user.config.css`
126
126
  - Properties & Animations: `docs/assets/document_dates/user.config.js`
127
127
  - Localized languages: `docs/assets/document_dates/languages/` , refer to the template file `en.json` for any additions or modifications
128
128
 
129
- Note: Due to the redesign of the configuration file update mechanism, the configuration file starting with document-dates.config in the previous version has been canceled and replaced by user.config
130
-
131
129
  ## Other Tips
132
130
 
133
131
  - 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:
134
- - `docs/.dates_cache.jsonl`, cache file (.json without the l is the old cache file and will be automatically migrated to .jsonl after any git commit)
135
- - `docs/.gitattributes`, configuration file (merge mechanism for cache file in case of multi-person collaboration)
136
- - 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
137
- - The installation of Git Hooks is automatically triggered when the plugin is installed
138
- - The above actions are fully automated without any manual intervention, applicable to any environment, and have been tested and validated in Git-less environments, CI/CD environments (e.g., GitHub Actions), one-person collaborations, multi-person collaborations, etc
132
+ - `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!
135
+
136
+ <br />
139
137
 
140
138
  ## Development Stories (Optional)
141
139
 
142
- A dispensable, insignificant little plug-in, friends who have nothing to do can take a look \^\_\^
140
+ A dispensable, insignificant little plug-in, friends who have time can take a look \^\_\^
143
141
 
144
142
  - **Origin**:
145
143
  - Because [mkdocs-git-revision-date-localized-plugin](https://github.com/timvink/mkdocs-git-revision-date-localized-plugin), a great project. When I used it at the end of 2024, I found that I couldn't use it locally because my mkdocs documentation was not included in git management, then I don't understand why not read the file system time, but to use the git time, and raised an issue to the author, but didn't get a reply for about a week (the author had a reply later, nice guy, I guess he was busy at the time), and then I thought, there is nothing to do during the Chinese New Year, and now AI is so hot, why not with the help of the AI try it out for myself, it was born, born in February 2025
146
144
  - **Iteration**:
147
145
  - After development, I understood why not use filesystem time, because files will be rebuilt when they go through git checkout or clone, resulting in the loss of original timestamp information, and there are many solutions:
148
146
  - Method 1: Use the last git commit time as the last update time, and the first git commit time as the creation (there is a margin of error, but it's acceptable), mkdocs-git-revision-date-localized-plugin does this
149
- - 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. Existing in the Front Matter is very reasonable and 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!
147
+ - 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!
150
148
  - **Difficulty**:
151
- 1. When to read and store raw 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!
149
+ 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!
152
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
153
151
  2. How can I ensure that a single cache file does not conflict when collaborating with multi-person?
154
152
  - My solution: use JSONL (JSON Lines) instead of JSON, and with the merge strategy 'merge=union'
@@ -97,35 +97,33 @@ email: e-name@gmail.com
97
97
 
98
98
  ## Customization
99
99
 
100
- The plugin supports deep customization, such as icon style, font style, theme color, animation type, dividing line, etc. All of it can be customized by modifying the code in the corresponding file (I've already written the code and comments, you just need to turn on the switch and change the value, it's super easy):
100
+ The plugin supports deep customization, such as icon style, font style, theme color, animation type, dividing line, etc. All of it can be customized by modifying the code in the corresponding file (I've already written the code and comments, you just need to turn on the switch and change the value):
101
101
 
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
105
 
106
- Note: Due to the redesign of the configuration file update mechanism, the configuration file starting with document-dates.config in the previous version has been canceled and replaced by user.config
107
-
108
106
  ## Other Tips
109
107
 
110
108
  - 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:
111
- - `docs/.dates_cache.jsonl`, cache file (.json without the l is the old cache file and will be automatically migrated to .jsonl after any git commit)
112
- - `docs/.gitattributes`, configuration file (merge mechanism for cache file in case of multi-person collaboration)
113
- - 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
114
- - The installation of Git Hooks is automatically triggered when the plugin is installed
115
- - The above actions are fully automated without any manual intervention, applicable to any environment, and have been tested and validated in Git-less environments, CI/CD environments (e.g., GitHub Actions), one-person collaborations, multi-person collaborations, etc
109
+ - `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!
112
+
113
+ <br />
116
114
 
117
115
  ## Development Stories (Optional)
118
116
 
119
- A dispensable, insignificant little plug-in, friends who have nothing to do can take a look \^\_\^
117
+ A dispensable, insignificant little plug-in, friends who have time can take a look \^\_\^
120
118
 
121
119
  - **Origin**:
122
120
  - Because [mkdocs-git-revision-date-localized-plugin](https://github.com/timvink/mkdocs-git-revision-date-localized-plugin), a great project. When I used it at the end of 2024, I found that I couldn't use it locally because my mkdocs documentation was not included in git management, then I don't understand why not read the file system time, but to use the git time, and raised an issue to the author, but didn't get a reply for about a week (the author had a reply later, nice guy, I guess he was busy at the time), and then I thought, there is nothing to do during the Chinese New Year, and now AI is so hot, why not with the help of the AI try it out for myself, it was born, born in February 2025
123
121
  - **Iteration**:
124
122
  - After development, I understood why not use filesystem time, because files will be rebuilt when they go through git checkout or clone, resulting in the loss of original timestamp information, and there are many solutions:
125
123
  - Method 1: Use the last git commit time as the last update time, and the first git commit time as the creation (there is a margin of error, but it's acceptable), mkdocs-git-revision-date-localized-plugin does this
126
- - 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. Existing in the Front Matter is very reasonable and 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!
124
+ - 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!
127
125
  - **Difficulty**:
128
- 1. When to read and store raw 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!
126
+ 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!
129
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
130
128
  2. How can I ensure that a single cache file does not conflict when collaborating with multi-person?
131
129
  - My solution: use JSONL (JSON Lines) instead of JSON, and with the merge strategy 'merge=union'
@@ -0,0 +1,6 @@
1
+ """MkDocs Document Dates Plugin."""
2
+
3
+ from .hooks_installer import install
4
+
5
+ # 在包被导入时自动执行 hooks 安装
6
+ install()
@@ -53,6 +53,18 @@ def get_file_creation_time(file_path):
53
53
  logging.error(f"Failed to get file creation time for {file_path}: {e}")
54
54
  return datetime.now()
55
55
 
56
+ def get_git_first_commit_time(file_path):
57
+ try:
58
+ # git log --reverse --format="%aI" --date=iso -- {file_path} | head -n 1
59
+ result = subprocess.run(['git', 'log', '--reverse', '--format=%aI', '--', file_path], capture_output=True, text=True)
60
+ if result.returncode == 0:
61
+ commits = result.stdout.strip().split('\n')
62
+ if commits and commits[0]:
63
+ return datetime.fromisoformat(commits[0]).replace(tzinfo=None)
64
+ except Exception as e:
65
+ logging.info(f"Error getting git first commit time for {file_path}: {e}")
66
+ return None
67
+
56
68
  def setup_gitattributes(docs_dir):
57
69
  gitattributes_path = docs_dir / '.gitattributes'
58
70
  union_config_line = ".dates_cache.jsonl merge=union"
@@ -180,6 +192,10 @@ def update_cache():
180
192
  project_updated = True
181
193
  elif full_path.exists():
182
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)
183
199
  jsonl_dates_cache[rel_path] = {
184
200
  "created": created_time.isoformat()
185
201
  }
@@ -0,0 +1,126 @@
1
+ import os
2
+ import sys
3
+ import logging
4
+ import subprocess
5
+ from pathlib import Path
6
+ import platform
7
+
8
+ # 配置日志等级 (INFO WARNING ERROR)
9
+ logging.basicConfig(
10
+ level=logging.WARNING,
11
+ format='%(levelname)s: %(message)s'
12
+ )
13
+
14
+ def get_config_dir():
15
+ if platform.system().lower().startswith('win'):
16
+ return Path(os.getenv('APPDATA', str(Path.home() / 'AppData' / 'Roaming')))
17
+ else:
18
+ return Path.home() / '.config'
19
+
20
+ def check_python_version(interpreter):
21
+ try:
22
+ result = subprocess.run(
23
+ [interpreter, "-c", "import sys; print(sys.version_info >= (3, 7))"],
24
+ capture_output=True, text=True, check=False
25
+ )
26
+ if result.returncode == 0 and result.stdout.strip() == 'True':
27
+ return True
28
+ else:
29
+ logging.warning(f"Low python version, requires python_requires >=3.7")
30
+ return False
31
+ except Exception as e:
32
+ logging.debug(f"Failed to check {interpreter}: {str(e)}")
33
+ return False
34
+
35
+ def detect_python_interpreter():
36
+ # 检查可能的Python解释器
37
+ python_interpreters = ['python3', 'python']
38
+
39
+ for interpreter in python_interpreters:
40
+ if check_python_version(interpreter):
41
+ return f'#!/usr/bin/env {interpreter}'
42
+
43
+ # 如果都失败了,使用当前运行的Python解释器
44
+ return f'#!{sys.executable}'
45
+
46
+ def check_git_available():
47
+ try:
48
+ subprocess.run(['git', '--version'], check=True, capture_output=True, encoding='utf-8')
49
+ return True
50
+ except (subprocess.CalledProcessError, FileNotFoundError):
51
+ logging.warning("Git not detected, skip hooks installation")
52
+ return False
53
+
54
+ def setup_hooks_directory():
55
+ config_dir = get_config_dir() / 'mkdocs-document-dates' / 'hooks'
56
+ try:
57
+ config_dir.mkdir(parents=True, exist_ok=True)
58
+ os.chmod(config_dir, 0o755)
59
+ return config_dir
60
+ except PermissionError:
61
+ logging.error(f"No permission to create directory: {config_dir}")
62
+ return None
63
+ except Exception as e:
64
+ logging.error(f"Failed to create directory {config_dir}: {str(e)}")
65
+ return None
66
+
67
+ def install_hook_file(source_hook, target_dir):
68
+ target_hook_path = target_dir / source_hook.name
69
+ try:
70
+ # 读取并更新hook文件内容
71
+ with open(source_hook, 'r', encoding='utf-8') as f_in:
72
+ content = f_in.read()
73
+
74
+ # 更新shebang行
75
+ shebang = detect_python_interpreter()
76
+ if content.startswith('#!'):
77
+ content = shebang + os.linesep + content[content.find('\n'):]
78
+ else:
79
+ content = shebang + os.linesep + content
80
+
81
+ # 写入并设置权限
82
+ with open(target_hook_path, 'w', encoding='utf-8') as f_out:
83
+ f_out.write(content)
84
+ os.chmod(target_hook_path, 0o755)
85
+ return True
86
+ except Exception as e:
87
+ logging.error(f"Failed to create hook file {target_hook_path}: {str(e)}")
88
+ return False
89
+
90
+ def configure_git_hooks(hooks_dir):
91
+ try:
92
+ subprocess.run(
93
+ ['git', 'config', '--global', 'core.hooksPath', str(hooks_dir)],
94
+ check=True, capture_output=True, encoding='utf-8'
95
+ )
96
+ logging.info(f"Git hooks successfully installed in: {hooks_dir}")
97
+ return True
98
+ except subprocess.CalledProcessError as e:
99
+ logging.error(f"Failed to set git hooks path: {str(e)}")
100
+ return False
101
+
102
+ def install():
103
+ try:
104
+ # 检查git是否可用
105
+ if not check_git_available():
106
+ return False
107
+
108
+ # 创建hooks目录
109
+ hooks_dir = setup_hooks_directory()
110
+ if not hooks_dir:
111
+ return False
112
+
113
+ # 安装hook文件
114
+ source_hook = Path(__file__).parent / 'hooks' / 'pre-commit'
115
+ if not install_hook_file(source_hook, hooks_dir):
116
+ return False
117
+
118
+ # 配置git hooks路径
119
+ return configure_git_hooks(hooks_dir)
120
+
121
+ except Exception as e:
122
+ logging.error(f"Unexpected error during hooks installation: {str(e)}")
123
+ return False
124
+
125
+ if __name__ == '__main__':
126
+ install()
@@ -56,8 +56,18 @@ class DocumentDatesPlugin(BasePlugin):
56
56
  super().__init__()
57
57
  self.translations = {}
58
58
  self.dates_cache = {}
59
+ self.is_git_repo = False
59
60
 
60
61
  def on_config(self, config):
62
+
63
+ # 检查是否为 Git 仓库
64
+ try:
65
+ check_git = subprocess.run(['git', 'rev-parse', '--is-inside-work-tree'], capture_output=True, text=True)
66
+ if check_git.returncode == 0:
67
+ self.is_git_repo = True
68
+ except subprocess.CalledProcessError as e:
69
+ logging.info(f"Not a Git repository: {str(e)}")
70
+
61
71
  docs_dir_path = Path(config['docs_dir'])
62
72
 
63
73
  # 加载 json 语言文件
@@ -265,19 +275,16 @@ class DocumentDatesPlugin(BasePlugin):
265
275
  return None
266
276
 
267
277
  def _get_git_first_commit_time(self, file_path):
268
- try:
269
- check_git = subprocess.run(['git', 'rev-parse', '--is-inside-work-tree'],
270
- capture_output=True, text=True)
271
- if check_git.returncode == 0:
272
- result = subprocess.run(
273
- ['git', 'log', '--reverse', '--format=%aI', '--', file_path],
274
- capture_output=True, text=True)
278
+ if self.is_git_repo:
279
+ try:
280
+ # git log --reverse --format="%aI" --date=iso -- {file_path} | head -n 1
281
+ result = subprocess.run(['git', 'log', '--reverse', '--format=%aI', '--', file_path], capture_output=True, text=True)
275
282
  if result.returncode == 0:
276
283
  commits = result.stdout.strip().split('\n')
277
284
  if commits and commits[0]:
278
285
  return datetime.fromisoformat(commits[0]).replace(tzinfo=None)
279
- except Exception as e:
280
- logging.info(f"Error getting git first commit time for {file_path}: {e}")
286
+ except Exception as e:
287
+ logging.info(f"Error getting git first commit time for {file_path}: {e}")
281
288
  return None
282
289
 
283
290
  def _get_file_creation_time(self, file_path, rel_path):
@@ -310,20 +317,18 @@ class DocumentDatesPlugin(BasePlugin):
310
317
  def _get_file_modification_time(self, file_path):
311
318
  """
312
319
  # 从git获取最后修改时间
313
- try:
314
- # 检查是否是git仓库
315
- check_git = subprocess.run(['git', 'rev-parse', '--is-inside-work-tree'],
316
- capture_output=True, text=True)
317
- if check_git.returncode == 0:
320
+ if self.is_git_repo:
321
+ try:
318
322
  # 获取文件最后修改时间
319
323
  cmd = f'git log -1 --format="%aI" --date=iso -- "{file_path}"'
320
324
  process = subprocess.run(cmd, shell=True, capture_output=True, text=True)
321
325
  if process.returncode == 0 and process.stdout.strip():
322
326
  git_time = process.stdout.strip()
323
327
  return datetime.fromisoformat(git_time).replace(tzinfo=None)
324
- except Exception as e:
325
- logging.warning(f"Failed to get git modification time: {str(e)}")
328
+ except Exception as e:
329
+ logging.warning(f"Failed to get git modification time: {str(e)}")
326
330
  """
331
+
327
332
  # 从文件系统获取最后修改时间
328
333
  stat = os.stat(file_path)
329
334
  return datetime.fromtimestamp(stat.st_mtime)
@@ -366,13 +371,10 @@ class DocumentDatesPlugin(BasePlugin):
366
371
  return None
367
372
 
368
373
  def _get_git_authors(self, file_path: str) -> Union[Author, List[Author], None]:
374
+ if not self.is_git_repo:
375
+ return None
376
+
369
377
  try:
370
- # 先检查是否是 Git 仓库
371
- check_git = subprocess.run(['git', 'rev-parse', '--is-inside-work-tree'],
372
- capture_output=True, text=True)
373
- if check_git.returncode != 0:
374
- return None
375
-
376
378
  # # 检查文件是否在 Git 中
377
379
  # check_file = subprocess.run(f'git ls-files --error-unmatch {file_path}',
378
380
  # shell=True, capture_output=True, text=True)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mkdocs-document-dates
3
- Version: 3.1
3
+ Version: 3.1.1
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
@@ -120,35 +120,33 @@ email: e-name@gmail.com
120
120
 
121
121
  ## Customization
122
122
 
123
- The plugin supports deep customization, such as icon style, font style, theme color, animation type, dividing line, etc. All of it can be customized by modifying the code in the corresponding file (I've already written the code and comments, you just need to turn on the switch and change the value, it's super easy):
123
+ The plugin supports deep customization, such as icon style, font style, theme color, animation type, dividing line, etc. All of it can be customized by modifying the code in the corresponding file (I've already written the code and comments, you just need to turn on the switch and change the value):
124
124
 
125
125
  - Style & Theme: `docs/assets/document_dates/user.config.css`
126
126
  - Properties & Animations: `docs/assets/document_dates/user.config.js`
127
127
  - Localized languages: `docs/assets/document_dates/languages/` , refer to the template file `en.json` for any additions or modifications
128
128
 
129
- Note: Due to the redesign of the configuration file update mechanism, the configuration file starting with document-dates.config in the previous version has been canceled and replaced by user.config
130
-
131
129
  ## Other Tips
132
130
 
133
131
  - 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:
134
- - `docs/.dates_cache.jsonl`, cache file (.json without the l is the old cache file and will be automatically migrated to .jsonl after any git commit)
135
- - `docs/.gitattributes`, configuration file (merge mechanism for cache file in case of multi-person collaboration)
136
- - 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
137
- - The installation of Git Hooks is automatically triggered when the plugin is installed
138
- - The above actions are fully automated without any manual intervention, applicable to any environment, and have been tested and validated in Git-less environments, CI/CD environments (e.g., GitHub Actions), one-person collaborations, multi-person collaborations, etc
132
+ - `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!
135
+
136
+ <br />
139
137
 
140
138
  ## Development Stories (Optional)
141
139
 
142
- A dispensable, insignificant little plug-in, friends who have nothing to do can take a look \^\_\^
140
+ A dispensable, insignificant little plug-in, friends who have time can take a look \^\_\^
143
141
 
144
142
  - **Origin**:
145
143
  - Because [mkdocs-git-revision-date-localized-plugin](https://github.com/timvink/mkdocs-git-revision-date-localized-plugin), a great project. When I used it at the end of 2024, I found that I couldn't use it locally because my mkdocs documentation was not included in git management, then I don't understand why not read the file system time, but to use the git time, and raised an issue to the author, but didn't get a reply for about a week (the author had a reply later, nice guy, I guess he was busy at the time), and then I thought, there is nothing to do during the Chinese New Year, and now AI is so hot, why not with the help of the AI try it out for myself, it was born, born in February 2025
146
144
  - **Iteration**:
147
145
  - After development, I understood why not use filesystem time, because files will be rebuilt when they go through git checkout or clone, resulting in the loss of original timestamp information, and there are many solutions:
148
146
  - Method 1: Use the last git commit time as the last update time, and the first git commit time as the creation (there is a margin of error, but it's acceptable), mkdocs-git-revision-date-localized-plugin does this
149
- - 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. Existing in the Front Matter is very reasonable and 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!
147
+ - 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!
150
148
  - **Difficulty**:
151
- 1. When to read and store raw 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!
149
+ 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!
152
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
153
151
  2. How can I ensure that a single cache file does not conflict when collaborating with multi-person?
154
152
  - My solution: use JSONL (JSON Lines) instead of JSON, and with the merge strategy 'merge=union'
@@ -1,5 +1,28 @@
1
1
  from setuptools import setup, find_packages
2
- import mkdocs_document_dates
2
+ from setuptools.command.install import install
3
+ import atexit
4
+
5
+ def trigger_hook_install():
6
+ try:
7
+ import os
8
+ import sys
9
+ # 动态添加包路径确保导入成功
10
+ package_path = os.path.abspath(os.path.dirname(__file__))
11
+ if package_path not in sys.path:
12
+ sys.path.insert(0, package_path)
13
+
14
+ # from mkdocs_document_dates.hooks_installer import install
15
+ # install()
16
+ # import mkdocs_document_dates
17
+ __import__('mkdocs_document_dates')
18
+ except Exception as e:
19
+ print(f"Warning: Failed to install Git hooks: {e}")
20
+
21
+ class CustomInstallCommand(install):
22
+ def run(self):
23
+ # 注册在安装结束时执行 trigger_hook_install
24
+ atexit.register(trigger_hook_install)
25
+ install.run(self)
3
26
 
4
27
  try:
5
28
  with open("README.md", "r", encoding="utf-8") as fh:
@@ -7,7 +30,7 @@ try:
7
30
  except FileNotFoundError:
8
31
  long_description = "An easy-to-use, lightweight MkDocs plugin for displaying the exact creation time, last modification time and author info of markdown documents."
9
32
 
10
- VERSION = '3.1'
33
+ VERSION = '3.1.1'
11
34
 
12
35
  setup(
13
36
  name="mkdocs-document-dates",
@@ -26,6 +49,9 @@ setup(
26
49
  "License :: OSI Approved :: MIT License",
27
50
  "Operating System :: OS Independent",
28
51
  ],
52
+ cmdclass={
53
+ 'install': CustomInstallCommand,
54
+ },
29
55
  entry_points={
30
56
  'mkdocs.plugins': [
31
57
  'document-dates = mkdocs_document_dates.plugin:DocumentDatesPlugin',
@@ -1,11 +0,0 @@
1
- """MkDocs Document Dates Plugin."""
2
-
3
- from .hooks_installer import install
4
-
5
- # 在包被导入时自动执行 hooks 安装
6
- try:
7
- result = install()
8
- if not result:
9
- print("Tip: Git hooks installation was skipped (probably because Git was not detected or not in the Git repository)")
10
- except Exception as e:
11
- print(f"Warning: Git hooks installation failed: {e}")
@@ -1,128 +0,0 @@
1
- import os
2
- import sys
3
- import logging
4
- import subprocess
5
- from pathlib import Path
6
- import platform
7
-
8
- # 配置日志等级 (INFO WARNING ERROR)
9
- logging.basicConfig(
10
- level=logging.WARNING,
11
- format='%(levelname)s: %(message)s'
12
- )
13
-
14
- def get_config_dir():
15
- if platform.system().lower().startswith('win'):
16
- return Path(os.getenv('APPDATA', str(Path.home() / 'AppData' / 'Roaming')))
17
- else:
18
- return Path.home() / '.config'
19
-
20
- def check_python_version(interpreter):
21
- try:
22
- result = subprocess.run(
23
- [interpreter, "-c", "import sys; print(sys.version_info >= (3, 7))"],
24
- capture_output=True, text=True, check=False
25
- )
26
- if result.returncode == 0 and result.stdout.strip() == 'True':
27
- return True
28
- else:
29
- logging.warning(f"Low python version, requires python_requires >=3.7")
30
- return False
31
- except Exception as e:
32
- logging.debug(f"Failed to check {interpreter}: {str(e)}")
33
- return False
34
-
35
- def detect_python_interpreter():
36
- # 检查可能的Python解释器
37
- python_interpreters = ['python3', 'python']
38
-
39
- for interpreter in python_interpreters:
40
- if check_python_version(interpreter):
41
- return f'#!/usr/bin/env {interpreter}'
42
-
43
- # 如果都失败了,使用当前运行的Python解释器
44
- return f'#!{sys.executable}'
45
-
46
- def install():
47
- try:
48
- # 检查 git 是否可用
49
- try:
50
- subprocess.run(['git', '--version'], check=True, capture_output=True, encoding='utf-8')
51
- except (subprocess.CalledProcessError, FileNotFoundError):
52
- logging.warning("Git not detected, skip hooks installation")
53
- return False
54
-
55
- # 准备配置目录
56
- config_dir = get_config_dir() / 'mkdocs-document-dates' / 'hooks'
57
- try:
58
- config_dir.mkdir(parents=True, exist_ok=True)
59
- except PermissionError:
60
- logging.error(f"No permission to create directory: {config_dir}")
61
- return False
62
- except Exception as e:
63
- logging.error(f"Failed to create directory {config_dir}: {str(e)}")
64
- return False
65
-
66
- # 检测Python解释器并获取合适的shebang行
67
- shebang = detect_python_interpreter()
68
- logging.info(f"Using shebang: {shebang}")
69
-
70
- # 安装钩子文件
71
- hooks_installed = False
72
- source_hooks_dir = Path(__file__).parent / 'hooks'
73
- for hook_file in source_hooks_dir.glob('*'):
74
- if hook_file.is_file() and not hook_file.name.startswith('.'):
75
- target_hook_path = config_dir / hook_file.name
76
- try:
77
- # 读取源文件内容
78
- with open(hook_file, 'r', encoding='utf-8') as f_in:
79
- content = f_in.read()
80
-
81
- # 修改shebang行
82
- if content.startswith('#!'):
83
- content = shebang + os.linesep + content[content.find('\n'):]
84
- else:
85
- content = shebang + os.linesep + content
86
-
87
- # 直接写入目标文件
88
- with open(target_hook_path, 'w', encoding='utf-8') as f_out:
89
- f_out.write(content)
90
-
91
- # 设置执行权限
92
- os.chmod(target_hook_path, 0o755)
93
- hooks_installed = True
94
- logging.info(f"Created hook with custom shebang: {hook_file.name}")
95
- except Exception as e:
96
- logging.error(f"Failed to create file {target_hook_path}: {str(e)}")
97
- return False
98
-
99
- if not hooks_installed:
100
- logging.warning("No hook files found, the hooks installation failed")
101
- return False
102
-
103
- # 设置目录权限
104
- try:
105
- os.chmod(config_dir, 0o755)
106
- except OSError as e:
107
- logging.warning(f"Failed to set directory permissions: {str(e)}")
108
-
109
- # 配置全局 git hooks 路径
110
- try:
111
- subprocess.run(
112
- ['git', 'config', '--global', 'core.hooksPath', str(config_dir)],
113
- check=True,
114
- capture_output=True,
115
- encoding='utf-8'
116
- )
117
- logging.info(f"Git hooks successfully installed in: {config_dir}")
118
- return True
119
- except subprocess.CalledProcessError as e:
120
- logging.error(f"Failed to set git hooks path: {str(e)}")
121
- return False
122
-
123
- except Exception as e:
124
- logging.error(f"Unexpected error during hooks installation: {str(e)}")
125
- return False
126
-
127
- if __name__ == '__main__':
128
- install()