Affichage des articles dont le libellé est outils. Afficher tous les articles
Affichage des articles dont le libellé est outils. Afficher tous les articles

dimanche 3 novembre 2013

tmux & vim

Vous vous rappelez, il y a assez longtemps, j'avais écrit ici à propos de tmux, qui est un outil assez génial pour multiplexer des terminaux, que vous travaillez sur un serveur distant ou en local.

Plus récemment, j'ai aborder l'importance de faire un peu de tuning pour la coloration syntaxique de Vim pour éviter de passer votre vie professionnelle en thérapie.

Hier, j'ai un peu cherché parce que je n'arrivais pas à avoir tmux ET un vim en 256 couleurs. Je peux vous dire que je suais à grosses gouttes devant la perspective de ne pas pouvoir utiliser conjointement les deux.

Donc ne cherchez plus, mettez ceci dans votre .tmux.conf :

set-option -g default-terminal "screen-256color"

Et ceci dans votre .bashrc (je ne parle pas aux utilisateurs de zsh, chacun ses valeurs) :

# Le teste évite à tmux de basculer sur TERM=xterm-256color s'il d'aventure
# il sourçait  ~/.bashrc au démarrage (ce qui serait une bonne idée
# remarquez...)
# Tout va bien marcher avec tmux si la variable TERM est exportée avec
# screen-256coloret rien d'autre !
if [[ $TERM != screen-256color ]]
then
    export TERM=xterm-256color
fi

Deux dernières choses avant de partir. Premièrement, vous avez remarqué que par défaut, tmux ne chargeait pas votre .bashrc sous Debian (en tout cas, chez moi, il ne le fait pas, ce petit salopard). Vous pouvez toujours le lancer en faisant tmux bash mais ça manque de classe... Ajoutez plutôt la ligne suivante à votre .tmux.conf :

set-option -g default-command "/bin/bash"

À présent, le petit test sur TERM dans la config de bash prend tout son sens !

Et enfin, ajoutez cette ligne si vous voulez avoir les bindings vi sans avoir à exporter EDITOR=vi (ce qui est un peu old school comme habitude, il faut le dire).

set-window-option -g mode-keys vi

Voilà, j'ai partagé avec vous ma config pas trop velue de tmux. Je vous souhaite une bonne semaine de boulot dans votre terminal !

mardi 30 avril 2013

Caractères Appariés

Une fonctionnalité sympathique de certains éditeurs de texte est de pouvoir apparier des caractères et de placer le curseur au milieu pour continuer la frappe. Exemple : vous tapez un guillemet double, l'éditeur en écrit deux et laisse le curseur entre les deux. C'est ce que fait par exemple l'éditeur d'IntelliJ. Le problème est que ce comportement est parfois indésirable et nous ralentit dans certaines situations. Je me suis demandé comment mettre en place ce comportement vim. Ma solution simple, utiliser des mappings en mode insertion.

