poky/scripts/b4-wrapper-poky.py
Quentin Schulz 31a537d124 b4-wrapper-poky.py: send changes to .b4-config to the poky mailing list
Both OE-Core and poky git repos have a .b4-config, both at the same
location and both different.

Therefore, changes made to .b4-config for OE-Core need to be sent to the
OE-Core mailing list and changes made to .b4-config for poky sent to the
poky mailing list.

Changes made to OE-Core's .b4-config can only be made from a vanilla
OE-Core git repo, not from poky git repo. With the current content of
OE-Core's .b4-config, b4-wrapper-poky.py script is NOT called to figure
out where to send patches, b4 gets it from the hardcoded value in
send-series-to.

Thus, we can say that if b4-wrapper-poky.py detects changes for
.b4-config, those changes are for poky since this script wouldn't be run
by b4 outside of poky git repo.

(From OE-Core rev: 1006712027812326fdeade2ab539b42bdf5b10e6)

Signed-off-by: Quentin Schulz <quentin.schulz@cherry.de>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2025-02-10 13:03:58 +00:00

184 lines
6.4 KiB
Python
Executable File

#!/usr/bin/env python3
#
# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: MIT
#
# This script is to be called by b4:
# - through the b4.prep-perpatch-check-cmd with "prep-perpatch-check-cmd" as
# first argument,
# - through b4.send-auto-cc-cmd with "send-auto-cc-cmd" as first argument,
# - through b4.send-auto-to-cmd with "send-auto-to-cmd" as first argument,
#
# When prep-perpatch-check-cmd is passsed:
#
# This checks that a patch makes changes to at most one project in the poky
# combo repo (that is, out of yocto-docs, bitbake, openembedded-core combined
# into poky and the poky-specific files).
#
# Printing something to stdout in this file will result in b4 prep --check fail
# for the currently parsed patch.
#
# It checks that all patches in the series make changes to at most one project.
#
# When send-auto-cc-cmd is passed:
#
# This returns the list of Cc recipients for a patch.
#
# When send-auto-to-cmd is passed:
#
# This returns the list of To recipients for a patch.
#
# This script takes as stdin a patch.
import pathlib
import re
import shutil
import subprocess
import sys
cmd = sys.argv[1]
patch = sys.stdin.readlines()
# Subject field is used to identify the last patch as this script is called for
# each patch. We edit the same file in a series by using the References field
# unique identifier to check which projects are modified by earlier patches in
# the series. To avoid cluttering the disk, the last patch in the list removes
# that shared file.
re_subject = re.compile(r'^Subject:.*\[.*PATCH.*\s(\d+)/\1')
re_ref = re.compile(r'^References: <(.*)>$')
subject = None
ref = None
if not shutil.which("lsdiff"):
print("lsdiff missing from host, please install patchutils")
sys.exit(-1)
try:
one_patch_series = False
for line in patch:
subject = re_subject.match(line)
if subject:
# Handle [PATCH 1/1]
if subject.group(1) == 1:
one_patch_series = True
break
if re.match(r'^Subject: .*\[.*PATCH[^/]*\]', line):
# Single patch is named [PATCH] but if there are prefix, it could be
# [PATCH prefix], so handle everything that doesn't have a /
# character which is used as separator between current patch number
# and total patch number
one_patch_series = True
break
if cmd == "prep-perpatch-check-cmd" and not one_patch_series:
for line in patch:
ref = re_ref.match(line)
if ref:
break
if not ref:
print("Failed to find ref to cover letter (References:)...")
sys.exit(-2)
ref = ref.group(1)
series_check = pathlib.Path(f".tmp-{ref}")
patch = "".join(patch)
if cmd == "send-auto-cc-cmd":
# Patches to BitBake documentation should also go to yocto-docs mailing list
project_paths = {
"yocto-docs": ["bitbake/doc/*"],
}
else:
project_paths = {
"bitbake": ["bitbake/*"],
"yocto-docs": ["documentation/*"],
"poky": [
"meta-poky/*",
"meta-yocto-bsp/*",
"README.hardware.md",
"README.poky.md",
# scripts/b4-wrapper-poky.py is only run by b4 when in poky
# git repo. With that limitation, changes made to .b4-config
# can only be for poky's and not OE-Core's as only poky's is
# stored in poky git repo.
".b4-config",
],
}
# List of projects touched by this patch
projs = []
# Any file not matched by any path in project_paths means it is from
# OE-Core.
# When matching some path in project_paths, remove the matched files from
# that list.
files_left = subprocess.check_output(["lsdiff", "--strip-match=1", "--strip=1"],
input=patch, text=True)
files_left = set(files_left)
for proj, proj_paths in project_paths.items():
lsdiff_args = [f"--include={path}" for path in proj_paths]
files = subprocess.check_output(["lsdiff", "--strip-match=1", "--strip=1"] + lsdiff_args,
input=patch, text=True)
if len(files):
files_left = files_left - set(files)
projs.append(proj)
continue
# Handle patches made with --no-prefix
files = subprocess.check_output(["lsdiff"] + lsdiff_args,
input=patch, text=True)
if len(files):
files_left = files_left - set(files)
projs.append(proj)
# Catch-all for everything not poky-specific or in bitbake/yocto-docs
if len(files_left) and cmd != "send-auto-cc-cmd":
projs.append("openembedded-core")
if cmd == "prep-perpatch-check-cmd":
if len(projs) > 1:
print(f"Diff spans more than one project ({', '.join(sorted(projs))}), split into multiple commits...")
sys.exit(-3)
# No need to check other patches in the series as there aren't any
if one_patch_series:
sys.exit(0)
# This should be replaced once b4 supports prep-perseries-check-cmd (or something similar)
if series_check.exists():
# NOT race-free if b4 decides to parallelize prep-perpatch-check-cmd
series_projs = series_check.read_text().split('\n')
else:
series_projs = []
series_projs += projs
uniq_series_projs = set(series_projs)
# NOT race-free, if b4 decides to parallelize prep-perpatch-check-cmd
series_check.write_text('\n'.join(uniq_series_projs))
if len(uniq_series_projs) > 1:
print(f"Series spans more than one project ({', '.join(sorted(uniq_series_projs))}), split into multiple series...")
sys.exit(-4)
else: # send-auto-cc-cmd / send-auto-to-cmd
ml_projs = {
"bitbake": "bitbake-devel@lists.openembedded.org",
"yocto-docs": "docs@lists.yoctoproject.org",
"poky": "poky@lists.yoctoproject.org",
"openembedded-core": "openembedded-core@lists.openembedded.org",
}
print("\n".join([ml_projs[ml] for ml in projs]))
sys.exit(0)
finally:
# Last patch in the series, cleanup tmp file
if subject and ref and series_check.exists():
series_check.unlink()