Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incremental Document Build Based on Git Management #617

Closed
wants to merge 0 commits into from

Conversation

Fioooooooo
Copy link
Contributor

@Fioooooooo Fioooooooo commented Oct 2, 2023

此 PR 来自于 Discussion #520

有几点需要额外说明:

  1. 本次更新的逻辑涉及文件较多,且改动了核心逻辑,社区可能需要严格 Review;
  2. 增量文档构建需要 maven 插件的支持,因此在 smart-doc-maven-plugin 也有 PR;
  3. 由于组织的迁移,某些包还未迁移到 com.ly.doc。为了方便本地构建,本次 PR 一并修改了。若不符合 smart-doc 官方规则,我可以再修改;
  4. 注意 PR 中已将 smart-doc 的版本修改为 2.8.0-SNAPSHOT

@Fioooooooo
Copy link
Contributor Author

1. 逻辑流程图

image

2. 接口依赖树文件

在 git 仓库的工作目录放置一个隐藏文件夹 .smart-doc,以 groupIdartifactId 为每个 web 模块的配置文件名称。

以多模块的 maven 项目举例(提供 rest 接口),在项目 smart-doc-multi-module 中包含两个 web 模块 web-module-aweb-module-b

smart-doc-multi-module/
├── web-module-a/
└── web-module-b/

smart-doc-multi-module 是 git 仓库的工作目录。首次给web-module-a执行增量文档生成后,会在web-module-a下生成一个.smart-doc-dependency.json文件,记录 api 接口的依赖,目录结构会如下所示:

smart-doc-multi-module/
├── .smart-doc/
├── web-module-a/
│   └── .smart-doc-dependency.json
└── web-module-b/

如果团队内有公用的接口管理工具(如 Torna),我们建议将 .smart-doc 目录也提交到 git,便于CI流水线自动或团队内其他成员手动构建增量文档。

每个模块的配置文件格式如下所示:

{  
  // 最近一次成功构建增量文档时基于的 git commit id
  "commitId": "7bc3220f8cc9e7421c6e45511d25acb3ced3653a",
  
  // 模块下的接口依赖树
  "dependencyTree": [
    {
      // 接口所在的类全限定名
      "clazz": "org.example.a.controller.TestController",
      
      // 类中所有对外暴露的 api
      "apis": [
        {
          // api 的方法名称
          "method": "getUserInfo",
          
          // 方法的参数,全限定名
          "args": [
            "org.example.a.request.UserRequest"
          ],
          
          // 方法的返回值,全限定名
          "returns": [
            "org.example.a.response.ApiResponse",
            "org.example.a.response.UserResponse"
          ]
        }
      ]
    }
  ]
}

3. 增量文档生成

3.1 maven 插件新增 Parameter

新增参数 increment,用于标识是否增量构建文档,默认值为 false。使用方式如下:

  1. pom.xml
<plugin>
    <groupId>com.ly.smart-doc</groupId>
    <artifactId>smart-doc-maven-plugin</artifactId>
    <configuration>
        <increment>true</increment>
    </configuration>
</plugin>
  1. 命令行
mvn smart-doc:html -Dfile.encoding=UTF-8 -Dmaven.test.skip=true -Dincrement=true

3.2 改造 IDocBuildTemplate

原本的 IDocBuildTemplate 作为接口,给各框架解析提供了一些基础能力。并对外暴露 getApiData 方法,用于获取框架解析 ApiDoc 的结果。但是接口无法完成完整的文档解析流程编排。

基于以上考虑,将接口改造为抽象类 AbstractDocBuildTemplate。对外暴露的方法不变,依然是 getApiData,但在其中加入一些流程。

public List<T> getApiData(ProjectDocConfigBuilder projectBuilder) {
    // 创建 DocHelper,并检测依赖树文件
    DocHelper docHelper = DocHelper.create(projectBuilder.getApiConfig());

    // 构建文档前置处理
    preRender(docHelper);

    // 获取项目的全量或增量 class 文件
    Collection<JavaClass> candidateClasses = getCandidateClasses(projectBuilder, docHelper);
    List<T> apiList = renderApi(projectBuilder, candidateClasses);

    // 构建文档后置处理 - 合并新的依赖树
    postRender(docHelper, apiList);

    return apiList;
}

