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 | ||
