# Contributor: Jakub Jirutka <jakub@jirutka.cz>
# Maintainer: Jakub Jirutka <jakub@jirutka.cz>
pkgname=deno
pkgver=2.3.1
pkgrel=2
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=20
makedepends="
	cargo
	cargo-auditable
	clang-dev
	cmake
	compiler-rt
	curl
	glib-dev
	gn
	icu-dev
	jq
	lcms2-dev
	libffi-dev
	lld
	llvm-dev
	protoc
	python3
	samurai
	simdutf-dev
	sqlite-dev
	zlib-dev
	zlib-ng-dev
	zstd-dev
	"
checkdepends="
	bash
	coreutils-env
	curl
	nodejs
	npm
	"
subpackages="
	$pkgname-bash-completion
	$pkgname-fish-completion
	$pkgname-zsh-completion
	"
# This must match "v8" version in Cargo.lock.
_rusty_v8_ver=135.1.0
# This must match "stacker" version in Cargo.lock.
_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-no-execinfo.patch
	v8-use-system-icu.patch
	v8-unbundle-simdutf.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
	tests-ignore-broken.patch
	unbundle-ca-certs.patch
	cargo.lock.patch
	"
builddir="$srcdir/deno"
options="!check"  # FIXME: all tests pass on CI, but some fails on builders

# 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
	use_system_libffi=true
	"

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 simdutf"
	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"

	# 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"

	# NOTE: denort is broken (Could not find standalone binary section).
	cargo auditable build $_cargo_opts --workspace --exclude denort --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
}

package() {
	install -D -m755 target/release/deno -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
}

# 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="
2ce1acb408b60878bdf471553fc9d7f7debcd1a8ffc2ec4072730cf46a61b306f40f580f1cb2a92afa52ed54657af18bffc9dbba1c84026c3d11d47e1ee4a010  deno-2.3.1.tar.gz
0b141ba4e41f84583bd29944dd5c0f076cbd96a1c0f6c1ba1299115743d3cb88997f2a71a7fa24ecea58ed7d43d688f75b3820e068fee9a0fec09bc3f05cdf07  deno-rusty_v8-135.1.0.tar.gz
88412e029262a0dffe295a648ba87ec50f782afceb19fbe1eda4239c54fbd56432106fcea5d58c93bfbb5b91317dc6642fc7a8e72136df0ef600c77d99e0970f  deno-stacker-0.1.15.tar.gz
ecea1432982e55c462f54aae135e1b7d0c964d9faa2f245cf114910e81ba6b3a06379c11ecd56f82cf3528f478cd394ad759cb246b3cdf70f6a40be744e17ecd  deno-generate_shim_headers.py
08d09c979191d422d71a6db971bdf4472b322ef829b238519bc35db22f9b4639cca40342c7786777684a4ffa4af2c64febf9d9224b2d7d2d33f63671acfa6d5b  stacker-detect-stack-overflow.patch
e56b1bfefcd47c21d1ed4aad531990ffdfbb79b560740ca2dbddeb0103028ae2b47709473642078acd67e0947fe91e423909452a2936ae057d8607b9249ab943  stacker-disable-guess_os_stack_limit.patch
67ecb86cf9a3c72753b0cae1b56996696d372b4e3b9bbb67961e6db5bfa77912a3e07b69b4f92656a73c0993eedd0debae409ffcf82b2dbc4d825bdab9a458d2  v8-build.patch
780822e79b8ff35d6560ac773574a4ab0e0a72153a6f4feeb984b2d240170aa847f73630981d1ee8590fe5d9e1f6b2c0f5683d96eb75b1b29feb9a5a36a7e244  v8-compiler.patch
c7a406d80a8f63ce2a65de043380f00d7370ceec1bae45d819f741eeb550b8e340224334916f10dd85cc46f6204c7bab0f7d5e0045234e7d790ee63472328454  v8-no-execinfo.patch
645596649b88efd34021d696c19e692b57ad8951f117f58ce98dace314932471ac8456a538cf964df5079c93576e9dc3e7cbd02ee8775e8e394a6bfde13c7311  v8-use-system-icu.patch
fa8973d76c0c334eaf3a96d48421754593898cc36909ce7342482e1b62169d5308b83774ed0ff77bb5677710739da559d3e1633540935f571cddee872c5cf4d7  v8-unbundle-simdutf.patch
19df82f973dbe2b56eeb29709c6391c987d14bfc2e742ec67fdc09514517dfa134a703d16392f960f71e2567f37587cbd44aeeb52417228ae43fdf34551c241f  disable-core-defaults.patch
a4c7d63b79224e0fcad5a956d31a3edc5ca38e08086b8660e80f63e6159bd63c90134c4a950f5053f83ebf7078c8de37145ddd2bbac3bcb98208b939c0d5c0a6  use-system-libs.patch
9e255dc6696917cf5bceaf081aff43e0ce0a56b64910a60bec60f1bf82a7abe72fc88c7ff4629bfa4a2dd1ef6e5428cb1da9d92a2acded7b1a05a06a4793fe6c  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
160221f2984af42401ea8b3da6dae019d7e894577e4f8b24eb51e172b64d5b34997e4bea1890d9689ad6e81524f7b9a9af7eb2f2ebdb7c20f68f5cd0b41b00bc  tests-ignore-broken.patch
1d724c4a960a88744a0b4290cb9bb56f6d8bd39a24dfd156b90d9e84c212897141a7d077975f448ce5239109575bd01f1b50c6a1cd764cf82cdfbad9b2a14051  unbundle-ca-certs.patch
89a052c672fc584ac00e1038ec705b8ea7fe0859c9df0ee75ecac788b2ed7393f84416e924eb1ae021e069e59d29dceb8f9344d2d480398456ea7d0ed162cb77  cargo.lock.patch
"
