Krótki kurs Anta

English versionEnglish version | Wersja PolskaWersja Polska

Zawartość

Co to za dokument?
Dokument jest samouczkiem [tutorialem], aby pomóc ludziom w poradzeniu sobie z Antem. Został stworzony na zajęcia z "Projektowania obiektowego", na które uczęszczałem w semestrze letnim 2003r. Umieściłem tu swoje doświadczenia z długiej już pracy z Antem.
Co możemy tutaj znaleźć?
Możemy znaleźć tutaj kilka rozdziałów:
Kim jest autor tego dokumentu?
Autor dokumentu jest doświadczonym programistą (Java), który jak większość programistów nie lubi wykonywać pewnych czynności wielokrotnie i lubi używać komputerów, aby robiły za niego pewne czynności.
Uwagi do tłumaczenia
Tłumaczenie z języka angielskiego może być niedoskonałe. Już w trakcie tłumaczenia zauważyłem, że nie jestem w stanie przetłumaczyć niektórych zwrotów angielskich (np: build tool).
Postanowiłem pozostawić w oryginalnej formie niektóre angielskie nazwy, które wg mnie nie powinny zostać wogóle tłumaczone (być może nawet nie mogą być tłumaczone). Przykłady:
task, target, project..
Słowa kluczowe pliku konfiguracyjnego Anta

Za wszelkie uwagi do tłumaczenia, oraz do angielskiej wersji będę wdzięczny uśmiechem :-)

Podstawy Anta

Czym jest Ant?
Tak jak piszą w oficjalnej dokumentacji do Anta:
Z dokumentacji do Anta:
Apache Ant is a Java-based build tool. In theory, it is kind of like make, without make's wrinkles.

Ant to narzędzie zaprojektowane, aby pomóc ludziom z automatyzacją. Jeśli znasz narzędzie make, to będzie Ci łatwiej to zrozumieć.
Ant jest napisany całkowicie w Javie, więc jest przenośny. Możesz używac tego samego pliku konfiguracyjnego w Linuksie, Windowsie, na Solarisie i w każdym innym systemie operacyjnym, gdzie dostępna jest Java i Ant.
Jak zaprojektowany jest Ant?
Do pracy z Antem potrzebujesz stworzyć plik konfiguracyjny. Plik musi być poprawnym dokumentem XML. Plik ten (zwykle nazywany: build.xml) ma swoją własną strukturę. Korzeniem tego pliku XML jest tag: <project>. Składa się on z różnej ilości innych tagów, zwanych: <target> [pol: cel]. Każdy <target> składa się z dowolnej ilości wykonywanych zadań: <task>.
<project name="project_name" basedir="." default="default">

    <target name="default">
        <task1 param1="value" />
        <task2>
            <type param="value" />
        </task2>
    </target>

    <target name="target2">
        <task1 />
        <task3 />
    </target>

    <target name="targetN">
    </target>

</project>
Czym jest <target> (cel)?
Definiujemy <target> jako nasz logiczny cel, który ma wykonać za nas Ant. Przykładowo jedym z takich celów, może być: kompilacja, utworzenie kopii zapasowej, wysłanie poczty elektronicznej.
Możemy osiągnąć nasz logiczny cel na wiele sposobów. W prawdziwym życiu naprzykład, gdy chcemy dotrzeć do kraju Grecja, możemy to wykonać na wiele sposobów. Możemy polecieć samolotem, pojechać pociągiem albo popłynąć statkiem do Hiszpani, a później samochodem przez Afrykę i statkiem do Grecji. Tak czy inaczej, nasz cel to: "dotrzeć do Grecji". Możemy to zrobić na kilka sposobów, ale zawsze na koniec znajdziemy się w Grecji. Każdy mały krok naszej podróży to zadanie. W Ancie nazwiemy je: <task>.
Zadanie to:
  • podróż pociągiem
  • lot samolotem
  • płynięcie statkiem
  • przygotowywanie do podróży poprzez pakowanie się

