Archives de Catégorie: Tools

Bitbucket vs Github

Vous savez peut-être que Bitbucket vous permet depuis fin 2011 d’héberger vos projets Git, comme Github, après avoir été un temple de Mercurial. Est-ce pour autant une bonne alternative ? Passons en revue leurs particularités !

Repository

Les interfaces du site sont extrêmement similaires, même si les designers de Github sont probablement légèrement meilleurs.

Chacun permet de créer des repositories publics et privés (mais pratique des prix différents, voir plus bas). Une fois le repository créé, on obtient une URL de remote, sur laquelle il est possible de pousser du code.

La navigation dans les sources se fait de façon identique sur le site, en parcourant les répertoires ou en utilisant les raccourcis claviers (par exemple `t` pour rechercher un fichier dans Github et `f` dans Bitbucket). Une fois le fichier trouvé, il est possible de le visionner, de faire un `blame`, de voir son historique ou de le modifier depuis le navigateur dans les deux cas.

Il est également possible de voir l’activité du projet, et les deux concurrents utilisent le fichier README de façon similaire pour décrire le projet.

L’historique des commits est un peu plus fonctionnel dans Bitbucket avec l’affichage possible de toutes les branches. La visualisation des branches est aussi intéressante, plus graphique que celle proposée par Github.

Fork/Pull Request/Code review

On trouve également le même mécanisme de fork (copie d’un repository dans votre espace utilisateur sur lequel vous avez tous les droits), de pull requests (demande d’intégration d’une fonctionnalité que vous avez codé dans un repo qui ne vous appartient pas) et de code reviews (possibilité de voir les différences introduites et de commenter le code).

Bitbucket ajoute quelques features « nice to have » : il est possible d’afficher un diff avec le fichier dans son ancienne version et dans sa nouvelle version côte à côte, d’affecter les code reviews à certains collaborateurs pour approbation et de ne pouvoir merger que si la pull request a été approuvée un certain nombre de fois. Ce petit workflow d’intégration n’est pas sans intérêt, même s’il est souvent pratiqué informellement sur Github. Autre petit avantage : lorsqu’une pull request ne peut être mergée pour cause de conflit, Bitbucket affiche clairement quels sont les fichiers et lignes en cause.

Administration

Peu de différence là encore : possibilité de créer des équipes et de leur affecter certains droits sur un repository. Bitbucket innove avec la possibilité de donner certains droits sur une branche spécifique.

Bug tracking

Chacun des concurrents propose un bug tracker intégré. Les fonctionnalités sont à peu près identiques :
– création d’anomalie avec assignation possible et version cible de correction.
– description au format markdown, avec images jointes.
– recherche des anomalies.
– lien possible entre anomalies (mais pas d’autocomplétion sur Bitbucket…).
– surveiller les anomalies.
– résolution automatique par commit.

Bitbucket propose en plus une criticité, une priorité et une gestion du workflow intégrée alors que Github compense en permettant la création dynamique de labels comme vous l’entendez. Le système de Github est flexible mais demande un peu plus de travail.

Une autre fonctionnalité intéressante réside dans le vote sur les issues. Là où Github ne permet toujours pas de voter, et où les commentaires ‘+1’ sont le seul moyen de manifester son intérêt, Bitbucket intègre directement le vote sur les issues, ce qui permet de jauger l’intérêt de la communauté pour une feature particulière.

La synchronisation avec d’autres bug trackers est généralement possible. L’intégration de Bitbucket avec Jira est mise en avant mais le même connecteur est utilisé pour Github et Bitbucket dans JIRA, les fonctionnalités sont donc possiblement équivalentes (mais je n’ai pas testé).

Wiki

Un wiki minimaliste est disponible pour les deux sites, avec syntaxe markdown, code highlighting et téléchargement possible (avec Git bien sûr) pour consultation offline.

Money, Money

Bitbucket mise sur un bon argument pour attirer les développeurs : les repositories privés. Alors que sur Github, le plan gratuit ne vous donne accès qu’à des repositories publics, Bitbucket autorise la création gratuite et illimitée de repositories privés. La restriction, car il faut bien une incitation à passer à la version payante, concerne le nombre maximum d’utilisateurs d’un repository privé : 5. Vous ne pouvez donc donner les droits d’accès à ces repo privés qu’à 5 de vos collègues : au-delà, il faudra mettre la main au portefeuille.

Les stratégies sont donc différentes en terme de marketing :
Github limite le nombre de repositories privés en fonction du prix (0 en gratuit, puis 5 pour 7$, 10 pour 12$…), le nombre de collaborateurs étant illimité.
Bitbucket permet de créer un nombre illimité de repositories privés mais limite le nombre de collaborateurs (5 en gratuit, puis 10 pour 10$, 25 pour 25$…).

Bitbucket a donc un argument intéressant pour une petite équipe créant un projet privé. A noter également la possibilité d’héberger vous même un Github Enterprise ou la suite professionelle de Bitbucket, nommée Stash, si la perspective d’avoir vos sources sur des serveurs américains vous trouble (mais franchement on ne voit pas pourquoi…). Ces outils vous donnent toutes les fonctionnalités de base plus la possibilité de s’intégrer avec votre système d’authentification interne.

