diff --git a/README.md b/README.md index 2f45113..ad1f206 100644 --- a/README.md +++ b/README.md @@ -18,3 +18,23 @@ Example `flendor.json`: } } ``` + +Example usage: + +``` +$ ./flendor +./flendor: copying flake git+https://forgejo.helveticanonstandard.net/helvetica/forgesync.git to vendor/forgesync +./flendor: copying flake git+https://forgejo.helveticanonstandard.net/helvetica/hxwrap.git to vendor/hxwrap +./flendor: copying flake git+https://forgejo.helveticanonstandard.net/helvetica/musicomp.git to vendor/musicomp +./flendor: copying flake git+https://forgejo.helveticanonstandard.net/helvetica/mympv.git to vendor/mympv +./flendor: copying flake git+https://forgejo.helveticanonstandard.net/helvetica/myphps.git to vendor/myphps +./flendor: copying flake git+https://forgejo.helveticanonstandard.net/helvetica/nini.git to vendor/nini +./flendor: copying flake git+https://forgejo.helveticanonstandard.net/helvetica/xenumenu.git to vendor/xenumenu +./flendor: removing old flake at vendor/asdf +./flendor: removing old flake at vendor/hjkl +``` + +## Why? + +I don't know. +I personally just use this to vendor my own flakes in my NixOS configuration, so that if my Forgejo server ever stops working, I still have the possibility to rebuild its configuration without much hassle. diff --git a/flake.nix b/flake.nix index c298f5a..3b55359 100644 --- a/flake.nix +++ b/flake.nix @@ -40,9 +40,13 @@ treefmt = { projectRootFile = "flake.nix"; - programs.nixfmt = { - enable = true; - package = pkgs.nixfmt-rfc-style; + programs = { + nixfmt = { + enable = true; + package = pkgs.nixfmt-rfc-style; + }; + + shfmt.enable = true; }; }; diff --git a/flendor b/flendor index 52db54e..6b0e4b3 100755 --- a/flendor +++ b/flendor @@ -4,6 +4,8 @@ set -o errexit set -o nounset set -o pipefail +shopt -s nullglob + progname=$0 warn() { @@ -21,7 +23,7 @@ error() { args=$( getopt \ - --options t:rv \ + --options d:rv \ --longoptions vendor:,refresh,verbose \ --name "$progname" \ -- "$@" @@ -31,10 +33,8 @@ eval set -- "$args" nixflags=() rmflags=() -mkdirflags=() -cpflags=() +rsyncflags=() prefetchflags=() -verbose=false while true; do case $1 in -d | --vendor) @@ -48,9 +48,7 @@ while true; do -v | --verbose) nixflags+=(--verbose) rmflags+=(--verbose) - mkdirflags+=(--verbose) - cpflags+=(--verbose) - verbose=true + rsyncflags+=(--verbose) shift ;; --) @@ -70,21 +68,41 @@ if [[ ! -v vendor ]]; then vendor=$(jq --exit-status --raw-output '.vendor' <<<"$json") fi +keeppaths=() + while IFS= read -r k; do name=$(jq --null-input --argjson k "$k" --raw-output '$k') + + if [[ $name =~ / ]]; then + error 'flake input name cannot contain slashes' + fi + flake=$(jq --argjson k "$k" --raw-output '.flakes.[$k]' <<<"$json") dest="$vendor/$name" - if [[ $verbose == true ]]; then - warn "copying flake $flake to $dest" - fi + keeppaths+=("$dest") - rm --recursive --force "${rmflags[@]}" -- "$dest" + warn "copying flake $flake to $dest" - src=$(nix flake prefetch --json "${prefetchflags[@]}" -- "$flake" | jq --exit-status --raw-output '.storePath') + src=$(nix "${nixflags[@]}" flake prefetch --json "${prefetchflags[@]}" -- "$flake" | jq --exit-status --raw-output '.storePath') - mkdir --parents "${mkdirflags[@]}" -- "$(dirname -- "$dest")" - - cp --recursive --no-preserve all "${cpflags[@]}" -- "$src/." "$dest" + rsync --recursive --delete --update --mkpath "${rsyncflags[@]}" -- "$src/" "$dest" done < <(jq '.flakes | keys[]' <<<"$json") + +for path in "$vendor"/{,.}*; do + keep=0 + + for keeppath in "${keeppaths[@]}"; do + a=$(realpath --strip -- "$path") + b=$(realpath --strip -- "$keeppath") + if [[ $a == "$b" ]]; then + keep=1 + fi + done + + if (( ! keep )); then + warn "removing old flake at $path" + rm --recursive --force "${rmflags[@]}" -- "$path" + fi +done diff --git a/package.nix b/package.nix index bff4bda..05c4acb 100644 --- a/package.nix +++ b/package.nix @@ -1,12 +1,14 @@ { writeShellApplication, jq, + rsync, }: writeShellApplication { - name = "jq"; + name = "flendor"; runtimeInputs = [ jq + rsync ]; text = builtins.readFile ./flendor;