aboutsummaryrefslogtreecommitdiff
path: root/Mk/Scripts/do-patch.sh
blob: ef2a7ce9f64cfa32b68a044b57b707adf92191ca (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#!/bin/sh
# $FreeBSD$
#
# MAINTAINER: portmgr@FreeBSD.org

set -e
set -o pipefail

. "${dp_SCRIPTSDIR}/functions.sh"

validate_env dp_BZCAT dp_CAT dp_DISTDIR dp_ECHO_MSG dp_EXTRA_PATCHES \
	dp_EXTRA_PATCH_TREE dp_GZCAT dp_OPSYS dp_PATCH dp_PATCHDIR \
	dp_PATCHFILES dp_PATCH_ARGS dp_PATCH_DEBUG_TMP dp_PATCH_DIST_ARGS \
	dp_PATCH_SILENT dp_PATCH_WRKSRC dp_PKGNAME dp_PKGORIGIN \
	dp_UNZIP_NATIVE_CMD dp_XZCAT

[ -n "${DEBUG_MK_SCRIPTS}" -o -n "${DEBUG_MK_SCRIPTS_DO_PATCH}" ] && set -x

set -u

has_failed=""

cat_file() {
	case "$1" in
		*.Z|*.gz)
			${dp_GZCAT} "$1"
			;;
		*.bz2)
			${dp_BZCAT} "$1"
			;;
		*.xz)
			${dp_XZCAT} "$1"
			;;
		*.zip)
			${dp_UNZIP_NATIVE_CMD} -p "$1"
			;;
		*)
			${dp_CAT} "$1"
			;;
	esac
}

# If we want to continue when one patch fails, set the flag, otherwise, abort.
if [ -n "${dp_PATCH_CONTINUE_ON_FAIL}" ]; then
	failure_fatal() {
		has_failed=1
	}
else
	failure_fatal() {
		false
	}
fi

apply_one_patch() {
	local file="$1"
	local msg="$2"
	local verbose="$3"
	shift 3
	local patch_strip=""

	case ${file} in
		*:-p[0-9])
			patch_strip=${file##*:}
			file=${file%:-p[0-9]}
			;;
	esac

	if [ -n "${verbose}" -o -n "${dp_PATCH_DEBUG_TMP}" ]; then
		${dp_ECHO_MSG} "===>  Applying ${msg} ${file}${patch_strip:+ with ${patch_strip}}"
	fi

	if ! cat_file "$file" | do_patch "$@" ${patch_strip}; then
		${dp_ECHO_MSG} "===>  FAILED Applying ${msg} ${file}${patch_strip:+ with ${patch_strip}}"
		false
	fi
}

do_patch() {
	"${dp_PATCH}" -d "${dp_PATCH_WRKSRC}" "$@"
}

patch_from_directory() {
	local dir="$1"
	local msg="$2"
	local patches_applied=""
	local patches_failed=""

	if [ -d "${dir}" ]; then
		cd "${dir}"

		if [ "$(echo patch-*)" != "patch-*" ]; then

			${dp_ECHO_MSG} "===>  Applying ${msg} patches for ${dp_PKGNAME} from ${dir}"


			for i in patch-*; do
				case ${i} in
					*.orig|*.rej|*~|*,v)
						${dp_ECHO_MSG} "====>   IGNORING patchfile ${i}"
						;;
					*)
						if apply_one_patch "${i}" "${msg}" "" ${dp_PATCH_ARGS}; then
							patches_applied="${patches_applied} ${i}"
						else
							patches_failed="${patches_failed} ${i}"
							if ! failure_fatal; then
								break
							fi
						fi
						;;
				esac
			done

			if [ -n "${patches_failed}" -a "${dp_PATCH_SILENT}" != "yes" ]; then
				if [ -n "${patches_applied}" ]; then
					${dp_ECHO_MSG} "===> Cleanly applied ${msg} patch(es) ${patches_applied}"
				fi
				${dp_ECHO_MSG} "===> FAILED to apply cleanly ${msg} patch(es) ${patches_failed}"
				# If we want to stop after the first failure, this returns false,
				# let its return value bubble up here and stop everything.
				failure_fatal
			fi
		fi
	fi
}

if [ -n "${dp_PATCHFILES}" ]; then
	${dp_ECHO_MSG} "===>  Applying distribution patches for ${dp_PKGNAME}"
	cd "${dp_DISTDIR}"
	for i in ${dp_PATCHFILES}; do
		if ! apply_one_patch "${i}" \
			"distribution patch" \
			"" \
			${dp_PATCH_DIST_ARGS}; then
			failure_fatal
		fi
	done
fi

if [ -n "${dp_EXTRA_PATCHES}" ]; then
	for i in ${dp_EXTRA_PATCHES}; do
		if [ -d "${i}" ]; then
			patch_from_directory "${i}" \
				"extra patch"
		else
			if ! apply_one_patch "${i}" \
				"extra patch" \
				"verbose" \
				${dp_PATCH_ARGS}; then
				failure_fatal
			fi
		fi
	done
fi

patch_from_directory "${dp_PATCHDIR}" "${dp_OPSYS}"

if [ -n "${dp_EXTRA_PATCH_TREE}" ]; then
	patch_from_directory "${dp_EXTRA_PATCH_TREE}/${dp_PKGORIGIN}" "local"
fi

if [ -n "$has_failed" ]; then
	if [ -n "${dp_PATCH_DEBUG_TMP}" ]; then
		${dp_ECHO_MSG} "==> Some patches failed to apply cleanly."
		${dp_ECHO_MSG} "==> Look for FAILED messages above."
	fi
	false
fi