# Contributor: Jakub Jirutka <jakub@jirutka.cz>
# Maintainer: Jakub Jirutka <jakub@jirutka.cz>
pkgname=deno
pkgver=2.0.6
pkgrel=0
pkgdesc="A modern runtime for JavaScript and TypeScript"
url="https://deno.land/"
# armhf,armv7,x86: deno currently doesn't support 32-bit arches
# ppc64le,riscv64,s390x: fails to build ring crate
arch="aarch64 x86_64"
license="MIT"
depends="ca-certificates"
# This follows compiler-rt, not clang or llvm package.
_llvmver=19
makedepends="
	cargo
	cargo-auditable
	clang-dev
	compiler-rt
	curl
	glib-dev
	gn
	icu-dev
	jq
	libffi-dev
	lld
	llvm-dev
	protoc
	python3
	samurai
	sqlite-dev
	zlib-dev
	zlib-ng-dev
	zstd-dev
	"
checkdepends="
	bash
	coreutils-env
	curl
	nodejs
	npm
	"
subpackages="
	denort
	$pkgname-bash-completion
	$pkgname-fish-completion
	$pkgname-zsh-completion
	"
_rusty_v8_ver=0.106.0
_stacker_ver=0.1.15
# Note: We use the crate instead of GitHub tarball due to lacks of submodules
# in the tarball.
source="$pkgname-$pkgver.tar.gz::https://github.com/denoland/deno/releases/download/v$pkgver/deno_src.tar.gz
	$pkgname-rusty_v8-$_rusty_v8_ver.tar.gz::https://static.crates.io/crates/v8/v8-$_rusty_v8_ver.crate
	$pkgname-stacker-$_stacker_ver.tar.gz::https://github.com/rust-lang/stacker/archive/stacker-$_stacker_ver.tar.gz
	$pkgname-generate_shim_headers.py::https://raw.githubusercontent.com/chromium/chromium/117.0.5881.2/tools/generate_shim_headers/generate_shim_headers.py
	stacker-detect-stack-overflow.patch
	stacker-disable-guess_os_stack_limit.patch
	v8-build.patch
	v8-compiler.patch
	v8-musl-monotonic-pthread-cont_timedwait.patch
	v8-no-execinfo.patch
	v8-use-system-zlib.patch
	v8-use-system-icu.patch
	v8-fix-bindgen-macro.patch
	disable-core-defaults.patch
	use-system-libs.patch
	ignore-tests-broken-on-ci.patch
	tests-musl-compat.patch
	tests-disable-upgrade.patch
	tests-fix-sh-path.patch
	tests-ignore-flaky.patch
	unbundle-ca-certs.patch
	cargo.lock.patch
	"
	#tests-fix-npx-output.patch
builddir="$srcdir/deno"

# TODO:
# - build variant without dev tools
#
# NOTES:
# - deno segfaults when built with is_official_build=true and upstream doesn't
#   enable this flag either.
# - deno_runtime (build script) fails when built with use_thin_lto=true.
# - We can link against system libsecp256k1, but author of rust-secp256k1
#   strongly discourages against it (https://github.com/rust-bitcoin/rust-secp256k1/issues/629).
#   Also, it reduces the binary size only by 0.1 MiB.

# Don't use prebuilt libv8.a, build it from source (for rusty_v8).
export V8_FROM_SOURCE=1

# Use system gn and ninja (for v8).
export GN=/usr/bin/gn
export NINJA=/usr/bin/ninja

# Build with clang (for v8).
export AR=llvm-ar
export CC=clang
export CXX=clang++
export LD=clang++
export NM=llvm-nm

# Flags copied from community/chromium (for building v8)
export CFLAGS="${CFLAGS/-Os/} -O2 -Wno-unknown-warning-option -Wno-builtin-macro-redefined -Wno-deprecated-declarations"
export CXXFLAGS="${CXXFLAGS/-Os/} -O2 -Wno-unknown-warning-option -Wno-builtin-macro-redefined -Wno-deprecated-declarations"
export CPPFLAGS="$CPPFLAGS -D__DATE__=  -D__TIME__=  -D__TIMESTAMP__="

