Votre utilisation de svn:externals

24 views
Skip to first unread message

Romain Verdier

unread,
Jul 16, 2008, 10:48:27 AM7/16/08
to paris.alt.net
Juste par curiosité : Lorsque vous utilisez les externals dans
subversion, précisez-vous le numéro de révision correspondant à la
version du projet dont vous dépendez ? Ou laissez-vous les externals
pointer vers la head revision de chaque projet dont vous dépendez ?

Maxence Dislaire

unread,
Jul 16, 2008, 1:28:56 PM7/16/08
to paris...@googlegroups.com

Tout d'abord bonjour à tous!

 

Je viens tout juste de m'inscrire et suis très heureux d'avoir découvert des gens passionnés par la communauté ALT.Net!

 

C'est marrant je me suis posé la même question le mois dernier je pense.

 

Voici mon contexte d'utilisation du externals : j'ai 3 projets A, B et C et tous utilisent un framework. Chacun des 3 projets A, B, C et Framework ont leur propre repository svn. J'ai donc un répertoire externals dans les projet A, B et C.

 

Initialement les 3 externals pointaient sur le head du projet Framework.

 

Ce qui est intéressant:

 * Jusqu'à quel moment cette solution a été satisfaisante pour nous?

 * Quand ne l'à-t-elle plus était?

 

L'Histoire d'A,B C

 * Si on remonte dans le temps, un seul projet A existe incluant un Framework (1 seul svn).

 * Puis quelques mois plus tard, le projet B démarre et justement B et très intéressé par le Framework qui est dans A (mais ne veut rien savoir du projet A)

 * Il y a donc refactoring de A -> extraction du Framework et création d'un svn Framework séparé. B et A utilisent framework en externals (head) B et A ne se connaissent pas. (3 svn maintenant) Pause : Jusque la nous somme satisfait du externals en mode head car nous savons maitriser le cycle d'évolution de A, B et du Framework. Lorsque le projet Framework évolue, le projet A et B se synchronise avec un minimum d'effort. On va dire que c'est maitrisable.

 * On avance encore dans le temps. Un projet C démarre et lui aussi est très intéressé par le projet Framework. Même schéma : externals en mode head sur le SVN Framework. (4 svn maintenant) Pause : On continue d'être satisfait par le mode externals pendant un moment. Les évolutions se répercutent sur A, B, C assez naturellement. Mais les choses s'accélèrent. Victime de leur succès les projets A,B et C doivent évoluer. Or pour avancer correctement il faut faire une évolution majeure du projet Framework. (Mode : on va tout péter) Et la l'histoire du svn externals commence a devenir un vrai sujet dans mon contexte. Le refactoring va être importante sur Framework et donc grosse grosse impacte sur A,B,C. On baigne dans le "war-factoring"...

Mini Parenthèse et je reprend mon histoire juste après : Je suis un grand fan de resharper et impossible de me lancer dans un tel chantier sans cette outil. Hors nous avons 4 solutions :

 -> Framework.sln (projet .net)

 -> A.sln (référence Framework.csproj du externals)  -> B.sln et C.Sln pareil Dans A,B,C, j'ai référencé directement le projet csproj plutot que la dll *uniquement* pour bénéficier de Resharper. C'est aussi une facilité pour travailler simplement sur le framework. Refactoring, refactoring quand tu nous tiens! Le problème c'est que ca marche bien pour du petit refactoring. Lorsque je travail dans A.sln je dois manuellement impacter B.sln et C.sln... mais si je me lance dans un chantier de war-factoring dans le Framework resharper n'impactera pas les 3 projets A,B,C simultanément. Bref c'est la misère.

Reprise de l'histoire : Grosse décision est prise : on fusionne tous les projets dans la même solution pour récupérer les avantages de resharper. Mais impossible de tout faire d'un coup. Obligation de faire ca progressivement. D'abord on fussione A, puis B, puis C. On gèle donc les 3 externals. Il ne pointe plus sur le head mais sur un numéro de révision. Ensuite la fusion s'effectue très progressivement. Nous n'utilisons donc plus de externals. Le refactoring a d'ailleurs été une vraie partie de plaisir....

 

