Codingame : fin de partie

Il y avait ces dix derniers jours un contest codingame.

Et j’étais assez bien parti, puisque je suis arrivé en ligue silver. Malheureusement, à un moment donné, je me suis rendu compte que j’y passais sans doute trop de temps.

J’ai donc décidé d’arrêter de participer aux contests codingame. D’ailleurs, je ne pense pas me remettre à codingame, même en-dehors des contests, avant un bon moment. Je retire de nombreuses choses de mes participations que je vais tenter de découper en plusieurs morceaux

Wondev Woman

Sur le contest proprement dit, c’était bien. J’avais commencé à coder mardi un algorithme conceptuellement proche de celui que j’utilisais pour Hypersonic, me permettant théoriquement de faire une analyse complète du plateau à plusieurs tours d’avance. J’achoppais sur un problème de chargement des directions possibles, mais j’avais en tête une solution.

Mais avant un peu de vocabulaire

  • J’appelle action une action complète (MOVE&BUILD ou PUSH&BUILD).
  • Un mouvement est un élément d’une action (déplacer la case « active » dans le futur d’une des directions possibles). Donc si on y réfléchit bien, une action est une paire de mouvements. Petite révélation : la différence entre PUSH&BUILD et MOVE&BUILD est que, dans le premier cas, le premier mouvement arrive sur une case occupée

Du coup, mon algorithme devenait quelque chose ressemblant à

  1. Calculer les mouvements possibles au tour courant pour mes pions
  2. Pour chaque mouvement, calculer l’état du terrain après le mouvement (sans tenir compte de la position des joueurs). Il va y avoir des tonnes de superposition, qui correspondent à des futurs communs, ça offre une bonne réduction de l’espace de recherche.
  3. Scorer les positions des pions. Pour les meilleures positions, recommencer à l’étape 1. Le score utilisé doit être indépendant de la longueur des chemins

A mon avis, avec ça, j’aurais pu atteindre l’or. mais.

  • Implémenter un tel code est long, et assez fastidieux.
  • J’ai eu cette idée uniquement parce que j’ai repris hypersonic après la fin du contest
  • Je n’ai ni la motivation, ni le talent pour atteindre la légende (mon meilleur score à été d’atteindre le fond de la ligue gold).

Plus généralement

Ces constats, qui ne sont pas d’ordre techniques mais personnels, sont reproductibles pour tous les problèmes de codingame : il y a de bien meilleurs joueurs que moi, et je le vois clairement.

A mon avis, c’est parfait pour découvrir un nouveau langage. Et en réalité, attaquer ces problèmes en Java était pour moi une facilité. En théorie, j’aurais dû les attaquer en Python, en Scala, ou dans n’importe quel langage dans lequel j’ai envie de progresser vite.

Parce que les structures de données que j’ai mis en place, contrairement à d’autres participants, faisaient la part belle aux design patterns, à la bonne programmation orientée objet, bref au code Java bien idiomatique. Et je sais que j’aurais fait pareil dans d’autres langages.

Du coup, je vais arrêter d’y jouer en Java, et je m’y remettrais si je dois découvrir un nouveau langage.

Chtijug et barbecue

Gravitee

Bon, je connais les speakers depuis …​ 10 ans facile. Et ça fait plaisir de les voir sur scène !

Gravitee, un API Manager

Donc l’API management (voir la session chez Kiabi – et la page Wikipedia de définition), ça permet de créer et de publier des API, de les maintenir en état de marche, et enfin de collecter des statistiques d’usage.

D’un point de vue architecture, il y a principalement deux composants

  1. Un portail d’API, permettant l’enregistrement d’utilisateurs, la découverte des API.
  2. Une gateway, qui va exécuter les appels en les dispatchant auprès des services backend.

Pour les clients, ça peut être

  • Une façon d’exposer une API
  • Un reverse proxy
  • Un ESB pour les API REST (mais ça c’est faux : il y a tout un tas de différences entre l’API manager et l’ESB)

Gravitee, le produit

Existe depuis 2015, et nos speakers ont créé la société GraviteeSource pour fournir le conseil, la formation autour du produit.

Démonstration de création d’API

A partir d’un serveur exposant l’API, on peut facilement créer les éléments dans Gravitee grâce …​ à un wizard ! Il faut noter que, dans le wizard simple, la notion de plan de consomation (pour pouvoir facturer facilement, évidement). Par ailleurs, on peut importer facilement de la doc RAML/SWAGGER/Markdown. Et c’est fini, l’API est déployable

Consomation d’API

Une fois l’API créée, il faut créer une souscription pour pouvoir l’utiliser.

Et là, les petits gars, vous avez déja de quoi remplir quelques rapports de bugs pour améliorer vos présentations 😉

Cela dit, les écrans d’administration sont sacrément bien fichus, avec une vision complète des temps de réponse et de la qualité des réponses.

Réécriture de la réponse