imap '<TAB> ''<ESC>i
imap "<TAB> ""<ESC>i
imap [<TAB> []<ESC>i
imap {<TAB> {}<ESC>i
imap (<TAB> ()<ESC>i
imap <<TAB> <><ESC>i

Dans cette configuration, je valide l'appariement par Tab. Ça demande un peu de pratique mais ça me convient : je préfère avoir à valider un comportement automatique plutôt que d'annuler son déclenchement.

J'ai vu qu'il existait un plugin pour faire la même chose mais la description et le code ont l'air compliqués ('¬°o°)¬. Alors je crois que je vais continuer à utiliser mes petits mappings.

dimanche 28 avril 2013

Markdown Versus reStructuredText

Markdown est un langage que j'utilise pour à peu près toute ma doc depuis plus d'un an maintenant. Je m'en sert pour générer rapidement du html à copier coller dans un doc Word ou dans ce blog, par exemple. Dernièrement, je me suis intéressé à reStructuredText dont l'objectif est similaire mais qui est originellement implémenté en Python (est-ce ce qui le rend moins populaire ?)

Les deux langages proposent de définir la mise en forme d'un document texte via un balisage (markup) léger, à la manière de ce que proposent les syntaxes wiki. On utilise un outil pour générer le document formaté suivant la sortie désiré (principalement du html). L'intéret est d'avoir un document texte, éditable avec les éditeur moderne dont la mise en forme donne déjà un aperçu du rendu final. En fait un document texte décrit en utilisant ces syntaxes se suffirait presque à lui-même ! La possibilité de le transformer est un plus pour communiquer avec le reste du monde.

Les deux langages présentent une syntaxe de base très similaire pour écrire du texte en gras ou en italique, faire des titres ou des listes. Toutefois, reStructuredText se veut beaucoup plus complet, permet de décrire des tableaux, des notes en bas de page, d'insérer des formules en Latex (j'en passe...). Il est également livré avec des outils permettant de générer du texte dans plusieurs formats (html, Latex, odt,...). Ces fonctionnalités le rendent également bien plus complexe à apréhenter, alors que celles de Markdown tiennent sur une page.

Il y a une différence aussi sur le html généré. Pour schématiser, disons que Markdown génère le minimum et et reStructuredText le maximum. En effet, Markdown fait juste une conversion du balisage en html alors que reStructuredText génère un document complet, avec du CSS dedans, un doctype xhtml et un en-tête détaillé. De ce fait, il est, en première approche, plus simple d'intégrer du Markdown dans un autre document. Pour cet article par exemple, j'écris en Markdown, génère le html et le colle directement dans l'interface Blogger. Je pourrais le faire aussi en reStructuredText, mais en utilisant la commande de base, il faut que j'aille chercher le bout de html à extraire avant de le coller dans Blogger. C'est moins pratique.

Autre point en faveur de Markdown, la possibilité d'écrire directement du html dedans. Moi je trouve ça cool pour mettre des entities unicode (car j'en connais plusieurs). Avec reStructuredText, c'est plus compliqué, il faut utiliser les substitutions, inclure un fichier regroupant toutes les entities et utiliser une syntaxe qui ne fonctionne pas dans toutes les situation (par exemple, pas en début de ligne...). D'un autre côté, quand vous voulez faire des tableau, le html c'est sympa mais c'est vite peu lisible. Avec reStructuredText, vous pouvez (vous faire chier à) dessiner tout le tableau en ascii, avec des - et des + ! Bon, je vous rassure, il y a également une syntaxe simplifiée.

J'ai l'air super dur avec reStructuredText en comparaison avec Markdown. Je pense qu'on peut en faire une utilisation différente. Pour générer rapidement des bouts de html, je continuerai d'utiliser Markdown car j'aime bien sa syntaxe minimaliste et il ne génère que le strict nécessaire. Pour générer des documents plus complets toutefois, comme ce que j'ai besoin de faire au travail, je vais donner une chance à reStructuredText. Il est plus simple d'intégrer des styles dans le workflow et, qui sait, peut-être possible de générer directement du Open XML ! Les fonctionnalités proposées permettent aussi plus de fantaisie que du classique gras / italique / bullet points. Si je trouve des trucs cools à faire avec, cela me redonnera l'occasion d'écrire quelque chose.

jeudi 21 mars 2013

Pomodoro Technique, le retour

Voici une petite suite à l'article que j'avais fait sur la Pomodoro Technique.

Je m'aperçois que depuis que j'ai écrit l'article, j'ai suivi cette méthode en dilettante. Au départ, je faisais un semblant de reporting que j'ai vite arrêter (il y a un an). J'ai continué à time boxer mon travail mais sans respecter parfaitement les fin de tomates et les pauses. À un moment, ne constant même plus les apports de la pratique, j'ai même tout arrêté pour essayer de retrouver de la spontanéité dans mon travail. J'ai vite déchanté : le temps m'échappait complètement. J'ai eu l'impression de ne plus réussir à remplir mes journées efficacement.

Vers Novembre ou Décembre, j'ai repris. J'ai changé de logiciel pour utiliser Tomightly plus simple, plus beau, moins contraignant et open source. J'ai repris mais toujours en dilettante : je notais mes listes d'actions quotidiennes sur mon cahier mais je ne traçais pas tout et respectait que moyennement les fins de tomates.

En fin de semaine dernière, je suis arrivé à un score misérable de 3 tomates. Ce week-end, j'ai relu le bouquin et j'ai décidé de retenter ma chance, plus sérieusement cette semaine. Je me suis efforcé de respecter les tomates.

Et aujourd'hui, pour la première fois, j'ai utilisé les longues pauses !