En bref! Dans mon contexte le svn:externals (head) m'a rendu de fiers service pendant longtemps. Le mode head était géré mais attention nous maitrisions complètement les cycles d'évolution du projet pointé par le externals (Framework). A noté que l'on a toujours su resté en mode head pour faire avancer les 3 projets plus ou moins simultanément. Au cas ou un projet ne pouvez pas suivre le rythme on aurait toujours pu geler le externals sur un numéro de révision donné (mais ca permet juste de gagner du temps. Il faudra tout de même faire la synchronisation si l'on veut 'décongeler' le lien externals). On peut aussi noter qu'a un moment nous avons fusionné tous les projets (gros gros chantier) et du coup nous n'avons plus besoin d'utiliser d'externals pour le projet Framework.

 

En tout cas la question du "head / pas head" est très liée à la maitrise (ou pas) de l'évolution du projet pointé par le svn:externals. Tout ca est aussi une longue histoire de refactoring ;-)

 

Et bien j'espère que ca pourra être utile.

 

A bientôt!

 

Max



2008/7/16 Romain Verdier <romain....@gmail.com>:

Gauthier Segay

unread,
Jul 16, 2008, 2:31:46 PM7/16/08
to paris.alt.net
Merci pour ce retour d'expérience très détaillé.

De mon côté je n'utilise pas le svn:external (j'ai découvert la
fonctionnalité il y'a à peine 1 an), je passe systématique par des
références aux binaires, même pour un framework interne.

Cela reste une fonctionnalité intéressante dans le cadre des branches
trunk de certains projets, en mode "cycle de dev continu jusqu'à
prochain ordre".

Pour revenir sur les possibilités de refactoring, cela est attrayant
au niveau maitrisable d'une solution, mais faire du refactoring d'un
framework en ayant ouvert les projets de 3 solutions de manière à coup
de resharper me semble quelquechose d'assez "risqué" (à moins d'être
le lead developer sur les 3 projets ainsi que sur le framework...).

Je peux comprendre qu'en utilisant un langage dynamique, cela soit
nécéssaire de passer par un tel outil, mais je m'accomode autant des
erreurs de compilations pour m'assister dans le refactoring (resharper
possède l'option change all MethodXXXX sur ces erreurs), même si c'est
un peu plus fastidieux, je pense que la solution décrite ne peut pas
"scaler" pour plusieurs raisons, on peut aussi faire des "stubs" en
enlevant les références et utiliser le refactoring pour faire en une
passe par solution.

Dans le cadre d'un framework, il est important de le faire évoluer de
manière raisonnée (utilisation d'ObsoleteAttribute, refactoring en
douceur), en général, j'attends d'avoir utilisé/implémenté/copié une
même fonctionnalité sur plusieurs projets avant d'en extraire une API
pure jugée "digne" d'intégrer un tel framework.

On va dire que dans une approche "separation of concerns" cela ne me
dérange pas d'avoir des breaking changes lors de la mise à jour d'une
référence, je trouve que faire le refactoring d'un framework en ayant
ouvert toutes les solutions le référençant ne s'inscrit pas trop dans
cette approche ;)

Gauthier

On Jul 16, 7:28 pm, "Maxence Dislaire" <maxence.disla...@gmail.com>
wrote:
> 2008/7/16 Romain Verdier <romain.verd...@gmail.com>:

Julien Lavigne du Cadet

unread,
Jul 17, 2008, 3:12:13 AM7/17/08
to paris.alt.net
Une question de se type s'est très longuement posé dans un job
précédent. Nous avions le même problème que Maxence à une échelle
significativement plus grande (litéralement des dizaines de solutions/
projets plus ou moins interdépendants).

A l'époque, nous avions décider de pointer sur la head par défaut. Les
petits refactorings étaient appliqués tels quels, il fallait donc
aller modifier à la main tous les projets qui dépendaient de la partie
modifiée. Pour les gros refactorings avec breaking changes et cie (ou
"war-factoring" :-)), nous avons choisi une approche plus extrème:
recreer de nouveaux repository/projets et les faire évoluer
indépendamment pendant la refacto. Autrement dit, c'est une sorte de
branche un peu spéciale. A la fin de la refacto, et en fonction du
contexte, on choisissait ce qu'on faisait des 2 repository. La plupart
du temps on gardait les 2 en activité pendant quelques mois, le temps
de tout migrer vers le nouveau repository et une fois qu'on était sur
que plus rien ne dépendait du vieux, on le faisait disparaitre.

Enfin, dans le cas ou on ne contrôlait pas un repository (par exemple
si on utilisait une brique open-source), on utilisait systématiquement
des binaires, afin d'éviter toute surprise...

Julien.