Les prix sont tout de suite plus … entreprise! Github Enterprise démarre à 5000$ par an pour 20 utilisateurs, et est à peu près linéaire avec 250$ par utilisateur (100 utilisateurs donnent donc 25000$ par an, aïe). Bitbucket utilise là aussi une stratégie incitative avec une offre à seulement 10$ par mois pour 10 utilisateurs. La pente est ensuite plus raide mais les prix restent beaucoup plus abordables que ceux de Github avec 100 utilisateurs à 6000$ par an. A noter que Stash offre quelques fonctionnalités intéressantes comme une intégration poussée avec Jira (le bugtracker de la même société), ou les merges automatiques en cascade (un bugfix sur une ancienne release peut être automatiquement mergé sur les releases plus récentes).

Extras

Tous deux proposent une très bonne API REST, et des « hooks » qui permettent de s’intégrer avec tout ce que votre écosystème comporte d’important (les intégrations continues, dashboards, issue trackers…).
Bitbucket ne pose aucune limite sur la taille des fichiers, là où Github restreint à 100Mb par fichier.
Dans les petits bonus de Github, il ne faut pas oublier Github Pages, un support de nouveaux formats (fichier STL 3D, fichier GeoJSON) et une application mobile (même si c’est un peu anecdotique).

Communauté

Difficile de concurrencer Github, leader historique, dans le domaine. Avec près de 5 millions d’utilisateurs contre 1.5 million pour Bitbucket, la marge est encore grande. Les projets OSS phares hébergés sur Github sont très connus : Twitter Bootstrap, Node.js, Rails, JQuery, Angular.js, MongoDB, Linux Kernel. Bitbucket de son coté héberge les projets Atlassian, quelques projets de l’écosystème Python/Django et… pas grand chose d’autre de renommé. Mais surtout très difficile de trouver l’information, qui n’est pas mise en avant. A croire donc que les projets open source boudent le produit.

Les deux sites ont un petit aspect social, avec la possibilité de suivre des utilisateurs, de voir leur flux d’activité public, de mettre en favoris certains projets…

TL; DR;

Bitbucket a bien rattrapé son retard et ne souffre d’aucune lacune flagrante, au-delà de sa communauté moins nombreuse. Il possède même quelques fonctionnalités que l’on retrouverait avec plaisir sur Github.

Pour résumer :
– vous avez un projet open source ? Github sans réfléchir. L’exposition sera un ordre de magnitude supérieure.
– vous avez beaucoup de repositories privés, une petite équipe et peu d’argent ? Bitbucket est la solution économique. Vous pouvez même envisager Stash, leur solution pro.
– vous avez peu de repo privés et/ou de grandes équipes ? Github a un pricing plus intéressant.
– vous voulez héberger la solution chez vous ? Stash est beaucoup moins cher et ajoute quelques fonctionnalités intéressantes. Mais vous pouvez également regarder du côté des projets open source gratuits comme Gitlab par exemple.

Publicités

My essentials OSX applications

Difficile de blogger sur les frameworks hypes avec autre chose qu’un MacBook Pro. Récemment j’ai sauté le pas de passer au SSD : j’aurais du faire ça depuis longtemps! Alors pour tous ceux qui, comme moi, aiment payer 3000€ leur machine et 60€ par adaptateur-supplémentaire-non-fourni-mais-indispensable, voici la liste de toutes les applications que je me suis empressé de ré-installer sur mon disque tout neuf avec une installation de OSX Mountain Lion toute fraîche dessus. J’avais toutes ces applications sous Snow Leopard, donc cela conviendra à la majorité des gens intéressés.

Général

Alfred l’utilitaire hyper pratique pour lancer une application ou rechercher un fichier.
TotalFinder le finder MacOS est pas terrible, TotalFinder permet le multi onglet, copier/coller…
Flycut pour un buffer de copier/coller.
Dropbox pour synchroniser mes fichiers (il y a aussi GDrive pour les Google addicts).
Audacity pour les enregistrements de podcasts.
Dashlane pour gérer mes mots de passe. Mais 1Password semble pas mal, je vais peut être migrer.
Skype (ou Google Hangout) pour les réunions de télétravail ou organiser Mix-it.
Transmit comme client FTP.
Chrome pour navigateur.
Disk Inventory X pour avoir la heat map de l’utilisation du disque dur.
Zipeg pour unzip/untar les fichiers.
AppCleaner pour désinstaller proprement.
Mira pour controller toutes les applications à la télécommande (pratique pour les slides HTML par exemple).
KeyCastr pour afficher à l’écran vos frappes de clavier (pratique pour les talks, screencasts…).

Bureautique

Keynote : on dira ce que l’on veut, cela permet de faire des petites présentations classes rapidement. Même si je suis plus slides en HTML ces derniers temps.
OmniGraffle permet de faire des graphs sympas. Pratique pour les documentations.

Développement

iterm2 le terminal bien au dessus de celui par défaut. Avec zsh installé, il ne manque plus que oh my zsh pour avoir une configuration opérationnelle. L’autojump avec z m’est devenu indispensable et httpie pour faire des requêtes HTTP, sans connaître les 39 options nécessaires de curl. Je n’ai pas encore sauté le pas des .dotfiles, mais cela va être l’occasion.
Homebrew qui permet d’installer depuis la ligne de commande bien des choses nécessaires :
– asciidoc pour faire de magnifiques documents,
– git et git-extras et hub bien sûr,
– maven, gradle, sbt pour builder,
– play, groovy, ruby, python3,
– mongodb, redis, postgresql, elasticsearch pour les bases de données,
– phantomjs pour les tests,
– heroku-toolbelt, cloudbees-sdk pour le cloud.

nvm pour gérer les version de nodejs
Intellij IDEA pour développer. What else? Ha si, Sublime Text qui fait un très bon éditeur de texte ponctuel et a l’avantage de se trouver sur tous les OS.
Virtual Box pour les machines virtuelles.
Dash pratique pour avoir de la doc en offline.
Github l’application sert parfois, même si le combo ligne de commande/IDE me suffit le plus souvent.

Loisir

iTunes et Google Music pour ma musique et les podcasts vidéos.
µtorrent pour récupérer les … distribs linux (et les nouvelles versions de LibreOffice, pour se rappeler régulièrement comment c’est chiant une application bureautique pourrie.)? …
VLC pour regarder les vidéos avec le bien pratique Subtitles pour récupérer automatiquement les sous titres.
Calibre pour gérer mes e-books.
Twitter l’application officielle pour Mac s’est bien améliorée.
Steam pour les jeux. Y’en a peu mais des bons.

Voilà l’essentiel, je serais ravi d’entendre toute bonne application que vous utilisez et qui ferait cruellement défaut à cette liste!

Update : Vos contributions

Vous avez été nombreux à conseiller certaines applications, les voici (crédit au premier à l’avoir cité)!
Cafeine (@alexishassler) pour désactiver la mise en veille ponctuellement.
ControlPane (@alexishassler) pour gérer les configurations réseaux, les applications à lancer selon l’endroit où vous êtes.
PixelMator (@xlepaul) pour éditer les images.
Boom (@xlepaul) pour booster le son.
CrashPlan (@xlepaul) pour le backup de données.
Diffmerge (@xlepaul) pour comparer et merger vos fichiers.
Synergie (@Cedric_Gatay) pour gérer plusieurs machines avec un seul clavier/souris.
Cloudapp (@Cedric_Gatay) pour partager facilement des fichiers.
Pocket (@Cedric_Gatay) pour lire vos articles plus tard.
Colloquy (@Cedric_Gatay) comme client IRC.
Clusters (@Cedric_Gatay) qui compresse les dossiers en tâche de fond pour gagner de l’espace.
Monolingual (@slandelle) pour désinstaller les langues inutiles de MacOSX.
Evernote (@k33g_org) pour gérer vos listes, notes entre devices.
SourceTree (@k33g_org) comme client Git graphique.
VMWare Fusion (@k33g_org) comme alternative à VirtualBox.
XMind (@romaintaz) pour faire du mind mapping.
XtraFinder (@happynoff) comme alternative gratuite à TotalFinder.
Mou (@happynoff) pour la rédaction de document en Markdown.
Slate (@dgageot) comme gestionnaire de fenêtre (ou Moom (@morlhon), payant).
F.lux (@glours)pour gérer la luminosité de votre écran selon l’heure de la journée.

MongoDB Aggregation Framework

Vous avez probablement entendu parlé de MongoDb, une solution NoSQL orientée document développée par 10Gen. Les documents sont stockés en JSON, et bien que vous ayez un driver disponible pour chaque language, on se retrouve souvent à coder les requêtes en javascript dans le shell mongo fourni. Je vais vous parler de la version 2.2 qui est la dernière version stable et contient le framework d’aggregation, grande nouveauté attendue par les développeurs. Pour votre information, les numéros de version de Mongo suivent le vieux modèle du kernel Linux : les numéros pairs sont stables (2.2) alors que les versions de développement sont instables (2.1). Node.js suit le même modèle par exemple.

L’aggrégation donc, qu’est ce que c’est? Pour vous faire comprendre l’intérêt nous allons prendre un petit exemple (version simplifée d’un vrai projet). Admettons que vous stockiez les connexions à votre application toute les minutes, par exemple avec un document qui ressemblerait à

{"timestamp": 1358608980 , "connections": 150}

C’est à dire un timestamp qui correspond à la minute concernée et un nombre de connexions total.

Disons que vous vouliez récupérer les statistiques sur une plage de temps, par exemple sur une heure : il faudrait alors aggréger ces données pour obtenir le nombre total de connexion et le nombre moyen par minute. Seulement voilà, MongoDb ne propose pas de “group by”, de “sum” ou de “avg” comme l’on pourrait avoir en SQL. Ce genre d’opération est même déconseillé, car fait en javascript cela prend un plus de temps que dans une base classique. C’est en tout cas à éviter pour répondre à des requêtes en temps réel. Mais bon des fois, on est obligé…

 The old way : Map/Reduce
Jusqu’à la version 2.2 donc, on utilisait un algo map/reduce pour arriver à nos fins. Si vous ne connaissez pas, je vous invite à lire cet article de votre serviteur expliquant le fonctionnement. Dans un algo map/reduce, Il faut écrire une fonction map et une fonction reduce, qui vont s’appliquer sur les données selectionnées par une requête (un sous ensemble de votre collection MongoDb).

La requête qui permet de selectionner ce sous ensemble serait par exemple :

// stats comprises entre 15:00 et 16:00

var query = { timestamp : { $gte: 1358607600, $lte: 1358611200 }}

La fonction map va renvoyer les informations qui vous intéressent pour une clé. Ici nous voulons les connexions pour l’heure qui nous intéresse, donc nous aurons une fonction comme suit :

// on renvoie les infos pour la clé 15:00

var map = function(){ emit(1358607600, { connections : this.connections}) }

La fonction reduce va ensuite aggréger les informations, en ajoutant les connexions totales pour la clé 15:00 et calculer la moyenne associée.

// calculer la somme de toutes les connexions et la moyenne

var reduce = function(key, values){
 var connections = Array.sum(values.connections);
 var avg = connections/values.length;
 return { connections: connections, avg: avg}
 }

Maintenant que nous avons nos fonctions map et reduce, ainsi que la requête pour remonter les données qui nous intéressent, on peut lancer le map reduce.

// dans le shell mongo

db.statistics.mapReduce(map, reduce, { query: query, out: { inline: 1 }})

Le out inline permet d’écrire la réponse dans le shell directement (sinon il faut préciser une collection qui acceuillera le résultat). On obtient une réponse du style :

{connections: 180000, avg: 3000}

en 4,5 secondes environ sur ma collection de plusieurs millions de document légèrement plus complexes que l’exemple.

The new way : Aggregation Framework
Maintenant voyons la nouvelle façon de faire avec le framework d’aggrégation. Une nouvelle opération apparaît : aggregate. Celle-ci remplace mapReduce et fonctionne comme le pipe sous Linux : de nouveaux opérateurs sont disponibles et on peut les enchaîner. Par exemple, le “group by” est simplifié avec un nouvel attribut $group. La requête qui permet de filtrer un sous ensemble de la collection est écrite avec un opérateur $match. Enfin de nouveaux opérateurs viennent nous simplifier la vie : $sum, $avg, $min, $max… J’imagine que vous avez saisi l’idée.

Ici on veut un élément match qui limite l’opération aux données de l’heure concernée, on peut réutiliser la même query que tout à l’heure. On groupe ensuite les documents avec une seule clé : celle de l’heure qui nous intéresse, puis l’on demande le calcul de deux valeurs, le nombre total de connexions (une somme) et la moyenne des connections (une moyenne donc).

db.statistics.aggregate(
 { $match: query},
 { $group: { _id: 1358607600, totalCompleted: {$sum: "$connections"}, totalAvg: {$avg: "$connections"}
 }})

Le résultat est le suivant (en 4,2 secondes, soit un temps légérement inférieur au précédent) :

{ result: [{
 "_id": 1358607600,
 "totalCompleted": 180000,
 "totalAvg": 3000
 }], ok: 1}

L’avantage principal du framework d’aggrégation réside dans sa plus grande simplicité d’écriture et de lecture : plus besoin d’écrire des fonctions js soi-même pour des opérations somme toute assez courantes. Spring Data Mongo par exemple, le très bon projet de SpringSource pour vous simplifier la vie, demande d’écrire des fonctions en js pour faire du map/reduce. Vous avez donc un projet Java, qui contient quand même quelques fichiers js au milieu pour faire certaines opérations. Beaucoup attendent donc avec impatience l’arrivée du support du framework d’aggrégation dans Spring Data. Espérons qu’il ne tarde pas trop! En attendant d’autres frameworks comme Jongo l’ont déjà intégré. Il y a toutefois quelques limites comme le résultat de l’aggregate qui doit faire moins de 16Mo. Bref tout n’est pas idéal, mais ce très bon produit s’améliore à chaque version!

Le site Mix-it : making-of

Mix-IT est terminé et beaucoup de participants ont apprécié le nouveau site avec ses facettes communautaires et social gaming. En tout cas, nous avons pris beaucoup de plaisir à le faire. Car oui, ce site a été entièrement développé par les soins de notre équipe, particulièrement par Cyril Lacote (qui, il faut le dire doit avoir 60% du code à lui seul), Agnès Crépet et moi même, aidé par le reste de la team, avec leurs propositions, tests et feedback.

Voici donc une liste non exhaustive des outils et technos utilisés :

Trello : nous sommes des fans de la première heure de cet outil, qui nous a beaucoup servi pour échanger (mes camarades globe trotteur étant toujours décalés de plusieurs heures). Trello permet de faire un scrumboard interactif (on est notifié des échanges sur une tache), temps reel, avec un système de vote, label et filtre. Ça n’est pas JIRA mais pour un outil gratuit, c’est un outil génial.

Github : les sources du projet sont gérées sous Git. Aucun d’entre nous n’est un expert mais nous n’avons pas rencontré de problème majeur passés les premiers réglages. Nous avons utilisé le modèle décrit par Github (voir le talk de Zach Holman, et les articles GitHub), a savoir des pull requests, revues par un autre développeur avant d’être acceptées dans le master. C’est une bonne façon de garder une ‘collective ownership’ du code, même sans commiter.

Cloudbees : l’application est hébergée gracieusement par Cloudbees, qui a de plus acceptée généreusement de nous offrir les services additionnels qui nous était nécessaires (SendGrid, base de données en mode étendu, application en mode On Demand). La plateforme est très bien réalisée, le déploiement prend quelques minutes et est très simple à configurer. Ajoutez à ça un support ultra réactif et le fait qu’un déploiement est invisible pour les utilisateurs et vous avez une plateforme de choix pour vos développements.

Techniquement, l’application est codée avec le framework Play! (1.2.4 à l’heure actuelle) : rien à dire là dessus, Cyril et Agnès ne connaissaient pas et étaient productifs en quelques heures, peu de problèmes rencontrés, et avec tout un tas de modules à disposition (recherche full text Lucene, export PDF, parser Markdown). Bref, un outil génial! Un peu de Guava en plus et nous avions nos briques côté serveur. La base de données est un MySQL (hébergement cloudbees oblige).

Côté client, rien de très original, du bon vieux jQuery pour la manipulation de DOM. Et pour faire la même chose côté serveur (en Java donc), nous avons utilisé Jerry, qui nous permet de manipuler le contenu HTML des posts Google+ pour transformer les mentions d’utilisateurs. Nous avons également utilisé un plugin jQuery bien pratique pour gérer la dirtiness des formulaires et empêcher la sortie des pages en cours d’édition : dirtyforms.

Twitter Bootstrap : probablement notre coup de coeur, car même si nous faisons tous du développement, aucun d’entre nous n’est très doué en CSS. Et là, Twitter Bootstrap peut vous sauver : c’est un bootstrap CSS qui vous donne juste ce qu’il faut de cadre pour faire une application web présentable. Inconvénient : beaucoup de sites utilisent la même chose, il faut donc faire un peu de customisation pour différencier votre site. Tous les icones utilisés proviennent de fontawesome. Nous utilisons la version Less de Bootstrap plutôt que la version CSS : pour plus d’infos voir article précédent.

Ce qui n’a jamais atteint la mise en ligne

Nous avions envie de mettre un peu de communication temps réel sur le site avec un système de notifications lorsqu’un participant auquel vous étiez relié effectuait une action sur le site. Pour ça, un projet annexe (disponible sur github également) utilisant nodejs était utilisé. Dès qu’une action était effectuée sur le site, une requête était envoyée à un serveur nodejs, qui notifiait les utilisateurs intéressés connectés (par websocket en utilisant socket.io). La notification se fait sous forme d’une notification HTML5 si disponible dans le navigateur, ou en utilisant le plugin noty. Malheureusement nous n’avons pas eu le temps de terminer cette fonctionnalité.

Maybe next year… D’ici là, vous pouvez trouver les sources sur Github et vous amusez avec!

So what is Meteor?

Il y a quelques jours, un (enième) framework javascript faisait son lancement : Meteor. Un très bon lancement d’ailleurs, avec un site agréable, 3 petites applications d’exemple, presentées avec des screencasts clairs. Cette sortie est remarquée et se retrouve rapidement commentée sur Hacker News, Twitter et Quora. Car Meteor est un framework de développement d’application web full stack en javascript qui entend bien révolutionner notre façon de coder.


Pourquoi autant d’attention pour un framework vieux de quelques jours ? Parce qu’il y a quelques idées très intéressantes à étudier! Le site annonce la couleur de suite : développer rapidement une application web de qualité dont l’une des qualités, et pas des moindres, est de pouvoir faire du temps réel. Et il faut reconnaitre que leurs démos sont enthousiasmantes : il y a longtemps que je ne m’étais pas dit ‘il faut que j’essaye ce truc!’ en regardant un framework web! Pour avoir fait un petit essai d’appli, c’est simple à mettre en oeuvre, et en une heure j’avais une petite démo qui tournait en ligne (meteor propose son service d’hébergement). L’une des fonctions extrêmement agréable en code est l’auto refresh du navigateur. Play! mettait déjà en avant son cycle de développement rapide, à la portée d’un refresh manuel d’une seconde (enfin ca c’était avant la version 2…). Ici même plus besoin de cette étape, votre navigateur est automatiquement notifié d’un changement et les affiche à l’écran. En dual-screen, c’est un bonheur à coder! Faisons un petit tour sous le capot maintenant.


Real time

Plutot que d’envoyer du html a votre client, Meteor propose d’envoyer seulement les données et de laisser le client décider de la façon dont elles doivent être affichées. La où Meteor donne son effet “wahou”, c’est par sa gestion native du temps réel. L’objet affiché dans votre navigateur a été modifié par un autre utilisateur ? No problem, Meteor va informer tous les clients de cette modification, et vous allez voir votre affichage se modifier en conséquence! C’est vraiment impressionnant d’obtenir un tel résultat sans rien coder, et rien que pour ça, prenez 5 minutes et essayez. D’autres outils proposent également de vous aider à bâtir des applications avec temps réels dont socketstream qui est très bon et s’appuie sur socket.io (le lead développeur de socketstream explique la différence de philosophie, socketstream etant beaucoup plus léger et prévu pour s’intégrer en complément d’autres frameworks). Ici Meteor a fait le choix d’utiliser SockJS, une librairie un peu équivalente. Mais pour l’instant rien ne passe par les websockets, tous les transferts de data sont par requête xhr (dans le code source il est indiqué que c’est par soucis de compatibilité avec les différentes navigateurs, mais c’est évidement modifiable). Tout se passe par un système de publish/suscribe que l’on retrouve de plus en plus et qui est très intéressant (vos clients s’abonnent à des événements qui les intéressent et réagissent en conséquence).


Auto refresh

Lorsque vous êtes en train de développer, la sauvegarde d’un fichier sur votre poste va automatiquement rafraichir le navigateur avec vos modifications. Comme je le disais en introduction, c’est un vrai bonheur et c’est quelque que l’on voit apparaître un peu partout. Ce principe de modification à chaud est aussi disponible en production : Meteor annonce qu’une nouvelle version de votre application peut être déployée de façon transparente pour vos utilisateurs (bon ça je pense que personne n’a vraiment testé…).


Node.js as runtime

