nixpkgs/maintainers/scripts/update.nix
Jan Tojnar fa1bbe69fb
maintainers/scripts/update.nix: Do not store updateScripts
For update script parallelization, we have started calling builtins.toJSON
on updateScripts, which triggers evaluation of paths and therefore their copying
to Nix store. This breaks update scripts that assume that they exist in nixpkgs
like dwarf-fortress.

https://github.com/NixOS/nixpkgs/issues/61935

Let’s stringify the paths before JSONification to prevent the evaluation.
2019-06-02 08:10:17 +02:00

144 lines
4.6 KiB
Nix
Executable file

{ package ? null
, maintainer ? null
, path ? null
, max-workers ? null
, keep-going ? null
}:
# TODO: add assert statements
let
/* Remove duplicate elements from the list based on some extracted value. O(n^2) complexity.
*/
nubOn = f: list:
if list == [] then
[]
else
let
x = pkgs.lib.head list;
xs = pkgs.lib.filter (p: f x != f p) (pkgs.lib.drop 1 list);
in
[x] ++ nubOn f xs;
pkgs = import ./../../default.nix { };
packagesWith = cond: return: set:
nubOn (pkg: pkg.updateScript)
(pkgs.lib.flatten
(pkgs.lib.mapAttrsToList
(name: pkg:
let
result = builtins.tryEval (
if pkgs.lib.isDerivation pkg && cond name pkg
then [(return name pkg)]
else if pkg.recurseForDerivations or false || pkg.recurseForRelease or false
then packagesWith cond return pkg
else []
);
in
if result.success then result.value
else []
)
set
)
);
packagesWithUpdateScriptAndMaintainer = maintainer':
let
maintainer =
if ! builtins.hasAttr maintainer' pkgs.lib.maintainers then
builtins.throw "Maintainer with name `${maintainer'} does not exist in `maintainers/maintainer-list.nix`."
else
builtins.getAttr maintainer' pkgs.lib.maintainers;
in
packagesWith (name: pkg: builtins.hasAttr "updateScript" pkg &&
(if builtins.hasAttr "maintainers" pkg.meta
then (if builtins.isList pkg.meta.maintainers
then builtins.elem maintainer pkg.meta.maintainers
else maintainer == pkg.meta.maintainers
)
else false
)
)
(name: pkg: pkg)
pkgs;
packagesWithUpdateScript = path:
let
attrSet = pkgs.lib.attrByPath (pkgs.lib.splitString "." path) null pkgs;
in
packagesWith (name: pkg: builtins.hasAttr "updateScript" pkg)
(name: pkg: pkg)
attrSet;
packageByName = name:
let
package = pkgs.lib.attrByPath (pkgs.lib.splitString "." name) null pkgs;
in
if package == null then
builtins.throw "Package with an attribute name `${name}` does not exists."
else if ! builtins.hasAttr "updateScript" package then
builtins.throw "Package with an attribute name `${name}` does not have a `passthru.updateScript` attribute defined."
else
package;
packages =
if package != null then
[ (packageByName package) ]
else if maintainer != null then
packagesWithUpdateScriptAndMaintainer maintainer
else if path != null then
packagesWithUpdateScript path
else
builtins.throw "No arguments provided.\n\n${helpText}";
helpText = ''
Please run:
% nix-shell maintainers/scripts/update.nix --argstr maintainer garbas
to run all update scripts for all packages that lists \`garbas\` as a maintainer
and have \`updateScript\` defined, or:
% nix-shell maintainers/scripts/update.nix --argstr package garbas
to run update script for specific package, or
% nix-shell maintainers/scripts/update.nix --argstr path gnome3
to run update script for all package under an attribute path.
You can also add
--argstr max-workers 8
to increase the number of jobs in parallel, or
--argstr keep-going true
to continue running when a single update fails.
'';
packageData = package: {
name = package.name;
pname = (builtins.parseDrvName package.name).name;
updateScript = map builtins.toString (pkgs.lib.toList package.updateScript);
};
in pkgs.stdenv.mkDerivation {
name = "nixpkgs-update-script";
buildCommand = ''
echo ""
echo "----------------------------------------------------------------"
echo ""
echo "Not possible to update packages using \`nix-build\`"
echo ""
echo "${helpText}"
echo "----------------------------------------------------------------"
exit 1
'';
shellHook = ''
unset shellHook # do not contaminate nested shells
exec ${pkgs.python3.interpreter} ${./update.py} ${pkgs.writeText "packages.json" (builtins.toJSON (map packageData packages))}${pkgs.lib.optionalString (max-workers != null) " --max-workers=${max-workers}"}${pkgs.lib.optionalString (keep-going == "true") " --keep-going"}
'';
}