L’un des éléments intéressants d’un API manager, c’est la possibilité de modifier les requêtes pendant leur exécution grâce à des politiques de transformation préconçues (des transformations simples) ou …​ du Groovy (j’aime beaucoup), ou aussi de créer un cache au niveau de la gateway.

Développement de policy

Comme gravitee est développé en Java avec des mécanismes de plugins typiques, ajouter une policy, c’est assez facile, et c’est parti …​ avec un archétype Maven ! Et je dois dire que le code produit par la génération d’archétype est, un peu comme pour Wisdom, assez complet.

Web multi-écrans

J’ai déja vu la présentation sur Youtube, mais en live, ça n’est évidement pas pareil …​

Un truc marrant dès le début de la présentation : Hubert nous parle de 2008 et de ses deux écrans. De mémoire, avec mon voisin de derrière, en 2009, on bossait dans une boîte où chaque poste avait 3 écrans sur deux machines avec Synergy …​ Et encore, ça n’était pas ma première fois avec plusieurs écrans.

Donc, plusieurs écrans, et des interfaces avec plusieurs écrans. Dans le web.

Un truc très intéressant dans sa présentation, c’est qu’il intègre un avis contraire, celui de quelqu’un qui affirme ne travailler qu’avec un seul écran.

Et Hubert enchaîne ensuite avec les différentes techniques permettant la communication : window.open, et autres hacks. J’ai malheureusement un trou dans mes notes. Dans mes souvenirs, il y a un ou deux hacks, et une technologie parfaite pour les applis du futur, mais pas forcément disponible partout.

Cela dit, il y a une faille dans cette présentation (formellement impressionante) : le cas d’usage est quand même super limité : faire du web, sur plusieurs écrans, sans serveur …​ mis à part TiddliWiki, je connais peu de projets sur ce créneau. D’ailleurs, même les applications comme Atom, Brackets, Code ont un serveur web (oui, dans le même process, mais conceptuellement, il y a quand même un client, et un serveur). Personnellement, quand j’ai le genre de besoin dont Hubert parle (avoir des clients qui communiquent entre eux), je reste simple et je mets du websocket sur mon serveur.

Conclusion

Les sujets étaient assez spécifiques, mais les speakers étaient très chouettes, et la soirée s’est finie tranquillement sur les pelouses de Norsys

Générer mon asciidoc dans docker

Non mais pourquoi je veux faire ça ?

Parce que j’ai des collègues qui n’ont pas installé Graphviz. Personnellement, je ne comprend vraiment pas pourquoi. Mais bon, chacun ses choix.

Donc, comme ils n’ont pas Graphviz, et ne veulent pas l’installer, qu’en bonus ils ne veulent installer ni maven, ni java, et qu’ils semblent considérer que Docker est « la meilleure chose depuis le pain en tranches » (un indice : à mon avis, c’est faux), j’ai créé une image docker « kivabien » :

Donc vous prenez ce dockerfile, là, et comme je n’aime pas trop l’idée de publier ça sur le Hub (faut voir aussi que je suis un peu une quiche en docker), ben vous le lancez … avec docker-compose et cette configuration :

d’un habile coup de docker-compose up. Et si tout se passe bien, vous allez retrouver votre dossier target votre doc correctement générée. Notez que, normalement, votre doc pourra contenir du PlantUML, des liens, toute la richesse d’asciidoc.

Elle est pas belle la vie ? Perso, je suis pas sûr, mais on me dit que c’est ça le progrès. Moi je dis ok.

 

Et pouf, un nouveau projet open-source !

Bon, le projet existe depuis un moment, et est déja utilisé par quelques happy fews.

Il s’agit de codingame-maven-plugins, qui fournit des plugins facilitant le développement et le déploiement pour Codingame.

Le source est chez framagit, parce que je me voyais mal faire un projet en com.github, et que Sonatype tient à ce qu’on détienne le domaine correspondant au groupId.

Du coup, merci framagit, et merci framasoft !

Hop, hop, hop, un chtijug !

Un nouveau site (les terrains de Décathlon), pour deux présentations …​ au chaud !

Dix méthodes pour garder les développeurs

J’ai vu les slides de cette présentation, j’en ai donc une idée assez précise (malheureusement, je n’arrive pas à les retrouver dans la timeline de Cyril …​).

Les 3/4 des développeurs sont plus on moins à la recherche d’un nouvel emploi.

Bien recruter

D’abord, il faut s’arranger pour que le recrutement se passe bien, avec un peu de transparence : vision, cadre, salaire, code, soft skills (beuark, quelle frangliche dilbertien), tout ça doit être présenté.

En bonus, il y a certaines pratiques à éviter :

  • L’offre d’emploi impossible
  • Le code sur tableau blanc, remplacé par exemple par Codingame (mais ça n’est pas encore le vrai environnement …​)

Et d’autres à favoriser

  • Code review
  • Pair programming (eh, mais c’est ce que j’ai fait avec Youssef !)

