前言

还记得去年写年终总结时,立下了众多Flag,其中一条就是

为优秀的开源项目贡献自己的代码,尤其是Halo

本来计划年后开始逐项完成这些flag的,但是由于年后公司的组织架构调整以及产品发版计划等一系列的事情,我没有时间和精力去完成这些flag,直到五月下旬,我的工作与生活缓和了下来。于是,在端午假期我决定先完成一个比较简单且容易实现的。

选择问题

首先进入到Halo仓库主页,进入到Issues列表,作为一个尚不了解系统,第一次贡献代码的我,选择从一个bug开始入手,于是我过滤出了打上bug标签的issue,在查看了众多的Issue之后,我选中了一个看起来比较简单的Issue #2115 小工具上传文件不一致

ok,目标选择完毕,接下来就是搭建环境。

搭建开发环境

  1. fork仓库

    1. image-20220605182352517
  2. clone 仓库

    1. image-20220605182511252
    2. 红框中的内容填成自己的
  3. 配置Gradle(之前都是用的maven)

    1. 参考 https://www.cnblogs.com/NyanKoSenSei/p/11458953.html
  4. 统一代码风格

    1. 参考Halo 官方文档 https://docs.halo.run/developer-guide/core/code-style
  5. 启动项目进入开发之旅

解决问题

确认问题出现的原因

经过测试,可以确定是

使用系统的小工具进行 Markdown 文章导入时,在文章内容无 Front Matter 时,MarkdownUtils中的正则表达式 Front Matter
private static final Pattern FRONT_MATTER = Pattern.compile("^(---)?[\\s\\S]*?---");

错误的匹配 Front Matter 内容,导致MarkdownUtilsremoveFrontMatter方法

public static String removeFrontMatter(String markdown) {
    markdown = markdown.trim();
    Matcher matcher = FRONT_MATTER.matcher(markdown);
    if (matcher.find()) {
    	return markdown.replace(matcher.group(), "");
    }
    return markdown;
}

删除Front Matter内容时,错误地删除了md 语法中表格表头与标题之间的分隔符的---之前的内容,从而导致文章内容丢失。

修复问题

搜索了Front Matter相关内容,发现此内容通常是Hexo 文章以---开头,以---结尾的内容,在查询正则表达式语法之后,修改了MarkdownUtils中的正则表达式 Front Matter

private static final Pattern FRONT_MATTER = Pattern.compile("^(---)+?[\\s\\S]*?---");

匹配文件内容以--- 开头找到下一个以---结尾的段落,避免当文章中不存在Front Matter 但存在md 制表符|---是会将制表符之前的内容当作Front Matter移除的问题。

2022-06-05更新

代码审核后,合并时CI未通过,通过查看错误原因发现是MarkdownUtilsTest的单元测试未通过

image-20220605191928450

如上代码41行未通过,同时预计46行也将失败,目前修改后的匹配 Front Matter 的正则表达式匹配规则是文件内容以
--- 开头找到下一个以---结尾的段落,但看此单测是存在不以---开头,但以---结尾的 Front Matter 。

查阅了相应的提交PR#1492 hexo的md文档可能存在省略开头的---的情况,虽然在验证时, hexo V5.2.0 Front Matter 省略开头的---将报错image

但为兼容#1492 可能出现的开头省略---的写法,修改了此bug的修复方式,增加对匹配到的 Front Matter 校验,如果存在制表符则认为是非 Front Matter 的内容,不进行移除 Front Matter 操作。

private static final Pattern TABLE = Pattern.compile("\\|\\s*:?---");

public static String removeFrontMatter(String markdown) {
    markdown = markdown.trim();
    Matcher matcher = FRONT_MATTER.matcher(markdown);
    // if has '| ---' or '| :---' return
    if (matcher.find() && !TABLE.matcher(matcher.group()).find()) {
        return markdown.replace(matcher.group(), "");
    }
    return markdown;
}

并添加了对应的单元测试。

提交PR

参考Halo代码贡献

提交之后可以在Halo仓库的PR列表看到你的PR

image-20220605190137746

然后等待Halo的审核和测试,审核成功后就会将代码合并到项目中了。

需要注意的点是,在第一次提交PR时需要登录一下CLA同意一下Halo的开源许可(图是仙总的😝)

image-20220605190037021

参考文献

Gradle的安装与配置

Halo官方文档