ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

JPlag 贡献指南:源码构建、代码规范与 Pre-commit 钩子实战

JPlag 贡献指南:源码构建、代码规范与 Pre-commit 钩子实战
  • 代码质量
  • 教育
  • 后端

【免费下载链接】JPlag

State-of-the-Art Source Code Plagiarism & Collusion Detection. Check for plagiarism in a set of programs.

项目地址:https://gitcode.com/gh_mirrors/jp/JPlag
点击查看免费下载

本文基于 JPlag 官方贡献文档 docs/3.-Contributing-to-JPlag.md 展开,完整覆盖项目对代码语言、JavaDoc、格式化和 Pull Request 的要求,并结合根 POM、CheckStyle 配置与 Git hooks 脚本的源码实现,说明如何在本地完成 JPlag 的 Maven 构建、report-viewer 前端开发环境搭建以及 pre-commit 自动检查的启用与排错。

贡献规范总览

JPlag 欢迎一切对代码库的改进:fork 项目后提交 Pull Request 即可。官方文档建议新手可以先从仓库中标记为 “good first issue” 的问题单入手,降低首次贡献的门槛。

文档中列出的贡献者要求可以归纳为以下几类:

  • 语言与表达:所有产物(代码、注释等)必须使用英文,并避免使用缩写;
  • 文档注释:利用 JavaDoc / TsDoc 为类和公共方法编写文档;
  • 代码质量:变更应始终提升代码库质量,尤其是在维护较老的组件时;
  • 第三方代码:复用其他项目代码时必须明确标注出处,并确认其许可证允许复用(JPlag 本身采用 GNU General Public License v3.0,见 LICENSE 与根 POM 中的licenses声明);
  • Git 信息:提交信息要简洁且更具描述性(concise but descriptive);保持 git 历史干净,否则 PR 在合并时可能被 squash;
  • PR 描述:创建 PR 时提供详尽的变更说明及其目的,用解释充分的 PR 来提议你的特性。

这些要求在仓库中都有对应的自动化工具支撑:Java 侧由 Spotless(格式化)与 Checkstyle(Javadoc 强制)把守,TypeScript/Vue 侧由 prettier 与 eslint 把守,详见下文。

Java 代码格式化:Spotless 与 formatter.xml

仓库为 Java 代码提供了统一的 Eclipse 格式化工具配置 formatter.xml,其 profile 名称为 “JPlag Java Formatter”(Eclipse CodeFormatterProfile),并规定了 4 空格缩进、续行缩进等细节。该配置通过根 POM 中的 Spotless 插件被强制执行,关键配置位于 pom.xml:

<plugin> <groupId>com.diffplug.spotless</groupId> <artifactId>spotless-maven-plugin</artifactId> <version>${version.plugin.spotless}</version> <configuration> <java> <eclipse> <file>${maven.multiModuleProjectDirectory}/formatter.xml</file> </eclipse> <importOrder> <file>spotless.importorder</file> </importOrder> <removeUnusedImports/> </java> <pom> <sortPom> <encoding>UTF-8</encoding> <keepBlankLines>true</keepBlankLines> ... </sortPom> </pom> </configuration> </plugin>

从源码结构看,Spotless 在这里做了三件事:

  1. 按formatter.xml对 Java 源码重排格式(该插件同时被声明在pluginManagement与<plugins>中,即对所有 Maven 子模块生效);
  2. 按 spotless.importorder 规定的顺序整理 import,顺序为java→javax→org→de,并自动移除未使用的 import;
  3. 对 POM 文件执行sortPom排序,保持依赖声明的书写顺序一致。

日常开发中的两个关键命令:

  • 检查格式是否合规:mvn spotless:check(pre-commit 钩子会自动执行);
  • 自动修复格式:mvn spotless:apply——这是文档推荐的一键方案,任何不符合规范的代码都可以在提交前用这条命令修复。

