sobota, 16 sierpnia 2008

Groovy w praktyce - part 6 - przykład z ANT, XML i plikami

Pewnego dnia czekało na mnie czterdzieści parę projektów do statycznej analizy kodu. Pojawił się problem, ponieważ projekty pochodziły z SVN, wszystkie nazywały się tak samo i miały nie wygodną strukturę folderów. By policzyć metryki musiałem wszystkie projekty zaimportować do Eclipse. Groovy był wtedy na mojej liście narzędzi, które chce dodać do swojego pudełka. Poniższe skrypty powstały w około 30 - 40 minut wraz z nauką Groovy od zera i szukaniem odpowiednich poleceń ANT. Były pierwsze linijki kodu jaki napisałem w Groovy i wklejam je w wersji oryginalnej. Warto zauważyć, że Groovy jest produktywny już od momentu zaczęcia nauki. Skrypty pisane były w GroovyConsole.


Skrypt I
Kopiuje pliki \pXX\project\* bezpośrednio do \pXX\*
def f = new File("E:\\Pomiary")
AntBuilder ant = new AntBuilder()

f.eachDir{ dir_pXX ->
print(dir_pXX)

dir.eachDir{d -> if(d.name == "project"){
ant.move(todir: dir_pXX){
fileset(dir: d, defaultexcludes: "no") {
include(name: '**')
}
}
}
}
AntBuilder to klasa pozwalająca na używanie zadań Ant bezpośrednio w kodzie Groovy. Korzysta z kilku przedstawionych wcześniej map i domknięć. W wyrażeniu
ant.move(todir: dir_pXX){
fileset(dir: d, defaultexcludes: "no"){
include(name: '**')
}
}
Wszystkie nawiazy klamrowe to domknięcia, a wszystkie parametry funkcji:
dir: d, defaultexcludes: "no"
to definicja mapy. Takie budowanie struktur jest powszechne w Groovy, nazywane Builder i dostępne przykładowo dla Swing i wielu innych struktur drzewiastych.


Skrypt II
W każdym ze skopiowanych folderów znajduje się projekt Eclipse o nazwie "project". Nie można importować kilku projektów o tej samej nazwie do Eclipse więc potrzeba te nazwy zmienić. Nazwa projektu jest zdefiniowana w pliku xml, przy odrobinie szczęścia wystarczyłoby podmienić za pomocą wyrażenia regularnego wystąpienia "project". No ale wtedy nie sprawdzimy jak Groovy radzi sobie z XML.
def f = new File("E:\\Pomiary")
f.eachDir{ dir ->
dir.eachFile{file ->
if(file.name == ".project"){
def projectDescription = new XmlParser().parseText(file.getText())
projectDescription.name[0].value = dir.name
def writer = new FileWriter(file)
new XmlNodePrinter(new PrintWriter(writer)).print(projectDescription)
}
}
}
Zauważyliście File.getText()? Małe a cieszy. Najciekawszą linijką jest linijka
projectDescription.name[0].value = dir.name
Groovy pozwala na korzystanie podstawowych wyrażeń XPath bezpośrednio w języku. Po tak wybranych elementach można się iterować z pomocą each, można pobierać lub przypisywać im wartość. Odwołanie do atrybutów też jest możliwe np. node.'@atrybut'. Nie wszystko da się zapisać tak samo jak w XPath, ale produktywność jest wspaniała. Może o XML napisze więcej w innym poscie.

Skrypt III
Plug-in liczący metryki zapisywał wyniki w folderach analizowanych projektów, więc jeszcze mały skrypt co zbierał wyniki w jedno miejsce.

def f = new File("E:\\Pomiary")
def ant = new AntBuilder()

f.eachDir{ dir ->
dir.eachFile{file ->
if(file.name == "results.xls"){
ant.copy(file: file,toFile: new File("E:\\Pomiary\\Wyniki\\${dir.name}.xls"))
}
}
}



Linki
Podstawy Groovy i ANT
Więcej informacji Ant Fileset, Ant Move, klasa File
Inne przykłady pracy z plikami Groovy i Pliki

ps. To były pierwsze kroki z Groovy i całkiem sporo elementów w tych prostych skryptach da się zrobić lepiej. Najbardziej mnie drażni w tym starym kodzie korzystanie "\\" i nie korzystanie z choćby File.eachFileMatch.

1 komentarz:

Grzegorz Białek pisze...

Witam. Dzięki za odwiedziny i komentarz na blogu.

W listopadzie organizowana będzie kolejna edycja spotkań EclipseCamp. Chciałbym spróbować zorganizować takie spotkanie we Wrocławiu. Po komentarzach widzę że interesujesz się tematem oAW. Jeżeli byłbyś zainteresowany udziałem (a w zasadzie współorganizacją) takiego wydarzenia to napisz do mnie - deepdiveinto na poczcie gmail.