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