En ce jeudi soir, je peux faire un petit bilan de cette pratique plus disciplinée. Tout d'abord, c'est très agréable. Le fait de respecter les différentes durées et les temps de pause insuffle un rythme qu'on ressent tout de suite. C'est très satisfaisant. D'autre part, j'ai décidé d'écrire et de tracer l'ensemble de mes tâches de la journées, même les réunions. Je sais maintenant que je peux sélectionner 12 tomates à faire par jour. En fin de journée, je trace ce que j'ai fait dans un fichier Excel en associant des thèmes. Cela me permet de connaitre le temps passé par activité d'améliorer mon reporting et, j'espère, d'améliorer mes futurs chiffrages (ce sera moins évident...). Je sais maintenant exactement le temps que je passe par semaine en pilotage, en développement, etc. Le fait de réussir à faire 11 ou 12 tomates par jour est très encourageant. J'espère que j'aurai le courage de continuer dans cette voie, le jeu en vaut la chandelle.

Seul point négatif, je me suis complètement isolé, le casque sur les oreilles toute la journée...

En même temps, on cherche à éviter les interruptions, pas vrai ?

mardi 26 février 2013

Marre des rongeurs

À la maison, j'essaie d'utiliser de moins en moins la souris au profit du clavier. J'en ai marre de sans arrêt aller chercher des icônes minuscules à la con pour interagir avec les logiciels ou simplement la fenêtre qui les entoure. J'en ai marre d'aller chercher un email à la souris. Bref, voici quelques stratégies de geek pour se passer de la souris.

1. Se procurer un iPad

OK mais ça ne répond pas à la question ! Je veux continuer à utiliser mon vieux matos (réponse aka je n'aurai jamais le blé).

2. Repasser à Firefox

Firefox propose des facilités assez sympa pour se passer de souris. Rapidement :
  • Le single quote (') vous permet de rechercher parmi les lien d'une page. F3 passe au lien suivant, Shift + F3 au lien précédent. Les liens mis en surbrillance sont suivis en tapant sur Return.
  • Vous pouvez vous mettre en mode curseur avec la touche F7, ce qui vous permet de naviguer dans la page caractère par caractère et de faire des sélections plus précises.
  • Pour les malades de Vim, vous avez l'extension Pentadactyl (successeur de Vimperator) pour vimiser votre pandat roux. À vous de voir. Moi ça me gonfle à la longue.

3. Utiliser AwesomeWM

Attention, là on passe en mode Jacky. AwesomeWM est un gestionnaire de fenêtre pour Linux qui propose de réaliser un maximum d'interactions sur les fenêtre à l'aide du clavier. Les différentes fenêtres sont organisables via des configurations prédéfinies à l'aide de la combinaison Mod4 + Espace (Mod4, c'est la touche windows de votre clavier). En cas de stress important, Mod4 + Return ouvre un terminal. Ouf.
Pour finir, sachez que l'envrionnement est configurable à l'extrême. Évidemment, la configuration se fait dans un langage laaaaaargement utilisé : lua.
Un autre gestionnaire existe sur le même concept : i3wm. Je ne l'ai pas testé à cause d'un obscur problème de dépendance lorsque j'ai voulu le compiler (il n'est pas disponible sur Debian Squeeze).

4. Utiliser Vim en mode terminal

Ouais là ça le fait. Lâchez Notepad++ et passez à gVim. Puis lachez gVim quand vous vous êtes aperçu que votre souris est recouverte d'une fine pélicule de poussière pour passer à Vim. Respirez : vous êtes bien, tout est sous contrôle.
Petite astuce lorsque vous utilisez Vim : vous pouvez le mettre en arrière plan en faisant Ctrl + Z. Remontez le en tapant fg dans votre terminal.

5. Utiliser un multiplexeur de terminal

Tmux est un multiplexeur de terminal. Il vous permet d'ouvrir plusieurs sous-fenêtres, de splitter votre écran, de naviger dans le terminal pour en copier des parties. C'est un peu le successeur de GNU Screen... Comble de bon gout, ses derniers empèchent le système de killer vos process lors d'une déconnexion. Il est possible de détacher des sessions en cours pour les rattacher plus tard (assez génial quand vous avez lancé des traitements sur un serveur et que vous voulez les laisser tourner la nuit et vous déconnecter pour rentrer chez vous). Autre point sympa, ils vous permettent de partager l'environnement entre toutes les fenêtres (ceux qui utilisent ssh-agent apprécierons).
Contrairement à Tmux, Screen est disponible dans Cygwin.

6. Mutt pour lire les mails

