Automatisch SASS compilen

SASS heeft veel weg van LESS wat vooral door Twitter gebruikt wordt maar het schijnt iets beter te zijn.  Het is een manier van CSS code schrijven waarbij de CSS syntax gevolgd wordt maar waarmee je ineens toegang krijgt tot variabelen, functies en meer. Het enige nadeel is dat je SASS (.scss) bestanden wel nog moet omzetten naar CSS.  Daar is een handig programmaatje voor maar die moet je dan nog steeds elke keer dat je een aanpassing doet handmatig uitvoeren. Om dat op te lossen heb ik een klein Bash script gemaakt.

Dit script maakt gebruik van inotify en sassc en is getest onder Ubuntu 14.04. Om inotify te installeren voer je het volgende uit:

sudo apt-get install inotify-tools

sassc installeren is iets moeilijker want die moet je zelf compilen. Voor zover ik me herinner heb ik daar deze tutorial voor gevolgd.

Dit is het script wat ik gemaakt hebt. Deze kun je in principe overal neerzetten. Sla dit script op als scss2css.sh en voer een "chmod +x scss2css.sh" uit. Pas de dir= regel aan naar de map waar je sass/css code in staat.

#!/bin/bash
dir='/var/www/http_docs/'
sassc='/usr/local/bin/sassc'

inotifywait -m -r -e modify,close_write,create,moved_to,move --format %w%f $dir | while read scss_filepath; do 
    filename=$(basename "$scss_filepath")
    extension="${filename##*.}"

    if [[ "$extension" == "scss" ]]; then
        if  [[ ! $filename =~ ^_ ]]; then
            css_filepath=${scss_filepath/.scss/.css}
            $("$sassc" "$scss_filepath" "$css_filepath")
        else
            filename=${filename:1}
            filename=${filename/.scss/}
            files=$(grep -clRE --include=*.scss "import.*$filename" "$dir")

            for scss_filepath in $files; do
                css_filepath=${scss_filepath/.scss/.css}
                $("$sassc" "$scss_filepath" "$css_filepath")
            done

        fi
    fi
done

exit 0

Als laatste is het natuurlijk handig als het script tijdens het booten gestart word. Dit kan door een aanpassing in /etc/rc.local. Voeg daar deze regel aan toe:

su www-data --shell=/bin/bash -c '/var/www/scss2css.sh  > /dev/null 2>&1 &'

Backup m.b.v. rsync

Ik wilde al langer een offsite backup oplossing waarvan ik zeker kon zijn dat deze altijd zijn werk deed. Zelfs al zou er een ip adres wijzigen of de verbinding wegvallen tijdens het maken van de backup.

Op een gegeven moment vond ik BitTorrent Sync wat bijna precies deed wat ik wilde. BTSync is een volledig decentrale synchronisatie dienst. Je kan data dus zonder problemen naar verschillende devices toe synchroniseren. Het is alleen nog steeds geen echte backup oplossing omdat bestanden gewoon overschreven kunnen worden door een nieuwe versie.

Om dit toch voor elkaar te krijgen heb ik een simpel bash script gemaakt. Dit script moet twee argumenten meekrijgen. De eerste is de naam van het interval (hour, day, week, month, …) en de ander het maximum aantal kopieën die bewaard moeten blijven van dat interval. Het script word uitgevoerd via crontab en stuurt je een e-mail met de resultaten.

#!/bin/sh

# stuff to add to crontab:
# 1 1     * * 1   root    /etc/rsyncbak/rsyncbak.sh weekly 15
# 1 8     1 * *   root    /etc/rsyncbak/rsyncbak.sh monthly 24
# 1 16    2 1 *   root    /etc/rsyncbak/rsyncbak.sh yearly 100

# directory settings
BTSYNC_DIR='/mnt/backup/btsync/'
BACKUP_DIR='/mnt/backup/backups/'
PREV_LINK='/mnt/backup/backups/previous'
EXCLUDE_FILE='/etc/rsyncbak/exclude.txt'
EMAIL='youremail@domain.com'

# create vars for backup
NOW=$(date +'%Y-%m-%d_%H-%M-%S')
INTERVAL=$1
KEEP_X_COPIES=$(($2+1))
FOLDER="${BACKUP_DIR}${INTERVAL}_${NOW}"

# create backup using rsync
RSYNC_OUT=$(rsync -av --delete --link-dest="$PREV_LINK" "$BTSYNC_DIR" "$FOLDER/" --exclude-from="$EXCLUDE_FILE")
RSYNC_EC=$?

# create a new symlink
if [ -L "$PREV_LINK" ]; then
    rm "$PREV_LINK"
fi
ln -s "$FOLDER" "$PREV_LINK"

# remove obsolete backups
TO_REMOVE=$(ls -rd "${BACKUP_DIR}${INTERVAL}"_* | tail -n +"${KEEP_X_COPIES}")
for dir in $TO_REMOVE; do
    rm -rf "$dir"
done

printf "rsyncbak completed, exit code: %s\n\n%s" "$RSYNC_EC" "$RSYNC_OUT" | mail -s "rsyncbak completed" "$EMAIL"