traalberierami

Tra alberi e rami

Una introduzione a tutti i termini utilizzati nel mondo Mozilla quando si parla di versioni dei vari prodotti, con una spiegazione (anche storica) della scelta di alcuni termini.

Il muro linguistico

Capita a volte di appassionarsi a un progetto o a un'idea e spontaneamente essere colti dalla curiosità di saperne di più. Come in tutti i campi, anche nel mondo legato ai computer il più grande ostacolo per i non addetti ai lavori è costituito dalla barriera linguistica: non tanto dalla lingua Inglese, quanto dai termini prettamente tecnici. Come si cerca di superare un attimo le notizie generiche, ad esempio quelle che leggiamo su giornali e riviste, per scendere un po' più nel dettaglio, ci si incaglia subito su termini a prima vista sconcertanti e confusi. Prendendo come base il progetto Mozilla (Firefox e compagnia varia), cercheremo di fare un po' di chiarezza al riguardo, soprattutto per capire meglio come procede lo sviluppo di una base di codice così ampia e complessa, fatta di tanti piccoli pezzi incastrati insieme.

Analogie vegetali

Quando si parla di progetti Open Source, si parla spesso di "albero" e un po' meno spesso di "ramo", specialmente in abbinamento con "di sviluppo" oppure "stabile". Cerchiamo subito di chiarire questi termini. L'albero (in Inglese: "tree", oppure "trunk") non è altro che l'insieme di tutti i codici sorgenti di cui consiste un progetto, e prende tale nome perché la struttura, ovvero come questi codici sono catalogati e messi in relazione gli uni con gli altri, ricorda molto quella quasi gerarchica di un albero: abbiamo una radice (ad es. "mozilla/") che rappresenta la cartella principale che comprende tutti i sorgenti facenti parte del progetto, e quindi i vari tronchi e fusti (ad es. "mail/" per i sorgenti di buona parte di Thunderbird, o "browser/" per buona parte di Firefox). Tale struttura poi si esplica ancora meglio vedendo come i sorgenti sono organizzati in un file system tradizionale fatto di file e cartelle gli uni dentro le altre e così via, come possiamo vedere in figura:

mozilla/[root] (dimensione) (ultima modifica)

│ LEGAL 2k Aug 21 13:10

│ Makefile.in 5k Dec 6 02:10

│ README.txt 9k Mar 13 2004

│ aclocal.m4 687 Dec 20 2005

│ allmakefiles.sh 456k Dec 3 08:10

│ camino.mk 1k Nov 24 2004

│ client.mk 37k Dec 7 17:10

│ configure 638k Dec 4 22:10

│ configure.in 260k Dec 4 22:10

│ embed.mak 2k Sep 13 2005

│ embed.mk 4k Sep 13 2005

├───README/ - Dec 8 11:11

│ └───mozilla/ - Apr 19 2006

│ README.build 87 Dec 1 2001

│ README.os2 9k Apr 19 2006

├───accessible/ - Dec 8 11:11

.

.

.

.

└───xulrunner/ - Dec 8 11:11

│ Makefile.in 1k Oct 5 2005

│ build.mk 2k Oct 25 16:11

├───app/ - Apr 19 2006

.

.

.

└───stub/ - Apr 19 2006