Quelque-chose que je déteste de plus en plus : les clients mail classiques vous récupèrent les mails tous les X minutes par défaut. C'est chiant. Mutt ne rapatrie les messages que quand je lui demande. Ah et c'est un client mail en mode terminal. Ses dernières versions intègrent l'IMAP et peuvent fonctionner avec Gmail.
J'en chie un peu pour mémoriser ses raccourcis clavier (un peu comme avec AwesomeWM), mais globalement c'est de la bonne came. Utilisez-ça et vous détesterez les indélicats qui vous envoient des mails au format HTML ;).

7. C'est tout pour aujourd'hui

J'espère que cet article sur l'outillage ultramoderne de l'informaticien vous a plus et donné envie de tester quelques uns de ces outils. En attendant, je vous permet d'utiliser votre souris.

dimanche 17 février 2013

Make, ou de la pilosité faciale.

Je suis passé sur Windows 7 sur mon laptop de travail, entrant ainsi dans l'ère de la modernité. Cette réinstallation m'a poussé à repenser ou rationaliser ma boite à outils. Je suis revenu aux fondamentaux : Cygwin, vim en mode texte, openssh... et make.

Car oui, je commence à utiliser ce bon vieux (GNU) make pour tout et n'importe quoi... Peut-être que certains d'entre vous ne connaissent pas, ou peu, ce monument du monde Unix alors ça me fait une belle occasion de blogguer.

À la base, make est utilisé pour lancer un ensemble de commandes. Toutefois attention : on ne veut pas que ces commandes soient lancées inutilement. Si des commandes sont censées produire un fichier cible à partir de fichiers sources, comme par exemple un exécutable à partir des sources, on ne va pas regénérer la cible si celle-ci est plus récente que les sources : il n'y a pas de raison de dépencer du CPU pour ça. C'est toute la beauté de make : il cherche à en faire le moins possible !

Les présentations sont faites, décrivons à présent le fonctionnement de make. Make utilise un fichier décrivant les actions à réaliser (on appelle ça des règles dans le jargons des barbus). Traditionnellement, on utilise un fichier nommé Makefile, qui a la bonne idée d'être automatiquement analysé lorsque la commande make est lancée. Dans ce fichier Makefile, les règles sont organisées de la façon suivante :

cible: dépendance
<tab>commande1
<tab>commande2
<tab>...

<tab> représente ici un caractère tabulation. Pas 4 espaces les gars, un bon gros tab, alors attention à vos éditeurs...

Bref, un exemple de la vraie vie pour compiler un .c super compliqué et closed source.

hello: hello.c
    gcc -o hello hello.c

Lorsque vous lancez make avec ça dans un Makefile, l'outil va vérifier que hello.c a une date de modification plus récente que hello et va lancer gcc si c'est le cas. Dans le cas contraire, il vous dira qu'il n'a rien à faire. Il ne perd pas son temps. Et vous non plus.

Vous pouvez également faire des actions en cascade comme dans l'inutile exemple ci-dessous :

hello: hello.o
    gcc -o hello hello.o

hello.o: hello.c
    gcc -c hello.c

Ci-dessus, hello dépend de hello.o. Alors il va chercher à construire hello.o. Quelle chance : il y a une règle qui fait ça à partir de hello.c. Il génère donc le .o puis notre bel exécutable.

Dernière chose, quand vous lancez make sans lui spécifier de cible, il va prendre la première règle de fichier. C'est tout.

Il s'agit d'un exemple de base : l'outil possède plein de petites subtilités desquelles vous pourrez vous délecter en lisant le putain de manuel. Genre :

  • Utiliser des variables
  • Réutiliser des variables du shell
  • Donner n'importe quoi comme nom de cible (pas forcément un nom de fichier, comme all ou clean)
  • Utiliser des racourcis crypto cabalistiques de barbus pour définir vos règles, comme *.o:*.c, $@, $^,...

