diff options
-rw-r--r-- | nix/default.nix | 1 | ||||
-rw-r--r-- | nix/rolling-directory.nix | 25 | ||||
-rw-r--r-- | rolling-directory | 58 |
3 files changed, 84 insertions, 0 deletions
diff --git a/nix/default.nix b/nix/default.nix index 1c0105f..a40d8f6 100644 --- a/nix/default.nix +++ b/nix/default.nix | |||
@@ -7,4 +7,5 @@ in rec { | |||
7 | rebuild-system = pkgs.callPackage ./rebuild-system.nix {}; | 7 | rebuild-system = pkgs.callPackage ./rebuild-system.nix {}; |
8 | pulseaudio-ctl = pkgs.callPackage ./pulseaudio-ctl.nix {}; | 8 | pulseaudio-ctl = pkgs.callPackage ./pulseaudio-ctl.nix {}; |
9 | monitor-uucp = pkgs.callPackage ./monitor-uucp.nix {}; | 9 | monitor-uucp = pkgs.callPackage ./monitor-uucp.nix {}; |
10 | rolling-directory = pkgs.callPackage ./rolling-directory.nix {}; | ||
10 | } | 11 | } |
diff --git a/nix/rolling-directory.nix b/nix/rolling-directory.nix new file mode 100644 index 0000000..bb5dd53 --- /dev/null +++ b/nix/rolling-directory.nix | |||
@@ -0,0 +1,25 @@ | |||
1 | { stdenv | ||
2 | , zsh, coreutils, findutils, gawk, inotify-tools | ||
3 | }: | ||
4 | |||
5 | stdenv.mkDerivation rec { | ||
6 | name = "rolling-directory-${version}"; | ||
7 | version = "0.2"; | ||
8 | src = ../rolling-directory; | ||
9 | |||
10 | phases = [ "buildPhase" "installPhase" ]; | ||
11 | |||
12 | inherit zsh coreutils findutils gawk; | ||
13 | inotify = inotify-tools; | ||
14 | |||
15 | buildPhase = '' | ||
16 | substituteAll $src rolling-directory | ||
17 | ''; | ||
18 | |||
19 | installPhase = '' | ||
20 | mkdir -p $out/bin | ||
21 | |||
22 | install -m 755 -t $out/bin \ | ||
23 | rolling-directory | ||
24 | ''; | ||
25 | } | ||
diff --git a/rolling-directory b/rolling-directory new file mode 100644 index 0000000..d85f8b7 --- /dev/null +++ b/rolling-directory | |||
@@ -0,0 +1,58 @@ | |||
1 | #!@zsh@/bin/zsh | ||
2 | |||
3 | set -e | ||
4 | |||
5 | PATH=@coreutils@/bin:@findutils@/bin:@gawk@/bin:@inotify@/bin:$PATH | ||
6 | |||
7 | dir=${1:A} | ||
8 | maxSize=$(numfmt --from=auto --to=none -- $2) | ||
9 | shift 2 | ||
10 | |||
11 | [[ -d "${dir}" ]] || exit 2 | ||
12 | [[ "${maxSize}" = <-> ]] || exit 2 | ||
13 | |||
14 | typeset -a findExtra | ||
15 | findExtra=(-not -path ${dir}/CACHEDIR.TAG) | ||
16 | |||
17 | resize() { | ||
18 | echo "Resizing ${dir} to below $(numfmt --to=iec-i --suffix=B -- ${maxSize})..." >&2 | ||
19 | |||
20 | while [[ $(du -xbs ${dir} | awk '{ print $1; }') -gt $maxSize ]]; do | ||
21 | find ${dir} -xdev -type f \( ${findExtra} \) -print0 | \ | ||
22 | xargs -r0 -- stat --printf '%W %Y %Z %X %n\0' | \ | ||
23 | sort -t '\0' -z | \ | ||
24 | awk -F '\0' '{ gsub("^\\S+\\s+\\S+\\s+\\S+\\s+\\S+\\s+", "", $1); printf "%s\0", $1; }' | \ | ||
25 | xargs -r0 -- rm -v | ||
26 | done | ||
27 | |||
28 | find ${dir} -xdev -xtype l -print0 | xargs -r0 -- rm -v | ||
29 | find ${dir} -xdev -type d \( -not -path ${dir} \) -empty -print0 | xargs -r0 -- rmdir -v | ||
30 | } | ||
31 | |||
32 | case "${1}" in | ||
33 | monitor) | ||
34 | shift | ||
35 | |||
36 | typeset -a inotifyExtra | ||
37 | inotifyExtra=() | ||
38 | |||
39 | if [[ "${1}" = <-> ]]; then | ||
40 | inotifyExtra=(-t "${1}") | ||
41 | shift | ||
42 | fi | ||
43 | |||
44 | while | ||
45 | resize | ||
46 | inotifywait -qq -r ${dir} ${inotifyExtra} \ | ||
47 | -e modify \ | ||
48 | -e close_write \ | ||
49 | -e moved_to \ | ||
50 | -e move_self \ | ||
51 | -e create | ||
52 | true | ||
53 | do :; done | ||
54 | ;; | ||
55 | *) | ||
56 | resize | ||
57 | ;; | ||
58 | esac | ||