2015-02-24 5 views
1

У меня довольно сложная задача для написания. Мне пришлось сделать отдельные файлы сборки и 1 осталось. Есть 4 файла:Задача ANT - несколько файлов - петля через

buildpackage.bat, buildpackage.xml, buildpackage.txt, structure.xml 

buildpackage.bat просто муравей файл, который вызывает buildpackage.xml "ant -f buildpackage.xml". Это нормально.

buildpackage.txt проста и имеет запятую строки:

server1,client1 
server2,client2 
genericserver,client[x] 
server[x],client[x] 

Существует всегда имя сервера и имя клиента:

  • Server name могут быть буквы только цифры и буквы, но имеет переменную длину.

  • Client name - только буквы.

Мне нужно разделить эти файлы на 2 отдельных переменных: server.name и client.name.

То, что я сделал это:

<loadfile property="buildpackage" srcFile="buildpackage.txt"/>  
<for list="${buildpackage}" param="depl.det" delimiter="${line.separator}"> 
<sequential> 
    <echo> 
    Input: @{deploy.details} 
    </echo> 
</sequential> 
</for> 

Результаты я получаю:

[echo] Input: server_01,Client_01 
[echo] Input: server_02,Client_02 
[echo] Input: server_03,Client_03 
[echo] Input: clientserver,client_04 

Я хотел server_01 быть параметр1 и client_02 быть параметр2.

Я буду выполнять другие задачи в последовательности. Я скопирую файлы из клиентской директории [x] на сервер [x] (это просто, но как я могу разделить эту строку на две отдельные переменные?).

А теперь очень сложная задача.

I тоже есть структура.xml файл. Структура:

<core> 
    <clients> 
    <client> 
     <name>Client_01</name> 
     <branding>brand_01</branding> 
     <applications> 
     <application>application_01</application> 
     </applications> 
     <solutions> 
     <solution>solution01</solution> 
     </solutions> 
    </client> 
    <client> 
    <name>Client_07</name> 
    <branding>brand_09</branding> 
    <applications> 
     <application>application_03</application> 
    </applications> 
    <solutions> 
     <solution>solution01</solution> 
     <solution>solution07</solution> 
     <solution>solution08</solution> 
    </solutions> 
    </client> 
    <clients> 
<core> 

У меня есть много клиентов, приложений, брендингов, решений. Каждый клиент может иметь только 1 приложение и 1 брендинг, но несколько решений.

на основе предыдущей последовательной задачи (получить сервер и имя) У меня есть Переберите, что XML-файл и получить для каждого сопоставления клиента (из предыдущей задачи)

- branding 
- application 
- solutions (multiple or one) 

Я могу читать XML с помощью <xmlproperty> но я не знаю, как сделать это последовательно (итерация) и получить соответствующие свойства.

Я знаю, что это сложно. Краткое изложение:

  1. сценарий сборки начинается
  2. сценарий сборки извлекает данные из buildpackage.txt как client.name и server.name
  3. сценарий сборки получает ${client.name} со стадии 2 в качестве параметра и петли через структуру. XML. Он находит подходящий брендинг/приложение/решения и выводит его для каждого соответствующего клиента.

Выход:

server.name 
client.name 
branding.name 
application name 
solution [X] 
solution [y] 

Ant должен быть обработан для каждого сервера/клиента. Я могу сделать остальную часть сборки и скомпилировать, если у меня есть свойства. Я не могу прикоснуться к struct.xml. Я могу сделать все, что мне нужно/хочу, чтобы buildpackage.cml и buildpackge.txt. Buildpackage.txt можно заменить файлом .xml или любым файлом (например, .properties). Он должен содержать эти 2 значения сервера и клиента.

Благодарим за помощь.

EDIT

Теперь у меня есть проблема. Если я помещаю одно приложение 2x в файл сборки, он строит только первый. Вот мой build.xml файла