Proposer une carrière

Oui, alors ça, bon, je connais. Et franchement, les développeurs non motivés, au bout de 3 ans, ils sont devenus chefs de projet.

Quant au graphique produit par N. Martignole sur la carrière d’un déveeloppeur, il est adapté à la vision moderne de l’informatique. Expert au bout de 5 ans, c’est vraiment de la blague.

Travailler sur l’environnement

Avant tout, arrêter l’open-space. Et c’est vrai que mes expériences récentes, dans des bureaux de moins de 15 personnes, m’ont réconcilié avec les gens : quelqu’un qui vient me voir vient réellement me voir, et ça change tout, à la fois en qualité de communication et en amour-propre.

En parallèle, avoir des machines de qualité, et avec de bons écrans, c’est évidement bénéfique. Et de la même manière, avoir de bons logiciels, ça ne coûte pas bien cher par rapport à la valeur ajoutée.

Hey, mais ils citent le test de Joël ! Cool. Bon, en fait, je suis sûr que ce test reprend tout le contenu de cette présentation, mais je ne vais pas râler.

Organiser son travail

Mettre en place des features teams, ça peut être bien. Ou les pizzas teams. En tout cas éviter les équipes façon galère de 50 personnes.

Software craftmanship

Bon, je vous encourage à relire le manifeste …​

Du coup, pour ça, il faut avant tout vouloir s’améliorer. En passant, pour vouloir s’améliorer, il faut avoir un sens du temps long …​ Autrement dit, envisager sa vie professionnelle sur plus de deux ans …​ voire plus de dix.

Tech radar

Bon, là, j’ avoue, j’ai soupiré. Mettre en place un tech radar, ça a un côté tellement poussiéreux, tellement pénible. J’ai vraiment du mal à voir en quoi ça peut présenter un intérêt, parce que ça met en place des comités théodule internes. Je comprend le besoin d’urbanisme, mais franchement, j’ai l’impression que c’est la très mauvaise méthode pour suivre l’évolution technologique.

Ne pas se mentir

Dire qu’on est cool, avec des consoles, du café gratuit, des nerfs (eh, mais on a tout ça, et en plus une Wii U), ça ne vaut pas le travail intéressant (mais on a aussi ça, ça va).

Autrement dit, il ne faut pas remplacer le sens de l’entreprise par tout un tas de bonu qui, eux, ne font pas sens. Cela dit, c’est raccord avec le premier point : lorsqu’on recrute un développeur, on l’intègre au sens de l’entreprise, à ses valeurs.

S’organiser en communautés

Alors théoriquement, c’est censé permettre de la transversalité, encore faut-il que les communautés soient vivantes. Et pour ça, il leur faut des moyens matériels : du temps, de l’espace, des outils de collaboration.

Malheureusement, dans le seul contexte où j’ai vu des gens essayer, ça n’a rien apporté.

Contribuer à l’open-source

Bon, alors là, ça tombe bien, parce que ce matin, un collègue a lancé un recensement des participations de l’entreprise à l’open-source. Et ce soir, il y a déja 60 contributions recensées ! Evidement, parfois, c’est difficile, parce que la sécurfité, tout ça. Dans ces cas-là, monter un Gitlab est une très chouette idée.

Participer aux événements

brown bag lunch, conférences, jugs (ou meetups, ça dépend comment vous voulez appeler ça), tout ça, c’est assez plaisant effectivement. Et puis ça permet à des speakers débutants de prendre l’habitude de parler en public.

Conclusion

Je crois que le message est bon. Mais je crois aussi que le public n’est pas le bon : faire cette conf à l’USI, ou dans un truc de décideurs, bien sûr. Mais je ne suis pas sûr de l’intérêt pour les développeurs.

Vert.x et Kubernetes

Eh, mais c’est Clément Escoffier ! Sans vouloir dire de mal de Cyril et Romain, j’étais surtout venu voir Vert.x et des conteneurs, et je n’ai pas été déçu. Donc Clément va développer des microservices Vert.x et les déployer dans un cloud …​ local (parce que le wifi ne semble pas très bien marcher). Le tout sans aucun slide.

Et il va packager son application avec le vert.x-maven-plugin pour générer des fat-jars. Ca n’est pas indispensable, mais c’est plus facile. Et ça permet à Clément de montrer un peu de maven-fu (parce qu’honnêtement, il en a sacrément, du maven-fu).

Donc en Java, un vert.x, c’est une sous-classe de AbstractVerticle …​ mais ça marche aussi dans la plupart des langages supportés par la JVM (Scala, Groovy, Ruby, Clojure sans doute, …​). Et dans une application Vert.x, pour chaque requête, on appelle la méthode de réponse …​ dans le même thread. Et c’est cool, parce qu’il n’y a pas de context switch.

Mais d’un autre côté, il ne faut pas bloquer ce thread. Sinon c’est la merde.

