fr en

Déplacer des lignes correspondant à une regexp en bash

Posted on 2015-07-22 in Trucs et astuces

Récemment sur un projet j'ai dû mettre à jour closure compiler. Afin de faire cette mise à jour, j'ai dû déplacer certaines lignes de code utilisées par closure : le compilateur utilise des goog.require et des goog.provide pour trouver les dépendances entre les fichiers. Dans la version utilisée par le projet, ces lines étaient dans une IEF :

(function() {
       goog.require('toto');
       goog.provide('titi');

Mais cette façon d'écrire le code n'est plus possible dans les versions récentes du closure compiler : les dépendances doivent être gérées directement au niveau du fichier. Les goog.require et goog.provide doivent donc être déplacées dans tous les fichiers en dehors de l'IEF. Vu le nombre de fichiers concernés, j'ai écrit le script suivant pour le faire automatiquement.

# Boucle sur tous les fichiers qui ont une IEF dans les sources
for file in $(grep -rl '^(function() {' src | grep -v lib); do
    # On supprime la ligne de l'IEF
    sed -i '/^(function() {/d' "${file}"
    # On supprime l'indentation des goog.*
    sed -i -r 's/^  (goog.(provide|require))/\1/g' "${file}"
    # Affiche le fichier de bas en haut.
    # Pour la première ligne qui correspond à la gestion de dépendance, on
    # "imprime" la première ligne de l'IEF et on affiche la ligne de dépendance.
    # Remet le ficher à l'endroit.
    tac "${file}" | awk '/goog.(provide|require)/ && ! seen {print "(function() {"; seen=1} {print}' | tac > "${file}.new"
    # On doit utiliser un nouveau fichier car du fait des pipes, le fichier
    # va s'écrire avant d'avoir été complètement lu, ce qui va tout faire planter.
    mv -f "${file}.new" "${file}"
done