(ça ne sert à rien de faire ce listing car vous êtes déjà devant le man make ;  c'est juste pour montrer que je ne suis pas un n00b de base, que je connais quelques trick. Ha ha, vous rigolez moins les barbus, hein ?)

Cette semaine, je n'ai pas du tout utilisé le bousin pour faire de la compilation mais simplement pour envoyer des fichiers shell (de merde) sur le serveur en utilisant scp. Pour que ça ne prenne pas trop de temps, je me suis démerdé pour que make n'envoie que les fichiers qui ont été modifiés. Trop dur, ça donne ça :

# ici, c'est la première règle : elle dépend de toutes les règles que je veux
# lancer. Belle astuce.
all: .fichier1.tmp .fichier2.tmp

.fichier1.tmp: fichier1
    scp fichier1 user@server:/repertoire/destination
    @touch .fichier1.tmp

.fichier2.tmp: fichier2
    scp fichier2 user@server:/repertoire/destination
    @touch .fichier2.tmp

Plus qu'à lancer la commande :make dans vim qui a le bon gout de lancer make par défaut, et là je me relaxe... Pendant que j'y pense, j'aurai pu bricoler un script de test à lancer derrière...

Il y a besoin d'explication ? On fait un touch sur un fichier temporaire si le scp réussi (si une commande plante -retourne autre chose que 0-, make arrète son exécution). Et oui les enfant, touch ne sert pas qu'à créer les fichiers, il met aussi à jour la date de modification des fichiers existants.

Plus d'infos sur make :

jeudi 3 janvier 2013

Mercurial, le DVCS à l'esprit KISS

Ça c'est du SEO, sérieux !

Git par ci, Github par là... on ne parle que de Git dirait-on ! Toutefois croyez-moi, des alternatives existent.

Mercurial en est une. Ce DVCS écrit en Python m'a étonné par la simplicité de son interface.

romain@lilibox:~/tmp$ hg
Mercurial, système de gestion de sources distribué

commandes de base :

add        add the specified files on the next commit
annotate   show changeset information by line for each file
clone      make a copy of an existing repository
commit     commit the specified files or all outstanding changes
diff       diff repository (or selected files)
export     dump the header and diffs for one or more changesets
forget     forget the specified files on the next commit
init       create a new repository in the given directory
log        show revision history of entire repository or files
merge      merge working directory with another revision
pull       pull changes from the specified source
push       push changes to the specified destination
remove     remove the specified files on the next commit
serve      start stand-alone webserver
status     show changed files in the working directory
summary    summarize working directory state
update     update working directory (or switch revisions)

utiliser "hg help" pour la liste complète des commandes ou "hg -v" pour plus de détails

17 commandes. OK, Git en affiche 21, ce n'est pas flagrant. Mais on retrouve un peu l'esprit Python quelque part.

Voici un exemple d'utilisation (qui suppose que vous avez déjà installé mercurial et configuré votre .hgrc... c'est le plus dur, c'est pourquoi ce n'est pas décrit dans la note !)

Créons un répertoire projet avec un fichier blabla.markdown dedans.

romain@lilibox:~/tmp$ mkdir hermes_project
romain@lilibox:~/tmp$ cat > hermes_project/blabla.markdown
hello you

Initialisons un dépot Mercurial dedans.

romain@lilibox:~/tmp$ cd hermes_project/
romain@lilibox:~/tmp/hermes_project$ hg init

Ajoutons notre fichier.

romain@lilibox:~/tmp/hermes_project$ hg add blabla.markdown

On contrôle que tout semble fonctionner.

romain@lilibox:~/tmp/hermes_project$ hg status
A blabla.markdown

On a A comme added. Oui, c'est sobre... On peut faire notre premier commit.

romain@lilibox:~/tmp/hermes_project$ hg commit -m "initialisation"

On vérifie l'état de notre dépôt avec la commande log :

romain@lilibox:~/tmp/hermes_project$ hg log
changeset:   0:8b1b093873ca
tag:         tip
user:        Romain TOUZE <romain.touze@exemple.com>
date:        Wed Jan 02 23:04:03 2013 +0100
summary:     initialisation

On peut cloner le dépôt pour faire nos développement isolément ailleurs sur le disque ou sur le réseau.

romain@lilibox:~/tmp/hermes_project$ cd ..
romain@lilibox:~/tmp$ hg clone hermes_project hermes_project_clone
updating to branch default
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
romain@lilibox:~/tmp$ ls
hermes_project  hermes_project_clone  hermes_projectls
romain@lilibox:~/tmp$ rmdir hermes_projectls/

Vérifions que le clone fonctionne.

romain@lilibox:~/tmp$ cd hermes_project_clone/
romain@lilibox:~/tmp/hermes_project_clone$ ls
blabla.markdown
romain@lilibox:~/tmp/hermes_project_clone$ hg log
changeset:   0:8b1b093873ca
tag:         tip
user:        Romain TOUZE <romain.touze@exemple.com>
date:        Wed Jan 02 23:04:03 2013 +0100
summary:     initialisation

On fait alors une modification dans le fichier.

