forked from mirrors/nixpkgs
update.nix: Run update scripts in parallel
To make updating large attribute sets faster, the update scripts are now run in parallel. Please note the following changes in semantics: - The string passed to updateScript needs to be a path to an executable file. - The updateScript can also be a list: the tail elements will then be passed to the head as command line arguments.
This commit is contained in:
parent
7a9acea944
commit
59a94b57f0
|
@ -671,6 +671,43 @@ passthru = {
|
|||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>passthru.updateScript</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
A script to be run by <filename>maintainers/scripts/update.nix</filename> when
|
||||
the package is matched. It needs to be an executable file, either on the file
|
||||
system:
|
||||
<programlisting>
|
||||
passthru.updateScript = ./update.sh;
|
||||
</programlisting>
|
||||
or inside the expression itself:
|
||||
<programlisting>
|
||||
passthru.updateScript = writeScript "update-zoom-us" ''
|
||||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -i bash -p curl pcre common-updater-scripts
|
||||
|
||||
set -eu -o pipefail
|
||||
|
||||
version="$(curl -sI https://zoom.us/client/latest/zoom_x86_64.tar.xz | grep -Fi 'Location:' | pcregrep -o1 '/(([0-9]\.?)+)/')"
|
||||
update-source-version zoom-us "$version"
|
||||
'';
|
||||
</programlisting>
|
||||
The attribute can also contain a list, a script followed by arguments to be passed to it:
|
||||
<programlisting>
|
||||
passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ];
|
||||
</programlisting>
|
||||
Note that the update scripts will be run in parallel by default; you should avoid running <command>git commit</command> or any other commands that cannot handle that.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For information about how to run the updates, execute
|
||||
<cmdsynopsis><command>nix-shell</command> <arg>maintainers/scripts/update.nix</arg></cmdsynopsis>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</section>
|
||||
<section xml:id="sec-stdenv-phases">
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{ package ? null
|
||||
, maintainer ? null
|
||||
, path ? null
|
||||
, max-workers ? null
|
||||
, keep-going ? null
|
||||
}:
|
||||
|
||||
# TODO: add assert statements
|
||||
|
@ -105,26 +107,23 @@ let
|
|||
% 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.
|
||||
'';
|
||||
|
||||
runUpdateScript = package: ''
|
||||
echo -ne " - ${package.name}: UPDATING ..."\\r
|
||||
${package.updateScript} &> ${(builtins.parseDrvName package.name).name}.log
|
||||
CODE=$?
|
||||
if [ "$CODE" != "0" ]; then
|
||||
echo " - ${package.name}: ERROR "
|
||||
echo ""
|
||||
echo "--- SHOWING ERROR LOG FOR ${package.name} ----------------------"
|
||||
echo ""
|
||||
cat ${(builtins.parseDrvName package.name).name}.log
|
||||
echo ""
|
||||
echo "--- SHOWING ERROR LOG FOR ${package.name} ----------------------"
|
||||
exit $CODE
|
||||
else
|
||||
rm ${(builtins.parseDrvName package.name).name}.log
|
||||
fi
|
||||
echo " - ${package.name}: DONE. "
|
||||
'';
|
||||
packageData = package: {
|
||||
name = package.name;
|
||||
pname = (builtins.parseDrvName package.name).name;
|
||||
updateScript = pkgs.lib.toList package.updateScript;
|
||||
};
|
||||
|
||||
in pkgs.stdenv.mkDerivation {
|
||||
name = "nixpkgs-update-script";
|
||||
|
@ -139,21 +138,7 @@ in pkgs.stdenv.mkDerivation {
|
|||
exit 1
|
||||
'';
|
||||
shellHook = ''
|
||||
echo ""
|
||||
echo "Going to be running update for following packages:"
|
||||
echo "${builtins.concatStringsSep "\n" (map (x: " - ${x.name}") packages)}"
|
||||
echo ""
|
||||
read -n1 -r -p "Press space to continue..." confirm
|
||||
if [ "$confirm" = "" ]; then
|
||||
echo ""
|
||||
echo "Running update for:"
|
||||
${builtins.concatStringsSep "\n" (map runUpdateScript packages)}
|
||||
echo ""
|
||||
echo "Packages updated!"
|
||||
exit 0
|
||||
else
|
||||
echo "Aborting!"
|
||||
exit 1
|
||||
fi
|
||||
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"}
|
||||
'';
|
||||
}
|
||||
|
|
79
maintainers/scripts/update.py
Normal file
79
maintainers/scripts/update.py
Normal file
|
@ -0,0 +1,79 @@
|
|||
import argparse
|
||||
import concurrent.futures
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
updates = {}
|
||||
|
||||
def eprint(*args, **kwargs):
|
||||
print(*args, file=sys.stderr, **kwargs)
|
||||
|
||||
def run_update_script(package):
|
||||
eprint(f" - {package['name']}: UPDATING ...")
|
||||
|
||||
subprocess.run(package['updateScript'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=True)
|
||||
|
||||
|
||||
def main(max_workers, keep_going, packages):
|
||||
with open(sys.argv[1]) as f:
|
||||
packages = json.load(f)
|
||||
|
||||
eprint()
|
||||
eprint('Going to be running update for following packages:')
|
||||
for package in packages:
|
||||
eprint(f" - {package['name']}")
|
||||
eprint()
|
||||
|
||||
confirm = input('Press Enter key to continue...')
|
||||
if confirm == '':
|
||||
eprint()
|
||||
eprint('Running update for:')
|
||||
|
||||
with concurrent.futures.ProcessPoolExecutor(max_workers=max_workers) as executor:
|
||||
for package in packages:
|
||||
updates[executor.submit(run_update_script, package)] = package
|
||||
|
||||
for future in concurrent.futures.as_completed(updates):
|
||||
package = updates[future]
|
||||
|
||||
try:
|
||||
future.result()
|
||||
eprint(f" - {package['name']}: DONE.")
|
||||
except subprocess.CalledProcessError as e:
|
||||
eprint(f" - {package['name']}: ERROR")
|
||||
eprint()
|
||||
eprint(f"--- SHOWING ERROR LOG FOR {package['name']} ----------------------")
|
||||
eprint()
|
||||
eprint(e.stdout.decode('utf-8'))
|
||||
with open(f"{package['pname']}.log", 'wb') as f:
|
||||
f.write(e.stdout)
|
||||
eprint()
|
||||
eprint(f"--- SHOWING ERROR LOG FOR {package['name']} ----------------------")
|
||||
|
||||
if not keep_going:
|
||||
sys.exit(1)
|
||||
|
||||
eprint()
|
||||
eprint('Packages updated!')
|
||||
sys.exit()
|
||||
else:
|
||||
eprint('Aborting!')
|
||||
sys.exit(130)
|
||||
|
||||
parser = argparse.ArgumentParser(description='Update packages')
|
||||
parser.add_argument('--max-workers', '-j', dest='max_workers', type=int, help='Number of updates to run concurrently', nargs='?', default=4)
|
||||
parser.add_argument('--keep-going', '-k', dest='keep_going', action='store_true', help='Do not stop after first failure')
|
||||
parser.add_argument('packages', help='JSON file containing the list of package names and their update scripts')
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = parser.parse_args()
|
||||
|
||||
try:
|
||||
main(args.max_workers, args.keep_going, args.packages)
|
||||
except (KeyboardInterrupt, SystemExit) as e:
|
||||
for update in updates:
|
||||
update.cancel()
|
||||
|
||||
sys.exit(e.code if isinstance(e, SystemExit) else 130)
|
|
@ -191,7 +191,7 @@ stdenv.mkDerivation {
|
|||
# update with:
|
||||
# $ nix-shell maintainers/scripts/update.nix --argstr package firefox-bin-unwrapped
|
||||
passthru.updateScript = import ./update.nix {
|
||||
inherit name channel writeScript xidel coreutils gnused gnugrep gnupg curl;
|
||||
inherit stdenv name channel writeScript xidel coreutils gnused gnugrep gnupg curl;
|
||||
baseUrl =
|
||||
if channel == "devedition"
|
||||
then "http://archive.mozilla.org/pub/devedition/releases/"
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{ name
|
||||
{ stdenv
|
||||
, name
|
||||
, channel
|
||||
, writeScript
|
||||
, xidel
|
||||
|
@ -17,6 +18,7 @@ let
|
|||
channel != "release";
|
||||
|
||||
in writeScript "update-${name}" ''
|
||||
#!${stdenv.shell}
|
||||
PATH=${coreutils}/bin:${gnused}/bin:${gnugrep}/bin:${xidel}/bin:${curl}/bin:${gnupg}/bin
|
||||
set -eux
|
||||
pushd ${basePath}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{ writeScript
|
||||
, stdenv
|
||||
, lib
|
||||
, xidel
|
||||
, common-updater-scripts
|
||||
|
@ -13,6 +14,7 @@
|
|||
}:
|
||||
|
||||
writeScript "update-${attrPath}" ''
|
||||
#!${stdenv.shell}
|
||||
PATH=${lib.makeBinPath [ common-updater-scripts coreutils curl gnugrep gnused xidel ]}
|
||||
|
||||
url=${baseUrl}
|
||||
|
|
|
@ -131,7 +131,7 @@ stdenv.mkDerivation {
|
|||
dontStrip = true;
|
||||
dontPatchElf = true;
|
||||
|
||||
updateScript = import ./update.nix { inherit writeScript; };
|
||||
updateScript = import ./update.nix { inherit stdenv writeScript; };
|
||||
|
||||
meta = with stdenv.lib; {
|
||||
homepage = http://www.mendeley.com;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{ writeScript }:
|
||||
{ stdenv, writeScript }:
|
||||
|
||||
writeScript "update-mendeley" ''
|
||||
#!${stdenv.shell}
|
||||
function follow() {
|
||||
local URL=$1
|
||||
while true; do
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{ lib, writeScript, coreutils, curl, gnugrep, gnused, jq, common-updater-scripts, nix }:
|
||||
{ stdenv, lib, writeScript, coreutils, curl, gnugrep, gnused, jq, common-updater-scripts, nix }:
|
||||
{ name, ignored-versions ? "^2014\\.|^v[0-9]+" }:
|
||||
|
||||
let
|
||||
|
@ -9,6 +9,7 @@ let
|
|||
in
|
||||
|
||||
writeScript "update-${packageName}" ''
|
||||
#!${stdenv.shell}
|
||||
set -o errexit
|
||||
set -x
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
{ lib, writeScript, python3, common-updater-scripts, coreutils, gnugrep, gnused }:
|
||||
{ stdenv, lib, writeScript, python3, common-updater-scripts, coreutils, gnugrep, gnused }:
|
||||
{ packageName, attrPath ? packageName, versionPolicy ? "odd-unstable" }:
|
||||
|
||||
let
|
||||
python = python3.withPackages (p: [ p.requests ]);
|
||||
in writeScript "update-${packageName}" ''
|
||||
#!${stdenv.shell}
|
||||
set -o errexit
|
||||
PATH=${lib.makeBinPath [ common-updater-scripts coreutils gnugrep gnused python ]}
|
||||
latest_tag=$(python "${./find-latest-version.py}" "${packageName}" "${versionPolicy}" "stable")
|
||||
|
|
|
@ -13,6 +13,7 @@ stdenv.mkDerivation rec {
|
|||
|
||||
passthru = {
|
||||
updateScript = ''
|
||||
#!${stdenv.shell}
|
||||
cd ${toString ./.}
|
||||
${toString path}/pkgs/build-support/upstream-updater/update-walker.sh default.nix
|
||||
'';
|
||||
|
|
|
@ -16,6 +16,7 @@ stdenv.mkDerivation rec {
|
|||
cp -r python/bin $out/bin
|
||||
'';
|
||||
passthru.updateScript = ''
|
||||
#!${stdenv.shell}
|
||||
set -e
|
||||
echo
|
||||
cd ${toString ./.}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{ lib
|
||||
{ stdenv
|
||||
, lib
|
||||
, writeScript
|
||||
, coreutils
|
||||
, curl
|
||||
|
@ -11,6 +12,7 @@
|
|||
}:
|
||||
|
||||
writeScript "update-nodejs" ''
|
||||
#!${stdenv.shell}
|
||||
PATH=${lib.makeBinPath [ common-updater-scripts coreutils curl gnugrep jq gnupg nix ]}
|
||||
|
||||
HOME=`mktemp -d`
|
||||
|
|
|
@ -34,7 +34,7 @@ stdenv.mkDerivation rec {
|
|||
enableParallelBuilding = true;
|
||||
|
||||
passthru.updateScript = import ./update.nix {
|
||||
inherit lib writeScript coreutils gnugrep jq curl common-updater-scripts;
|
||||
inherit stdenv lib writeScript coreutils gnugrep jq curl common-updater-scripts;
|
||||
};
|
||||
|
||||
meta = {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{ lib, writeScript, coreutils, curl, gnugrep, jq, common-updater-scripts }:
|
||||
{ stdenv, lib, writeScript, coreutils, curl, gnugrep, jq, common-updater-scripts }:
|
||||
|
||||
writeScript "update-tp_smapi" ''
|
||||
#!${stdenv.shell}
|
||||
PATH=${lib.makeBinPath [ common-updater-scripts coreutils curl gnugrep jq ]}
|
||||
|
||||
tags=`curl -s https://api.github.com/repos/evgeni/tp_smapi/tags`
|
||||
|
|
|
@ -26,6 +26,7 @@ let self = stdenv.mkDerivation rec {
|
|||
let impl = import "${self}/share/nix/api.nix" { inherit pkgs pinConfig; }; in
|
||||
{ inherit (impl) augmentedPkgs pins callPackage; };
|
||||
updateScript = ''
|
||||
#!${stdenv.shell}
|
||||
set -e
|
||||
echo
|
||||
cd ${toString ./.}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{ lib, pkgs, fetchFromGitHub, python3Packages, nix-prefetch-scripts }:
|
||||
{ stdenv, lib, pkgs, fetchFromGitHub, python3Packages, nix-prefetch-scripts }:
|
||||
python3Packages.buildPythonApplication rec {
|
||||
version = "0.6.3";
|
||||
name = "nix-update-source-${version}";
|
||||
|
@ -28,6 +28,7 @@ python3Packages.buildPythonApplication rec {
|
|||
overrideSrc = drv: lib.overrideDerivation drv (orig: { inherit src; });
|
||||
};
|
||||
updateScript = ''
|
||||
#!${stdenv.shell}
|
||||
set -e
|
||||
echo
|
||||
cd ${toString ./.}
|
||||
|
|
Loading…
Reference in a new issue