# clang supports stack-clash-protection only on x86(_64), ppc64le and s309x.
if [ "$CARCH" != 'x86_64' ]; then
	export CFLAGS="${CFLAGS/-fstack-clash-protection/}"
	export CXXFLAGS="${CXXFLAGS/-fstack-clash-protection/}"
fi

# Enable verbose logging for v8 compilation, so we can see actual flags used.
export SAMUFLAGS="$SAMUFLAGS -v"

# Flags for building v8; inspired by community/chromium and
# https://github.com/12101111/overlay.
export GN_ARGS="
	chrome_pgo_phase=0
	custom_toolchain=\"//build/toolchain/linux/unbundle:default\"
	host_toolchain=\"//build/toolchain/linux/unbundle:default\"
	v8_snapshot_toolchain=\"//build/toolchain/linux/unbundle:default\"
	clang_base_path=\"/usr/lib/llvm$_llvmver\"
	clang_version=\"$_llvmver\"
	fatal_linker_warnings=false
	is_debug=false
	symbol_level=0
	system_zlib=true
	use_custom_libcxx=false
	use_sysroot=false
	"

export EXTRA_GN_ARGS="use_custom_libcxx=false"

# deno seems to foolishly assume 8MiB stack
# -A warnings - silence rust linter warnings
export RUSTFLAGS="$RUSTFLAGS -C linker=clang++ -C link-arg=-fuse-ld=lld -C link-args=-Wl,-zstack-size=8388608 -A warnings"

# Included limited debug info.
export CARGO_PROFILE_RELEASE_DEBUG=1
# Use "thin" instead of "fat" to speed up builds (it costs +4% binary size).
export CARGO_PROFILE_RELEASE_LTO="thin"

# Deno fine-tunes opt-level per crate.
unset CARGO_PROFILE_RELEASE_OPT_LEVEL
# Switching to panic=abort is too risky for Deno.
unset CARGO_PROFILE_RELEASE_PANIC

_cargo_opts="--frozen --no-default-features"

prepare() {
	mkdir -p vendor
	mv ../stacker-stacker-$_stacker_ver vendor/stacker
	mv ../v8-$_rusty_v8_ver vendor/v8
	install -Dm755 "$srcdir"/$pkgname-generate_shim_headers.py \
		vendor/v8/tools/generate_shim_headers/generate_shim_headers.py

	default_prepare

	cd vendor/v8

	local use_system="icu"
	python3 build/linux/unbundle/replace_gn_files.py --system-libraries $use_system
	local lib; for lib in $use_system; do
		sed -i '/"\/\/base"/d' third_party/$lib/BUILD.gn
		find . -type f -path "*third_party/$lib/*" \
			\! -regex '.*\.\(gn\|gni\|isolate\|py\)' \
			\! -name 'compression_utils_portable.*' \
			-delete
	done

	cd "$builddir"

	# Build with patched stacker and v8 (see *.patch files).
	cat >> Cargo.toml <<-EOF

		[patch.crates-io]
		stacker = { path = "vendor/stacker" }
		v8 = { path = "vendor/v8" }
	EOF

	# Rust target triple.
	local target=$(rustc -vV | sed -n 's/host: //p')

	# NOTE: zstd "pkg-config" feature doesn't work, so we have to do this.
	mkdir -p .cargo
	cat >> .cargo/config.toml <<-EOF
		[target.$target]
		z-ng = { rustc-link-lib = ["z-ng"], rustc-cfg = ["zng"] }
		zstd = { rustc-link-lib = ["zstd"] }
	EOF

	cargo fetch --target="$CTARGET" --locked

	local stacker_ver="$(_crate_ver 'stacker')"
	[ "$stacker_ver" = "$_stacker_ver" ] || die "Update _stacker_ver to $stacker_ver"

	local rusty_v8_ver="$(_crate_ver 'v8')"
	[ "$rusty_v8_ver" = "$_rusty_v8_ver" ] || die "Update _rusty_v8_ver to $rusty_v8_ver"

	# FIXME: This test is perhaps broken.
	rm -rf tests/specs/cert/cafile_install

	# We disable the upgrade feature.
	rm -rf tests/specs/upgrade
}

