From da9269ba62b60757663ff8761ff7e218d1ab498c Mon Sep 17 00:00:00 2001
From: Bart Ribbers <bribbers@disroot.org>
Date: Wed, 28 Aug 2024 10:27:02 +0200
Subject: [PATCH] abuild: warn when files are installed to non-usr locations

As agreed upon by the TSC:
https://gitlab.alpinelinux.org/alpine/tsc/-/blob/master/minutes/2024-08-15.md?ref_type=heads#implement-usr-merge-73
Should be changed to an error once some core packages are adjusted.
---
 abuild.in         | 12 +++++++-
 tests/abuild_test | 77 ++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 70 insertions(+), 19 deletions(-)

diff --git a/abuild.in b/abuild.in
index b4a6d411..3d8ec6f2 100644
--- a/abuild.in
+++ b/abuild.in
@@ -788,7 +788,7 @@ postcheck() {
 	# to warrant a lib64 check
 	if ! options_has "lib64"; then
 		if [ -e "$dir"/lib64 ]; then
-			error "Packages must not put anything under /lib64, use /lib instead"
+			error "Packages must not put anything under /lib64, use /usr/lib instead"
 			e=1
 		elif [ -e "$dir"/usr/lib64 ]; then
 			error "Packages must not put anything under /usr/lib64, use /usr/lib instead"
@@ -796,6 +796,16 @@ postcheck() {
 		fi
 	fi
 
+	# /usr merge
+	if ! options_has "!usrmerge"; then
+		for i in bin sbin lib; do
+			if [ -e "$dir"/$i ]; then
+				warning "Packages must not put anything under /$i, use /usr/${i##*s} instead"
+				e=1
+			fi
+		done
+	fi
+
 	# remove *.la files if libtool is not set
 	if ! options_has "libtool"; then
 		find "$dir" -name '*.la' -type f -delete
diff --git a/tests/abuild_test b/tests/abuild_test
index cc6aa86e..b00e2eb1 100755
--- a/tests/abuild_test
+++ b/tests/abuild_test
@@ -48,7 +48,8 @@ init_tests \
 	abuild_gocache_dir \
 	abuild_cargo_home_dir \
 	abuild_fish_comp_split \
-	abuild_deps
+	abuild_deps \
+	abuild_usr_merge
 
 export ABUILD_SHAREDIR=$(atf_get_srcdir)/..
 export ABUILD_CONF=/dev/null
@@ -722,16 +723,16 @@ abuild_amove_body() {
 
 		package() {
 			mkdir -p "\$pkgdir"/etc \
-				"\$pkgdir"/bin \
-				"\$pkgdir"/sbin \
+				"\$pkgdir"/usr/bin \
+				"\$pkgdir"/usr/sbin \
 				"\$pkgdir"/var/lib/\$pkgname \
 				"\$pkgdir"/usr/share
 			touch "\$pkgdir"/etc/file \
 				"\$pkgdir"/etc/\$pkgname.conf \
-				"\$pkgdir"/bin/hello \
-				"\$pkgdir"/sbin/shello \
+				"\$pkgdir"/usr/bin/hello \
+				"\$pkgdir"/usr/sbin/shello \
 				"\$pkgdir"/root \
-				"\$pkgdir"/sbin/space' ' \
+				"\$pkgdir"/usr/sbin/space' ' \
 				"\$pkgdir"/var/lib/\$pkgname/testfile \
 				"\$pkgdir"/usr/share/a \
 				"\$pkgdir"/usr/share/b
@@ -746,11 +747,11 @@ abuild_amove_body() {
 		}
 		_bin() {
 			# trailing /
-			amove bin///
+			amove usr/bin///
 		}
 		_sbin() {
 			# no leading and trailing /
-			amove sbin/shello
+			amove usr/sbin/shello
 		}
 		_root() {
 			# no /
@@ -770,7 +771,7 @@ abuild_amove_body() {
 		}
 		_space() {
 			# with space
-			amove sbin/space' '
+			amove usr/sbin/space' '
 		}
 
 	EOF
@@ -778,14 +779,14 @@ abuild_amove_body() {
 	for i in \
 			test-amove-file/etc/file \
 			test-amove-etc/etc/test-amove.conf \
-			test-amove-bin/bin/hello \
-			test-amove-sbin/sbin/shello \
+			test-amove-bin/usr/bin/hello \
+			test-amove-sbin/usr/sbin/shello \
 			test-amove-root/root \
 			test-amove-root/symlink \
 			test-amove-var/var/lib/test-amove/testfile \
 			test-amove-usr/usr/share/a \
 			test-amove-usr/usr/share/b \
-			test-amove-space/sbin/space' ' \
+			test-amove-space/usr/sbin/space' ' \
 			; do \
 		[ -L pkg/"$i" ] || [ -e pkg/"$i" ] || atf_fail "$i failed"
 	done
@@ -1098,7 +1099,7 @@ abuild_command_provides_body() {
 			chmod +x "\$pkgdir/usr/bin/foo"
 			cp -a "\$pkgdir/usr/bin/foo" "\$pkgdir/usr/bin/foo@"
 			mkdir -p "\$pkgdir/usr/bin/dir/"
-			ln -s /bin/not-on-the-host-system-but-in-a-dependency "\$pkgdir/usr/bin/link"
+			ln -s /usr/bin/not-on-the-host-system-but-in-a-dependency "\$pkgdir/usr/bin/link"
 		}
 	EOF
 	abuild rootpkg
@@ -1216,8 +1217,8 @@ abuild_fish_comp_split_body() {
 }
 
 create_mock_apk() {
-	mkdir -p bin
-	cat > bin/apk <<-EOF
+	mkdir -p usr/bin
+	cat > usr/bin/apk <<-EOF
 		#!/bin/sh
 		if [ "\$1" = "--print-arch" ]; then
 			echo 'aarch64'
@@ -1225,9 +1226,9 @@ create_mock_apk() {
 		fi
 		printf 'apk %s\n' "\$*" >&2
 	EOF
-	chmod +x bin/apk
-	ln -s apk bin/abuild-apk
-	PATH="$PWD/bin:$PATH"
+	chmod +x usr/bin/apk
+	ln -s apk usr/bin/abuild-apk
+	PATH="$PWD/usr/bin:$PATH"
 }
 
 abuild_deps_body() {
@@ -1289,3 +1290,43 @@ abuild_deps_body() {
 		-e match:"apk add .*--repository It's \\\\b'\"\"'  \"escaped\"/.*" \
 		abuild -P "It's \b'\"\"'  \"escaped\"" deps
 }
+
+abuild_usr_merge_body() {
+	init_keys
+	mkdir usrmergetest
+	cd usrmergetest
+	cat >APKBUILD <<-EOF
+		# Maintainer: Joe User <juser@example.com>
+		pkgname="usrmergetest"
+		pkgver="1.0"
+		pkgrel=0
+		pkgdesc="Dummy test package"
+		url="https://gitlab.alpinelinux.org/alpine/aports"
+		arch="noarch"
+		license="MIT"
+		source=""
+		prepare() {
+			mkdir -p "\$builddir"
+		}
+		build() {
+			mkdir -p \
+				lib \
+				bin \
+				sbin
+		}
+		check() {
+			true
+		}
+
+		package() {
+			mkdir -p "\$pkgdir"
+			cp -r * "\$pkgdir"/
+		}
+	EOF
+	atf_check -s exit:1 \
+		-e match:"WARNING:.*: Packages must not put anything under /lib, use /usr/lib instead" \
+		-e match:"WARNING:.*: Packages must not put anything under /bin, use /usr/bin instead" \
+		-e match:"WARNING:.*: Packages must not put anything under /sbin, use /usr/bin instead" \
+		abuild
+}
+
-- 
GitLab