JSLint4java, Jenkins and Violation plugin

In a previous article I told you about the existence of the violation plugin for Jenkins which can take in consideration the output generated by jslint4java.

jslint4java has an ant plugin which can be easily integrated in your environment and you need just to configure it for your javascript.

Let’s suppose you have a javascript file, in my case user-extensions.js coming from Selenium, in your repository.

At the same level create a folder named “jslint”. Under this folder place the jslint4java-2.0.1.jar file that you can find inside the zip file of jslint4java and create a build.xml file with the following content:

<project name="proj" default="main" basedir=".">
<target name="main" depends="jslint"/>

<taskdef name="jslint"
classname="com.googlecode.jslint4java.ant.JSLintTask"
classpath="jslint4java-2.0.1.jar" />

<target name="jslint">
<jslint haltOnFailure="false" options="sloppy">
<predef>selenium,Selenium,storedVars,LOG,Assert</predef>
<formatter type="xml" destfile="jslint.xml"/>
<fileset dir="../" includes="user-extensions.js"/>
</jslint>
</target>

</project>

In practice in the taskdef tag we say where the jar file is located (same folder), in the jslint tag I specified:

  1. haltOnFailure=”false”, to not  make stop and fail the plugin if a violation is found (in this way the entire job in Jenkins will not fail)
  2. options=”sloppy”, to disable the strict control in the file (used for ECMAScript 5)
  3. using predefined variables like “selenium” with the predef tag
  4. specifying the output file (in the same folder) in xml format (useful for the violation plugin)
  5. specifying just the input file that I have (which is in the top folder)

Once the folder is created with the 2 files (build.xml and jslint4java jar file) in the repository let’s go to the Jenkins job to install the violation plugin and configure the job.

First let’s configure the ant task in the Job (my directory is under trunk/test):

Ant configuration

Then we configure the Violation plugin in the Job:

Violation plugin configuration

Let’s save and run the build and we should see a graph the following in the Job page:

Violation graph in job page

If you click on the left menu on Violations (or in the graph) you will see the same graph with the number of violations per file:

Number of violations per file

If you click on the filename you will see all the violations with the respective row numbers:

Violations in a file

If you click on the row number you can see the line of the code (just below):

Photobucket

Enjoy fixing your javascript file :-)

Advertisements

Axis2: codegen Ant task; perchè no ?

Sempre piccola nota per chi genera web services a partire da file wsdl.

Fino ad ora avevo suggerito di usare il wizard di Axis2 su Eclipse perchè più completo di quello di Netbeans. Ebbene si usarlo alla fine è comodo ma non mi accontento soprattutto quando il wizard lascia qualche parametro implicito come la cartella resources.

Vi spiego meglio: se generate il codice dal wizard e, tra l’altro usate xmlbeans, vi ritrovete la cartella resources come root nel progetto java. In questa cartella ci sono il file wsdl ricopiato, il file services.xml e una cartella usata da Xmlbeans per gli schema generati. Fatto sta che se rilanciate il wizard per un altro web services tale cartella viene sovrascritta, in particolare il file services.xml viene sovrascritto.

Questo accade perchè l’output di default va nella root del progetto fatta eccezione per la cartella src in cui ci vanno le classi generate. Per impedire questo dovete sapere che il comando del codegen prende il parametro -R dove si puo’ indicare un path alternativo per la cartella resources.

A questo punto siccome mi piace automatizzare le cose (pigrizia da programmatore) mi sono chiesto se ne vale la pena usare il comando Ant relativo che permette di impostare tutte le opzioni.

A mia sorpresa scopro che il path che va specificato per il tag targetResourcesFolderLocation deve essere relativo al path specificato nel tag output.

Cmq era giusto per ricordarvi che è comodo poterlo usare basta importare alcuni package come specificato nella pagina:

http://ws.apache.org/axis2/tools/1_4_1/CodegenToolReference.html

Ant e le espressioni regolari

Mentre oggi ero intento a generare un po’ di web services tramite axis2 il mio capo mi chiede di fare un lavoretto per conto di altre persone in azienda.

In pratica chiedono di modificare all’incirca 100.000 file di testo in formato XML, di 2kb, modificando il testo all’interno di un tag. La modifica è uguale per tutti: il testo da modificare in pratica contiene un path ad un file pdf e si  tratta aggiungere alla fine del path l’estensione “.pdf”.

Mi sono detto, siccome sto studiando Ant, perchè non farlo con questo ?

La cosa buona di Ant è che si puo’ installare ovunque ci sia una java virtual machine, fino ad ora avevo usato i miei script bash ma il mio capo mi disse sarebbe bello poterli far girare su Windows cosi’ ho preso a studiarmi Ant che non credo (fino ad ora) sia potente come la bash ma scopro di giorno in giorno le sue potenzialità. Qualcuno dirà che anche il perl e il python possono essere usati ma ho preferito questo.

