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