Ho volutamente tralasciato il termine "ramo" perché esso rappresenta un concetto un po' diverso. Nel campo dello sviluppo di software infatti, un ramo (o "branch") è una versione particolare dell'albero o di parte di esso; spieghiamoci meglio. Durante lo sviluppo di Firefox, gli sviluppatori decidono che è giunta l'ora di fare uscire una nuova versione stabile del browser, diciamo la 2.0: stabiliscono quindi una data e un'ora esatta in cui verrà "tagliato" (in Inglese: "cut") il ramo 2.0 dall'albero principale. Il taglio del ramo consiste nel fare una "fotografia" dello stato attuale dei sorgenti, marcandoli con una stringa particolare: nel caso di Firefox tale stringa è "MOZILLA_1.8.1" che fa riferimento alla versione di Gecko (il motore grafico che genera le pagine a video) utilizzata dal browser. Una volta tagliato un ramo, lo sviluppo continua sia sull'albero principale, detto di sviluppo, sia sul ramo che di solito viene chiamato "stabile", perché in esso non vengono accettati grossi cambiamenti che potrebbero appunto metterne in pericolo la stabilità. Per essere più precisi, in un ramo stabile non vengono più accettate nuove funzionalità, né riscritture o miglioramenti delle funzionalità esistenti, ma solo le correzioni ai bug che non mettano a rischio la stabilità del codice (talvolta capita che chiudendo un buco da una parte si apra una voragine dall'altra), né sono permesse modifiche a come il software "comunica" con gli utenti (ad es. non è possibile modificare la spiegazione di un errore o il testo che compare in una finestra di avviso). Se gli sviluppatori ritengono che una modifica del trunk sia necessaria sul branch, devono valutarne il rischio ed in alcuni casi preparare una versione specifica della patch (una modifica ai codici sorgenti) da mettere nel ramo. Ciò accade perché lo sviluppo sul trunk non si interrompe mai, e quindi le versioni dello stesso file tra trunk e branch possono risultare anche molto diverse.

Cerchiamo di spiegarci con un esempio pratico.

Al momento della creazione del ramo, supponiamo che il file superBrowser.cpp (un file sorgente in C++ in questo esempio) sia alla versione 1.22: lo sviluppo sul trunk continua ed il file viene aggiornato più volte, cambiando numero di versione (1.23, 1.24, 1.25, ecc.), mentre sul ramo stabile essa rimane alla versione 1.22.0. Un bel giorno uno sviluppatore trova il modo di sistemare un bug che affligge superBrowser.cpp da prima della versione 1.22 (supponiamo un bel crash del browser) e propone una patch per il trunk: la patch viene controllata, approvata e applicata al trunk che ora non va più in crash per quel caso particolare. Gli sviluppatori sono molto soddisfatti della modifica e pensano che sia utile averla anche sul branch stabile: peccato che superBrowser.cpp versione 1.35 sia molto diverso da superBrowser.cpp versione 1.22. Deve quindi essere preparata una patch a partire da superBrowser 1.22 che sistemi lo stesso bug: anche questa patch viene analizzata, testata, approvata ed inserita sul ramo stabile, e superBrowser passa alla versione 1.22.1.

Ciò avviene per tutte le migliaia di file dell'albero! Sembrerebbe a prima vista una cosa complicatissima, ma in pratica non lo è affatto: sono infatti i tool di sviluppo come RCS (revision control system) e CVS (concurrent versioning system) che si prendono cura di gestire tutte le problematiche relative alla varie versioni stabili o meno dei sorgenti.

Eredità storiche

Passiamo ora a un'altra fonte comune di confusione, le versioni "stabili" e le versioni "nightly" degli eseguibili. Le prime altro non sono che le versioni ufficiali rilasciate da Mozilla dei suoi prodotti, ovvero 1.0, 1.5, 2.0 e tutte le relative revisioni di sicurezza (come 1.5.0.8, 2.0.0.1, ecc.). Le revisioni vengono tutte da uno stesso ramo: FF 1.5.0.x deriva dal branch 1.8.0, mentre FF 2.0.0.x deriva dal branch 1.8.1. Per chi è particolarmente curioso oppure impaziente, è possibile provare le versioni nightly. Storicamente, lo sviluppo del software è sempre stato un processo molto lungo e costoso, per cui durante il giorno si preparavano le modifiche al software che poi di notte sarebbero state compilate in una nuova versione da provare il giorno seguente, e così via, ciclicamente. Questo perché il costo dei computer (e la scarsa velocità) era tale che di giorno dovevano funzionare a pieno ritmo, mentre di notte (da qui il nome "nightly") andavano sfruttati in qualche modo per poter rientrare dai costi e per non interrompere mai il loro lavoro principale. Lo sviluppo ed il testing andava fatto nei tempi morti, per evitare di sottrarre del costosissimo tempo macchina al lavoro di tutti i giorni. Attualmente invece i cicli di test e compilazione possono essere portati avanti in contemporanea o addirittura su tante macchine senza grandi costi. La perdurante lunghezza dello sviluppo quindi è data dalla complessità del software; ovvero oggi un programma fa molto, molto di più di un suo equivalente di 10 anni fa, per esempio.

Esistono diverse versioni nightly, a seconda della provenienza:

    • Trunk: Sono le versioni eseguibili che vengono create tutti i giorni per poter provare l'albero principale di sviluppo. Solitamente sono versioni sconsigliatissime, visto che possono causare perdite di dati ed incompatibilità di diverso genere.
    • Branch: Sono le versioni di prova che compaiono di frequente prima di una nuova versione ufficiale. Ad esempio, su questo tipo di nightly viene effettuato il test delle localizzazioni dei prodotti.
    • Experimental: Queste sono versioni particolari del software, in cui viene sviluppata una specifica funzionalità. Di solito i cambiamenti sono talmente complessi e toccano così tanti file che gli sviluppatori preferiscono portare avanti le modifiche in un ramo parallelo, detto appunto "di sviluppo". Quando lo sviluppo sembra aver raggiunto gli obbiettivi fissati, allora il ramo viene riunito all'albero principale (in Inglese: "merged to tip", oppure "merged to trunk"), e le build experimental per quel ramo smettono di essere create.

Va ricordato che qualsiasi tipo di nightly non offre alcuna garanzia circa il suo funzionamento! Potreste installare una versione che non parte nemmeno, che vi distrugge il profilo o che vi formatta l'hard disk: insomma, comunque lo fate a vostro rischio e pericolo, e non pensate di potervi poi lamentare una volta fatto il danno! Dopo questa dovuta precisazione, bisogna dire che attualmente è molto difficile trovare delle versioni nightly così devastanti: nella peggiore delle ipotesi può capitare che per diversi giorni non esca una sola nightly che parte, ma di solito basta tornare alla versione di qualche giorno prima per non aver problemi di sorta.

La parte affascinante dell'installazione delle versioni nightly è la possibilità di provare le nuove funzionalità delle future versioni di Firefox e compagnia prima che il grande pubblico ne venga a conoscenza. Provando e riprovando le varie funzioni è possibile isolare e segnalare i problemi e magari anche suggerire delle modifiche. In un certo senso si diventa protagonisti dello sviluppo di Mozilla, e del suo continuo miglioramento (si spera). Certo, anche questa possibilità ha un costo: si deve rinunciare alla stabilità dei programmi su cui facciamo affidamento tutti i giorni, per vivere sul filo del rasoio (in Inglese: "bleeding edge").

E che c'entra l'alfabeto greco?

Per completare il quadro delle sigle relative alle varie versioni del software, bisogna accennare all'uso che si fa di alcuni caratteri dell'alfabeto greco. Si sente infatti parlare spesso di versioni "alfa" oppure "beta": che cosa indicano? Sempre storicamente, durante lo sviluppo di un software la designazione alfa ha riguardato il periodo che di solito segue una versione stabile e che segna l'inizio dei cambiamenti in vista della versione stabile successiva. E' il periodo in cui gli sviluppatori hanno più mano libera nella creazione del software, in cui non hanno grandi limitazioni e possono permettersi di mettere le mani e devastare, se lo ritengono necessario, tutto il codice che aveva funzionato fino al giorno prima... Insomma, se nella vita del software ci deve essere un periodo di grandi cambiamenti, aggiunte di funzionalità, o riscritture complete o quasi di funzionalità già esistenti, tutte queste prendono il via con le versioni alfa.

Dopo la "furia creativa" del periodo alfa, viene il periodo "beta", in cui si cerca di evitare l'aggiunta di funzionalità nuove, e si passa ad una fase di rifinitura e messa a regime di quanto fatto. Spesso la decisione di passare da alfa a beta coincide col raggiungimento degli obbiettivi di progetto programmati per la nuova versione stabile del software, ovvero quando tutte le nuove funzionalità previste sembrano essere state implementate, magari anche solo parzialmente. Durante la fase beta, il software viene sottoposto a prove sempre più esaustive per correggere il maggior numero di problemi e difetti (nessun software è privo di difetti). Questa viene anche detta la fase di ripulitura: il codice viene mondato dalle scorie dello sviluppo (funzionalità parzialmente implementate o scritte in maniera oscena pur di rispettare i tempi di consegna, ad esempio), vengono eliminati i bachi (difetti, in Inglese: "bug") più fastidiosi e vengono rifiniti per esempio l'interfaccia grafica ed i messaggi verso l'utente. Di solito è la fase più lunga e quella meno amata dagli sviluppatori che già stanno pensando alla loro futura nuova funzionalità (e magari hanno creato un branch sperimentale apposta).

Quando la situazione sembra accettabile, il prodotto sembra usabile e le nuove funzionalità sembrano lavorare a dovere, gli sviluppatori decidono di creare un nuovo branch stabile, come spiegato prima, e tutto il ciclo ricomincia. In passato oltre la fase beta c'era anche la fase "gamma", ovvero la fase di prova definitiva prima dell'uscita della versione ufficiale. Oggi di solito si usa la dicitura "Release Candidate", versione candidata ad essere pubblicata, ovvero la versione che sarà la prossima versione ufficiale a meno che non vengano scoperti problemi che rendano necessaria una ulteriore Release candidate. Nel mondo Microsoft a tale fase spesso ne segue un'altra che si chiama RTM (release to manifacture, ovvero "versione inviata alla produzione"), mentre nel mondo Mozilla in passato è stata indicata da versioni "Pre-Release" o anche "Technology Preview".

Buon approfondimento a tutti!

Scritto da: Giacomo Magnini (giacomo.magnini@mozillaitalia.org)

Tutti i diritti riservati - Ultima modifica: 20 Marzo 2008