Retour de subversion sur le N900

The view of the front of a Nokia N900
Image via Wikipedia

L’évolution des distributions Linux consiste principalement à s’assurer que les divers logiciels puissent cohabiter entre eux, notamment en vérifiant les dépendances des logiciels vis-à-vis des librairies. Ainsi une simple incompatibilité d’un logiciel avec la version d’une librairie centrale ou d’un logiciel phare de la distribution suffit à écarter celui-ci.

Sous Maemo 5, il existe un paquet subversion qui a cessé de fonctionner depuis une récente mise à jour (PR1.3?). En effet subversion crash sur un segmentation fault. La raison en est la dépendance de subversion vis-à-vis de la librairie APR (Apache Portable Runtime) qui a changé de version mais est devenu incompatible avec le paquet subversion.

Malheureusement le paquet subversion pour N900 est devenu orphelin. Son mainteneur ne va pas repackager une version compatible avec la dernière version de la distribution du système (voir ce thread sur le forum maemo.org). Heureusement que le système de gestion de paquet permet de forcer la version des librairies … Au risque d’introduire de nouvelles incompatibilié.

Ainsi pour refaire fonctionner subversion il suffit de lancer la commande suivante en root

apt-get install libaprutil1=1.3.9-2 libapr1=1.4.2-1

Les versions sont celles qui fonctionnaient avec le paquet subversion pour Maemo 5 au moment où il a été créé.

Plus de subversion pour Maemo

Maemo 5 Screenshot
Image via Wikipedia

Il y a quelques temps, j’ai développé des programmes pour mon N900 en utilisant l’environnement ESBox qui est un Eclipse avec tous les plugins adéquoits. La seule chose qui manquait était la présence du client subversion (ou tout autre SCM) dans l’edtiteur. Mais cela n’était qu’une problème passager car il suffisait d’installer via Eclipse les bons plugins. De même sur le terminal, je souhaitais avoir accès au dépôt de source et l’installation du client subversion via un apt-get me donnait alors toute satisfaction.

Mais voilà, le N900 est le dernier de la famille Maemo car Nokia est passé sous le giron de Microsoft… cela s’en ressent dans l’environnement de développement. En effet la dernière version de la Virtual Appliance (Machine Virtuelle dont le but est d’embarquer un ESBox déjà configuré), le support de subversion est cassé. Il ne s’agit d’ailleurs pas de subversion spécifiquement, car toute mise à jour ou ajout de plugin semble cassé. Il m’est donc devenu impossible d’utiliser l’intégration d’éclipse dans ESBox. Cela m’oblige à passer en ligne de commande pour exécuter des svn status, svn add, svn commit… un poil moins sympathique qu’un clic dans Eclipse.

De plus, le client subversion du terminal ne fonctionne plus non plus. Toute commande svn provoque un segmentation fault. Une solution glaneé sur le forum de maemo.org propose une installation de subversion depuis les sources mais cela n’a pas fonctionné chez moi. Je dois ssans doute mal m’y prendre car non habitué à la compilation d’application native sous Linux.

Le retour dans le panier de python est un peu décevant mais c’est le prix de la liberté !

Révision globale subversion dans un projet en python chez googlecode

Il est courant dans un projet d’insérer dans les sources la révision du fichier. Cela est accomplit par le système de versionnage de source par un mécanisme de substitution d emot clé. Par exemple le mot clé Revision balisé par $Revision:$ est automatiquement remplacé par subversion par $Revision: 70$ si la révision du fichier est 70.

Ce mécanisme est très utile si on veut pouvoir raccroché un source à un révision en dehors de l’environnement de développement. Cela est en l’occurence utile quand on souhaite remonté un bug dans un projet en python. Imaginons un projet ecrit en python. Python étant un langage interprété, l’application est distribuée sous forme de fichiers sources .py. Lorsqu’une exception survient, python peut rapporter la pile d’execution constituant un début rapport d’erreur. Mais il faut encore associer cette pile à une version de l’application. Quand l’application est en version finale, on peut inclure dans le livrable la version commerciale de l’application mais il est encore plus facile pour le développeur d’inclure dans le rapport la révision des sources. Et c’est encore plus vrai quand l’application est en phase de développement ou de beta-test.

