Introduction
Je suis un utilisateur Linux depuis plus de 10 ans. Je fis mes premiers pas avec une distribution Slackware, à une époque ou les gestionnaires de fenêtres étaient encore hésitants. Après un retour sous Windows XP pendant 2 ans, je changeai a nouveau pour Fedora Core (devenu Fedora), puis Mandriva. Enfin, je passai à Ubuntu depuis mon arrivée au Japon, que j'utilise toujours à ce jour. Malgré multiple essais, je n'ai jamais vraiment réussi à utiliser Windows ou Mac OS pour le développement.
Que ce soit dans le cadre privé ou professionnel, l'installation est toujours l'étape laborieuse et répétitive;
réinstallation des mêmes logiciels, réédition des mêmes fichiers de configuration sous /home/<user>
...
Le besoin de centralisation se faisant sentir de plus en plus, la sortie du service de cloud storage Canonical,
"Ubuntu One", fut l'occasion pour moi de m'atteler à cette tâche.
Je vais donc présenter ici la façon dont je configure une installation tout fraîche en 3 étapes.
Je maintiens un répertoire home-env
à la racine de mon compte Ubuntu One en dessous duquel je place tous les fichiers nécessaires.
I ) Installation de vim
et des plugins
D'une manière générale, je suis partisan du minimalisme, que ce soit mon gestionnaire de fenêtre (bureau vierge, nombre d'icones de raccourcis réduit à 3-4 applications) ou les langages de programmation (Scheme & Python); il en va de même pour le choix de l'IDE.
Excepté le développement pour Android, j'utilise exclusivement vim
.
Il est donc tout naturel que l'une des premières commandes soit :
$ sudo apt-get install vim
J'installe également certains plugins vi sur toutes mes machines servant au développement.
Tous les plugins sont disponibles sur internet très facilement, mais pour ceux que j'installe systématiquement,
je les ai sauvegardés sur Ubuntu One sous home-env
, en gardant la même hiérarchie système :
$ home-env/vim/plugin , home-env/vim/doc , home-env/vim/after/ftplugin
Les plugins que je garde toujours sous le coude sont les suivants :
- fugitive [1] : intégration de
git
dansvim
- camelcasemotion [2] : Support de commandes permettant d'effacer/changer une partie du mot écrit en camel case, utilisant la majuscule comme séparateur.
- pydiction [3] : auto completion pour Python.
II ) Création des fichiers de configuration vi , git et bash
Ja garde chaque fichier de configuration sous un nom différent du nom système, sous la forme conf-file.<username> (sans le [.] au début du fichier).
E.g., .vimrc
devient vimrc.<username>
Selon le type de fichier de conf., je rajoute une commande permettant d'exécuter les .<username>
dans le fichier de conf. correspondant :
.vimrc
$ echo "source ~/Ubuntu\ One/home-env/vimrc.<username>" >> .vimrc
.bashrc
$ echo ". ~/Ubuntu\ One/home-env/bashrc.<username>" >> ~/.bashrc
.gitconfig
La version actuelle de git
(1.7.9.x sur mon Ubuntu 12.04) ne permet malheureusement pas l'inclusion de fichiers de configuration externes via une syntaxe particulière.
La solution que j'utilise actuellement est de créer un lien symbolique :
$ ln -s ~/Ubuntu\ One/home-env/gitconfig.<username> ~/.gitconfig
Note: 1.7.10 [4] devrait permettre ce type d'inclusion externe avec une définition du type :
[include]
path = <path>/gitconfig.<username>
En procédant de cette manière, lorsque j'apporte une modification dans un fichier de configuration sur une machine, les changements sont automatiquement uploadés, puis mis à jour sur mes autres machines.
Voici le contenu de mes fichiers de configuration :
vimrc.<username>
syntax on
set sm
set nu
set sc
set is
set hlsearch
set nosi
set bs=2
set ts=4
set winminheight=0
let mapleader = ","
filetype plugin on
imap <Nul> <Space>
map <Nul> <Nop>
vmap <Nul> <Nop>
cmap <Nul> <Nop>
nmap <Nul> <Nop>
highlight Error ctermbg=red
highlight LeadingTabs ctermfg=lightgrey ctermbg=darkgrey
highlight TrailingWS ctermbg=lightgrey ctermfg=darkgrey
autocmd BufNewFile,BufRead *.sql set filetype=mysql
autocmd BufNewFile,BufRead *.html set filetype=php
autocmd FileType php set et ts=4 sw=4
autocmd FileType python set setlocal expandtab tabstop=4 shiftwidth=4
autocmd BufNewFile,BufRead * let m=matchadd('LeadingTabs', '^\t\+', -1)
autocmd BufNewFile,BufRead * let m2=matchadd('Error', '\%>120v', -1)
autocmd InsertEnter * match TrailingWS /\s\+\%#\@<!$/
autocmd InsertLeave * match TrailingWS /\s\+$/
map <silent> W <Plug>CamelCaseMotion_w
map <silent> B <Plug>CamelCaseMotion_b
map <silent> E <Plug>CamelCaseMotion_e
"clearing highlighted search
nmap <silent> <leader>/ :nohlsearch<CR>
" visual shifting (does not exit Visual mode)
vnoremap < <gv
vnoremap > >gv
let g:pydiction_location = '~/.vim/after/ftplugin/.dict/complete-dict'
let g:pydiction_menu_height = 10
" Opening file only
match TrailingWS /\s\+$/
" backup to /tmp
set backup
set backupdir=~/tmp/vim/bak
set backupskip=~/tmp/vim/bak/*
set directory=~/tmp/vim/swap
set writebackup
set laststatus=2
" Broken down into easily includeable segments
set statusline=%<%f\ " Filename
set statusline+=%w%h%m%r " Options
set statusline+=%{fugitive#statusline()} " Git Hotness
set statusline+=\ [%{&ff}/%Y] " filetype
set statusline+=\ [%{getcwd()}] " current dir
set statusline+=\ [A=\%03.3b/H=\%02.2B] " ASCII / Hexadecimal value of char
set statusline+=%=%-14.(%l,%c%V%)\ %p%% " Right aligned file nav info
Quelques détails :
Je surbrille en gris les tabulations. Que ce soit PHP, Python ou n'importe quel autre langage, j'utilise toujours l'espace pour l'indentation. Cela me permet de déceler les endroits où mon code ne respecte pas cette convention. Cela permet accessoirement de détecter les lignes vides composées uniquement de tabulations.
highlight LeadingTabs ctermfg=lightgrey ctermbg=darkgrey autocmd BufNewFile,BufRead * let m=matchadd('LeadingTabs', '^\t\+', -1)
Je colore en rouge toute ligne dépassant 120 caractères (j'avais mis 80 jusqu'à peu mais je me suis dit qu'on n'était plus en 1970). Bien qu'on ne soit plus à l'époque des cartes perforées, origine de la limite à 80 colonnes (et accessoirement une contrainte forte en Cobol), j'estime qu'il est préférable de limiter la longueur de chaque ligne de code afin de le garder lisible. Au pire, je divise le code en plusieurs lignes. Voici la commande associée :
highlight Error ctermbg=red autocmd BufNewFile,BufRead * let m2=matchadd('Error', '\%>120v', -1)
Je surbrille en gris les espaces (ou tabulations) en fin de ligne; ceci est une raison purement esthétique et aussi pour garder une cohérence dans le code source. Je n'active la coloration qu'en sortant du mode édition ou après un retour à la ligne pour éviter que la subrillance aparaisse après chaque insertion d'un espace dans une ligne en cours d'édition :
highlight TrailingWS ctermbg=lightgrey ctermfg=darkgrey autocmd InsertEnter * match TrailingWS /\s\+\%#\@<!$/ autocmd InsertLeave * match TrailingWS /\s\+$/
Pour illustrer le tout, voici un échantillon d'un programme Python que j'ai délibérément modifié :
La recherche d'un texte sous
vim
est très facile et puissante, mais en utilisant l'optionhl on
(highlightsearch on
), les résultats de recherche sont surlignés en jaune, qui reste active jusqu'à la recherche suivante, ce qui peut devenir gênant. Avant, j'annulais la recherche en cours avec la commande plutôt maladroite/\\\\\\\\\\\\\\\\\\
Ce qui, au lieu d'annuler le surlignage, effectue une nouvelle recherche sur le texte
\\\\\\\\\
, qui donc indirectement supprime le surlignage. J'ai récemment ajouté la macro suivante :let mapleader = "," nmap <silent> <leader>/ :nohlsearch<CR>
Ce qui me permet dorénavant de réellement supprimer le surlignage automatique en utilisant la commande "
,/
", ce qui est plus propre et rapide.Par défaut,
vim
crée un fichier.swap
dans le même répertoire que le fichier en cours d'édition. En cas de plantage de la console, ou pour diverses raisons, il arrive que le fichier swap ne soit pas effacé ce qui génère un warning lors de la réouverture du fichier sousvim
. Tracer ces fichiers.swap
est fastidieux; de plus, ils encombrent inutilement les répertoires projets. Je préfère une centralisation :set backup set backupdir=~/tmp/vim/bak set backupskip=~/tmp/vim/bak/* set directory=~/tmp/vim/swap set writebackup
J'utilise un répertoire
tmp
local a home afin de ne pas créer de conflits avec un autre utilisateur. Plus embêtant (mais utile) sont les fichiers de backup quevim
crée, avecun tilde (~) rajouté à la fin du nom de fichier (e.g.foo
⇒foo~
,foo.php
⇒foo.php~
). Embêtant car ces fichiers se retrouvent parfois malencontreusement archivés sousgit
ousvn
, n'étant pas cachés par Linux faute de "." en début de fichier. Je ne veux pas désactiver la création des fichiers de backup, c'est pourquoi ces derniers sont aussi centralisés a l'instar des fichiers swap.
bashrc.<username>
GIT_PS1_SHOWDIRTYSTATE=true
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[31m\]$(__git_ps1)\[\033[00m\]\$ '
Ces deux commandes permettent simplement d'activer l'intégration de git
au sein de la console. Le prompt affiche la branche active du projet, et son état (clean, dirty...) si le répertoire actuel pwd
est inclus dans un repository git
.
gitconfig.<username>
[color]
branch = auto
diff = auto
status = auto
[color "branch"]
current = yellow reverse
local = yellow
remote = green
[color "diff"]
meta = yellow bold
frag = magenta bold
old = red bold
new = green bold
[color "status"]
added = yellow
changed = green
untracked = cyan
[alias]
ci = commit
st = status -sb
co = checkout
b = branch
l = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative --decorate
lc = log ORIG_HEAD.. --stat --no-merges
undo = reset --hard
[core]
editor = vim
En grosse partie, configure les couleurs lors de l'affichage dans la console, et les alias pour les commandes fréquemment utilisées.
Pour git status
et git log
-alias st
et l
- je privilégie un affichage compact à celui par défaut :
$ git st
## dev
A foo/src/main.py
M foo/src/utils.py
?? foo/src/libs/rfc3339.py
?? bar/
^^__ Modifié mais non ajouté au stage
|___ Ajouté au stage (ce qui sera envoyé au prochain commit)
Affichage proche de celui de svn
, à la sauce git
.
Pour git log
, voici un extrait d'un projet Android utilisant git
en interne, et git-svn
pour l'intégration avec svn
:
$ git l
(...)
| * 0774882 - Merge branch 'build_03_01' of origin.local:myproject into build_03_01 (4 months ago) <Y M>
| |\
| | * af2188f - Updated demo samples (4 months ago) <Y M>
| | * 116ef0e - Fixed layout of sound tab header (4 months ago) <Y M>
| | * 317856f - Keep screen on (4 months ago) <Y M>
| | * 5fefbb8 - (PROTO_02_14, origin/dev, dev) Added ant build properties file Fixed fast tab switching issue! (try..catch) (4 months ago) <Y M>
| | * 02ee652 - Put car overlay over spot/traffic overlays (4 months ago) <Y M>
* | | f012bad - Updated R.java (4 months ago) <Y M>
* | | 7e63ae9 - Updated demo samples (4 months ago) <Y M>
* | | 91087cb - Fixed layout of sound tab header (4 months ago) <Y M>
* | | e1c2f8b - Focus on first spot/traffic during RadioAutomaton instead of Next Removed commented code from BottombannerAreaFragment (4 months ago) <Y M>
* | | bc2ef04 - Traffic level labels array resource used where needed. => Needed custom Application to allow Application Resources access from TrafficInfo (4 months ago)
* | | 8fb3e51 - Fixed merge (4 months ago) <Y M>
* | | 2fc921a - Tried to improve the fragment tab switching. Removing dependency on executePendingCommits(). Added delayed operations (4 months ago) <Y M>
|/ /
(...)
Cet affichage en plus d'être beaucoup plus compact que celui par défaut, rajoute en plus des informations visuelles sur les différents merge qui ont eu lieu et les branches qui en résultent.
III ) Import de mes clés GPG
J'utilise deux jeux de clés PGP : pour usage personnel et usage professionel. Note : Je ne met PAS mes clés sur mon compte UOne pour des raisons évidentes de sécurité!
J'utilise ma clé PGP pour encrypter les informations de connexion sur les divers serveurs utilisés pour les projets. Il s'agit d'un simple fichier texte qui est encrypté en utilisant l'option ascii-armored :
$ gpg --recipient xxx@yyy -a --encrypt server_info
Un fichier server_info.asc contenant le contenu encrypté. j'efface ensuite le fichier original :
$ rm server_info
Et je peux vérifier le contenu du fichier server_info.asc
en fournissant mon passphrase :
$ gpg --decrypt -a server_info.asc
Afin de pouvoir décrypter les fichiers précédemment encryptés en cas de nouvelle installation, j'exporte ma clé privée GPG avant de réinstaller :
$ gpg --export-secret-key -a > my_private_key
Puis je la réimporte :
$ gpg --import my_private_key
J'utilise deux subkeys : une pour le cryptage, une pour la signature.
Au passage, idéalement j'aimerais avoir ma clé publique inscrite quelque part sur ma carte de visite :
Fingerprint : 0D67 DA34 9989 2211 7EE0 8FFF A7BA 11BA 7A0E A2B8
Conclusion
Je n'inclus pas dans ces étapes l'installation des logiciels restants (php, python, mysql, apache, nginx ...), mais la configuration nécessaire afin de retrouver son petit chez soi en lançant le terminal est facilement automatisable et par conséquent mérite de l'être.
A propos du blogway 777
Cet article fait partie du blog-relai instauré par Kayac pour l'événement "777" relatif au festival Tanabata (七夕). D'ici le 7 Juillet, nous vous invitons à suivre les 4 blogs (ingénieur, designer, directeur, ingénieur front-end), mis à jour quotidiennement sous la forme d'un relai. Le thème est "Les 3 outils sacrés de la création" (San'shu no shin'gi - 三種の神器).
Pour le prochain article, je passe la main au blog designer.