build() {
	export CLANG_BASE_PATH="$(llvm-config --prefix)"
	# Build with -g1 instead of -g (which is -g2); -g is added by abuild
	# after sourcing APKBUILD, so is must be modified in a function.
	export CFLAGS="${CFLAGS/-g/-g1}"
	export CXXFLAGS="${CXXFLAGS/-g/-g1}"
	# Increase stack size for 'cargo build' to avoid stack overflow.
	export RUST_MIN_STACK="4194304"

	cargo auditable build $_cargo_opts --release -vv

	mkdir -p comp
	local shell; for shell in bash fish zsh; do
		./target/release/deno completions $shell > comp/deno.$shell
	done
}

check() {
	export CLANG_BASE_PATH="$(llvm-config --prefix)"
	# Skip some tests that don't work on CI (e.g. webgpu_test).
	export CI=true
	# Increase stack size for 'cargo build' to avoid stack overflow.
	export RUST_MIN_STACK="4194304"

	# Build tests in release mode to avoid rebuilding v8 again (in debug mode).
	local cargo_opts="$_cargo_opts --release --no-fail-fast"

	msg "Running tests"

	PATH="$PWD/target/release:$PATH" cargo test $cargo_opts --workspace --exclude test_ffi

	case "$CARCH" in
		# basic test fails on aarch64.
		# https://gitlab.alpinelinux.org/alpine/aports/-/merge_requests/48979#note_323013
		# TODO: Figure out why...
		aarch64) cargo test $cargo_opts --package test_ffi || true;;
		*) cargo test $cargo_opts --package test_ffi;;
	esac
}

package() {
	install -D -m755 target/release/deno -t "$pkgdir"/usr/bin/
	install -D -m755 target/release/denort -t "$pkgdir"/usr/bin/

	install -D -m644 comp/$pkgname.bash "$pkgdir"/usr/share/bash-completion/completions/$pkgname
	install -D -m644 comp/$pkgname.fish "$pkgdir"/usr/share/fish/vendor_completions.d/$pkgname.fish
	install -D -m644 comp/$pkgname.zsh "$pkgdir"/usr/share/zsh/site-functions/_$pkgname
}

denort() {
	pkgdesc="Deno runtime-only binary for deno compile"

	amove usr/bin/denort
}

# Resolves version(s) of crate $1 in the depenendecy graph that satisfies
# regular expression $2 (default is ".*").
_crate_ver() {
	cargo metadata --locked --format-version 1 \
		| jq -r ".packages[] | select(.name == \"$1\" and (.version | test(\"$2\"))) | .version"
}

