Non aux brevets logiciels

SpipLab

Reves

PagePrincipale :: DerniersChangements :: Vous êtes 38.103.63.61 (Connexion)

rêves à propos d’un spip 2.0

Si je dis rêves, c’est juste pour que ça ne soit pas pris comme argent comptant. C’est juste des idées en vrac sur cette histoire de spip en légo évoqué je sais même plus quand sur la liste.

L’idée de base est la suivante : organiser les briques du code de spip comme les packages d’une distrib linux.

Dans une distrib, quelle qu’elle soit, on retrouve les mêmes règles :
-  certains packages de base sont nécessaires (le noyau, de quoi booter, les services basiques)
-  certains packages sont plus que conseillés (un environnement graphique)
-  certains packages sont au choix : la fonction est nécessaire ou fortement conseillée, mais différents packages remplissent cette fonction (noyau 2.4 ou 2.6, postfix/sendmail, gnome/kde)
-  certains packages dépendent d’autres packages (il faut X pour mettre kde, et il faut kde pour mettre koffice)

Pour qu’une distrib soit souple, il faut que les packages soient suffisamment petits pour permettre de mettre en place une fonctionnalité sans avoir à tout bousculer, et les dépendances doivent être bien cablées pour éviter les conflits (impossibilité d’installer un truc sans en dégager un autre)

Enfin, un package est généralement une entité à part entière, avec son propre historique, son versionning ... les dépendence ne sont pas simplement «X->Y» mais aussi «X version n -> Y version >= m».

Les dépendences n’étant pas forcément relative à un package donné mais plutôt à la fonction qu’il rempli, on trouve dans les packaging les notions de provides et de requires (je vois pas de mots français pour traduire ça sans risque de confusions - pourquoi pas permet ou fourni pour provides, et requière ou nécessite pour requires). Par exemple, «postfix» et «sendmail» sont des packages qui provide «mail», et «cron» et «at» require «mail».

De la même manière :
-  le code de spip contient des briques de taille plus ou moins importante (le compilo de squelettes est un gros morceau, alors que la gestion des meta est assez basique).
-  certaines briques dépendent d’autres (les meta sont nécessaires pour pleins de trucs et dépendent de l’accès bdd)
-  certaines fonctionnalités peuvent être faites par différentes briques au choix (librairie de génération de vignettes)
-  certains codes sont optionnels (les plugins, certains extensions de typo, ou même la possibilité de faire des forums ou d’utiliser les admins restreints) ou spécifiques à certains cas (codes spécifiques à certains hébergeurs)

L’idéal (d’où le terme «rêve» ;-) serait donc d’avoir la possibilité de monter son spip à partir d’un choix de briques :
-  on a une liste des briques avec un résumé de leur fonction et leur statut (nécessaire / optionnel / au choix ..)
-  on coche certaines briques, et l’installeur signale au fil de la sélection les dépendences afin d’obtenir un montage cohérent
-  on «clique sur ok» et on obtient un code spip «sur mesure»

Ensuite, chacune de ces briques peut être échangée contre une autre, mise à jour, supprimée ...

Les gros intérêts de cette approche :
-  chaque brique devient une entité à part entière, qui peut être maintenue par une équipe spécifique, ce qui permettrait d’éviter le système pyramidal actuel où toutes les discussions passent par une "autorisation" des codeurs "historiques".
-  chaque brique peut être testée individuellement afin d’avoir un code plus carré et faciliter des tests de non régression
-  une contrib, quand elle n’est pas trop transversale, peut être un package comme un autre
-  certaines fonctionnalités "au choix" peuvent être choisies dès l’installation au lieu d’être testée tout le temps (je pense surtout à certains tests bas niveau genre "peut on gzipper la sortie", ou les tests sur l’hébergeur)
-  on peut utiliser des packages en dehors de spip (formatteur typo pour spikini, méthode d’authent reprises dans spikini et mantis, système de cache ou de langue ..)
-  inversement, certains produits existants peuvent être packagés "à la spip" pour les utiliser (produits de gestion de cache, d’internationalisation ..)
-  les squelettes eux même peuvent être packagés sous cette forme (squelettes de base, eva, biospip ...), et gérés en dépendences (un jeu de squelettes utilisant les forums nécessite le package "forums").

Les points délicats :
-  chaque package doit être "pensé" de façon suffisamment générique pour qu’une implémentation différente puisse garder la même API (lire_meta pour le package meta par exemple, est assez immédiat, mais pour le cache ou l’accès à la base de données, c’est beaucoup plus coton).
-  la gestion des dépendences peut vite être un casse tête
-  le mécanisme de packaging lui même doit être défini (il faut qu’un package contienne du code, des dépendances, des "scripts" de pre et post install pour adaptation de la bdd et autres ...)
-  certaines parties transversales sont difficiles à séparer en briques. Typiquement, l’interface d’admin risque d’être éparpillée dans tous les coins, donc comment en faire une interface graphique cohérente ?

Les packages

Voici un début de brouillon de commencement de liste. L’idée, pour l’instant est de lister les fonctionnalités en vrac, sans chercher comment ça peut se coder. Ça permettra de lister les besoins avant de se jeter sur le cvs ;-)