Dowolny <target>, może zależeć od innego celu. Na przykład, jeśli chcemy podjąć pracę w Grecji, najpierw musimy się tam dostać, następnie znaleźć miejsce do zamieszkania, a dopiero wtedy zająć się szukaniem pracy. Jeśli nie znajdziemy mieszkania, to bez sensu jest szukać pracy.
Czym jest <task> (zadanie)?
<task> (zadanie) w Ancie jest prostą, małą czynnością, która będzie wykonywana. Prostymi zadaniami są: tworzenie katalogu, kopiowanie pliku, czytanie pliku z ustawieniami lub łączenie dwóch plików. Istnieje wiele bardziej zaawansowanych zadań. Przykładowo: wysyłanie listu, kompilacja kodów źródłowych programów, tworzenie archiwów, itp..
Każde zadanie może posiadać parametry lub być zależnym od innych zadań.
Ant posiada bardzo wiele wbudowanych zadań (ponad 70 w wersji podstawowej, oraz kilkadziesiąt napisanych przez ludzi z całego świata). Nie będzie trzeba pisać samemu tych zadań. Inni ludzie ułatwili nam korzystanie z Anta i zaprogramowali najczęściej potrzebne zadania. Przepisali oni najprostrze programy systemów operacyjnych operujące na plikach, typu: copy, delete, concat, mkdir i inne.
Więc jak wygląda prosty plik konfiguracyjny Anta?
<?xml version="1.0" encoding="iso-8859-2"?>
<project name="Project name" basedir="." default="resources">
    <description>
        Some description here..
    </description>

    <property name="build.dir" location=".." />
    <property name="src.dir" location="src/" />

    <target name="prepare">
        <mkdir dir="${build.dir}" />
    </target>

    <target name="resources" depends="prepare">
        <copy todir="${build.dir}" >
            <fileset dir="${src.dir}">
                <exclude
                name="includes/**/*.swp" />
            </fileset>
        </copy>
    </target>

</project>
Ok. A czy możemy używać zmiennych w pliku konfiguracyjnym Anta?
Tak, możemy. Możemy je zdefiniować bezpośrednio w pliku build.xml, poprzez użycie zadania: <property> lub poprzez użycie wbudowanych zmiennych, lub poprzez wczytanie zmiennych z pliku konfiguracyjnego.

Składnia używania zmiennych:
${variable}, i.e. <mkdir> dir="${build.dir}" />


możemy czytać zmienne z pliku konfiguracyjnego:
build.properties:
            build.dir=build/
            dist.dir=dist/
            archive.filename=archive.tgz
            ...
            
możemy użyć wbudowanych zmiennych:
  • basedir
  • ant.file
  • ant.version
  • ant.project.name
  • ant.java.version
definiowanie własnych zmiennych:
<property name="build.dir" location=".." />
<property name="src.dir" location="src/" />
<property name="archive.filename" value="archive.tgz" />
            
użycie zmiennych:
<echo> Źródła są tutaj: ${src} <echo>
Jakie są wbudowane w Ant zadania?
Jest ich dużo. Kompletna lista znajduje się w oryginalnej dokumentacji
Poniżej są jedynie przykłady:
Archiwizacja
<bzip2>, <gzip>, <tar>, <zip>, <jar>, <war>, <ear>, ...
Kompilacja
<javac>, <rmic>, ...
Dokumentacja
<javadoc>, <doxygen>
Deployment
 
Zadania logujące czynności (logging tasks)
 
Mail
<mail>
Różne
<echo>, <sound>, <splash>, <sql>, ...
.NET
 
Pre-process
 
Property Tasks
 
Zdalne usługi (remote)
<ftp>, <telnet>
SCM
<cvs>, <cvspass>, <perforce>, <starteam>, ...
Testowania (testing tasks)
<junit>, <junitreport>, <test>
Visual Age for Java
 
A co z uruchamianiem zadań na grupie plików?
W celu wybrania grupy plików (katalogów) używamy zadania nazwanego: <fileset> lub <filelist> (<dirset>).

Hint!
Zadania: <DirSet>, <FileList>, <FileSet>, <File Mappers>, <FilterChains> i <FilterReaders>, <FilterSet>, <PatternSet>, <Selectors>, <XMLCatalog> są zwane Core types


Oto przykład użycia <fileset>:
<!-- ... -->
<fileset dir="${server.src}" casesensitive  ="yes" >
    <include name="**/*.java"/>
    <exclude name="**/*Test*"/>
</fileset>
<!-- ... -->
        
To będzie zawierało pliki z końcówką: .java, ale nie pliki, które występują w katalogu o nazwie *Test (gdzie '*' oznacza dowolny ciąg).

Jak widać, łatwo jest wybrać pliki wewnątrz naszej struktury katalogów. (zakładam, że istnieje jakaś ;-) )

Pokażmy teraz użycie prostych zadań..

Pierwszy przykład:
Zadanie <javac> kompiluje pliki źródłowe ze wskazanych katalogów.

    <target name="compile" depends="...">
        <javac
            destdir="${build.classes.dir}"
            deprecation="on">

            <include name="**/*.java" />
            <src path="${src.main.dir}" />
            <src path="${src.prevayler.dir}" />
            <src path="${src.ant.dir}" />

        </javac>
    </target>
        