框架的解析实现类,由原来重写 getApiData 改为重写 renderApi,并在解析时预先提供一批 candidateClasses,各框架解析源码尝试寻找 Endpoint 时,直接从 candidateClasses 中检测。

同时 AbstractDocBuildTemplategetApiData 提供了 preRenderpostRender,可用于在文档构建时做一些前置、后置的动作。

改造后的 getApiData 时序图如下:

image

3.3 关于 DocHelper

对外提供获取依赖树、构建依赖树、获取增量文件等方法

image

3.4 检测 candidateClasses

image

3.5 关于 GitHelper

基于 JGit 封装的 Git 操作工具类,提供了一些常用的方法

image

3.6 postRender

可用于文件构建后的一些后置处理操作。会在这一步重建依赖树。

private void postRender(DocHelper docHelper, List<T> apiList) {
    docHelper.rebuildDependencyTree(apiList);
}

为了便于在多类型文档中提取到公用属性(在构建依赖树时用到的方法参数、返回等),增加了两个接口 IDocIMethod。在重建依赖树时,通过这两个接口提取到依赖树所需的信息。

image
image

构建好本次接口的依赖树后,即会开始合并依赖树。

image

最后将最新的 commit-id 与合并后的依赖树写入依赖树文件。

4. 还需完善的地方

目前只是基于 git 变更的 [文件] 做增量更新,并未解析具体变更代码涉及到的接口方法,因此此方案的增量文档构建有两处不足:

  1. 若一个 class 中存在多个接口 endpoint,但只是变更了一行,依然会构建此 class 中的全部 endpoint 文档;
  2. 若已将某个 class 记录到依赖树中,但是后续构建时将 class 上的 endpoint 删除,比如 Spring 框架,删除某个 controller 标注在类上的 @RequestMapping 注解(是类上的注解,不是方法上的),或是 Dubbo 框架,删除某个 service 类上的 @DubboService 注解。这种情况下,暂时没有很好的方法将其从依赖树中删除。

@shalousun
Copy link
Collaborator

这个pr会放11月份来合并,10月主要是过渡期的维护

@Fioooooooo
Copy link
Contributor Author

之前提到的 4.2 还需完善的地方,无法从依赖树中剔除已弃用的 class,已经提交了对应的 commit。

为了实现此功能,并且规范文档构建流程,AbstractDocBuildTemplate 做了如下改动:

  1. preRender() 步骤时自动注册框架解析所需的注解,解析各框架的 Template 类只需重写 registeredAnnotations() 方法即可,无需手动注册。并且对外暴露了 getFrameworkAnnotations() 方法,各 Template 类如需用到注解,可从此处获取;
  2. 新增 isEntryPoint(JavaClass javaClass, FrameworkAnnotations frameworkAnnotations) 方法。基于 git 获取文件变更时,会基于此方法预先给变更文件标记是否是 entryPoint,此标记只为了检验文档构建前后 dependency-tree 的变更,以便可以正确识别被删除的 API class

@Fioooooooo
Copy link
Contributor Author

同时,在 dependency-tree文件中新增了 schema 字段,简单标记了构建 dependency-tree 时的版本。后续如有不兼容的依赖树构建,可以在 DependencyTree#write() 基于 schema 做出版本适配。

@@ -0,0 +1,380 @@
package com.ly.doc.helper;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add license

@@ -41,4 +41,28 @@ public static String formatMockValue(String mock) {
}
return mock.replaceAll("\\\\","");
}

public static List<String> extractQualifiedName(List<ApiParam> paramList) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is possible to add unit tests for this method

@@ -0,0 +1,139 @@
package com.ly.doc.model.dependency;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add license

import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import org.eclipse.jgit.treewalk.CanonicalTreeParser;

import javax.annotation.Nullable;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not work in a higher version JDK environment, and manual check is recommended.

@shalousun
Copy link
Collaborator

It is recommended to rebase multiple commit messages into one effective commit message before merging. You can refer this document https://smart-doc-group.github.io/#/zh-cn/community/pull-request-process.md

@Fioooooooo Fioooooooo force-pushed the master branch 2 times, most recently from 5dd8558 to b9ed9a6 Compare November 14, 2023 01:30
@Fioooooooo Fioooooooo closed this Nov 14, 2023
@shalousun shalousun changed the title 基于 git 管理的增量文档构建 Incremental Document Build Based on Git Management Feb 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants