Une petite mise à jour de rss-bridge, ça vous dit ?

Suite aux mises à jour de Sexactu, j’ai dû réécrire le bridge correspondant, et j’en ai donc profité pour mettre à jour rss-bridge.

Et même si je n’aime pas spécialement le PHP, je dois dire que les choix d’API sont quand même vachement pratiques.

En bonus, avec xampp et Eclipse-PDT, c’est quand même super facile de bosser.

Du coup, j’en ai profité pour mettre à jour tous mes bridges … et évidement les envoyer sur github. Et franchement, c »était facile. Bravo à l’équipe rss-bridge.

Il est un peu moins RAID …

Mais ça va s’arranger.

Parce que j’ai reçu aujourd’hui mon disque de remplacement.

J’ai d’abord essayé de remplacer le disque à l’arrache, avant de me souvenir qu’il y a sur le site de Alt-F une page complète sur le changement d’un composant dans un disque RAID.

J’ai donc repris la procédure en suivant méthodiquement les étapes.

Hélas, dès la suppression du composant, c’est le drame :

[root@dlink-6A4EB1]# mdadm --manage /dev/md0 --fail /dev/sda2
mdadm: set device faulty failed for /dev/sda2:  Device or resource busy

Et j’ai passé du temps avant d’avoir l’éclair de lucidité.

En fait, j’ai partitionné mes disques « simplement » : une grosse partition en RAID1 avec tout dedans. Tout … y compris ffp … Lequel ffp fournit évidement les services SSH et compagnie. Du coup, évidement, quand j’essaye d’enlever le composant (enfin, le disque, mais en RAID, apparemment, ça s’appelle un composant), ça ne marche pas … Attendez, c’est du RAID1, donc ça devrait marcher, non ?

Du coup, si c’est pas ça … je fais quoi, moi ? Ben j’en sais rien. Enfin, j’ai bien une idée : je peux toujours copier tout le contenu de mon montage RAID1 sur mon nouveau disque, et le faire évoluer vers un disque RAID1 en reformattant le composant qui reste dans le RAID1.

Bon, en théorie, la solution idéale serait quand même de mettre mon nouveau disque directement dans le conteneur RAID1 … mais je ne sais pas trop comment faire ça, ni dans l’interface d’Alt-F, ni même dans mdadm. Je sens que je vais encore aller écumer ServerFault, moi …

Il est RAID … mort ?

Bon, ça sent pas bon

2017-03-07 19_48_12-

Oui, mon RAID est dégradé.

Mais comment ?

Une première réponse grâce à cet article : How to get the status of a Linux software raid?

Qui donne ce résultat éloquent :

[root@dlink-6A4EB1]# cat /proc/mdstat
Personalities : [linear] [raid0] [raid1] [raid6] [raid5] [raid4]
md0 : active raid1 sda2[0]
975585856 blocks [2/1] [U_]

unused devices: 

Effectivement, le U_ est clair : l’un des deux disques semble être dysfonctionnel. Mais lequel ?

En regardant dans l’interface de Alt-F, je peux avoir ces informations là :

/dev/sda2:
          Magic : a92b4efc
        Version : 0.90.00
           UUID : a112692c:cd4ddd32:b98be83a:b8b6c728
  Creation Time : Sun Feb  8 22:22:54 2009
     Raid Level : raid1
  Used Dev Size : 975585856 (930.39 GiB 999.00 GB)
     Array Size : 975585856 (930.39 GiB 999.00 GB)
   Raid Devices : 2
  Total Devices : 1
Preferred Minor : 0

    Update Time : Tue Mar  7 20:15:34 2017
          State : clean
 Active Devices : 1
Working Devices : 1
 Failed Devices : 1
  Spare Devices : 0
       Checksum : 67beb987 - correct
         Events : 12447483


      Number   Major   Minor   RaidDevice State
this     0       8        2        0      active sync   /dev/sda2

   0     0       8        2        0      active sync   /dev/sda2
   1     1       0        0        1      faulty removed