Drugi prosty przykład:
Tu pokażemy, użycie zadania: <copy>, które kopiuje pliki lub katalogi pod wskazane miejsce.

<copy file="myfile.txt" todir="../some/other/dir"/>
        

Trzeci przykład:

<copy todir="../dest/dir" >
<fileset dir="src_dir" >
<exclude name="**/*.java"/>
</fileset>
</copy>
        

Istnieje także zadanie, które pozwala na uruchomienie testów Junit.

<junit>
<test name="my.test.TestCase" />
</junit>
        

Bardziej zaawansowany przykład:

<junit printsummary="yes" haltonfailure="yes">
    <classpath>
      <pathelement location="${build.tests}" />
      <pathelement path="${java.class.path}" />
    </classpath>

    <formatter type="plain" />

    <test name="my.test.TestCase" haltonfailure="no" outfile="result" >
        <formatter type="xml" />
    </test>

    <batchtest fork="yes" todir="${reports.tests}">
        <fileset dir="${src.tests}">
        <include name="**/*Test*.java" />
        <exclude name="**/AllTests.java" />
        <!-- ... -->
        

Zaawansowany Ant: Piszemy własne zadania

Zadanie do generowania pliku MasterTest.java
Napisałem proste i użyteczne dla mnie zadanie, które pozwala na generowanie pliku źródłowego klasy, której celem jest uruchomienie innych klas testowych JUnit. Plik, który generuję ma odpowiednią składnię, oraz pewne bloki kodu, które można wygenerować automatycznie na podstawie nazw plików. Wykorzystałem do tego Anta.
Oto strona ze źródłem zadania i strona z wywołaniem zadania.

Plik, który będziemy generowali, wygląda tak:

package nthx.some_project.tests;

import nthx.some_project.order.action.tests.UpdateWorkingDaysInWorkstandActionTest;
import nthx.some_project.order.action.tests.AddWorkingDaysToWorkstandActionTest;
        /** 
         *  many imports more..
         *  cut here 
         */
import junit.framework.*;

public class MasterTest extends TestCase {

    public static Test suite() {
        TestSuite result = new TestSuite();

        result.addTest(new TestSuite(StringUtilsTest.class));
        result.addTest(new TestSuite(OrderTest.class));
        /** 
         *  50 lines more..
         *  cut here 
         */
        result.addTest(new TestSuite(UpdateWorkersExperiencesBeanTest.class));
        result.addTest(new TestSuite(InsertWorkerBeanTest.class));
        return result;
    }
        

Jak ta strona została stworzona

GTML
Na stan 19.07.2003 strony te są generowane narzędziem GTML. więcej o tym narzędziu
Budowanie stron WWW z użyciem Anta
Ta strona oraz inne początkowo były generowane z użyciem Anta. Użyłem prostego mechanizmu łączenia plików (nagłówek, zawartość, stopka) w jeden wyjściowy plik.
Istnieje stary, nieładnie napisany plik konfiguracyjny Anta. Można go obejrzeć, ale nie należy kopiować użytych tu rozwiązań.
Lepszym rozwiązaniem byłoby napisanie zadania, które bierze na wejście pliki znalezione przez zadanie <fileset> i z nich generuje strony. Próbowałem także użyć jakiegoś języka skrpytowego w Ancie (Javascript), ale spędziłem zbyt dużo czasu na to i mój osobisty wniosek jest taki, że lepiej napisać własne zadanie niż używać skryptu w Ancie.

Podziękowania

Dziękuję
Dziękuję wszystkim ludziom, którzy użyli tego samouczka w swojej pracy. Mam nadzieję, że był dostatecznie pomocny.
Będzie mi bardzo miło ulepszyć ten samouczek, jeśli jest taka potrzeba. W każdym wypadku dowolnej krytyki tego dokumentu proszę o użycie formatki na samym dole tej strony, aby dostarczyć mi opinii zwrotnej. Jest ona zawsze mile widziana!
Official Ant site
http://jakarta.apache.org/ant
Official Ant manual
http://ant.apache.org/manual/index.html
Article at JavaWorld
Automate your build process using Java and Ant
Article at IBM/developerworks
Automating the build and test process

Designed with CSS| Created with GIMP| Get Firefox!| | Opel Omega Forum|

Copyright © Tomasz Nazar 2007
Revision: $Id: ant_pl.gtml 3768 2005-07-25 23:47:33Z nthx $