-
Notifications
You must be signed in to change notification settings - Fork 21
/
rerun2
executable file
·82 lines (72 loc) · 2.59 KB
/
rerun2
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
72
73
74
75
76
77
78
79
80
81
82
#!/usr/bin/env bash
# Events that occur within this time from an initial one are ignored
cooldown_s='0.250'
clear=''
verbose=''
# check dependencies
if ! command -v inotifywait >/dev/null
then
echo "error: inotifywait: command not found. hint: install inotify-tools"
exit 1
fi
function usage {
echo "Rerun a given command every time filesystem changes are detected."
echo ""
echo "Usage: $(basename $0) [OPTIONS] COMMAND"
echo ""
echo " -c, --clear Clear the screen before each execution of COMMAND."
echo " -v, --verbose Print the name of the files that changed to cause"
echo " each execution of COMMAND."
echo " -h, --help Display this help and exit."
echo ""
echo "Run the given COMMAND, and then every time filesystem changes are"
echo "detected in or below the current directory, run COMMAND again."
echo "Changes within $cooldown_s seconds are grouped into one."
echo ""
echo "This is useful for running commands to regenerate visual output every"
echo "time you hit [save] in your editor. For example, re-run tests, or"
echo "refresh markdown or graphviz rendering."
echo ""
echo "COMMAND can only be a simple command, ie. \"executable arg arg...\"."
echo "For compound commands, use:"
echo ""
echo " rerun bash -c \"ls -l | grep ^d\""
echo ""
echo "Using this it's pretty easy to rig up ad-hoc GUI apps on the fly."
echo "For example, every time you save a .dot file from the comfort of"
echo "your favourite editor, rerun can execute GraphViz to render it to"
echo "SVG, and refresh whatever GUI program you use to view that SVG."
echo ""
echo "COMMAND can't be a shell alias, and I don't understand why not."
}
while [ $# -gt 0 ]; do
case "$1" in
-c|--clear) clear='1';;
-v|--verbose) verbose='1' ;;
-h|--help) usage; exit;;
*) break;;
esac
shift
done
function execute() {
[ -n "$clear" ] && clear
[ -n "$verbose" ] && echo "$@"
"$@"
}
execute "$@"
end_of_cooldown="$( date +%s%N )"
cooldown_ns="$( LC_ALL=C printf '%0.9f' "$cooldown_s" | sed -r -e 's|\.||' -e 's|^0+||' )"
inotifywait --quiet --recursive --monitor --format '%e %w%f' \
--event='modify,close_write,move,create,delete' \
--exclude='\.git|\..*\.swp|__pycache__|\.cache|\.pytest_cache' \
. | while read changed
do
now="$( date +%s%N )"
if (( now > end_of_cooldown )); then
end_of_cooldown="$(( now + cooldown_ns ))"
( sleep "$cooldown_s" && execute "$@" ) &
fi
if [ -n "$verbose" ]; then
echo "$changed"
fi
done