C’est exactement ce qui m’arriva avec Zourite, une application de réseautage professionnel pour N900. Zourite contient un mécanisme de rapport de bug qui envoie la pile d’erreur au site du développement du projet. Ce dernier étant hébergé par googlecode, je n’ai pas d’accès aux mécansime de hook subversion. Je dois donc me contenter de la substitution de révision qui ne fournit pour un fichier que la plus récente révision où ce fichier a été modifié. Or la pile d’éxecution fait appel à plusieurs fichiers donc afin que le développeur reproduise le bug, il me faut absolument la révision gloable des sources qui ont produit le bug.

Subversion fournit un outil svnversion mais celui-ci doit être executé sur un copie local des sources donc il n’est pas utilisable avec l’application livrée. De plus n’ayant pas accès au serveur subversion de googlecode, il m’est impossible d’envisager utiliser un hook pour automatiser le renseignement de la révision globale du projet.

Mais heureusement python contrairement à Java utilise la notion d’import dans son sens originel c’est-a-dire monter en mémoire un module et non pas comme un simple raccourci de notation comme en Java. Donc on peut se servir des instruction d’import des module python pour que l’application parcours tous les modules la composant. Si chaque module va proposer sa révision à un module centralisant les révisions, on est capable de connaitre la révision globale du projet… à l’éxécution.

La mise en place du mécanisme de substitution est assez aisé. Pour un ajout automatique à un nouveau fichier, suivre les instructions ici pour lesquels nous retiendrons les étapes suivantes:

  1. ouvrir le fichier ~/.subversion/conf
  2. dans la section [miscellany] décommenter la ligne enable-auto-props = yes
  3. dans la section [auto-props] ajouter la ligne *.py = svn:eol-style=native;svn:keywords=Revision

Malheureusement les fichiers qui sont déjà sous subversion ne seront pas affectés. Il faut donc un a un leur rajouter la propriété de substitution. Dans ESBox il faut selectionner le fichier et dans le menu contextuel ouvrir le menu Team > Set property:

Ajout propriété svn à un fichier dans ESBox

Puis selectionner pour property name la propriété svn:keywords et pour property content la valeur Revision

Répéter l’opération pour tous les fichiers où subversion doit appliquer la substituoin par mot clé.

Maintenant nos pouvons ajouter le mot clé $Revision$ dans les sources python. Cette valeur sera reprise par chaque module et soumis à un module centrale qui portera la révision globale.

Voic le code source du module centrale qui lui même renseigne sa révision à lui-même !

# -*- encoding: UTF-8 -*-
'''
Created on 28 mars 2010

@author: thierry
'''

CURRENT_VERSION = "1.0-SNAPSHOT"  # this must be modified before any release

def getInstance():
 return SINGLETON

class Version(object):
 '''
 Hold the revision of the application.
 '''        

 def __init__(self):
 '''
 Constructor
 '''
 self.revision = ""

 def submitRevision(self, rev):
 '''
 submit a new revision. If the revision is upper than
 the current revision, it become the new current revision
 '''

 if self.revision < rev:
 self.revision = rev

 def getRevision(self):
 '''
 Return the scm revision for this application
 '''
 return self.revision

 def getVersion(self):
 '''
 Return the marketing version for this application.
 '''
 return CURRENT_VERSION

SINGLETON = Version()  # object that track the revision of current applcation for issue tracking purpose

getInstance().submitRevision("$Revision: 73 $")

Chaque module doit alors à l’instar du module version lui-même, renseigner sa révision. Ainsi chaque module devra contenir en dernière instruction d’import le code suivant:

import version
version.getInstance().submitRevision("$Revision: 74 $")

Quand on aura besoin de connaitre la révision globale de l’application pour soumettre un bug par exemple, il suffit de faire :

versionInstance = version.getInstance()
versionStr = versionInstance.getVersion()
revisionStr = versionInstance.getRevision()

Révision globale subversion dans un projet en python chez googlecode

Il est courant dans un projet d’insérer dans les sources la révision du fichier. Cela est accomplit par le système de versionnage de source par un mécanisme de substitution d emot clé. Par exemple le mot clé Revision balisé par $Revision:$ est automatiquement remplacé par subversion par $Revision: 70$ si la révision du fichier est 70.

