From 673504e52457b17bc9e8c0a3fefe3eae10d19d60 Mon Sep 17 00:00:00 2001
From: maxice8 <thinkabit.ukim@gmail.com>
Date: Sun, 13 Jan 2019 03:25:44 -0200
Subject: [PATCH] meta: add vsed function

---
 Manual.md                        | 10 +++++++
 common/environment/setup/vsed.sh | 45 ++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+)
 create mode 100644 common/environment/setup/vsed.sh

diff --git a/Manual.md b/Manual.md
index 905efaf91d5..3d610142e66 100644
--- a/Manual.md
+++ b/Manual.md
@@ -314,6 +314,16 @@ The following functions are defined by `xbps-src` and can be used on any templat
 	For further information on how to create a new service directory see
 	[The corresponding section the FAQ](http://smarden.org/runit/faq.html#create).
 
+- *vsed()* `vsed -i <file> -e <regex>`
+
+	Wrapper around sed that checks sha256sum of a file before and after running
+	the sed command to detect cases in which the sed call didn't change anything.
+	Takes any arbitrary amount of files and regexes by calling `-i file` and
+	`-e regex` repeatedly, at least one file and one regex must be specified.
+
+	Note that vsed will call the sed command for every regex specified against
+	every file specified, in the order that they are given.
+
 > Shell wildcards must be properly quoted, Example: `vmove "usr/lib/*.a"`.
 
 <a id="global_vars"></a>
diff --git a/common/environment/setup/vsed.sh b/common/environment/setup/vsed.sh
new file mode 100644
index 00000000000..400b1f2c9d2
--- /dev/null
+++ b/common/environment/setup/vsed.sh
@@ -0,0 +1,45 @@
+# Helper function for calling sed on files and checking if the
+# file is actually changed
+#
+# NOTE: this will not check if the input is valid, you can problably
+# make it execute arbirtrary commands via passing '; cmd' to a vsed
+# call.
+
+vsed() {
+	local files=() regexes=() OPTIND
+
+	while getopts ":i:e:" opt; do
+		case $opt in
+			i) files+=("$OPTARG") ;;
+			e) regexes+=("$OPTARG") ;;
+			*) ;;
+		esac
+	done
+
+	if [ ${#files[@]} -eq 0 ]; then
+		msg_red "$pkgver: vsed: no files specified with -i.\n"
+		return 1
+	fi
+
+	if [ ${#regexes[@]} -eq 0 ]; then
+		msg_red "$pkgver: vsed: no regexes specified with -e.\n"
+		return 1
+	fi
+
+	for rx in "${regexes[@]}"; do
+		for f in "${files[@]}"; do
+			shasums="$(sha256sum "$f" 2>/dev/null | awk '{print $1}')"
+
+			sed -i "$f" -e "$rx" || {
+				msg_red "$pkgver: vsed: sed call failed with regex \"$rx\" on file \"$f\"\n"
+				return 1
+			}
+
+			sha256sum="$(sha256sum "$f" 2>/dev/null)"
+
+			if [ "$shasums" = "${sha256sum%% *}" ]; then
+				msg_warn "$pkgver: vsed: regex \"$rx\" didn't change file \"$f\"\n"
+			fi
+		done
+	done
+}