Romain Verdier a écrit :
> Juste par curiosit� : Lorsque vous utilisez les externals dans
> subversion, pr�cisez-vous le num�ro de r�vision correspondant � la
> version du projet dont vous d�pendez ? Ou laissez-vous les externals
> pointer vers la head revision de chaque projet dont vous d�pendez ?

Maxence Dislaire

unread,
Jul 17, 2008, 6:14:16 AM7/17/08
to paris...@googlegroups.com

Merci pour cette réponse très intéressante.

 

En effet, dans cette expérience je pilote les 3 projets (y compris le framework qui représente 60% de la volumétrie du code de tous les projets) sur une équipe d'une 10ene de développeurs incluant une équipe offshore. Pendant 2 ans, le refactoring ce faisait de cette manière: [ObsoleteAttribut], breaking changes et cie. Dans mon contexte, le projet A, B et C ne sont pas des erps mais des outils de montage/production de videocast (flash/silverlight,...) donc le tout est très proche structurellement parlant. Victime de leurs succès, les demandes d'évolutions ont commencées à pleuvoir. Mais il fallait passer un cap structurelle important pour avancer correctement. Cette modification structurelle du framework était très impactante (couplage afferrent très élevé sur A,B et C forcément).

 

D'ailleurs je vous rejoins complètement. Pour les mêmes raisons que vous énoncez je ne voulais surtout pas faire de fusion. Un projet de cette taille est peut-être gérable par le lead développeur mais pour avancer correctement les équipes responsables des projets A, B C ne doivent *absolument* pas se connaître ou se marcher dessus. Quand mon équipe A travaille, je ne veux elle impacte B au minimum. Etc...

 

Voici a quoi ressemble la ligne produit a la fin du chantier de refactoring:

 

SVN ligne produit.

+trunk

 +Framework

  +Framework.sln (aucun couplage avec A,B,C) (niveau d'exigence, criticité et contrôle très élevé)  +A

  +A.sln (reference Framework binaires)

  +A.All.sln (reference Framework csprojs)  +B

  +B.sln (reference Framework binaires)

  +B.All.sln (reference Framework csprojs)  +C

  +C.sln (reference Framework binaires)

  +C.All.sln (reference Framework csprojs)  +All.sln (A + B + C + Framework csproj. Solution uniquement réservée aux opérations de refactoring transversale - accès restreint)

 

Les équipes projets A, B et C n'ont l'accès qu'a ce qu'ils ont besoin de connaître et rien d'autre. Seulement certaines personnes ont l'accès au Framework. Le refactoring continue a se faire par [ObsoleteAttribut], breaking changes...

 

Grace a cette organisation, pour toutes modifications sur le framework impactant A,B,C nous avons maintenant 2 alternatives a notre disposition :

 * 1 - soit le cas générale [ObsoleteAttribut] / breaking changes.

 * 2 - soit utiliser la solution All.sln.

 

Le travail quotidien s'effectue dans A.Sln (idem pour les équipes offshore qui n'ont pas accès au Framework même en lecture) Le framework est référence en bbinaire donc refactoring impossible.

Pour les opérations de refactoring basiques, je demande a mes équipes projets de passer par A.All.sln ou ils ont un accès au Framework en écriture a procès de revue de code.

 

Pour un renommage de classe ou de méthode, par exemple on sait qu'on va passer par All.Sln (A+B+C+Framework). Avec R# (ou autre outil de refactoring) l'opération est tellement simple qu'elle devient très agréable. J'attache une grande importance a cette idée "d'opération agréable". Tout le monde sais que quand un truc est chiant a faire, à un moment donnée il y aura un problème humain a gèrer. En ce qui me concerne je peux être capable de dépenser bcp d'énergie pour rendre le refactoring 'agréable' a faire :-). J'ai vu trop de projet se paralyser lentement justement parque le refactoring ne faisait pas partie des trucs 'simples' à faire. Quit a prendre des risques parfois mais jusqu'à présent ca à toujours étant payant :-)

 

Max

Maxence Dislaire

unread,
Jul 17, 2008, 7:09:30 AM7/17/08
to paris...@googlegroups.com
Hello!

Une chose me revient : quand on fait une branch sur svn, svn ne va pas impacter les properties svn:externals. Il faut donc dans ce cas faire une branch puis pour "geler" la branche aller modifier "a la mano" les svn:externals pour qu'il pointe bien sur le numéro de révision - correspondant au numéro de révision du head - du projet pointé par externals. Hum... Si c'est pas clair c'est normale, je n'ai encore du boire assez de café. Bref:

