1{ package ? null
2, maintainer ? null
3}:
4
5# TODO: add assert statements
6
7let
8
9 pkgs = import ./../../default.nix { };
10
11 packagesWith = cond: return: set:
12 pkgs.lib.flatten
13 (pkgs.lib.mapAttrsToList
14 (name: pkg:
15 let
16 result = builtins.tryEval (
17 if pkgs.lib.isDerivation pkg && cond name pkg
18 then [(return name pkg)]
19 else if pkg.recurseForDerivations or false || pkg.recurseForRelease or false
20 then packagesWith cond return pkg
21 else []
22 );
23 in
24 if result.success then result.value
25 else []
26 )
27 set
28 );
29
30 packagesWithUpdateScriptAndMaintainer = maintainer':
31 let
32 maintainer =
33 if ! builtins.hasAttr maintainer' pkgs.lib.maintainers then
34 builtins.throw "Maintainer with name `${maintainer'} does not exist in `lib/maintainers.nix`."
35 else
36 builtins.getAttr maintainer' pkgs.lib.maintainers;
37 in
38 packagesWith (name: pkg: builtins.hasAttr "updateScript" pkg &&
39 (if builtins.hasAttr "maintainers" pkg.meta
40 then (if builtins.isList pkg.meta.maintainers
41 then builtins.elem maintainer pkg.meta.maintainers
42 else maintainer == pkg.meta.maintainers
43 )
44 else false
45 )
46 )
47 (name: pkg: pkg)
48 pkgs;
49
50 packageByName = name:
51 let
52 package = pkgs.lib.attrByPath (pkgs.lib.splitString "." name) null pkgs;
53 in
54 if package == null then
55 builtins.throw "Package with an attribute name `${name}` does not exists."
56 else if ! builtins.hasAttr "updateScript" package then
57 builtins.throw "Package with an attribute name `${name}` does have an `passthru.updateScript` defined."
58 else
59 package;
60
61 packages =
62 if package != null then
63 [ (packageByName package) ]
64 else if maintainer != null then
65 packagesWithUpdateScriptAndMaintainer maintainer
66 else
67 builtins.throw "No arguments provided.\n\n${helpText}";
68
69 helpText = ''
70 Please run:
71
72 % nix-shell maintainers/scripts/update.nix --argstr maintainer garbas
73
74 to run all update scripts for all packages that lists \`garbas\` as a maintainer
75 and have \`updateScript\` defined, or:
76
77 % nix-shell maintainers/scripts/update.nix --argstr package garbas
78
79 to run update script for specific package.
80 '';
81
82 runUpdateScript = package: ''
83 echo -ne " - ${package.name}: UPDATING ..."\\r
84 ${package.updateScript} &> ${(builtins.parseDrvName package.name).name}.log
85 CODE=$?
86 if [ "$CODE" != "0" ]; then
87 echo " - ${package.name}: ERROR "
88 echo ""
89 echo "--- SHOWING ERROR LOG FOR ${package.name} ----------------------"
90 echo ""
91 cat ${(builtins.parseDrvName package.name).name}.log
92 echo ""
93 echo "--- SHOWING ERROR LOG FOR ${package.name} ----------------------"
94 exit $CODE
95 else
96 rm ${(builtins.parseDrvName package.name).name}.log
97 fi
98 echo " - ${package.name}: DONE. "
99 '';
100
101in pkgs.stdenv.mkDerivation {
102 name = "nixpkgs-update-script";
103 buildCommand = ''
104 echo ""
105 echo "----------------------------------------------------------------"
106 echo ""
107 echo "Not possible to update packages using \`nix-build\`"
108 echo ""
109 echo "${helpText}"
110 echo "----------------------------------------------------------------"
111 exit 1
112 '';
113 shellHook = ''
114 echo ""
115 echo "Going to be running update for following packages:"
116 echo "${builtins.concatStringsSep "\n" (map (x: " - ${x.name}") packages)}"
117 echo ""
118 read -n1 -r -p "Press space to continue..." confirm
119 if [ "$confirm" = "" ]; then
120 echo ""
121 echo "Running update for:"
122 ${builtins.concatStringsSep "\n" (map runUpdateScript packages)}
123 echo ""
124 echo "Packages updated!"
125 exit 0
126 else
127 echo "Aborting!"
128 exit 1
129 fi
130 '';
131}