mkdocs-document-dates 3.1.6__tar.gz → 3.2.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 (47) hide show
  1. mkdocs_document_dates-3.2.1/LICENSE +22 -0
  2. {mkdocs_document_dates-3.1.6/mkdocs_document_dates.egg-info → mkdocs_document_dates-3.2.1}/PKG-INFO +11 -11
  3. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/README.md +9 -8
  4. mkdocs_document_dates-3.2.1/mkdocs_document_dates/cache_manager.py +122 -0
  5. mkdocs_document_dates-3.2.1/mkdocs_document_dates/hooks_installer.py +109 -0
  6. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/plugin.py +96 -113
  7. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/config/user.config.css +6 -7
  8. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/config/user.config.js +13 -5
  9. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/core/core.css +15 -8
  10. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/core/core.js +58 -10
  11. mkdocs_document_dates-3.2.1/mkdocs_document_dates/static/core/timeago-load.js +18 -0
  12. mkdocs_document_dates-3.2.1/mkdocs_document_dates/utils.py +122 -0
  13. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1/mkdocs_document_dates.egg-info}/PKG-INFO +11 -11
  14. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates.egg-info/SOURCES.txt +1 -0
  15. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/setup.py +3 -4
  16. mkdocs_document_dates-3.1.6/LICENSE +0 -11
  17. mkdocs_document_dates-3.1.6/mkdocs_document_dates/cache_manager.py +0 -226
  18. mkdocs_document_dates-3.1.6/mkdocs_document_dates/hooks_installer.py +0 -114
  19. mkdocs_document_dates-3.1.6/mkdocs_document_dates/static/core/timeago-load.js +0 -5
  20. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/MANIFEST.in +0 -0
  21. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/__init__.py +0 -0
  22. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/hooks/pre-commit +0 -0
  23. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/core/timeago.full.min.js +0 -0
  24. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/core/timeago.min.js +0 -0
  25. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/languages/ar.json +0 -0
  26. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/languages/de.json +0 -0
  27. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/languages/en.json +0 -0
  28. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/languages/es.json +0 -0
  29. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/languages/fr.json +0 -0
  30. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/languages/ja.json +0 -0
  31. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/languages/ko.json +0 -0
  32. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/languages/ru.json +0 -0
  33. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/languages/zh.json +0 -0
  34. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/languages/zh_TW.json +0 -0
  35. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/tippy/backdrop.css +0 -0
  36. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/tippy/light.css +0 -0
  37. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/tippy/material.css +0 -0
  38. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/tippy/popper.min.js +0 -0
  39. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/tippy/scale.css +0 -0
  40. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/tippy/shift-away.css +0 -0
  41. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/tippy/tippy.css +0 -0
  42. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/tippy/tippy.umd.min.js +0 -0
  43. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates.egg-info/dependency_links.txt +0 -0
  44. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates.egg-info/entry_points.txt +0 -0
  45. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates.egg-info/requires.txt +0 -0
  46. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates.egg-info/top_level.txt +0 -0
  47. {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/setup.cfg +0 -0
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Aaron Wang
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -1,13 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mkdocs-document-dates
3
- Version: 3.1.6
4
- Summary: An easy-to-use, lightweight MkDocs plugin for displaying the exact creation time, last modification time and author info of markdown documents.
3
+ Version: 3.2.1
4
+ Summary: A new generation MkDocs plugin for displaying exact meta-info of documents, such as creation time, last update time, authors, email, etc.
5
5
  Home-page: https://github.com/jaywhj/mkdocs-document-dates
6
6
  Author: Aaron Wang
7
7
  Author-email: aaronwqt@gmail.com
8
8
  License: MIT
9
9
  Classifier: Programming Language :: Python :: 3
10
- Classifier: License :: OSI Approved :: MIT License
11
10
  Classifier: Operating System :: OS Independent
12
11
  Requires-Python: >=3.7
13
12
  Description-Content-Type: text/markdown
@@ -31,7 +30,7 @@ English | [简体中文](README_zh.md)
31
30
 
32
31
 
33
32
 
34
- An easy-to-use, lightweight MkDocs plugin for displaying the <mark>exact</mark> creation time, last modification time and author info of markdown documents.
33
+ A new generation MkDocs plugin for displaying exact meta-info of documents, such as **creation time, last update time, authors, email**, etc.
35
34
 
36
35
  ## Features
37
36
 
@@ -44,6 +43,7 @@ An easy-to-use, lightweight MkDocs plugin for displaying the <mark>exact</mark>
44
43
  - Intelligent repositioning to always float optimally in view
45
44
  - Supports automatic theme switching following Material's light/dark color scheme
46
45
  - Multi-language support, cross-platform support (Windows, macOS, Linux)
46
+ - Ultimate build efficiency O(1), typically less than 0.2 seconds, regardless of whether the number of documents is 1,000 or 10,000
47
47
 
48
48
  ## Showcases
49
49
 
@@ -76,7 +76,7 @@ plugins:
76
76
  time_format: '%H:%M:%S' # Time format strings (valid only if type=datetime)
77
77
  exclude: # List of excluded files
78
78
  - temp.md # Exclude specific file
79
- - private/* # Exclude all files in private directory, including subdirectories
79
+ - private/* # Exclude all files in private folder, including subfolders
80
80
  show_author: true # Show author or not, default: true
81
81
  ```
82
82
 
@@ -84,7 +84,7 @@ plugins:
84
84
 
85
85
  The plugin will automatically get the exact time of the document, will automatically cache the creation time, but of course, you can also specify it manually in `Front Matter`
86
86
 
87
- Priority order: `Front Matter` > `Cache Files` > `File System Timestamps`
87
+ Priority order: `Front Matter` > `File System Timestamps(Cached)` > `Git Timestamps`
88
88
 
89
89
  ```yaml
90
90
  ---
@@ -102,7 +102,7 @@ modified: 2025-02-23
102
102
 
103
103
  The plugin will automatically get the author of the document, will parse the email and make a link, also you can specify it manually in `Front Matter`
104
104
 
105
- Priority order: `Front Matter` > `Git Author` > `site_author (mkdocs.yml)` > `PC Username`
105
+ Priority order: `Front Matter` > `Git Author` > `site_author(mkdocs.yml)` > `PC Username`
106
106
 
107
107
  ```yaml
108
108
  ---
@@ -118,9 +118,9 @@ email: e-name@gmail.com
118
118
 
119
119
  ## Customization
120
120
 
121
- The plugin supports deep customization, such as **icon style, font style, theme color, animation type, dividing line**, etc. Everything is customizable (I've already written the code, you just need to turn on the uncomment switch):
121
+ The plugin supports deep customization, such as **icon style, theme color, font, animation, dividing line**, etc. Everything is customizable (Find the file below and turn on the uncomment switch):
122
122
 
123
- | Function: | Location |
123
+ | Category: | Location: |
124
124
  | :----------------------: | ---------------------------------------- |
125
125
  | **Style & Theme** | `docs/assets/document_dates/user.config.css` |
126
126
  | **Properties & Functions** | `docs/assets/document_dates/user.config.js` |
@@ -129,7 +129,7 @@ The plugin supports deep customization, such as **icon style, font style, theme
129
129
  **Tip**: when `type: timeago` is set, timeago.js is enabled to render dynamic time, `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):
130
130
 
131
131
  - 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
132
- - In `mkdocs.yml`, add the following two lines to configure the full version of `timeago.full.min.js` to load all languages at once
132
+ - In `mkdocs.yml`, configure the full version of `timeago.full.min.js` to load all languages at once
133
133
  ```yaml
134
134
  extra_javascript:
135
135
  - assets/document_dates/core/timeago.full.min.js
@@ -147,7 +147,7 @@ The plugin supports deep customization, such as **icon style, font style, theme
147
147
  ![06-change-theme](mkdocs_document_dates/demo_images/06-change-theme.png)
148
148
  ![08-pop-up-from-bottom](mkdocs_document_dates/demo_images/08-pop-up-from-bottom.png)
149
149
 
150
- ## Used in templates
150
+ ## Template Variables
151
151
 
152
152
  You can access the meta-info of a document in a template using the following variables:
153
153
 
@@ -4,7 +4,7 @@ English | [简体中文](README_zh.md)
4
4
 
5
5
 
6
6
 
7
- An easy-to-use, lightweight MkDocs plugin for displaying the <mark>exact</mark> creation time, last modification time and author info of markdown documents.
7
+ A new generation MkDocs plugin for displaying exact meta-info of documents, such as **creation time, last update time, authors, email**, etc.
8
8
 
9
9
  ## Features
10
10
 
@@ -17,6 +17,7 @@ An easy-to-use, lightweight MkDocs plugin for displaying the <mark>exact</mark>
17
17
  - Intelligent repositioning to always float optimally in view
18
18
  - Supports automatic theme switching following Material's light/dark color scheme
19
19
  - Multi-language support, cross-platform support (Windows, macOS, Linux)
20
+ - Ultimate build efficiency O(1), typically less than 0.2 seconds, regardless of whether the number of documents is 1,000 or 10,000
20
21
 
21
22
  ## Showcases
22
23
 
@@ -49,7 +50,7 @@ plugins:
49
50
  time_format: '%H:%M:%S' # Time format strings (valid only if type=datetime)
50
51
  exclude: # List of excluded files
51
52
  - temp.md # Exclude specific file
52
- - private/* # Exclude all files in private directory, including subdirectories
53
+ - private/* # Exclude all files in private folder, including subfolders
53
54
  show_author: true # Show author or not, default: true
54
55
  ```
55
56
 
@@ -57,7 +58,7 @@ plugins:
57
58
 
58
59
  The plugin will automatically get the exact time of the document, will automatically cache the creation time, but of course, you can also specify it manually in `Front Matter`
59
60
 
60
- Priority order: `Front Matter` > `Cache Files` > `File System Timestamps`
61
+ Priority order: `Front Matter` > `File System Timestamps(Cached)` > `Git Timestamps`
61
62
 
62
63
  ```yaml
63
64
  ---
@@ -75,7 +76,7 @@ modified: 2025-02-23
75
76
 
76
77
  The plugin will automatically get the author of the document, will parse the email and make a link, also you can specify it manually in `Front Matter`
77
78
 
78
- Priority order: `Front Matter` > `Git Author` > `site_author (mkdocs.yml)` > `PC Username`
79
+ Priority order: `Front Matter` > `Git Author` > `site_author(mkdocs.yml)` > `PC Username`
79
80
 
80
81
  ```yaml
81
82
  ---
@@ -91,9 +92,9 @@ email: e-name@gmail.com
91
92
 
92
93
  ## Customization
93
94
 
94
- The plugin supports deep customization, such as **icon style, font style, theme color, animation type, dividing line**, etc. Everything is customizable (I've already written the code, you just need to turn on the uncomment switch):
95
+ The plugin supports deep customization, such as **icon style, theme color, font, animation, dividing line**, etc. Everything is customizable (Find the file below and turn on the uncomment switch):
95
96
 
96
- | Function: | Location |
97
+ | Category: | Location: |
97
98
  | :----------------------: | ---------------------------------------- |
98
99
  | **Style & Theme** | `docs/assets/document_dates/user.config.css` |
99
100
  | **Properties & Functions** | `docs/assets/document_dates/user.config.js` |
@@ -102,7 +103,7 @@ The plugin supports deep customization, such as **icon style, font style, theme
102
103
  **Tip**: when `type: timeago` is set, timeago.js is enabled to render dynamic time, `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):
103
104
 
104
105
  - 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
105
- - In `mkdocs.yml`, add the following two lines to configure the full version of `timeago.full.min.js` to load all languages at once
106
+ - In `mkdocs.yml`, configure the full version of `timeago.full.min.js` to load all languages at once
106
107
  ```yaml
107
108
  extra_javascript:
108
109
  - assets/document_dates/core/timeago.full.min.js
@@ -120,7 +121,7 @@ The plugin supports deep customization, such as **icon style, font style, theme
120
121
  ![06-change-theme](mkdocs_document_dates/demo_images/06-change-theme.png)
121
122
  ![08-pop-up-from-bottom](mkdocs_document_dates/demo_images/08-pop-up-from-bottom.png)
122
123
 
123
- ## Used in templates
124
+ ## Template Variables
124
125
 
125
126
  You can access the meta-info of a document in a template using the following variables:
126
127
 
@@ -0,0 +1,122 @@
1
+ import logging
2
+ import subprocess
3
+ from pathlib import Path
4
+ from .utils import read_json_cache, read_jsonl_cache, write_jsonl_cache, get_file_creation_time
5
+
6
+ logger = logging.getLogger("mkdocs.plugins.document_dates")
7
+ logger.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, CRITICAL
8
+
9
+ def find_mkdocs_projects():
10
+ projects = []
11
+ try:
12
+ git_root = Path(subprocess.check_output(
13
+ ['git', 'rev-parse', '--show-toplevel'],
14
+ text=True, encoding='utf-8'
15
+ ).strip())
16
+
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)
21
+
22
+ if not projects:
23
+ logger.warning("No MkDocs projects found in the repository")
24
+ except subprocess.CalledProcessError as e:
25
+ logger.error(f"Failed to find the Git repository root: {e}")
26
+ except Exception as e:
27
+ logger.error(f"Unexpected error while searching for MkDocs projects: {e}")
28
+
29
+ return projects
30
+
31
+ def setup_gitattributes(docs_dir: Path):
32
+ try:
33
+ gitattributes_path = docs_dir / '.gitattributes'
34
+ union_merge_line = ".dates_cache.jsonl merge=union"
35
+ # custom_merge_line = ".dates_cache.json merge=custom_json_merge"
36
+ content = gitattributes_path.read_text(encoding='utf-8') if gitattributes_path.exists() else ""
37
+ if union_merge_line not in content:
38
+ if content and not content.endswith('\n'):
39
+ content += '\n'
40
+ content += f"{union_merge_line}\n"
41
+ gitattributes_path.write_text(content, encoding='utf-8')
42
+ subprocess.run(["git", "add", str(gitattributes_path)], check=True)
43
+ logger.info(f"Updated .gitattributes file: {gitattributes_path}")
44
+ return True
45
+ except (IOError, OSError) as e:
46
+ logger.error(f"Failed to read/write .gitattributes file: {e}")
47
+ except Exception as e:
48
+ logger.error(f"Failed to add .gitattributes to git: {e}")
49
+ return False
50
+
51
+ def update_cache():
52
+ global_updated = False
53
+
54
+ for project_dir in find_mkdocs_projects():
55
+ try:
56
+ project_updated = False
57
+
58
+ docs_dir = project_dir / 'docs'
59
+ if not docs_dir.exists():
60
+ logger.warning(f"Document directory does not exist: {docs_dir}")
61
+ continue
62
+
63
+ # 设置.gitattributes文件
64
+ global_updated = setup_gitattributes(docs_dir)
65
+
66
+ # 获取docs目录下已跟踪(tracked)的markdown文件
67
+ cmd = ["git", "ls-files", "*.md"]
68
+ result = subprocess.run(cmd, cwd=docs_dir, capture_output=True, text=True)
69
+ tracked_files = result.stdout.splitlines() if result.stdout else []
70
+
71
+ if not tracked_files:
72
+ logger.info(f"No tracked markdown files found in {docs_dir}")
73
+ continue
74
+
75
+ # 读取旧的JSON缓存文件(如果存在)
76
+ json_cache_file = docs_dir / '.dates_cache.json'
77
+ json_dates_cache = read_json_cache(json_cache_file)
78
+
79
+ # 读取新的JSONL缓存文件(如果存在)
80
+ jsonl_cache_file = docs_dir / '.dates_cache.jsonl'
81
+ jsonl_dates_cache = read_jsonl_cache(jsonl_cache_file)
82
+
83
+ # 根据 git已跟踪的文件来更新
84
+ for rel_path in tracked_files:
85
+ try:
86
+ # 如果文件已在JSONL缓存中,跳过
87
+ if rel_path in jsonl_dates_cache:
88
+ continue
89
+
90
+ full_path = docs_dir / rel_path
91
+ # 处理新文件或迁移旧JSON缓存
92
+ if rel_path in json_dates_cache:
93
+ jsonl_dates_cache[rel_path] = json_dates_cache[rel_path]
94
+ project_updated = True
95
+ elif full_path.exists():
96
+ created_time = get_file_creation_time(full_path).astimezone()
97
+ jsonl_dates_cache[rel_path] = {
98
+ "created": created_time.isoformat()
99
+ }
100
+ project_updated = True
101
+ except Exception as e:
102
+ logger.error(f"Error processing file {rel_path}: {e}")
103
+ continue
104
+
105
+ # 标记删除不再跟踪的文件
106
+ if len(jsonl_dates_cache) > len(tracked_files):
107
+ project_updated = True
108
+
109
+ # 如果有更新,写入JSONL缓存文件
110
+ if project_updated or not jsonl_cache_file.exists():
111
+ global_updated = write_jsonl_cache(jsonl_cache_file, jsonl_dates_cache, tracked_files)
112
+ except subprocess.CalledProcessError as e:
113
+ logger.error(f"Failed to execute git command: {e}")
114
+ continue
115
+ except Exception as e:
116
+ logger.error(f"Error processing project directory {project_dir}: {e}")
117
+ continue
118
+ return global_updated
119
+
120
+
121
+ if __name__ == "__main__":
122
+ update_cache()
@@ -0,0 +1,109 @@
1
+ import os
2
+ import sys
3
+ import logging
4
+ import subprocess
5
+ from pathlib import Path
6
+ import platform
7
+
8
+ logger = logging.getLogger("mkdocs.plugins.document_dates")
9
+ logger.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, CRITICAL
10
+
11
+ def get_config_dir():
12
+ if platform.system().lower().startswith('win'):
13
+ return Path(os.getenv('APPDATA', str(Path.home() / 'AppData' / 'Roaming')))
14
+ else:
15
+ return Path.home() / '.config'
16
+
17
+ def check_python_version(interpreter):
18
+ try:
19
+ result = subprocess.run(
20
+ [interpreter, "-c", "import sys; print(sys.version_info >= (3, 7))"],
21
+ capture_output=True, text=True)
22
+ if result.returncode == 0 and result.stdout.strip().lower() == 'true':
23
+ return True
24
+ else:
25
+ logger.warning(f"Low python version, requires python_requires >=3.7")
26
+ except Exception as e:
27
+ logger.info(f"Failed to check {interpreter}: {str(e)}")
28
+ return False
29
+
30
+ def detect_python_interpreter():
31
+ # 检查可能的Python解释器
32
+ python_interpreters = ['python3', 'python']
33
+ for interpreter in python_interpreters:
34
+ if check_python_version(interpreter):
35
+ return f'#!/usr/bin/env {interpreter}'
36
+
37
+ # 如果都失败了,使用当前运行的Python解释器
38
+ return f'#!{sys.executable}'
39
+
40
+ def setup_hooks_directory():
41
+ config_dir = get_config_dir() / 'mkdocs-document-dates' / 'hooks'
42
+ try:
43
+ config_dir.mkdir(parents=True, exist_ok=True)
44
+ os.chmod(config_dir, 0o755)
45
+ return config_dir
46
+ except PermissionError:
47
+ logger.error(f"No permission to create directory: {config_dir}")
48
+ except Exception as e:
49
+ logger.error(f"Failed to create directory {config_dir}: {str(e)}")
50
+ return None
51
+
52
+ def install_hook_file(source_dir: Path, target_dir: Path):
53
+ try:
54
+ shebang = detect_python_interpreter()
55
+ for item in source_dir.iterdir():
56
+ # 跳过隐藏文件和目录
57
+ if item.name.startswith('.') or not item.is_file():
58
+ continue
59
+ # 添加 shebang 行
60
+ content = item.read_text(encoding='utf-8')
61
+ if content.startswith('#!'):
62
+ content = shebang + os.linesep + content[content.find('\n')+1:]
63
+ else:
64
+ content = shebang + os.linesep + content
65
+
66
+ target_hook_path = target_dir / item.name
67
+ target_hook_path.write_text(content, encoding='utf-8')
68
+ os.chmod(target_hook_path, 0o755)
69
+
70
+ return True
71
+ except Exception as e:
72
+ logger.error(f"Failed to create hook file {target_hook_path}: {str(e)}")
73
+ return False
74
+
75
+ def configure_git_hooks(hooks_dir):
76
+ try:
77
+ # 配置自定义合并驱动
78
+ # script_path = hooks_dir / 'json_merge_driver.py'
79
+ # subprocess.run(['git', 'config', '--global', 'merge.custom_json_merge.name', 'Custom JSON merge driver'], check=True)
80
+ # subprocess.run(['git', 'config', '--global', 'merge.custom_json_merge.driver', f'"{sys.executable}" "{script_path}" %O %A %B'], check=True)
81
+
82
+ subprocess.run(['git', 'config', '--global', 'core.hooksPath', str(hooks_dir)], check=True)
83
+ logger.info(f"Git hooks successfully installed in: {hooks_dir}")
84
+ return True
85
+ except Exception:
86
+ logger.warning("Git not detected, using plugin in a no-Git environment")
87
+ return False
88
+
89
+ def install():
90
+ try:
91
+ # 创建hooks目录
92
+ target_dir = setup_hooks_directory()
93
+ if not target_dir:
94
+ return False
95
+
96
+ # 安装hook文件
97
+ source_dir = Path(__file__).parent / 'hooks'
98
+ if not install_hook_file(source_dir, target_dir):
99
+ return False
100
+
101
+ # 配置git hooks路径
102
+ return configure_git_hooks(target_dir)
103
+
104
+ except Exception as e:
105
+ logger.error(f"Unexpected error during hooks installation: {str(e)}")
106
+ return False
107
+
108
+ if __name__ == '__main__':
109
+ install()