This repository has no description
4.5 kB
108 lines
1{ ... }:
2{
3 perSystem =
4 { pkgs, ... }:
5 {
6 # update-pkgs [attr...] (no attrs: every package with an updateScript)
7 #
8 # Runs passthru.updateScript the way nixpkgs' maintainers/scripts/update.py
9 # does (UPDATE_NIX_ATTR_PATH/PNAME/OLD_VERSION/NAME, cwd = flake root),
10 # for this flake's packages. Packages missing from the host's package set
11 # (linux-only ones on darwin) are taken from x86_64-linux; nix-update in
12 # their command is swapped for the host's, the rest of the command stays.
13 packages.update-pkgs =
14 (pkgs.writeShellApplication {
15 name = "update-pkgs";
16 runtimeInputs = [
17 pkgs.git
18 pkgs.jq
19 pkgs.nix-update
20 ];
21 text = ''
22 root=$(git rev-parse --show-toplevel)
23 cd "$root"
24 host=$(nix eval --raw --impure --expr builtins.currentSystem)
25 # Only update scripts written for this flake: nix-update with --flake,
26 # or a script inside this flake. Packages wrapping nixpkgs or
27 # flake-input packages otherwise inherit an updateScript meant for
28 # that checkout; those follow flake.lock instead.
29 src=$(nix flake metadata --json . | jq -r .path)
30
31 # attr -> {cmd, pname, version, name}. Per package tryEval: one
32 # package refusing to evaluate on this system must not hide the rest.
33 scripts() {
34 nix eval --json ".#packages.$1" --apply "
35 ps: builtins.mapAttrs (n: p:
36 let
37 r = builtins.tryEval (
38 let
39 u = p.passthru.updateScript or null;
40 isOurs = s: s == \"--flake\"
41 || builtins.substring 0 (builtins.stringLength \"$src/\") s == \"$src/\";
42 c =
43 if builtins.isList u then u
44 else if builtins.isAttrs u && u ? command then
45 (if builtins.isList u.command then u.command else [ u.command ])
46 else [ u ];
47 v = {
48 cmd = map toString c;
49 pname = p.pname or n;
50 version = p.version or \"\";
51 name = p.name or n;
52 };
53 in
54 if u == null || !(builtins.any isOurs v.cmd) then null else builtins.deepSeq v v
55 );
56 in
57 if r.success then r.value else null) ps"
58 }
59 host_scripts=$(scripts "$host")
60 linux_scripts='{}'
61 if [ "$host" != x86_64-linux ]; then
62 linux_scripts=$(scripts x86_64-linux)
63 fi
64 # host entries win over linux ones
65 all=$(jq -s '.[1] + .[0] | with_entries(select(.value != null))' \
66 <<<"$host_scripts $linux_scripts")
67
68 if [ "''${1:-}" = --list ]; then
69 jq -r 'to_entries[] | "\(.key)\t\(.value.cmd | join(" "))"' <<<"$all"
70 exit 0
71 fi
72 if [ $# -gt 0 ]; then
73 attrs=("$@")
74 else
75 mapfile -t attrs < <(jq -r 'keys[]' <<<"$all")
76 fi
77
78 failed=()
79 for attr in "''${attrs[@]}"; do
80 entry=$(jq -c --arg a "$attr" '.[$a] // empty' <<<"$all")
81 if [ -z "$entry" ]; then
82 echo "update-pkgs: $attr has no updateScript" >&2
83 failed+=("$attr")
84 continue
85 fi
86 mapfile -t cmd < <(jq -r '.cmd[]' <<<"$entry")
87 case "''${cmd[0]}" in
88 */bin/nix-update) cmd[0]=nix-update ;;
89 esac
90 printf '\n\033[1m== %s\033[0m\n' "$attr" >&2
91 if ! UPDATE_NIX_ATTR_PATH=$attr \
92 UPDATE_NIX_PNAME=$(jq -r .pname <<<"$entry") \
93 UPDATE_NIX_OLD_VERSION=$(jq -r .version <<<"$entry") \
94 UPDATE_NIX_NAME=$(jq -r .name <<<"$entry") \
95 "''${cmd[@]}"; then
96 failed+=("$attr")
97 fi
98 done
99
100 if [ ''${#failed[@]} -gt 0 ]; then
101 echo "update-pkgs: failed: ''${failed[*]}" >&2
102 exit 1
103 fi
104 '';
105 }).overrideAttrs
106 { passthru.usage = builtins.readFile ./usage.kdl; };
107 };
108}