# Contributor: Jakub Jirutka <jakub@jirutka.cz>
# Maintainer: Jakub Jirutka <jakub@jirutka.cz>
pkgname=deno
pkgver=1.43.5
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"
makedepends="
	cargo
	cargo-auditable
	clang-dev
	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
	nodejs
	npm
	"
subpackages="
	$pkgname-dbg
	denort
	$pkgname-bash-completion
	$pkgname-fish-completion
	$pkgname-zsh-completion
	"
_rusty_v8_ver=0.91.1
_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-musl-monotonic-pthread-cont_timedwait.patch
	v8-no-execinfo.patch
	v8-revert-llvm16-linker-flag.patch
	v8-use-alpine-target.patch
	v8-use-system-zlib.patch
	v8-use-system-icu.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-npx-output.patch
	unbundle-ca-certs.patch
	cargo.lock.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\"
	fatal_linker_warnings=false
	is_debug=false
	symbol_level=0
	system_icu=true
	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
}

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"

	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="
6b942d4a7abade03d1246efcfae61b2264d64a1098f9e2f8f526919cd33bfb233fe40f5b4e1fc29bf8cb34bccfec99db0e2f0c7891e6f6f1e8b1b5f997c4d565  deno-1.43.5.tar.gz
6b31944e9c020e3c53931d3e710a7de842f5c0ce62925044396468000388e3374137790d0524e4e70a82c50848c9ceae8d1d7b6ae3827b5e8556ca29b65c2ea1  deno-rusty_v8-0.91.1.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
26de81d145e898983befdd70e00ba6b15d898c280580a9403a8e4921825e754788aa97ff9b80992799791d3ba3d2ed3862a1635f2bc16f26ed70802b5fe1f304  v8-build.patch
858c7fa2714d290180e4e6b0000ee371f0540c7353762e6b5953f5e673a1800f6feab65e1dc525dab04caf64c4d689ac35700631337fabb4152cb5c375300cdf  v8-musl-monotonic-pthread-cont_timedwait.patch
a911c92e470823f3b6b578d1dc5784222769228e22cca3dc5bf9895e39835d578b28f48e763b5f92964e76c19f0b10a7a67c0575494d8f74dc1094f508a8efb1  v8-no-execinfo.patch
35eb224ecab762a972fff4bbc721972d686aec28d901481922b07cabf0c41ca441dc6b47257504932ee1d50011db317b51052b06455e89f351263689f29b5d3c  v8-revert-llvm16-linker-flag.patch
cb00ccb2055a53100c8d3e2d038443a2028461c62c17c7d0a50a5a33f2af480a9bc6cc1c9b465f9f5be063716e2315127006384e62f0114e9994069cb84f7d93  v8-use-alpine-target.patch
1be3c56e3aba4354abaff0a612380ab749dac98599a3dd50640b5d55306a27de64cd827bae7b3bd5fa059049a895bb6e44422aa7007f640482de894e13609d86  v8-use-system-zlib.patch
cd05aae0e1aa0771db82d9b96f5fe02f8047f20df1c1f42e7b3e8f93d0c84faa5c37f1c93e04a3d74a92b8242c9b9f4d0095f7e4e510130d3e42a31d3695a056  v8-use-system-icu.patch
f850d6418cbf10c9c0ea90a276be562f303133f3fd2f7e83de698866a2bb1fe74022f9b19e5fc8336ede8641779c2c021ad27c6079f998ae33b93d5d04e6647b  disable-core-defaults.patch
d2f6bd48b3e9fc561ed146d8c997d7f467312655d4126efed361c122f22ebf3971b6d6326d1cfccaffb48435a5f2c32c7b7ff13812d6d5f87bb52522ae6a88c0  use-system-libs.patch
f63dfe61ff1854f7242390cdeb09aa69c4b2f4ca131b75cccc726db37e3f95bb1eaad3d7431d9d19f14213ba112680534e0c32c82bee861d12c43e4e91763521  ignore-tests-broken-on-ci.patch
8674c6c53ef206253f88d6e9c68ef12ccca0759c5b364ffb3cc625e80b03b57cceff3a295e2b9eaba975fe9aca5b69bc17dc42b311a5a9ded461528bee19ad0f  tests-musl-compat.patch
14eddb7245ae4880bc3bd7f933a4ef69137707bcb3ccbf635fe60e7f8362573c03d2408c9b20c37e781642c9ac9aa9958b5be0a845a4c0f96a54329f80380482  tests-disable-upgrade.patch
b057c2cb374a4d931d0a25d9fd054ab242b0e57e710e66016a7d16de6376fa7be3472fa827a5d2e8088237b6c635099eb7c22f173929d62667a0ac3b2c46013e  tests-fix-npx-output.patch
3a32bd68860f8a393b8a337e411fdc14f1f0f35d8c8a851d4f0d3caf7a8c04cd1ea44ccde281f8e604884c088bb602862275e6dc8a45ed1d0da6303fc7962b9a  unbundle-ca-certs.patch
a0a538b486601879375430acb5ce2505347dd355384769e09e2ae2b6412891f9a0ba6699f0767c43ef5e21ae720d4b8d78e769cb50a54a365c170cec0d00af4c  cargo.lock.patch
"
