Homebrew formulae for Mutt with sidebar and trash patches

2016-03-15  |   |  Mac OS X   tool  

Homebrew's Mutt formulae is in a bit of a disarray. I can't blame them as Mutt has a bunch of not quite maintained patches not quite fully compatible with one another.

The problem is that some of these patches are very very useful. I have created a tap to maintain Mutt with the two key patches I use:

  • sidebar
  • trash

At the time of writing, it uses Mutt 1.5.24 but I might update it. To use the formulae, do:

brew tap emmanuelbernard/mutt
brew install emmanuelbernard/mutt/mutt

// or alternatively

brew install https://raw.githubusercontent.com/emmanuelbernard/homebrew-mutt/master/Formula/mutt.rb

I personally build them with the following options

brew install emmanuelbernard/mutt/mutt --with-sidebar-patch --with-trash-patch --with-gpgme --with-s-lang

s-lang supposedly has better support for color schemes like Solarized.

You can find the code at https://github.com/emmanuelbernard/homebrew-mutt.


Asciidoc folding for Vim

2016-02-11  |   |  tool  

I just learned about the ability to fold in Vim. For mere mortals, it means hiding parts of the file.

Here is a code to put in your .vimrc to allow folding for Asciidoc(tor) files. It folds asciidoc files at section boundaries and use nested folds for subsections.

"" Fold Asciidoc files at sections and using nested folds for subsections
" compute the folding level
function! AsciidocLevel()
    if getline(v:lnum) =~ '^== .*$'
        return ">1"
    endif
    if getline(v:lnum) =~ '^=== .*$'
        return ">2"
    endif
    if getline(v:lnum) =~ '^==== .*$'
        return ">3"
    endif
    if getline(v:lnum) =~ '^===== .*$'
        return ">4"
    endif
    if getline(v:lnum) =~ '^====== .*$'
        return ">5"
    endif
    if getline(v:lnum) =~ '^======= .*$'
        return ">6"
    endif
    return "="
endfunction
" run the folding level method when asciidoc is here
autocmd Syntax asciidoc setlocal foldexpr=AsciidocLevel()
" enable folding method: expression on asciidoc
autocmd Syntax asciidoc setlocal foldmethod=expr
" start with text unfolded all the way
autocmd BufRead *.adoc normal zR
autocmd BufRead *.asciidoc normal zR
" TODO following does not work as folding is lost up reloading
" autocmd Syntax asciidoc normal zR

I'm sure it can be improved - I'd love to fold blocks as well - but that's a start.

Here are a few commands to remember to fold in Vim

  • zo: open a fold at cursor
  • zO: open all folds down at cursor
  • zc: close a fold at cursor
  • zC: close all levels of folds at cursor
  • za: / zA: toggle fold
  • zm: close fold by one level across the file
  • zM: close all folds across the file
  • zr: open fold by one level across the file
  • zR: open all folds across the file
  • zj / zk: move to next / previous fold
  • [z / ]z: go to begining / end of the fold

Happy folding.


Adding color to Maven output

2015-07-27  |   |  tool  

Maven is quite verbose. Finding the useful information when the test fails requires you to squint eyes. Unless, you bring some coloring to the massive Maven output.

The state of color output in Maven is still quite messy. Just look at Arnaud's blog to see how non user friendly that is.

Enter maven-color

Enter Jean-Christophe and its Maven Color project. The goal is to bring colorized maven console in an easy and cross platform way.

It's relatively easy to install (check the README), and is even easier on Mac OS X

brew tap jcgay/jcgay
brew install maven-deluxe

From there you might need to unlink your brew maven install.

Usually, you are done. Well, not if like me you use CheckStyle.

SLF4J beam crossing

Unfortunately for me, it was failing on Hibernate OGM. The problem is that the CheckStyle plugin is compiled with the Maven 2.x version of SLF4J aka an old one.

This leads to funky errors like - in color mind you:

------------------------------------------------------------------------
Failed to execute goal org.apache.maven.plugins:maven-checkstyle-plugin:2.12.1:checkstyle (check-style) on project hibernate-ogm-core: Execution check-style of goal org.apache.maven.plugins:maven-checkstyle-plugin:2.12.1:checkstyle failed: An API incompatibility was encountered while executing org.apache.maven.plugins:maven-checkstyle-plugin:2.12.1:checkstyle: java.lang.NoSuchMethodError: org.slf4j.spi.LocationAwareLogger.log(Lorg/slf4j/Marker;Ljava/lang/String;ILjava/lang/String;Ljava/lang/Throwable;)V
-----------------------------------------------------
realm =    plugin>org.apache.maven.plugins:maven-checkstyle-plugin:2.12.1
strategy = org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy
urls[0] = file:/Users/emmanuel/.m2/repository/org/apache/maven/plugins/maven-checkstyle-plugin/2.12.1/maven-checkstyle-plugin-2.12.1.jar
urls[1] = file:/Users/emmanuel/.m2/repository/org/slf4j/slf4j-jdk14/1.5.6/slf4j-jdk14-1.5.6.jar
urls[2] = file:/Users/emmanuel/.m2/repository/org/slf4j/jcl-over-slf4j/1.5.6/jcl-over-slf4j-1.5.6.jar
urls[3] = file:/Users/emmanuel/.m2/repository/commons-cli/commons-cli/1.2/commons-cli-1.2.jar
urls[4] = file:/Users/emmanuel/.m2/repository/org/codehaus/plexus/plexus-interactivity-api/1.0-alpha-4/plexus-interactivity-api-1.0-alpha-4.jar
urls[5] = file:/Users/emmanuel/.m2/repository/backport-util-concurrent/backport-util-concurrent/3.1/backport-util-concurrent-3.1.jar
urls[6] = file:/Users/emmanuel/.m2/repository/org/sonatype/plexus/plexus-sec-dispatcher/1.3/plexus-sec-dispatcher-1.3.jar
urls[7] = file:/Users/emmanuel/.m2/repository/org/sonatype/plexus/plexus-cipher/1.4/plexus-cipher-1.4.jar
urls[8] = file:/Users/emmanuel/.m2/repository/org/apache/maven/reporting/maven-reporting-api/3.0/maven-reporting-api-3.0.jar
urls[9] = file:/Users/emmanuel/.m2/repository/org/apache/maven/reporting/maven-reporting-impl/2.2/maven-reporting-impl-2.2.jar
urls[10] = file:/Users/emmanuel/.m2/repository/org/apache/maven/doxia/doxia-core/1.2/doxia-core-1.2.jar
urls[11] = file:/Users/emmanuel/.m2/repository/xerces/xercesImpl/2.9.1/xercesImpl-2.9.1.jar
urls[12] = file:/Users/emmanuel/.m2/repository/xml-apis/xml-apis/1.3.04/xml-apis-1.3.04.jar
urls[13] = file:/Users/emmanuel/.m2/repository/org/apache/httpcomponents/httpclient/4.0.2/httpclient-4.0.2.jar
urls[14] = file:/Users/emmanuel/.m2/repository/org/apache/httpcomponents/httpcore/4.0.1/httpcore-4.0.1.jar
urls[15] = file:/Users/emmanuel/.m2/repository/commons-codec/commons-codec/1.3/commons-codec-1.3.jar
urls[16] = file:/Users/emmanuel/.m2/repository/commons-validator/commons-validator/1.3.1/commons-validator-1.3.1.jar
urls[17] = file:/Users/emmanuel/.m2/repository/commons-beanutils/commons-beanutils/1.7.0/commons-beanutils-1.7.0.jar
urls[18] = file:/Users/emmanuel/.m2/repository/commons-digester/commons-digester/1.6/commons-digester-1.6.jar
urls[19] = file:/Users/emmanuel/.m2/repository/commons-logging/commons-logging/1.0.4/commons-logging-1.0.4.jar
urls[20] = file:/Users/emmanuel/.m2/repository/org/apache/maven/doxia/doxia-sink-api/1.4/doxia-sink-api-1.4.jar
urls[21] = file:/Users/emmanuel/.m2/repository/org/apache/maven/doxia/doxia-logging-api/1.4/doxia-logging-api-1.4.jar
urls[22] = file:/Users/emmanuel/.m2/repository/org/apache/maven/doxia/doxia-decoration-model/1.4/doxia-decoration-model-1.4.jar
urls[23] = file:/Users/emmanuel/.m2/repository/org/apache/maven/doxia/doxia-site-renderer/1.4/doxia-site-renderer-1.4.jar
urls[24] = file:/Users/emmanuel/.m2/repository/org/apache/maven/doxia/doxia-module-xhtml/1.4/doxia-module-xhtml-1.4.jar
urls[25] = file:/Users/emmanuel/.m2/repository/org/apache/maven/doxia/doxia-module-fml/1.4/doxia-module-fml-1.4.jar
urls[26] = file:/Users/emmanuel/.m2/repository/org/codehaus/plexus/plexus-i18n/1.0-beta-7/plexus-i18n-1.0-beta-7.jar
urls[27] = file:/Users/emmanuel/.m2/repository/org/apache/velocity/velocity-tools/2.0/velocity-tools-2.0.jar
urls[28] = file:/Users/emmanuel/.m2/repository/commons-chain/commons-chain/1.1/commons-chain-1.1.jar
urls[29] = file:/Users/emmanuel/.m2/repository/dom4j/dom4j/1.1/dom4j-1.1.jar
urls[30] = file:/Users/emmanuel/.m2/repository/sslext/sslext/1.2-0/sslext-1.2-0.jar
urls[31] = file:/Users/emmanuel/.m2/repository/org/apache/struts/struts-core/1.3.8/struts-core-1.3.8.jar
urls[32] = file:/Users/emmanuel/.m2/repository/org/apache/struts/struts-taglib/1.3.8/struts-taglib-1.3.8.jar
urls[33] = file:/Users/emmanuel/.m2/repository/org/apache/struts/struts-tiles/1.3.8/struts-tiles-1.3.8.jar
urls[34] = file:/Users/emmanuel/.m2/repository/org/apache/maven/shared/maven-doxia-tools/1.4/maven-doxia-tools-1.4.jar
urls[35] = file:/Users/emmanuel/.m2/repository/commons-io/commons-io/1.4/commons-io-1.4.jar
urls[36] = file:/Users/emmanuel/.m2/repository/junit/junit/3.8.1/junit-3.8.1.jar
urls[37] = file:/Users/emmanuel/.m2/repository/org/codehaus/plexus/plexus-component-annotations/1.5.5/plexus-component-annotations-1.5.5.jar
urls[38] = file:/Users/emmanuel/.m2/repository/org/codehaus/plexus/plexus-resources/1.0-alpha-7/plexus-resources-1.0-alpha-7.jar
urls[39] = file:/Users/emmanuel/.m2/repository/org/codehaus/plexus/plexus-utils/3.0.15/plexus-utils-3.0.15.jar
urls[40] = file:/Users/emmanuel/.m2/repository/org/codehaus/plexus/plexus-interpolation/1.19/plexus-interpolation-1.19.jar
urls[41] = file:/Users/emmanuel/.m2/repository/org/codehaus/plexus/plexus-velocity/1.1.8/plexus-velocity-1.1.8.jar
urls[42] = file:/Users/emmanuel/.m2/repository/com/puppycrawl/tools/checkstyle/5.7/checkstyle-5.7.jar
urls[43] = file:/Users/emmanuel/.m2/repository/antlr/antlr/2.7.7/antlr-2.7.7.jar
urls[44] = file:/Users/emmanuel/.m2/repository/commons-beanutils/commons-beanutils-core/1.8.3/commons-beanutils-core-1.8.3.jar
urls[45] = file:/Users/emmanuel/.m2/repository/com/google/guava/guava-jdk5/14.0.1/guava-jdk5-14.0.1.jar
urls[46] = file:/Users/emmanuel/.m2/repository/org/apache/velocity/velocity/1.5/velocity-1.5.jar
urls[47] = file:/Users/emmanuel/.m2/repository/commons-lang/commons-lang/2.1/commons-lang-2.1.jar
urls[48] = file:/Users/emmanuel/.m2/repository/oro/oro/2.0.8/oro-2.0.8.jar
urls[49] = file:/Users/emmanuel/.m2/repository/commons-collections/commons-collections/3.2.1/commons-collections-3.2.1.jar
Number of foreign imports: 1
import: Entry[import  from realm ClassRealm[maven.api, parent: null]]

