Introduzione a CVS e messa a punto

Da Wiki di NetBSD Italia.

In questa guida si tratterà prima di CVS in generale e poi della sua messa a punto, cioè impareremo a configurare un server CVS appoggiandoci ad OpenSSH, ovviamente il tutto in un ambiente NetBSD.

Indice

Introduzione

CVS è un sistema di controllo versione: uno strumento molto utile, soprattutto per programmatori, che permette di gestire la cronologia di progetti. Ogni modifica fatta dallo sviluppatore viene memorizzata e quindi è anche semplice ritornare alla modifica precedente se l'ultima versione ha, per esempio, dei bug.

La potenza di CVS però si può osservare quando vi sono più sviluppatori. Se si sta sviluppando un software ogni sviluppatore può sviluppare tranquillamente negli orari che preferisce e gli altri sviluppatori una volta che riprendono il loro sviluppo dovranno semplicemente eseguire un aggiornamento del codice sorgente (cioè scaricare le modifiche che ha fatto il primo sviluppatore).

Anche NetBSD utilizza CVS come sistema di controllo versione.

La nostra situazione

Prima di tutto la situazione che abbiamo di fronte è la seguente: abbiamo più macchine, un server con NetBSD-stable (brucaliffo) in cui faremo girare il server CVS (e quindi funzionerà da repository) ed un desktop, sempre con NetBSD (bianconiglio). Oltre a queste macchine vi è una macchina con NetBSD-current (cappellaiomatto) e la rete locale ad un altra macchine con GNU/Linux (alice).

Gli sviluppatori hanno accesso ai computer bianconiglio, cappellaiomatto ed alice, e quindi sviluppano, compilano e testano i programmi sotto quegli ambienti.

L'esigenza

Gli sviluppatori però non usano tutti la stessa macchina: lo sviluppatore leot preferisce sviluppare su bianconiglio e cappellaiomatto, mentre l'utente gilberto di solito utilizza la macchina alice. Da qui nasce il primo problema: come fare ad avere il codice sorgente condivisibile con tutte le macchine e sempre accessibile? Ed una volta fatto ciò come si può gestire le versioni del codice al meglio? E se dovesse arrivare un altro sviluppatore esterno che vuole accedere solo al codice sorgente senza avere la possibilità di modificarlo? In questo documento daremo una risposta a tutte queste domande, per ora la nostra semplice e breve risposta è CVS.

Configurazione del server

La directory ${CVSROOT}

Iniziamo a risolvere il nostro problema: configuriamo subito il server CVS. Il destino di brucaliffo come server CVS era già segnato dall'inizio, per questo abbiamo fatto un apposito slice /cvsroot:

# mount | grep cvsroot
/dev/wd0h on /cvsroot type ffs (local)

La sua dimensione è di circa 5Gb, questa dimensione (da come si può facilmente intuire) dipende dalle vostre esigenze: un paio di Gb già sono abbastanza. Abbiamo scelto di fare uno slice apposito solo per il repository perché in questo modo se /cvsroot dovesse diventare troppo grande e superare la dimensione dei 5Gb possiamo stare tranquilli: la nostra / o la nostra /home non verrà esaurita. Se così non fosse possiamo creare la directory con un semplice mkdir(1):

# mkdir /cvsroot

Permessi e gruppi della ${CVSROOT}

Ora impostiamo i giusti permessi. I nostri progetti dovranno stare nelle sotto-directory di /cvsroot/, ad esempio /cvsroot/chello/. Quelle sotto-directory dovranno appartenere al gruppo degli sviluppatori di quel progetto, per semplicità noi avremo tutte le sotto-directory che appartengono al gruppo cvsusers, ma si potrebbe fare per ogni progetto un gruppo apposito: ad esempio un gruppo chellodevs che possono sviluppare solo il progetto chello. Creiamo la directory chello per il progetto chello:

# cd /cvsroot
# mkdir chello

Ed ora creiamo il gruppo a cui dovranno appartenere tutti i nostri sviluppatori:

# groupadd cvsusers

Infine aggiungiamo a questo gruppo lo sviluppatore leot.

# usermod -G cvsusers leot

Per vedere i nostri sviluppatori possiamo utilizzare lo strumento groupinfo(1):

# groupinfo cvsusers
name    cvsusers
passwd  *
gid     1001
members leot

Potente e semplice, non trovate? Ops, quasi scordavamo, che sbadati, dobbiamo dare i giusti permessi a chello:

# chgrp cvsusers /cvsroot/
# chmod 775 /cvsroot/
# cd /cvsroot/
# chgrp cvsusers chello/
# chmod 775 chello/

Ecco fatto. Ora arriva la parte più divertente... scrivere codice!

Utilizzare CVS