Soit
A/trunk/[révision 1]
A/trunk/externals/B pointe sur B/trunk:head

Opération branchage de A/trunk vers A/branches/brancheCongelée
Au moment du branchage le numéro de revision head de B=1 mais svn ne va pas impacter la propriété svn:externals pendant la création de la branche
Pour la geler il faut aller modifier a la main la propriété externals dans A/branches/brancheCongelée/externals

On peut aller plus loin encore:
Si vous voulez créer un tag, il suffira de faire cette opération.
Dans le cas d'une branche (qui va avoir sa propre vie. une release par exemple) j'ai déjà rencontré ce cas d'utilisation : Le projet pointé par externals était un projet interne (un framework encore :-)) et nous avions du créer une branche *aussi" sur le projet Framework et mettre a jour a la main la propriété externals A/branches/releaseX/externals en mettant /B/branches/releaseX.

---

A Propos des références open source nous aussi, nous utilisons généralement les binaires dans un répertoire lib ajouté au svn. Nous n'utilisons que ce type de référencement de dll et jamais le gac (pour des outils qui pourraient ajouter les dll dans le gac).

A ce propos, on ajoute aussi les outils type nuint, nant dans un répertoire tools. Par contre on référencera bien la dll qui est dans lib.
On utilise tools plutot pour les batchs de build automatique ou un serveur d'intégration continue.

Dans 2 cas exceptionnelles nous avons directement inclus les code sources. Cas ou l'ont avez besoin de faire un fix ou une modif dans le code du projet. (Il s'agisait de DotNetNuke et SCSF). Je sais qu'on a faillit travailler activement sur un projet open source a un moment donnée (ffmpeg). Il était question de passer par un externals.head mais cela c'est fait différement.

Un dernier cas d'utilisation me revient, dans le cadre d'un projet nous avions besoin d'un bibliothéque de skin (pour un template de fichier flash html) Un projet interne .Net en production ayant besoin d'une skin en particulier la référencait en svn:externals en passant par le numéro de révision

---

Ah tiens encore un autre cas me revient : nous avons une application interne qui est *déployée sur svn". Si si! Le SVN déployment... Et oui! MS nous a tellement vendu de déployment copier/coller qu'on l'a fait avec svn :-) Super pratique! Et on a pas hésité longtemps entre ça et clic once ;-)

---

A mon avis on peut dire sans trop prendre de risque que pointer sur "head" c'est la regle et que pointer sur "le numéro de révision" c'est l'exception. Le cas brache restant a mon avis celui le plus 'standard'.

Qu'en pensez vous? Avez vous rencontré d'autres cas d'utilisations? Me prennez vous pour un dingue de svn? :-)

Max

2008/7/17 Julien Lavigne du Cadet <julien....@gmail.com>:

Romain Verdier

unread,
Jul 17, 2008, 9:05:48 AM7/17/08
to paris.alt.net
Merci à tous pour vos réponses ! Je vois que tout le monde s'est pris
la tête un jour ou l'autre sur ces problématiques, et il y en a encore
beaucoup du même genre inhérentes à la gestion de configuration.

Pour ma part, je considère qu'il vaut mieux *toujours* spécifier la
révision vers laquelle pointe une dépendance externe. IMHO, il n'y a
aucune vraie raison de garder une référence vers la head revision d'un
projet dont on dépend. C'est ce que je comptais développer dans un
billet prochainement ; d'où la question originale :)


On Jul 17, 1:09 pm, "Maxence Dislaire" <maxence.disla...@gmail.com>
wrote:
> 2008/7/17 Julien Lavigne du Cadet <julien.lavi...@gmail.com>:

Julien Lavigne du Cadet

unread,
Jul 17, 2008, 11:23:14 AM7/17/08
to paris.alt.net
Je pense que l'utilisation de la head ou non est archi-dépendant du
contexte.

Par exemple, en mode agile avec de petites équipes et de l'intégration
continu en place, ca passe très bien. Apres tout, le but de
l'intégration continue est justement d'intégrer les dernieres
modifications et de detecter les breaking changes.
En revanche, avec des cycles de développement plus long/moins agiles,
je tend à penser qu'il faut mieux spécifier la révision. Voir
carrément importer l'assembly plutôt que de récupérer les sources.

Julien.

DenisD

unread,
Jul 17, 2008, 4:19:35 PM7/17/08
to paris.alt.net
C'est vrai que c'est un casse-tête récurrent.

