Maven插件:exec-maven-plugin-代码执行或者直接输出内置变量信息
文章目录
- 概述
- 使用
- 应用
- 自行实现记录项目打包插件
概述
官网: https://www.mojohaus.org/exec-maven-plugin/usage.html
依赖: https://mvnrepository.com/artifact/org.codehaus.mojo/exec-maven-plugin
使用
<plugin><groupId>org.codehaus.mojo</groupId><artifactId>exec-maven-plugin</artifactId><version>3.3.0</version> <!-- 请使用最新版本 --><executions><execution><id>unique-id-1</id><phase>validate</phase> <!-- 指定在哪个阶段执行 --><goals><goal>exec</goal></goals><configuration><executable>echo</executable><arguments><argument>${project.build.outputDirectory}</argument><argument>${project.basedir}</argument></arguments></configuration></execution><execution><id>unique-id-2</id><phase>validate</phase> <!-- 指定在哪个阶段执行 --><goals><goal>java</goal></goals><configuration><mainClass>work.linruchang.chatgptweb.maven.MavenRecordGitInfo</mainClass><arguments><argument>lrc</argument><argument>20240707</argument></arguments></configuration></execution></executions></plugin>
应用
自行实现记录项目打包插件
类似同样的功能,可以直接使用Maven的另一款插件:git-commit-id-maven-plugin
MavenRecordGitInfoPlugin.java
@Slf4j
public class MavenRecordGitInfoPlugin {private static String pluginName = "打包信息插件";/*** 获取当前的项目目录** @return*/public static File getCurrentProjectDir(MavenRecordGitInfoConfig mavenRecordGitInfoConfig) {File targetClassDir = FileUtil.file("").getAbsoluteFile();String gitCmd = "{execGitPath} rev-parse --show-toplevel";gitCmd = StrUtil.format(gitCmd, Dict.parse(mavenRecordGitInfoConfig));Process process = RuntimeUtil.exec(new String[0], targetClassDir, gitCmd);String currentProjectDir = StrUtil.trim(IoUtil.readUtf8(process.getInputStream()));return FileUtil.file(currentProjectDir);}/*** 项目打包时的信息** @return*/public static ProjectPackageInfo getProjectPackageInfo(MavenRecordGitInfoConfig mavenRecordGitInfoConfig) {ProjectPackageInfo projectPackageInfo = ProjectPackageInfo.builder().projectPackageTime(DateUtil.now()).projectPackageIp(SystemUtil.getHostInfo().getAddress()).build();String execGitPath = mavenRecordGitInfoConfig.getExecGitPath();if (!EnhanceRuntimeUtil.hasCommand(execGitPath)) {log.warn("【{}】警告:记录打包信息失败,可执行Git指令({})不生效", pluginName, execGitPath);return projectPackageInfo;}File currentProjectDir = getCurrentProjectDir(mavenRecordGitInfoConfig);projectPackageInfo.setProjectPackageDir(FileUtil.getAbsolutePath(currentProjectDir));// 输出格式// commitId: 4216872// commitAuthor: LinRuChang// commitTime: 2024-07-06 14:38:57// commitBranch: (HEAD -> master, origin/master, origin/HEAD)// commitMessage: 修复:【切换】展示用户默认AI模型问题String gitCmd = "{execGitPath} log --format='commitId: %h %ncommitAuthor: %an %ncommitTime: %ad %ncommitBranch: %d %ncommitMessage: %s' --date=format:'%Y-%m-%d %H:%M:%S' -1";gitCmd = StrUtil.format(gitCmd, Dict.parse(mavenRecordGitInfoConfig));String gitInfoRawContent = EnhanceRuntimeUtil.execResult(new String[0], currentProjectDir, gitCmd);if (StrUtil.isBlank(gitInfoRawContent)) {log.warn("【{}】警告:记录打包信息失败,获取不到Git提交信息,请检查", pluginName);return projectPackageInfo;}log.info("【{}】当前Git最新提交信息如下:\n{}", pluginName, gitInfoRawContent);// 去除前后缀的单引号gitInfoRawContent = StrUtil.strip(gitInfoRawContent, EnhanceStrUtil.singleQuotationMark);List<String> gitInfoRawContentS = StrUtil.splitTrim(gitInfoRawContent, StrUtil.LF);Map<String, String> gitParseInfoMap = gitInfoRawContentS.stream().filter(StrUtil::isNotBlank).filter(rowContent -> StrUtil.splitTrim(rowContent, EnhanceStrUtil.COLON).size() > 1).collect(CollectorUtil.toMap(rowContent -> StrUtil.trim(StrUtil.subBefore(rowContent, StrUtil.COLON, false)),rowContent -> StrUtil.strip(StrUtil.trim(StrUtil.subAfter(rowContent, StrUtil.COLON, false)), EnhanceStrUtil.singleQuotationMark),(v1, v2) -> v1));BeanUtil.copyProperties(gitParseInfoMap, projectPackageInfo, true);// 获取具体的分支(HEAD -> master, origin/master, origin/HEAD)String commitBranch = projectPackageInfo.getCommitBranch();if (StrUtil.isNotBlank(commitBranch)) {String branchInfoRawContent = CollUtil.findOne(StrUtil.splitTrim(commitBranch, StrUtil.COMMA), content -> {return StrUtil.containsAnyIgnoreCase(content, "->") && StrUtil.containsAnyIgnoreCase(content, "HEAD");});String simpleCommitBranch = StrUtil.trim(StrUtil.subAfter(branchInfoRawContent, "->", false));projectPackageInfo.setCommitBranch(StrUtil.blankToDefault(simpleCommitBranch, commitBranch));}return projectPackageInfo;}public static void main(String[] args) {try {Console.log("\n===============【{}】开始=======================\n", pluginName);MavenRecordGitInfoConfig mavenRecordGitInfoConfig = MavenRecordGitInfoConfig.parse(ArrayUtil.get(args, 0));log.info("【{}】原始配置参数:{},最终生效的配置参数:{}", pluginName, args, JSONUtil.toJsonStr(mavenRecordGitInfoConfig));ProjectPackageInfo projectPackageInfo = getProjectPackageInfo(mavenRecordGitInfoConfig);String projectPackageInfoJson = StrUtil.nullToEmpty(JSONUtil.toJsonPrettyStr(projectPackageInfo));File packageInfoFile = FileUtil.file(mavenRecordGitInfoConfig.getPackageInfoFileName());FileUtil.writeString(projectPackageInfoJson, packageInfoFile, CharsetUtil.UTF_8);log.info("【{}】当前项目的打包信息【{}】:{}", pluginName, FileUtil.getAbsolutePath(packageInfoFile), projectPackageInfo);} catch (Exception e) {// 必须捕获异常,否则这里面有任何的报错都会阻止项目的打包log.error("【{}】发生未知错误,导致插件崩溃", pluginName, e);} finally {Console.log("\n===============【{}】结束=======================\n", pluginName);}}}
MavenRecordGitInfoConfig.java
/*** @author LinRuChang* @version 1.0* @date 2024/07/08* @since 1.8**/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@ApiModel(description = "Git记录插件配置信息")
public class MavenRecordGitInfoConfig {private final static String defaultPackageInfoFileName = "package.info";private final static String defaultExecGitPath = "git";/*** 生成的打包信息文件的文件名*/private String packageInfoFileName = defaultPackageInfoFileName;/*** 生成打包信息时,需使用到Git执行程序,如果未设置成全局可执行命令,必须设置Git绝对路径地址*/private String execGitPath = defaultExecGitPath;public static MavenRecordGitInfoConfig parse(String rawContent) {MavenRecordGitInfoConfig mavenRecordGitInfoConfig = new MavenRecordGitInfoConfig();if(StrUtil.isBlank(rawContent)) {return mavenRecordGitInfoConfig;}Map<String, String> parseConfigInfo = StrUtil.splitTrim(rawContent, StrUtil.COMMA).stream().filter(StrUtil::isNotBlank).map(StrUtil::trim).filter(rowContent -> StrUtil.isNotBlank(StrUtil.subAfter(rowContent, EnhanceStrUtil.equalMark, false))).collect(CollectorUtil.toMap(rowContent -> StrUtil.subBefore(rowContent, EnhanceStrUtil.equalMark, false),rowContent -> StrUtil.subAfter(rowContent, EnhanceStrUtil.equalMark, false),(v1, v2) -> v1));BeanUtil.copyProperties(parseConfigInfo,mavenRecordGitInfoConfig, true);return mavenRecordGitInfoConfig;}public static void main(String[] args) {MavenRecordGitInfoConfig parse = MavenRecordGitInfoConfig.parse("packageInfoFileName=package.info2,git=");Console.log(parse);}}
ProjectPackageInfo.java
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@ApiModel(description = "项目打包信息")
public class ProjectPackageInfo implements Serializable {private static final long serialVersionUID = -7381111550970133734L;@ApiModelProperty("提交记录ID")String commitId;@ApiModelProperty("提交作者")String commitAuthor;@ApiModelProperty("提交的时间")String commitTime;@ApiModelProperty("提交记录所处的分支")String commitBranch;@ApiModelProperty("提交的描述信息")String commitMessage;@ApiModelProperty("项目打包的时间")String projectPackageTime;@ApiModelProperty("项目打包时的IP地址")String projectPackageIp;@ApiModelProperty("项目打包时的项目目录")String projectPackageDir;}
pom.xml
<plugin><groupId>org.codehaus.mojo</groupId><artifactId>exec-maven-plugin</artifactId><version>3.3.0</version> <!-- 请使用最新版本 --><executions><!--<execution>--><!-- <id>unique-id-1</id>--><!-- <phase>validate</phase> <!– 指定在哪个阶段执行 –>--><!-- <goals>--><!-- <goal>exec</goal>--><!-- </goals>--><!-- <configuration>--><!-- <executable>echo</executable>--><!-- <arguments>--><!-- <argument>${project.build.outputDirectory}</argument>--><!-- <argument>${project.basedir}</argument>--><!-- </arguments>--><!-- </configuration>--><!--</execution>--><execution><id>unique-id-2</id><!--<phase>validate</phase> <!– 指定在哪个阶段执行 –>--><!--必须这个阶段,validate代码还未编译完成,第一次运行会报类不存在的现象,故需使用compile这个阶段--><phase>compile</phase> <!-- 指定在哪个阶段执行 --><goals><goal>java</goal></goals><configuration><mainClass>work.linruchang.chatgptweb.maven.MavenRecordGitInfoPlugin</mainClass><arguments><argument>packageInfoFileName=package.info,execGitPath=git</argument></arguments></configuration></execution></executions></plugin></plugins>
@Api(tags = "管理员模块(不对外开放)")
@RestController
@RequestMapping("admin")
@Slf4j
public class AdminController {@ApiOperation(value = "查看系统打包版本信息")@GetMapping("/systemPackageInfo")public ResponseResult<ProjectPackageInfo> systemPackageInfo() {String s = ResourceUtil.readUtf8Str(MavenRecordGitInfoPlugin.mavenRecordGitInfoConfigFileName);MavenRecordGitInfoConfig mavenRecordGitInfoConfig = JSONUtil.toBean(s, MavenRecordGitInfoConfig.class);String packInfoContent = ResourceUtil.readUtf8Str(mavenRecordGitInfoConfig.getPackageInfoFileName());ProjectPackageInfo projectPackageInfo = JSONUtil.toBean(packInfoContent,ProjectPackageInfo.class);return ResponseResult.success(projectPackageInfo);}
}
相关文章:

Maven插件:exec-maven-plugin-代码执行或者直接输出内置变量信息
文章目录 概述使用应用自行实现记录项目打包插件 概述 官网: https://www.mojohaus.org/exec-maven-plugin/usage.html 依赖: https://mvnrepository.com/artifact/org.codehaus.mojo/exec-maven-plugin 使用 <plugin><groupId>org.codeh…...

https://ffmpeg.org/
https://ffmpeg.org/ https://www.gyan.dev/ffmpeg/builds/ https://github.com/BtbN/FFmpeg-Builds/releases F:\Document_ffmpeg F:\Document_ffmpeg\ffmpeg-master-latest-win64-gpl-shared\bin...

linux 源码部署polardb-x 错误汇总
前言 在linux 源码部署polardb-x 遇到不少错误,特在此做个汇总。 问题列表 CN 启动报错 Failed to init new TCP 详细错误如下 Caused by: Failed to init new TCP. XClientPool to my_polarx#267b21d8127.0.0.1:33660 now 0 TCP(0 aging), 0 sessions(0 runni…...

vscode用快捷键一键生成vue模板
项目中有些代码模块是固定的,如下面的代码所示,为了不重复写这些相同的代码,我们可以使用快键键一键生成模板。 流程: 中文:首选项-> 用户代码片段 -> 输入框中输入vue,找到vue.json文件(没有vue.j…...

ARM 架构硬件新趋势:嵌入式领域的未来
目录 目录 一、ARM 架构概述 二、新趋势一:AI 加速器集成 三、新趋势二:更高效的电源管理 四、新趋势三:安全性增强 五、结语 随着物联网 (IoT) 和边缘计算的发展,ARM 架构在嵌入式系统中的应用越来越广泛。从智能手机到智能…...

星戈瑞-二油酰磷脂酰乙醇胺标记荧光素 DOPE-FITC
DOPE-FITC,全称为1,2-dioleoyl-sn-glycero-3-phosphoethanolamine-N-FITC,是一种结合了二油酰磷脂酰乙醇胺(DOPE)与荧光素异硫氰酸酯(FITC)的复合标记物。以其独特的磷脂结构和强烈的绿色荧光特性ÿ…...

堆的实现(偷懒版)
🌹个人主页🌹:喜欢草莓熊的bear 🌹专栏🌹:数据结构 目录 前言 一、堆的实现 1.1 堆的向下调整算法 思路: 1.2 堆的向上调整算法 1.3 堆的创建 1.4 堆的复杂度计算 向下调整建堆的复杂度…...

一键启动,智能分拣:3D视觉系统赋能多SKU纸箱高效混拆作业
在快速发展的电商时代,仓储物流面临着前所未有的挑战。尤其是面对成千上万种不同的纸箱,如何实现快速、准确、高效的混拆作业,成为了众多企业亟待解决的问题。幸运的是,随着科技的进步,3D视觉系统正逐步成为这一领域的…...

unity草体渲染方案 GPU Instaning
有一天看项目里的FrameDebug发现在森林系的场景里草体的drawcall差不多有100多 主要是因为灯光贴图,位置等不一样导致的打断合批,导致一个批次只能渲染10个左右的草体 之前有了解过unity有接口(Graphics.DrawMeshInstanced)可以把…...

最近在西安召开的学术会议:EI检索超快,信息系统与计算技术领域!
第十二届信息系统与计算技术国际会议(ISCTech 2024)将于2024年11月8日-11月11日在中国西安盛大举行,由长沙理工大学主办,同济大学、西北工业大学联合协办。会议聚焦信息系统与计算技术等相关研究领域,广泛邀请国内外知…...
sRGB和伽马矫正
sRGB和伽马矫正 1. sRGB的含义: sRGB是一种色彩空间,全称为“标准红色-绿色-蓝色”(standard Red Green Blue)。它由惠普和微软在1996年共同开发,用于确保不同设备上色彩的一致性。 在sRGB中,“s”代表“…...

Summer School science communication project--Laptop Selection Suggestion
目录 Introduction Audiance Usage CPU What is a central processing unit (CPU) Notable makers of CPUs GPU Graphics Card: GPU The classifications of graphics cards The brands of graphics cards Dedicated Graphics Cards GeForce MX Series: GeForc…...

网络编程概念详解模拟回显客户端服务器
目录 1.网络中重要的概念 1)IP地址: 2)端口号: 3)协议 协议分层 OSI七层模型(教科书) TCP/IP五层模型 封装和分用 网络套接字 面试题:TCP/UDP的区别? UDP数据报套接字编程 模拟一个回…...
代码随想录第二十四天|动态规划(8)
目录 LeetCode 300. 最长递增子序列 LeetCode 674. 最长连续递增序列 LeetCode 718. 最长重复子数组 LeetCode 1143. 最长公共子序列 LeetCode 1035. 不相交的钱 LeetCode 53. 最大子序和 LeetCode 392. 判断子序列 总结 LeetCode 300. 最长递增子序列 题目链接&#…...
编程-设计模式 3:单例模式
设计模式 3:单例模式 定义与目的 定义:单例模式确保一个类只有一个实例,并提供一个全局访问点来访问该实例。目的:这种模式通常用于那些需要频繁访问且只需一个实例的对象,例如配置管理器、日志记录器等。 实现示例…...
Kaniko 构建 Docker 镜像
Kaniko 主要用于构建 Docker 镜像,而不是运行程序。它的主要用途是从 Dockerfile 构建容器镜像,但它并不负责运行容器或程序。以下是 Kaniko 的主要功能和局限性: 主要功能 构建镜像:Kaniko 从 Dockerfile 构建容器镜像。它通过…...