/dev/sdb2:
          Magic : a92b4efc
        Version : 0.90.00
           UUID : a112692c:cd4ddd32:b98be83a:b8b6c728
  Creation Time : Sun Feb  8 22:22:54 2009
     Raid Level : raid1
  Used Dev Size : 975585856 (930.39 GiB 999.00 GB)
     Array Size : 975585856 (930.39 GiB 999.00 GB)
   Raid Devices : 2
  Total Devices : 2
Preferred Minor : 0

    Update Time : Wed Feb 15 09:09:56 2017
          State : clean
 Active Devices : 2
Working Devices : 2
 Failed Devices : 0
  Spare Devices : 0
       Checksum : 67a3a500 - correct
         Events : 12444067


      Number   Major   Minor   RaidDevice State
this     1       8       18        1      active sync   /dev/sdb2

   0     0       8        2        0      active sync   /dev/sda2
   1     1       8       18        1      active sync   /dev/sdb2

Et donc, clairement, mon disque /dev/sda1 a un problème.

Du coup, j’essaye de l’enlever via Alt-F, encore une fois. Et c’est le drame :

Removing the sda2 partition from the md0 RAID device failed:

mdadm: hot remove failed for /dev/sda2: Device or resource busy

Damned ! Comment je fais, maintenant ?

Evidement, un coup d’oeil à ServerFault donne des réponses …comme celle-là, mais par prudence, je ne vais pas l’appliquer tout de suite …

Et je vais surtout (encore) acheter un nouveau disque de 1 To …

J’en profiterai évidement pour faire jouer la garantie, parce que le disque Toshiba n’a quand même qu’un an …

Ghost in the cell

La semaine dernière, j’étais plutôt pris par un … un contest codingame !

Malheureusement, j’ai un peu la flemme de faire le post-mortem avec Asciidoc pour ne pas avoir les images générées par PlantUML.

Donc je vais plutôt en faire une version raccourcie ici.

Qu’est-ce qu’il faut faire ?

Sur un terrain constitué d’un graphe de noeuds produisant des robots, il faut avoir plus de robots à la fin de la partie que l’adversaire.

Mais comment ?

A chaque tour, vous pouvez demander à chacun de vos noeuds d’envoyer autant de cyborgs que vous le voulez vers la destination de votre choix.

Oui, mais comment ?

Là, ça devient compliqué.

J’ai implémenté au début un système qui envoyait les cyborgs vers le noeud ennemi le plus proche (en en envoyant plus que ce qu’a l’ennemi au moment où j’arrive). Mais ça ne marchait pas trop bien. Même si ça m’a emmené jusqu’en bronze.

J’ai ensuite amélioré d’innombrables fois ce système en tentant les choses suivants

  • Envoyer les bombes vers les noeuds ennemis
  • Faire des upgrades des noeuds que je détiens (malin, parce que tout un tas d’ennemis envoient 2 cyborgs à chaque tour, en comptant sur les statistiques) … Ca m’a emmené en argent.
  • Implémenter un peu de solidarité en essayant d’équilibrer le nombre de cyborgs entre les noeuds. Ca a plutôt bien marché … mais je n’ai pas franchi l’argent
  • Et le dernier : trier les noeuds au début de chaque tour par distance au centre des noeuds de mon équipe. Et utiliser ce tri pour chacune des opérations précédentes. Et ça m’a emmené en or.

Résultat ?

683ème.

Pas forcément un mauvais score.

Mais nettement moins bon que mon collègue Nicolas, qui termine 41ème en Legend ! Et que je félicite.

Mais il y a des trucs qui n’ont pas marché ?

Tellement !

La plus grosse déception a été pour moi la tentative d’utiliser l’algorithme dynamique de résolution du problème du sac à dos, qui ne donnait pas vraiment de différence de score de mon algorithme naïf et brutal.

A côté de ça, j’aurais peut-être dû aussi tenter des algorithmes plus … intelligents.

Et des leçons à en tirer ?

Je connaissais bien Bomberman, donc j’ai pu utiliser un peu d’expertise pour sentir les bons algorithmes dans Hypersonic.

