#!/usr/bin/env atf-sh

. $(atf_get_srcdir)/test_env.sh
init_tests \
	abuild_help \
	abuild_invalid_opt \
	abuild_version \
	abuild_simple_pkg_without_deps \
	abuild_build_fail \
	abuild_invalid_filename \
	abuild_usr_lib64 \
	abuild_dbg_subpackage \
	abuild_reproducible \
	abuild_checksum_generation \
	abuild_checksum_duplicates \
	abuild_subpkg_dep_leak \
	abuild_subpkg_libs \
	abuild_py_providers_creation \
	abuild_py_dependency_scan \
	abuild_py_dependency_scan_versioned_python \
	abuild_py_dependency_scan_conflict \
	abuild_rpaths \
	abuild_reject_init_with_improper_shebang \
	abuild_valid_pkgnames \
	abuild_invalid_pkgnames \
	abuild_invalid_subpkgnames \
	abuild_duplicate_subpkgname \
	abuild_invalid_subpkg_version \
	abuild_provide_pkgname \
	abuild_validate_depends \
	abuild_subpackage_arch \
	abuild_large_doc_subpackage \
	abuild_bigdocs \
	abuild_pkgver_digit_letter_digit \
	abuild_multiline_license \
	abuild_license_spdx \
	abuild_git_ceiling \
	abuild_package_size \
	abuild_keepdirs \
	abuild_amove \
	abuild_doc \
	abuild_dev \
	abuild_devhelp_warn \
	abuild_devhelp \
	abuild_check_maintainer \
	abuild_cleanoldpkg \
	abuild_clean \
	abuild_path_with_spaces \
	abuild_pyc_warn \
	abuild_pyc \
	abuild_setcap_binary \
	abuild_setcap_binary_with_option \
	abuild_command_provides \
	abuild_gocache_dir \
	abuild_cargo_home_dir \
	abuild_fish_comp_split \
	abuild_deps \
	abuild_usr_merge \
	abuild_symlink_depends \
	abuild_pc_providers \
	abuild_pc_depends \
	abuild_split_vars_reset

export ABUILD_SHAREDIR=$(atf_get_srcdir)/..
export ABUILD_CONF=/dev/null
export ABUILD_USERDIR="$HOME"/.abuild
export APK="apk --keys-dir $(atf_get_srcdir)/testdata/.abuild"
export GIT_CONFIG_GLOBAL="$(atf_get_srcdir)/testdata/gitconfig"
export REPODEST="$PWD"/packages

testrepo=$(atf_get_srcdir)/testrepo

# copy keys
init_keys() {
	cp -Ra "$(atf_get_srcdir)"/testdata/.abuild "$PWD"
}

abuild_help_body() {
	atf_check -s exit:0 \
		-o match:"usage:" \
		abuild -h
}

abuild_invalid_opt_body() {
	atf_check -s exit:1 \
		-e match:"usage:" \
		abuild -@
}

abuild_version_body() {
	atf_check -s exit:0 \
		-o match:"abuild [0-9]+\.[0-9]+" \
		abuild -V
}

abuild_simple_pkg_without_deps_body() {
	init_keys
	cp -R "$testrepo"/pkg1 .
	cd pkg1
	atf_check -s exit:0 -o ignore \
		-e not-match:"WARNING" \
		-e not-match:"fatal" \
		abuild -d
}

abuild_build_fail_body() {
	init_keys
	mkdir buildfail
	cat >buildfail/APKBUILD <<-EOF
		# Maintainer: Joe User <juser@example.com>
		pkgname="buildfail"
		pkgver="1.0"
		pkgrel=0
		pkgdesc="Dummy test package that fails to build"
		url="https://gitlab.alpinelinux.org/alpine/aports"
		arch="noarch"
		license="MIT"
		subpackages="\$pkgname-dev \$pkgname-doc"
		source=""
		prepare() {
			mkdir -p "\$builddir"
		}
		build() {
			false
		}
		package() {
			true
		}
	EOF
	cd buildfail
	atf_check -s exit:1 \
		-e match:"ERROR: buildfail: build failed" \
		abuild -d
}

abuild_invalid_filename_body() {
	init_keys
	mkdir invalid-filename
	cd invalid-filename
	cat >APKBUILD <<-EOF
		# Maintainer: Joe User <juser@example.com>
		pkgname="invalid-filename"
		pkgver="1.0"
		pkgrel=0
		pkgdesc="Dummy test package that fails to build"
		url="https://gitlab.alpinelinux.org/alpine/aports"
		arch="noarch"
		license="MIT"
		prepare() {
			mkdir -p "\$builddir"
		}
		build() {
			touch $'bad\nfile'
		}
		check() {
			true
		}
		package() {
			mkdir -p "\$pkgdir"
			cp -R * "\$pkgdir"/
		}
	EOF
	atf_check -s exit:1 \
		-e match:"ERROR:.*: Found filenames with newline" \
		abuild -d
}

abuild_usr_lib64_body() {
	init_keys
	mkdir lib64test
	cd lib64test
	cat >APKBUILD <<-EOF
		# Maintainer: Joe User <juser@example.com>
		pkgname="lib64test"
		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 usr/lib64
		}
		check() {
			true
		}

		package() {
			mkdir -p "\$pkgdir"
			cp -R * "\$pkgdir"/
		}
	EOF
	atf_check -s exit:1 \
		-e match:"ERROR:.*: Packages must not put anything under /usr/lib64" \
		abuild -d

	options=lib64 atf_check -s exit:0 \
		-e match:"Build complete" \
		abuild -d
}

abuild_dbg_subpackage_body() {
	init_keys
	cp -Ra "$testrepo" .
	cd testrepo/dbgpkg
	atf_check -s exit:0 \
		-o match:"hello world" \
		-e match:"Build complete" \
		abuild -d
	cd ../..

	arch=$(abuild -A)
	tar -zxf "$REPODEST"/testrepo/$arch/dbgpkg-1.0-r0.apk \
		|| atf_fail "failed to extract dbgpkg-1.0-r0.apk"
	if [ -e usr/lib/debug ]; then
		atf_fail "usr/lib/debug should not exist"
	fi
	debuginfo=$(readelf -wk usr/bin/hello | grep '^  Separate debug info file: [^/]*\.debug$')
	debuginfo_file=${debuginfo#"  Separate debug info file: "}
	atf_check -s exit:0 \
		-e match:"nm: usr/bin/hello: no symbols" \
		nm usr/bin/hello

	if ! [ usr/bin/hello -ef usr/bin/hello-hard ]; then
		atf_fail 'hello is not a hardlink of hello-hard'
	fi

	rm -r usr
	tar -xf "$REPODEST"/testrepo/$arch/dbgpkg-dbg-1.0-r0.apk
	if [ -e usr/bin ]; then
		atf_fail "usr/bin should not exist"
	fi

	find usr
	atf_check -s exit:0 \
		-o match:"T main" \
		nm usr/lib/debug/usr/bin/$debuginfo_file

	if [ -e usr/lib/debug/usr/bin/hello-sym.debug ]; then
		atf_fail "usr/lib/debug/usr/bin/hello-sym.debug should not exist"
	fi

	if [ -e usr/lib/debug/usr/bin/hello.debug ] && [ -e usr/lib/debug/usr/bin/hello-hard.debug ]; then
		atf_fail "only one of hello.debug and hello-hard.debug should exist"
	fi
}

abuild_reproducible_body() {
	init_keys
	cp -Ra "$testrepo" .
	cd testrepo/pkg1

	# set timestamp of APKBUILD to 1 min older than current time
	touch -d @$(( $(date -u +%s) - 60)) APKBUILD

	arch=$(abuild -A)
	pkgs=$(abuild listpkg)

	abuild -d || atf_fail "first build failed"
	checksums=$(cd "$REPODEST"/testrepo/$arch && sha512sum $pkgs)
	echo "$checksums"

	rm -r "$REPODEST"/testrepo
	abuild -d || atf_fail "rebuild failed"
	checksums2=$(cd "$REPODEST"/testrepo/$arch && sha512sum $pkgs)
	echo "$checksums2"

	if [ "$checksums" != "$checksums2" ]; then
		atf_fail "checksums does not match"
	fi
}

abuild_checksum_generation_body() {
	mkdir foo
	cat > foo/APKBUILD <<-EOF
		pkgname="foo"
		pkgver="1.0"
		source="test.txt"
	EOF
	echo "foo" > foo/test.txt
	cd foo
	abuild checksum || atf_fail "checksum generation failed"
	( . ./APKBUILD && echo "$sha512sums" | sed '/^$/d' > sums )
	cat sums
	sha512sum -c sums || atf_fail "checksum mismatch"
}

abuild_checksum_duplicates_body() {
	mkdir -p foo/dir1 foo/dir2
	cat > foo/APKBUILD <<-EOF
		pkgname="foo"
		pkgver="1.0"
		source="dir1/testfile dir2/testfile"
	EOF
	echo "first" > foo/dir1/testfile
	echo "second" > foo/dir2/testfile
	cd foo
	atf_check -s exit:1 \
		-e match:"ERROR:.*duplicate found" \
		abuild checksum
}

abuild_subpkg_dep_leak_body() {
	mkdir -p testrepo/subpkg-dep-leak
	cd testrepo/subpkg-dep-leak
	cat > APKBUILD <<-EOF
		# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
		pkgname="subpkg-dep-leak"
		pkgver=1.0
		pkgrel=0
		pkgdesc="Dummy test package with subpackages and dependencies"
		url="https://gitlab.alpinelinux.org/alpine/aports"
		arch="noarch"
		depends="tar scanelf"
		license="MIT"
		subpackages="\$pkgname-subpkg"
		options="!check"

		package() {
			mkdir -p "\$pkgdir"
		}

		subpkg() {
			depends="sed"
			mkdir -p "\$subpkgdir"
		}
	EOF
	abuild clean unpack prepare build rootpkg

	grep 'depend = tar' pkg/.control.subpkg-dep-leak/.PKGINFO \
		|| atf_fail "subpkg-dep-leak should depend on tar"
	grep 'depend = scanelf' pkg/.control.subpkg-dep-leak/.PKGINFO \
		|| atf_fail "subpkg-dep-leak should depend on scanelf"
	! grep 'depend = sed' pkg/.control.subpkg-dep-leak/.PKGINFO \
		|| atf_fail "subpkg-dep-leak should not depends on sed"

	grep 'depend = sed' pkg/.control.subpkg-dep-leak-subpkg/.PKGINFO \
		|| atf_fail "subpkg-dep-leak-subpkg should depend on sed"

	! grep 'depend = tar' pkg/.control.subpkg-dep-leak-subpkg/.PKGINFO \
		|| atf_fail "subpkg-dep-leak-subpkg should not depend on tar"
}

abuild_subpkg_libs_body() {
	init_keys
	mkdir -p testrepo/pkg
	cd testrepo/pkg
	cat > APKBUILD <<-EOF
		maintainer="Natanael Copa <ncopa@alpinelinux.org>"
		pkgname="pkg"
		pkgver=1.0
		pkgrel=0
		pkgdesc="Dummy test package"
		url="https://gitlab.alpinelinux.org/alpine/aports"
		arch="noarch"
		license="MIT"
		subpackages="\$pkgname-libs"
		options="!check"

		package() {
			mkdir -p "\$pkgdir"/usr/lib
			touch "\$pkgdir"/usr/lib/libfoo.so.1
		}
	EOF
	abuild clean unpack prepare build rootpkg || atf_fail "abuild failed"
	if ! [ -e pkg/pkg-libs/usr/lib/libfoo.so.1 ]; then
		find pkg
		atf_fail "libfoo.so.1 was not moved"
	fi
}


abuild_py_providers_creation_body() {
	init_keys
	cp -Ra "$testrepo" .
	cd testrepo/py3\ foo\ and\ bar
	abuild rootpkg || atf_fail "abuild failed"
	atf_check -s exit:0 \
		-o match:"provides = py3.9:foo=1.0.0-r0" \
		cat pkg/.control.py3-foo-and-bar/.PKGINFO
}

abuild_py_dependency_scan_body() {
	init_keys
	cp -Ra "$testrepo" .
	cd testrepo/py3\ foo\ and\ bar
	abuild rootpkg || atf_fail "abuild failed"
	atf_check -s exit:0 \
		-o match:"depend = python3~3.9" \
		cat pkg/.control.py3-foo-and-bar/.PKGINFO
}

# test that depend = python3~3.12 is not added on python3.12
abuild_py_dependency_scan_versioned_python_body() {
	init_keys
	mkdir -p testrepo/python3.12
	cd testrepo/python3.12
	cat > APKBUILD <<-EOF
		# Maintainer: Test user <user@example.com>
		pkgname=python3.12
		pkgver=3.12.12
		pkgrel=0
		pkgdesc="dummy python package for test"
		url="https://python.org"
		license="MIT"
		builddir="\$srcdir"
		_sitedir=usr/lib/python3.12/site-packages
		package() {
			mkdir -p "\$pkgdir"/\$_sitedir/foo
			touch "\$pkgdir"/\$_sitedir/foo/__init__.py
			touch "\$pkgdir"/\$_sitedir/bar.py
		}
	EOF

	abuild rootpkg || atf_fail "abuild failed"
	atf_check -s exit:0 \
		-o not-match:"depend = python3~3.12" \
		cat pkg/.control.python3.12/.PKGINFO
}


abuild_py_dependency_scan_conflict_body() {
	init_keys
	cp -Ra "$testrepo" .
	cd testrepo/py3-conflicting-python-versions
	atf_check -s exit:1 \
		-e match:"ERROR.*package contains python3 modules for conflicting python3 versions" \
		abuild rootpkg
}

abuild_rpaths_body() {
	init_keys

	mkdir -p bin
	cat > bin/scanelf <<-EOF
		#!/bin/sh
		for i; do
			[ "\$i" = --rpath ] || continue
			echo "\$ABUILD_RPATH" /usr/lib/pkg/base.so
			break
		done
	EOF
	chmod +x bin/scanelf
	PATH="$PWD/bin:$PATH"

	mkdir -p testrepo/pkg
	cd testrepo/pkg
	cat > APKBUILD <<-EOF
		maintainer="Natanael Copa <ncopa@alpinelinux.org>"
		pkgname="pkg"
		pkgver=1.0
		pkgrel=0
		pkgdesc="Dummy test package"
		url="https://gitlab.alpinelinux.org/alpine/aports"
		arch="all"
		license="MIT"
		options="!check !strip !textrels !archcheck"

		package() {
			mkdir -p "\$pkgdir"/usr/lib
			touch "\$pkgdir"/usr/lib/libfoo.so.1
		}
	EOF
	ABUILD_RPATH='/usr/lib/foo' abuild rootpkg || atf_fail "abuild failed"
	atf_check -s exit:0 \
		-o match:"/usr/lib/foo" \
		cat pkg/.control.pkg/.rpaths
	ABUILD_RPATH='$ORIGIN/bar:${ORIGIN}/../baf' pkgbasedir=$PWD/pkg abuild rootpkg || atf_fail "abuild failed"
	atf_check -s exit:0 \
		-o match:"/usr/lib/pkg/bar" \
		-o match:"/usr/lib/pkg/../baf" \
		cat pkg/.control.pkg/.rpaths
	ABUILD_RPATH='/home/builder' atf_check -s exit:1 -o ignore \
		-e match:"ERROR:.*: Has /home/... in rpath" abuild rootpkg
}

abuild_reject_init_with_improper_shebang_body() {
	mkdir invalid-initd
	cd invalid-initd
	cat >APKBUILD<<-EOF
		# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
		pkgname="invalid-initd"
		pkgver="1.0"
		pkgrel=0
		pkgdesc="Dummy test package"
		url="https://gitlab.alpinelinux.org/alpine/aports"
		arch="noarch"
		license="MIT"
		subpackages=""
		source="test.initd"
		prepare() {
			mkdir -p "\$builddir"
		}
	EOF
	cat >test.initd<<-EOF
	 	#!/bin/sh
		command="test"
	EOF
	abuild checksum

	atf_check -s exit:1 \
		-o match:"OK" \
		-e match:"ERROR.*is not an openrc" \
		abuild unpack
}

abuild_valid_pkgnames_body() {
	cp -Ra "$testrepo"/test-pkgname .
	cd test-pkgname
	atf_check -s exit:0 \
		-e match:"Validating" \
		abuild validate
	TESTNAME=foo atf_check -s exit:0 \
		-e match:"Validating" \
		abuild validate
	TESTSUBNAME=foo atf_check -s exit:0 \
		-e match:"Validating" \
		abuild validate
	TESTNAME="more_+-2.0-complicated" atf_check -s exit:0 \
		-e match:"Validating" \
		abuild validate
}

abuild_invalid_pkgnames_body() {
	init_keys
	cp -Ra "$testrepo"/test-pkgname .
	cd test-pkgname
	TESTNAME="" atf_check -s exit:1 \
		-e match:"Validating" \
		abuild validate
	TESTNAME="-foo" atf_check -s exit:1 \
		-e match:"Validating" \
		abuild validate
	TESTNAME="foo with spaces" atf_check -s exit:1 \
		-e match:"Validating" \
		abuild validate
	TESTNAME="width@at" atf_check -s exit:1 \
		-e match:"Validating" \
		abuild validate
	TESTNAME="width=equal" atf_check -s exit:1 \
		-e match:"Validating" \
		abuild validate
}

abuild_invalid_subpkgnames_body() {
	init_keys
	cp -Ra "$testrepo"/test-pkgname .
	cd test-pkgname
	TESTSUBNAME="" atf_check -s exit:1 \
		-e match:"Validating" \
		abuild validate
	TESTSUBNAME="-foo" atf_check -s exit:1 \
		-e match:"Validating" \
		abuild validate
}

abuild_duplicate_subpkgname_body() {
	init_keys
	cp -Ra "$testrepo"/test-pkgname .
	cd test-pkgname
	TESTNAME="test-name" TESTSUBNAME="test-name" atf_check -s exit:1 \
		-e match:"Validating" \
		abuild validate
	TESTSUBNAME="foo bar foo" atf_check -s exit:1 \
		-e match:"Validating" \
		abuild validate
}

abuild_invalid_subpkg_version_body() {
	init_keys
	cp -Ra "$testrepo"/test-pkgname .
	cd test-pkgname
	TESTDEPVER="1.0-0" atf_check -s exit:1 \
		-e match:"Invalid version" \
		abuild -d all
}

abuild_provide_pkgname_body() {
	init_keys
	cp -Ra "$testrepo"/test-pkgname .
	cd test-pkgname
	TESTNAME=provided atf_check -s exit:1 \
		-e match:"provides must not contain" \
		abuild validate
	TESTNAME=test TESTPROVIDES='test~1' atf_check -s exit:1 \
		-e match:"provides must not contain" \
		abuild validate
	TESTNAME=test TESTPROVIDES='test=1' atf_check -s exit:1 \
		-e match:"provides must not contain" \
		abuild validate
	TESTNAME=test TESTPROVIDES='test>1' atf_check -s exit:1 \
		-e match:"provides must not contain" \
		abuild validate
	TESTNAME=test TESTPROVIDES='test<=1' atf_check -s exit:1 \
		-e match:"provides must not contain" \
		abuild validate
}

abuild_validate_depends_body() {
	init_keys
	cp -Ra "$testrepo"/test-pkgname .
	cd test-pkgname
	TESTDEPENDS="foo" TESTMAKEDEPENDS="bar" \
		atf_check -s exit:0 \
		-e match:"Validating" \
		abuild validate
	TESTDEPENDS="foo=1.0 bar>=1.0" TESTMAKEDEPENDS="baz<=1.0 x<2.0 z>1 !blah" \
		atf_check -s exit:0 \
		-e match:"Validating" \
		abuild validate
	TESTDEPENDS="foo~1.0 bar>~1.0 baz<~1"
		atf_check -s exit:0 \
		-e match:"Validating" \
		abuild validate

	for i in "foo=bar" "foo=~1.0" "foo>1.0_invalid"; do \
		TESTDEPENDS="$i" atf_check -s exit:1 \
			-e match:"Validating" \
			abuild validate
	done
}

abuild_subpackage_arch_body() {
	init_keys
	cp -Ra "$testrepo" .
	cd testrepo/subpackage-arch
	arch="$(abuild -A)"

	for i in noarch all "$arch"; do
		TESTSUBARCH="$i" abuild -d all

		[ -f "$REPODEST/testrepo/$arch/test-pkgname-$i-1.0-r0.apk" ] || \
			atf_fail "Failed to place $i arch subpackage correctly"
		rm -rf "$REPODEST/testrepo"
	done
}

abuild_large_doc_subpackage_body() {
	init_keys
	cp -Ra "$testrepo"/large-doc-subpkg .
	cd large-doc-subpkg
	atf_check -s exit:0 -o ignore \
		-e match:"-doc subpackage is unusually large" \
		abuild -d all
}

abuild_bigdocs_body() {
	init_keys
	cp -Ra "$testrepo"/large-doc-subpkg .
	cd large-doc-subpkg
	options=bigdocs atf_check -s exit:0 -o ignore \
		-e not-match:"-doc subpackage is unusually large" \
		abuild -d all
}

abuild_pkgver_digit_letter_digit_body() {
	cp -Ra "$testrepo"/test-pkgname .
	cd test-pkgname
	TESTPKGVER=1.0p1 atf_check -s exit:1 \
		-e match:'ERROR.*version' \
		abuild validate
}

abuild_multiline_license_body() {
	cp -Ra "$testrepo"/test-licenses .
	cd test-licenses
	abuild rootpkg
	atf_check -o match:'^license = \(GPL-3.0-only OR GPL-3.0-or-later AND BSD-4-Clause\) AND MIT$' \
		cat pkg/.control.test-licenses/.PKGINFO
}

abuild_license_spdx_body() {
	cp -Ra "$testrepo"/test-licenses .
	cd test-licenses
	TESTPKGVER=1.0_p1 atf_check -s exit:0 \
		-e not-match:'WARNING' \
		abuild validate
}

abuild_git_ceiling_body() {
	init_keys
	git init
	mkdir git-pkg
	cd git-pkg
	cat >APKBUILD<<-EOF
		# Maintainer: Joe User <juser@example.com>
		pkgname="git-pkg"
		pkgver="1.0"
		pkgrel=0
		pkgdesc="Dummy test package"
		url="https://gitlab.alpinelinux.org/alpine/aports"
		arch="noarch"
		license="MIT"
		prepare() {
			mkdir -p "\$builddir"
		}
		build() {
			git status
		}
		package() {
			mkdir -p "\$pkgdir"
		}
	EOF
	atf_check -s exit:1 \
		-e match:"not a git repository" \
		-e match:"ERROR: git-pkg: build failed" \
		abuild -d
}

abuild_package_size_body() {
	init_keys
	mkdir -p test-size

	cd test-size
	cat > APKBUILD <<-EOF
		# Maintainer: Test User 123 <123@example.com>
		pkgname="test-size"
		pkgver="1.0"
		pkgrel=0
		pkgdesc='Dummy test package that has no files'
		url='https://gitlab.alpinelinux.org/alpine/aports'
		arch='noarch'
		license='MIT'
		install="\$pkgname-empty-script.post-install"
		triggers="\$pkgname-empty-trigger.trigger=/"
		subpackages="
			\$pkgname-empty-noscript:_empty
			\$pkgname-empty-script:_empty
			\$pkgname-empty-trigger:_empty
			\$pkgname-empty-file:_empty_file
			\$pkgname-dirs:_dirs
			\$pkgname-files:_files
			\$pkgname-many:_many
			\$pkgname-holes:_holes
			\$pkgname-hardlink:_hardlink
			\$pkgname-symlink:_symlink
			\$pkgname-symlink-follow:_symlink_follow
		"

		# Test if multi line bc output is handle properly
		export BC_LINE_LENGTH=1

		package() {
			mkdir -p "\$pkgdir"
		}

		_empty() {
			mkdir -p "\$subpkgdir"
		}

		_empty_file() {
			mkdir -p "\$subpkgdir"
			touch "\$subpkgdir"/foo
		}

		_dirs() {
			mkdir -p "\$subpkgdir/a/ /v/e/r/y/ /d/e/e/p/ /d/i/r"
			mkdir -p "\$subpkgdir"/b "\$subpkgdir"/c
		}

		_files() {
			mkdir -p "\$subpkgdir"
			cd "\$subpkgdir"
			printf 'test\\n' > test
			touch empty
			mkdir -p dir
			printf 'more\\n' > dir/more
			printf 'size leak!\\n' > secret
			chmod a-rwx secret
			printf 'quoting and stuff\\n' > dir/"\\\$can't \\"touch \\\\this"
		}

		_many() {
			mkdir -p "\$subpkgdir"
			for i in \$(seq 1000); do
				printf '\\n' > "\$subpkgdir/\$i"
			done
		}

		_holes() {
			mkdir -p "\$subpkgdir"
			dd if=/dev/zero bs=1 seek=65534 count=1 of="\$subpkgdir"/holes
		}

		_hardlink() {
			mkdir -p "\$subpkgdir"
			cd "\$subpkgdir"
			printf 'test\\n' > test
			ln test link
			ln test link2
		}

		_symlink() {
			mkdir -p "\$subpkgdir"
			ln -s / "\$subpkgdir"/link
		}

		_symlink_follow() {
			mkdir -p "\$subpkgdir"
			printf 'test\\n' > "\$subpkgdir"/test
			ln -s test "\$subpkgdir"/link
		}
	EOF
	cat > test-size-empty-script.post-install <<-EOF
		#!/bin/sh
		echo 1
	EOF
	cat > test-size-empty-trigger.trigger <<-EOF
		#!/bin/sh
		echo 1
	EOF
	abuild rootpkg
	local i size
	for i in \
		empty-noscript:0 \
		empty-script:1 \
		empty-trigger:1 \
		empty-file:1 \
		dirs:1 \
		files:39 \
		many:1000 \
		holes:65535 \
		hardlink:5 \
		symlink:1 \
		symlink-follow:5 \
		; do \
		size=$(awk -F ' = ' '$1 == "size" {print $2}' pkg/.control.test-size-${i%:*}/.PKGINFO)
		[ "$size" -eq "${i#*:}" ] ||
			atf_fail "$i failed: got $size"
	done
}

abuild_keepdirs_body() {
	init_keys
	mkdir -p test-amove

	cd test-amove
	cat > APKBUILD <<-EOF
		# Maintainer: Test User 123 <123@example.com>
		pkgname="test-keepdirs"
		pkgver="1.0"
		pkgrel=0
		pkgdesc='Dummy test package - keepdirs'
		url='https://gitlab.alpinelinux.org/alpine/aports'
		arch='noarch'
		license='MIT'
		options='keepdirs'

		package() {
			mkdir -p "\$pkgdir"/usr/bin
		}
	EOF
	abuild rootpkg || atf_fail "abuild rootpkg failed"
	test -d pkg/test-keepdirs/usr/bin || atf_fail "$i failed"
}

abuild_amove_body() {
	init_keys
	mkdir -p test-amove

	cd test-amove
	cat > APKBUILD <<-EOF
		# Maintainer: Test User 123 <123@example.com>
		pkgname="test-amove"
		pkgver="1.0"
		pkgrel=0
		pkgdesc='Dummy test package - amove'
		url='https://gitlab.alpinelinux.org/alpine/aports'
		arch='noarch'
		license='MIT'
		subpackages="\$pkgname-file:_file
			\$pkgname-etc:_etc
			\$pkgname-bin:_bin
			\$pkgname-sbin:_sbin
			\$pkgname-root:_root
			\$pkgname-var:_var
			\$pkgname-usr:_usr
			\$pkgname-space:_space"

		package() {
			mkdir -p "\$pkgdir"/etc \
				"\$pkgdir"/usr/bin \
				"\$pkgdir"/usr/sbin \
				"\$pkgdir"/var/lib/\$pkgname \
				"\$pkgdir"/usr/share
			touch "\$pkgdir"/etc/file \
				"\$pkgdir"/etc/\$pkgname.conf \
				"\$pkgdir"/usr/bin/hello \
				"\$pkgdir"/usr/sbin/shello \
				"\$pkgdir"/root \
				"\$pkgdir"/usr/sbin/space' ' \
				"\$pkgdir"/var/lib/\$pkgname/testfile \
				"\$pkgdir"/usr/share/a \
				"\$pkgdir"/usr/share/b
			ln -s dangling "\$pkgdir"/symlink
		}
		_file() {
			amove etc/file
		}
		_etc() {
			# leading and trailing /
			amove ///etc/
		}
		_bin() {
			# trailing /
			amove usr/bin///
		}
		_sbin() {
			# no leading and trailing /
			amove usr/sbin/shello
		}
		_root() {
			# no /
			amove root

			# symlink without existing target
			amove symlink
		}
		_var() {
			# leading /
			amove /var/lib
		}
		_usr() {
			# glob *
			amove usr/share/*
			! amove no-glob-match/*
		}
		_space() {
			# with space
			amove usr/sbin/space' '
		}

	EOF
	abuild rootpkg || atf_fail "abuild rootpkg failed"
	for i in \
			test-amove-file/etc/file \
			test-amove-etc/etc/test-amove.conf \
			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/usr/sbin/space' ' \
			; do \
		[ -L pkg/"$i" ] || [ -e pkg/"$i" ] || atf_fail "$i failed"
	done
}

abuild_doc_body() {
	init_keys
	mkdir -p foo

	cd foo
	cat > APKBUILD <<-EOF
		# Maintainer: Test User 123 <123@example.com>
		pkgname="foo"
		pkgver="1.0"
		pkgrel=0
		pkgdesc='Dummy test package - doc'
		url='https://gitlab.alpinelinux.org/alpine/aports'
		arch='noarch'
		license='MIT'
		subpackages="\$pkgname-doc"

		build() {
			touch foo foo.1 readme
		}

		package() {
			install -Dt "\$pkgdir"/usr/bin foo
			install -Dt "\$pkgdir"/usr/share/man/man1 foo.1
			ln -s foo.1 "\$pkgdir"/usr/share/man/man1/sym.1
			ln "\$pkgdir"/usr/share/man/man1/foo.1 "\$pkgdir"/usr/share/man/man1/hard-a.1
			ln "\$pkgdir"/usr/share/man/man1/foo.1 "\$pkgdir"/usr/share/man/man1/hard-b.1
			# This should be considered a crime
			ln "\$pkgdir"/usr/share/man/man1/sym.1 "\$pkgdir"/usr/share/man/man1/hard-sym.1
			install -Dt "\$pkgdir"/usr/share/doc/foo readme
		}
	EOF
	abuild build rootpkg || atf_fail "abuild rootpkg failed"
	find pkg
	for i in \
			foo/usr/bin/foo \
			foo-doc/usr/share/man/man1/foo.1.gz \
			foo-doc/usr/share/doc/foo/readme \
			; do \
		test -f pkg/$i || atf_fail "$i failed"
	done
	cd pkg/foo-doc/usr/share/man/man1
	for i in sym.1.gz hard-a.1.gz hard-b.1.gz hard-sym.1.gz; do
		test "$(readlink $i)" = "foo.1.gz" || atf_fail "$i link failed"
	done
}

abuild_dev_body() {
	init_keys
	mkdir -p foo

	cd foo
	cat > APKBUILD <<-EOF
		# Maintainer: Test User 123 <123@example.com>
		pkgname="foo"
		pkgver="1.0"
		pkgrel=0
		pkgdesc='Dummy test package - dev'
		url='https://gitlab.alpinelinux.org/alpine/aports'
		arch='noarch'
		license='MIT'
		subpackages="\$pkgname-dev"

		build() {
			touch foo foo.h libfoo.so.1
		}

		package() {
			install -Dt "\$pkgdir"/usr/bin foo
			install -Dt "\$pkgdir"/usr/include foo.h
			install -Dt "\$pkgdir"/usr/lib libfoo.so.1
			ln -s libfoo.so.1 "\$pkgdir"/usr/lib/libfoo.so
		}
	EOF
	abuild build rootpkg || atf_fail "abuild rootpkg failed"
	find pkg
	for i in \
			foo/usr/bin/foo \
			foo-dev/usr/include/foo.h \
			; do \
		test -f pkg/$i || atf_fail "$i failed"
	done
	test -L pkg/foo-dev/usr/lib/libfoo.so || atf_fail "libfoo.so failed"
}

abuild_devhelp_warn_body() {
	init_keys
	mkdir -p foo

	cd foo
	cat > APKBUILD <<-EOF
		# Maintainer: Test User 123 <123@example.com>
		pkgname="foo"
		pkgver="1.0"
		pkgrel=0
		pkgdesc='Dummy test package that has devhelp'
		url='https://gitlab.alpinelinux.org/alpine/aports'
		arch='noarch'
		license='MIT'

		package() {
			mkdir -p "\$pkgdir"/usr/share/devhelp/book
		}
	EOF
	atf_check -e match:"WARNING:" \
		abuild rootpkg
}

abuild_devhelp_body() {
	init_keys
	mkdir -p foo

	cd foo
	cat > APKBUILD <<-EOF
		# Maintainer: Test User 123 <123@example.com>
		pkgname="foo"
		pkgver="1.0"
		pkgrel=0
		pkgdesc='Dummy test package that has devhelp'
		url='https://gitlab.alpinelinux.org/alpine/aports'
		arch='noarch'
		license='MIT'
		subpackages="\$pkgname-devhelp"

		package() {
			mkdir -p "\$pkgdir"/usr/share/devhelp/book
		}
	EOF
	atf_check -e not-match:"WARNING:" \
		-o match:'->' \
		abuild rootpkg
}

abuild_check_maintainer_body() {
	mkdir -p foo && cd foo
	for m in "Test User 123 <123example.com>" \
			"foo" \
			"user@example.com" \
			" Leading Space <n@example.com>" \
			"Trailing Space <n@example.com> " \
			"Foo<u@example.com>" \
			'"Quotes <u@example.com>"'; do
		printf "# Maintainer: %s\n%s\n" "$m" "pkgname=foo" > APKBUILD
		atf_check -s not-exit:0 \
			-e match:"ERROR:" \
			abuild check_maintainer
	done

	for m in "Test User <123@example.com>" "Foo O'Brian <n@example.com>" "Łukasz Something <s@example.com>"; do
		printf "# Maintainer: %s\n%s\n" "$m" "pkgname=foo" > APKBUILD
		atf_check abuild check_maintainer
	done
}

abuild_cleanoldpkg_body() {
	init_keys
	mkdir -p main/foo
	cd main/foo
	for arch in aarch64 x86_64; do
		for v in 0.9 1.0 1.1; do
			cat > APKBUILD <<-EOF
				# Maintainer: Test User 123 <123@example.com>
				pkgname="foo"
				pkgver="$v"
				pkgrel=0
				pkgdesc='Dummy test package - dev'
				url='https://gitlab.alpinelinux.org/alpine/aports'
				arch='noarch'
				license='MIT'
				options='!check'
				package() {
					mkdir -p "\$pkgdir"
				}
			EOF
			CARCH=$arch atf_check -e not-empty abuild clean unpack rootpkg
		done
	done

	CARCH=aarch64 atf_check -e match:"Cleaning" abuild cleanoldpkg

	find "$REPODEST"

	# should keep the current APKBUILD version
	for arch in aarch64 x86_64; do
		f="$REPODEST"/main/$arch/foo-1.1-r0.apk
		if ! test -e "$f"; then
			atf_fail "$f was deleted"
		fi
	done

	# should remove old packages of aarch64
	for i in 0.9 1.0; do
		f="$REPODEST"/main/aarch64/foo-$i-r0.apk
		if test -e "$f"; then
			atf_fail "$f was not deleted"
		fi
	done

	# should not delete other arches than aarch64
	for i in 0.9 1.0; do
		f="$REPODEST"/main/x86_64/foo-$i-r0.apk
		if ! test -e "$f"; then
			atf_fail "$f was deleted"
		fi
	done
}

abuild_clean_body() {
	mkdir -p testrepo/clean
	cd testrepo/clean
	cat > APKBUILD <<-EOF
		# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
		pkgname="clean"
		pkgver=1.0
		pkgrel=0
		pkgdesc="Dummy test package"
		url="https://gitlab.alpinelinux.org/alpine/aports"
		arch="noarch"
		license="MIT"
		options="!check"
		subpackages="\$pkgname-subpkg"
		builddir="\$srcdir"

		build() {
			mkdir -p "\$srcdir"/srcdir/a
			chmod 0 "\$srcdir"/srcdir

			mkdir -p "\$tmpdir"/tmpdir/a
			chmod 0 "\$tmpdir"/tmpdir
		}

		package() {
			mkdir -p "\$pkgdir"/pkgdir/a
			chmod 0 "\$pkgdir"/pkgdir
		}

		subpkg() {
			mkdir -p "\$subpkgdir"/subpkgdir/a
			chmod 0 "\$subpkgdir"/subpkgdir
		}
	EOF
	abuild clean unpack prepare build rootpkg

	abuild -K clean

	{
		[ -d src/srcdir ] &&
		[ -d tmp/tmpdir ] &&
		[ -d pkg/clean/pkgdir ] &&
		[ -d pkg/clean-subpkg/subpkgdir ]
	} || atf_fail "cleaned with -K"

	abuild clean || atf_fail "unable to clean"


	if
		[ -d src/srcdir ] ||
		[ -d tmp/tmpdir ] ||
		[ -d pkg/clean/pkgdir ] ||
		[ -d pkg/clean-subpkg/subpkgdir ]
	then
		atf_fail "not cleaned"
	fi
}

abuild_path_with_spaces_body() {
	init_keys
	cp -Ra "$testrepo" .
	cd testrepo/pkg\ path\ with\ spaces
	atf_check -s exit:0 \
		-o match:"hello world" \
		-e match:"Build complete" \
		abuild -d
}

abuild_pyc_warn_body() {
	init_keys

	mkdir -p pycachetest
	cd pycachetest
	cat >APKBUILD <<-EOF
		# Maintainer: Joe User <juser@example.com>
		pkgname="pycachetest"
		pkgver="1.0"
		pkgrel=0
		pkgdesc="Dummy test package"
		url="https://gitlab.alpinelinux.org/alpine/aports"
		arch="noarch"
		license="MIT"
		source=""

		package() {
			mkdir -p "\$pkgdir"/usr/lib/python3.11/site-packages/test/__pycache__/
			touch "\$pkgdir"/usr/lib/python3.11/site-packages/test/__pycache__/main.cpython-311.pyc
		}
	EOF

	atf_check -e match:"WARNING.*pyc*" abuild rootpkg
}

abuild_pyc_body() {
	init_keys

	mkdir -p foo
	cd foo
	cat >APKBUILD <<-EOF
		# Maintainer: Joe User <juser@example.com>
		pkgname="foo"
		pkgver="1.0"
		pkgrel=0
		pkgdesc="Dummy test package"
		url="https://gitlab.alpinelinux.org/alpine/aports"
		arch="noarch"
		license="MIT"
		source=""
		subpackages="\$pkgname-pyc"

		package() {
			mkdir -p "\$pkgdir"/usr/lib/python3.11/site-packages/test/__pycache__/
			touch "\$pkgdir"/usr/lib/python3.11/site-packages/test/__pycache__/main.cpython-311.pyc
		}
	EOF

	atf_check -o match:"->" -e not-match:"WARNING.*pyc*" abuild rootpkg
	atf_check -o match:"__pycache__" find pkg/foo-pyc -name '__pycache__'
	# verify install_if is correct
	atf_check -o match:"foo=1.0-r0" -o match:"pyc" \
		grep install_if pkg/.control.foo-pyc/.PKGINFO
}

abuild_setcap_binary_body() {
	init_keys
	cp -Ra "$testrepo"/setcap .
	cd setcap
	atf_check -s exit:1 \
		-e match:"Found binary with extra capabilities" \
		-e match:"Found setcap binary executable by others" \
		abuild -d all
}

abuild_setcap_binary_with_option_body() {
	init_keys
	cp -Ra "$testrepo"/setcap .
	cd setcap
	options=setcap atf_check -s exit:0 \
		-e not-match:"Found binary with extra capabilities" \
		-e match:"Found setcap binary executable by others" \
		abuild -d all
}

abuild_command_provides_body() {
	init_keys
	mkdir testprovides
	cd testprovides
	cat >APKBUILD<<-EOF
		# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
		pkgname=testprovides
		pkgver=1.0
		pkgrel=0
		pkgdesc="Dummy test package that installs a file and directory in path"
		url="https://gitlab.alpinelinux.org/alpine/aports"
		arch="noarch"
		license="MIT"
		subpackages="noprovides"
		options="noprovides::!tracedeps"
		package() {
			mkdir -p "\$pkgdir/usr/bin"
			printf "%s\n" '#!/bin/sh' >"\$pkgdir/usr/bin/foo"
			chmod +x "\$pkgdir/usr/bin/foo"
			cp -a "\$pkgdir/usr/bin/foo" "\$pkgdir/usr/bin/foo@"
			mkdir -p "\$pkgdir/usr/bin/dir/"
			ln -s /usr/bin/not-on-the-host-system-but-in-a-dependency "\$pkgdir/usr/bin/link"
		}

		noprovides() {
			mkdir -p "\$subpkgdir/usr/bin"
			printf "%s\n" '#!/bin/sh' >"\$subpkgdir/usr/bin/foo"
			chmod +x "\$subpkgdir/usr/bin/foo"
		}
	EOF
	abuild rootpkg

	atf_check \
		-o match:"provides = cmd:foo=1.0-r0" \
		-o not-match:"provides = cmd:foo@=1.0-r0" \
		-o match:"provides = cmd:link=1.0-r0" \
		-o not-match:"provides = cmd:dir=1.0-r0" \
		grep '^provides = ' pkg/.control.testprovides/.PKGINFO

	atf_check -s exit:1 \
		-o not-match:"provides" \
		grep '^provides = ' pkg/.control.noprovides/.PKGINFO
}

abuild_gocache_dir_body() {
	init_keys
	mkdir gocache-dir
	cd gocache-dir
	cat >APKBUILD<<-EOF
		# Maintainer: Joe User <juser@example.com>
		pkgname="gocache-dir"
		pkgver="1.0"
		pkgrel=0
		pkgdesc="Dummy test package"
		url="https://gitlab.alpinelinux.org/alpine/aports"
		arch="noarch"
		license="MIT"
		prepare() {
			mkdir -p "\$builddir"
		}
		build() {
			echo "dir:\$GOCACHE"
		}
		package() {
			:
		}
	EOF

	unset GOCACHE
	atf_check -s exit:0 \
		-o match:"dir:.*/tmp/go" \
		abuild prepare build
}

abuild_cargo_home_dir_body() {
	init_keys
	mkdir cargo-home-dir
	cd cargo-home-dir
	cat >APKBUILD<<-EOF
		# Maintainer: Joe User <juser@example.com>
		pkgname="cargo-home-dir"
		pkgver="1.0"
		pkgrel=0
		pkgdesc="Dummy test package"
		url="https://gitlab.alpinelinux.org/alpine/aports"
		arch="noarch"
		license="MIT"
		prepare() {
			mkdir -p "\$builddir"
		}
		build() {
			echo "dir:\$CARGO_HOME"
		}
		package() {
			:
		}
	EOF

	unset CARGO_HOME
	atf_check -s exit:0 \
		-o match:"dir:.*/tmp/cargo" \
		abuild prepare build
}

abuild_fish_comp_split_body() {
	init_keys
	mkdir fish-split-dir
	cd fish-split-dir
	cat >APKBUILD<<-EOF
		# Maintainer: Joe User <juser@example.com>
		pkgname="fish-split-dir"
		pkgver="1.0"
		pkgrel=0
		pkgdesc="Dummy test package"
		url="https://gitlab.alpinelinux.org/alpine/aports"
		arch="noarch"
		license="MIT"
		prepare() {
			mkdir -p "\$builddir"
		}
		package() {
			mkdir -p "\$pkgdir"/usr/share/fish/completions/
			mkdir -p "\$pkgdir"/usr/share/fish/vendor_completions.d/
			echo "comp" > "\$pkgdir"/usr/share/fish/completions/comp.fish
			echo "comp" > "\$pkgdir"/usr/share/fish/vendor_completions.d/comp.fish
		}
	EOF
	# test that there is a warning for the legacy dir existing
	atf_check -s exit:0 \
		-e match:"fish completions for programs should be located in /usr/share/fish/vendor_completions.d" \
		abuild prepare build rootpkg

	# now add the correct subpackage
	echo 'subpackages="$pkgname-subpkg-fish-completion"' >> APKBUILD
	abuild clean prepare build rootpkg

	if ! [ -d pkg/fish-split-dir-subpkg-fish-completion/usr/share/fish/completions ]; then
		echo "missing old dir"
		exit 1
	fi
	if ! [ -d pkg/fish-split-dir-subpkg-fish-completion/usr/share/fish/vendor_completions.d ]; then
		echo "missing new dir"
		exit 1
	fi
	atf_check \
		-o match:"install_if = fish-split-dir-subpkg=1.0-r0 fish" \
		grep '^install_if = ' pkg/.control.fish-split-dir-subpkg-fish-completion/.PKGINFO
}

create_mock_apk() {
	mkdir -p usr/bin
	cat > usr/bin/apk <<-EOF
		#!/bin/sh
		if [ "\$1" = "--print-arch" ]; then
			echo 'aarch64'
			exit 0
		fi
		printf 'apk %s\n' "\$*" >&2
	EOF
	chmod +x usr/bin/apk
	ln -s apk usr/bin/abuild-apk
	PATH="$PWD/usr/bin:$PATH"
	APK="apk"
}

abuild_deps_body() {
	create_mock_apk
	mkdir testdeps
	cd testdeps
	cat >APKBUILD <<-EOF
		# Maintainer: Joe User <juser@example.com>
		pkgname="testdeps"
		pkgver="1.0"
		pkgrel=0
		pkgdesc="Dummy test package"
		url="https://gitlab.alpinelinux.org/alpine/aports"
		arch="noarch"
		license="MIT"
		depends="foo"
		makedepends="bar"
		checkdepends="checkdep"
		makedepends_host="hostdep"
		makedepends_build="builddep"
	EOF

	export SUDO_APK=abuild-apk

	# native build. pull in both depends and makedepends
	# do not install in any --root
	atf_check \
		-e match:'Installing for build: build-base foo bar checkdep$' \
		-e match:'apk add .*--virtual .makedepends-testdeps build-base foo bar checkdep' \
		-e not-match:'apk add .*--root' \
		abuild deps

	# dont install checkdep with ABUILD_BOOTSTRAP
	ABUILD_BOOTSTRAP=1 atf_check \
		-e not-match:"apk add.*checkdep" \
		abuild deps

	# crosscompile:
	#   install makedepends_build without --root
	#   install makedepends_host with --root
	CTARGET='s390x' CHOST='ppc64le' CBUILDROOT="$PWD/root" atf_check \
		-e match:'Installing for build: build-base-s390x builddep' \
		-e match:'Installing for host: hostdep' \
		-e match:'apk add .*--virtual .makedepends-testdeps build-base-s390x builddep' \
		-e not-match:'apk add.*--root.*builddep' \
		-e match:'apk add .*--root.*hostdep' \
		-e not-match:'apk add.*checkdep' \
		abuild deps

	# crosscompile, set only CHOST
	CHOST='armhf' atf_check \
		-e match:'apk add.*builddep' \
		-e not-match:'apk add.*--root.*builddep' \
		-e match:'apk add.*--root.*hostdep' \
		abuild deps

	# Check shell_escape
	atf_check \
		-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"
		options="!check"

		package() {
			mkdir -p \
				"\$pkgdir"/lib \
				"\$pkgdir"/bin \
				"\$pkgdir"/sbin
		}
	EOF
	atf_check -s exit:0 \
		-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 -d
}

abuild_symlink_depends_body() {
	init_keys
	mkdir testsymlink
	cd testsymlink
	cat >APKBUILD<<- 'EOF'
		# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
		pkgname=testsymlink
		pkgver=1.0
		pkgrel=0
		pkgdesc="Dummy test package for symlink dependency tracing"
		url="https://gitlab.alpinelinux.org/alpine/aports"
		arch="noarch"
		license="MIT"
		subpackages="bar:_dir baz:_dir baz-2:_dir absolute relative multiple duplicate notrace:absolute"
		options="notrace::!tracedeps"

		package() {
			mkdir -p "$pkgdir/foo"
		}

		_dir() {
			mkdir -p "$subpkgdir/${subpkgname%-*}"
		}

		absolute() {
			mkdir -p "$subpkgdir"/links
			ln -s /foo "$subpkgdir"/links/
		}

		relative() {
			mkdir -p "$subpkgdir"/links
			ln -s ../foo "$subpkgdir"/links/
		}

		multiple() {
			mkdir -p "$subpkgdir"/links
			ln -s ../foo ../bar "$subpkgdir"/links/
		}

		duplicate() {
			mkdir -p "$subpkgdir"/links
			ln -s ../baz "$subpkgdir"/links/
		}
	EOF
	abuild rootpkg

	set -x

	atf_check \
		-o match:"depend = testsymlink=1.0-r0" \
		-o not-match:"depend = foo-notrace=1.0-r0" \
		grep '^depend = ' pkg/.control.absolute/.PKGINFO

	atf_check \
		-o match:"depend = testsymlink=1.0-r0" \
		-o not-match:"depend = foo-notrace=1.0-r0" \
		grep '^depend = ' pkg/.control.relative/.PKGINFO

	atf_check \
		-o match:"depend = testsymlink=1.0-r0" \
		-o not-match:"depend = foo-notrace=1.0-r0" \
		-o match:"depend = bar=1.0-r0" \
		grep '^depend = ' pkg/.control.multiple/.PKGINFO

	atf_check -s exit:1 \
		-o not-match:"depend = testsymlink=1.0-r0" \
		-o not-match:"depend = foo-notrace=1.0-r0" \
		grep '^depend = ' pkg/.control.notrace/.PKGINFO

	atf_check -s exit:1 \
		-o not-match:"depend = baz=1.0-r0" \
		-o not-match:"depend = baz-2=1.0-r0" \
		grep '^depend = ' pkg/.control.duplicate/.PKGINFO
}

abuild_pc_providers_body() {
	init_keys
	mkdir testsymlink
	cd testsymlink
	cat >APKBUILD<<- '__EOF__'
		# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
		pkgname=testpc
		pkgver=1.0
		pkgrel=0
		pkgdesc="Dummy test package for pkgconf provides tracing"
		url="https://gitlab.alpinelinux.org/alpine/aports"
		arch="noarch"
		license="MIT"
		subpackages="name provides share dot_rc nover"

		package() {
			mkdir -p "$pkgdir"/usr/lib/pkgconfig
			cat > "$pkgdir"/usr/lib/pkgconfig/pkg.pc <<EOF
Name: pkg
Description:
Version: 1.0
EOF
		}

		name() {
			mkdir -p "$subpkgdir"/usr/lib/pkgconfig
			cat > "$subpkgdir"/usr/lib/pkgconfig/pkg.pc <<EOF
Name: pkg-1.0
Description:
Version: 1.0
EOF
		}

		provides() {
			mkdir -p "$subpkgdir"/usr/lib/pkgconfig
			cat > "$subpkgdir"/usr/lib/pkgconfig/pkg.pc <<EOF
Name: pkg
Description:
Version: 1.0
Provides: unver, ver = 2.5
EOF
		}

		share() {
			mkdir -p "$subpkgdir"/usr/share/pkgconfig
			cat > "$subpkgdir"/usr/share/pkgconfig/pkg.pc <<EOF
Name: pkg
Description:
Version: 1.0
EOF
		}

		dot_rc() {
			mkdir -p "$subpkgdir"/usr/lib/pkgconfig
			cat > "$subpkgdir"/usr/lib/pkgconfig/pkg.pc <<EOF
Name: pkg
Description:
Version: 1.0.rc1
Provides: foo = 1.2.3.rc5
EOF
		}

		nover() {
			mkdir -p "$subpkgdir"/usr/lib/pkgconfig
			cat > "$subpkgdir"/usr/lib/pkgconfig/pkg.pc <<EOF
Name: pkg
Description:
Version:
EOF
		}
	__EOF__
	abuild rootpkg

	atf_check \
		-o match:"provides = pc:pkg=1.0" \
		grep '^provides = ' pkg/.control.testpc/.PKGINFO

	atf_check \
		-o match:"provides = pc:pkg=1.0" \
		-o not-match:"provides = pc:pkg-1.0=1.0" \
		grep '^provides = ' pkg/.control.name/.PKGINFO

	atf_check \
		-o match:"provides = pc:pkg=1.0" \
		-o match:"provides = pc:unver=0" \
		-o match:"provides = pc:ver=2.5" \
		grep '^provides = ' pkg/.control.provides/.PKGINFO

	atf_check \
		-o match:"provides = pc:pkg=1.0_rc1" \
		-o match:"provides = pc:foo=1.2.3_rc5" \
		grep '^provides = ' pkg/.control.dot_rc/.PKGINFO

	atf_check \
		-o match:"provides = pc:pkg=0" \
		grep '^provides = ' pkg/.control.nover/.PKGINFO
}

abuild_pc_depends_body() {
	init_keys
	mkdir testsymlink
	cd testsymlink
	cat >APKBUILD<<- '__EOF__'
		# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
		pkgname=testpc
		pkgver=1.0
		pkgrel=0
		pkgdesc="Dummy test package for pkgconf provides tracing"
		url="https://gitlab.alpinelinux.org/alpine/aports"
		arch="noarch"
		license="MIT"
		subpackages="noreq dummy"

		package() {
			mkdir -p "$pkgdir"/usr/lib/pkgconfig
			cat > "$pkgdir"/usr/lib/pkgconfig/pkg.pc <<EOF
Name: pkg
Description:
Version: 1.0
Requires: unver, fixed = 0.1, bound >= 1.2.3.rc5
# TODO these should maybe not be traced
Requires.private: private
# Should not prevent install
Conflicts: conflict
EOF
		}

		noreq() {
			mkdir -p "$subpkgdir"/usr/lib/pkgconfig
			cat > "$subpkgdir"/usr/lib/pkgconfig/pkg.pc <<EOF
Name: pkg
Description:
Version: 1.0
EOF
		}

		dummy() {
			mkdir -p "$subpkgdir"/usr/lib/pkgconfig
			cat > "$subpkgdir"/usr/lib/pkgconfig/pkg.pc <<EOF
Name: pkg
Description:
Version: 1.0
Provides: unver, fixed = 0.1, bound = 1.2.3.rc5, conflict, private
EOF
		}
	__EOF__
	abuild rootpkg

	atf_check \
		-o match:"depend = pkgconf" \
		-o match:"depend = pc:unver$" \
		-o match:"depend = pc:fixed=0.1" \
		-o match:"depend = pc:bound>=1.2.3_rc5" \
		-o match:"depend = pc:private" \
		-o not-match:"pc:conflict" \
		grep '^depend = ' pkg/.control.testpc/.PKGINFO

	atf_check \
		-o match:"depend = pkgconf" \
		-o not-match:"pc:" \
		grep '^depend = ' pkg/.control.noreq/.PKGINFO
}

abuild_split_vars_reset_body() {
	init_keys
	mkdir testsplitvars
	cd testsplitvars
	cat >APKBUILD<<- '__EOF__'
		# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
		pkgname=testsplit
		pkgver=1.0
		pkgrel=0
		pkgdesc="desc"
		url="https://gitlab.alpinelinux.org/alpine/aports"
		arch="noarch"
		license="MIT"
		subpackages="foo bar"

		package() {
			mkdir -p "$pkgdir"
		}

		foo() {
			pkgdesc="foo $pkgdesc"
			mkdir -p "$subpkgdir"
		}

		bar() {
			pkgdesc="bar $pkgdesc"
			mkdir -p "$subpkgdir"
		}
	__EOF__
	abuild rootpkg

	atf_check \
		-o match:"pkgdesc = desc" \
		grep '^pkgdesc = ' pkg/.control.testsplit/.PKGINFO

	atf_check \
		-o match:"pkgdesc = foo desc" \
		grep '^pkgdesc = ' pkg/.control.foo/.PKGINFO

	atf_check \
		-o match:"pkgdesc = bar desc" \
		grep '^pkgdesc = ' pkg/.control.bar/.PKGINFO
}
