Rolinh

Rolinh' release

Un Dépôt Pour Ses Fichiers De Configuration Et Un Rakefile Pour Les Déployer

J’ai plusieurs articles plutôt conséquents en préparation (un tutoriel sur les Makefile ainsi qu’une explication très détaillée du fonctionnement de l’algorithme RSA avec implémentation en Ruby) mais comme je ne trouve pas vraiment le temps de les finir en ce moment, j’en profite pour publier un petit article.

Un ami m’a demandé aujourd’hui comment je gérais mes fichiers de configuration; ces fameux dotfiles, ou fichiers cachés, présents dans $HOME ou $XDG_CONFIG_HOME. La réponse est simple: via un dépôt git. Oui mais… comment les copier dans $HOME ensuite? Simplement via un script, ou plus exactement un Rakefile qui s’occupe de faire des liens symboliques vers les fichiers de mon dépôt. J’utilisais auparavant un script shell (assez moche d’ailleurs) mais bon, un script shell, même si ça rend parfois bien service, c’est pas beau.

Voici donc la procédure que j’utilise: Lorsque j’ai accès à une nouvelle machine, mon premier réflexe est d’installer mes outils indispensables, comme vim, zsh et git. Une fois ceci fait, je clone mon dépôt de fichiers de configuration, je me déplace dedans via un terminal, je lance un rake install et hop, je me sens comme chez moi. Simple non? Mais comment ça marche? Pour les non-familiers, rake est un outil similaire à make, qui fonctionne donc avec un Rakefile en lieu et place d’un Makefile. C’est un outil écrit en Ruby que l’on peut facilement installer via une gem.

Quel avantage par rapport à make me direz-vous? Et bien simplement le fait que l’on peut profiter de toute la puissance du langage haut-niveau qu’est Ruby pour définir des tâches qui sont les cibles de notre Rakefile et que l’on peut appeler des méthodes (comprenez fonction) définies en Ruby directement depuis ces tâches.

Dans le cas présent, seule une tâche est définie: install. Cette tâche s’occupe donc, comme je l’ai dit, de lier tous mes fichiers de configuration mais aussi de changer mon shell pour zsh, si ce dernier est installé sur le système, via des méthodes définies également dans le Rakefile. Bon assez parlé, le voici donc:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
require 'rake'

desc "links configuration files from this repository to $HOME"
task :install do
  dest = ENV['HOME']
  puts "Linking to ~"
  link_folder_content(dest)

  dest = dest + "/.config"
  puts "Linking to ~/.config"
  Dir.chdir("config")
  link_folder_content(dest)

  check_shell("/bin/zsh")
end

def link_folder_content(dest)
  replace_all = false

  Dir['*'].each do |file|
      next if %w[config Rakefile README linkconfig.sh].include? file

      file = "." + file if dest = ENV['HOME']

      if File.exist?(File.join(dest, "#{file}"))
          if replace_all
              replace_file(dest, file)
          else
              print "overwrite #{dest}/#{file}? [ynaq] "
              case $stdin.gets.chomp
              when 'a'
                  replace_all = true
                  replace_file(dest, file)
              when 'y'
                  replace_file(dest, file)
              when 'q'
                  exit
              else
                  puts "skipping #{dest}/#{file}"
              end
          end
      else
          link_file(dest, file)
      end
  end
end

def replace_file(dest, file)
  system %Q{rm -v "#{dest}/#{file}"}
  link_file(dest, file)
end

def link_file(dest, file)
  system %Q{ln -sv "$PWD/#{file.sub(/^(.?)/, "")}" "#{dest}/#{file}"}
end

def check_shell(shell)
  if ENV['SHELL'] != shell
      if command?(shell)
          system "chsh -s #{shell}"
      else
          puts "#{shell} not installed. Skipping."
      end
  else
      puts "#{shell} is already set as default shell."
  end
end

def command?(cmd)
  system %Q{which "#{cmd}" > /dev/null 2>&1}
end

Le script est certainement très facilement adaptable à votre besoin. Il est à noter que, dans mon dépôt, mes fichiers et dossiers ne sont pas précédés d’un “.”. La ligne 21 permet d’éviter de créer des liens vers des fichiers où dossiers pour lesquels ce n’est pas nécessaire. À vous donc de l’adapter au même titre que la tâche install.

Ah, et si mes fichiers de configuration vous intéressent, vous pouvez toujours accéder mon dépôt git ici