Code multi-projet et versionning
#1
Salutations,

Je souhaite vos idées pour savoir comment vous gèreriez le cas de structure que j'ai, et que je vous présente ci-dessous.

Ayant plusieurs projets de jeux web tournant en même temps, j'ai quelques codes communs entre eux.

J'ai donc regroupé ces codes dans un projet dédié, appelé "Common", avec d'autres codes utiles constituant un genre de "framework", au sens *large* du terme. J'ai donc, dans ce projet "Common":
- sources/php/framework/* qui contient là des classes de "framework" classiques, histoire de ne pas me repalucher les enum des headers HTTP, des Mimetypes, ou mon logger Mantis
- sources/config/* avec mes configs Apache, mysql, etc
- sources/idea/* avec des configurations de mon IDE
- sources/shell avec des bash script et autres bat utilitaires (pour faire des commit hooks par exemple, ou autre scans/synchro de l'état des dépots mercurial)
etc

Bref, ce n'est pas juste un projet avec 3000 classes PHP réinventées pour le plaisir de refaire du framework.

Ensuite, dans mes projets de jeux (disons ECLERD, Variispace et Dracca), j'ai copié/collé la partie /sources/php/framework de ce Common project. Pour cela, j'ai une phing task "framework/pull" qui se content de dropper le sources/php/framework/* du projet (d'ECLERD par exemple si je suis sur le projet ECLERD) et de copier à la place le sources/php/framework du Common project, puis de commiter ça dans le projet (avec le message "Update to FW commit 78946515674648765" histoire d'avoir le n° de commit correspondant dans Common).

Donc, après un "pull framework" via Phing, j'ai ECLERD qui s'est synchronisé sur mon Common. Cela me permet donc de "récupérer" les modifications de ce Common project *uniquement* quand j'en ai besoin (ie: c'est pas un "maven version = latest") et de faire éventuellement les refactorings dans le projet qui sont nécessaires à ça.

Maintenant, quand ECLERD a besoin de changer des trucs dans ce Common project, pour rajouter une nouvelle classe ou en modifier une, ou autre. Ce que je fais, c'est que je modifie *dans ECLERD* le contenu de sources/php/framework/* pour faire mes modifs, et les tester dans la foulée. Une fois que les modifications me vont (elles vont généralement impacter un bout de sources/php/framework/* dans ECLERD, mais aussi des classes de ECLERD lui-même), je commite l'ensemble de ces modifications dans ECLERD, avec un "(+FW)" à la fin du message. Par exemple: "Added formatter for Excel export (+FW) #1234" (1234 étant le n° de ticket si j'en ai un). Ce genre de commit, pour l'exemple, va rajouter une classe de formattage /sources/php/framework/responder/PdobeanOdsResponder.php et modifier des classes d'ECLERD pour utiliser ce formatter.

Mais du coup, ECLERD a des modifs de /sources/php/framework/* qui ne sont pas dans le projet Common. J'ai donc, dans ECLERD, une second task "framework push" qui va supprimer le sources/php/framework *du Common project* et coller à la place celui d'ECLERD, puis m'inviter à aller ouvrir le projet Common dans mon IDE pour vérifier les modifs avant de les commiter manuellement (une fois commités dans Common, elles seront donc "pullable" par les autres projets, qui pourront faire leurs mises à jour).

Le seul défaut là dedans, c'est qu'avant de modifier sources/php/framework/ dans un projet, il faudrait que je pense à "pull" le Common d'abord, histoire d'être à jour dessus. Ca m'arrive d'oublier... Lors du "push" vers le Common, j'ai donc les modifcations que j'ai faites dans mon projet (ECLERD) mais aussi un "revert" des modifications du Common que je n'avait pas "pullé" dans ECLERD...


L'alternative plus standard qui existe serait de faire les modifs du Common dans le Common, de le "release", puis d'indiquer dans les projets le n° de version du Common à utiliser. Mais cela m'oblige à release le Common avant de pouvoir tester, dans ECLERD, si tout marche... Je trouve ça lourd?! Et quand bien même il existerait un moyen, cela m'obligerait à modifier le Common dans mon projet Common, à "fake release" ces modifs, à les mettre à jour côté ECLERD, et enfin seulement, vérifier si c'est tout OK... C'est très leeent (et chiant) je trouve.

J'avais aussi, avant, mis un symlink du projet vers le Common (ECLERD/sources/php/framework => Common/sources/php/framwork) et ignoré ce symlink dans ECLERD, mais cela signifiait que si ECLERD change des classes du Common, alors Variispace et Dracca ont direct les modifs et *doivent* les intégrer immédiatement... pas pratique (sans compter que le dossier étant ignoré par ECLERD, je ne sais pas dans quel "état" il était à une époque donnée). Donc, j'ai laissé tombé ça.

Comment géreriez-vous ce genre de cas? Mes buts sont:
- de rester léger dans l'archi, parce que je n'ai pas des modifs à faire tous les 4 matins
- de rester léger à l'usage, car je ne veux pas perdre 10 minutes de synchro entre les projets à chaque ligne à changer
- de conserver une notion de "freeze", car je ne veux pas qu'une modif de Common par le projet A oblige les projets B C et D à se mettre à jour avant de continuer leur vie
- d'être "rollbackable", car je veux pouvoir revenir facilement 1 semaine en arrière sur un projet si j'ai tout merdé

Vos idées?
Répondre
#2
ma vision (et c'est ce qu'on fait de note côté):

seul common peut changer common.

c'est donc :
Citation :L'alternative plus standard qui existe serait de faire les modifs du Common dans le Common, de le "release", puis d'indiquer dans les projets le n° de version du Common à utiliser.

y a un triple intérêt:
- ça t'oblige a vérifier sur ta dernière version de common que tout est ok
- ça te pousse à mettre à jour ton projet client quand il en a besoin
- ça évite que des équipes "projet" interviennent sur le "common" (normalement des équipes plus expertes)

bon évidemment dans le cas d'un type tout seul le troisième point n'est pas valable


Citation :Mais cela m'oblige à release le Common avant de pouvoir tester, dans ECLERD, si tout marche... Je trouve ça lourd?! Et quand bien même il existerait un moyen, cela m'obligerait à modifier le Common dans mon projet Common, à "fake release" ces modifs, à les mettre à jour côté ECLERD, et enfin seulement, vérifier si c'est tout OK... C'est très leeent (et chiant) je trouve.

pas vraiment
le processus que nous avons si un projet a besoin d'un changement/ajout

je développe le changement dans le projet, je le teste dans le projet, je le valide dans le projet (mais dans des fichiers spécifiques du projet, via surcharge ou création de classe, ou que sais-je, ça dépend du langage)

le jour où on décide que ce changement mérite une industrialisation (donc mise au pot commun), on récupère le code et on l'intègre dans common. On le teste dans common, on le valide dans common (avec potentiellement des améliorations du fait qu'il devient générique)

Puis on modifie le projet (et éventuellement d'autres) en supprimant les fichiers spécifiques pour intégrer la fonctionnalité proposée par common puis test et validation.

L'intérêt de ce processus est de focaliser le projet sur le projet. La fonctionnalité est "common-able" mais elle est d'abord fait pour le projet (planning, tout ça) et elle doit marcher pour le projet, sans réfléchir trop (réfléchir est dans notre adn cependant) sur les cas non utiles au projet

et quand on bascule sur common, ce n'est pas que du copier coller, c'est de la prise de recul, de l'enrichissement, de l'optimisation mais dans un temps plus long, sans la pression du planning du projet
[WIP]projet Rivages
[WIP]projet Arthur (comme si ça suffisait pas d'un...)
Répondre
#3
En effet, c'est la solution "formelle" sur laquelle j'étais initialement parti il y a quelques mois... Mais j'ai fini par la trouver lourde, n'ayant pas des équipes différentes entre Common, ECLERD, Dracca, Variispace, etc.
Si je viens à avoir différentes équipes (aucune chance 2 ), je pense que je procèderai comme tu l'as décris.

D'ici là, j'ai modifié un peu le process pour régler le "merge" manuel que je me tappais actuellement:
- Je fais les modifs dans le projet sur sources/php/framework/ de sorte qu'elles m'aillent bien (et en sachant que dès là, je m'assure qu'elles seront utiles aux autres projets, sinon, je fais mes modifs dans sources/php/projet plutôt)
- Je lance ma syncro (finit les 2 tasks, j'en ai une seule), qui se charge de tout (code ci-dessous)

Le contenu a été masqué



Le principe:
- J'ai 1 branche/projet dans mon "Common"
- Je push mes changements de projet sur la branche correspondante
- Je merge ces changements avec la branche "default" (=master), si ça conflict, je résoud à la mano (pas le choix!)
- J'update sur la branche "default", et je clone le code du Common de cette branche dans mon projet
- Je commit mon projet qui est maintenant à jour de mon Common

J'ai quelques lignes de complexité en plus pour éviter de faire ces opérations si "elles n'ont pas d'intérêt". Ca me permettra de faire, comme tu dis, mes modifs de Common dans le Common (le merge), avec la réflexion qu'il faut si besoin pour abstraire/généraliser les trucs (ou changer d'avis et revenir en arrière) puisque les changements issus du projet passent d'abord par une branche dédié à ce projet (si j'avais plusieurs équipes, le "merge" ne serait donc pas immédiat dans la foulée), tout en pouvant bidouiller dans le projet sans être bloqué 2 mois parce que j'ai besoin de 2 mois pour réfléchir à ma modif de Common.
En plus, au passage, je sais de quel projet viennent les changements du Common, et j'ai le n° de commit correspondant. Ca m'aidera sûrement à remonter la piste en cas de pépin.
Répondre
#4
Perso j'ai un repo pour chaque chose ... c'est beaoucoup plus simple. Ou alors j'ai un seul gros repo et je commit uniquement dans ce repo, et si je dois déployer un sous-dossier je ne déploie pas avec git mais avec une release. Comme ça pas de problème.
Répondre




Utilisateur(s) parcourant ce sujet : 1 visiteur(s)