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.
- mkdocs_document_dates-3.2.1/LICENSE +22 -0
- {mkdocs_document_dates-3.1.6/mkdocs_document_dates.egg-info → mkdocs_document_dates-3.2.1}/PKG-INFO +11 -11
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/README.md +9 -8
- mkdocs_document_dates-3.2.1/mkdocs_document_dates/cache_manager.py +122 -0
- mkdocs_document_dates-3.2.1/mkdocs_document_dates/hooks_installer.py +109 -0
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/plugin.py +96 -113
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/config/user.config.css +6 -7
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/config/user.config.js +13 -5
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/core/core.css +15 -8
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/core/core.js +58 -10
- mkdocs_document_dates-3.2.1/mkdocs_document_dates/static/core/timeago-load.js +18 -0
- mkdocs_document_dates-3.2.1/mkdocs_document_dates/utils.py +122 -0
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1/mkdocs_document_dates.egg-info}/PKG-INFO +11 -11
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates.egg-info/SOURCES.txt +1 -0
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/setup.py +3 -4
- mkdocs_document_dates-3.1.6/LICENSE +0 -11
- mkdocs_document_dates-3.1.6/mkdocs_document_dates/cache_manager.py +0 -226
- mkdocs_document_dates-3.1.6/mkdocs_document_dates/hooks_installer.py +0 -114
- mkdocs_document_dates-3.1.6/mkdocs_document_dates/static/core/timeago-load.js +0 -5
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/MANIFEST.in +0 -0
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/__init__.py +0 -0
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/hooks/pre-commit +0 -0
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/core/timeago.full.min.js +0 -0
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/core/timeago.min.js +0 -0
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/languages/ar.json +0 -0
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/languages/de.json +0 -0
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/languages/en.json +0 -0
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/languages/es.json +0 -0
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/languages/fr.json +0 -0
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/languages/ja.json +0 -0
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/languages/ko.json +0 -0
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/languages/ru.json +0 -0
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/languages/zh.json +0 -0
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/languages/zh_TW.json +0 -0
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/tippy/backdrop.css +0 -0
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/tippy/light.css +0 -0
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/tippy/material.css +0 -0
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/tippy/popper.min.js +0 -0
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/tippy/scale.css +0 -0
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/tippy/shift-away.css +0 -0
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/tippy/tippy.css +0 -0
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates/static/tippy/tippy.umd.min.js +0 -0
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates.egg-info/dependency_links.txt +0 -0
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates.egg-info/entry_points.txt +0 -0
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates.egg-info/requires.txt +0 -0
- {mkdocs_document_dates-3.1.6 → mkdocs_document_dates-3.2.1}/mkdocs_document_dates.egg-info/top_level.txt +0 -0
- {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
|
+
|
{mkdocs_document_dates-3.1.6/mkdocs_document_dates.egg-info → mkdocs_document_dates-3.2.1}/PKG-INFO
RENAMED
@@ -1,13 +1,12 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: mkdocs-document-dates
|
3
|
-
Version: 3.1
|
4
|
-
Summary:
|
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
|
-
|
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
|
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` > `
|
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
|
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,
|
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
|
-
|
|
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`,
|
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
|

|
148
148
|

|
149
149
|
|
150
|
-
##
|
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
|
-
|
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
|
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` > `
|
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
|
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,
|
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
|
-
|
|
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`,
|
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
|

|
121
122
|

|
122
123
|
|
123
|
-
##
|
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()
|