romain@lilibox:~/tmp/hermes_project_clone$ echo "Modif importante" >> blabla.markdown 
romain@lilibox:~/tmp/hermes_project_clone$ hg status
M blabla.markdown

On fait notre commit. Celui apparait bien dans le journal.

romain@lilibox:~/tmp/hermes_project_clone$ hg commit -m "ouh là là, j'ai bien travaillé"
romain@lilibox:~/tmp/hermes_project_clone$ hg log
changeset:   1:b4a72dc79003
tag:         tip
user:        Romain TOUZE <romain.touze@exemple.com>
date:        Wed Jan 02 23:11:09 2013 +0100
summary:     ouh là là, j'ai bien travaillé

changeset:   0:8b1b093873ca
user:        Romain TOUZE <romain.touze@exemple.com>
date:        Wed Jan 02 23:04:03 2013 +0100
summary:     initialisation

Retournons à présent à notre projet initial. On aimerait bien récupérer les informations de notre branche.

romain@lilibox:~/tmp/hermes_project_clone$ cd ../hermes_project
romain@lilibox:~/tmp/hermes_project$ hg pull ../hermes_project_clone/
pulling from ../hermes_project_clone/
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
(run 'hg update' to get a working copy)

Pour l'instant, les modifications ne sont pas appliquées au dépôt hermes_project.

romain@lilibox:~/tmp/hermes_project$ cat blabla.markdown 
hello you

Bah ouais, c'est écrit qu'il faut lancer une nouvelle commande...

romain@lilibox:~/tmp/hermes_project$ hg update
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
romain@lilibox:~/tmp/hermes_project$ cat blabla.markdown 
hello you
Modif importante

Pas besoin de faire un commit, tout est déjà là.

romain@lilibox:~/tmp/hermes_project$ hg log
changeset:   1:b4a72dc79003
tag:         tip
user:        Romain TOUZE <romain.touze@exemple.com>
date:        Wed Jan 02 23:11:09 2013 +0100
summary:     ouh là là, j'ai bien travaillé

changeset:   0:8b1b093873ca
user:        Romain TOUZE <romain.touze@exemple.com>
date:        Wed Jan 02 23:04:03 2013 +0100
summary:     initialisation

Soyons un peu foufous et codons un conflit dans nos fichiers.

romain@lilibox:~/tmp/hermes_project$ echo "modif branche 1" >> blabla.markdown 
romain@lilibox:~/tmp/hermes_project$ cd ../hermes_project_clone/
romain@lilibox:~/tmp/hermes_project_clone$ echo "modif speciale branche 2" >> blabla.markdown 
romain@lilibox:~/tmp/hermes_project_clone$ hg commit -m "commit sur branche 2"
romain@lilibox:~/tmp/hermes_project_clone$ cd ../hermes_project
romain@lilibox:~/tmp/hermes_project$ hg commit -m "commit sur branche 1"
romain@lilibox:~/tmp/hermes_project$ hg log
changeset:   2:cdfeb308599a
tag:         tip
user:        Romain TOUZE <romain.touze@exemple.com>
date:        Wed Jan 02 23:24:28 2013 +0100
summary:     commit sur branche 1

changeset:   1:b4a72dc79003
user:        Romain TOUZE <romain.touze@exemple.com>
date:        Wed Jan 02 23:11:09 2013 +0100
summary:     ouh là là, j'ai bien travaillé

changeset:   0:8b1b093873ca
user:        Romain TOUZE <romain.touze@exemple.com>
date:        Wed Jan 02 23:04:03 2013 +0100
summary:     initialisation

romain@lilibox:~/tmp/hermes_project$ cd ../hermes_project_clone/
romain@lilibox:~/tmp/hermes_project_clone$ hg log
changeset:   2:4787e4dc850c
tag:         tip
user:        Romain TOUZE <romain.touze@exemple.com>
date:        Wed Jan 02 23:24:16 2013 +0100
summary:     commit sur branche 2

changeset:   1:b4a72dc79003
user:        Romain TOUZE <romain.touze@exemple.com>
date:        Wed Jan 02 23:11:09 2013 +0100
summary:     ouh là là, j'ai bien travaillé

changeset:   0:8b1b093873ca
user:        Romain TOUZE <romain.touze@exemple.com>
date:        Wed Jan 02 23:04:03 2013 +0100
summary:     initialisation

Sur le pull, ça coince