Ce mécanisme est très utile si on veut pouvoir raccroché un source à un révision en dehors de l’environnement de développement. Cela est en l’occurence utile quand on souhaite remonté un bug dans un projet en python. Imaginons un projet ecrit en python. Python étant un langage interprété, l’application est distribuée sous forme de fichiers sources .py. Lorsqu’une exception survient, python peut rapporter la pile d’execution constituant un début rapport d’erreur. Mais il faut encore associer cette pile à une version de l’application. Quand l’application est en version finale, on peut inclure dans le livrable la version commerciale de l’application mais il est encore plus facile pour le développeur d’inclure dans le rapport la révision des sources. Et c’est encore plus vrai quand l’application est en phase de développement ou de beta-test.

C’est exactement ce qui m’arriva avec Zourite, une application de réseautage professionnel pour N900. Zourite contient un mécanisme de rapport de bug qui envoie la pile d’erreur au site du développement du projet. Ce dernier étant hébergé par googlecode, je n’ai pas d’accès aux mécansime de hook subversion. Je dois donc me contenter de la substitution de révision qui ne fournit pour un fichier que la plus récente révision où ce fichier a été modifié. Or la pile d’éxecution fait appel à plusieurs fichiers donc afin que le développeur reproduise le bug, il me faut absolument la révision gloable des sources qui ont produit le bug.

Subversion fournit un outil svnversion mais celui-ci doit être executé sur un copie local des sources donc il n’est pas utilisable avec l’application livrée. De plus n’ayant pas accès au serveur subversion de googlecode, il m’est impossible d’envisager utiliser un hook pour automatiser le renseignement de la révision globale du projet.

Mais heureusement python contrairement à Java utilise la notion d’import dans son sens originel c’est-a-dire monter en mémoire un module et non pas comme un simple raccourci de notation comme en Java. Donc on peut se servir des instruction d’import des module python pour que l’application parcours tous les modules la composant. Si chaque module va proposer sa révision à un module centralisant les révisions, on est capable de connaitre la révision globale du projet… à l’éxécution.

La mise en place du mécanisme de substitution est assez aisé. Pour un ajout automatique à un nouveau fichier, suivre les instructions ici pour lesquels nous retiendrons les étapes suivantes:

  1. ouvrir le fichier ~/.subversion/conf
  2. dans la section [miscellany] décommenter la ligne enable-auto-props = yes
  3. dans la section [auto-props] ajouter la ligne *.py = svn:eol-style=native;svn:keywords=Revision

Malheureusement les fichiers qui sont déjà sous subversion ne seront pas affectés. Il faut donc un a un leur rajouter la propriété de substitution. Dans ESBox il faut selectionner le fichier et dans le menu contextuel ouvrir le menu Team > Set property:

Ajout propriété svn à un fichier dans ESBox

Puis selectionner pour property name la propriété svn:keywords et pour property content la valeur Revision

Répéter l’opération pour tous les fichiers où subversion doit appliquer la substituoin par mot clé.

Maintenant nos pouvons ajouter le mot clé $Revision$ dans les sources python. Cette valeur sera reprise par chaque module et soumis à un module centrale qui portera la révision globale.

Voic le code source du module centrale qui lui même renseigne sa révision à lui-même !

# -*- encoding: UTF-8 -*-
'''
Created on 28 mars 2010

@author: thierry
'''

CURRENT_VERSION = "1.0-SNAPSHOT"  # this must be modified before any release

def getInstance():
 return SINGLETON

class Version(object):
 '''
 Hold the revision of the application.
 '''        

 def __init__(self):
 '''
 Constructor
 '''
 self.revision = ""

 def submitRevision(self, rev):
 '''
 submit a new revision. If the revision is upper than
 the current revision, it become the new current revision
 '''

 if self.revision < rev:
 self.revision = rev

 def getRevision(self):
 '''
 Return the scm revision for this application
 '''
 return self.revision

 def getVersion(self):
 '''
 Return the marketing version for this application.
 '''
 return CURRENT_VERSION

SINGLETON = Version()  # object that track the revision of current applcation for issue tracking purpose