<?xml version="1.0" encoding="UTF-8"?> 
<project name="DoTheJob" basedir="." xmlns:ac="antlib:net.sf.antcontrib" xmlns:if="ant:if" xmlns:unless="ant:unless"> 
    <!-- Define classpath and default locations--> 
    <property name="root.dir" location="../.."/> 
    <property name="dest.dir" location="packages"/> 
    <property name="ant.lib.dir" location="../lib"/> 
    <property name="repository_url" value="http://repository-url"/> 
    <path id="project.classpath"> 
     <fileset dir="${ant.lib.dir}"> 
     <include name="*.jar"/> 
     </fileset> 
     <fileset dir="${root.dir}/IIT/lib"> 
      <include name="*.jar"/> 
     </fileset> 
     <pathelement location="../savedjar/compiled.jar"/> 
    </path> 
    <path id="svnant.path"> 
     <fileset dir="../lib/"> 
      <include name="svnant.jar"/> 
      <include name="svnClientAdapter.jar"/> 
     </fileset> 
    </path> 
    <typedef resource="org/tigris/subversion/svnant/svnantlib.xml" classpathref="svnant.path" /> 
    <tstamp> 
     <format property="build_time" pattern="YYYY MMMM dd HH:mm:ss"/> 
    </tstamp> 
    <!-- Change characters to lowercase --> 
    <scriptdef language="javascript" name="lowercase"> 
     <attribute name="string" /> 
     <attribute name="to" /> 
     project.setProperty(attributes.get("to"),attributes.get("string").toLowerCase()); 
    </scriptdef> 
    <!-- Import XMLTask for XML transformations--> 
    <taskdef name="xmltask" classname="com.oopsconsultancy.xmltask.ant.XmlTask" classpathref="project.classpath"/> 
    <!-- Define buildfiles locations--> 
    <property name="structure.file" location="../structure.xml"/> 
    <property name="buildpackage.file" location="buildpackage.txt"/> 
    <!-- load client/server file--> 
    <property file="${buildpackage.file}"/> 
    <!-- loop over all clients --> 
    <xmltask source="${structure.file}"> 
    <call path="//client"> 
     <param path="name/text()" name="client"/> 
     <param path="branding/text()" name="branding"/> 
     <param path="applications/application/text()" name="application"/> 
      <actions> 
       <!-- loop through all XML properties only when @{client} condition is matched --> 
       <ac:if> 
        <isset property="@{client}"/> 
        <then> 
         <echo>=====================================================</echo> 
         <echo>Building package for @{client} on ${@{client}}  </echo> 
         <echo>=====================================================</echo> 
         <!-- creating destination directories -->       
         <delete dir="${build.dir}/@{client}"/> 
         <mkdir dir="${dest.dir}/@{client}"/> 
         <echo>=====================================================</echo> 
         <echo>Copy application files code/temaplates to destination</echo> 
         <echo>=====================================================</echo>      
         <!-- creating code build directory --> 
         <mkdir dir="${dest.dir}/@{client}/code"/> 
         <!-- copy application code --> 
         <echo>copy application code</echo> 
         <copy todir="${dest.dir}/@{client}/code/application/@{application}" overwrite="yes"> 
          <fileset dir="${root.dir}/client-source/application/@{application}" includes="**/*.*"/> 
         </copy> 
         <!-- copy application templates --> 
         <mkdir dir="${dest.dir}/@{client}/app/@{client}"/> 
         <echo>copy application templates</echo> 
         <copy todir="${dest.dir}/@{client}/app/@{client}" overwrite="yes"> 
          <fileset dir="${root.dir}/applications/apps/@{application}" includes="**/*.*"/> 
         </copy> 
         <echo>===================================================</echo> 
         <echo>copy Solutions files code/temaplates to destination</echo> 
         <echo>===================================================</echo>  
         <!-- nested xmltask for loop over solutions --> 
         <xmltask source="${structure.file}"> 
          <call path="/core/clients/client[name/text()='@{client}']/*/solution"> 
           <param path="text()" name="solution"/> 
            <actions> 
             <!-- making sure that solution is lowercase --> 
             <lowercase string="@{solution}" to="solution.lowercase" /> 
             <echo>copy solutions code</echo> 
             <!-- copy solutions code --> 
             <copy todir="${dest.dir}/@{client}/code/solutions/${solution.lowercase}" overwrite="yes"> 
              <fileset dir="${root.dir}/client-source/solutions/${solution.lowercase}" includes="**/*.*"/> 
             </copy> 
             <!-- copy solutions templates --> 
             <echo>copy Solutions templates</echo> 
             <copy todir="${dest.dir}/@{client}/app/@{client}" overwrite="yes"> 
              <fileset dir="${root.dir}/applications/solutions/${solution.lowercase}" includes="**/*.*"/> 
             </copy> 
            </actions> 
          </call> 
         </xmltask> 
         <echo>==============================================</echo> 
         <echo>copy Client files code/temaplates to destination</echo> 
         <echo>==============================================</echo> 
         <!-- copy branding directory --> 
         <copy todir="${dest.dir}/@{client}/app/@{client}" overwrite="yes"> 
          <fileset dir="${root.dir}/applications/brandings/@{branding}" includes="**/*.*"/> 
         </copy>       
         <!-- copy client code --> 
         <copy todir="${dest.dir}/@{client}/code/client/@{client}" overwrite="yes"> 
          <fileset dir="${root.dir}/client-source/client/@{client}" includes="**/*.*"/> 
         </copy>       
         <!-- set templates directory --> 
         <copy todir="${dest.dir}/@{client}/app/@{client}" overwrite="yes"> 
          <fileset dir="${root.dir}/applications/clients/@{client}" includes="**/*.*"/> 
         </copy>   
         <echo>==============================================</echo> 
         <echo>compiling code        </echo> 
         <echo>==============================================</echo> 
         <!-- making classes directory --> 
         <mkdir dir="${dest.dir}/@{client}/classes"/> 
         <javac destdir="${dest.dir}/@{client}/classes" classpathref="project.classpath" debug="on" fork="true" includeantruntime="false" memoryinitialsize="256m" memorymaximumsize="1024m"> 
          <src path="${dest.dir}/@{client}/code/"/> 
         </javac> 
         <echo>==============================================</echo> 
         <echo>creating Client.jar       </echo> 
         <echo>==============================================</echo> 
         <!-- jar classes directory --> 
         <jar jarfile="${dest.dir}/@{client}/app/Client.jar" basedir="${dest.dir}/@{client}/classes"/> 
         <!-- reaplce text in files --> 
         <replaceregexp byline="true"> 
          <regexp pattern="@[email protected]"/> 
          <substitution expression="${build_time}"/> 
          <fileset dir="${dest.dir}/@{client}/app/@{client}/templates/"> 
           <include name="*.htm"/> 
           <include name="*.html"/>    
           <include name="*.ini"/> 
          </fileset> 
         </replaceregexp> 
         <!-- get svn info --> 
         <svn username="********" password="************" javahl="false" svnkit="false"> 
          <info target="${repository_url}" /> 
         </svn> 
         <!-- creating Client.ini file --> 
         <touch file="${dest.dir}/@{client}/app/Client.ini"/> 
         <concat destfile="${dest.dir}/@{client}/app/Client.ini" append="true">releaseDate=${build_time}${line.separator}</concat> 
         <concat destfile="${dest.dir}/@{client}/app/Client.ini" append="true">svnrevision=${svn.info.lastRev}${line.separator}</concat> 
         <!-- ziping package --> 
         <zip destfile="${dest.dir}/@{client}/@{client}.zip" basedir="${dest.dir}/@{client}/app/" /> 
         <echo>==============================================</echo> 
         <echo>sending @{client}.zip to the server via scp  </echo> 
         <echo>==============================================</echo> 
         <!-- scp file to remote server --> 
         <property name="scp_username" value="**********"/> 
         <property name="scp_password" value="**********"/> 
         <property name="scp_server" value="${@{client}}"/> 
         <property name="scp_remote_directory" value="*********"/> 
         <scp trust="true" verbose="true" localFile="${dest.dir}/@{client}/@{client}.zip" remoteTodir="${scp_username}:${scp_password}@${scp_server}:${scp_remote_directory}"/> 
         <echo>${line.separator}${line.separator}${line.separator}</echo> 
        </then> 
       </ac:if> 
      </actions> 
     </call> 
    </xmltask> 
