3
votes

I am trying to write a ant script to automate the update process of our web application.

When some files is going to be updated, I need to backup that file. my question is how to copy that file to backup directory and also create the directory structure relative to the root directory of my web application?

for example:

${WEB_APP_ROOT}/dir1/file1
${WEB_APP_ROOT}/dir2/subdir1/file2

copied to backup folder should be:

${BACK_UP_DIR}/dir1/file1
${BACK_UP_DIR}/dir2/subdir1/file2

currently, I can only copy all files to backup folder, but if two file with same name but located in different folder will cause problem.

my ant code:

<?xml version="1.0"  encoding="UTF-8" ?>
<!-- 对公信贷自动更新Ant任务脚本 created by [email protected] at 2013.11.14 -->
<project default="patch" basedir=".">
    <!-- 引入Weblogic安装目录下的antcontrib包,才能使用if,foreach,propertyregex-->
    <taskdef resource="net/sf/antcontrib/antlib.xml">
        <classpath>
            <pathelement location="/home/weblogic/Oracle/Middleware/modules/net.sf.antcontrib_1.1.0.0_1-0b2/lib/ant-contrib.jar" />
        </classpath>
    </taskdef>

    <!-- 发布目标路径 -->
    <property name="target_dir" value="/home/weblogic/amarsoft/ccms/war/CCMS" />
    <!-- 数据库连接配置属性 -->
    <property name="db_driver" value="oracle.jdbc.OracleDriver" />
    <property name="db_url" value="jdbc:oracle:thin:@10.53.1.116:1521:credit" />
    <property name="db_user" value="als_sit" />
    <property name="db_pswd" value="als_sit" />
    <!-- WLST配置 -->
    <property name="wl_target_server" value="AdminServer" />
    <property name="wl_admin_url" value="t3://10.53.1.117:7001" />
    <property name="wl_user" value="weblogic" />
    <property name="wl_pswd" value="weblogic123" />
    <property name="wl_app_name" value="CCMS" />

    <target name="patch">
        <!-- 检查是否存在WEB-INF目录,如果有则说明更新了配置文件或者JAVA类需要重新加载应用 -->
        <available file="${patch_dir}/WebRoot/WEB-INF" type="dir" property="WEB-INF.present"/>
        <!-- 检查是否存在数据库更新脚本 -->
        <available file="${patch_dir}/update.sql" type="file" property="sql.present"/>

        <!-- 创建备份目录 -->
        <mkdir dir="${patch_dir}/backup" />
        <!-- 针对单个文件,检查是否更新还是新增,如果是更新则要先备份 -->
        <foreach target="move-to-backup" param="theFile">
            <path>
                <fileset dir="${patch_dir}/WebRoot" />
            </path>
        </foreach>
        <!-- 提醒用户检查更新列表预览 -->
        <input message="Is patching preview above correct?" validargs="y,n" addproperty="patch.continue" />
        <!-- 用户确认无误则更新 -->
        <if>
            <equals arg1="${patch.continue}" arg2="y" />
            <then>
                <!-- 存在WEB-INF目录,则先停止应用 -->
                <if>
                    <equals arg1="${WEB-INF.present}" arg2="true" />
                    <then>
                        <echo message="Directory [WEB-INF] found in patching dir, application will be stoped" />
                        <wldeploy action="stop" graceful="true" name="${wl_app_name}" user="${wl_user}" password="${wl_pswd}" 
                            verbose="true" adminurl="${wl_admin_url}" targets="${wl_target_server}" />
                    </then>
                </if>
                <copy todir="${target_dir}" verbose="true">
                    <fileset dir="${patch_dir}/WebRoot/" />
                </copy>
                <!-- 存在数据库更新脚本则执行 -->
                <if>
                    <equals arg1="${sql.present}" arg2="true" />
                    <then>
                        <sql driver="${db_driver}" url="${db_url}" userid="${db_user}" password="${db_pswd}">
                            <classpath>
                                <pathelement location="/home/weblogic/Oracle/Middleware/wlserver_10.3/server/lib/ojdbc6.jar" />
                            </classpath>
                            <transaction  src="${patch_dir}/update.sql"/>
                        </sql>
                    </then>
                </if>
                <!-- 更新完成后,重启应用 -->
                <if>
                    <equals arg1="${WEB-INF.present}" arg2="true" />
                    <then>
                        <echo message="Application will be started again." />
                        <wldeploy action="start" name="${wl_app_name}" user="${wl_user}" password="${wl_pswd}" 
                            verbose="true" adminurl="${wl_admin_url}" targets="${wl_target_server}" />
                    </then>
                </if>
                <echo message="Patching done! " />
            </then>
        </if>
    </target>

    <target name="move-to-backup">
        <propertyregex property="target.file" input="${theFile}" regexp=".+/${patch_dir}/WebRoot/(.+)" replace="${target_dir}/\1" casesensitive="true" />
        <available file="${target.file}" type="file" property="target.file.exist" />
        <if>
            <equals arg1="${target.file.exist}" arg2="true" />
            <then>
                <echo message="[UPDATE] ${target.file}" />
                <copy todir="${patch_dir}/backup" verbose="false">
                    <fileset file="${target.file}" />
                </copy>
            </then>
            <else>
                <echo message="[ADD   ] ${target.file}" />
            </else>
        </if>
    </target>
</project>
1

1 Answers

4
votes

In your target move-to-backup you have this copy task:

<copy todir="${patch_dir}/backup" verbose="false">
    <fileset file="${target.file}" />
</copy>

When you define a fileset as a single file, it uses the directory containing the file as the base directory for the fileset, and the path to the file is relative to that: simply the name of the file.

You can do something like this instead, so that the path to the file to be copied is relative to the root of your application:

<copy todir="${patch_dir}/backup" verbose="false">
    <fileset dir="${WEB_APP_ROOT}">
        <include name="${target.file}" />
    </fileset>
</copy>

If your file was

${WEB_APP_ROOT}/x/y/z/file.txt

It would then be copied to

${patch_dir}/backup/x/y/z/file.txt