Pour continuer à développer, avec vertx-web, on peut créer un routeur, et assigner à chaque route une méthode correspondante. Ensuite, Clément nous implémente le serveur tranquillement, avec un mode d’écriture qui m’a beaucoup amusé, et qui est à mon avis la marque des développeurs expérimentés.Par contre, IntelliJ IDEA qui s’amuse à mettre le nom du paramètre en gris devant la valeur, ça me trouble un peu, même si je dois bien reconnaitre que c’est une sacrément bonne idée.

Et maintenant, comment déployer ça sur le cloud ? Et en particulier Kubernetes ? Et en particulier OpenShift ? Donc Kubernetes, ça permet de gérer facilement des gros paquets de conteneurs (logs, sécurité, volumes, …​). Et avec OpenShift, on a une interface, et c’est cool. Et en bonus, on a du build automatisé, ce qui est encore plus pratique. Et avec tout ça, en tant que dév, Clément va pousser son code, qui sera buildé et déployé par OpenShift, et les requêtes seront exécutées dessus.

Et quand ça marche, ça fournit des trucs assez spectaculaires, comme par exemple du déploiement avec rolling updates ! Ou par exemple le déploiement de nouveaux pods avec un simple click. Du coup, comment partager les données ? Avec Redis, par exemple. Et évidement, il faut du service discovery …​ qui est vraiment très facile à implémenter avec vertx.

Et maintenant, depuis notre service, on va en appeler un autre …​ en parallèle …​ à travers RxJava ! Et d’un coup, l’une des propriétés intéressantes de http prend tout son sens : comme c’est un protocole chunked, il n’est pas éncessaire de calculer toute la réponse avant de l’envoyer. Du coup, la mémoire est moins utilisée, l’application coûte moins cher. Et en bonus, le garbage collector n’a pas besoin d’arrêter l’application pour passer. Et ça, c’est vraiment beaucoup plus efficace.

Et c’est le petit moment gênant où la démo s’enraye…​ Mais elle revient sur les rails assez rapidement.

Et maintenant, Clément ajoute des circuit breakers, au cas où le pricer soit un peu trop lent. Et là aussi, comme on fait du vertx, il faut un circuit breaker qui n’utilise pas de threads (donc pas hystrix, par exemple).

Et pour finir la démo, Clément pousse le code sur GitHub en live !

Conclusion

Le talk est à la fois parfaitement spectaculaire dans la forme et vraiment intéressant dans le fond : Vertx permet de développer très facilement des services HTTP (oui, on peut faire autre chose, mais à quoi bon ?), et l’intégration avec OpenShift était aussi poussée que propre.

Authentifier des utilisateurs Couchbase avec OpenID

Attention, pour les non techniciens, ça va piquer.

Donc, j’ai démarré récement une mission, dans laquelle je dois synchroniser une application mobile avec un serveur. le client comme le serveur utilise Couchbase, donc on va utiliser Sync Gateway. Sur le papier, ça paraît tout à fait raisonnable.

Là où ça l’est moins, c’est qu’on ne veut pas stocker de bases d’authentification (la CNIL, tout ça, c’est trop pénible). On va donc passer par de l’OpenID Connect (ce qui est conceputellement très cool). Et comme l’application est mobile-only, on va utiliser ce qu’ils appellent le flow implicite.

Il est assez bien décrit dans la doc de Couchbase Sync Gateway, et en particulier dans ce diagramme

images-003

Présenté comme ça, c’est simple. Mais en fait, c’est rempli de subtilités.

Un token, Quel token ?

D’abord, il faut obtenir le token JWT auprès de votre fournisseur.

Dans mon cas, c’était Auth0, donc un appel à /authorize avec les bons paramètres va renvoyer (via l’url de redirection) le token JWT. Pour ceux qui développent une application JavaFX, il y a une chouette question StackOverflow qui donne un bon exemple … mais je n’arrive plus à remettre la main dessus.

Poster le token ?

Bon alors vous voyez cette jolie image là-haut ? Elle donne toute la doc de Couchbase sur ce qu’il faut faire du token. J’ai essayé pendant une semaine différentes méthodes avant d’utiliser la seule vraie solution : regarder le source !

Ben oui, parce que la sync gateway de Couchbase est écrite en Go.

Donc, j’ai compris assez vite que ça se passait dans le dossier /rest, et en particulier dans le fichier session.go, qui sert de handler pour les urls de … session.

SAUF QUE en go, comme en d’autres langages, on utilise des intercepteurs pour la sécurité. Donc la gestion des authentifications se partage entre handler.go et auth.go. Pour être plus clair, dans handler.go, la gestion de l’authentification se fait dans cette fonction

En fait, si vous regardez le code, vous verrez que h.getBearerToken() lit en fait le token OpenId depuis les entêtes de la requête. Ca fait déja une réponse facile à trouver :

Il faut mettre le bearer token dans les entêtes HTTP, et PAS dans le corps du POST.