-----------------------------------------------------
-> [Help 1]

There is a relatively easy fix. You can force the SLF4J version of CheckStyle in your plugin dependencies.

<plugin>
    <artifactId>maven-checkstyle-plugin</artifactId>
    <version>2.15</version>
    <dependencies>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>1.7.5</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-jdk14</artifactId>
            <version>1.7.5</version>
        </dependency>
    </dependencies>
</plugin>

Now I can get spanked by CheckStyle in color!

If like me you drawn in Maven outputs, go give a try to Maven Color. And many thanks to Jean-Christophe for his help in solving the CheckStyle of death problem.


Get notified when terminal commands end

2015-03-26  |   |  tool  

Here is a tiny little tool that will speed up the multi-tasking life of terminal users: be notified when a command finishes.

How many times have you started a command in the terminal to realise that it will take a while? How many times did you then move to emails or twitter "in the mean time"? How many times have you forgotten about it and read our twitter feed for 30 minutes aka 25 minutes longer than the actual command?

This small tool solves that problem.

#!/bin/bash
# Notify you when a task is done
#
# $ notify mvn clean install
# runs 'mvn clean install'
# notify you when it's done
#
# A notification is sent upon build completion if your OS supports it:
# - on Mac OS, install Growl and grownnotifier
# - on Linux, install send-notify
#
# Released under the WTFPL license version 2 http://sam.zoy.org/wtfpl/
#
# Copyright (c) 2010 David Gageot
# Copyright (c) 2011 Sanne Grinovero
# Copyright (c) 2010-2015 Emmanuel Bernard

