maintainers/scripts/update.nix: support auto-committing by passing attrPath

Instead of having the updateScript support returning JSON object,
it should be sufficient to specify attrPath in passthru.updateScript.
It is much easier to use.

The former is now considered experimental.
This commit is contained in:
Jan Tojnar 2020-09-19 16:44:17 +02:00
parent 01b9d5371c
commit 4a161ddb3b
No known key found for this signature in database
GPG Key ID: 7FAB2A15F7A607A4
4 changed files with 36 additions and 9 deletions

View File

@ -475,11 +475,12 @@ passthru.updateScript = writeScript "update-zoom-us" ''
<programlisting>
passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ];
</programlisting>
Finally, the attribute can be an attribute set, listing the extra supported features among other things.
Finally, the attribute can be an attribute set, listing the attribute path and extra supported features in addition to command.
<programlisting>
passthru.updateScript = {
command = [ ../../update.sh pname ];
supportedFeatures = [ "commit" ];
attrPath = pname;
supportedFeatures = [ … ];
};
</programlisting>
<note>
@ -488,9 +489,12 @@ passthru.updateScript = {
</para>
</note>
</para>
<para>
<filename>maintainers/scripts/update.nix</filename> also supports automatically creating commits by running it with <literal>--argstr commit true</literal> but it requires either declaring the <variable>attrPath</variable>, or adding a <literal>commit</literal> to <variable>supportedFeatures</variable> and <link xlink:href="#var-passthru-updateScript-commit">modifying the script accordingly</link>.
</para>
<variablelist>
<title>Supported features</title>
<varlistentry>
<varlistentry xml:id="var-passthru-updateScript-commit">
<term>
<varname>commit</varname>
</term>

View File

@ -143,8 +143,10 @@ let
packageData = package: {
name = package.name;
pname = lib.getName package;
oldVersion = lib.getVersion package;
updateScript = map builtins.toString (lib.toList (package.updateScript.command or package.updateScript));
supportedFeatures = package.updateScript.supportedFeatures or [];
attrPath = package.updateScript.attrPath or null;
};
packagesJson = pkgs.writeText "packages.json" (builtins.toJSON (map packageData packages));

View File

@ -72,8 +72,7 @@ def make_worktree() -> Generator[Tuple[str, str], None, None]:
subprocess.run(['git', 'worktree', 'remove', '--force', target_directory])
subprocess.run(['git', 'branch', '-D', branch_name])
async def commit_changes(merge_lock: asyncio.Lock, worktree: str, branch: str, update_info: str) -> None:
changes = json.loads(update_info)
async def commit_changes(name: str, merge_lock: asyncio.Lock, worktree: str, branch: str, changes: List[Dict]) -> None:
for change in changes:
# Git can only handle a single index operation at a time
async with merge_lock:
@ -85,7 +84,29 @@ async def commit_changes(merge_lock: asyncio.Lock, worktree: str, branch: str, u
async def merge_changes(merge_lock: asyncio.Lock, package: Dict, update_info: str, temp_dir: Optional[Tuple[str, str]]) -> None:
if temp_dir is not None:
worktree, branch = temp_dir
await commit_changes(merge_lock, worktree, branch, update_info)
if 'commit' in package['supportedFeatures']:
changes = json.loads(update_info)
elif 'attrPath' in package:
attr_path = package['attrPath']
obtain_new_version_process = await check_subprocess('nix-instantiate', '--expr', f'with import ./. {{}}; lib.getVersion {attr_path}', '--eval', '--strict', '--json', stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, cwd=worktree)
new_version = json.loads((await obtain_new_version_process.stdout.read()).decode('utf-8'))
changed_files_process = await check_subprocess('git', 'diff', '--name-only', stdout=asyncio.subprocess.PIPE, cwd=worktree)
changed_files = (await changed_files_process.stdout.read()).splitlines()
if len(changed_files) > 0:
changes = [
{
'files': changed_files,
'oldVersion': package['oldVersion'],
'newVersion': new_version,
'attrPath': attr_path,
}
]
else:
changes = []
await commit_changes(package['name'], merge_lock, worktree, branch, changes)
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):
@ -95,7 +116,7 @@ async def updater(temp_dir: Optional[Tuple[str, str]], merge_lock: asyncio.Lock,
# A sentinel received, we are done.
return
if not ('commit' in package['supportedFeatures']):
if not ('commit' in package['supportedFeatures'] or 'attrPath' in package):
temp_dir = None
await run_update_script(merge_lock, temp_dir, package, keep_going)

View File

@ -21,9 +21,9 @@ let
version_policy="$3"
PATH=${lib.makeBinPath [ common-updater-scripts python ]}
latest_tag=$(python "${./find-latest-version.py}" "$package_name" "$version_policy" "stable" ${upperBoundFlag})
update-source-version "$attr_path" "$latest_tag" --print-changes
update-source-version "$attr_path" "$latest_tag"
'';
in {
command = [ updateScript packageName attrPath versionPolicy ];
supportedFeatures = [ "commit" ];
inherit attrPath;
}