Oui, mais quel token ?

Donc, j’en étais là, et à chaque fois que je postais mon token, avec tous les logs activés en mode debug, j’avais à peu près cette suite de messages

Bon, je vous fais grâce des détails, mais dites-vous que ça signifie que mon token est bien passé à la couche go-oidc, qui le refuse. Et là, j’ai dû lire le code environ 2 jours dans tous les sens avant de comprendre.

Alors, autant vous le dire, il y a plusieurs types de token JWT.

maxresdefault

Et en fait, la différence se fait dans l’algorithme. Vous avez le choix entre HS256 et RS256. Et la seule différence, c’est que le RS256 est signé avec un algorithme assymétrique.

Par défaut, Auth0 propose du HS256.

Et évidement, go-oidc ne décode que les tokens RS256. Et le choix de l’algorithme se fait dans les paramètres avancés du client Auth0.

Autrement dit

Utilisez l’algorithme RS256.

Une fois que vous aurez fait tout ça, vous pourrez bénéficier de l’authentification OpenId Connect pour vos synchronisations. Et ça vous créera les utilisateurs automatiquement. Bon, le nom des utilisateurs dans votre sync gateway sera leur id Auth0, mais franchement, vous allez vous laisser arrêter par ce genre de détail ? Moi non plus. D’ailleurs, je m’en vais de ce pas proposer une pull request à Couchbase pour modifier les différents éléments manquants.

J’abandonne

Samedi dernier, Codingame lançait code4life, le dernier contest en date.

N’écoutant que mon courage, je m’y suis jeté. Avec d’abord une implémentation basique pour atteindre le bronze, puis deux déclinaisons successives d’une machine à état.

Et aujourd’hui, avec cette machine profondément optimisée, je suis environ 250ème en silver. Il ne fait aucun doute que d’ici Lundi matin, je vais perdre encore 500 places. Mais je vais arrêter là ce contest. Plusieurs raisons à ça, que je vais détailler ici (non, je ne mettrai pas de post-mortem sur GitHub).

Fais une chose, et fais-la bien

J’ai commencé mon nouveau poste chez Zenika la semaine dernière. Et j’ai entamé ma première mission ce jeudi. Je pourrais vous mettre la liste des mots-clés ici, mais ce serait sûrement un peu prétentieux. Toujours est-il que beaucoup de technologies dans ce projet sont pour moi une nouveauté, ce qui m’a forcé à courir à fond dans la direction des découvertes techniques, ce qui n’est pas forcément compatible avec la précision, la focalisation nécessaire à la réussite d’un contest. Du coup, depuis avant-hier, je n’ai plus de gaz pour réfléchir correctement au problème.

C’est dommage pour mon succès à Codingame, et contrairement à un autre Nicolas, je ne risque pas de gagner de t-shirt, mais d’un autre côté, avoir trop de choses intéressantes à faire, c’est clairement un problème de riche.

Les streams, c’est fini

A un moment donné, j’ai commencé à avoir des sales problèmes de timeout. J’ai pu, à ma surprise et ma déception, j’ai pu associer chacun de ces timeouts à une utilisation des streams Java. Vous imaginez le truc ? Chaque utilisation de stream a occasionné à un moment ou un autre un timeout.

Attention, je ne dis pas que les streams sont mauvais. Juste que pour un contest codingame, les streams doivent être soigneusement évités.

Et ça n’est pas tout.

Vous avez tous vus les déclarations de Comparator sauce Java8 comme cet exemple

Eh bien de la même manière, chaque déclaration de Comparator avec une fonction s’est révélée trop coûteuse en temps CPU. Du coup, j’ai tout viré et tout réécrit de façon traditionnelle.

Et ça, n’importe quel chef de projet informatique vous le dira, ça a un coût. En l’occurence, du temps passé. En regardant mes commits Git, je dirais que j’ai perdu une heure à corriger ces problèmes de performance, avec à chaque fois ces étapes

  1. Copier le test généré
  2. Exécuter le PerformanceTest avec debug et VisualVM connecté
  3. Trouver le bout de code lent
  4. Remplacer le stream par un foreach façon java5

Démoralisant.

Les machines à état, c’est caca

Quand on regarde les règles, clairement, il y a différents états. J’ai tenté de les détailler dans ce schéma (vous pouvez le regarder en détail, mais franchement, on s’en fout).

sequence

Ca a l’air sophistiqué, non ? Eh ben ça l’est … Et je suis loin d’être sûr de la justesse du truc

En fait, tout ça ne sert à rien.

Ca simplifie peut-être un peu le code, mais d’une façon malsaine : je me retrouve à micromanager alors que je devrais arbitrer. Et du coup, chaque état (qui a certes une classe associée) se complique, devient plus lourd, nécessite plus de maintenance.

En vrai, si j’écoutais ce que des gens plus intelligents disent, ce que j’aurais dû faire, c’est de la programmation dynamique.

