1#!/bin/bash 2# Copyright (c) 2023 Institute of Parallel And Distributed Systems (IPADS), Shanghai Jiao Tong University (SJTU) 3# Licensed under the Mulan PSL v2. 4# You can use this software according to the terms and conditions of the Mulan PSL v2. 5# You may obtain a copy of Mulan PSL v2 at: 6# http://license.coscl.org.cn/MulanPSL2 7# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR 8# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR 9# PURPOSE. 10# See the Mulan PSL v2 for more details. 11 12set -e 13 14self=$(basename "$0") 15 16function usage { 17 echo "Usage: $self [patches_absolute_path] [target_absolute_path]" 18 exit 1 19} 20 21if [ "$#" -ne 2 ]; then 22 usage 23fi 24 25if [[ $1 != /* ]] || [[ $2 != /* ]]; then 26 usage 27fi 28 29pacthes=$1 30target=$2 31 32# Patching is based on mirror structure of $pacthes and $target directory. 33# So, for each file **under $pacthes**, we have defined following 34# patching semantics: 35# If this file is a *.sh or *.patch file, it indicates that this file is a patch file, 36# targeting corresponding files under $target without .sh or .patch. 37# 38# Based on above patching semantic, this process is implemented with target state-based 39# approach. The target state of each file to be patched under $target is that their 40# backups have been created, and their content have been patched using patch files. 41# 42# We recursively iterate over each subdirectories and files under $pacthes, for each patch 43# file, check the state of their corresponding B is reached target state or not. If reached, 44# we just skip for idempotence. Otherwise, we perform backup and use patch file to patch 45# target file(by using patch command or executing .sh). 46 47function traverse { 48 for file in "$1"/*; do 49 rel_path=${file#$pacthes/} 50 target_file=$target/${rel_path%.*} 51 bak_file=$target_file.bak 52 53 if [ -d "$file" ]; then 54 traverse "$file" 55 elif [ -f "$file" ]; then 56 ext=${file##*.} 57 if [ "$ext" = "patch" ] || [ "$ext" = "sh" ]; then 58 if [ ! -e "$target_file" ] || [ -e $bak_file ]; then 59 continue 60 else 61 cp "$target_file" "$target_file.bak" 62 fi 63 64 if [ "$ext" = "patch" ]; then 65 patch "$target_file" "$file" 66 echo "--- Patched ${target_file} with ${file}" 67 elif [ "$ext" = "sh" ]; then 68 bash "$file" "$target_file" 69 echo "--- Patched ${target_file} with ${file}" 70 fi 71 fi 72 fi 73 done 74} 75 76traverse $pacthes 77