aboutsummaryrefslogtreecommitdiff
path: root/maintainers/scripts
diff options
context:
space:
mode:
authorJan Tojnar <jtojnar@gmail.com>2020-09-20 10:29:34 +0200
committerJan Tojnar <jtojnar@gmail.com>2020-09-20 20:12:34 +0200
commit71c246c7856eafe369d673aec4ecbf7568b50a9f (patch)
tree5737bdc958a4a1ca5e62afd6af1b81b811f114b1 /maintainers/scripts
parent0c5ddf335836c521215ecc9bfbb07ba45256a7df (diff)
maintainers/scripts/update.nix: Run update scripts from the worktree
`update.nix` extracts `passthru.updateScript` attributes in the main repo and when they are relative paths (e.g. `./update.sh`), Nix will resolve them to absolute paths in the main repo. Update scripts can use $(dirname $0) to get the location of files they should update but that would point to the main repo. We want them to modify the appropriate git worktree instead so we replace the prefix accordingly. `git rev-parse --show-toplevel` will resolve symlinks but, fortunately, Nix will do that as well, so the path will match: https://github.com/NixOS/nixpkgs/pull/98304#issuecomment-695761754
Diffstat (limited to 'maintainers/scripts')
-rw-r--r--maintainers/scripts/update.py20
1 files changed, 15 insertions, 5 deletions
diff --git a/maintainers/scripts/update.py b/maintainers/scripts/update.py
index 74e36eaf80c6..8cc2bcbd67c9 100644
--- a/maintainers/scripts/update.py
+++ b/maintainers/scripts/update.py
@@ -5,6 +5,7 @@ import asyncio
import contextlib
import json
import os
+import re
import subprocess
import sys
import tempfile
@@ -30,16 +31,22 @@ async def check_subprocess(*args, **kwargs):
return process
-async def run_update_script(merge_lock: asyncio.Lock, temp_dir: Optional[Tuple[str, str]], package: Dict, keep_going: bool):
+async def run_update_script(nixpkgs_root: str, merge_lock: asyncio.Lock, temp_dir: Optional[Tuple[str, str]], package: Dict, keep_going: bool):
worktree: Optional[str] = None
+ update_script_command = package['updateScript']
+
if temp_dir is not None:
worktree, _branch = temp_dir
+ # Update scripts can use $(dirname $0) to get their location but we want to run
+ # their clones in the git worktree, not in the main nixpkgs repo.
+ update_script_command = map(lambda arg: re.sub(r'^{0}'.format(re.escape(nixpkgs_root)), worktree, arg), update_script_command)
+
eprint(f" - {package['name']}: UPDATING ...")
try:
- update_process = await check_subprocess('env', f"UPDATE_NIX_ATTR_PATH={package['attrPath']}", *package['updateScript'], stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, cwd=worktree)
+ update_process = await check_subprocess('env', f"UPDATE_NIX_ATTR_PATH={package['attrPath']}", *update_script_command, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, cwd=worktree)
update_info = await update_process.stdout.read()
await merge_changes(merge_lock, package, update_info, temp_dir)
@@ -125,7 +132,7 @@ async def merge_changes(merge_lock: asyncio.Lock, package: Dict, update_info: st
else:
eprint(f" - {package['name']}: DONE.")
-async def updater(temp_dir: Optional[Tuple[str, str]], merge_lock: asyncio.Lock, packages_to_update: asyncio.Queue[Optional[Dict]], keep_going: bool, commit: bool):
+async def updater(nixpkgs_root: str, temp_dir: Optional[Tuple[str, str]], merge_lock: asyncio.Lock, packages_to_update: asyncio.Queue[Optional[Dict]], keep_going: bool, commit: bool):
while True:
package = await packages_to_update.get()
if package is None:
@@ -135,7 +142,7 @@ async def updater(temp_dir: Optional[Tuple[str, str]], merge_lock: asyncio.Lock,
if not ('commit' in package['supportedFeatures'] or 'attrPath' in package):
temp_dir = None
- await run_update_script(merge_lock, temp_dir, package, keep_going)
+ await run_update_script(nixpkgs_root, merge_lock, temp_dir, package, keep_going)
async def start_updates(max_workers: int, keep_going: bool, commit: bool, packages: List[Dict]):
merge_lock = asyncio.Lock()
@@ -147,6 +154,9 @@ async def start_updates(max_workers: int, keep_going: bool, commit: bool, packag
# Do not create more workers than there are packages.
num_workers = min(max_workers, len(packages))
+ nixpkgs_root_process = await check_subprocess('git', 'rev-parse', '--show-toplevel', stdout=asyncio.subprocess.PIPE)
+ nixpkgs_root = (await nixpkgs_root_process.stdout.read()).decode('utf-8').strip()
+
# Set up temporary directories when using auto-commit.
for i in range(num_workers):
temp_dir = stack.enter_context(make_worktree()) if commit else None
@@ -163,7 +173,7 @@ async def start_updates(max_workers: int, keep_going: bool, commit: bool, packag
# Prepare updater workers for each temp_dir directory.
# At most `num_workers` instances of `run_update_script` will be running at one time.
- updaters = asyncio.gather(*[updater(temp_dir, merge_lock, packages_to_update, keep_going, commit) for temp_dir in temp_dirs])
+ updaters = asyncio.gather(*[updater(nixpkgs_root, temp_dir, merge_lock, packages_to_update, keep_going, commit) for temp_dir in temp_dirs])
try:
# Start updater workers.