</project> 

И если я пытаюсь года строите buildpackage.txt файл

client1=server1 
client2=server1 
client1=server2 

Я получаю client1-> сервер1, client2-> сервер1 но ...... нет клиента 1to server2

EDIT2

Все фиксированные. Решение УПП задачи является:

 <!-- scp file to remote server --> 
     <property name="scp_username" value="XXX"/> 
     <property name="scp_password" value="YYY"/> 
     <property name="scp_remote_directory" value="path"/> 
     <for list="${@{client}}" delimiter="=" param = "val"> 
      <sequential> 
      <property name="token" value="@"/> 
      <scp trust="true" verbose="true" localFile="${dest.dir}/@{client}/@{client}.zip" remoteTodir="${scp_username}:${scp_password}${token}@@{val}:${scp_remote_directory}"/> 
     </sequential> 
     </for> 

Все работы. Спасибо за вашу помощь

ответ

1

Для любого xmldriven сборки я рекомендую использовать муравей аддон xmltask, так что-то вроде:
(при условии, что clientnames подобны в buildpackage.txt и structure.xml - ваш фрагмент кода имеет несколько названий Client_01, client1 ..!?)

<project> 
<!-- Import XMLTask --> 
<taskdef name="xmltask" classname="com.oopsconsultancy.xmltask.ant.XmlTask"/> 