getInstance().submitRevision("$Revision: 73 $")

Chaque module doit alors à l’instar du module version lui-même, renseigner sa révision. Ainsi chaque module devra contenir en dernière instruction d’import le code suivant:

import version
version.getInstance().submitRevision("$Revision: 74 $")

Quand on aura besoin de connaitre la révision globale de l’application pour soumettre un bug par exemple, il suffit de faire :

versionInstance = version.getInstance()
versionStr = versionInstance.getVersion()
revisionStr = versionInstance.getRevision()

Un environnement de developpement Java: création d’un projet

Les outils qui vont être utilisés sont déjà selectionnés et installés. Nous allons maintenant vérifier que tout fonctionne bien en créant un premier projet. La régle principale que je me fixe quand je dois créer un projet est que l’ensemble de la chaine de production doit être fonctionnelle avant tout développement à proprement parler. Cela siginifie que le dépot de source, le système de build et de reporting doivent être en parfait état de marche.

Dans le cas de notre environnement il s’agit de vérifier que Subversion, le mécanisme de build maven 2  couplé au système d’intégration continue Continuum sont pleinement fonctionnels.

L’installation de Subversion via le gestionnaire de paquet constituent seulement le dépaquetage du logiciel. Il faut encore créer  un “repository” ou dépôt de source puis paramétrer le serveur pour permettre l’accès à ce dépôt en distant. N’oublions pas que nous créons notre environnement de développement dans l’optique d’être un environnement ressemblant le plus possible à celui utilisé dans une équipe de plusieurs personnes. Pour cela nous commençons par créer le dépôt de sources en ouvrant une console et tapant la commande suivante

mkdir /home/thierry/repository/svn/default

Bien entendu vous aller utiliser le chemin qui correspond le mieux à votre besoin. Dans mon cas je veux seulement un repository dans mon répertoire personnel.Puis il faut initialiaser ce dépôt par la command :

svnadmin create /home/thierry/repository/svn/default

Puis il faut paramétrer le démon svnserve pour rendre ce repository accessible en distant. Cela passe par la création d’un fichier de /etc/init.d/svnserve

sudo vim /etc/init.d/svnserve

Voici le contenu du fichier

#!/bin/sh

set -e
if [ -x /usr/bin/svnserve ] ; then
HAVE_SVNSERVE=1
else
echo “Svnserve not installed.”
exit 0
fi

. /lib/lsb/init-functions

case “$1” in
start)
log_action_begin_msg “Starting SVN server”
svnserve -d -r /home/thierry/repository/svn/default
log_action_end_msg $?
;;
stop)
log_action_begin_msg “Stoping SVN server”
start-stop-daemon –stop –exec /usr/bin/svnserve
log_action_end_msg $?
;;
force-reload|restart)
$0 stop
$0 start
;;
*)
echo “Usage: /etc/init.d/svnserve {start|stop|restart|force-reload}”
exit 1
;;
esac

exit 0

Ajouter les droits d’éxécution au script par :

sudo chmod +x /etc/init.d/svnserve

Ce script devra être lancé automatiquement au démarrage de la machine. Nous l’ajoutons aux services de démarrage comme suit:

sudo update-rc.d svnserve defaults

Voilà le serveur de source est presque prêt. Il ne reste que l’étape des droit d’accès. En effet une Software Factory  ne doit pas permettre un accès non contrôlé au dépôt de source. Aller dans le répertoire du repository i.e. /home/thierry/repository/svn/default

repository subversion

Allez ensuite dans le répertoir conf qui contient les fichiers svnserve.conf et passwd. Modifier le fichier svnserve.conf en décommentant les lignes suivantes:

anon-access = read
auth-access = write
password-db = passwd

Cela a pour effet de n’autoriser que les utilisateurs authentifiés à modifier les sources, les autres ayant un accès en lecture seule. L’authentification se fait par le fichier passwd en y mettant des couples login = password comme par exemple :

thierry = thierry

Enfin le serveur de source est prêt. Lancer le par la commande suivante :

sudo /etc/init.d/svnserve start

