一个用于规整多个微服务Pom.xml中的Mevan依赖的脚本

111 阅读1分钟

背景

接手某项目后,发现由于初期”快速上线“而没有规范好pom.xml,现象有:

  1. pom文件中没有使用<hutool.version>5.8.0</hutool.version> 去管理,不同服务可能存在不同的版本
  2. 各服务各自为政,乱引入,代码重复,可读性差,没有使用Bom管理

改造:使Bom对整个项目的依赖进行管理,避免以后依赖混乱

脚本

人为整理,一点都不酷😎,整个脚本,感觉日后还会用得上,效果:会扫描多个pom.xml,并自动合并生成<properties><dependencies>

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.XmlUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.xpath.XPathConstants;
import java.util.*;

/**
 * 整理多个pom.xml中的依赖
 *
 * @author yejunxi 2022/08/19
 */
public class PomArrange {
    /**
     * 用于构建新的version  properties
     */
    private final Map<String, String> versionMap = new HashMap<>();
    /**
     * 解析的dependency Node
     */
    private final Set<Node> dependencyNodeSet = new HashSet<>();

    public PomArrange(String[] paths) {
        XmlUtil.setNamespaceAware(false);
        //Pom中properties所有值
        Map<String, String> propertiesMap = new HashMap<>();
        //用于防重
        Set<String> artifactIdSet = new HashSet<>();

        for (String path : paths) {
            if (!FileUtil.exist(path)) {
                throw new RuntimeException("文件不存在" + path);
            }
            Document doc = XmlUtil.readXML(path);
            NodeList propertiesList = XmlUtil.getNodeListByXPath("//project/properties/*", doc);

            for (int i = 0; i < propertiesList.getLength(); i++) {
                Node item = propertiesList.item(i);
                propertiesMap.put(item.getNodeName(), item.getTextContent());
            }


            NodeList dependencyList = XmlUtil.getNodeListByXPath("//project/dependencies/dependency", doc);
            for (int i = 0; i < dependencyList.getLength(); i++) {
                Node node = dependencyList.item(i);
                String artifactId = getArtifactId(node);
                //重复就不处理了
                if (artifactIdSet.contains(artifactId)) {
                    continue;
                }

                artifactIdSet.add(artifactId);

                // ===============  处理version ===============
                String version = null;
                Node versionNode = (Node) XmlUtil.getByXPath("version", node, XPathConstants.NODE);
                if (versionNode != null) {
                    version = versionNode.getTextContent();
                    String versionProp = ReUtil.getGroup1("\\$\\{(.*?)\\}", version);
                    if (versionProp != null) {
                        version = propertiesMap.get(versionProp);
                    }
                }
                if (version != null) {
                    versionNode.setTextContent(StrUtil.format("${{}.version}", artifactId));
                    versionMap.put(artifactId + ".version", version);
                }
                // ===============  处理version ===============
                dependencyNodeSet.add(node);
            }
        }
    }

    private String getArtifactId(Node node) {
        return XmlUtil.getByXPath("artifactId", node, XPathConstants.STRING).toString();
    }

    /**
     * 获取version properties Text
     */
    public String getVersionText() {
        return XmlUtil.mapToXmlStr(versionMap, "properties", null, true, true);
    }

    /**
     * 获取Dependencies Text
     */
    public String getDependenciesText() {
        return dependencyNodeSet.stream()
                .sorted(Comparator.comparing(this::getArtifactId))
                .map(e -> XmlUtil.toStr(e, "utf-8", true, true))
                .reduce((s, s2) -> s + s2)
                .orElse(null);
    }

    public static void main(String[] args) {
        String[] paths = new String[]{
                ".../pom.xml",
                ".../pom.xml",
        };

        PomArrange pomMavenGet = new PomArrange(paths);
        //dependenciesText
        System.out.println(pomMavenGet.getDependenciesText());
        //versionText
        System.out.println(pomMavenGet.getVersionText());

    }
}

versionText 效果:

<HikariCP.version>3.3.1</HikariCP.version>
略...

dependenciesText 效果:

        <dependency>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
            <version>${HikariCP.version}</version>
        </dependency>
       略...

最后当然是需要人为去检查了,比较只是个工具~