#!/bin/sh set -e SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" ROOT="$(dirname "$SCRIPT_DIR")" SING_BOX="$ROOT/works/sing-box" PATCH_DIR="$ROOT/works/patch" OUTPUT="$ROOT/works/core" REV_FILE="$ROOT/works/rev" # defaults REPO_URL="https://git.sfclub.cc/icybear/sing-box.git" UPSTREAM_BRANCH="testing" CONFIG="$ROOT/works/config" if [ -f "$CONFIG" ]; then . "$CONFIG" fi # Clone if not present if [ ! -d "$SING_BOX/.git" ]; then echo "Cloning sing-box..." if [ -n "$UPSTREAM_BRANCH" ]; then git clone -b "$UPSTREAM_BRANCH" "$REPO_URL" "$SING_BOX" else git clone "$REPO_URL" "$SING_BOX" fi fi # Checkout stored rev if [ -f "$REV_FILE" ]; then REV="$(cat "$REV_FILE" | tr -d '[:space:]')" echo "Checking out stored rev: $REV" git -C "$SING_BOX" fetch --all git -C "$SING_BOX" checkout "$REV" else echo "Warning: works/rev not found, using current HEAD." >&2 fi echo "Initializing works/core/ from works/sing-box/ (retaining .git)..." rm -rf "$OUTPUT" cp -a "$SING_BOX" "$OUTPUT" echo "Applying patches..." applied=0 failed=0 failed_list="" if [ -d "$PATCH_DIR" ]; then patch_list="$(mktemp)" trap 'rm -f "$patch_list"' EXIT find "$PATCH_DIR" -name "*.patch" | sort > "$patch_list" while IFS= read -r patch_file; do rel="${patch_file#$PATCH_DIR/}" rel="${rel%.patch}" dst="$OUTPUT/$rel" mkdir -p "$(dirname "$dst")" if patch --merge --no-backup-if-mismatch --force "$dst" < "$patch_file"; then applied=$((applied + 1)) else echo " FAILED: $rel" >&2 failed=$((failed + 1)) failed_list="${failed_list} ${rel} " fi done < "$patch_list" fi # Commit applied patches to keep history and clean worktree git -C "$OUTPUT" add -A git -C "$OUTPUT" commit -m "patches applied" --allow-empty total=$((applied + failed)) echo "" echo "Result: $applied/$total patches applied." if [ "$failed" -gt 0 ]; then echo "" echo "Failed patches (merge conflicts written to files):" printf "%s" "$failed_list" exit 1 fi echo "Done."