Git per il controllo di qualità
Wednesday, June 8th, 2011Dopo aver parlato dell’uso dei filtri con Git, penso sia una buona idea descrivere gli usi degli hook in pre commit, ad esempio, per fare dei controlli preventivi di qualità.
JavaScript non è cattivo, sono i browser che lo dipingono così
Chiunque abbia un po’ di dimestichezza con JavaScript se che ci sono delle differenze fra le varie implementazioni dei browser che possono dare problemi, anche molto gravi1 , a partire da un codice apparentemente senza difetti.
Un caso classico è l’uso della virgola dopo l’ultimo elemento di una collezione: lo standard lo proibisce ma quasi tutti i browser lo interpretano senza problemi. La frase “quasi tutti i browser” di solito significa “tutti tranne Explorer” ed è così anche in questo caso ma a parti invertite. Qui è Explorer che applica alla lettera le specifiche interrompendo il parsing e lasciando gli utenti a piedi2.
Un altro caso classico, questa volta applicabile a tutti i browser, è l’uso di variabili non dichiarate. In questo caso la cosa è più subdola perché non si tratta di un errore dalle conseguenze vistose, ma specifico per qualche browser, bensì di una cosa perfettamente legale che può causare problemi solo in certe condizioni. Neanche questa è una bella prospettiva!
Insomma, è necessario un qualche strumento che ci permetta di controllare la qualità del codice che scriviamo prima che venga mandato nella repo.
JSLint e JSHint
Per controllare la qualità di JavaScript conosco due strumenti: JSLint e JSHint.
Il primo è quello più famoso, è in circolazione da molto e fa un lavoro egregio nel segnalare una serie sterminata di possibili problemi.
Il secondo è una derivazione di JSLint, creata con l’intenzione di dare uno strumento un po’ più adattabile alle convenzioni usate in un certo progetto.
Ho scelto JSHint proprio per questa ragione perché negli ultimi tempi mi sono abituato a scrivere le virgole prima dell’argomento successivo3:
var items = [
'a'
, 'b'
, 'c'
];
Il problema è che JSLint non ne vuol sapere di considerarlo valido.
Come invocare i controlli
Il problema con entrambi questi strumenti è che sono scritti essi stessi in JavaScript e quindi, visto che dobbiamo invocare i controlli da Git, ci serve un interprete al di fuori del browser.
Per fare questo, l’avrete già capito, possiamo usare Node.js, che possiamo installare con MacPorts o Homebrew o a mano; poi ci serve npm per installare i moduli di Node.js, in particolare node-jshint, che consente di usare JSHint con Node.js.
Node.js ed npm sono molto semplici da installare. Per quanto riguarda JSHint bisogna solo avere l’accortezza di installarlo nella directory dei moduli condivisa, definita da npm come installazione globale.
Una volta installato il tutto ci serve un script di shell che invocheremo dall’hook di pre-commit di git. Questo script ha il solo compito di leggere l’output di JSHint ed emettere l’eventuale segnale d’errore, visto che la utilità di suo non lo fa anche se ci sono problemi. Limitandoci al minimo indispensabile:
#!/bin/sh
#
# Verifica la conformità dei file js alle linee guida stabilite.
RESULT=$(node-hint public/scripts/*.js)
if [ "$RESULT" != 'Lint Free!' ] ; then
echo "$RESULT"
exit 1
fi
Lo script appena mostrato va messo in .git/hooks/pre-commit.
Altre possibilità
In questo caso specifico, ovvero, quello del controllo dei file JavaScript ci sono altre possibilità. Per TextMate ci sono un paio di bundles: js-tools e javascript-tools che fanno questo e molto altro; per Emacs la situazione è meno strutturata e, come sempre, bisogna arrabattarsi per adattare le varie info che si trovano in rete alla propria situazione; per ora ne faccio tranquillamente a meno.
- Quanto gravi? Il caso descritto più avanti, ovvero, la presenza di una virgola in coda ad un oggetto letterale, ha causato un’interruzione di quasi un giorno del sito di Lifehacker, all’inizio di Febbraio.
In questo caso va notato che il problema è stato esacerbato dall’eccessiva dipendenza da JavaScript per costruire la pagina, un anti-pattern che è circolato molto negli ultimi mesi. L’abuso dello scripting per comporre il contenuto in pagina ha tante forme ma quella più conosciuta, usata appunto anche da Lifehacker, è il cosiddetto hashbang pattern.
Mi sembra un caso da manuale di inversione dei fini: Google introduce l’hashbang per poter indicizzare anche le pagine con contenuti dinamici, mettendo una toppa ai siti costruiti senza tenere in considerazione il progressive enhancement; gli sviluppatori prendono questo rimedio e lo usano come base di partenza su cui costruire l’architettura dei link di un sito, compromettendone la robustezza. ↩
- Sto semplificando selvaggiamente perché il punto del post non riguarda le specifiche di JavaScript e le sue implementazioni. In particolare non tengo conto né delle versioni dei browser né di quelle dello standard. ↩
- Quando ho visto questa convenzione per la prima volta l’ho trovata bizzarra, tuttavia mi sembra che renda il codice più facilmente manipolabile perché la virgola serve a separare l’elemento successivo e quindi ha senso che viaggino insieme. ↩