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.xmlJest 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[\\/]" />
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.htmlOpis języka skryptowego http://ant.apache.org/manual/Tasks/script.html