romain@lilibox:~/tmp/hermes_project_clone$ cd ../hermes_project
romain@lilibox:~/tmp/hermes_project$ hg pull ../hermes_project_clone/
pulling from ../hermes_project_clone/
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
(run 'hg heads' to see heads, 'hg merge' to merge)

La commande hg heads nous dit que nous avons un nouveau changeset :

romain@lilibox:~/tmp/hermes_project$ hg heads
changeset:   3:4787e4dc850c
tag:         tip
parent:      1:b4a72dc79003
user:        Romain TOUZE <romain.touze@exemple.com>
date:        Wed Jan 02 23:24:16 2013 +0100
summary:     commit sur branche 2

changeset:   2:cdfeb308599a
user:        Romain TOUZE <romain.touze@exemple.com>
date:        Wed Jan 02 23:24:28 2013 +0100
summary:     commit sur branche 1

Fusionnons tout ça :

romain@lilibox:~/tmp/hermes_project$ hg merge

À ce moment là, hg m'ouvre vim pour que j'édite le conflit. Je garde le contenu ci-dessous :

hello you
Modif importante
modif branche 1
modif speciale branche 2

Mercurial me dit ça :

0 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
romain@lilibox:~/tmp/hermes_project$ cat blabla.markdown 
hello you
Modif importante
modif branche 1
modif speciale branche 2

Très bien, je commite et tout est OK.

romain@lilibox:~/tmp/hermes_project$ hg commit -m "un conflit de canard"
romain@lilibox:~/tmp/hermes_project$ hg log
changeset:   4:2c0cad92cac3
tag:         tip
parent:      2:cdfeb308599a
parent:      3:4787e4dc850c
user:        Romain TOUZE <romain.touze@exemple.com>
date:        Wed Jan 02 23:30:17 2013 +0100
summary:     un conflit de canard

changeset:   3:4787e4dc850c
parent:      1:b4a72dc79003
user:        Romain TOUZE <romain.touze@exemple.com>
date:        Wed Jan 02 23:24:16 2013 +0100
summary:     commit sur branche 2

changeset:   2:cdfeb308599a
user:        Romain TOUZE <romain.touze@exemple.com>
date:        Wed Jan 02 23:24:28 2013 +0100
summary:     commit sur branche 1

changeset:   1:b4a72dc79003
user:        Romain TOUZE <romain.touze@exemple.com>
date:        Wed Jan 02 23:11:09 2013 +0100
summary:     ouh là là, j'ai bien travaillé

changeset:   0:8b1b093873ca
user:        Romain TOUZE <romain.touze@exemple.com>
date:        Wed Jan 02 23:04:03 2013 +0100
summary:     initialisation

Vous pouvez également créer une branche in place :

romain@lilibox:~/tmp/hermes_project$ hg branch test
marked working directory as branch test
romain@lilibox:~/tmp/hermes_project$ hg commit -m "branch test"

La branche est créée :

romain@lilibox:~/tmp/hermes_project$ hg log
changeset:   5:b707281d46fc
branch:      test
tag:         tip
user:        Romain TOUZE <romain.touze@exemple.com>
date:        Wed Jan 02 23:49:17 2013 +0100
summary:     branch test

changeset:   4:2c0cad92cac3
parent:      2:cdfeb308599a
parent:      3:4787e4dc850c
user:        Romain TOUZE <romain.touze@exemple.com>
date:        Wed Jan 02 23:30:17 2013 +0100
summary:     un conflit de canard

On ajoute des trucs dans notre fichier :

romain@lilibox:~/tmp/hermes_project$ echo "more" >> blabla.markdown 
romain@lilibox:~/tmp/hermes_project$ hg status
M blabla.markdown
romain@lilibox:~/tmp/hermes_project$ hg commit -m "More on the named branch"
romain@lilibox:~/tmp/hermes_project$ hg log
changeset:   6:94594bfe9c50
branch:      test
tag:         tip
user:        Romain TOUZE <romain.touze@exemple.com>
date:        Wed Jan 02 23:50:20 2013 +0100
summary:     More on the named branch

changeset:   5:b707281d46fc
branch:      test
user:        Romain TOUZE <romain.touze@exemple.com>
date:        Wed Jan 02 23:49:17 2013 +0100
summary:     branch test

changeset:   4:2c0cad92cac3
parent:      2:cdfeb308599a
parent:      3:4787e4dc850c
user:        Romain TOUZE <romain.touze@exemple.com>
date:        Wed Jan 02 23:30:17 2013 +0100
summary:     un conflit de canard