Node.js gagne en maturité et devient un runtime vraiment intéressant pour bâtir des applications (pas forcément des webapps d’ailleurs). On trouve déjà des frameworks webs par poignées, l’un de mes préférés étant Express. Celui ci est différent à bien des égards par rapport à ce qu’il existe déjà, par son aspect full-stack et temps réel. Mais un point a dérangé pas mal de monde, une phrase de la doc indiquant : “In Meteor, your server code runs in a single thread per request, not in the asynchronous callback style typical of Node”. L’encapsulation de Node est donc différente de ce à quoi nous sommes habitués dans la majeure partie des cas. Mais tout ça est transparent pour le développeur, et l’équipe derrière a l’air d’avoir une certaine “street cred” (notamment les développeurs d’Etherpad, un Google Docs avant l’heure, d’ailleurs racheté par Google par la suite), donc leur choix n’est peut être pas aussi absurde qu’il peut en avoir l’air a première vue. Cette gestion différente de Node se fait grâce à la librairie node-fibers entre autre. En tout cas, même si vous n’avez jamais fait de Node.js, aucun problème pour se lancer avec Meteor, tout est transparent. Nodejs est d’ailleurs le seul prérequis pour déployer une application Meteor.


Partage du code client et serveur

Meteor est un framework full stack qui donne les outils nécessaires pour faire votre application depuis le templating client à la persistance en base de données. Mais de plus pour Meteor, vos objets javascripts clients sont les mêmes que les objets javascripts serveurs. On dénombre quelques frameworks javascripts qui ont la même idée, comme par exemple Tower.js, voire même des choses assez proches de Meteor comme Derby (beaucoup de features identiques sont présentes, au point que l’équipe de Derby a fait un billet pour expliquer leurs différences). Plus que les objets, se sont même les fonctions qui peuvent s’exécuter indifféremment côté client ou côté serveur!

Le code est à tel point partagé que par défaut, vous écrivez les deux parties dans le même fichier (chaque partie étant quand même identifiée, mais on peut partager des fonctions entre les deux). Vous pouvez également scinder ce fichier, la convention étant de créer un dossier ‘client’ et un dossier ‘serveur’ qui contiennent vos fichiers.


Base de données

Par défaut, c’est une instance MongoDB qui est lancée pour la persistence. MongoDB est une base NoSQL, orientée document, dont l’API est en javascript. Cette API est d’ailleurs disponible aussi bien dans la partie serveur que dans la partie cliente! Hein? Oui, en fait, Meteor va répliquer la base de données dans le navigateur, pour que vous puissiez manipuler un ensemble valide de données directement depuis le client (on imagine bien que ce système a des limites, mais n’est pas trop détaillé à ma connaissance).


Côté client

Le système de templating retenu est Handlebars par défaut, mais il est à priori possible de choisir son préféré. Pour le reste, le comportement ressemble à beaucoup d’autres frameworks à la Backbone : vous définissez à quels ‘events’ vont réagir vos objets et la façon dont ils vont réagir. Pour manipuler le DOM vous pouvez utiliser votre bibliothèque favorite (en interne Meteor utilise JQuery). Ce qui est intéressant c’est qu’une action côté client n’attend pas forcément la réponse du serveur : elle va effectuer son action immédiatement (en simulant la requête, puisque votre base de code fonctionne aussi bien côté client que côté serveur). Quand le serveur renvoie sa réponse, le client compare les résultats et se met à jour en conséquence. Cette fonctionnalité s’appelle la ‘compensation de latence’ et permet également de faire fonctionner Meteor en offline : si votre serveur est indisponible, le client va effectuer tous les traitements localement, donnant l’impression que tout fonctionne normalement. Lorsque la connection est rétablie, les requêtes en attente sont jouées sur le serveur et le client se met à jour. Ce mécanisme est détaillé par l’un des développeurs sur stack overflow.

Le protocole de communication client serveur est de leur cru et baptisé DDP (ce n’est donc pas du REST par exemple, bien que les développeurs indiquent qu’il est simple d’adapter DDP pour en faire du REST, ou le connecter à d’autres protocoles, mais cela manque un peu de doc là encore).


Packaging

Meteor vient avec son propre système de gestion de dépendances et de packaging. C’est bien fait et efficace mais cela ne s’appuie pas sur NPM qui est pourtant devenu le standard de facto de la communauté Node, et qui s’avère très très pratique. Un choix un peu discutable donc. Un certain nombre de packages sont déjà disponibles, dont backbone ou less par exemple. Côté déploiement, c’est vraiment efficace : un simple “meteor deploy” pousse votre application sur le service de hosting maison de Meteor (sur une url etant par défaut lenomdemonappli.meteor.com). Il est possible de sécuriser le déploiement de l’application avec un mot de passe (option -P).

Sécurité

L’un des points non traités pour l’instant, et non des moindres, est la partie sécurité/authentification. Pour cette version, on ne peut tout simplement rien faire dans ce domaine, donc une application mise en ligne peut voir sa base de données vidée en quelques secondes (l’API de la base étant exposée côté client, une petite requête dans la console javascript et c’est plié).

Licence

Un dernier mot sur la licence : Meteor est en GPL, licence virale par excellence. Donc tant que vous faites vous aussi du GPL et que vous redistribuez votre code pas de soucis, sinon vous êtes encouragés à contacter l’équipe de Meteor (entendez, éventuellement payer) pour une utilisation commerciale. Ca n’est pas fondamentalement gênant, et on comprend bien qu’ils veulent gagner leur vie. Bien d’autres outils connus utilisent cette double licence (MySQL par exemple), mais c’est finalement assez peu courants dans les projets Javascript, qui ont habituellement des licences plus permissives. La question qui se pose est : est ce que cela va limiter l’adoption et les contributions à Meteor? Cet article vous expliquera tout ça mieux que moi si le sujet des licences vous intéresse.

Edit : depuis l’écriture de ce post, la licence est passée en MIT. Comme quoi, le pouvoir de la communauté…