De mon côté j'ai pu constater que le partage de fonctionnalités au
niveau source amène souvent des problèmes quand les sources sont
éditables et que les tests unitaires sont absents ou insuffisants.
J'ai même envie de dire qu'en l'absence de tests unitaires sur le
framework partagé ET de tests sur chaque projet qui l'exploite, il y a
toujours de gros problèmes.

Donc sauf bonnes pratiques agiles (ne révons pas c'est assez rare
sinon on serait déjà 100 dans ce groupe :), je suis convaincu qu'il
vaut mieux pointer vers du figé. Et tant qu'à faire, vers du binaire
pour éviter d'être tenté de modifier les sources (ah la tentation de
modifier les projets open-source...).

Mais si voir les sources a un intérêt ou si la techno l'impose
(framework Javascript...), ou même si le contrat exposé par le
composant partagé est assez obscur (p. ex. le composant n'a pas été
pensé en termes d'API, il n'y a pas d'interface claire) et justifie
ainsi de voir le code, une révision partagée me semble acceptable.

Denis

PS : salut Max :)

On Jul 17, 5:23 pm, Julien Lavigne du Cadet <julien.lavi...@gmail.com>
wrote:
> > > > > pointer vers la head revision de chaque projet dont vous d�pendez ?- Hide quoted text -
>
> - Show quoted text -

Maxence Dislaire

unread,
Jul 17, 2008, 8:31:22 PM7/17/08
to paris...@googlegroups.com
Tiens Hello Denis!

Tous ces points de vues sont très intéressants!

Je suis entièrement d'accord avec Julien. Cela est archi-dépendant du contexte. Equipe agile ou pas. Projet démarrant ou pas. Projet maitrisé ou pas (Tests unitaires ou pas.) Développeurs expérimenté ou pas...

Sur un tel sujet, je pense que des guidelines dans le style : DO, DO NOT, CONSIDER, et AVOID se prêterait peut être mieux IMHO :-)

En tout cas pour moi ce qui est sur c'est qu'il y a des bons cas d'utilisation du head mais des moins bons aussi.

Max

2008/7/17 DenisD <denis....@gmail.com>:

Romain Verdier

unread,
Jul 21, 2008, 6:58:41 AM7/21/08
to paris.alt.net
Décidément je vais me faire détester pour continuer à penser qu'il est
préférable de toujours faire pointer ses externals vers des révisions
fixes :)

J'essaye de détailler mon point de vue ici :
http://romainverdier.wordpress.com/2008/07/19/la-propriete-svnexternals-et-les-revisions/

N'hésitez pas à me donner des exemples de configuration dans lesquels
il est mieux de laisser pointer les externals vers des head revisions.
J'ai longtemps travaillé de cette façon, mais maintenant je ne
voudrais plus y retourner... Peut-être ne suis-je pas assez souple !


On Jul 18, 2:31 am, "Maxence Dislaire" <maxence.disla...@gmail.com>
wrote:
> Tiens Hello Denis!
>
> Tous ces points de vues sont très intéressants!
>
> Je suis entièrement d'accord avec Julien. Cela est archi-dépendant du
> contexte. Equipe agile ou pas. Projet démarrant ou pas. Projet maitrisé ou
> pas (Tests unitaires ou pas.) Développeurs expérimenté ou pas...
>
> Sur un tel sujet, je pense que des guidelines dans le style : DO, DO NOT,
> CONSIDER, et AVOID se prêterait peut être mieux IMHO :-)
>
> En tout cas pour moi ce qui est sur c'est qu'il y a des bons cas
> d'utilisation du head mais des moins bons aussi.
>
> Max
>
> 2008/7/17 DenisD <denis.doll...@gmail.com>:

Gauthier Segay

unread,
Jul 28, 2008, 7:41:47 PM7/28/08
to paris.alt.net
Une utilisation probablement pertinente:

référencer des binaires en provenance d'un autre repository (pour des
simples questions d'administration) pour les images ou références dll?

On Jul 21, 12:58 pm, Romain Verdier <romain.verd...@gmail.com> wrote:
> Décidément je vais me faire détester pour continuer à penser qu'il est
> préférable de toujours faire pointer ses externals vers des révisions
> fixes :)
>
> J'essaye de détailler mon point de vue ici :http://romainverdier.wordpress.com/2008/07/19/la-propriete-svnexterna...
Reply all
Reply to author
Forward
0 new messages