利用ant脚本 自动构建svn增量/全量 系统程序升级包
首先请允许我这样说,作为开发或测试,你一定要具备这种 本领。你可以手动打包、部署你的工程,但这不是最好的方法。最好的方式就是全自动化的方式。开发人员提交了代码后,可以自动构建、打包、部署到测试环境。 测试通过后进入到模拟环境或是直接发布的生产环境,这个过程可以是全自动的。但这个自动化的方式有一些公司用到了,但也有很多公司还不知道,他们的攻城师 天天在做反复、没有多大意义的、浪费生命的事情。当然这种方式一般针对做自己的产品,如电商、通信行业。而给其他公司或企业做项目的比较少利用这种方式, 当然也可以利用这种方式,只是不能直接发布到客户的服务器而已。当然有些公司是专门有人做这部分事情的!
说了这么多也没有什么恶意,只是觉得这种方式可以大大提高效率,降低人力、物力、财力而已。勿喷,O(∩_∩)O哈哈~嘿嘿~
在 部署项目或打包项目中,通常大家都是手动部署或打包的多。很多公司把这一任务交个了我们做开发的,其实这部分应该谁做呢?本质上应该是测试的来完成,但一 些公司的测试不会做这个,慢慢的就变成了开发的事情。有些公司是人手比较少、不健全,所以一部分人自己承担了这个事情。在我们手动打包的时,其实这是一个 重复的、没有技术含量的、耗费体力的活儿。一般步骤就是更新svn上代码、修改好相关的配置、编译class、发布到tomcat(web工程)、测试启 动无误、手动打包。
而有一种比较简单快速的方式就是利用meven或ant来完成这些工作,只要我们编写好脚本后。给相关的工作人 员去运行这部分脚本就可以完成打包,甚至是部署项目,这些都是so easy~!我个人也比较赞成使用这种方式,比较简单、快速、重用性好,最难的可能编写build脚本,但这个脚本其实也是很简单的,它就想dos命令 行,只不过它是用xml方式来完成命令行的而已。所以测试会写ant的build脚本这个也是应该的,如果你不会的话,还是建议你学习学习。反正是百益无 一害的事情,何乐而不为呢!
一、基本流程
利用ant打包项目或打增量包的基本流程
值 得一提的是jar包这个部分,这个步骤是为下面编译增量包做准备的。因为增量包导出的增量文件,它依赖于整个项目的其他代码,如果没有这些代码的支持是编 译不通过。然而又不能直接通过diff得到增量的class,所以只能导出增量文件后,通过引用全部工程的代码的class再进行编译即可。
二、运行环境
1、安装jdk,不会自己上网查其他的
2、如果你还没有安装ant,那么你可以参考:http://www.cnblogs.com/hoojo/archive/2013/06/14/java_ant_project_target_task_run.html
会介绍一下ant的安装和使用的方法。
3、这里需要用到svn的ant相关工具包、命令支持。你需要下载svnant-1.3.1.zip,将里面的lib库放置在你的ant脚本的编译运行环境中。
4、因为某些项目使用到了泛型、annotation注解,使用javac有些代码是编译不通过的,所以这里使用了jdt的编译方式。参考:使用eclipse JDT compile class 会有很详细的介绍。
需要用到
jdtCompilerAdapter.jar
org.eclipse.jdt.compiler.tool_1.0.1.v_793_R33x.jar
org.eclipse.jdt.core_3.3.3.v_793_R33x.jar
org.eclipse.jdt.debug.ui_3.2.102.v20071002_r332.jar
复制到ant_home/lib目录下,如果是利用eclipse运行脚本就需要把它加载到运行环境中。可以参考上面的:使用eclipse JDT compile class
三、编写ant的build脚本
1、首先看看ant工程的目录结构
简单介绍下目录结构:
src下面的ExportIncrementFiles.java是导出增量文件要用的,它在build命令increment中执行。它会读取diff 比较后的文件中的内容,并导出文件
dest 是checkout出来最新的svn的工程
dist 是编译上面dest目录中的工程,也是svn全量war的工程目录和jar
increment_dest 是增量工程,也就是上面的ExportIncrementFiles工具导出的工程
increment_dist 是编译上面increment_dest 的工程,也是增量包的工程目录
因为每个人的项目工程目录结构不一样,所以这个脚本并不会通用,我这里指针对自己的项目进行测试。
lib中是运行环境需要的jar库,其中主要的就是svnlib 这个你可以去下载 svnant-1.3.1.zip 以及JDT编译class的jar包,这个可以通过eclipse中的plugin中的jar包找到,可以参考:使用eclipse JDT compile class
increment.export.jar就是ExportIncrementFiles的class打成的jar包,这个是自己打的包,可以直接应用class也可以的,在increment命令引用,jar下载:http://download.csdn.net/detail/ibm_hoojo/6501165
build.properties是当前build的配置文件
build.xml就是主要的ant脚本
选中部分是打的war包,这个就可以部署了
patch.txt就是svn的diff 比较出的增量文件的目录路径列表
2、ExportIncrementFiles.java 导出增量文件
package com.hoo.util;import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.FileReader;/*** <b>function:</b> 导出在增量的文件* @author hoojo* @createDate 2013-11-2 下午10:00:01* @file ExportIncrementFiles.java* @package com.hoo.util* @project AntTest* @blog http://blog.csdn.net/IBM_hoojo* @email hoojo_@126.com* @version 1.0*/public class ExportIncrementFiles {/*** <b>function:</b> 导出增量文件* @author hoojo* @createDate 2013-11-2 下午10:15:43* @param configPath 增量文件路径配置目录* @param baseDir 基本路径 目标位置* @param destDir 增量文件保存位置* @throws Exception*/private static void export(String configPath, String baseDir, String destDir) throws Exception {String srcFile = baseDir + configPath;String desFile = destDir + configPath;int lastIndex = desFile.lastIndexOf("/");String desPath = desFile.substring(0, lastIndex);File srcF = new File(srcFile);if(srcF.exists()){//如果不存在这样的源文件,就不再拷贝,这个用来解决版本之间有删除文件的情况。File desF = new File(desFile);File desP = new File(desPath);if(!desP.exists()) {desP.mkdirs();}System.out.println(srcFile);FileInputStream fis = new FileInputStream(srcF);FileOutputStream fos = new FileOutputStream(desF);byte[] buf = new byte[1024];int len = 0;while((len = fis.read(buf)) != -1) {fos.write(buf,0,len);}fos.flush();fos.close();fis.close();}}/*** <b>function:</b> 主函数 执行导出增量包任务* @author hoojo* @createDate 2013-11-2 下午10:00:01* @param args 参数1 增量包导出文件路径,参数2 要导出的文件的所在目标位置,参数3 增量包导出保存的位置路径*/public static void main(String[] args) {if (args.length > 0) {if (args.length == 1 && "help".equals(args[0])) {System.out.println("args[0] is Export Increment Files content path");System.out.println("args[1] is Export Increment Files target path");System.out.println("args[2] is Increment Files Export loaction");} else {String configPath = args[0];String baseDir = args[1];String destDir = args[2];try {BufferedReader br = new BufferedReader(new FileReader(configPath));String s = null;while((s = br.readLine()) != null) {s = s.trim();//去掉路径前面的空格String str = destDir + s;if(!destDir.equals(str)){//过滤空行export(s, baseDir, destDir);}}br.close();} catch (Exception e) {e.printStackTrace();}}}}}main函数参数看注释,主要就是读取patch.txt增量文件路径,导出文件到指定目录的。
3、build 脚本
<?xml version="1.0" encoding="UTF-8" ?><!-- createDate 2013-10-28 --><!-- author hoojo & http://blog.csdn.net/IBM_hoojo & http://hoojo.cnblogs.com --><project default="checkout" basedir="."><property file="build.properties"/><!-- svn 比较项目最新路径 --><property name="svn.url" value="${svn._url}"/><!-- svn 备份路径--><property name="bak.svn.url" value="${bak.svn._url}"/><property name="svn.username" value="${svn.username}"/><property name="svn.password" value="${svn.password}"/><!-- 项目名称 --><property name="webapp" value="${webapp.name}"/><!-- 目标项目的Web 名称(WEB-INF上一级的目录名称) --><property name="webroot" value="${web.root}"/><!-- svn改动文件列表信息 --><property name="compare.path.file" value="${increment.file}"/><!-- svn导出/切出文件存放目录 --><property name="dest.path" location="dest/${webapp}"/><!-- svn导出/切出文件编译后存放目录 --><property name="dist.path" location="dist/${webapp}"/><!-- svn增量文件保存目录 --><property name="increment.dest.path" location="increment_dest/${webapp}"/><!-- svn增量文件编译后保存目录 --><property name="increment.dist.path" location="increment_dist/${webapp}"/><!-- 利用jdt编译class 解决泛型不能转换的问题 需要将jdtCompilerAdapter.jarorg.eclipse.jdt.compiler.tool_1.0.1.v_793_R33x.jarorg.eclipse.jdt.core_3.3.3.v_793_R33x.jarorg.eclipse.jdt.debug.ui_3.2.102.v20071002_r332.jar复制到ant_home/lib目录下<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>--><path id="svnant.classpath"><fileset dir="${basedir}"><include name="**/*.jar"/></fileset></path><path id="buildpath"><fileset dir="${dest.path}"><include name="**/lib/*.jar"/></fileset><fileset dir="C:/Program Files/Java/jdk1.6.0_13"><include name="**/*.jar"/></fileset></path><typedef resource="org/tigris/subversion/svnant/svnantlib.xml" classpathref="svnant.classpath"/><svnSetting id="svn.settings" javahl="false" svnkit="true" username="${svn.username}" password="${svn.password}" failonerror="true"/><target name="init" description="init clean dirs"><echo message="${svn.username}"/><echo message="${svn.password}"/><echo message="${webapp}"/><echo message="${webroot}"/><echo message="${compare.path.file}"/><delete dir="${dest.path}" failonerror="false" deleteonexit="true" excludes="**/lib"/><delete dir="${dist.path}" failonerror="false" deleteonexit="true" excludes="**/lib"/><delete file="${compare.path.file}" failonerror="false"/><delete dir="${increment.dest.path}" failonerror="false" deleteonexit="true"/><delete dir="${increment.dist.path}" failonerror="false" deleteonexit="true"/></target><!-- that is to test i svnant is available //--><target name="tool-available" depends="init"><echo message="run task test svnant is available"></echo><available resource="org/tigris/subversion/svnant/svnantlib.xml" classpathref="svnant.classpath" property="available.svnant"/><echo message="SVN-ANT is available = ${available.svnant}"></echo></target><!-- 比较差异 增量文件 --><target name="diff" description="deff/compare project"><svn refid="svn.settings"><diffSummarize oldUrl="${bak.svn.url}" newUrl="${svn.url}" outFile="${compare.path.file}" recurse="true"/></svn></target><!-- 下载 切成 导出 服务器上最新代码 --><target name="checkout" depends="tool-available" description="checkout/export project code ${svn.url} "><echo message="checkout/export project code ${svn.url}"></echo><svn refid="svn.settings"><export srcUrl="${svn.url}" destPath="${dest.path}" revision="HEAD" force="true"/></svn></target><!-- javac编译 --><target name="compile"><buildnumber/><echo>compile ${dest.path} ......</echo><delete dir="${dist.path}" failonerror="false" deleteonexit="true" excludes="**/lib"/><mkdir dir="${dist.path}/classes"/><javac nowarn="true" debug="${javac.debug}" debuglevel="${javac.debuglevel}" destdir="${dist.path}/classes" source="${javac.source}" target="${javac.target}" encoding="utf-8" fork="true" memoryMaximumSize="512m" includeantruntime="false"><src path="${dest.path}/src"/><!--<compilerarg value="-Xlint:unchecked"/><compilerarg value="-Xlint:deprecation"/><compilerarg value="-Xlint"/>--><classpath refid="buildpath"/><classpath refid="svnant.classpath"/></javac></target><!-- 利用JDT编译 --><target name="compile_jdt"><buildnumber/><echo>compile ${dest_path} ......</echo><delete dir="${dist_path}" failonerror="false" deleteonexit="true" excludes="**/lib"/><mkdir dir="${dist_path}/classes"/><javac compiler="org.eclipse.jdt.core.JDTCompilerAdapter" nowarn="true" debug="${javac.debug}" debuglevel="${javac.debuglevel}" destdir="${dist_path}/classes" source="${javac.source}" target="${javac.target}" encoding="utf-8" fork="true" memoryMaximumSize="512m" includeantruntime="false"><src path="${dest_path}/src"/><classpath refid="buildpath"/><classpath refid="svnant.classpath"/></javac></target><!-- 利用JDT编译SVN 最新项目 --><target name="compile_svn"><!-- 回调任务 --><antcall target="compile_jdt"><param name="dest_path" value="${dest.path}"/><param name="dist_path" value="${dist.path}"/></antcall></target><!-- 将全部项目的class 建立jar包 --><target name="jar" depends="compile_svn"><jar destfile="${basedir}/lib/${webapp}.jar" level="9" compress="true" encoding="utf-8" basedir="${dist.path}/classes"><manifest><attribute name="Implementation-Version" value="Version: 2.2"/></manifest></jar></target><!-- 导出增量文件 --><target name="increment" depends="diff"><java classname="com.hoo.util.ExportIncrementFiles" classpath="${basedir}/lib/increment.export.jar" fork="true"><arg value="${compare.path.file}"/><arg value="${dest.path}/"/><arg value="${increment.dest.path}/"/></java></target><!-- 利用JDT编译增量文件 --><target name="compile_increment"><antcall target="compile_jdt"><param name="dest_path" value="${increment.dest.path}"/><param name="dist_path" value="${increment.dist.path}"/></antcall></target><!-- 全部打包 --><target name="war"><echo>create war file.......</echo><copy todir="${dist_path}" failonerror="false"><fileset dir="${dest_path}/${webroot}" includes="**"/></copy><move todir="${dist_path}/WEB-INF/classes" failonerror="false"><fileset dir="${dist_path}/classes" /></move><copy todir="${dist_path}/WEB-INF/classes" failonerror="false"><fileset dir="${dest_path}/src/main/" includes="**/*.xml, **/*.properties, **/*.xsd"/><fileset dir="${dest_path}/src/test/" includes="**/*.xml, **/*.properties, **/*.xsd"/><fileset dir="${dest_path}/src/resource/" includes="**/*.xml, **/*.properties, **/*.xsd"/></copy><!--得到当前日期--><tstamp><format property="DSTAMP" pattern="yyyyMMdd" locale="zh"/><format property="TSTAMP" pattern="HHmmss" locale="zh"/></tstamp><war destfile="${basedir}/${webapp}_${DSTAMP}_${TSTAMP}.war" basedir="${dist_path}" webxml="${dist_path}/WEB-INF/web.xml"/></target><!-- 全部打包 --><target name="war_svn"><antcall target="war"><param name="dest_path" value="${dest.path}"/><param name="dist_path" value="${dist.path}"/></antcall></target><!-- 全部打包 --><target name="war_increment"><copy todir="${increment.dist.path}/WEB-INF" file="${dest.path}/${webroot}/WEB-INF/web.xml"/><antcall target="war"><param name="dest_path" value="${increment.dest.path}"/><param name="dist_path" value="${increment.dist.path}"/></antcall></target><!-- svn 全量包 --><target name="svn_war" depends="checkout, compile_svn, war_svn"/><!-- 增量包 --><target name="increment_war" depends="checkout, increment, jar, compile_increment, war_increment"/></project>
4、build的配置文件内容
#Mon, 04 Nov 2013 11:18:12 +0800svn._url=http://172.31.100.100/svn/iMVS_DataComm2bak.svn._url=http://172.31.100.100/svn/iMVS_DataCommsvn.username=hoojosvn.password=mypasswebapp.name=iMVS_DataCommweb.root=WebRootincrement.file=patch.txtjavac.debuglevel=source,lines,varsjavac.target=1.6javac.source=1.6javac.debug=true运行svn_war任务可以打全部的包,也就是svn最新地址的项目工程包。
运行increment_war任务可以打增量包,也会形成一个war文件。
如果你需要发布到tomcat目录,可以写一个任务copy相关war包到tomcat的webapps的目录下,这个很简单~如果你需要调用tomcat的相关任务或命令,你需要在build脚本中加入
<target name="_def_tomcat_tasks"><!-- tasks: deploy,undeploy,reload,stop,start,list,roles,resources --><taskdef name="deploy" classname="org.apache.catalina.ant.DeployTask" /><taskdef name="list" classname="org.apache.catalina.ant.ListTask" /><taskdef name="reload" classname="org.apache.catalina.ant.ReloadTask" /><taskdef name="resources" classname="org.apache.catalina.ant.ResourcesTask" /><taskdef name="roles" classname="org.apache.catalina.ant.RolesTask" /><taskdef name="start" classname="org.apache.catalina.ant.StartTask" /><taskdef name="stop" classname="org.apache.catalina.ant.StopTask" /><taskdef name="undeploy" classname="org.apache.catalina.ant.UndeployTask" /></target>关于这些命令使用方法有兴趣的可以自己研究研究。
四、总结
整个流程稍微有点复杂,只要思路清晰这个build脚本还是很容易编写的。前提是你要懂得Java发布、编译、部署的流程,很多人用 eclipse或MyEclipse来发布工程,好像很简单。其实在工具背后也是使用这些脚本完成的,知道在用户目录下有一个 .m2的目录么,这个就是eclipse工具的meven的缓存和配置的内容。所以当我们不使用这些ide的情况下,你怎么编译、部署你的项目呢~!这篇 文章只是一个抛砖引玉的效果,希望能给大家一个启示。在这之前,我在网上搜集了些资料也没有找到打增量包的比较好的方法,全都是手动方式。
同时,在一些自动集成或持续集成的智能工具中,也大量的使用到了这方面的技术。如果你想更智能的完成这个项目的发布、部署的话,这里只是其中的第一步。有兴趣的朋友可以研究下Continuous integration或Hudson等相关自动化集成技术应用。
原文:http://www.cnblogs.com/hoojo/p/ant_increment_svn_diff_diffSummarize.html
利用ant脚本 自动构建svn增量/全量 系统程序升级包的更多相关文章
- 利用ant脚本 自动构建svn增量/全量 系统程序升级包【转】
引文:我们公司是做自己使用产品,迭代更新周期短,每次都花费较多时间和精力打包做增量更新,发现了一篇文章用于 自动构建svn增量/全量 系统程序升级包,收藏之,希望可以通过学习,更加简化我们的工作. 文 ...
- docker微服务部署之:五、利用DockerMaven插件自动构建镜像
docker微服务部署之:四.安装docker.docker中安装mysql和jdk1.8.手动构建镜像.部署项目 在上一篇文章中,我们是手动构建镜像,即: 4.1.2.5.1.2.6.1.2中的将d ...
- sql server编写通用脚本自动统计各表数据量心得
工作过程中,如果一个数据库的表比较多,手工编写统计脚本就会比较繁琐,于是摸索出自动生成各表统计数据量脚本的通用方法,直接上代码: /* 脚本来源:https://www.cnblogs.com/zha ...
- 利用jenkins实现自动构建、部署,提升团队开发效率
一大早就被群里的同学刷银川下雪的消息,看着我都发冷,突觉一阵凉风裹身,是不是该考虑秋裤了. 偏离主题,正文走起...... 使用jenkins目标:利用其结合maven完成自动构建,并部署到tomca ...
- 增量+全量备份SVN服务器
#!/bin/bash # 获取当前是星期几 DAY=$(date +%w) # 获取当前的日期 DATE=$(date '+%Y-%m-%d-%H-%M') # 获取当前版本库中最新的版本 CURR ...
- 利用Ant脚本生成war包的详细步骤
使用ant脚本前的准备 1.下载一个ant安装包.如:apache-ant-1.8.4-bin.zip.解压到E盘. 2.配置环境变量.新增ANT_HOME:E:\apache-ant-1.8.4:P ...
- RDS备份到OSS增量+全量
一.前言 阿里云的RDS备份是占用使用量的,你购买200G那备份使用量是100G左右,导致备份一般也就存半个月,2个全备份. 那半个月后之前的也就删除了,如果要持续保留更久将花费不少的金钱.所以这里用 ...
- solr-DIH:dataimport增量全量创建索引
索引创建完毕,就要考虑怎么定时的去重建, 除了写solrj,可以定时调用下面两条url进行增量或者全量创建索引 全量:http://ip:port/webapp_name/core_name/da ...
- HBase备份还原OpenTSDB数据之Export/Import(增量+全量)
前言 本文基于伪分布式搭建 hadoop+zookeeper+hbase+opentsdb之后,文章链接:https://www.cnblogs.com/yybrhr/p/11128149.html, ...
随机推荐
- UIView的autoresizingMask和autoresizesSubviews属性的剖析
UIVIew的autoresizingMask和autoresizesSubviews属性的剖析 autoresizingMask是为了iPad开发中横竖屏适配而降生的,他只能约束父子控件之间的关系. ...
- SQL Server 自增字段重置
--- 删除原表数据,并重置自增列 truncate table tablename --truncate方式也可以重置自增字段 --重置表的自增字段,保留数据 DBCC CHECKIDENT (ta ...
- camerc文件播放
下载CamtasiaStudio 5中文版,打开CamtasiaStudio.exe在左边有生成选项,点左边工具框内添加/导入媒体,则选择下面的批量生成.弹出添加文件的菜单点添加文件,加入你要转换的c ...
- BZOJ3295 [Cqoi2011]动态逆序对
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...
- 负载均衡下的资源文件配置/多站点下的资源文件夹共享(Windows IIS)
前言: 负载均衡用的是NLB,微软的方案不太靠谱,举个例子吧,AB两台服务器负载出C,如果用户访问访问C之后分配的是A,那么如果A挂了,是不会自动切换到B的.据说后来还有一种NLB的方案可以实现,也不 ...
- POJ2187Beauty Contest(任意点的最远距离 + 凸包)
题目链接 题意:就是给N个点的坐标,然后求任意两个点距离的平方最大的值 枚举超时. 当明白了 最远距离的两个点一定在凸包上,一切就好办了.求出凸包,然后枚举 #include <iostream ...
- PHP-权限控制类
http://blog.csdn.net/painsonline/article/details/7183679 <?php /** * 权限控制类 */ class include_purvi ...
- Objective-C之字典
//字典:(关键字 值) //插入代码字太小 // NSArray *array = [NSArray array];//空数组 // NSDictionary *dict ...
- Mysql数据库设置定时任务
最近手头在做一个拍卖的电商项目. 中间需要将到点的拍卖会状态设置为进行中. 我们的解决方案是Mysql的定时器任务,这里进行一个简单的总结. 1.使用范围 不是所有的MySQL版本都支持,Mysql ...
- IIS Express 外部访问
http://blog.csdn.net/zhangjk1993/article/details/36671105