J’espère que cet article vous aura fait partager mon enthousiasme pour Meteor, bien que j’explique également les quelques choix qui font débat. Le meilleur moyen de vous faire votre avis est vraiment de regarder les quelques screencasts disponibles. Il y a d’excellentes idées dans cet outil, et nous allons voir de plus en plus de frameworks nous offrir ce genre de fonctionnalités pour faire des applications web bien différentes de ce que nous faisons actuellement.

CSS sucks, do Less!

L’écriture d’une feuille de style est l’un des moments les plus douloureux pour tout développeur Web : la science occulte des CSS et sa verbosité en font une soupe rarement agréable à avaler. Mais un outil peut changer tout ça : Less!

Less est un preprocesseur CSS et n’est pas magique : vous devrez tout de même travailler pour avoir un style graphique convenable. Mais la où il innove, c’est par l’ajout de quelques fonctionnalités bien pratiques, et on se demande comment nous avons pu nous en passer jusque la.

Do Less

Pour démarrer, un fichier css peut être un fichier less : vous le renommez en .less et le tour est joué. Ensuite, pour utiliser ce fichier, plusieurs choix s’offrent à vous. Vous pouvez inclure less.js dans votre page web et le laisser transformer vos fichiers less en css.

<script src="less.js" type="text/javascript"></script>
<link rel="stylesheet/less" type="text/css" href="styles.less">

Ou vous pouvez compiler directement vos fichiers less en css, selon le type de votre application :
– Avec des compilateurs existants comme less.app
– Avec le module less de nodejs
– Si vous faites du Play!, vous pouvez utiliser le module prévu. A noter qu’en Play!2, le support de less est natif, la compilation se fait de façon transparente pour vous. Bref, Less commence à être connu et intégré un peu partout. Le magnifique Twitter Bootstrap par exemple, un super bootstrap css qui vous permet de faire un style sympa même sans rien comprendre à l’art obscur des css, est fait avec Less. Mais bon, Less, ça fait quoi ?

Variables

Que tout ceux qui n’ont jamais pesté pour changer la couleur d’un thème lève la main! Bon, je ne peux pas voir, mais je suis sûr que vous n’êtes pas nombreux. Tout ça à cause de l’absence de variable en CSS. Voyons un peux comment Less remédie à ce problème, et à bien d’autres… Les variables sont nos amies : c’est la première chose que l’on apprend en programmation. On se retrouve un peu démuni en CSS, avec l’obligation de copier/coller n fois la même couleur ou la taille de police, et la galère qui suit pour un changement. Avec Less, c’est fini!Si vous voulez créer un thème, après avoir repéré le code couleur qui vous faisait rêver sur ColourLovers, vous pouvez définir vos premières variables :

@body_color: #262626;
@font_color: #EAF2D9;

On peut également définir d’autres variables, telles que la taille de la police :

@font_size: 20px;

Là où ça devient intéressant, c’est que l’on peut également faire des opérations (pas n’importe quoi hein, juste des opérations mathématiques de base) :

@big_font_size: font_size + 2px;

Fonctions

Si l’on a des variables et des opérations, vous vous doutez que l’on a aussi … des fonctions ! Baptisées “mixins” elles permettent de créer des styles avec des paramètres. Exemple :  les petits bords arrondis sympas que l’on veut mettre sur tous les boutons mais qui sont définis avec des styles spécifiques à chaque navigateur, et que l’on doit répéter à chaque taille d’arrondis que l’on veut.
Less nous permet de créer une fonction border-radius avec un seul paramètre nommé radius

.border-radius(@radius){
 border-radius: @radius;
 -webkit-border-radius: @radius;
 -moz-border-radius: @radius;
}

Cette fonction peut ensuite être appelée dans votre style :

.border-radius(10px);

Et ca devient franchement cool, quand on voit que d’autres ont pris le temps de faire des fonctions à notre place, et que l’on peut utiliser ces fichiers dans nos styles, lesselements ou encore dans le Bootstrap Twitter (oui, je suis fan).

Vous n’aurez plus jamais besoin d’écrire un préfixe navigateur (voir l’excellent screencast de nettuts), et ça, ça n’a pas de prix!

