mirror of
https://github.com/armbian/build
synced 2025-09-24 19:47:06 +07:00
patching: auto patchers: bare dts, bare overlays, DT Makefile
This commit is contained in:
30
lib/tools/autopatch-devicetree-makefile.py
Normal file
30
lib/tools/autopatch-devicetree-makefile.py
Normal file
@@ -0,0 +1,30 @@
|
||||
# ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Copyright (c) 2023 Ricardo Pardini <ricardo@pardini.net>
|
||||
# This file is a part of the Armbian Build Framework https://github.com/armbian/build/
|
||||
# ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹
|
||||
|
||||
# So this thing takes
|
||||
# - an absolute path to a kernel check-ed out git tree (GIT_WORK_DIR=/Volumes/LinuxDev/mainline-kernel-3rd-party-rebase)
|
||||
# - the relative path to a Device Tree directory (DT_REL_DIR=arch/arm64/boot/dts/amlogic)
|
||||
# and will for the DT_REL_DIR:
|
||||
# - find all the .dts files
|
||||
# - find the Makefile
|
||||
# It will then regex-parse the Makefile for the CONFIG_ARCH_xxx variable, find the preamble and postamble, and insert the DT files in between.
|
||||
|
||||
import logging
|
||||
|
||||
import common.armbian_utils as armbian_utils
|
||||
import common.dt_makefile_patcher as dt_makefile_patcher
|
||||
|
||||
# Prepare logging
|
||||
armbian_utils.setup_logging()
|
||||
log: logging.Logger = logging.getLogger("patching")
|
||||
|
||||
# Show the environment variables we've been called with
|
||||
armbian_utils.show_incoming_environment()
|
||||
|
||||
GIT_WORK_DIR = armbian_utils.get_from_env("GIT_WORK_DIR", "/Volumes/LinuxDev/mainline-kernel-3rd-party-rebase")
|
||||
DT_REL_DIR = armbian_utils.get_from_env("DT_REL_DIR", "arch/arm64/boot/dts/amlogic")
|
||||
|
||||
dt_makefile_patcher.auto_patch_dt_makefile(GIT_WORK_DIR, DT_REL_DIR)
|
||||
@@ -38,8 +38,8 @@ def parse_env_for_tokens(env_name):
|
||||
return [token for token in [token.strip() for token in (tokens)] if token != ""]
|
||||
|
||||
|
||||
def get_from_env(env_name):
|
||||
value = os.environ.get(env_name, None)
|
||||
def get_from_env(env_name, default=None):
|
||||
value = os.environ.get(env_name, default)
|
||||
if value is not None:
|
||||
value = value.strip()
|
||||
return value
|
||||
|
||||
191
lib/tools/common/dt_makefile_patcher.py
Normal file
191
lib/tools/common/dt_makefile_patcher.py
Normal file
@@ -0,0 +1,191 @@
|
||||
# ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Copyright (c) 2023 Ricardo Pardini <ricardo@pardini.net>
|
||||
# This file is a part of the Armbian Build Framework https://github.com/armbian/build/
|
||||
# ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹
|
||||
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
|
||||
import git
|
||||
from git import Actor
|
||||
|
||||
from common.patching_config import PatchingConfig
|
||||
from common.patching_utils import PatchRootDir
|
||||
|
||||
log: logging.Logger = logging.getLogger("dt_makefile_patcher")
|
||||
|
||||
|
||||
class AutoPatcherParams:
|
||||
def __init__(
|
||||
self,
|
||||
pconfig: PatchingConfig,
|
||||
git_work_dir: str,
|
||||
root_types_order: list[str],
|
||||
root_dirs_by_root_type: dict[str, list[PatchRootDir]],
|
||||
apply_patches_to_git: bool,
|
||||
git_repo: git.Repo):
|
||||
self.pconfig = pconfig
|
||||
self.git_work_dir = git_work_dir
|
||||
self.root_types_order = root_types_order
|
||||
self.root_dirs_by_root_type = root_dirs_by_root_type
|
||||
self.apply_patches_to_git = apply_patches_to_git
|
||||
self.git_repo = git_repo
|
||||
|
||||
|
||||
def auto_patch_dt_makefile(git_work_dir: str, dt_rel_dir: str) -> dict[str, str]:
|
||||
ret: dict[str, str] = {}
|
||||
dt_path = os.path.join(git_work_dir, dt_rel_dir)
|
||||
# Bomb if it does not exist or is not a directory
|
||||
if not os.path.isdir(dt_path):
|
||||
raise ValueError(f"DT_PATH={dt_path} is not a directory")
|
||||
makefile_path = os.path.join(dt_path, "Makefile")
|
||||
# Bomb if it does not exist or is not a file
|
||||
if not os.path.isfile(makefile_path):
|
||||
raise ValueError(f"MAKEFILE_PATH={makefile_path} is not a file")
|
||||
|
||||
ret["MAKEFILE_PATH"] = makefile_path
|
||||
|
||||
# Grab the contents of the Makefile
|
||||
with open(makefile_path, "r") as f:
|
||||
makefile_contents = f.read()
|
||||
log.info(f"Read {len(makefile_contents)} bytes from {makefile_path}")
|
||||
log.debug(f"Contents:\n{makefile_contents}")
|
||||
# Parse it into a list of lines
|
||||
makefile_lines = makefile_contents.splitlines()
|
||||
log.info(f"Read {len(makefile_lines)} lines from {makefile_path}")
|
||||
regex = r"^dtb-\$\(([a-zA-Z_]+)\)\s+\+=\s+([a-zA-Z0-9-_]+)\.dtb"
|
||||
# For each line, check if it matches the regex, extract the groups
|
||||
line_counter = 0
|
||||
line_first_match = 0
|
||||
line_last_match = 0
|
||||
config_var_dict: set[str] = set()
|
||||
for line in makefile_lines:
|
||||
line_counter += 1
|
||||
match = re.match(regex, line)
|
||||
if match:
|
||||
line_first_match = line_counter if line_first_match == 0 else line_first_match
|
||||
line_last_match = line_counter
|
||||
config_var_dict.add(match.group(1))
|
||||
# Sanity check, make sure config_var_dict is not empty and has only one element
|
||||
if len(config_var_dict) != 1:
|
||||
raise ValueError(f"config_var_dict={config_var_dict} -- found too few or too many CONFIG_ARCH_xx variables in {makefile_path}")
|
||||
config_var = config_var_dict.pop()
|
||||
log.info(f"Found '{config_var}' in Makefile lines {line_first_match} to {line_last_match}")
|
||||
# Now compute the preambles and the postamble
|
||||
preamble_lines = makefile_lines[:line_first_match - 1]
|
||||
postamble_lines = makefile_lines[line_last_match:]
|
||||
# Find all .dts files in DT_PATH (not subdirectories), but add to the list without .dts suffix
|
||||
dts_files = []
|
||||
listdir: list[str] = os.listdir(dt_path)
|
||||
for file in listdir:
|
||||
if file.endswith(".dts"):
|
||||
dts_files.append(file[:-4])
|
||||
# sort the list. alpha-sort: `meson-sm1-a95xf3-air-gbit` should come sooner than `meson-sm1-a95xf3-air`? why?
|
||||
dts_files.sort()
|
||||
log.info(f"Found {len(dts_files)} .dts files in {dt_path}")
|
||||
# Show them all
|
||||
for dts_file in dts_files:
|
||||
log.debug(f"Found {dts_file}")
|
||||
# Create the mid-amble, which is the list of .dtb files to be built
|
||||
midamble_lines = []
|
||||
for dts_file in dts_files:
|
||||
midamble_lines.append(f"dtb-$({config_var}) += {dts_file}.dtb")
|
||||
|
||||
# Late to the game: if DT_DIR/overlay/Makefile exists, add it.
|
||||
overlay_lines = []
|
||||
DT_OVERLAY_PATH = os.path.join(dt_path, "overlay")
|
||||
DT_OVERLAY_MAKEFILE_PATH = os.path.join(DT_OVERLAY_PATH, "Makefile")
|
||||
if os.path.isfile(DT_OVERLAY_MAKEFILE_PATH):
|
||||
ret["DT_OVERLAY_MAKEFILE_PATH"] = DT_OVERLAY_MAKEFILE_PATH
|
||||
ret["DT_OVERLAY_PATH"] = DT_OVERLAY_PATH
|
||||
overlay_lines.append("")
|
||||
overlay_lines.append("subdir-y := $(dts-dirs) overlay")
|
||||
|
||||
# Now join the preambles, midamble, postamble and overlay stuff into a single list
|
||||
new_makefile_lines = preamble_lines + midamble_lines + postamble_lines + overlay_lines
|
||||
# Rewrite the Makefile with the new contents
|
||||
with open(makefile_path, "w") as f:
|
||||
f.write("\n".join(new_makefile_lines))
|
||||
log.info(f"Wrote {len(new_makefile_lines)} lines to {makefile_path}")
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def copy_bare_files(autopatcher_params: AutoPatcherParams, type: str):
|
||||
# group the pconfig.dts_directories by target dir
|
||||
dts_dirs_by_target = {}
|
||||
if type == "dt":
|
||||
config_dirs = autopatcher_params.pconfig.dts_directories
|
||||
elif type == "overlay":
|
||||
config_dirs = autopatcher_params.pconfig.overlay_directories
|
||||
else:
|
||||
raise ValueError(f"Unknown copy_bare_files::type {type}")
|
||||
|
||||
for one_dts_dir in config_dirs:
|
||||
if one_dts_dir.target not in dts_dirs_by_target:
|
||||
dts_dirs_by_target[one_dts_dir.target] = []
|
||||
dts_dirs_by_target[one_dts_dir.target].append(one_dts_dir.source)
|
||||
|
||||
# for each target....
|
||||
for target_dir in dts_dirs_by_target:
|
||||
all_files_to_copy = []
|
||||
dts_source_dirs = dts_dirs_by_target[target_dir]
|
||||
full_path_target_dir = os.path.join(autopatcher_params.git_work_dir, target_dir)
|
||||
if not os.path.exists(full_path_target_dir):
|
||||
os.makedirs(full_path_target_dir)
|
||||
|
||||
for one_dts_dir in dts_source_dirs:
|
||||
for type_in_order in autopatcher_params.root_types_order:
|
||||
root_dirs = autopatcher_params.root_dirs_by_root_type[type_in_order]
|
||||
for root_dir in root_dirs:
|
||||
full_path_source = os.path.join(root_dir.abs_dir, one_dts_dir)
|
||||
log.warning(f"Would copy {full_path_source} to {full_path_target_dir}...")
|
||||
if not os.path.isdir(full_path_source):
|
||||
continue
|
||||
# get a list of regular files in the source directory
|
||||
files_to_copy = [
|
||||
os.path.join(full_path_source, f) for f in os.listdir(full_path_source)
|
||||
if os.path.isfile(os.path.join(full_path_source, f))
|
||||
]
|
||||
all_files_to_copy.extend(files_to_copy)
|
||||
# Create a dict of base filename -> list of full paths; this way userpatches with same name take precedence
|
||||
all_files_to_copy_dict = {}
|
||||
for one_file in all_files_to_copy:
|
||||
base_filename = os.path.basename(one_file)
|
||||
all_files_to_copy_dict[base_filename] = one_file
|
||||
# do the actual copy
|
||||
all_copied_files = []
|
||||
for one_file in all_files_to_copy_dict:
|
||||
log.warning(f"Copy '{one_file}' (from {all_files_to_copy_dict[one_file]}) to '{full_path_target_dir}'...")
|
||||
full_path_target_file = os.path.join(full_path_target_dir, one_file)
|
||||
shutil.copyfile(all_files_to_copy_dict[one_file], full_path_target_file)
|
||||
all_copied_files.append(full_path_target_file)
|
||||
|
||||
# If more than 0 files were copied, commit them if we're doing commits
|
||||
if autopatcher_params.apply_patches_to_git and len(all_copied_files) > 0:
|
||||
autopatcher_params.git_repo.git.add(all_copied_files)
|
||||
maintainer_actor: Actor = Actor(f"Armbian Bare {type.upper()} AutoPatcher", "patching@armbian.com")
|
||||
commit = autopatcher_params.git_repo.index.commit(
|
||||
message=f"Armbian Bare Device Tree files for {target_dir}"
|
||||
, author=maintainer_actor, committer=maintainer_actor, skip_hooks=True
|
||||
)
|
||||
log.info(f"Committed Bare {type.upper()} changes to git: {commit.hexsha} for {target_dir}")
|
||||
log.info(f"Done with Bare {type.upper()} autopatch commit for {target_dir}.")
|
||||
|
||||
|
||||
def auto_patch_all_dt_makefiles(autopatcher_params: AutoPatcherParams):
|
||||
for one_autopatch_config in autopatcher_params.pconfig.autopatch_makefile_dt_configs:
|
||||
log.warning(f"Autopatching DT Makefile in {one_autopatch_config.directory}...")
|
||||
autopatch_makefile_info = auto_patch_dt_makefile(autopatcher_params.git_work_dir, one_autopatch_config.directory)
|
||||
if autopatcher_params.apply_patches_to_git:
|
||||
autopatcher_params.git_repo.git.add(autopatch_makefile_info["MAKEFILE_PATH"])
|
||||
maintainer_actor: Actor = Actor("Armbian DT Makefile AutoPatcher", "patching@armbian.com")
|
||||
commit = autopatcher_params.git_repo.index.commit(
|
||||
message=f"Armbian automatic DT Makefile patch for {one_autopatch_config.directory}",
|
||||
author=maintainer_actor, committer=maintainer_actor, skip_hooks=True
|
||||
)
|
||||
log.info(f"Committed changes to git: {commit.hexsha} for {one_autopatch_config.directory}")
|
||||
log.info(f"Done with Makefile autopatch commit for {one_autopatch_config.directory}.")
|
||||
84
lib/tools/common/patching_config.py
Normal file
84
lib/tools/common/patching_config.py
Normal file
@@ -0,0 +1,84 @@
|
||||
# ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Copyright (c) 2023 Ricardo Pardini <ricardo@pardini.net>
|
||||
# This file is a part of the Armbian Build Framework https://github.com/armbian/build/
|
||||
# ‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹
|
||||
|
||||
import logging
|
||||
|
||||
import yaml
|
||||
|
||||
log: logging.Logger = logging.getLogger("patching_config")
|
||||
|
||||
|
||||
class PatchingAutoPatchMakefileDTConfig:
|
||||
|
||||
def __init__(self, data: dict):
|
||||
self.config_var: str = data.get("config-var", None)
|
||||
self.directory: str = data.get("directory", None)
|
||||
|
||||
def __str__(self):
|
||||
return f"PatchingAutoPatchMakefileDTConfig(config-var={self.config_var}, directory={self.directory})"
|
||||
|
||||
|
||||
class PatchingDTSDirectoryConfig:
|
||||
def __init__(self, data: dict):
|
||||
self.source: str = data.get("source", None)
|
||||
self.target: str = data.get("target", None)
|
||||
|
||||
def __str__(self):
|
||||
return f"PatchingDTSDirectoryConfig(source={self.source}, target={self.target})"
|
||||
|
||||
|
||||
class PatchingOverlayDirectoryConfig:
|
||||
def __init__(self, data: dict):
|
||||
self.source: str = data.get("source", None)
|
||||
self.target: str = data.get("target", None)
|
||||
|
||||
def __str__(self):
|
||||
return f"PatchingOverlayDirectoryConfig(source={self.source}, target={self.target})"
|
||||
|
||||
|
||||
class PatchingToGitConfig:
|
||||
def __init__(self, data: dict):
|
||||
self.do_not_commit_files: list[str] = data.get("do-not-commit-files", [])
|
||||
self.do_not_commit_regexes: list[str] = data.get("do-not-commit-regexes", [])
|
||||
|
||||
def __str__(self):
|
||||
return f"PatchingToGitConfig(do_not_commit_files={self.do_not_commit_files}, do_not_commit_regexes={self.do_not_commit_regexes})"
|
||||
|
||||
|
||||
class PatchingConfig:
|
||||
def __init__(self, yaml_config_file_paths: list[str]):
|
||||
self.yaml_config_file_paths = yaml_config_file_paths
|
||||
if len(yaml_config_file_paths) == 0:
|
||||
self.yaml_config = {}
|
||||
else:
|
||||
# I'm lazy, single one for now.
|
||||
self.yaml_config = self.read_yaml_config(yaml_config_file_paths[0])["config"]
|
||||
|
||||
self.patches_to_git_config: PatchingToGitConfig = PatchingToGitConfig(self.yaml_config.get("patches-to-git", {}))
|
||||
|
||||
# Parse out the different parts of the config
|
||||
# DT Makefile auto-patch config
|
||||
self.autopatch_makefile_dt_configs: list[PatchingAutoPatchMakefileDTConfig] = [
|
||||
PatchingAutoPatchMakefileDTConfig(data) for data in self.yaml_config.get("auto-patch-dt-makefile", [])
|
||||
]
|
||||
self.has_autopatch_makefile_dt_configs: bool = len(self.autopatch_makefile_dt_configs) > 0
|
||||
|
||||
# DTS directories to copy config
|
||||
self.dts_directories: list[PatchingDTSDirectoryConfig] = [
|
||||
PatchingDTSDirectoryConfig(data) for data in self.yaml_config.get("dts-directories", [])
|
||||
]
|
||||
self.has_dts_directories: bool = len(self.dts_directories) > 0
|
||||
|
||||
# Overlay directories to copy config
|
||||
self.overlay_directories: list[PatchingOverlayDirectoryConfig] = [
|
||||
PatchingOverlayDirectoryConfig(data) for data in self.yaml_config.get("overlay-directories", [])
|
||||
]
|
||||
self.has_overlay_directories: bool = len(self.overlay_directories) > 0
|
||||
|
||||
def read_yaml_config(self, yaml_config_file_path):
|
||||
with open(yaml_config_file_path) as f:
|
||||
yaml_config = yaml.load(f, Loader=yaml.FullLoader)
|
||||
return yaml_config
|
||||
@@ -19,6 +19,8 @@ import git # GitPython
|
||||
from unidecode import unidecode
|
||||
from unidiff import PatchSet
|
||||
|
||||
from common.patching_config import PatchingConfig
|
||||
|
||||
MAGIC_MBOX_MARKER_STANDARD = "Mon Sep 17 00:00:00 2001"
|
||||
MAGIC_MBOX_MARKER_B4 = "git@z Thu Jan 1 00:00:00 1970"
|
||||
|
||||
@@ -456,7 +458,7 @@ class PatchInPatchFile:
|
||||
self.problems.append("failed_apply")
|
||||
raise Exception(f"Failed to apply patch {self.parent.full_file_path()}")
|
||||
|
||||
def commit_changes_to_git(self, repo: git.Repo, add_rebase_tags: bool, split_patches: bool):
|
||||
def commit_changes_to_git(self, repo: git.Repo, add_rebase_tags: bool, split_patches: bool, pconfig: PatchingConfig):
|
||||
log.info(f"Committing changes to git: {self.parent.relative_dirs_and_base_file_name}")
|
||||
# add all the files that were touched by the patch
|
||||
# if the patch failed to parse, this will be an empty list, so we'll just add all changes.
|
||||
@@ -496,7 +498,13 @@ class PatchInPatchFile:
|
||||
return self.commit_changes_to_git_grouped(all_files_to_add, repo)
|
||||
|
||||
if not add_all_changes_in_git:
|
||||
repo.git.add("-f", all_files_to_add)
|
||||
log.debug(f"Adding (pre-config ) {len(all_files_to_add)} files to git: {' '.join(all_files_to_add)}")
|
||||
do_not_commit_files = pconfig.patches_to_git_config.do_not_commit_files # from config
|
||||
do_not_commit_regexes = pconfig.patches_to_git_config.do_not_commit_regexes # from config
|
||||
final_files_to_add = [f for f in all_files_to_add if f not in do_not_commit_files]
|
||||
final_files_to_add = [f for f in final_files_to_add if not any(re.match(r, f) for r in do_not_commit_regexes)]
|
||||
log.debug(f"Adding (post-config) {len(final_files_to_add)} files to git: {' '.join(final_files_to_add)}")
|
||||
repo.git.add("-f", final_files_to_add)
|
||||
|
||||
if self.failed_to_parse or self.parent.patch_dir.is_autogen_dir or add_all_changes_in_git:
|
||||
log.warning(f"Rescue: adding all changed files to git for {self}")
|
||||
|
||||
@@ -18,9 +18,11 @@ from git import InvalidGitRepositoryError
|
||||
from git import Repo
|
||||
|
||||
import common.armbian_utils as armbian_utils
|
||||
import common.dt_makefile_patcher as dt_makefile_patcher
|
||||
import common.patching_utils as patching_utils
|
||||
from common.md_asset_log import SummarizedMarkdownWriter
|
||||
from common.md_asset_log import get_gh_pages_workflow_script
|
||||
from common.patching_config import PatchingConfig
|
||||
|
||||
# Prepare logging
|
||||
armbian_utils.setup_logging()
|
||||
@@ -31,6 +33,9 @@ armbian_utils.show_incoming_environment()
|
||||
|
||||
# @TODO: test that "patch --version" is >= 2.7.6 using a subprocess and parsing the output.
|
||||
|
||||
# Consts
|
||||
CONST_CONFIG_YAML_FILE: str = '0000.patching_config.yaml'
|
||||
|
||||
# Let's start by reading environment variables.
|
||||
# Those are always needed, and we should bomb if they're not set.
|
||||
SRC = armbian_utils.get_from_env_or_bomb("SRC")
|
||||
@@ -91,6 +96,29 @@ for patch_root_dir in CONST_PATCH_ROOT_DIRS:
|
||||
for patch_sub_dir in CONST_PATCH_SUB_DIRS:
|
||||
ALL_DIRS.append(patching_utils.PatchDir(patch_root_dir, patch_sub_dir, SRC))
|
||||
|
||||
# Group the root directories by root_type.
|
||||
ROOT_DIRS_BY_ROOT_TYPE: dict[str, list[patching_utils.PatchRootDir]] = {}
|
||||
for patch_root_dir in CONST_PATCH_ROOT_DIRS:
|
||||
if patch_root_dir.root_type not in ROOT_DIRS_BY_ROOT_TYPE:
|
||||
ROOT_DIRS_BY_ROOT_TYPE[patch_root_dir.root_type] = []
|
||||
ROOT_DIRS_BY_ROOT_TYPE[patch_root_dir.root_type].append(patch_root_dir)
|
||||
|
||||
# Search the root directories for a 0000.patching_config.yaml file. It can be either in core or userpatches, and if both found, they're merged.
|
||||
CONST_ROOT_TYPES_CONFIG_ORDER = ['core', 'user'] # user patches configs are added last, so they override core patches configs.
|
||||
all_yaml_config_files: list[str] = []
|
||||
for root_type in CONST_ROOT_TYPES_CONFIG_ORDER:
|
||||
if root_type not in ROOT_DIRS_BY_ROOT_TYPE:
|
||||
continue
|
||||
for root_patch_dir in ROOT_DIRS_BY_ROOT_TYPE[root_type]:
|
||||
full_yaml_config_path = os.path.join(root_patch_dir.abs_dir, CONST_CONFIG_YAML_FILE)
|
||||
log.debug(f"Looking for config file: '{full_yaml_config_path}'")
|
||||
if os.path.isfile(full_yaml_config_path):
|
||||
log.info(f"Found patching config file: '{full_yaml_config_path}'")
|
||||
all_yaml_config_files.append(full_yaml_config_path)
|
||||
|
||||
# load the configs and merge them.
|
||||
pconfig: PatchingConfig = PatchingConfig(all_yaml_config_files)
|
||||
|
||||
PATCH_FILES_FIRST: list[patching_utils.PatchFileInDir] = []
|
||||
EXTRA_PATCH_FILES_FIRST: list[str] = armbian_utils.parse_env_for_tokens("EXTRA_PATCH_FILES_FIRST")
|
||||
EXTRA_PATCH_HASHES_FIRST: list[str] = armbian_utils.parse_env_for_tokens("EXTRA_PATCH_HASHES_FIRST")
|
||||
@@ -252,6 +280,11 @@ if apply_patches:
|
||||
|
||||
patching_utils.prepare_clean_git_tree_for_patching(git_repo, BASE_GIT_REVISION, BRANCH_FOR_PATCHES)
|
||||
|
||||
# the autopatcher params
|
||||
autopatcher_params: dt_makefile_patcher.AutoPatcherParams = dt_makefile_patcher.AutoPatcherParams(
|
||||
pconfig, GIT_WORK_DIR, CONST_ROOT_TYPES_CONFIG_ORDER, ROOT_DIRS_BY_ROOT_TYPE, apply_patches_to_git, git_repo
|
||||
)
|
||||
|
||||
# Loop over the VALID_PATCHES, and apply them
|
||||
log.info(f"Applying {total_patches} patches {patch_file_desc}...")
|
||||
# Grab the date of the root Makefile; that is the minimum date for the patched files.
|
||||
@@ -276,15 +309,14 @@ if apply_patches:
|
||||
failed_to_apply_list.append(one_patch)
|
||||
|
||||
if one_patch.applied_ok and apply_patches_to_git:
|
||||
committed = one_patch.commit_changes_to_git(git_repo, (not rewrite_patches_in_place), split_patches)
|
||||
committed = one_patch.commit_changes_to_git(git_repo, (not rewrite_patches_in_place), split_patches, pconfig)
|
||||
|
||||
if not split_patches:
|
||||
commit_hash = committed['commit_hash']
|
||||
one_patch.git_commit_hash = commit_hash
|
||||
|
||||
if rewrite_patches_in_place:
|
||||
rewritten_patch = patching_utils.export_commit_as_patch(
|
||||
git_repo, commit_hash)
|
||||
rewritten_patch = patching_utils.export_commit_as_patch(git_repo, commit_hash)
|
||||
one_patch.rewritten_patch = rewritten_patch
|
||||
|
||||
if (not apply_patches_to_git) and (not rewrite_patches_in_place) and any_failed_to_apply:
|
||||
@@ -292,6 +324,18 @@ if apply_patches:
|
||||
f"Failed to apply {len(failed_to_apply_list)} patches: {','.join([failed_patch.__str__() for failed_patch in failed_to_apply_list])}")
|
||||
exit_with_exception = Exception(f"Failed to apply {len(failed_to_apply_list)} patches.")
|
||||
|
||||
# Include the dts/dtsi marked dts-directories in the config
|
||||
if pconfig.has_dts_directories:
|
||||
dt_makefile_patcher.copy_bare_files(autopatcher_params, "dt")
|
||||
|
||||
# Include the overlay stuff
|
||||
if pconfig.has_dts_directories:
|
||||
dt_makefile_patcher.copy_bare_files(autopatcher_params, "overlay")
|
||||
|
||||
# Autopatch the Makefile(s) according to the config
|
||||
if pconfig.has_autopatch_makefile_dt_configs:
|
||||
dt_makefile_patcher.auto_patch_all_dt_makefiles(autopatcher_params)
|
||||
|
||||
if rewrite_patches_in_place:
|
||||
# Now; we need to write the patches to files.
|
||||
# loop over the patches, and group them by the parent; the parent is the PatchFileInDir object.
|
||||
|
||||
Reference in New Issue
Block a user