Scrivere un piccolo progetto

Ci trasferiamo un attimo su bianconiglio, ed iniziamo a scrivere chello.c un programma che stampa la stringa Hello, world! scritto in C:

$ mkdir chello/
$ $EDITOR chello.c
[...]
$ cat chello.c
#include <stdio.h>


/*
 * The main routine
 */
int main(void)
{
   /* Print the string "Hello, world!\n" via printf() and exit */
   printf("Hello, world!\n");

   return 0;
}

Configurare le variabili CVSROOT e CVS_RSH

Bene, ora siamo pronti per importare il progetto ed iniziare ad utilizzare CVS, per prima cosa dobbiamo configurare la variabile ${CVSROOT}, cioè il nostro repository:

$ export CVSROOT=":ext:leot@brucaliffo:/cvsroot"

Vogliamo accedere al server utilizzando OpenSSH:

$ export CVS_RSH="ssh"

Per caricare il server OpenSSH su brucaliffo basta aggiungere sshd=YES sul file /etc/rc.conf, o altrimenti forzare il caricamento nel seguente modo:

# /etc/rc.d/sshd forcestart

Inizializzare ed importare il progetto

Perfetto, ed ora importiamo il tutto!

$ cvs init
$ cvs import -m "chello first version imported" chello CHELLO CHELLO_0-1

Per fare entrambi le operazioni ci chiederà la password dell'utente leot della macchina brucaliffo, una volta inserita fa l'operazione richiesta. Analizziamo ora i due comandi:

  • init: inizializza il nostro repository, dobbiamo usarlo la prima volta per inizializzare il server CVS.
  • import: importa tutti i file presenti nella directory in cui siamo posizionati (nel nostro caso solo chello.c) sul server CVS remoto. Vuole tre opzioni: directory in cui importare il progetto (chello), vendor tag (CHELLO) e release tag (CHELLO_0-1).

L'opzione -m invece si può usare anche in altri comandi (ad esempio commit), quest'opzione specifica il commento dell'azione che abbiamo fatto. Se la omettiamo si aprirà il ${CVSEDITOR} (se dichiarata) o ${EDITOR} che ci permetterà di editare il nostro commento.

Ottenere il progetto: checkout

Ora per vedere che abbiamo fatto tutto bene otteniamo il nostro progetto chello tramite un checkout (si chiama così l'opzione per ottenere l'intero albero dei sorgenti di un repository):

$ cd ..
$ rm -r chello/
$ cvs checkout chello

Questo checkout crea la directory che abbiamo appena rimosso chello/ e prende tutto l'albero dei sorgenti del progetto chello.

Apportare modifiche e miglioramenti ad un file del progetto: commit

Ora però ci siamo accorti di aver fatto una piccola imprecisione sul nostro progetto, il return 0 in C è sconsigliabile e di cattivo stile, è meglio utilizzare l'apposita costante EXIT_SUCCESS presente nell'header file stdlib.h, editiamo quindi chello.c:

$ $EDITOR chello.c
[...]
$ cvs commit -m "ugly return 0 removed" chello.c

Da come si può osservare l'utilizzo dell'opzione commit è semplicissimo: l'unico parametro di cui abbiamo necessariamente bisogno è il nome del file da aggiornare (nel nostro caso chello.c).

Aggiornare l'albero dei sorgenti: update

A volte può risultare utile aggiornare l'intero albero dei sorgenti, ad esempio dopo aver editato e salvato il file chello.c per sbaglio, o (come succede la maggior parte delle volte) perché altri sviluppatori hanno apportato qualche modifica all'albero dei sorgenti e noi vogliamo stare aggiornati all'ultima versione disponibile.

$ cvs update

Confrontare due diverse versioni di un file: diff

Se per esempio modifichiamo la copia di chello.c sul client CVS e poi vogliamo confrontarla con la copia sul server CVS possiamo utilizzare l'opzione diff di cvs nel seguente modo:

$ cvs diff chello.c

Un altro esempio di utilizzo di diff (e probabilmente anche più utile) è quello tra due versioni diverse:

$ cvs diff -r 1.2 -r 1.3 chello.c

In questo modo confrontiamo la versione 1.2 con la versione 1.3 di chello.c.

Ottenere la cronologia di un file: log

Tramite il comando log si può osservare tutti i cambiamenti di un file, in questo caso se abbiamo precedentemente fatto un buon utilizzo del flag -m ciò può fare la differenza (può risparmiare un sacco di tempo per trovare una cattiva modifica o per rendersi conto delle modifiche fatte ad un file, per esempio):

$ cvs log hello.c

Aggiungere un file o una directory: add

Per aggiungere un file o una directory dobbiamo utilizzare il comando add, la stringa passata tramite il flag -m è la descrizione di questo file, ad esempio:

$ cvs add -m "chellòs license" COPYING

Ora per rendere questo file disponibile dobbiamo eseguire il commit, come già abbiamo visto sopra:

$ cvs commit -m "COPYING added, chello now is under GPLv3" COPYING

Rimuovere un file o una directory: remove

L'approccio affrontato con l'opzione add è piuttosto simile a remove. Il comando remove permette di cancellare un file o una directory possiamo utilizzarlo, ad esempio, in questo modo:

$ rm chello.c
$ cvs remove chello.c
$ cvs commit -m "chello.c removed (too wine in my head)" chello.c

Ops, quel file era di vitale importanza, ma non c'è nessun problema, lo possiamo recuperare:

$ cvs add chello.c
$ cvs commit -m "chello.c magically restored" chello.c


CVS non è solo cvs(1): cvsweb

In questo capitolo affronteremo l'installazione e la messa a punto di cvsweb, questo strumento ci permette di accedere in maniera alternativa alla nostra ${CVSROOT} preferita: tramite un browser web grazie al protocollo http.

Che cosa è cvsweb e perché utilizzarlo

cvsweb è uno script CGI scritto in Perl, è un interfaccia per repository CVS. Risulta utile quando vogliamo accedere al nostro repository tramite il nostro browser web preferito.

Installazione

cvsweb è presente in pkgsrc sotto www/cvsweb, per installarlo basta digitare:

$ cd ${PKGSRCDIR}/www/cvsweb
$ make install clean-depends

Oppure ottenerlo tramite pkg_add:

# pkg_add cvsweb

Configurazione e messa a punto

Assumendo che la nostra wwwroot sia /www/root copiamo tutti i file necessari e configuriamo l'apposito file di configurazione ${LOCALBASE}/etc/cvsweb/cvsweb.conf come segue:

# mkdir /www/root/cvs
# cd /www/root/cvs
# cp ${LOCALBASE}/libexec/cgi-bin/cvsweb.cgi .
# cp -r /usr/pkg/share/examples/cvsweb/css/ /www/root/cvs/
# cp -r /usr/pkg/share/examples/cvsweb/icons/ /www/root/cvs/

Ora modificare le righe di cvsweb.conf come segue:

[...]
@CVSrepositories = (
    'local' => ['Local Repository', '/cvsroot'],
);
[...]
my $iconsdir = '/cvs/icons';
[...]
$cssurl = '/cvs/css/cvsweb.css';
[...]

NOTA: sul server web www/lighttpd bisogna anche rimuovere sullo shebang l'opzione -T passata all'interprete perl per funzionare correttamente.

cvsweb ancora più carino: print/enscript e devel/cvsgraph

cvsweb può utilizzare diversi strumenti esterni per rendere la nostra interfaccia ancora più elegante, come ad esempio enscript e cvsgraph.

GNU Enscript

Tramite GNU Enscript possiamo ottenere il syntax highlighting, per installarlo basta farlo nel modo preferito, è infatti presente in pkgsrc sulla categoria print/:

$ cd ${PKGSRCDIR/print/enscript
$ make install clean clean-depends

o tramite pkg_add:

# pkg_add enscript

Dopo averlo installato basta copiare tutti i file presenti in ${WRKSRC}/enscript/ su ${LOCALBASE}/share/enscript/hl/, ad esempio:

# cp /usr/pkgsrc/www/cvsweb/work/cvsweb-3.0.6/enscript/*.st /usr/pkg/share/enscript/hl/

CvsGraph

CvsGraph invece è utile per creare dei grafici delle varie versioni, per installarlo:

$ cd ${PKGSRCDIR/devel/cvsgraph
$ make install clean clean-depends

oppura via pkg_add:

# pkg_add cvsgraph

Una volta installato proprio come GNU Enscript cvsweb si accorge che CvsGraph è presente nel sistema e lo utilizzerà, anche senza editare la sua configurazione (file ${LOCALBASE}/etc/cvsgraph.conf).

Conclusioni

CVS è uno strumento molto utile e potente. In questa guida abbiamo affrontato la messa a punto di un server CVS ed il suo utilizzo base; per ulteriori informazioni consultare gli approfondimenti.

Buon divertimento con CVS e felice hacking!

Approfondimenti

  • guida ufficiale di CVS, leggibile tramite un info CVS
  • cvs(1): manpage del comando cvs (meno completa della pagina info)
  • Open Source Development with CVS 3rd Edition: libro libero che tratta in maniera completa CVS
  • [[Messa a punto di Lighttpd + PHP (mod cgi)]]: interessante guida esaustiva sul web server Lighty (indispensabile per far girare cvsweb)
Strumenti personali