C’est-à-dire qu’à chaque tour, j’aurais dû calculer tous les mouvements possibles avec autant de profondeur que possible, et choisir le mouvement qui m’apportait statistiquement le meilleur résultat.

Mais je me suis entêté avec ma machine à état. Et je me retrouve comme un con la veille de la fin, sans avoir le temps de corriger mon code. C’est moche. Très moche.

OK, donc t’es qu’une merde en fait ?

Pas tout à fait non plus.

J’ai un peu modifié mon générateur de tests pour y inclure automatique un assertThat(myCommand).isNotEqualsTo(« La commande exécutée ») et ça me fait gagner encore un peu de temps. Par ailleurs, je compte en gagner encore plus – un jour – via un système d’annotation pour écrire automatiquement la méthode de génération de test unitaire (JavaParser et annotations seront de la partie).

Et je vais prochainement releaser sur maven central mon plugin de génération de classe unique.

Ce ne sont pas des victoires, c’est vrai, et je ne gagne pas de XP. Mais je fais des choses qui m’amusent aussi.

Donc tu vas faire le prochain ?

On verra … Mais je pense que oui.

Une installation rapide …

Qui dit nouveau travail dit, en 2017, nouvel ordinateur prêté par l’employeur. En l’occurrence, un chouette Dell XPS 15 avec un très bel écran, un clavier assez moyen, de la RAM et du CPU en suffisance.

Évidemment, comme tout développeur, j’ai mon jeu d’outils de sélection. Et pour l’installation, le premier parmi les égaux est évidement Chocolatey, qui m’a permis d’installer facilement tous les programmes que j’avais noté dans ce gist

Et évidement, ça a très bien marché (sauf pour WinSplit Revolution, dont il va falloir que je retrouve une version compatible Windows 10 ou une alternative).

Il manquait deux ou trois trucs que j’avais précédemment installé séparément (Java, Eclipse, Maven, Groovy, ou encore OwnCloud).  Je les ai donc ajouté.

Et puis il a fallu installer les plugins des différents logiciels (qui ne sont hélas pas disponibles dans Chocolatey). Pour Firefox, c’est facile. Pour Eclipse, par contre, il faut le faire à la main … Comme pour Keepass.

Et c’est d’ailleurs avec ce dernier que j’ai apporté la plus grande modification en installant  KeeAgent. Avec ce dernier, je ne risque plus de perdre mes clés, puisqu’il transforme un outil déjà génial en porte-clé pour Pageant. En fait, à l’ouverture de la base, il injecte les clés dans Pageant, et comme ça je n’ai plus rien à taper … tout en restant en sécurité.

En fait, je pense que j’aurais pu avoir un poste fonctionnel en deux heures. Evidement, il faudra aussi que je reconfigure tout ça : les polices de caractère, les couleurs, les configurations d’écran, etc, … Mais ça, c’est quasiment de la blague par rapport à l’installation à la main.

Bon, par contre, j’ai un souci d’ordre domestique : ce superbe portable haut de gamme perd quand même facilement la connexion avec le wifi M de ma freebox (qui est à deux mètres). Du coup, périodiquement, je dois relancer la connexion wifi … pas très pratique, mais je crois qu’il va falloir que je fasse une vraie enquête d’engorgement des canaux wifi dans le quartier (habiter dans des maisons de 5 mètres de large, ça n’a pas vraiment que des avantages).

Enfin, ça, c’était avant que je change un paramètre de la carte wifi grâce à ce commentaire : Comment from discussion XPS15 9560 Wifi Problems.

Et depuis, ça marche bien mieux.

Comment bien documenter un système informatique ?

Je crois que je n’ai jamais écrit un titre aussi pompeux.

Enfin bref, cet article s’appuie sur différentes expériences que j’ai vécues … avec plus ou moins de succès.

Avant tout, posons la situation.

Quelques hypothèses

  • Vous faites partie d’une équipe de développement logiciel (je ne sais pas si ce que je vais décrire ici marche dans d’autres situations)
  • Vous disposez d’un outil de build moderne (Maven, Gradle, ou tous leurs équivalents)
  • Je vais parler ici de système, plus que de logiciel, parce que la plupart du temps, vous développez plusieurs logiciels livrables : un site web, un back-end, des plugins ou des applications clientes, …
  • Le système que vous développez est unique : personne d’autre dans le monde ne fait le même système que vous en utilisant les specs à votre disposition (ou pas)
  • Vous pouvez créer un nouvel artefact dans votre base de code pour stocker la partie principale de votre documentation

Quelques prises de conscience utiles

Vous avez donc, que vous utilisez une méthode agile ou en V, commencé par définir l’architecture de votre système avant de développer le code, qui a donné lieu à une structure de données.

Ca, c’est pour le système que vous allez livrer. Mais avez-vous conscience de l’autre système ?

6bwCQwX

