1
0

Add blacklist of failed patches

This commit is contained in:
2026-03-26 11:59:15 +01:00
parent 1c8e58e34d
commit eb938b7d89
3 changed files with 157 additions and 3 deletions

4
.gitignore vendored
View File

@@ -2,10 +2,8 @@
kobo_usb_root/
firmware/
# Pre-built kobopatch tool (reference only)
kobopatch/
# Kobopatch WASM build artifacts
kobopatch-wasm/kobopatch
kobopatch-wasm/go/
kobopatch-wasm/kobopatch-src/
kobopatch-wasm/kobopatch.wasm

135
kobopatch-wasm/test-patches.sh Executable file
View File

@@ -0,0 +1,135 @@
#!/bin/bash
set -euo pipefail
# Test all patches against the cached firmware using kobopatch -t.
# This builds the native kobopatch binary, extracts the patch set,
# and runs each patch in test mode to check if it can be applied.
cd "$(dirname "$0")"
# Use local Go if available
LOCAL_GO_DIR="$(pwd)/go"
if [ -x "$LOCAL_GO_DIR/bin/go" ]; then
export GOROOT="$LOCAL_GO_DIR"
export PATH="$LOCAL_GO_DIR/bin:$PATH"
fi
FIRMWARE_FILE="${FIRMWARE_ZIP:-$(cd .. && pwd)/tests/cached_assets/kobo-update-4.45.23646.zip}"
PATCHES_ZIP="${PATCHES_ZIP:-$(cd .. && pwd)/web/src/patches/patches_4.45.zip}"
if [ ! -f "$FIRMWARE_FILE" ]; then
echo "ERROR: Firmware zip not found at $FIRMWARE_FILE"
echo "Run ./test.sh from the project root to download test assets first."
exit 1
fi
if [ ! -f "$PATCHES_ZIP" ]; then
echo "ERROR: Patches zip not found at $PATCHES_ZIP"
exit 1
fi
# Build the native kobopatch binary.
echo "=== Building kobopatch ==="
cd kobopatch-src
go build -o ../kobopatch ./kobopatch
cd ..
echo "Built kobopatch successfully."
# Extract patches to a temp directory.
TMPDIR="$(mktemp -d)"
trap 'rm -rf "$TMPDIR"' EXIT
echo ""
echo "=== Extracting patches ==="
unzip -q "$PATCHES_ZIP" -d "$TMPDIR"
# Rewrite the config to point at the cached firmware and create output dir.
sed -i "s|^in:.*|in: $FIRMWARE_FILE|" "$TMPDIR/kobopatch.yaml"
mkdir -p "$TMPDIR/out"
BLACKLIST_FILE="$(cd .. && pwd)/web/src/patches/blacklist.json"
VERSION="${VERSION:-4.45}"
# Run patch tests and capture output.
echo ""
echo "=== Testing patches against $(basename "$FIRMWARE_FILE") ==="
echo ""
OUTPUT=$(./kobopatch -t -f "$FIRMWARE_FILE" "$TMPDIR/kobopatch.yaml" 2>&1 || true)
echo "$OUTPUT"
# Generate blacklist.json from failed patches.
echo ""
echo "=== Generating blacklist.json ==="
echo "$OUTPUT" | python3 -c "
import sys, json, os
version = '$VERSION'
blacklist_file = '$BLACKLIST_FILE'
# Load existing blacklist to preserve other versions.
if os.path.exists(blacklist_file):
with open(blacklist_file) as f:
blacklist = json.load(f)
else:
blacklist = {}
# Map binary paths back to patch file names.
# kobopatch prints 'Patching ./usr/local/Kobo/libnickel.so.1.0.0' but we need 'src/libnickel.so.1.0.0.yaml'.
target_to_src = {}
current_file = None
failed = {}
for line in sys.stdin:
line = line.rstrip()
if line.startswith('Patching ./'):
target = line.split('Patching ./')[1]
current_file = target
elif '✕' in line and current_file:
name = line.split('✕')[1].strip()
failed.setdefault(current_file, []).append(name)
# Read kobopatch.yaml to get target -> src mapping.
# Parse the 'patches:' section without a YAML dependency.
src_to_target = {}
in_patches = False
with open('$TMPDIR/kobopatch.yaml') as f:
for cfg_line in f:
cfg_line = cfg_line.rstrip()
if cfg_line.startswith('patches:'):
in_patches = True
continue
if in_patches and cfg_line and not cfg_line.startswith(' ') and not cfg_line.startswith('#'):
in_patches = False
if in_patches:
parts = cfg_line.strip().split(':')
if len(parts) >= 2 and parts[0].endswith('.yaml'):
src_to_target[parts[0].strip()] = parts[1].strip()
# Build a patch-name -> src file mapping by scanning patch files.
patch_name_to_src = {}
for src in src_to_target:
src_path = os.path.join('$TMPDIR', src)
if not os.path.exists(src_path):
continue
with open(src_path) as pf:
for pf_line in pf:
pf_line = pf_line.rstrip()
if pf_line and not pf_line.startswith(' ') and not pf_line.startswith('#') and pf_line.endswith(':'):
patch_name_to_src[pf_line[:-1].strip()] = src
# Build the version entry keyed by src file.
version_entry = {}
for target, patches in sorted(failed.items()):
for patch in sorted(patches):
src = patch_name_to_src.get(patch, target)
version_entry.setdefault(src, []).append(patch)
blacklist[version] = version_entry
with open(blacklist_file, 'w') as f:
json.dump(blacklist, f, indent=2)
f.write('\n')
total_failed = sum(len(v) for v in version_entry.values())
print(f'Wrote {total_failed} blacklisted patch(es) for version {version} to {blacklist_file}')
"

View File

@@ -0,0 +1,21 @@
{
"4.45": {
"src/libadobe.so.yaml": [
"Remove PDF map widget shown during panning"
],
"src/libnickel.so.1.0.0.yaml": [
"Allow rotation on all devices",
"Allow showing info panel on random screensaver",
"Both page turn buttons go next",
"Customize ComfortLight settings",
"Hide browser from beta features",
"My 24 line spacing values",
"Replace adobe page numbers toggle with invert screen",
"Set KePub hyphenation"
],
"src/librmsdk.so.1.0.0.yaml": [
"Default ePub sans-serif font (Gill Sans)",
"Default ePub serif font (Amasis)"
]
}
}