]> ruderich.org/simon Gitweb - config/dotfiles.git/blobdiff - shell/crontab.d/setup.sh
Move to shell/ in preparation for merge into new dotfiles repository
[config/dotfiles.git] / shell / crontab.d / setup.sh
diff --git a/shell/crontab.d/setup.sh b/shell/crontab.d/setup.sh
new file mode 100755 (executable)
index 0000000..46ebb56
--- /dev/null
@@ -0,0 +1,96 @@
+#!/bin/sh
+
+# Combine all crontab.* files in ~/.crontab.d/ into a single crontab file and
+# load it with `crontab`.
+#
+# An existing crontab entry not generated with this script is not overwritten.
+
+# Copyright (C) 2012-2014  Simon Ruderich
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+set -eu
+
+
+HEADER_WARNING='# WARNING! DO NOT EDIT THIS FILE! #'
+
+# Don't overwrite existing crontab entries. Not race condition free but that
+# can't be helped.
+if crontab -l >/dev/null 2>&1; then
+    if crontab -l | head -n3 | grep -F -x "$HEADER_WARNING" >/dev/null; then
+        :
+    else
+        echo 'Existing crontab entry found, please remove it manually.'
+        exit 2
+    fi
+fi
+
+
+DIRECTORY="$HOME/.crontab.d"
+if test ! -d "$DIRECTORY" || test ! -O "$DIRECTORY"; then
+    exit 1
+fi
+
+# `set -e` aborts when `mktemp` fails.
+CRONTAB=`mktemp --tmpdir="$DIRECTORY" update-crontab.XXXXXXXXXXXX`
+
+echo '###################################'  >"$CRONTAB"
+echo "$HEADER_WARNING"                     >>"$CRONTAB"
+echo '###################################' >>"$CRONTAB"
+echo >>"$CRONTAB"
+printf "# It was generated from '%s/*' on %s." \
+    "$DIRECTORY" "`LANG=C date '+%a, %d %b %Y %H:%M:%S %z'`" >>"$CRONTAB"
+
+# Enforce C sort order.
+LC_ALL=C
+
+NO_MATCHES=
+for file in "$DIRECTORY"/crontab.*; do
+    # No crontab.* files exist, abort.
+    if test ! -e "$file"; then
+        NO_MATCHES=y
+        break
+    fi
+
+    printf "Found '%s'.\n" "$file"
+
+    printf '\n\n## %s:\n' "$file" >>"$CRONTAB"
+
+    # Strip licenses, multiple empty lines and fix $HOME variables in PATH
+    # (cron doesn't expand variables).
+    START_REGEX='^# This [a-zA-Z]* is free software: you can redistribute it'
+    END_REGEX='^# along with this [a-zA-Z]*.  If not, see <[^>]*>\.'
+    <"$file" sed -e "/$START_REGEX/,/$END_REGEX/ d" \
+                 -e "/^#[ ]*$/ d" \
+                 -e "/^# Copyright (C) [0-9][0-9]* / d" \
+        | cat --squeeze-blank \
+        | sed "/^PATH/ s:\$HOME:$HOME:g" \
+        >>"$CRONTAB"
+done
+
+# Update crontab with the crontab.* files.
+if test -z "$NO_MATCHES"; then
+    echo
+    echo 'Updating crontab.'
+    crontab "$CRONTAB"
+
+# No files found, remove the existing crontab entry. Ignore errors in case no
+# crontab entry existed in the first place.
+else
+    echo 'No files found, removing old crontab (if it exists).'
+    crontab -r || true
+fi
+
+rm "$CRONTAB"