Javascript常见算法(每日两个)
合并两个有序链表 在JavaScript中,合并两个有序链表通常指的是将两个已经按照某种顺序(如升序或降序)排列的链表合并成一个新的有序链表。由于JavaScript本身不直接支持链表数据结构,我们通常会用对象或数组来模拟链表的行为。但…...

Spring -- 事务
Spring中事务的操作分为两类:(1)编程式事务 – 手动写代码操作事务(2)声明式事务 – 利用注解开启事务和提交事务 1. 编程式事务 准备Controller RestController RequestMapping("/user") public class UserInfoController {Autowiredprivate UserInfoService use…...

生命密码的破译者:AI如何学会读懂DNA语言?
引言 如果能像解读一本神秘的书籍那样,理解DNA的“语言”,将是多么令人兴奋的科学突破!如今,这正在逐步变为现实。科学家们训练出的AI模型GROVER正如一个勤奋的学生,学习着DNA的每一个“单词”和“语法”,…...

大数据信用报告查询哪家平台的比较好?
相信在搜索大数据信用的你,已经因为大数据信用不好受到了挫折,想详细了解一下自己的大数据信用,但是找遍了网络上的平台之后才发现,很多平台都只提供查询服务,想要找一个专业的平台查询和讲解很困难。下面本文就为大家…...
Flink 失败重试策略 :restart-strategy.type
在 Apache Flink 中,restart-strategy.type 用于指定作业的重启策略(Restart Strategy),它决定了作业在失败后如何恢复。 Flink 提供了 4 种内置重启策略,可以通过 flink-conf.yaml 或代码动态配置。 1. 可配置的 rest…...
pandas 字符串存储技术演进:从 object 到 PyArrow 的十年历程
文章目录 1. 引言2. 阶段1:原始时代(pandas 1.0前)3. 阶段2:Python-backed StringDtype(pandas 1.0 - 1.3)4. 阶段3:PyArrow初次尝试(pandas 1.3 - 2.1)5. 阶段4…...
React从基础入门到高级实战:React 实战项目 - 项目三:实时聊天应用
React 实战项目:实时聊天应用 欢迎来到本 React 开发教程专栏 的第 28 篇!在前 27 篇文章中,我们从 React 的基础概念逐步深入到高级技巧,涵盖了组件设计、状态管理、路由配置、性能优化和架构模式等核心知识。这一次,…...
Vue前端篇——Vue 3的watch深度解析
📌 前言 在 Vue.js 的世界中,“数据驱动”是其核心理念之一。而在这一理念下,watch 扮演着一个非常关键的角色。它允许我们监听响应式数据的变化,并在其发生变化时执行特定的业务逻辑。 本文将通过实际代码示例,深入…...

【bug】Error: /undefinedfilename in (/tmp/ocrmypdf.io.9xfn1e3b/origin.pdf)
在使用ocrmypdf的时候,需要Ghostscript9.55及以上的版本,但是ubuntu自带为9.50 然后使用ocrmypdf报错了 sudo apt update sudo apt install ghostscript gs --version 9.50 #版本不够安装的版本为9.50不够,因此去官网https://ghostscript.c…...

NLP学习路线图(二十九):BERT及其变体
在自然语言处理(NLP)领域,一场静默的革命始于2017年。当谷歌研究者发表《Attention is All You Need》时,很少有人预料到其中提出的Transformer架构会彻底颠覆NLP的发展轨迹,更催生了以GPT系列为代表的语言模型风暴,重新定义了人类与机器的交互方式。 一、传统NLP的瓶颈:…...
嵌入式面试高频(5)!!!C++语言(嵌入式八股文,嵌入式面经)
一、C有几种传值方式之间的区别 一、值传递(Pass by Value) 机制:创建参数的副本,函数内操作不影响原始数据语法:void func(int x)特点: 数据安全:原始数据不受影响性能开销:需要复…...

蒲公英盒子连接问题debug
1、 现象描述 2、问题解决 上图为整体架构图,其中左边一套硬件设备是放在机房,右边是放在办公室。左边的局域网连接了可以访问外网的路由器,利用蒲公英作为旁路路由将局域网暴露在外网环境下。 我需要通过蒲公英作为旁路路由来进行远程访问&…...

计算机网络第2章(下):物理层传输介质与核心设备全面解析
目录 一、传输介质1.1 传输介质的分类1.2 导向型传输介质1.2.1 双绞线(Twisted Pair)1.2.2 同轴电缆(Coaxial Cable)1.2.3 光纤(Optical Fiber)1.2.4 以太网对有线传输介质的命名规则 1.3 非导向型传输介质…...
Langchain学习笔记(十一):Chain构建与组合技巧
注:本文是Langchain框架的学习笔记;不是教程!不是教程!内容可能有所疏漏,欢迎交流指正。后续将持续更新学习笔记,分享我的学习心得和实践经验。 前言 在LangChain的发展过程中,API设计经历了重…...