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
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