-  jeux de squelettes
-  mécanisme de choix de squelettes
-  compilo de squelettes
-  gestion de cache (de metas, de messages, de squelettes compilés, de pages ... bref, un beau chantier)
-  metas (lire_meta et ecrire_meta)
-  messages et internationalisation (en gros, les fonctions _L et _T)
-  typo
-  formatteur (interprétation des raccourcis) (là, c’est à tiroirs : il peut y avoir des briques "raccourcis xyz")
-  accès à la (ou les) bdd (et ainsi faciliter les portages vers autre que MySql)
-  correcteur d’orthographe
-  article / brève / mot clés / forums / documents attachés (en gros, ça, coté front c’est des extraits de description de tables et boucles, c’est coté admin que ça se complique, mais stop, j’ai dit pas de considération techniques pour l’instant ;-)
-  gestion de session
-  authentification
-  moteur de recherche
-  taches de fond
-  notification
-  multi-sites (plusieurs interfaces publics pour une privée)
-  accès à un http externe (syndication, correcteur orthographe, tex)
-  gestion de serveurs distants répliqués (correcteur orthographe, tex)

Petit détail en passant : il y a un exemple de brique qui peut être utilisé en plusieurs exemplaires, éventuellement en versions différentes : le cache.
Le cache des messages ou des méta peut être codé avec memcache alors que celui des squelettes passe par des fichiers avec invalidation sur évènement (une modif du squelette) et celui des pages passe par des fichiers avec invalidation par délai et/ou par évènement.
Il faut donc disposer d’un mécanisme dont l’interface est sensiblement la même (on file une clé on récupère une donnée ou rien auquel cas on génère) mais dont plusieurs implémentations peuvent cohabiter.

Ça ressemble vachement aux notions d’interface, de classe et d’instance de la programmation objet, mais de là à savoir coment en faire des briques, c’est pas bien clair dans ma tête (que devient la notion de dépendance quand il peut y avoir plusieurs exemplaires d’un même provides.
D’un autre coté, c’est vrai que c’est tentant de voir tout ça à la sauce objet, mais certains cas risquent d’être un peu lourds pour pas grand chose.

une approche possible

Le gros risque d’un chantier de ce type, c’est l’effet tunnel : il va falloir revoir la totalité du code de spip pendant des mois avant d’obtenir un premier jet qui n’aura rien de plus (en fonctionnalités) que la version d’avant, sauf qu’il faudra le débuguer de zéro.

Pour éviter ça, on peut avoir une autre approche, plus progressive :
-  commençons par certains package qui sont assez immédiats (dans leur principe au moins) à créer : l’accès aux méta, l’internationnalisation (quoique la partie charset est pas immédiate).
-  ensuite, pour d’autres packages le terrain est déjà préparé : le nouveau compilo est modulaire en soi, la gestion de raccourcis est assez isolée (quoiqu’elle appelle des trucs dans tous les coins pour les charsets et les métas notamment)
-  ensuite des gros morceaux comme le cache, l’authentification, les taches de fonds et autres peuvent être menés en parallèle.

Le problème de cette approche, c’est que c’est quand il restera les gros morceaux qu’on découvrira peut être que le système de packaging ou le découpage choisi ne permet pas de faire telle ou telle chose.
Il faut donc se préparer à refaire des choses tôt ou tard, mais si on y va calmenent dès le début, ces refontes ne seront peut être que des modifs "bêtes et méchantes" qui n’impliqueront pas une refonte complète de tout le truc.

des exemples par ailleurs ?

histoire de s’en rappeler, sur la liste lab, il a été fait référence à d’autres projets utilisant une approche modulaire :

Pour les idées de logiciels modulaires qui fonctionnent bien, au dela de l’analogie avec Linux, il y a DotClear , au code très propre, et Firefox où l’intégration des modules est ultime.

Il faudrait jeter un oeil à l’approche utilisée par ces produits (bas de la page wiki DotClear par exemple) , et surtout sur la façon dont le socle est écrit pour permettre de brancher des trucs auxquels on n’a même pas encore pensé

Dans le même genre, Templeet utilise un système de packaging apparemment assez complet.

Pear intègre également un mécanisme de module (merci à Minh Ha Duong d’avoir insisté sur cette voie) : voir LegoPear

Autre point à mon avis important : un module (ou une brique) et un plugin, pour moi, c’est pas pareil.
Pour qu’un plugin marche, il faut qu’il se plugue dans un machin pour lequel c’est prévu, c’est à dire qu’il faut prévoir des points d’entrées dans tous les coins.
De plus, en général, un plugin marche un peu comme un filtre avant ou après une action existante (c’est flagrant avec les avant_propre et compagnie qui multiplient les regex incompréhensibles.
Inversement un module peut avoir sa vie propre et être utilisé dans autre chose que le projet pour lequel il a été écrit (cf spikini).

Honnètement, je n’aime pas ce principe de plugin car ça oblige à des tas de if juste pour être sur de pouvoir éventuellement un jour appeler un code complémentaire.
Je préfère la notion de patch, ou de mod, même si elle est plus technique et moins évidente à faire évoluer.
Dans un contexte de modules, écrits pas trop salement, je pense qu’une notion de mod peut être plus facile à maintenir quand chaque mod se limite à un module.
L’autre alternative, c’est une solution "à points d’entrée" avec une prégénération de code pour dégager les tests d’existence de code complémentaire. Mais ça, c’est chaud à coder ...

Solutions techniques

Même s’il est trop tôt pour parler technique sur ce sujet, il y a forcement des idées qui trottent dans la tête de certains, alors autant les noter quelque part : LegoSolution