Parce que vous faite quoi de votre gestionnaire de source ? De votre chaîne d’intégration et de déploiement continu ? A ce que je sache, ces éléments sont au minimum configurés pour votre équipe (dans le cas de git, ça va vite), et dans la plupart des cas hautement personnalisés selon vos besoins. Typiquement, vous avez deux systèmes à documenter :

  1. Celui que vous allez livrer
  2. Celui qui vous permet de le livrer

Quelqu’un à l’esprit joueur pourrait y voir une forme d’inception : développer un logiciel avec un ensemble de logiciels qu’on est en train de développer …

Il vous faut documenter à la fois le système que vous livrez, et celui que vous utilisez pour livrer.

Par ailleurs, est-il judicieux de parler de votre système, ou des différentes incarnations de celui-ci ?

3Bm98kT

Parce qu’après tout, votre système va connaître de multiples incarnations :

  • Architecture logique ne décrivant que les différents composants de l’application hors de toute réalité
  • Architecture physique incluant les différents environnements
    • Environnements de dév,
      • de recette
      • de prod
    • Environnements locaux
      • en PAAS
      • dans des conteneurs Docker

Dans l’idéal, votre documentation doit pouvoir se projeter sur ces différents environnements.

Quelques outils et méthodes utiles

D’abord, mettons-nous d’accord pour dire que, comme tout le monde, vous n’avez pas envie de vous répéter. Heureusement, ce problème de la non répétition est connu depuis longtemps. Regardez par exemple cet article : Single Source Information: An Agile Best Practice for Effective Documentation. Il est un peu vieux et prône donc l’utilisation de Dita XML. Ne vous enfuyez pas tout de suite, je suis sûr que vous allez voir où je veux en venir.

Quel format de document source utiliser ?

Effectivement, il faut limiter les sources de documentation et multiplier au contraire les formats de sortie. Ca revient à dire qu’il ne faut pas utiliser Office pour créer de la documentation, et pour plusieurs raisons :

  • Le livrable et la source documentaire sont identiques
  • Le système de gestion de révision intégré est loin derrière les outils de développement à notre disposition
  • Le travail collaboratif est pratiquement impossible
  • La création de documents lourds ne marche pas
  • L’inclusion de données externes mobiles est difficile à maintenir

En face, évidement, il y a eu XML (avec Docbook et Dita). Eux aussi avaient leurs défauts

  • Une syntaxe lourde
  • Des include incroyablement difficiles à maintenir
  • La nécessité d’utiliser des éditeurs spécialisés

Du coup, on pourrait penser que LaTeX pourrait être une réponse. Malheureusement, je crois que sa syntaxe n’est pas vraiment légère.

Du coup, je recommande chaudement d’utiliser AsciiDoc.

  • La syntaxe est simple
  • Il est possible de créer des structures de documents complexes (avec les include de fragments de documents)
  • Il existe des éditeurs WYSIWYG (comme par exemple AsciidocFX) qui facilitent réellement la montée en compétence
  • Et enfin, les documents finaux peuvent être générés pendant le build de votre projet, ce qui permet de raprocher la documentation et le code

Comment dessiner les diagrammes ?

Evidement, ce qui vaut pour les documents vaut également pour les diagrammes : pourquoi utiliser Visio, yEd pour des diagrammes qui vont être partagés ?

Coup de bol, asciidoctor fournit une bibliothèque (asciidoctor-diagram) qui permet de générer un paquet de type de schémas différents en intégrant quelques bibliothèques bien pratiques, et en particulier PlantUML. C’est d’autant plus intéressant que ça limite, par la nature textuelle du diagramme, la taille du dessin qui va être créé (parce que je sais pas vous mais personnellement, quand je vois un diagramme avec plus de dix noeuds, je commence à pleurer un peu).

Quel plan utiliser ?

On arrive à l’une des questions cruciales.

Avant tout, une bonne documentation, c’est une bonne histoire. Par conséquent, tout plan de documentation qui ne permettra pas l’exposé de l’histoire du système ne pourra pas être un bon plan. Et par histoire, je ne veux pas dire son historique des décisions. Non, je parle d’une histoire au sens le plus journalistique du terme : qui ? quoi ? quand où ? comment ? et surtout pourquoi ? Si votre plan ne contient pas ces éléments sous une forme ou une autre, vous n’y arriverez pas.

Coup de bol, j’ai le bon plan. ou plutôt Simon Brown a le bon plan.

Vous connaissez Structurizr ? Non ? Eh bien allez y faire un tour, c’est très intéressant.

En revanche, à titre personnel, comme j’aime mettre plus de texte que de diagramme, je trouve sa page Documentation encore plus intéressante. Pour une raison en particulier : il y décrit le contenu d’une bonne documentation sous la forme d’un sommaire assez bien fichu. Le voici :

  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

Eh bien le plan que je vous propose de suivre, c’est celui-là précisément.

Mais comment tout ça s’organise ?

Créer un artefact de documentation pour le système livrable