In realtà Ant è una applicazione java e i suoi script sono file xml. I tag di questi file corrispondono a relative classi java permettendo quindi la loro estensione.

Ant può copiare e spostare file e directory, creare jar e war file per il deploy, calcolare l’md5 dei file, agire su variabili da usare come condizioni, collegarsi ad un CVS, creare test con Junit e tra le altre cose lavorare con le espressioni regolari.

Se vi serve una introduzione ad Ant, che vi collega al mio precedente articolo sull’integrazione continua, la redazione di Mokabyte ne scrisse una interessante:  eccovela !

Una volta installato (estratto) Ant ho configurato le variabili di ambiente ANT_HOME che punta alla cartella estratta e PATH che punta alla sottocartella bin.

Ho poi creato il file “build.xml” e l’ho messo insieme a file da modificare; il fatto di metterlo nella stessa cartella non è strettamente necessario perchè poi gli do la cartella di lavoro come parametro.

Ed eccovi il file:

<?xml version="1.0" encoding="UTF-8"?>
<project name="program" default="convert" basedir=".">
<property name="folder" value="." />
<property name="backup_folder" value="backup" />
<property name="file_extension" value="inf" />
<property name="tag" value="PrintFileName" />
<property name="extension" value="pdf" />

<target name="backup" description="backup folder">
<mkdir dir="${folder}/${backup_folder}" />
<copy todir="${folder}/${backup_folder}" >
<fileset file="${folder}"/**.*${file_extension}" />
</copy>
</target>

<target name="del_extension">
<replaceregexp
  match="<${tag}>(.*).${extension}<\/${tag}>"
  replace="<${tag}>\1<\/${tag}>">
<fileset dir="${folder}" includes="*.${file_extension}" />
</replaceregexp>
</target>

<target name="add_extension">
<replaceregexp
  match="<${tag}>[^(\.${extension})]<\/${tag}>"
  replace="<${tag}>\1.${extension}<\/${tag}>">
<fileset dir="${folder}" includes="*.${file_extension}" />
</replaceregexp>
</target>

<target name="convert" description="open files and add an extension to the text inside the selected tag">
<antcall target="backup" />
<antcall target="add_extension" />
</target>

</project>

Intestazione XML a parte, nella seconda riga dichiaro che il target (funzione o metodo) da richiamare di default è convert. All’interno di questo target richiamo dapprima il target backup che realizza il backup della directory di lavoro e poi richiamo add_extension per modificare i file xml.

I parametri di default quali la cartella di lavoro (folder), la cartella di backup (backup_folder), l’estensione dei file che vado a modificare (file_extension), il tag xml che seleziono (tag) e l’estensione che aggiungo nel path (extension) sono definiti all’inizio del file e possono anche essere passati come parametro ad Ant.

Ad esempio se do:

ant -Dfolder=./test

Indico che la cartella dei file da modificare è la sottodirectory test, attenzione che se nel path ci sono degli spazi dovete usare le virgolette ” ” prima e dopo il path.

Il target backup crea quindi una cartella (mkdir) di backup dentro alla cartella di lavoro e copia in essa (copy) i file dalla cartella di lavoro con l’estensione che ho indicato (fileset). Se non volete fare il backup potete semplicemente rimuovere il suo richiamo nel target convert.

Andiamo alla parte delicata, come avete notato il target del_extension non viene richiamato, me lo sono lasciato per convienenza e vi permette di capire più facilmente il target add_extension.

Con il target del_extension si vuole selezionare tutti i path con il tag selezionato che già contengono la stringa “.pdf” e rimuoverla. Per fare ciò usiamo il task replaceregexp che ha 2 attributi: match e replace.

Con l’attributo match selezionamo il tag XML, di default PrintFileName, che contiene la stringa mentre con il tag replace sostituiamo la stringa trovata. I caratteri < e > mi servono per sostituire < e > in quanto non vengono accettati direttamente, poi vedete la variabile ${tag} che viene aperta e chiusa (usando \/ in quanto il simbolo / è particolare) e all’interno l’espressione (.*) che indica tutti i caratteri con a seguire l’estensione .${extension}.

Quello che vogliamo fare è sostituire tutti i caratteri trovati nel mezzo togliendo l’estensione, il risultato della stringa trovata in match con i caratteri (.*) è indicata con \1.

Applico infine questa trasformazione all’insieme di file tramite il task fileset.

Il target add_extension dovrebbe funzionare al contrario se non che può capitare che alcuni path finiscano già per “.pdf” e quindi corriamo il rischio di aggiungerli nuovamente perciò nel mezzo è stato aggiunta l’espressione [^(\.${extension})] che indica di escludere tali path.

Semplice no ?

Ora non sono un esperto di espressioni regolari, me le sono giuste viste un pò, ma la cosa mi ha fatto apprezzare di più Ant.