Less inclue lui aussi nativement un certain nombre de fonctions portant sur le traitement des couleurs (saturate, lighten, etc http://lesscss.org/#-color-functions). Par exemple :

fade(@color, 50%);

renvoie une couleur 50% plus transparente. Cool, huh ?

Nesting

Maintenant que nous avons vu les briques de base, on peut se pencher un peu plus sur l’apparence d’un fichier .less. On a l’habitude en css de répéter pour chaque régle toute les classes concernées, ce qui devient vite très verbeux :

.share {
 ...
}
.share .name {
 ...
}
.share .tag {
 ...
}
.share .tag .price {
 ...
}

En less, on peut faire quelque chose de plus simple et plus logique :

.share {
  ...
  .name {
    ...
  }
  .tag {
    ...
    .price {
      ...
    }
  }
}

Ce nesting peut s’appliquer aussi bien aux classes, aux ids et aux éléments.
Le nesting a de plus l’avantage d’inciter a regrouper les règles, ce qui peut vite tourner à l’anarchie dans un fichier css classique (qui n’a jamais ajouté sa règle tout en bas du fichier pour aller vite …).

Import

Toujours dans l’idée d’avoir un style plus clair, il est possible de découper ses fichiers less en fichier plus petits et de faire des inclusions là où ils sont nécessaires. Ainsi, vous pouvez avoir un fichier de variables, avec les propriétés générales de l’application, couleurs, font etc… et un fichier de fonctions utilitaires que vous incluez ensuite dans vos fichiers de style.

@import "variables.less";
@import "utils.less";

Magique non ? Moi je ne peux plus m’en passer !

Il existe bien sûr des alternatives à Less telles que Sass issu du monde Ruby (excellent screencast pour le découvrir) ou Stylus, Cet article met d’ailleurs en avant les différences entre Sass et Less.

Le prochain article reprendra la mini appli nodejs des articles précédents et ajoutera un peu de style en less ! Stay tuned !

Cloud9, Coding node.js in the cloud

Coder du javascript, ca n’est pas forcément simple, et on a toujours besoin d’un bon outil. C’est pourquoi je veux vous parler d’un IDE que j’ai utilisé récemment, et qui change un peu d’Eclipse et d’IntelliJ : Cloud9.

Cloud9 est un IDE un peu particulier : comme son nom le laisse supposer c’est un environnement de développement web-based, open source, écrit en javascript pour faire du javascript. Le back-end est d’ailleurs écrit en node.js, le front est html5 et le tout utilise massivement les websockets, que du hype! Votre code est donc accessible depuis n’importe quel poste de travail, pour peu que vous ayez une connection web, évidemment.

Pour tester rendez vous sur c9.io ou installez le directement dans votre navigateur si vous utilisez Chrome (si vraiment vous n’aimez pas votre navigateur, vous pouvez également récupérer les sources et lancer l’IDE en local). Une fois installé, il faut se connecter : pour cela vous pouvez utiliser votre compte Github ou Bitbucket, ou encore créer un compte cloud9. Le projet utilisé pour cette série d’article étant hébergé sur Github, j’utiliserais donc cette option.

Une fois connecté vous arrivez sur une page d’accueil qui liste les projets de votre compte Github. Pour commencer à travailler, il faut créer ou cloner un projet. La création permet d’héberger son projet directement sur Github, Bitbucket ou un ftp (bientôt sur Dropbox également). Cloud9 adopte un modèle de fonctionnement à la Github : si votre projet est public, l’utilisation est gratuite, si vous voulez faire un projet privé, il faut payer (15$ par mois).

L’IDE permet également de créer des contextes : en haut à gauche, cliquez sur ‘Active context’. Ces contextes permettent de changer rapidement entre vos projets et également de gérer l’aspect collaboratif : il est possible d’ajouter des membres aux différents projets et de travailler à plusieurs (avec modifications temps réel et chat intégré).

Pour faire simple, nous allons cloner le projet du précédent article, pour cela, cliquez sur le ‘+’ à côté de ‘My project’ puis choisissez ‘clone from url’. Entrez alors l’adresse du projet shares : git://github.com/cexbrayat/shares.git. Une fois que Cloud9 a terminé de cloner le projet, on peut commencer à coder en cliquant sur ‘Start editing’ !

La fenêtre qui apparaît ressemble à un IDE traditionnel avec barre de menu, explorateur de fichier et zone d’edition. En bas la zone de saisie sert de console. Si l’on ouvre le fichier app.js, on voit que la coloration syntaxique est présente et agréable. La complétion est elle aussi disponible (et très pratique, mais si elle n’est pas exempte de quelques errements). Le code est également analysé en fond, et des indications vous sont données pendant l’édition. On peut voir par exemple qu’un point virgule est manquant sur la ligne 42 avec un petit warning dans la marge. Beaucoup de raccourcis clavier traditionnels sont disponibles, le debug, l’inspection des variables, bref tout ce dont nous avons besoin. Il est même possible d’ajouter des extensions (et d’en créer) ou de modifier les thèmes (IdleFinger ou Monokai sont assez sympas).

La où Cloud9 se distingue c’est qu’il est réellement pensé pour créer du code et le tester depuis n’importe quelle machine, et particulièrement pour du code node.js. L’intégration de différents composants vont en faire l’un de vos nouveaux amis :

Github : la ligne de commande (zone de saisie tout en bas de l’écran) vous permet de saisir vos commandes git, avec une autocomplétion bien pratique. Vous pouvez donc directement commiter vos modifications, créer vos branches etc…

NPM : le gestionnaire de dépendances de node est déjà installé ! Le projet utilisant les modules express et jade, il faut donc les récupérer, pour cela entrez dans la ligne de commande ‘npm install’ et voilà le projet prêt à être lancé.

– Node : évidemment node.js est déjà installé, vous pouvez donc lancer votre projet directement depuis votre navigateur en cliquant sur ‘run’ et en indiquant le fichier principal ‘app.js’. Le projet démarre alors et une url s’affiche en console (pour moi http://shares.cexbrayat.cloud9ide.com/) et me permet d’accéder au projet (ainsi qu’à n’importe qui, voilà qui va simplifier les démos!). La seule modification qu’il soit nécessaire de faire pour lancer le projet est de modifier le port de lancement de l’application par la variable d’environnement process.env.C9_PORT

– Le déploiement : une fois votre application prête pour le monde, vous pouvez la déployer directement depuis cloud9 vers une instance joyent ou heroku.

Les seuls reproches que je lui ferais sont le manque d’outils pour le refactoring et quelques rares plantages (pas beaucoup plus qu’un Eclipse traditionnel cependant. Un troll, où ça ?).

Vous voilà à deux clics de commencer à coder votre première application node.js, sans avoir besoin d’installer moults outils : vous n’avez plus d’excuse pour ne pas essayer !