--- /dev/null
+#!/usr/bin/env bash
+
+set -e
+
+declare -A refreshed
+
+while [ -n "$1" ]; do
+ case "$1" in
+ --no-new-inputs)
+ no_new_inputs="y"
+ shift;;
+ *)
+ flake_or_dir="$1"
+ shift;;
+ esac
+done
+
+refresh_deps() {
+ local flake
+ local inputs=()
+ local depname
+ local deppath
+ flake="$(realpath $1)"
+ if [ "${refreshed[$flake]}" = 1 ]; then
+ return
+ fi
+ pushd "$flake" 2>/dev/null >/dev/null
+ if [ -z "$no_new_inputs" ]; then
+ nix --no-warn-dirty flake lock
+ fi
+ if [ ! -e "$flake/flake.lock" ]; then
+ popd 2>/dev/null >/dev/null
+ refreshed[$flake]=1
+ return
+ fi
+
+ deps=$(jq -r '. as $root | .nodes[.root].inputs|values|to_entries|map({ key: .key, value: $root.nodes[.value].original.path })[]|select(.value != null)|.key + " " + .value' < flake.lock)
+ if [ -n "$deps" ]; then
+ while read depname deppath; do
+ refresh_deps "$deppath"
+ inputs+=(--update-input "$depname")
+ done <<<"$deps"
+ fi
+ nix --no-warn-dirty flake lock "${inputs[@]}"
+ popd 2>/dev/null >/dev/null
+ refreshed[$flake]=1
+}
+
+git_dir=$(git rev-parse --show-toplevel)
+
+# If argument is given (flake.nix or directory containing), refresh that argument
+# Otherwise, if we are in a subdirectory containing a flake.nix, refresh that
+# Otherwise, refresh all
+if [ -n "$flake_or_dir" ]; then
+ if [ -d "$flake_or_dir" -a -e "$1/flake.nix" ]; then
+ refresh_deps "$flake_or_dir"
+ elif [ -f "$flake_or_dir" -a -e "$(dirname $flake_or_dir)/flake.nix" ]; then
+ refresh_deps "$(dirname $flake_or_dir)"
+ else
+ echo "No flake.nix file in specified location"
+ exit 1
+ fi
+else
+ if [ "$(pwd)" != "$git_dir" -a -e "$(pwd)/flake.nix" ]; then
+ refresh_deps "$(pwd)"
+ else
+ find $git_dir -name "flake.lock" | while read flake; do
+ refresh_deps "$(dirname $flake)"
+ done
+ fi
+fi