Par contre, là, les graphes, je n’y connais rien. Enfin, si, en terme d’algorithmique, de navigation, je m’y connais … un peu. Par contre, ce genre de jeux, vraiment, je n’y connais rien, et je suis nul. Et je sais pourquoi : on est là dans le même genre de problème que pour le go : c’est un jeu distribué sans valeur autre que positionnelle. En effet, un noeud vaut plus par le nombre de cyborgs qu’il produit que par toute autre valeur ou information.

Et du coup, c’est très difficile à appréhender pour l’esprit humain qui est fondamentalement focalisé sur un objectif, et pas sur une situation globale.

Et ça, c’est une super leçon : il est difficile pour moi de concevoir un algorithme intelligent si je ne connais pas vraiment bien l’espace du problème.

Oh, bien sûr, j’ai atteint une position au moins aussi bonne qu’à hypersonic. Mais quelque part, et même si j’étais hier extrêmement content d’atteindre l’or, j’ai quand même une petite pointe de déception de ne pas avoir fait un meilleur score (qui aurait pu être Legend, mais c’est ma prétention habituelle).

Asciidoc for the win !

Il y a quelques temps, j’avais écrit un article expliquant pourquoi les documents Office n’étaient pas de bons livrables. J’y indiquais par ailleurs qu’Asciidoc me semblait une bonne alternative.

Mais un format, ça n’est qu’un format. Une documentation, ça n’est hélas pas qu’un format technique de document. C’est aussi, avant tout, le moyen de raconter l’histoire du logiciel. Et parfois, ça n’est pas facile

A la recherche du bon format

Pas son histoire au sens biographique, mais plus son usage, son architecture, bref, l’ensemble des éléments qui contraignent son code à avoir sa structure. Autrement dit, les éléments qui donnent les réponses aux questions invraissemblables que se posent un développeur.

you_down_wit_opc-yeah_you_know_me

C’est pas que je déteste, c’est que je comprend pas l’histoire

Et ça, que j’écrive ma doc dans Word, en Asciidoc, en LaTeX, la question se pose toujours : pourquoi ces décisions ont été prises.

Heureusement, j’ai découvert il y a quelques temps le format de documentation agile de Simon Brown, qu’il documente dans la doc de Structurizr.

Regardons ensemble le sommaire :

  1. Context
  2. Functional Overview
  3. Quality Attributes
  4. Constraints
  5. Principles
  6. Software Architecture
  7. Code
  8. Data
  9. Infrastructure Architecture
  10. Deployment
  11. Development Environment
  12. Operation and Support
  13. Decision Log

Et maintenant, imaginez ce que ça donne pour votre projet. Tous les aspects sont documentés dans un seul gros document Word. C’est pénible … heureusement, là, asciidoc peut vous aider.

Je vous montre : si votre doc est en asciidoc, vous pouvez faire des include.

Et donc, vous pouvez avoir un dossier de doc qui ressemble un peu à ça

  • monprojet.adoc
  • images/ Vous mettez toutes vos images là-dedans
  • includes Et chacun des chapitres de votre doc est un document séparé dans ce dossier.
    • /00_intro.adoc
    • /01_context.adoc
    • /02_functional_overview.adoc
    • /03_quality_attributes.adoc
    • /04_constraints.adoc
    • /05_principles.adoc
    • /06_software_architecture.adoc
    • /07_code Si vous avez des éléments à détailler, n’hésitez pas à créer des sous-dossiers
      • /un_detail.adoc
    • /07_code.adoc
    • /08_data.adoc
    • /09_infrastructure_architecture.adoc
    • /10_deployment.adoc
    • /11_development_environment.adoc
    • /12_operation_and_support.adoc
    • /13_usage.adoc
    • /14_decision_log.adoc
    • /99_faq.adoc

Du coup, avec tout ça, vous avez une documentation correctement découpée, dans laquelle vous mettez vos diagrammes UML (ou autres) générés avec asciidoctor-diagram, et vous êtes content …

Bon, et puis si vous n’êtes pas contents de ce format, Simon Brown mentionne également le support d’arc42, qui a l’air tout aussi intéressant :

A un détail près.

Parfois, il y a du code que vous voulez voir généré pour le mettre dans la doc.

