Skip to content

Commit b9dcf98

Browse files
Update - add apply_patch.sh
to help copy uncommitted changes (git diff / patch)
1 parent a8e9b3f commit b9dcf98

File tree

1 file changed

+188
-0
lines changed

1 file changed

+188
-0
lines changed
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
#!/bin/bash
2+
#
3+
# apply_patch.sh
4+
#
5+
# Usage: ./buildroot/share/scripts/apply_patch.sh
6+
# Run script in the root folder.
7+
#
8+
# Automatically generate patch files from uncommitted changes (pulled and ready to Merge)
9+
# in 'Marlin/Configuration|_adv.h' and apply them to all files in 'configurations/'.
10+
#
11+
12+
# --- Configuration ---
13+
# Define colors for output
14+
RED='\033[0;31m'
15+
GREEN='\033[0;32m'
16+
YELLOW='\033[0;33m'
17+
NC='\033[0m' # No Color
18+
19+
# The base directory where your target configuration files are located
20+
BASE_DIR="configurations"
21+
22+
# Array of files to process.
23+
# Format: "target_filename|marlin_path|strip_level"
24+
FILE_DETAILS=(
25+
"Configuration.h|Marlin/Configuration.h|2"
26+
"Configuration-MP.h|Marlin/Configuration.h|2"
27+
"Configuration_adv.h|Marlin/Configuration_adv.h|2"
28+
)
29+
30+
# --- Argument & System Validation ---
31+
32+
# Function to check for required commands
33+
check_command() {
34+
if ! command -v "$1" &> /dev/null; then
35+
echo -e "${RED}❌ Error: '$1' command not found. Please install $1.${NC}"
36+
exit 1
37+
fi
38+
}
39+
40+
# Function to display usage
41+
usage() {
42+
echo -e "${GREEN}Usage: $0${NC}"
43+
echo "This script automatically generates patches from uncommitted changes in Marlin/ and applies them to all files in the '$BASE_DIR' directory tree."
44+
echo ""
45+
exit 0
46+
}
47+
48+
# Check for help flag
49+
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
50+
usage
51+
fi
52+
53+
# Check for required binaries
54+
check_command "git"
55+
check_command "patch"
56+
check_command "find"
57+
check_command "sed"
58+
59+
# Check if BASE_DIR exists
60+
if [ ! -d "$BASE_DIR" ]; then
61+
echo -e "${RED}❌ Error: Base directory '$BASE_DIR' not found. Check your configuration.${NC}"
62+
exit 1
63+
fi
64+
65+
# --- Script Logic ---
66+
67+
SCRIPT_DIR="$(pwd)"
68+
echo "Patch files will be generated and saved in: $SCRIPT_DIR"
69+
70+
# 1. --- PATCH GENERATION PHASE ---
71+
echo -e "\n${YELLOW}==========================================================${NC}"
72+
echo -e "${YELLOW}PHASE 1: ⚙️ Generating Patch Files from Uncommitted Git Diff${NC}"
73+
echo -e "${YELLOW}==========================================================${NC}"
74+
75+
declare -A GENERATED_PATCHES
76+
FILE_DETAILS_UPDATED=()
77+
78+
for DETAIL in "${FILE_DETAILS[@]}"; do
79+
IFS='|' read -r TARGET_FILENAME MARLIN_PATH STRIP_LEVEL <<< "$DETAIL"
80+
81+
PATCH_SOURCE_KEY="${MARLIN_PATH//\//_}"
82+
PATCH_FILE="${PATCH_SOURCE_KEY}.patch.tmp"
83+
84+
if [[ -z "${GENERATED_PATCHES[$PATCH_SOURCE_KEY]}" ]]; then
85+
86+
echo "Generating patch for $MARLIN_PATH -> $PATCH_FILE"
87+
88+
if git diff HEAD "$MARLIN_PATH" > "$PATCH_FILE"; then
89+
90+
if [ -s "$PATCH_FILE" ]; then
91+
echo -e "${GREEN}✅ Patch generated successfully.${NC}"
92+
GENERATED_PATCHES[$PATCH_SOURCE_KEY]="$PATCH_FILE"
93+
else
94+
echo -e "${YELLOW}⚠️ Warning: No uncommitted changes found in $MARLIN_PATH. Patch file is empty.${NC}"
95+
rm -f "$PATCH_FILE"
96+
GENERATED_PATCHES[$PATCH_SOURCE_KEY]=""
97+
fi
98+
else
99+
echo -e "${RED}❌ Error: Failed to generate git diff for $MARLIN_PATH. Check file path.${NC}"
100+
GENERATED_PATCHES[$PATCH_SOURCE_KEY]=""
101+
fi
102+
fi
103+
104+
FINAL_PATCH_FILE="${GENERATED_PATCHES[$PATCH_SOURCE_KEY]}"
105+
FILE_DETAILS_UPDATED+=("$TARGET_FILENAME|$FINAL_PATCH_FILE|$STRIP_LEVEL|$MARLIN_PATH")
106+
107+
done
108+
109+
FILE_DETAILS=("${FILE_DETAILS_UPDATED[@]}")
110+
111+
# 2. --- PATCH APPLICATION PHASE ---
112+
echo -e "\n${YELLOW}==========================================================${NC}"
113+
echo -e "${YELLOW}PHASE 2: 🛠️ Applying Generated Patch Files in '$BASE_DIR'${NC}"
114+
echo -e "${YELLOW}==========================================================${NC}"
115+
116+
for DETAIL in "${FILE_DETAILS[@]}"; do
117+
IFS='|' read -r TARGET_FILENAME PATCH_FILE STRIP_LEVEL MARLIN_PATH <<< "$DETAIL"
118+
119+
if [ -z "$PATCH_FILE" ]; then
120+
echo "Skipping application for $TARGET_FILENAME (no patch generated)."
121+
continue
122+
fi
123+
124+
FULL_PATCH_PATH="$SCRIPT_DIR/$PATCH_FILE"
125+
EXPECTED_PATCH_FILENAME=$(basename "$MARLIN_PATH")
126+
127+
echo -e "\n--- Processing: ${YELLOW}$TARGET_FILENAME${NC} with patch $PATCH_FILE ---"
128+
129+
find "$BASE_DIR" -type f -name "$TARGET_FILENAME" -print0 | while IFS= read -r -d $'\0' TARGET_FILE_PATH; do
130+
echo -e " -> Applying patch to: ${TARGET_FILE_PATH}"
131+
132+
TARGET_DIR=$(dirname "$TARGET_FILE_PATH")
133+
134+
if ! pushd "$TARGET_DIR" > /dev/null; then
135+
echo -e " ${RED}❌ Could not change directory to $TARGET_DIR. Skipping.${NC}"
136+
continue
137+
fi
138+
139+
CURRENT_PATCH_PATH="$FULL_PATCH_PATH"
140+
TEMP_MODIFIED_PATCH=""
141+
142+
# KEY FIX: Modify the patch file if TARGET_FILENAME doesn't match EXPECTED_PATCH_FILENAME
143+
if [[ "$TARGET_FILENAME" != "$EXPECTED_PATCH_FILENAME" ]]; then
144+
TEMP_MODIFIED_PATCH="$SCRIPT_DIR/${PATCH_FILE}.modified"
145+
146+
# Use sed to replace all instances of the expected filename with the actual target filename
147+
# This is done on the diff header lines.
148+
sed "s|${EXPECTED_PATCH_FILENAME}|${TARGET_FILENAME}|g" "$FULL_PATCH_PATH" > "$TEMP_MODIFIED_PATCH"
149+
150+
CURRENT_PATCH_PATH="$TEMP_MODIFIED_PATCH"
151+
fi
152+
153+
# Apply the patch
154+
if patch -p"$STRIP_LEVEL" --silent --forward -N --no-backup-if-mismatch < "$CURRENT_PATCH_PATH"; then
155+
echo -e " ${GREEN}✅ Success!${NC}"
156+
else
157+
echo -e " ${RED}❌ Failure: Patch could not be applied. Checking verbose output...${NC}"
158+
# For debugging, run the command again without --silent
159+
patch -p"$STRIP_LEVEL" --forward -N < "$CURRENT_PATCH_PATH"
160+
fi
161+
162+
# Clean up the temporary modified patch file if created
163+
if [ ! -z "$TEMP_MODIFIED_PATCH" ]; then
164+
rm -f "$TEMP_MODIFIED_PATCH"
165+
fi
166+
167+
popd > /dev/null
168+
done
169+
done
170+
171+
# 3. --- CLEANUP PHASE ---
172+
echo -e "\n${YELLOW}==========================================================${NC}"
173+
echo -e "${YELLOW}PHASE 3: 🧹 Cleaning Up Temporary Files${NC}"
174+
echo -e "${YELLOW}==========================================================${NC}"
175+
176+
# Clean up generated temporary patch files
177+
for UNIQUE_PATCH_FILE in "${GENERATED_PATCHES[@]}"; do
178+
if [ ! -z "$UNIQUE_PATCH_FILE" ]; then
179+
rm -f "$UNIQUE_PATCH_FILE"
180+
echo -e "🗑️ Removed temporary patch file: ${UNIQUE_PATCH_FILE}"
181+
fi
182+
done
183+
184+
# Clean up reject files
185+
find "$BASE_DIR" -type f -name "*.rej" -delete
186+
echo -e "🗑️ Removed all *.rej files from '$BASE_DIR'.${NC}"
187+
188+
echo -e "\n--- ${GREEN}Script Finished${NC} ---"

0 commit comments

Comments
 (0)