środa, 26 lutego 2014

Ant - Selektory plików dla fileset

Na wstępie powiem tak - to nie jest tutorial. Znacznie lepsze określenie do tego co jest niżej to rodzaj pamiętnika. Wiele rzeczy można zrobić na wiele sposobów. Niektóre są dobrze opracowane i łatwo je znaleźć. Niektóre nie wydają się zbyt popularne i drążenie zaczyna się od suchej dokumentacji. To co próbuje zrobić niżej można zrobić na wiele innych sposobów (pewnie to prawda). Ja akurat się uwziąłem aby zrobić to przy pomocy ANT-a. Chodzi o wybieranie elementów do fileset-a. fileset jest przekazywany jako argument do innych task-ów i dlatego jest popularny.

W przypadku prostych definicji nie trzeba sobie zawracać głowy, wystarczy tylko wskazać katalog i się robi. To jest dobre. Co zrobić gdy trzeba w jakiś złożony sposób spreparować listę do skopiowania?
Zamiast zmagać się z jakimś kosmicznym wyrażeniem regularnym pisanym w xml-u można spróbować dodać do fileset selektor który będzie wybierał pliki przy pomocy kodu. Wydaje się że to będzie prostsze. Czy to prawda? Z tego co piszą można to zrobić korzystając z języków skryptowych. Można też napisać klasę która to realizuje wykorzystując Custom Selectors.

Może najpierw spróbuje sprawdzić selektory skryptowe. Wybrałem jako język JavaScript.
Przykład selektora który wybiera każdy plik
<scriptselector language="javascript">
    self.setSelected(true);
</scriptselector>
Przykład selektora który ma nazwę o długości parzystej
<scriptselector language="javascript">
    self.setSelected((filename.length%2)==0);
</scriptselector>
Jak to wykorzystać w taskach które akceptują fileset? Poniżej przykład kopiowania z takim selektorem
<copy todir="dir-to">
    <fileset dir="..">
        <scriptselector language="javascript">
            self.setSelected((filename.length%2)==0);
        </scriptselector>
    </fileset>
</copy>
Po wykonaniu widać że kopiowana jest cała hierarchia. Wcale nie jest to takie proste. Na pierwszy rzut oka nie wiadomo dlaczego i skąd bierze się self i co to w ogóle jest. No na szczęście w tym temacie wyjaśnia się sprawa po lekturze manual-a Script Selector (patrz Selektory w ANT i radzę dokładnie przeczytać pisze co i jak).

Mam już jakieś narzędzie. Postawiłem więc sobie takie zadanie. Chcę wybrać tylko katalogi (nie pliki), które są w katalogu poniżej i zaczynają się od liczby.
Moja struktura może to wyglądać tak:
[all]
    build.xml
    test.xml
[00]
    [properties]
    ...
    build.xml
[00_auth]
    [properties]
    ...
    build.xml
[02]
    [properties]
    ...
    build.xml
...
[17]
    [properties]
    ...
    build.xml
[17_auth]
    [properties]
    ...
    build.xml
Jest to typowe zadanie gdy buduje wersję dla różnych oddziałów. W każdym katalogu który wybiorę jest skrypt, który buduje aplikację. Nie jest ważne jak to się buduje. Ważne jest to że chce mieć jakiś customizowalny sposób na wybieranie tych katalogów. Jakby się zastanowić to wcale może nie trzeba korzystać z selektora skryptowego! Może skorzystać z Filename Selector oraz Depth Selector. Mój testowy skrypt Ant-a to test.xml. Przyjąłem założenie, że w każdym katalogu jest plik o nazwie build.xml. Jako częściowa próba zrealizowania tego może to wyglądać tak:
<copy todir="dir-to" verbose="true">
    <fileset dir="..">
        <and>
            <depth max="1" />
            <filename regex="^\d+" />
            <filename regex="build.xml" />
        </and>
    </fileset>
</copy>
Wydaje się to działać. Ale czy to koniec? Normalne copy kopiuje wszystko to kopiuje tylko build.xml. Działa ale tylko dlatego że jest jeden build.xml. Co by było gdyby  build.xml był w kolejnym podkatalogu [00]/xx/build.xml? Skopiuje się! Nie okazuje się że właśnie depth przed tym zabezpieczył!

Selectory filename

W selektorze przekazywana jest nazwa pliku. W dokumentacji bezpośrednio nie ma informacji że to jest pełna ścieżka od miejsca podanego jako atrybut dir dla fileset. To dość ważne. Pisząc warunek który wybiera po nazwie chcemy np zdefiniować tak aby brało 17/ ale już nie 17_auth/. W zależności od tego czy ant jest odpalony na Windows czy Linux warunek jest interpretowany inaczej i wartość filename przekazana do badania warunkiem może mieć ścieżkę z separatorem / lub \.
Stosując wyrażenie regularne można to opędzić definiując np. wyważenie
<filename regex="^17[\\/]" />
Taki patent działa na obu systemach.

Eclipse

Uruchomienie takiego skryptu w Eclipse wymaga ustawienia ANT_HOME w Eclipse na właściwą wersję ANT. Wymagana też jest wskazanie odpowiedniej wersji JAVA. W moim przypadku korzystałem ze starej wersji Eclipse dlatego wskazałem moją własną - zewnętrzną wersję ANT (Window / Preferences / Ant / Runtime / Ant Home). Uruchomnienie przy pomocy Eclipse wymagało wskazania JAVA 1.6 (prawoklik - menu - Debug As / Ant Build / JRE / minumum 1.6)
W przypadku JAVA 1.5 dostałem komunikat że nie można załadować BSF
Nie udało mi się na razie debugować wyrażenia w JavaScript. Debuguje się jedynie skrypt ANT-a.
W sumie mało użyteczne odpalenie tego z Eclipse!

Selektory w ANT http://ant.apache.org/manual/Types/selectors.html
Opis języka skryptowego http://ant.apache.org/manual/Tasks/script.html

Brak komentarzy:

Prześlij komentarz