Dans votre gestionnaire de source, créez votre artefact de documentation. Généralement, je crée un module maven sous le projet principal. Si j’ai plusieurs sous-systèmes, je vais créer un module maven par sous-système et les agréger ensuite par chapitre (si le chapitre existe) au niveau principal

Pour ma part, ce sera un projet maven dans lequel je vais tout de suite ajouter le plugin asciidoc avec la configuration nécessaire pour générer du PlantUML.

Dans le dossier des sources asciidoc (donc dans mon cas dans src/docs/asciidoc), créez un dossier include dans lequel vous créez un fichier asciidoc pour chacun des chapitres de la doc.

Ecrivez votre doc

Pour chacun de ces chapitres, commencez par décrire le système d’une façon générale. Ne plongez dans les détails que si ces détails sont pertinents.

Ou générez votre doc

Il y a tout un tas d’éléments pour lesquels il peut être pertinent de générer certains éléments :

  • des diagrammes de classes extraits du code
  • des listes de classes implémentant certaines interfaces (avec des propriétés utiles)

Par pitié, ne vous répétez pas : vous pouvez, et devez, générer ces informations en asciidoc à partir de votre code.

Pour ça, j’utilise de façon systématique groovy : avant la génération de la doc, j’ai des scripts Groovy qui vont générer (dans target/generated/docs) les différents documents utiles.

Générez la doc livrable

Comme les fichiers asciidoc sont dans votre doc et utilisent le même système de build, vous pouvez générer la doc à chaque livraison, et même l’inclure comme artefact de votre build.

Ca vous garantit une documentation

  • à jour (puisqu’il est facile pour les développeurs de la modifier
  • propre (parce que Asciidoc génère facilement quele chose de joli)
  • conforme aux différents besoin de doc (puisqu’on peut facilement inclure les différentes parties de la doc dans différents documents)

Et ça marche bien ?

Chaque fois que j’ai utilisé cette méthode, j’ai réussi à produire de la documentation efficace, propre, et complète. Je ne sais pas si c’est une preuve

Mais où documente-t-on le système de développement ?

Dans la partie Development Environement, tout simplement.

Ca n’est pas un peu fastidieux de tenir à jour les diagrammes PlantUML ?

Ca peut rapidement l’être, c’est pour ça que je vous présenterai bientôt les différentes solutions auxquelles je pense pour … les générer, évidement ! (je dois d’ailleurs les tester sur mes programmes Codingame).

Tout ça n’est pas un nouveau nom sur une vieille idée ?

Bien sûr que si. L’idée, c’est le litterate programming, qui a connu des dizaines d’incarnation. Celle-ci est juste un peu plus moderne.

Changement de cap

Souvenez vous de l’article Cap sur 2015

Celui-ci en est une suite directe.

Il y a deux ans, j’avais donc décidé de tenter de travailler dans cet énorme multinationale. J’espérais y découvrir des choses …

  • Comment travailler sur des gros projets
  • Comment être efficace dans des organisations complexes
  • Comment discuter avec des clients du CAC40, ou semi-publics
  • Comment faire avancer des projets d’entreprise

J’ai découvert tout ça, et bien plus.

Je ne vais pas détailler tout ça publiquement. Si vous voulez plus de détails, je pourrais vous en donner de façon plus personnelle.

Toujours est-il qu’au bout de deux ans, même si je suis loin d’avoir fait le tour de l’entreprise, j’ai au moins compris une chose, grâce à ce dessin de XKCD

settling

Je dois bien admettre que prendre une décision de travail sur la base d’un dessin peut sembler ridicule … mais il s’agit plus d’un déclencheur que d’autre chose. Un déclencheur qui a bien aidé certaines personnes à me placer dans une orbite plus incertaine, mais aussi plus excitante.

En effet, je rejoins dès mardi Zenika, pour continuer à y fournir mes services de développeur Java un peu expérimenté et d’architecte … un peu moins expérimenté.

Pourquoi ?

Parce que je vais au chtijug très régulièrement, et que Zenika en est un sponsor depuis un moment.

Parce que j’ai vraiment beaucoup aimé aller à DevoxxFr, et que Zenika en est également un sponsor.

Parce qu’au-delà de ça, un certain nombre de consultants Zenika contribuent à l’open-source.

Autrement dit, parce que je me sens plus aligné avec les valeurs de Zenika.

Une nouvelle aventure, donc, dont je ne sais pas encore où elle me mènera.

En tout cas, elle évitera que je me retrouve propulsé au management

dt170216

Ca me fait le même effet

Ou, pire encore, que je me retrouve coincé dans la matrice des buzzwords

index

Et en terme de réalignement des objectifs sur les deadlines, croyez-moi, c’est pas une bonne idée.

Sincèrement, j’espère éviter ça chez Zenika … A moins que je ne le souhaite d’une façon obscure.

En tout cas, une chose est sûre, la nouveauté m’attend dès mardi !