Le titre de l’article est volontairement non révélateur de son contenu afin de souligner que la création d’un projet nécessite des étapes de préparation préalables. La première étape de la créationde l’environnement de développement est la mise en place du dépôt de source. Mais que l’on se rassure, la création d’un repository ne se fait pas à chaque fois que l’on crée un projet. Le prochain article de la série traitera de la création de l’arborescence du projet et de l’import dans le repository.

Un environnement de developpement Java: création d’un projet

Les outils qui vont être utilisés sont déjà selectionnés et installés. Nous allons maintenant vérifier que tout fonctionne bien en créant un premier projet. La régle principale que je me fixe quand je dois créer un projet est que l’ensemble de la chaine de production doit être fonctionnelle avant tout développement à proprement parler. Cela siginifie que le dépot de source, le système de build et de reporting doivent être en parfait état de marche.

Dans le cas de notre environnement il s’agit de vérifier que Subversion, le mécanisme de build maven 2  couplé au système d’intégration continue Continuum sont pleinement fonctionnels.

L’installation de Subversion via le gestionnaire de paquet constituent seulement le dépaquetage du logiciel. Il faut encore créer  un “repository” ou dépôt de source puis paramétrer le serveur pour permettre l’accès à ce dépôt en distant. N’oublions pas que nous créons notre environnement de développement dans l’optique d’être un environnement ressemblant le plus possible à celui utilisé dans une équipe de plusieurs personnes. Pour cela nous commençons par créer le dépôt de sources en ouvrant une console et tapant la commande suivante

mkdir /home/thierry/repository/svn/default

Bien entendu vous aller utiliser le chemin qui correspond le mieux à votre besoin. Dans mon cas je veux seulement un repository dans mon répertoire personnel.Puis il faut initialiaser ce dépôt par la command :

svnadmin create /home/thierry/repository/svn/default

Puis il faut paramétrer le démon svnserve pour rendre ce repository accessible en distant. Cela passe par la création d’un fichier de /etc/init.d/svnserve

sudo vim /etc/init.d/svnserve

Voici le contenu du fichier

#!/bin/sh

set -e
if [ -x /usr/bin/svnserve ] ; then
HAVE_SVNSERVE=1
else
echo “Svnserve not installed.”
exit 0
fi

. /lib/lsb/init-functions

case “$1” in
start)
log_action_begin_msg “Starting SVN server”
svnserve -d -r /home/thierry/repository/svn/default
log_action_end_msg $?
;;
stop)
log_action_begin_msg “Stoping SVN server”
start-stop-daemon –stop –exec /usr/bin/svnserve
log_action_end_msg $?
;;
force-reload|restart)
$0 stop
$0 start
;;
*)
echo “Usage: /etc/init.d/svnserve {start|stop|restart|force-reload}”
exit 1
;;
esac

exit 0

Ajouter les droits d’éxécution au script par :

sudo chmod +x /etc/init.d/svnserve

Ce script devra être lancé automatiquement au démarrage de la machine. Nous l’ajoutons aux services de démarrage comme suit:

sudo update-rc.d svnserve defaults

Voilà le serveur de source est presque prêt. Il ne reste que l’étape des droit d’accès. En effet une Software Factory  ne doit pas permettre un accès non contrôlé au dépôt de source. Aller dans le répertoire du repository i.e. /home/thierry/repository/svn/default

repository subversion

Allez ensuite dans le répertoir conf qui contient les fichiers svnserve.conf et passwd. Modifier le fichier svnserve.conf en décommentant les lignes suivantes:

anon-access = read
auth-access = write
password-db = passwd

Cela a pour effet de n’autoriser que les utilisateurs authentifiés à modifier les sources, les autres ayant un accès en lecture seule. L’authentification se fait par le fichier passwd en y mettant des couples login = password comme par exemple :

thierry = thierry

Enfin le serveur de source est prêt. Lancer le par la commande suivante :

sudo /etc/init.d/svnserve start

Le titre de l’article est volontairement non révélateur de son contenu afin de souligner que la création d’un projet nécessite des étapes de préparation préalables. La première étape de la créationde l’environnement de développement est la mise en place du dépôt de source. Mais que l’on se rassure, la création d’un repository ne se fait pas à chaque fois que l’on crée un projet. Le prochain article de la série traitera de la création de l’arborescence du projet et de l’import dans le repository.