前言
使用 husky
来为 Hexo
帖子增加更新时间
本文都是建立在 Hexo
的 Next
主题下的,其他的主题可能会不兼容
在 Next
主题下,其实有配置可以让我们开启帖子更新时间的,如下:
默认情况下,Next
应该是会去读取文件的最后修改时间来作为更新时间的
但是这会出现一个问题,那就是我们使用的 Github Action
自动部署的
每次都会重新拉取仓库,这样子每个文件的最后修改时间都会变成创建时间
正文
为了解决上面提到的问题,有两种解决办法
- 直接关闭更新时间,眼不见为敬(
推荐
- 增加
updated
字段手动更新帖子更新时间
这里我个人思考了下,决定还是得手动更新帖子时间,原因如下:
- 我想开启这个功能但我又想通过
Github Action
部署
- 万一换电脑了,重新拉取仓库,那更新时间就全乱了
为了学习
添加 updated 字段
在每个帖子 md
文件的顶部, 我们可以通过增加 updated
字段来指定更新时间
首先我们可以更改模板,加上 updated
,这样每一次 hexo new
就会带上 updated
字段了
接下来我们要给之前的帖子加上更新时间
我们依然使用 js
来写个脚本来批量修改文章内容
在这之前,我们首先要做个表格来保存帖子的最后修改时间,至于原因,后面会讲
在 Node
上,我们可以使用 fs.stat
来获取文件的信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| const fsPromise = require('fs/promises'); const path = require('path'); const dayjs = require('dayjs');
const POST_LIST_DIR = path.resolve('./source/_posts');
const main = async () => { const filenameList = await fsPromise.readdir(POST_LIST_DIR); const fileHandler = await fsPromise.open("./updated.json", "w+"); const infoList = []; for (const filename of filenameList) { const filepath = path.resolve(POST_LIST_DIR, filename); const fileStat = await fsPromise.stat(filepath); const updated = dayjs(fileStat.mtime).format("YYYY-MM-DD HH:mm:ss"); infoList.push({ filepath, updated }); } await fileHandler.write(JSON.stringify(infoList)); await fileHandler.close(); }
main();
|
执行之后我们就能发现项目根目录下有个 updated.json
文件,打开它格式化下
这样子我们就保存了文件的更新日期
有人可能疑问了,你这更新时间怎么一个样
因为之后的操作会写入文件,会导致 mtime
发生改变,而我当时又没有备份,留下了悔恨的泪水…
ok
,有了数据备份之后我们就可以开始折腾了,和之前处理 CDN
前缀一样,我们依然分为三个步骤
- 读取帖子列表
- 加上
updated
字段
- 把新的帖子内容写回文件
代码如下,由于 getPostList
和 writePostList
和之前是一样的,所以这里直接抽成公共函数引入了
不清楚实现的可以去 一个替换 cdn 前缀的小工具 这个帖子查看
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| const {getPostList, writePostList} = require('./util'); const fsPromise = require("fs/promises"); const dayjs = require('dayjs');
const REGEXP = /---(?<frontMatter>(\S|\s)*?)---/;
const getFileLastModifyDate = async (filepath) => { const fileStat = await fsPromise.stat(filepath); return dayjs(fileStat.mtime).format("YYYY-MM-DD HH:mm:ss"); }
const addPostUpdated = async (postList) => { postList = postList.filter(post => { const {fileContent} = post; return REGEXP.test(fileContent); });
const newPostList = [];
for (const post of postList) { const {filepath, fileContent} = post; const updated = await getFileLastModifyDate(filepath); const {frontMatter} = fileContent.match(REGEXP).groups; const infoList = frontMatter .split(/\r|\n|\r\n/) .filter(item => !!item.trim()); const dateInfoIndex = infoList.findIndex(item => item.startsWith("date")); const updatedInfoIndex = infoList.findIndex(item => item.startsWith("updated")); if (updatedInfoIndex > -1) { continue; } infoList.splice(dateInfoIndex + 1, 0, `updated: ${updated}`); newPostList.push({ filepath, fileContent: fileContent.replace(REGEXP, `---\n${infoList.join('\n')}\n---`) }); }
return newPostList; }
const main = async () => { const postList = await getPostList(); const newPostList = await addPostUpdated(postList); await writePostList(newPostList); }
main();
|
这里依然用到了我们的老朋友正则,使用 /---(?<frontMatter>(\S|\s)*?)---/
来匹配开头的帖子元数据
注意到这里使用了具名捕获组,这样方便我们拿到数据,以及非贪婪匹配 *?
默认贪婪匹配的情况下,我发现有点问题,主要是表格的语法里面也会出现 ---
三个横杠的情况,会修改到其他的地方,所以要使用非贪婪
以及使用 (\S|\s)*?
而不是 .*?
,因为 .
不匹配换行符号
重要:这个工具只有在第一次才能获取正确的修改时间,因为存在重新写入文件,会导致 mtime
变化!!
重要:这个工具只有在第一次才能获取正确的修改时间,因为存在重新写入文件,会导致 mtime
变化!!
重要:这个工具只有在第一次才能获取正确的修改时间,因为存在重新写入文件,会导致 mtime
变化!!
如果不小心搞错了,也不用担心,因为前文我们提前存了个 updated.json
,读出来,然后不用 fs.stat
了,而是根据 json
文件里的映射一一对应重新 patch
一下即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| const {getPostList, writePostList} = require('./util'); const fsPromise = require("fs/promises"); const dayjs = require('dayjs'); const path = require("path");
const REGEXP = /---(?<frontMatter>(\S|\s)*?)---/; let updatedMap = {};
const getUpdatedJsonMap = async () => { const string = (await fsPromise.readFile(path.resolve('./updated.json'))).toString('utf-8'); const array = JSON.parse(string); updatedMap = array.reduce((map, item) => { map[item.filepath] = item.updated; return map; }, {}); }
const addPostUpdated = async (postList) => { postList = postList.filter(post => { const {fileContent} = post; return REGEXP.test(fileContent); });
const newPostList = [];
for (const post of postList) { const {filepath, fileContent} = post; const updated = updatedMap[filepath]; if (!updated) { continue; } const {frontMatter} = fileContent.match(REGEXP).groups; const infoList = frontMatter .split(/\r|\n|\r\n/) .filter(item => !!item.trim()); const dateInfoIndex = infoList.findIndex(item => item.startsWith("date")); const updatedInfoIndex = infoList.findIndex(item => item.startsWith("updated")); if (updatedInfoIndex > -1) { infoList[updatedInfoIndex] = `updated: ${updated}`; } else { infoList.splice(dateInfoIndex + 1, 0, `updated: ${updated}`); } newPostList.push({ filepath, fileContent: fileContent.replace(REGEXP, `---\n${infoList.join('\n')}\n---`) }); }
return newPostList; }
const main = async () => { const postList = await getPostList(); await getUpdatedJsonMap(); const newPostList = await addPostUpdated(postList); await writePostList(newPostList); }
main();
|
到这里我们就完成了对所有的 md
文件添加上 updated
字段了
但是还有个问题,难道我每次修改帖子提交,我都要自己去改 updated
字段吗
这也太不优雅了,作为一个爱搞事的人,绝不会去做没意义的事,所以我们要让帖子自己更新
使用 husky 来自动更新帖子
刚开始也有在网络上查找相应的办法,但是关于这个问题还是太少解决方案了
最后我决定使用 husky
来解决这个问题
husky
是一个工具,可以让我们在 git
操作上 hook
一些逻辑
我们主要使用 husky
在 commit
前检测 add
的文件中是否含有帖子,如果有,读取这个帖子,把 updated
字段置为当前的时间,然后重新 add
进去
husky
的官网 Husky - Git hooks
首先我们要安装 husky
,这里我用的是 pnpm
, 如果你用的是 npm
,那么使用 npm install husky --save-dev
安装完依赖之后,我们还要开启 git hooks
功能,执行
然后项目根目录下就会出现一个 .husky
的文件夹
接着我们添加一个 pre-commit
的 hook
1
| pnpx husky add .husky/pre-commit "pnpm run flushPostUpdated"
|
这里这个 flushPostUpdated
命令我们要注册到 package.json
中
1 2 3 4 5 6 7 8 9 10 11
| { // ... "scripts": { "build": "hexo generate", "clean": "hexo clean", "deploy": "hexo deploy", "server": "hexo server", "flushPostUpdated": "node flushPostUpdated.js" } // ... }
|
我们可以在 flushPostUpdated.js
里面写个 hello world
,然后随便 add
一个文件 commit
一下
可以看到文件被执行了,打印了 hello world
接下来我们的目标就是在 flushPostUpdated
这个文件实现功能了
首先我们要获取当前 git add
的文件列表
这里我们使用 shelljs
配置 git status
命令来进行解析
一般我们都是直接使用 git status
来查看当前文件的追踪情况的,如下
但是这个格式不利于我们做解析,所以我们要配合一些参数来简化这些信息
我们可以打开 Git - git-status Documentation 查看文档
其中 --porcelain
以便于解析的格式输出相应的信息,如下:
这个格式我们就非常喜欢了,只要按行处理即可
当然,在这之前,我们需要明白每个文件之前的符号代表的意义
我们依然查看上面的文档,拉下来在 Output
中,详细的为我们介绍了符号的意义
可以看到两个 ?
代表文件未被跟踪,到时我们解析可以直接跳过这些行
M
代表文件被修改,而根据我们输出的图来看, M
可能在第一个字符(上图中的 X
位置),也可能在第二个字符(上图中的 Y
位置),这又是什么意思呢
这里我们要搞明白 X
和 Y
代表的意思,在这段文档的上面,解释了 X
和 Y
的意义,这里我们直接关注圈出来的部分
X
代表了 index
索引区的情况,而 Y
代表了工作区的情况,每当我们把文件 add
之后,实际上是把工作区的文件复制到索引区
根据我们上图的输出的信息,此时 package.json
文件应该是在 index
区里面的,我们把它从 index
区删除再输出信息看看
这时 M
标记在 Y
位置展示了,表示工作区和索引区的 package.json
不一致,被标记为修改了
其实更容易的理解是: X
代表了 index
区和当前版本库的差异,而 Y
代表了工作区和 index
区的差异
我们可以重新添加 package.json
,然后再修改 package.json
的内容
这时会出现两个 M
,意味着 index
区和当前的版本库文件不一致,工作区和当前的 index
区文件不一致
ok ,明白了之后,我们其实要处理的行就很明确了,即 X 列为 M 状态的帖子文件
有没有办法不输出这些未追踪的文件呢?
git status
提供了 --untracked-files[=<mode>]
来让我们能够选择是否输出为追踪的文件,其中 mode
为 no
的情况下即可不输出未追踪的文件
这样子就非常 nice 了,非常好操作,但是这个帖子的中文被转义了,而且还出现了引号,有点不适
使用 git config --global core.quotepath false
关掉 git
的自动转义功能,记得控制台保持 utf-8
编码,不然会乱码
再输出一次命令看看
现在中文直接显示,那么我们就能很好的解析了
接下来我们尝试使用 shelljs
来解析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| const shelljs = require('shelljs'); const path = require('path'); const fsPromise = require('fs/promises');
const POST_LIST_DIR = path.resolve('./source/_posts'); const CODE = { SUCCESS: 0, FAILURE: 101, };
const getMdFilepathList = () => { const result = shelljs.exec("git status --porcelain --untracked-files=no", { silent: true });
if (result.code !== CODE.SUCCESS) { throw result.stderr; }
return result.stdout .split(/\r|\n|\r\n/) .filter(line => line.startsWith("M")) .map(line => path.resolve(line.substring(3))) .filter(filepath => filepath.startsWith(POST_LIST_DIR)) .filter(filepath => path.extname(filepath) === '.md'); }
console.log(getMdFilepathList());
|
执行之后,就可以看到输出的文件列表了
得到文件路径列表之后,我们要做的就是和之前脚本增加 updated
字段的逻辑
首先我们要创建一个当前的 updated
1 2 3 4 5 6 7 8
| const dayjs = require('dayjs');
const createCurrentUpdated = () => { return dayjs().format('YYYY-MM-DD HH:mm:ss'); }
|
使用它,就能获取 commit
时的时间字符串了,把它 patch
到 updated
字段即可
接着我们根据前面获取的 mdFilepathList
来获取文件内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
const getPostList = async (filepathList) => { const postList = []; for (const filepath of filepathList) { const buffer = await fsPromise.readFile(filepath); postList.push({ filepath, fileContent: buffer.toString('utf-8') }); } return postList; }
|
这个函数和之前的 getPostList
逻辑是一样的,不过我们使用了参数来获取特定的文件
接着我们依然使用正则来替换 updated
字段
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| const REGEXP = /---(?<frontMatter>(\S|\s)*?)---/;
const flushPostUpdated = async (postList) => { const newPostList = [];
const updated = createCurrentUpdated();
for (const post of postList) { const {filepath, fileContent} = post; const {frontMatter} = fileContent.match(REGEXP).groups; const infoList = frontMatter .split(/\r|\n|\r\n/) .filter(item => !!item.trim()); const dateInfoIndex = infoList.findIndex(item => item.startsWith("date")); const updatedInfoIndex = infoList.findIndex(item => item.startsWith("updated")); if (updatedInfoIndex > -1) { infoList[updatedInfoIndex] = `updated: ${updated}`; } else { infoList.splice(dateInfoIndex + 1, 0, `updated: ${updated}`); } newPostList.push({ filepath, fileContent: fileContent.replace(REGEXP, `---\r\n${infoList.join('\r\n')}\r\n---`) }); }
return newPostList; }
|
patch
完成之后我们使用之前的 writePostList
重新写回去
然后我们要重新把这些文件 add
进 index
区
1 2 3 4 5 6 7 8 9 10 11
|
const reGitAdd = (filepathList) => { for (const filepath of filepathList) { let result; if ((result = shelljs.exec(`git add ${filepath}`)).code !== CODE.SUCCESS) { throw result.stderr; } } }
|
这样子我们就完成了整个逻辑的编写
然后我们来测试一下效果,我们先把文件的 updated
字段改成 1999-01-01 00:00:00
注意,这里我们先不使用 pre-commit
钩子,可以先注释掉,如下
然后我们 add
进去,然后提交一个 commit
,确保我们的版本库里面的日期是 1999-01-01 00:00:00
然后我们打开 pre-commit
钩子,随便更改一下内容,再次提交
成功的变为当前的时间,并且此时是已经 commit
的了
到这里我们基本完成了整个流程,现在我们只管更新文章的内容,更新 updated
字段交给了脚本
大大地减少了心智负担,又可以愉快地写帖子了
但是到这里就结束了吗,不一定
当然以下部分为扩展部分,我觉得大部分人用上面的方式即可,没必要搞太复杂
现在我们来复现一下一个场景
小林正在写一篇帖子,帖子名为 使用 husky 来为帖子增加更新时间
写完了帖子,小林开心的把帖子 add
到 index
区,准备 commit
然后 push
到 Github
上
这时候小林的老妈大喊了一声:“孩儿,去把洗好的衣服凉一下”
小林想着,既然 add
了,晚点 commit
也没事,就去晾衣服了
回来的时候,小林把一些额外的部分写进了帖子,还没写完突然想起之前的版本忘记了 commit
试问:如果这个时候 commit
,会出现什么情况
没错,还没 add
进 index
区的部分会被一同提交到版本库
因为在钩子中,我们的逻辑就是 patch
头部的 updated
字段,然后重新 git add
也就是说,如果此时文件的 X
和 Y
都是 M
标志的话,会出现一些矛盾
即我们 git add
的文件是当前工作区的文件,而工作区的文件存在另外的更新
那我们改如何解决这个问题呢?
刚开始的时候我是想像 VSCode
那样,选中某些行来进行局部 add
的,但是实在是没搞懂
之后,我就想了一个比较笨的办法,这个笨方法的步骤是:
- 把当前工作区的文件备份
- 对当前工作区的备份文件
patch
它的 updated
字段
- 把
index
区的文件写回工作区
- 对当前工作区的文件
patch
它的 updated
字段
git add
当前工作区的文件
- 把备份文件写回原来的位置
- 删除备份文件
其中有一个非常重要的步骤是:把 index
区的文件写回工作区
这意味着我们必须知道当前在 index
区的文件长什么样
这里可以使用 git show ":文件名"
这个命令查看(别问我怎么知道的,我百度的
这样我们就可以用 shelljs
执行然后获取内容了
其他的步骤其实很简单,文件拷来拷去而已
这里放下完整的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
| const shelljs = require('shelljs'); const path = require('path'); const fsPromise = require('fs/promises'); const { writePostList, gitAdd, createCurrentUpdated, POST_META_REGEXP, POST_LIST_DIR, SHELLJS_CODE } = require("./util");
const getMdFilepathList = () => { const result = shelljs.exec("git status --porcelain --untracked-files=no", { silent: true });
if (result.code !== SHELLJS_CODE.SUCCESS) { throw result.stderr; }
return result.stdout .split(/\r|\n|\r\n/) .filter(line => line.startsWith("M")) .map(line => ({ X: line[0], Y: line[1], path: line.substring(3), filepath: path.resolve(line.substring(3)) })) .filter(({filepath}) => filepath.startsWith(POST_LIST_DIR)) .filter(({filepath}) => path.extname(filepath) === '.md'); }
const getPostListInIndex = async (filepathList) => { const postList = []; for (const filepath of filepathList) { const result = shelljs.exec(`git show ":${filepath}"`, { silent: true, }); if (result.code !== SHELLJS_CODE.SUCCESS) { throw result.stderr; } postList.push({ filepath, fileContent: result.stdout, }); } return postList; }
const getPostList = async (filepathList) => { const postList = []; for (const filepath of filepathList) { const buffer = await fsPromise.readFile(filepath); postList.push({ filepath, fileContent: buffer.toString("utf-8"), }); } return postList; }
const backupMdFile = async (mdFilepathList) => { const list = []; for (const {filepath} of mdFilepathList) { const dir = path.dirname(filepath); const destFilename = path.basename(filepath) + '.pre-commit' + path.extname(filepath); const destFilepath = path.resolve(dir, destFilename) await fsPromise.copyFile(filepath, destFilepath); console.log(`backup md, source file: ${filepath}, backup file: ${destFilepath}`); list.push(destFilepath); } return list; }
const flushPostUpdated = async (postList) => { const newPostList = []; const updated = createCurrentUpdated();
for (const post of postList) { const {filepath, fileContent} = post; console.log(`patching filepath: ${filepath}`); const {frontMatter} = fileContent.match(POST_META_REGEXP).groups; const infoList = frontMatter .split(/\r|\n|\r\n/) .filter(item => !!item.trim()); const dateInfoIndex = infoList.findIndex(item => item.startsWith("date")); const updatedInfoIndex = infoList.findIndex(item => item.startsWith("updated")); if (updatedInfoIndex > -1) { infoList[updatedInfoIndex] = `updated: ${updated}`; } else { infoList.splice(dateInfoIndex + 1, 0, `updated: ${updated}`); } newPostList.push({ filepath, fileContent: fileContent.replace(POST_META_REGEXP, `---\n${infoList.join('\n')}\n---`) }); }
return newPostList; }
const recoveryMdList = async (filepathList) => { for (const filepath of filepathList) { const dir = path.dirname(filepath); const backupFilepath = path.resolve(dir, path.basename(filepath) + '.pre-commit' + path.extname(filepath)); const sourceFilepath = filepath; await fsPromise.copyFile(backupFilepath, sourceFilepath); } }
const deleteBackupMdList = async (filepathList) => { for (const filepath of filepathList) { await fsPromise.rm(filepath); } }
const main = async () => { const mdFileList = getMdFilepathList(); if (mdFileList.length === 0) { console.log('no md file need to patch.'); return; } console.log('will patch count: ', mdFileList.length); const backupMdList = await backupMdFile(mdFileList); const backupPostList = await getPostList(backupMdList); const newBackupPostList = await flushPostUpdated(backupPostList); await writePostList(newBackupPostList); console.log('backup success.');
const postList = await getPostListInIndex(mdFileList.map(file => file.path)); const newPostList = await flushPostUpdated(postList); await writePostList(newPostList); gitAdd(newPostList.map((post) => post.filepath)); console.log('patch success.');
await recoveryMdList(newPostList.map((post) => post.filepath)) console.log('recovery md success.'); await deleteBackupMdList(backupMdList); console.log('delete backup success.'); }
main();
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
| const shelljs = require('shelljs'); const fsPromise = require('fs/promises'); const path = require('path'); const dayjs = require('dayjs');
const POST_LIST_DIR = path.resolve('./source/_posts');
const POST_META_REGEXP = /---(?<frontMatter>(\S|\s)*?)---/;
const SHELLJS_CODE = { SUCCESS: 0, FAILURE: 101, };
const getPostList = async () => { const filenameList = await fsPromise.readdir(POST_LIST_DIR); const postList = []; for (const filename of filenameList) { const filepath = path.join(POST_LIST_DIR, filename); const buffer = await fsPromise.readFile(filepath); postList.push({ filepath, fileContent: buffer.toString('utf-8') }); } return postList; }
const writePostList = async (postList) => { for (const post of postList) { const {filepath, fileContent} = post; await fsPromise.writeFile(filepath, fileContent); } }
const getUpdatedJsonMap = async () => { const filepath = path.resolve('./updated.json'); try { await fsPromise.access(filepath); } catch (e) { return {}; } const string = (await fsPromise.readFile(filepath)).toString('utf-8'); const array = JSON.parse(string); return array.reduce((map, item) => { map[item.filepath] = item.updated; return map; }, {}); }
const saveUpdatedJson = async () => { const filenameList = await fsPromise.readdir(POST_LIST_DIR); const fileHandler = await fsPromise.open("./updated.json", "w+"); const infoList = []; for (const filename of filenameList) { const filepath = path.resolve(POST_LIST_DIR, filename); const fileStat = await fsPromise.stat(filepath); const updated = dayjs(fileStat.mtime).format("YYYY-MM-DD HH:mm:ss"); infoList.push({ filepath, updated }); } await fileHandler.write(JSON.stringify(infoList)); await fileHandler.close(); }
const gitAdd = (filepathList) => { for (const filepath of filepathList) { let result; if ((result = shelljs.exec(`git add ${filepath}`, { silent: true })).code !== SHELLJS_CODE.SUCCESS) { throw result.stderr; } } }
const createCurrentUpdated = () => { return dayjs().format('YYYY-MM-DD HH:mm:ss'); }
module.exports = { getPostList, writePostList, getUpdatedJsonMap, gitAdd, createCurrentUpdated, saveUpdatedJson, POST_META_REGEXP, POST_LIST_DIR, SHELLJS_CODE }
|
后记
虽然过程曲折,但终究实现了自动更新帖子 updated
字段的功能,单单依靠文件的信息确实不是很准确
想了下,做备份的话,感觉可以用 stash
来搞,部分文件 stash push
,然后部分文件 stash pop
也可以使用 git
操作指定撤销 index
区的文件,如下
这样看起来似乎更简单一点
还有优化空间,但是…
虽然解决了问题,可是我之前帖子的更新时间都不见了,我 TM …