<!-- make buildpackage.txt a valid propertyfile to get the job done 
     f.e. server1,client1 will get client1=server1 etc. .. 
     to make server easily accessible within xml loop 
--> 
<replaceregexp 
    file="buildpackage.txt" 
    match="(.+),(.+)" 
    replace="\2=\1" 
    byline="true" /> 

<!-- now load that file --> 
<property file="buildpackage.txt"/> 

<!-- loop over all clients --> 
<xmltask source="structure.xml"> 
    <call path="//client"> 
    <param path="name/text()" name="client"/> 
    <param path="branding/text()" name="branding"/> 
    <param path="applications/application/text()" name="application"/> 

    <!-- inside action adress params with @{..} syntax ! --> 
    <actions> 
    <!-- the copy (or whatever) action 
     here demonstrated with echoxml --> 
    <echoxml> 
    <!-- access the corresponding server (set via buildpackage.txt) 
     with nested ${@{..}} syntax ! --> 
    <copy todir="//${@{client}}/share"> 
    <fileset dir="@{client}/somedir"/> 
    </copy> 
    </echoxml> 

    <echo>${@{client}}${line.separator}@{client}${line.separator}@{application}${line.separator}@{branding}</echo> 

    <!-- another nested xmltask for loop over solutions --> 
    <xmltask source="structure.xml"> 
    <call path="//client[name/text()='@{client}']/*/solution"> 
    <param path="text()" name="solution"/> 
     <actions> 
     <echo>@{solution}${line.separator}</echo> 
     </actions> 
    </call> 
    </xmltask> 

    </actions> 
    </call> 
</xmltask> 
</project> 

Если возможно, вы должны создать buildpackage.txt как действительный propertyfile
с форматом => Client [х] = Сервер [х] сразу.
Тогда вам понадобится только xmltask. Поместите все свои шаги в секцию вложенных действий, как показано с помощью echoxml/copy.

Выход:

<?xml version="1.0" encoding="UTF-8"?> 
<copy todir="//server1/share"> 
    <fileset dir="client1/somedir" /> 
</copy> 
    [echo] server1 
    [echo] client1 
    [echo] application_03 
    [echo] brand_01 
    [echo] solution01 
<?xml version="1.0" encoding="UTF-8"?> 
<copy todir="//server4/share"> 
    <fileset dir="client4/somedir" /> 
</copy> 
    [echo] server4 
    [echo] client4 
    [echo] application_03 
    [echo] brand_09 
    [echo] solution01 
    [echo] solution07 
    [echo] solution08 
BUILD SUCCESSFUL 

- EDIT после вопроса об условном действии, только если $ {@ {клиента}} установлена ​​-

если propertyfile buildpackage.txt содержит неправильные свойства, средства server = client вместо client = server, fe :

Sol-e-45-D=PRODUCTION1 
CONNECTION=PRODUCTION3 
PRODUCTION4=DFHH 
PRODUCTION5=MEGA-5 

Вам нужна какая-либо, если логика isset. Лучше всего использовать new if/unless feature (представленный с ant191), если вы используете ant> = 1.9.3, f.e.:

<!-- you need to activate that feature via namespaces --> 
<project 
    xmlns:if="ant:if" 
    xmlns:unless="ant:unless" 
> 

<!-- Import XMLTask --> 
<taskdef name="xmltask" classname="com.oopsconsultancy.xmltask.ant.XmlTask"/> 

<!-- load propertyfile with client=server mappings --> 
<property file="buildpackage.txt"/> 

<!-- loop over all clients --> 
<xmltask source="structure.xml"> 
    <call path="//client"> 
    <param path="name/text()" name="client"/> 
    <param path="branding/text()" name="branding"/> 
    <param path="applications/application/text()" name="application"/> 

    <!-- inside action adress params with @{..} syntax ! --> 
    <actions> 
    <!-- the copy (or whatever) action 
     here demonstrated with echoxml --> 
    <echoxml if:set="@{client}"> 
    <!-- access the corresponding server (set via buildpackage.txt) 
     with nested ${@{..}} syntax ! --> 
    <copy todir="//${@{client}}/share"> 
    <fileset dir="@{client}/somedir"/> 
    </copy> 
    </echoxml> 

    <echo if:set="@{client}">${@{client}}${line.separator}@{client}${line.separator}@{application}${line.separator}@{branding}</echo> 

    <!-- another nested xmltask for loop over solutions --> 
    <xmltask source="structure.xml"> 
    <call path="//client[name/text()='@{client}']/*/solution"> 
    <param path="text()" name="solution"/> 
     <actions> 
     <echo if:set="@{client}">@{solution}${line.separator}</echo> 
     </actions> 
    </call> 
    </xmltask> 

    </actions> 
    </call> 
</xmltask> 
</project> 

Примечание => вызов xmltask имеет также, если атрибут, но ClientName не известно, когда начинает цикл, не может использовать <call path="//client" if="@{client}">
выход:

<?xml version="1.0" encoding="UTF-8"?> 
<copy todir="//PRODUCTION1/share"> 
    <fileset dir="Sol-e-45-D/somedir" /> 
</copy> 
    [echo] PRODUCTION1 
    [echo] Sol-e-45-D 
    [echo] Sol-e-45-D 
    [echo] Branding-BLUE 
    [echo] Sol-e-45-D 
<?xml version="1.0" encoding="UTF-8"?> 
<copy todir="//PRODUCTION3/share"> 
    <fileset dir="CONNECTION/somedir" /> 
</copy> 
    [echo] PRODUCTION3 
    [echo] CONNECTION 
    [echo] Sol-e-45-D 
    [echo] Branding-BLUE 
    [echo] Sol-e-45-D 

В противном случае, когда связанный с ant < = 1.9.3, вы можете использовать antcontrib if task, так как у вас уже есть эта задача в вашем фрагменте:

<if> 
<isset property="@{client}"/> 
    <then> 
    <!-- ... --> 
    </then> 
</if> 

Осторожно, ваше определение antcontrib taskdef неправильно !!, то antcontrib.properties содержит только taskdefs для муравья < 1,6, объявить его как что (при условии, antcontrib.jar уже на пути):

<project xmlns:ac="antlib:net.sf.antcontrib"> 

    <ac:if> 
    ... 

или без пробелов:

<project> 

    <!-- Import AntContrib --> 
    <taskdef resource="net/sf/antcontrib/antlib.xml"/> 
    ... 
+0

EDIT. теперь все работает отлично, но есть одна проблема. Если я хочу построить application1 = server1 и application1 = server2 и appcation1 = server3 - он строит только 1 приложение. Если я положил applicaiton1 = server1, application2 = server1, applicaiton1 = server2 - stull build appliciton 1 раз один раз. –

+0

@ES У вас есть 3 свойства с именем application1. Это невозможно. В ant свойство, которое когда-то установлено, является неизменным. Когда свойствоfile загружается первым определением, т. Е. application1 = server1 wins, означает, что свойство будет иметь значение server1. – Rebse

+0

Что делать, если 'buildpackage.txt' будет в формате:' client1 = server1 = server2 = server3' 'client2 = server1'' client3 = server1 = server2 = server3 = server4 = server5' с одного до 5 серверов. Является ли это возможным? –

 Смежные вопросы

  • Нет связанных вопросов^_^