sha512sums="
de4949ef3bba82ee1b176cddfa818307d8cd847855b87d596b38b9459cab5f51aed7d87bc8b41ba9cf762eca4d71983b2ca9d2906023495c1d8934986bdedec3  deno-2.0.6.tar.gz
ebc1d90e706003f0aea174011241bcf0303355f579855ed7ebadb71b4d8e1711cd70e207b19fdcc657fa0be57525d6398b6bb16e02c18f9e752ad23fce54e936  deno-rusty_v8-0.106.0.tar.gz
88412e029262a0dffe295a648ba87ec50f782afceb19fbe1eda4239c54fbd56432106fcea5d58c93bfbb5b91317dc6642fc7a8e72136df0ef600c77d99e0970f  deno-stacker-0.1.15.tar.gz
ecea1432982e55c462f54aae135e1b7d0c964d9faa2f245cf114910e81ba6b3a06379c11ecd56f82cf3528f478cd394ad759cb246b3cdf70f6a40be744e17ecd  deno-generate_shim_headers.py
08d09c979191d422d71a6db971bdf4472b322ef829b238519bc35db22f9b4639cca40342c7786777684a4ffa4af2c64febf9d9224b2d7d2d33f63671acfa6d5b  stacker-detect-stack-overflow.patch
f2352e197c1da8011b9c11f19150e85dd48cc9356fdc837ccc9ae74a47ee5cde736c838509646527be529b21badd2d25e002a22cc9cb265d2ceedecd9f808b09  stacker-disable-guess_os_stack_limit.patch
c22ea9a32b6c5850a75681ebbb3772fa9539f36b186a1b01c6c83b9f9cdc9c9f3559be915d4f75c7eba12c450980ade14278934764da64ee473c42f15250076d  v8-build.patch
bb1732b087917c363a8b77f8d57fafcc7f2ef0a320ea6d1099c3108bc8c15243a6738960b73f43403ba47777c195db6f7239563103b42a36d6350be8896f2e88  v8-compiler.patch
858c7fa2714d290180e4e6b0000ee371f0540c7353762e6b5953f5e673a1800f6feab65e1dc525dab04caf64c4d689ac35700631337fabb4152cb5c375300cdf  v8-musl-monotonic-pthread-cont_timedwait.patch
a911c92e470823f3b6b578d1dc5784222769228e22cca3dc5bf9895e39835d578b28f48e763b5f92964e76c19f0b10a7a67c0575494d8f74dc1094f508a8efb1  v8-no-execinfo.patch
1be3c56e3aba4354abaff0a612380ab749dac98599a3dd50640b5d55306a27de64cd827bae7b3bd5fa059049a895bb6e44422aa7007f640482de894e13609d86  v8-use-system-zlib.patch
8016f73e53188f53ef98a72dd97b43cd8bae113d1a5a3e69d4c43fb93a6dca6916e2194d9679655f68ef323b449db701b9d032f8814d4d871ce1b58bf0f66bd3  v8-use-system-icu.patch
2be4dd5cad17332c0163ae008ad645ff0c45bdb6626ed005ced959989dbffe3cda5bdf8e05b382464a93ba80944e811f4f982cf29c08ee8ae2da190154182788  v8-fix-bindgen-macro.patch
c98575145fbbf7b2b7f82700e14ed28b6de69ae5f34223ea2dce99bc61c19cec800c8fba1667f4a982dc2ea4aa6ae84a6adc453c93232db4e50dded97b84202e  disable-core-defaults.patch
c34d8ad2e874343864922fbf2290bff3307e5ab2bbeb8af20e414c94617b68aeb4244a7d935b1a70e5b1f6c9fb175ee451556518810bb538f62b0e8f80cfbf05  use-system-libs.patch
f63dfe61ff1854f7242390cdeb09aa69c4b2f4ca131b75cccc726db37e3f95bb1eaad3d7431d9d19f14213ba112680534e0c32c82bee861d12c43e4e91763521  ignore-tests-broken-on-ci.patch
8674c6c53ef206253f88d6e9c68ef12ccca0759c5b364ffb3cc625e80b03b57cceff3a295e2b9eaba975fe9aca5b69bc17dc42b311a5a9ded461528bee19ad0f  tests-musl-compat.patch
46f8c23998abb0a38e6982646bf548bce6d4c86f7e5d7ecfec0d4552a50c0e20b017e195bcc1115efadb0bc874dd394a0553537ebab62c686d4e00bfd02ce240  tests-disable-upgrade.patch
32b0218879ac55dff3997e7a4e08257af51472afb4f8726507a6bedcd98845988739e095089db83119a6e398dd2b5889255139d257ad6063237898816a5253a6  tests-fix-sh-path.patch
1c73e5b4b4bbba8f0cdd8c8be5c285f5a2c97311f25847e78c0140ade0da5a3ccdc914772bf667421666d3809453a048d45ffa9881a9785b416d01a5c57afbc0  tests-ignore-flaky.patch
59ba2177221f8ac531ed488b117dc629f66fa9c954acf378f488aa113733f671c5e3835142f92157fe521972b6d0c907712fae1efa2bddba2f271074ddb9480a  unbundle-ca-certs.patch
7d176b3eb7981f25b7827343f802cb902e1aede59f98f28f330e60f9eb823e63a13b3713495ad3d604b817cd4f0952ed880cb5185f17f6ae64b44231b0c273af  cargo.lock.patch
"