On fusionne dans notre branche default :

romain@lilibox:~/tmp/hermes_project$ hg update default
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
romain@lilibox:~/tmp/hermes_project$ hg merge test
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
romain@lilibox:~/tmp/hermes_project$ hg commit -m "merge test branch to default"

Et voilà, c'est magique.

Le moins que l'on puisse dire, c'est que pour l'habitué du DVCS, ce n'est pas trop dépaysant. Il y aura parfois plus, parfois moins de commande à taper.

Pour aller plus loin, suivez le tutorial sur le site officiel.

Ne vous méprenez pas, Mercurial est une application solide et sérieuse. Elle est utilisée notamment pour le service Bitbucket (concurrent de Github) et est également utilisé par ce petit projet.

PS 1 : pour les ignares, Hg est évidemment le symbole du Mercure, comme je l'ai appris lors de ma première colle de chimie (Z = 80 les enfants !)
PS 2 : une dernière fonctionnalité pour la route :

romain@lilibox:~/tmp/hermes_project$ hg serve
listening at http://lilibox.workgroup:8000/ (bound to *:8000)

Et hop, votre dépôt se trouve accessible via une superbe interface web sur le port 8000. Cool, non ?

dimanche 28 octobre 2012

Avec TMUX, on respire

J'ai installé Tmux sur mon serveur de dev au boulot. Comme son nom l'indique presque, il s'agit d'un multiplexeur de terminal, comme GNU screen mais en plus vivant. Dans une session Tmux, vous pouvez splitter votre écran, ouvrir plusieurs fenêtres. Vous pouvez naviguer dans l'historique, faire du copier coller. Mieux, vous pouvez détacher votre session pour la reprendre plus tard.

Le plus beau est que la session reste ouverte en cas de déconnexion. Vous vous reconnectez, vous faites un tmux attach et là c'est cool : vous retrouvez tout ! Fini les cris dans l'openspace parce que vous vous êtes déco pour partir en réunion alors que vous aviez un traitement de 6 heures en cours. Fini le stress que la dame de ménage débranche l'ordi pour brancher son aspirateur lorsque vous lancez un traitement pendant la nuit !

Derniers trucs :

  • j'ai eu un souci sur Solaris pour lancer vi (le classique, pas le improuvède). Il se trouve que Tmux valorise la variable TERM à screen, ce qui perturbe un peu vi. Un export TERM=xterm avant de lancer vi règle le problème.
  • Si vous voulez facilement avoir les bindings vi dans le copy-mode de Tmux, faites un export EDITOR=vi avant de lancer votre session. Il y a aussi une option qu'on peut lui passer après le lancement, mais elle est compliquée à mémoriser.
  • Si vous n'avez pas tmux ni de quoi télécharger des binaires ou compiler des sources et que vous devez lancer un traitement long, pensez quand même au bon vieux nohup qui en cas de déconnexion de votre client, rattachera le process au PID 1 qui normalement ne peut pas se déconnecter, lui :).
Site officiel de tmux (oui, c'est moche)

mercredi 1 août 2012

Pas d'iPad mais IPython (c'est mieux !)

Pas d'iPad mais IPython

Une des qualités de Python est de proposer une aide contextuelle en affichant des docstrings de n'importe quel objet grâce à la fonction help. Vous pouvez également lister le contenu d'un module ou d'une classe grâce à la fonction dir.

Il y toutefois des possibilités d'amélioration de l'interpréteur. En effet, un peu de complétion de code est un accès plus simple à l'aide serait intéressant.

C'est ici qu'intervient IPython (Interactive Python). Cet interpréteur amélioré propose notamment :

  • la complétion de code avec Tab
  • l'accès à l'aide en tapant object.methode?
  • tout un tas de commandes magiques, permettant des alias pour beaucoup de fonctionnalités (ex : commande shell, multiprocessing,...)

Le projet propose également des interfaces Qt de web pour faire de l'affichage graphique. Vous pouvez également le lancer en mode serveur pour accéder à votre runtime python à distance.

Vous pouvez installer IPython par les moyens habituels (aptitude, easy_install, pip,...).

Personnellement, même s'il est plus long à se lancer, j'aime bien l'avoir sous la main pour accéder à l'aide facilement. J'imagine que je vais avoir de plus en plus d'usage de ce truc !

La page du projet : http://ipython.org/.