Par exemple, si vous utilisez le ServiceLoader de Java, savoir quelles classes implémentent une interface sans avoir à chercher dans Eclipse, c’est cool.

Tant qu’à générer la doc, pourquoi ne pas générer la doc ?

Parce qu’en fait, votre doc asciidoc, vous la générez, pas vrai ? Si vous faites du maven, vous utilisez sans doute le maven-asciidoc-plugin. Je vais faire l’hypothèse que vous êtes dans ce cas.

Et dans ce cas, si vous avez besoin d’avoir un morceau de la doc qui dépende plus directement du code, vous pouvez tout à fait … utiliser Groovy pour générer des fichiers asciidoc qui vont bien !

Typiquement, pour mon exemple, j’ai un script Groovy qui a dans son CLASSPATH tous les modules de mon application, et qui à l’aide de reflections recherche les implémentations de l’interface pour générer un tableau Asciidoc les affichant.

Et comme ce script Groovy est lancé grâce à gmaven avant la génération de la doc, cette partie est toujours à jour.

Et pour un projet multimodule ?

Pour l’instant, j’ai juste testé ça une fois, et d’une façon non satisfaisante. Comme j’arrivais sur un projet existant, j’ai simplement ajouté un module doc isolé du reste de l’application.

Je pense que j’aurais eu une doc d’une bien meilleure qualité si j’avais mis la doc dans chaque module avec des includes bien costauds dans la doc du module global (voire même des morceaux complètement générés). Evidement, dans ce genre de cas, la génération de la documentation doit également être documentée …

Donc ça marche bien ?

Oh que oui !

Ecrire de la doc est presque agréable, et les aspects générationnels sont une distraction encore plus agréable. Sans même parler de la fusion de cette doc et des différents diagrammes qui y sont intégrés.

Mais je crois qu’on peut aller encore beaucoup plus loin. Pas directement avec cette technique, mais sans doute en amont, via des graphes.

On pourrait faire encore mieux ?

Je vous donne quelques exemples.

Pour décrire votre applications, vous utilisez en fait plusieurs graphes

  • L’architecture conceptuelle (ou fonctionnelle) décrit comment les composants remplissent les fonctions
  • L’architecture applicative organise ces composants en modules
  • L’architecture technique montre comment ces composants se déploient.

Tout ça est censé être à peu près couvert par Structurizr.

Mais d’autres éléments ne le sont pas : quand je décris une organisation de classe, c’est aussi un graphe. Et un diagramme de séquence pourrait tout à fait être construit à partir du code un peu annoté.

Imaginez que je dispose d’un modèle comme celui de Structurizr, mais enrichi à la fois avec les informations du code (pour produire les différents diagrammes de bas niveau), et pour lequel je puisse générer des diagrammes via une quelconque syntaxe de recherche des noeuds dans un graphe. Je pourrais alors demander facilement des trucs comme

Dessine-moi le diagramme de séquence partant de cette interaction Javascript et incluant les échanges avec le serveur, la base de données, et le composant Java bidule

Et d’un coup, je n’ai plus un simple outil de documentation, mais un outil d’analyse et de compréhension de mon code, que je peux ensuite faire produire un truc que j’ai bien galéré à faire il y a quelques temps :

Fais-moi un diagramme de composant où les classes sont coloriés en fonction de leur dette technique

Bon, c’est une très chouette idée, et je sais à peu près comment l’implémenter … Mais c’est malheureusement encore un projet de plus. Et mon temps est déjà bien rempli.

Il n’y aurait pas une bulle, là ?

Après la fameuse halle F de Xavier Niel

Après, évidement, Euratechnologies (qui cela dit est déja un acteur installé du domaine)

Et là, je me pose sérieusement une question.

Quand on voit le nombre d’investisseurs potentiels, la pression pour faire augmenter la valorisation des start-ups doit être assez élevée. Au détriment sans aucun doute de la qualité des produits.

Du coup, j’ai tendance à penser ces temps-ci que, si quelqu’un a une idée valable, il vaut peut-être mieux ne pas se lancer maintenant. ou tout au moins ne pas se lancer dans la croissance à tout prix, histoire d’éviter de se faire parasiter par des business pas si angels.

Jenkins, sers-moi donc un Chtijug !

Nicolas Géraud était venu nous parler des pipelines il y déja deux ans.Est-ce que cette présentation allait être mieux ? En tout cas, elle est bien différente.

Petit point sponsoring de l’IUT sur la taxe d’apprentissage : les entreprises peuvent déclarer des organismes de formation bénéficiaires de leur taxe d’apprentissage. Ca peut avoir une influence sur le budget de ces organismes.

Et c’est parti !

Avec d’abord un petit sondage :

  • qui connait Jenkins ? A main levée, tout le monde dans la salle.
  • qui a déja migré vers Jenkins 2 ? Encore à main levée, pas grand monde.

Jenkins 2

Donc Jenkins 2 … est totalement compatible avec Jenkins 1. Et c’est bien, parce que la montée de version va être simple. Dans l’ensemble, les plugins sont compatibles.

Avec Jenkins 2, il y a aussi de nouveaux sites

  • http://jenkins.io qui est bien plus grand public
  • le project Voltron sert de plugin store avec une chouette présentation. Limite comme le google play store, en fait.

Il y a maintenant au premier démarrage un mot de passe à aller chercher dans les logs de la machine. Ca va permettre de sécuriser le serveur Jenkins avec un admin par défaut. Evidement, on peut toujours avoir un Jenkins non sécurisé, mais il faut le vouloir. Ce qui change pas mal de Jenkins 1 qui, par défaut, n’était pas sécurisé. En bonus, une liste de plugins par défaut est disponible, pour faire une première personnalisation de Jenkins.

Et ensuite, on arrive aux fameux pipeline-as-code.

Pipeline as code

Un job est défini par un Jenkinsfile, écrit dans un DSL Groovy, qu’on peut stocker dans son SCM. L’avantage, c’est aussi de permettre d’utiliser les structures de contrôle de Groovy pour personnaliser le job.

Et ensuite

Il y a tout un tas de nouveaux trucs qui ne vont pas tarder à arriver

BlueOcean (déja disponible en pas beta, mais pas release non plus)

La fameuse nouvelle interface graphique pour Jenkins. Les captures sont très chouettes !

Franchement, l’affichage des pipelines est très chouette. Si j’avais eu ça chez Perigee, j’aurais pu montrer un vraiment très beau pipeline. Le plus incroyable, c’est quand même de pouvoir faire « pousser » un pipeline graphiquement. Il faut voir l’écran pour le croire, je trouve.

Pipeline déclaratif

En bonus, ça permet à des non-développeurs de modifier le build, ce qui n’est pas une si mauvaise idée, puisque le code exécuté est toujours en SCM. En fait, le pipeline généré n’est pas exactement identique à celui qu’un développeur écrirait : c’est un pipeline déclaratif.

D’une façon amusante, le speaker décrit la syntaxe d’un DSL Groovy comme « à mi-chemin entre YAML et Groovy ». Guillaume Laforge et tous ses amis pleurent des larmes de sang en entendant ça. Parce que quand on regarde un DSL Groovy, comme par exemple le MarkupBuilder, on est exactement dans la syntaxe visible à l’écran. Bon, je ne vais pas en vouloir au speaker : il connaît sans doute mieux Jenkins que je connais Groovy.

Back-end storage

Manifestement, l’objectif est de découpler le fonctionnement de Jenkins et le stockage des configurations d’exécution et des résultats. C’est une chouette idée, mais pas vraiment assistée par les capacités des plugins à écrire eux-mêmes des fichiers.

Donc Jenkins 2, c’est ?

Jenkins 2, c’est mieux, et orienté sur le continuous delivery. Et pas le continuous deployment. Autrement dit, l’équipe de cloudbees ne vise pas trop à utiliser Jenkins pour le déploiement en prod.

Quelques questions

Si les pipelines sont déclaratifs, comme maven ou gradle, pourquoi ne pas réutiliser leur outillage ?

