| 1 | Je ne sais pas si nous utiliserons Darcs, mais si j'avais retenu cet |
|---|
| 2 | outil lorsque je l'avais découvert il y a quelques temps, c'est que |
|---|
| 3 | ses concepts m'ont beaucoup intéressés et m'ont inspiré dans ma |
|---|
| 4 | réflexion sur E3 et la gestion de configuration extrême. |
|---|
| 5 | |
|---|
| 6 | Une autre réflexion que je menais concernait comment fournir une |
|---|
| 7 | interface textuelle. Fabrice nous en a récemment rappelé |
|---|
| 8 | l'importance. L'autre jour, dans un éclair de lucidité, ces deux |
|---|
| 9 | sujets en apparence distincts se sont rejoints. Je vais essayer de |
|---|
| 10 | décrire cette vision. |
|---|
| 11 | |
|---|
| 12 | Il faut commencer par ne plus penser au code comme un ensemble de |
|---|
| 13 | fichiers source, et ne plus penser au développement et à la gestion de |
|---|
| 14 | configuration comme une manipulation de fichiers contenant du |
|---|
| 15 | texte. Visualisons le code comme quelque chose de concret, qui possÚde |
|---|
| 16 | une structure, des formes, des relations. Par analogie, au lieu de se |
|---|
| 17 | mettre au niveau du code génétique (séquence d'ADN), on regarde |
|---|
| 18 | l'organisme vivant, sa structure cellulaire voire physiologique. |
|---|
| 19 | |
|---|
| 20 | Alors, chaque intervention sur le code devient une intervention |
|---|
| 21 | logique, ayant un sens concret. On ne modifie pas les caractÚres 30 à |
|---|
| 22 | 35 de la 56Úme ligne d'un fichier, on change le nom d'une variable |
|---|
| 23 | locale utilisée dans une fonction donnée. |
|---|
| 24 | |
|---|
| 25 | Imaginons un outil qui comprendrait cette structure du code. Pour |
|---|
| 26 | manipuler le code, il faut lui demander une intervention logique, pas |
|---|
| 27 | une édition d'un fichier source. Il offrirait tout un éventail de |
|---|
| 28 | commandes élémentaires (ajout d'une instruction, ajout d'un argument, |
|---|
| 29 | modification d'un nom de méthode...), des commandes plus complexes |
|---|
| 30 | composées de plusieurs commandes élémentaires (ajout d'une classe), et |
|---|
| 31 | des opérations intelligentes (refactoring). |
|---|
| 32 | |
|---|
| 33 | Ces commandes "logiques" sont un candidat parfait pour une interface |
|---|
| 34 | textuelle avec l'outil. Autant ce serait débile d'imaginer une |
|---|
| 35 | interface en ligne de commande pour faire de l'édition de fichiers |
|---|
| 36 | sources (on reviendrait à l'éditeur "ed" d'Unix, c'est vraiment un |
|---|
| 37 | retour en arriÚre par rapport à Emacs ou d'autres IDE modernes), |
|---|
| 38 | autant je trouve cela intéressant, au lieu d'aller trouver un fichier |
|---|
| 39 | source dans une arbo, de l'ouvrir, de descendre à la 56Úme ligne, de |
|---|
| 40 | sélectionner un mot à la souris et de saisir "newName", de simplement |
|---|
| 41 | saisir : |
|---|
| 42 | |
|---|
| 43 | e3 rename local variable MyModule:MyFunc:toto titi. |
|---|
| 44 | |
|---|
| 45 | Surtout si l'outil est assez intelligent pour modifier toutes les |
|---|
| 46 | occurrences de la variable dans la fonction ! |
|---|
| 47 | |
|---|
| 48 | Outre l'intérêt d'offrir un langage de commande (testabilité, |
|---|
| 49 | intégration avec des outils externes et tout simplement ergonomie pour |
|---|
| 50 | une utilisation avancée), cette approche à base de "commandes |
|---|
| 51 | logiques" offre une vision puissante et innovante de la gestion de |
|---|
| 52 | configuration. |
|---|
| 53 | |
|---|
| 54 | La gestion de configuration consiste à gérer les versions successives |
|---|
| 55 | du code, et à gérer le développement par équipes. Avec des commandes |
|---|
| 56 | logiques, la gestion de versions successives devient un jeu d'enfant |
|---|
| 57 | dÚs lors qu'on constate l'évidence que toute commande logique à une |
|---|
| 58 | commande inverse. Il suffit donc de conserver une trace de toutes les |
|---|
| 59 | commandes effectuées, et on peut à tout moment revenir en arriÚre en |
|---|
| 60 | appliquant une ou plusieurs commandes inverses. Notons au passage que |
|---|
| 61 | nous disposons par la même occasion d'une trace permettant de faire du |
|---|
| 62 | rejeu (Ã des fins d'analyse d'anomalies) et offrant un enregistrement |
|---|
| 63 | Ã des fins ISO9000/CMM bien plus utile (car intelligible |
|---|
| 64 | sémantiquement) que des diffs et bien plus objectif et fiable que des |
|---|
| 65 | commentaires mis dans CVS. |
|---|
| 66 | |
|---|
| 67 | Quant à la question du développement par équipe, nous avons à la fois |
|---|
| 68 | une façon d'égaler les fonctionnalités existantes (update, commit, |
|---|
| 69 | fusion...), et le moyen d'aller beaucoup plus loin. |
|---|
| 70 | |
|---|
| 71 | C'est là que cela ressemble un peu à la philosophie de Darcs. Chacun |
|---|
| 72 | travaille de son cÎté, puis soumet au référentiel ses |
|---|
| 73 | modifications. Les modifications sont soumises sous la forme d'une |
|---|
| 74 | séquence de commandes logiques. Là où cela devient intéressant, c'est |
|---|
| 75 | que si les autres binÎmes décident de faire un update (de récupérer |
|---|
| 76 | chez eux les modifs de quelqu'un d'autre), ils le font aussi sous |
|---|
| 77 | forme de commandes logiques... Or une commande logique, appliquée sur |
|---|
| 78 | du code qui n'est pas le même que celui sur lequelle elle a été |
|---|
| 79 | appliquée à l'origine, ne fera pas forcément la même chose |
|---|
| 80 | physiquement, mais devrait en fait faire ce qu'un développeur aurait |
|---|
| 81 | voulu. Il ne devrait même plus y avoir de "conflits" au sens CVS. On |
|---|
| 82 | peut même appliquer deux "patchs" dans un ordre différent, et toujours |
|---|
| 83 | tomber sur un résultat correct! Par contre, on peut déceler de |
|---|
| 84 | véritables conflits, par exemple lorsque deux commandes logiques ont |
|---|
| 85 | toutes les deux cherché à renommer une fonction. |
|---|
| 86 | |
|---|
| 87 | Prenons l'exemple de deux tâches menées en parallÚle qui ont modifié |
|---|
| 88 | la même ligne de code. Une tâche a renommé une fonction partout dans |
|---|
| 89 | le code, l'autre a éliminé du code dupliqué en extractant deux zones |
|---|
| 90 | de code semblables dans une nouvelle fonction. Or, cette zone de code |
|---|
| 91 | contenait un appel à la fonction dont le nom a été modifié par l'autre |
|---|
| 92 | tâche. CVS serait incapable de gérer cette situation. Avec l'approche |
|---|
| 93 | en question, c'est possible. Lorsqu'on applique la commande logique |
|---|
| 94 | "rename function" sur le code d'un binÎme, elle renomme la définition |
|---|
| 95 | et tous les appels, y compris dans les /deux/ zones de code |
|---|
| 96 | dupliqué. Sur le code du binÎme qui a lui supprimé cette duplication, |
|---|
| 97 | elle renomme la définition et tous les appels, y compris celui qui se |
|---|
| 98 | trouve maintenant dans la nouvelle fonction! Mais le plus fort est que |
|---|
| 99 | l'inverse est vrai aussi. Le binÎme ayant supprimé la duplication a |
|---|
| 100 | lui-même fait une séquence de commandes logiques qu'on peut appliquer |
|---|
| 101 | aussi au code du binÎme qui a renommé la fonction, et ce dans |
|---|
| 102 | n'importe quel ordre... |
|---|
| 103 | |
|---|
| 104 | Du coup, c'est là qu'on peut envisager (mais il faudra expérimenter à |
|---|
| 105 | l'usage) une approche consistant à "broadcaster" en temps réel toutes |
|---|
| 106 | les commandes logiques faites par les uns et les autres, et tout le |
|---|
| 107 | monde update continuellement (en fait quasiment sans s'en rendre |
|---|
| 108 | compte...) Et tout cela avec toujours la possibilité de faire "undo", |
|---|
| 109 | Ã la fois individuellement dans son propre espace, ou dans le |
|---|
| 110 | référentiel, ou globalement chez tout le monde! |
|---|