Eclipse 与 IntelliJ 用户也可以直接导入formatter.xml作为 IDE 格式方案,保证手工编辑时风格与 CI 一致。

Javadoc 强制执行:CheckStyle 配置

文档指出,仓库还额外提供了一份 CheckStyle 配置(位于config/checkstyle),主要用于强制 Javadoc 注释。具体规则见 config/checkstyle/checkstyle.xml,整个 Checker 的 severity 被设为error,核心检查项包括:

检查模块作用
MissingJavadocType/MissingJavadocMethod强制类、接口、枚举、注解、record 及方法具备 Javadoc(方法覆盖METHOD_DEF、构造器等)
MissingJavadocPackage强制包级别 Javadoc(package-info.java)
JavadocMethod校验 public/protected/package 方法中@param、@return、@throws的完整性
JavadocVariable校验 public/package 变量的 Javadoc
JavadocStyleJavadoc 必须以句号等规范标点收尾
AtclauseOrder、JavadocLeadingAsteriskAlign等规范 atclause 顺序与*对齐
AvoidStarImport禁止import xxx.*通配导入

该配置在构建中被挂载到verify阶段:根 POM 中maven-checkstyle-plugin显式设置了configLocation为config/checkstyle/checkstyle.xml、failsOnError为true,并同时覆盖主源码与测试源码目录(见 pom.xml)。也就是说,任何缺失 Javadoc 或违规 import 的 Java 代码都会直接导致mvn verify/mvn clean package构建失败——这也解释了贡献规范中“使用 JavaDoc/TsDoc 文档化”并非软性建议,而是构建门禁。

TypeScript / Vue 格式化:prettier 与 eslint

对 report-viewer 的 TypeScript/Vue 代码,项目使用 prettier 与 eslint,两者都可以通过 report-viewer/package.json 中的脚本执行:

npm run format # 即 prettier --write . npm run lint # 即 eslint --max-warnings 0(零警告容忍)

prettier 的具体风格由 report-viewer/.prettierrc.json 定义:不使用分号、2 空格缩进、单引号、行宽 100、行尾无尾逗号,并接入prettier-plugin-tailwindcss对 Tailwind 类名排序。