Jenkins est utilisé pour faire le delivery, ce que ne font pas ces outils. En un sens, je comprend cette réponse : le scope fonctionnel est différent, et ce serait assez curieux de dire « on peut faire du gradle pour le déploiement ». Et puis, Cloudbees et Gradle inc ne vont pas fusionner demain.

Mais quand même, en transformant les jobs en bouts de code, je trouve que Cloudbees fait rentrer Jenkins dans une espace de continuum de build qui va de mon poste jusqu’aux artefacts déployables en prod.

Comment se compare l’API de pipeline-as-code et de job-dsl ?

L’inspiration initiale de pipeline-as-code était buildflow, mais ça a vite divergé.

Et la démo

  • Premier truc cool : les plugins installés sont toujours installés à la dernière version.
  • Deuxième truc cool : BlueOcean est déjà disponible comme plugin, et donc installable.
  • Troisième truc cool : le travail d’administrateur Jenkins s’arrête, pour les jobs, à créer les jobs et les connecter à des SCM. Tout le reste vient du Jenkinsfile.

Et donc, on passe à la création du Jenkinsfile. Et là, la structure des DSL Groovy réapparaît vraiment, et c’est bien.

  • Quatrième truc cool : les commandes checkout de SCM utilisent la révision du Jenkinsfilecomme référence. Par conséquent, l’enchaînement d’étapes se passera beaucoup mieux que dans Jenkins 1, puisqu’il n’y aura pas de révision à passer. Par contre, curieusement, le DSL ne semble pas contenir de commande maven, puisque notre speaker exécute les commandes maven via un sh "mvn clean package". Arf … apparement, le plugin exécutant maven est « mauvais ».
  • Cinquième truc cool : l’interface de Jenkins inclut un générateurs de snippets façon vieux wizards qui permet d’apprendre très rapidement le DSL des pipelines.
  • Sixième truc cool : l’affichage des pipelines en cours est vraiment très sympa, avec des logs par noeud du pipeline affichés en temps réel.
  • Septième truc cool : le DSL inclut une notion de stashes, valable uniquement pour la durée du pipeline, qui permet donc de ne pas déployer dans Nexus les artefacts temporaires.
  • Premier truc pas cool : le pipeline est toujours exécuté sur le master. Du coup, la montée en charge pourrait mal se passer.
  • Huitième truc cool : pour les pipelines déclaratifs, il est possible de demander à Jenkins d’analyser la syntaxe.
  • Deuxième truc pas cool : on peut relancer un pipeline à partir d’une étape uniquement dans la version commerciale de Jenkins. C’est moins bien … mais je comprend tout à fait.
  • Neuvième truc cool : il est possible de créer des morceaux de code partagés entre pipelines.
  • Dixième truc cool : les milestones permettent d’éviter de lancer plusieurs builds concurrents sur une ressource critique.

Et si vous voulez voir le Jenkinsfile utilisé pour ce live-coding, il est disponible sur github.

D’autres questions

Comment tester un pipeline ?

Eh bien, on ne peut pas : il faut le lancer dans une instance de Jenkins. Autrement dit, c’est le genre de truc où il faut une instance de test de Jenkins. Et mon collègue me souffle à l’oreille qu’on peut très bien utiliser l’annotation @StaticCompile de Groovy pour vérifier la syntaxe autant que possible (parce que @StaticCompile, sur un DSL, il doit bien s’amuser, tiens).

Conclusion

J’ai quand même hâte de voir les projets passer au moins aux pipelines as code, histoire d’avoir dans mon SCM, à côté de mon pom.xml, le Jenkinsfile qui va bien. Et histoire aussi d’ajouter un peu de Groovy dans tout ça !

Compiler ou tester ?

En fin de cette semaine, une controverse intéressante a eu lieu sur twitter, habilement lancée par cet article de « Uncle » Bob Martin : The Dark Path.

Regardez par exemple cette sélection de tweets sur le sujet :

On peut dire que les avis sont contrastés.

Et comme la meilleure façon de ne laisser aucun doute sur le sujet de ma propre stupidité, laissez-moi vous donner mon avis sur le sujet.

A quoi sert le compilateur ?

