Jenkins 持续集成之使用批处理替换文件中的目标字符串

Jenkins 持续集成之使用批处理替换文件中的目标字符串

一、背景

在 Android 项目开发中使用 Jenkins 持续集成,将可以解耦的 module 作为一个独立项目,然后在 Jenkins 上自动打包,推送到 maven 私服,最后主工程通过 gradle 将 aar 包添加到项目中。一般情况下,当 module 的版本发生改变时,只需要修改build.gradle 中的 versionName,然后打一个新的版本推送到 maven 私服即可。而实际中,由于项目需要,这个版本号却需要从另外一个项目中获取。这样问题就来了,我们需要从另外一个项目的源文件中读取版本号,然后写入 module 的 build.gradle 文件,再提交修改到 git 仓库,通过 webhook 触发 module 的 Jenkins 构建推送到 maven。

假设主工程为 A,解耦的 module 新建为依赖项目 B,而我们需要的第三个项目 C,Jenkins 集成流程如下:

  1. git 拉取 C 项目,执行构建任务,并且把构建结果复制到 B 的约定目录(项目需要);
  2. 约定 C 项目的源文件中有一个文件 x.txt,这个文件中有我们需要的 B 的版本号
  3. 通过批处理脚本,从 x.txt 中读取到版本号:versionName
  4. 将 versionName 替换 B 项目中 build.gradle 中的 versionName
  5. cd 到 B 项目的根目录,执行 git add .,git commit -m “msg”,git push,将构建结果和build.gradle提交到仓库。
  6. 提交操作触发 B 项目的 Jenkins 构建,构建成功后将新版本上传到 maven仓库。

而我遇到的问题就是:

  1. 读取 C 项目源文件中 x.txt 中的版本号(x.txt 的内容可能是一个json字符串:{“versionName”:“1.0.0”}),那么我们需要用 bat 脚本读取到 “1.0.0”
  2. 将从 C 项目源文件中读取到的 versionName 替换 B 项目build.gradle中的 versionName

本文主要是记录一下如何使用批处理,解决以上两个问题。

二、提取x.txt文件中的versionName

这里主要的问题是如何解析这个json字符串,解决问题的思路是将将 json 字符串替换成 name=value 的格式,然后设置为变量,最后就可以通过name 来读取其值value。但是有一个缺点,如果中间json格式不是这种非标准格式,则会出错,bat脚本如下:

rem # 读取文件,在Jenkins构建中,我们是知道C项目的源码目录的所以文件的路径是已知的
@echo off
set versionFile=C:\Users\lenovo\Desktop\transport\bat\version.txt
echo %versionFile%
rem # 读取文件的第一行,并赋值给:a
set /p a=<%versionFile%
echo.%a%
pause

rem # 解析json,拿到版本号,假定上面读取到的a={"versionName":"1.0.0"}
@echo off
setlocal
set string={"versionName":"1.0.0"}
rem # Remove quotes
set string=%string:"=%
echo %string%
rem # Remove braces
set "string=%string:~1,-1%"
echo %string%
rem # Change colon+space by equal-sign
set string=%string::==%
echo %string%
rem # Separate parts at comma into individual assignments
set "%string:,=" & set "%"
echo %string%
echo %versionName%
pause

三、替换build.gradle中的versionName

原理比较简单,一行一行地读取build.gradle,判断是否包含“versionName”,如果有,则用新的替代,并写入temp.txt,否则直接写入temp.txt,最后再将temp.txt重命名为build.gradle。注意的是循环读取文件时,使用 delims 而不是 tokens,后者不会保存每行前的空格。脚本如下:

@echo off
echo ***** Replace "123" as "abc" *****
set strOld=abc
set strNew=        versionName "2.0.0"
set readFile=C:\Users\lenovo\Desktop\transport\bat\build.txt

setlocal enabledelayedexpansion
for /f "delims=*" %%j in (%readFile%) do (
    set "tmp=%%j"
    if not !tmp!.==. (
	    set found=hello
	    echo !tmp!|find "versionName">nul&&set found=world
        if !found! equ world (
		   echo %strNew%
           echo %strNew%>>temp.txt
        ) else (
           echo !tmp!>>temp.txt
        )
    )
)
move temp.txt %readFile% 
pause

拿到了版本号:versionName,也修改了目标build.gradle中的versionName的值,那么就可以提交 git 仓库,继续完成 Jenkins 自动化构建流程了。

四、记一下:遇到的 batch 代码

4.1 读取文件

@echo off
set versionFile=C:\Users\lenovo\Desktop\transport\bat\version.txt
echo %versionFile%
rem # 读取文件的第一行,并赋值给:a
set /p a=<%versionFile%
echo.%a%
pause
@echo off
set versionFile=C:\Users\lenovo\Desktop\transport\bat\version.txt
rem # 读取整文件
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /F "delims=" %%a IN (%versionFile%) DO (
call set filelist=%%filelist%%%%a
)
echo !filelist!
ENDLOCAL
pause

4.2 写如文件

@echo off
set content=abcdefghijklmnopqrstuvwxyz
rem # 写入文件
echo %content%>>C:\Users\lenovo\Desktop\temp.txt
pause

4.3 字符串替换

  1. 利用A:B=C的方式来替换字符串,具体含义就是在字符串变量A中查找所有的子串B并且替换成子串C
@echo off
setlocal
set string={"other":1234,"year":2016,"value":"str","time":"05.01"}
rem Remove quotes
set string=%string:"=%
echo %string%
rem Remove braces
set "string=%string:~1,-1%"
echo %string%
rem Change colon+space by equal-sign
set string=%string::==%
rem Separate parts at comma into individual assignments
set "%string:,=" & set "%"

echo other=%other%
echo year=%year%
echo value=%value%
echo time=%time%
pause

五、参考

用批处理批量替换文件中的某个字符串
Parse simple JSON string in Batch

你可能感兴趣的:(环境搭建,android,工具)