say() {
    if [ `uname -s` == "Darwin" ]; then 
        # On Mac OS, notify via Growl
        which -s growlnotify && growlnotify --name "Command line" --sticky --message "'$CMD_DISPLAY' has finished - $RESULT"
    fi
    if [ `uname -s` == "Linux" ]; then
        # On Linux, notify via notify-send
        which notify-send && notify-send "'$CMD_DISPLAY' has finished" "$RESULT"
    fi
}

if [[ $# -eq 0 ]]; then 
  echo "Usage notify <command to run>"
else
  CMD_DISPLAY="$@"
fi

$@
EXIT_CODE=$?

if [ $EXIT_CODE -eq 0 ]; then
  RESULT="SUCCESS"
  echo $RESULT    
  say
else
  RESULT="FAILURE"
  echo $RESULT
  say
  exit $EXIT_CODE
fi

When you want to monitor the completion of a command, simply prefix it with notify.

# Longish command you will forget about
rake clean publish

# Longish command you will be notified of upon completion
notify rake clean publish

A few things I particularly like:

  • I can decide which command to monitor
  • it reports the status (success or failure)

No more excuse for Twitter or other time sinkers.


Split a commit in two with Git

2014-04-14  |   |  tool   git  

Ever wanted a commit was actually made of two? Read on.

There are several reasons why you could wish a commit was actually made of several distinct ones:

  • because it makes the history more readable
  • because you are trying to reorder some commits and it creates nasty conflicts
  • just because

Merging two commits into one is easy: look for squashing for more info. While I am relatively versed in Git, I never knew how to efficiently do the opposite - splitting commits - until today.

Split a commit in two for the busy ones

Let's see the sequence first before explaining it

git rebase -i <oldsha1>
# mark the expected commit as `edit` (replace pick in front of the line), save a close
git reset HEAD^
git add ...
git commit -m "First part"
git add ...
git commit -m "Second part"
git rebase --continue

What did we do?

A detailed explanation

Interactive rebase

git rebase -i <oldsha1> opens a list of commits from oldsha1 to the latest commit in the branch. You can:

  • reorder them,
  • change the commit message of some,
  • squash (merge) two commits together,
  • and edit a commit.

We use edit in our case as we want to change the commit. Simply replace the pick word with edit on the line of the commit you want to split. When you save and close this "file", you will be placed at that commit in the command line.

Undo the actual commit

If you do a git status or a git diff, you will see that git places you right after the commit. What we want is to undo the commit and place the changes in our working area.

This is what git reset HEAD^ does: reset the state to the second last commit and leave the changes of the last commit in the working area. HEAD^ means the commit at HEAD minus 1.

Create the two commits

Next is simple gittery where you add changes and commit them the way you wish you had.

Finish the interactive rebasing

Make sure to finish the rebase by calling git rebase --continue. Hopefully, there won't be any conflicts and your history will contain the new commits.

A few more tips

This tip becomes much more powerful when you know how to add to the staging area parts of a file changes - instead of all the file changes that is.

The magic tool for that is git add -p myfile but it is quite arid. I recommend you use either GitX (Mac OS X, GUI) or tig (CLI). They offer a more friendly interactive way to add chunks of changes (up to line by line additions).

Another interesting tip for people that work on topic branches forked off master. You can do git rebase -i master which will list the commits between master and your branch. See my previous post on the subject for more info.


Fixing Page Up and Page Down in Mac OS X Terminal.app

2013-12-12  |   |  Mac OS X   tool  

I am currently trying to move from iTerm to Terminal.app.

Terminal.app maps the Page Up/Down action to move around its buffer. This is quite annoying when you use text applications with their own buffer like mutt, vim, weechat etc).

Fortunately, there are two solutions, one easy and one more permanent.

Use Shift + Page Up

The easy one is to use Shift + Page Up instead of Page Up. Page Down works the same. The inconvenient is that you need to train your muscle memory.

Update the Terminal.app mapping

The more permanent one is to change the Terminal.app behavior.

Go in Preferences->Settings, select the right profile and go in the Keyboard tab. Find the Page Up entry and edit it to send text. Then type the ESC key followed by [5~. For good measure, I mapped Shift + Page Up to the Scroll Page Up action.
Do the same for page down with the following text ESC key followed by [6~.

You're all set.


Encrypt your Dropbox or any folder with EncFS on Mac OS X

2013-07-01  |   |  tool  

This entry describes how to install EncFS on Mac OS X with homebew without breaking other tools using osxfuse (like TrueCrypt).

Why EncFS

I have been looking of a smart solution to encrypt a directory file by file. TrueCrypt is an awesome tool but does not play well with backups or Dropbox / Google Drive / SkyDrive like syncing: a TrueCrypt volume appears like a single big file which has to be synced entirely for each tiny change.

I just discovered this week-end EncFS. This is the exact tool I was looking for:

  • encrypts a directory file by file: each file and its name is encrypted
  • when one file is changed, only this encrypted file has to be synced
  • support for each major platform (Windows, Mac OS X, Linux)

I did choose EncFS over eCryptfe for its cross platform support.

Note that some metadata still leak in such system (as opposed to TrueCrypt) but I can happily live with that.

Installing EncFS with homebrew without breaking everything else

It took me far too much experimentation for my taste. Basically EncFS in Homebrew is using fuse4x which is incompatible with osxfuse - the now preferred solution. TrueCrypt - that I still use for disk encryption - happens to be using osxfuse and my attempts to make osxfuse cohabit with fuse4x and TrueCrypt to cohabit with fuse4x failed.

Here is the working solution:

  • install osxfuse via the .dmg install - I did install the MacFUSE compatibility layer for good measure
  • install TrueCrypt (.dmg install)
  • install the EncFS version compatible with osxfuse via brew

The last step requires to use a non standard recipe

brew install https://raw.github.com/jollyjinx/encfs.macosx/master/encfsmacosxfuse.rb

From what I gathered, osxfuse build is too complicated to be made a standard brew recipe. Too bad as I don't like to manage these externalities.

Versions

At the time, we are talking about:

  • Max OS X 10.7.5
  • OSXFUSE 2.5.6
  • EncFS 1.7.4

Using EncFS

Once installed, it is super easy to use

encfs ~/Dropbox/Private.enc/ ~/Private/
# or with a custom volume name
encfs ~/Dropbox/Private.enc/ ~/Private/ -- -o volname="Dropbox private"

mounts the encrypted ~/Dropbox/Private.enc directory as ~/Private/ and under the volume name Dropbox private.

If you add or change files from ~/Private, you will see an encrypted equivalent under ~/Dropbox/Private.enc.

To unmount, simply do

umount ~/Dropbox/Private.enc/

That's it. Happy secure data.

Update:

I was wrong in assuming a few things:

  • Dropbox can do partial sync of a big file, so the whole file is not reuploaded in its entirety. Reference here.
  • TrueCrypt does encrypt by block so changing one file does not change the whole TrueCrypt container file.
  • Mac OS SpaceBundle does roughly like TrueCrypt and split a bundle into files of 8MB each. Reference here.

It remains that encfs is a nice tool but not for the reasons I mentioned :)

Thanks for Renaud and Jekyll for pointing these errors. Bad karma for Jekyll for not resisting the urge to express it like a dick.


Autocompletion is crap

2013-05-28  |   |  java   tool   ide  

I can't believe autocompletion is still so stupid in 2013. Alright, I said it, I feel better. It's actually not quite true and a lot of smart things are going on in Eclipse or IntelliJ IDEA but completion remains incredibly stupid when it comes to discovering an API and offering the most appropriate choice.

It is very important for fluent APIs tailored to offer only the APIs that make sense in a particular context. So when the autocompletion offers you the full monty of useless methods of Object, it kills the hours of work an API designer put into his fluent API and its discoverability. Seriously notify(), notifyAll() and wait() x 3!

I developed, help develop or gave advice on a number of fluent APIs in Java including:

  • Hibernate Search and Hibernate Validator programmatic mapping API,
  • an upcoming Hibernate OGM programmatic configuration API
  • ShrinkWrap API
  • Hibernate Search Query DSL API

So I feel very personally offended when something gets between my work and the end user.

Eclipse

I use Eclipse these days and the sort by relevance works only in so far as relevance is synonymous to alphabetical. In other words it sucks... but in a predictably alphabetical way.

Eclipse autocompletion

IntelliJ IDEA

IntelliJ IDEA is smarter as it puts in bold the methods hosted on the type and leave supertype methods in regular.

IntelliJ IDEA autocompletion

If you dig enough though, you can find a setting

Sort lookup items lexicographically

by opening up preferences and search of autocompletion. Weirdly enough, if you uncheck this box, IntelliJ IDEA does the better thing and put the elements in bold next to each others.

IntelliJ IDEA smarter
autocompletion

And that concludes this half rant, half tip, half call to action to IDE developers. Yes I know but it takes at least 3 halfs for a good cocktail :)


Making the best of Google Authenticator for One Time Passwords

2013-03-26  |   |  apple   tool  

You can't reorder tokens on Google Authenticator nor edit the associated description? Read on.

I use one time passwords everywhere I can. It's a little hassle but increases security by a whole lot. And the good thing is that more and more providers offer this:

  • GMail
  • Google Apps
  • Dropbox
  • Amazon Web Services
  • Your company if they are not too dinosaur-y

Go use one time passwords aka two factor authentication, you will thank me later.

I looked around on iOS and the most well known soft token application that supports both time based and event based tokens is Google Authenticator. Except that Google Authenticator's UI is really crap and buggy.

The edit button does not seem to function properly and nothing happens most of the time. The trick is to go to Legal information then back. You can now press the edit button and voilà! Things work. You can now:

  • reorder the list properly
  • edit the name under each token

That made my life much easier.


Google Drive - the good and the ugly

2013-01-09  |   |  tool  

Google Drive is a bit confusing at first but the Dropbox like feature works reasonably well. They have a desktop client that works pretty much like the Dropbox client and syncs your local directory with the cloud.

This is quite handy when your friends have maxed out their Dropbox quota: Google Drive gives you 5 GB free. Images you store on Google Plus and files you store on Google Drive count against your quota. The Google Drive documents do not though.

Not everything is rosy in the Google Drive land though.

Trash or no trash

Data in your trash is counted as used space. It took me a while to figure that out and I could not get why my free space was lower that it should have. I don't think other services do that.

Bugs

When you delete a non empty directory and then try to remove it from the trash, well nothing happens. Someone has forgotten to write the recursive part of the algorithm :) You have to go in each subdirectory and remove files and empty directories.

Simplistic client and speed

It seems to me that Dropbox syncs faster than Google Drive but I have not properly benched them so that might be subjective.

What is for sure is that the sync up cues on Google Drive are too simplistic. It tells you synchronization happens and that's it. Dropbox tells you how many files are uploaded and downloaded, what is the speed rate for each as well as the estimated time it will take. It's not gimmicky, it shows progress to the user.

Overall, I tend to stick with Dropbox despite the fact that it is twice as expensive per GB.


Name: Emmanuel Bernard
Bio tags: French, Open Source actor, Hibernate, (No)SQL, JCP, JBoss, Snowboard, Economy
Employer: JBoss by Red Hat
Resume: LinkedIn
Team blog: in.relation.to
Personal blog: No relation to
Microblog: Twitter, Google+
Geoloc: Paris, France

Tags