Il y a des années, à l’époque du C, le compilateur servait à transformer le code source écrit dans un langage quasiment humainement compréhensible (le C) en un code exécutable par la machine.

Aujourd’hui, quelque soit la plateforme d’exécution (la JVM, la CLR de Microsoft, ou le résultat d’une transformation LLVM), le compilateur fait beaucoup plus de choses : il simplifie, optimise, vérifie le code d’une façon très poussée.

Et à mon avis, c’est l’argument de Romain Guy : si le système de type est suffisamment poussé, il est impossible d’écrire un code qui ne corresponde pas précisément aux souhaits du développeur. Mais à quel prix ? C’est ce que cherche à évaluer Uncle Bob.

Laisser le compilateur vérifier ? ou Tester

Parce que l’avantage des tests sur le compilateur, c’est quand même de laisser le développeur vérifier les choses à sa façon : il écrit l’histoire dans son test, et vérifie les choses comme il le souhaite. Qui plus est, le compilateur est certes capable de vérifier certaines erreurs bas niveau, mais il y a tout un tas de trucs que le compilateur ne sera absolument pas capable de vérifier, et qui nécessiteront des tests.

Alors quoi ?

Heureusement, aujourd’hui, la question est en fait tranchée : les développeurs utilisent les deux, en fonction à la fois du coût d’implémentation de chacun, et de l’expressivité de chacun. Cela dit, je continue à trouver cette question intéressante. Et, à titre personnel, je comprend parfaitement la décision de Kotlin et Swift d’empêcher les références null, même si je préfère une solution plus simple : je n’utilise autant que possible jamais de nullen Java. Et du coup, si NullPointerException il y a, c’est forcément un bug qui nécessitera un test. Est-ce que c’est plus coûteux que d’avoir des <Object>? à déréférencer ? Je n’ai pas l’impression. Mais bien sûr, je peux me tromper.

Ne livrez pas de document Office !

Vous travaillez sur un grand projet … ou un moyen.

Et par exemple, on vous demande de livrer de la doc sur le code, l’architecture. ou des éléments de volumétrie. Et là vous vous dites « je livre un Excel ! » ou « Je livre un Word ! ». Par pitié, ne le faites pas.

Pas parce que c’est moche, lourd, et peu conforme à vos valeurs éthiques de partage.

Mais plutôt parce que les fichiers Office ne sont pas compatibles avec un processus de développement, ou plutôt d’écriture ?

Parce qu’après tout, votre document a bien un cycle d’écriture, non ? Vous avez bien, sous une forme ou une autre, les étapes suivantes

  • Ecriture
  • Relecture
  • Livraison
  • Passage à la version suivante

Si ça vous rappelle le cycle de vie d’artefacts de développement, ça n’est pas un hasard, c’est la même chose.

Et d’un point de vue format, comment faire ?

D’abord, si votre livrable ne bouge plus, c’est que ça n’est pas le même format que celui dans lequel vous écrivez. Typiquement, quand vous livrez un PDF, par exemple, vous ne pouvez pas vraiment le modifier (mis à part hacks visibles).

Ensuite, dans l’idéal, vous cherchez un format qui vous permette de répondre aux critiques habituelles d’Office :

  • Pas de travail collaboratif possible
  • Pas de merge
  • Un outillage de composition de document assez faible

Autrement dit, vous cherchez un format source qui soit vraiment ça : un fichier source que vous pouvez gérer dans votre SCM, sur lequel vous pouvez faire des merge, et enfin que vous pouvez composer (ou compiler) dans votre chaîne de build. Eh bien, ce format existe. En fait, il y en a plusieurs, mais un seul qui marche : Asciidoc.

De nos jours, avec Asciidoctor, vous pouvez compiler votre doc via maven, et la gérer dans votre SCM (je le fais déja). Vous pouvez par ailleurs créer de gros documents en assemblant plusieurs fragments (voir leur fameux tag include). Et, comme vous créez votre doc avec maven, elle est packagée et livrée comme le reste de votre application.

Alors, pourquoi vous continuez à utiliser Office ? Parce que vos utilisateurs le demandent ? En vrai, je ne crois pas que ce soit une bonne raison.