eslint 采用 flat config(report-viewer/eslint.config.mjs),叠加了@eslint/js推荐规则、eslint-plugin-vue的 flat/recommended、typescript-eslint推荐规则,并以eslint-config-prettier关闭与 prettier 冲突的规则。几条值得注意的自定义规则:

  • no-console为 error,但允许warn、error、info三个方法;
  • 禁止默认导出(no-restricted-exports),保证模块导出显式化;
  • 对**/*.test.ts放宽@typescript-eslint/no-unused-expressions,方便断言写法。

此外,prettier 与 eslint 也可以在提交时自动运行——这正是下一节 pre-commit 钩子的一部分。

从源码构建 JPlag

Maven 侧:核心与可执行 JAR

仓库根 POM(pom.xml)当前版本由<revision>属性固定为6.3.0,编译目标为 Java 25(maven.compiler.source/target)。默认激活的module-defaultsprofile 包含cli、core、coverage-report、endtoend-testing、languages、language-api、language-antlr-utils、language-testutils等模块,因此构建入口非常统一:

  1. 下载或克隆仓库代码;
  2. 在仓库根目录执行:
mvn clean package

即可编译并构建所有子模块。如果需要包含全部依赖的完整可运行 JAR,则启用with-report-viewerprofile:

mvn clean package assembly:single -P with-report-viewer

文档指出,生成的 JAR 位于jplag.cli/target子目录下(jplag-x.y.z-jar-with-dependencies.jar)。从 cli/pom.xml 的 profile 定义可以确认这个 profile 的完整行为:它会通过exec-maven-plugin依次执行npm install(工作目录../report-viewer)和npm run build(工作目录../report-viewer/report-viewer),然后把前端构建产物dist目录打包进 JAR 的report-viewer资源路径下,并额外打入src/main/resources/v5、v6_1两份旧版报告数据;同时 assembly 描述指定mainClass为de.jplag.cli.CLI、finalName 为jplag-${project.version}。可以推断,启用该 profile 的前提是本机安装了 Node.js 与 npm,否则exec阶段会直接失败。

Report Viewer 侧:本地开发服务器

单独开发前端时,按 report-viewer/README.md 的步骤操作:

npm install # 在 report-viewer 目录安装全部依赖 cd report-viewer npm run dev # 启动开发服务器

开发服务器启动后,report viewer 运行在http://localhost:5173/。若只需构建独立的 report-viewer 产物(而非打入 JAR),执行npm run build即可。

Git Hooks:提交前的自动格式与 Lint 检查

仓库内置了一个 pre-commit 钩子:若提交内容未通过 Spotless 检查则阻止提交,并对 report-viewer 代码自动执行 prettier 与 eslint。启用方式有两种(任选其一):

# 方式一:手动指定钩子目录(在本地仓库中执行一次即可) git config --local core.hooksPath gitHooks/hooks # 方式二:在 report-viewer 包中安装依赖时自动安装 npm i # 或 npm run prepare

其中方式二之所以成立,是因为 report-viewer/package.json 定义了"prepare": "git config --local core.hooksPath gitHooks/hooks",npm 在npm i后会自动触发该脚本。

从钩子脚本的实现来看,其行为是“按文件类型分发”的:

  • gitHooks/hooks/pre-commit 通过git diff --name-only --cached枚举暂存区文件:只要存在report-viewer*路径下的文件,就进入report-viewer目录执行 gitHooks/scripts/reportViewerPreCommit;只要存在*.java文件,就执行 gitHooks/scripts/javaPreCommit。任一步骤返回非零码,整个提交被中止。
  • gitHooks/scripts/javaPreCommit 实际执行的是mvn spotless:check;失败时输出提示Spotless failed. Please run 'mvn spotless:apply' to fix.,即修复方式就是前文的一键格式化命令。若系统未安装 Maven,则打印 “Maven is not installed. Spotless will not be checked” 并跳过检查(退出码 0)。
  • gitHooks/scripts/reportViewerPreCommit 执行npx lint-staged,具体规则由 report-viewer/.lintstagedrc.json 声明:.ts/.vue/.js/.html文件依次跑prettier --write与eslint --max-warnings 0(.ts额外带--no-warn-ignored),.json文件仅跑prettier --write。若未安装 npm 同样会跳过。

这种“检测失败给出修复命令 + 缺少工具链时优雅降级”的设计,意味着贡献者即使只改动了 Java 代码,也不会被前端检查拖慢,反之亦然。

贡献者工作流速查

把上述机制串起来,一次典型的 JPlag 贡献流程是:

  1. 克隆仓库,执行git config --local core.hooksPath gitHooks/hooks(或在 report-viewer 下npm i);
  2. 修改代码,为新增/修改的类和公共方法补齐 JavaDoc / TsDoc,使用英文且避免缩写;
  3. 提交前运行mvn spotless:apply与npm run format/npm run lint(或直接依赖 pre-commit 钩子);
  4. 本地执行mvn clean package确认 Checkstyle 与测试均通过;
  5. 保持提交信息简洁而有描述性、历史干净,并以详尽描述创建 Pull Request;
  6. 如需完整可运行 JAR,执行mvn clean package assembly:single -P with-report-viewer。

掌握以上规范与构建路径后,无论是修改 JPlag 核心比较算法、新增语言支持,还是完善 report-viewer 前端,都可以按照仓库既有的质量门禁平滑地提交并合并代码。

  • 代码质量
  • 教育
  • 后端

【免费下载链接】JPlag

State-of-the-Art Source Code Plagiarism & Collusion Detection. Check for plagiarism in a set of programs.

项目地址:https://gitcode.com/gh_mirrors/jp/JPlag
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进