Skip to content

Instantly share code, notes, and snippets.

@soraxas
Last active February 22, 2023 06:55
Show Gist options
  • Save soraxas/c57178976a714555165832b7296633fc to your computer and use it in GitHub Desktop.
Save soraxas/c57178976a714555165832b7296633fc to your computer and use it in GitHub Desktop.
script:Taskwarrior auto sync script, with the ability to sync in background (non-blocking) and with delays so that it waits for you to finish modifing all files. In additions, it allows you to perform task undo (because once you have synced, you cannot undo). Requires tmux or screen for some form of background session.
#!/bin/bash
# This hooks script syncs task warrior to the configured task server.
# The on-exit event is triggered once, after all processing is complete.
# let's do a quick check. If the taskw command already is synchronize, we
# wouldn't need to run this script:)
for arg in $*; do
if [[ "$arg" == api:* ]]; then
IFS=':'
read -ra api_level <<< "$arg"
api_level=${api_level[1]}
case $api_level in
1|2) ;;
*) echo "SyncOnExit: Unspoorted api level '$api_level'"
exit ;;
esac
fi
if [[ "$arg" == command:synchronize ]]; then
exit
fi
done
TMUX_SESSION_TOKEN="_taskw-sync"
SYNC_DELAY=30
TASKW_HOOK_TMP_DIR="$HOME/.task/hooks/.tmp"
TASKW_IS_DIRTY_FILE="$TASKW_HOOK_TMP_DIR/sync_is_dirty"
mkdir -p "$TASKW_HOOK_TMP_DIR"
# The logic is as following:
# 1. only continue the script if something was modified in this session,
# or something in previous session has not been synced.
# 2. spawn a tmux session to run in background (non-blocking)
# 3. within the session, sleep to create delays, allow user to *undo*
# or add more data.
# 4. when that happens, and when this script is called again, kill
# the previous existing session, and the new session will starts
# from 1. again.
# 5 if it succeed, it will empty the is_dirty file.
# 6. if it fails, the taskw will remained to be dirty and will tries
# to perform sync the next time.
# Count the number of tasks modified
n=0
while read modified_task
do
n=$(($n + 1))
done
# if file exists and it's non-empty
is_dirty=$(test -e "$TASKW_IS_DIRTY_FILE" && cat $TASKW_IS_DIRTY_FILE)
if [[ $is_dirty || (($n > 0)) ]]; then
# kill existing session, if exists
tmux kill-session -t "$TMUX_SESSION_TOKEN" 2>/dev/null && echo "Existing taskw-sync has been stopped."
# mark taskw sync as dirty
echo 1 > "$TASKW_IS_DIRTY_FILE"
# SYNC IN BACKGROUND.
# tmux also prevent duplicated session
tmux new -d -s "$TMUX_SESSION_TOKEN" 'sleep '"$SYNC_DELAY"' \
&& task sync >> ~/.task/sync_hook.log 2>&1 \
&& notify-send Taskwarrior "Successfully synced." \
&& true > '"$TASKW_IS_DIRTY_FILE"' \
|| notify-send Taskwarrior "Failed to sync."'
echo "Taskw will be synced in $SYNC_DELAY seconds."
fi
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment