# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4

PortSystem          1.0
PortGroup           github 1.0

# Compile oven-sh/bun instead of the npm registry stub (a 6 KB wrapper that
# destroots a prebuilt Mach-O via optionalDependencies).
#
# Upstream's build is ninja driven by an already-installed bun (codegen
# and JS builtins). That cycle is broken the same way Homebrew-core does:
# a checksummed previous-release zip is the bootstrap compiler.
# JavaScriptCore is the checksummed prebuilt from oven-sh/WebKit (building
# JSC from source is the build:release:local path and a 7–18 GB clone).
#
# Pins below match bun-v${version}:
#   bootstrap bun  — .buildkite/Dockerfile OLD_BUN_VERSION
#   WebKit         — WEBKIT_VERSION in scripts/build/deps/webkit.ts
#   LLVM           — LLVM_VERSION_RANGE in scripts/build/tools.ts
#   GIT_SHA        — tag revision (archive tarball has no .git)

github.setup        oven-sh bun 1.4.0 bun-v
github.tarball_from archive
revision            0

set git_sha         34cbb9a40b4bd1bd767d134a7065e66c2432a676
set bootstrap_version \
                    1.3.13
set webkit_version  0f966e81b78c84bb23213e391bc679c4ef83e56b
set webkit_version16 \
                    [string range ${webkit_version} 0 15]
# Upstream scripts/build/tools.ts: LLVM_VERSION_RANGE >=21.1.0 <21.1.99.
# clang-22 is rejected. Older macOS may need a different pin later.
set llvm_version    21

maintainers         {@oakimov} openmaintainer
categories          devel
license             MIT LGPL-2
supported_archs     arm64 x86_64

description         JavaScript runtime built from scratch to serve the modern JavaScript ecosystem
long_description    Bun is an all-in-one JavaScript runtime and toolkit designed for \
                    speed, complete with a bundler, test runner, and Node.js-compatible \
                    package manager. This port compiles bun from source using LLVM 21, \
                    a bootstrap bun, and a prebuilt JavaScriptCore.

homepage            https://bun.sh

checksums           ${distname}${extract.suffix} \
                    rmd160  d6ba66f4b78b0ecf81ba8af1dcb6c51f5b258e26 \
                    sha256  c9000959b40823dad7eda10b769a9f4e3a8f29b49d75d8b1954ed8f83ba8251b \
                    size    64053999

if {${configure.build_arch} eq "arm64"} {
    set bootstrap_distfile  bun-darwin-aarch64.zip
    set bootstrap_dir       bun-darwin-aarch64
    set webkit_distfile     bun-webkit-macos-arm64.tar.gz
    set webkit_cache_key    webkit-${webkit_version16}-arm64
    checksums-append    ${bootstrap_distfile} \
                        rmd160  55b7a0c8b61752a958fcc589d3294c4a51b44bba \
                        sha256  5467e3f65dba526b9fea98f0cce04efafc0c63e169733ec27b876a3ad32da190 \
                        size    23094987 \
                        ${webkit_distfile} \
                        rmd160  fc03b17a27ab138aa6bc188a3c148ec0fbd3c47b \
                        sha256  11530a541112b20f0fab20250e4bdadf9924f98a6483244ff69b4bcc3cceaaba \
                        size    200603143
} elseif {${configure.build_arch} eq "x86_64"} {
    # baseline: no AVX, matching Homebrew-core for generic Intel.
    set bootstrap_distfile  bun-darwin-x64-baseline.zip
    set bootstrap_dir       bun-darwin-x64-baseline
    set webkit_distfile     bun-webkit-macos-amd64.tar.gz
    set webkit_cache_key    webkit-${webkit_version16}
    checksums-append    ${bootstrap_distfile} \
                        rmd160  fac1773c3ba8e34bcba84524b8ff4b16746d2d67 \
                        sha256  a98ba6a480f22fda9b343626b906a4e26aa53618bf85d2bc5928ecf2ba45f0ed \
                        size    25534684 \
                        ${webkit_distfile} \
                        rmd160  2aa656fa1bba68916699836177cefa27b084c31f \
                        sha256  56fb0246949453166288d21bc2bd1f0d1b303b07493754ec29345bcd84b78613 \
                        size    210188366
} else {
    known_fail          yes
    set bootstrap_distfile  {}
    set bootstrap_dir       {}
    set webkit_distfile     {}
    set webkit_cache_key    {}
    pre-fetch {
        ui_error "${name} is only supported on arm64 and x86_64"
        return -code error "unsupported architecture"
    }
}

if {${bootstrap_distfile} ne ""} {
    master_sites-append https://github.com/oven-sh/bun/releases/download/bun-v${bootstrap_version}/:bootstrap \
                        https://github.com/oven-sh/WebKit/releases/download/autobuild-${webkit_version}/:webkit
    distfiles-append    ${bootstrap_distfile}:bootstrap \
                        ${webkit_distfile}:webkit
}

extract.only        ${distname}${extract.suffix}

depends_build-append \
                    path:bin/cargo:cargo \
                    port:clang-${llvm_version} \
                    path:bin/cmake:cmake \
                    port:llvm-${llvm_version} \
                    port:ninja \
                    path:bin/pkg-config:pkgconfig \
                    port:rust

# libjpeg-turbo's x86_64 SIMD is nasm-assembled.
if {${configure.build_arch} eq "x86_64"} {
    depends_build-append port:nasm
}

# Upstream 1.4.0 rebuilds std from source on release (-Zbuild-std), which
# needs a nightly rustc + rust-src. We keep MacPorts' stable rust: the patch
# below drops -Zbuild-std and RUSTC_BOOTSTRAP=1 (set in the build env)
# unlocks the remaining nightly-only flags.
patchfiles          patch-rust-no-build-std.diff

# Vendor C libraries (boringssl, zstd, …), cargo crates and node_modules
# (esbuild) are still fetched during the bun install / ninja / cargo steps.
# The top-level tarballs above are the ones MacPorts checksums.
#
# use_configure no: compiler.whitelist does not apply. CC/CXX below are
# the clang-mp wrappers so the SDK is visible (raw clang-${llvm_version}
# from libexec does not).

use_configure       no

set llvm_bindir     ${prefix}/libexec/llvm-${llvm_version}/bin
set bun_cache_dir   ${workpath}/bun-cache

post-extract {
    system -W ${workpath} "/usr/bin/unzip -q [shellescape ${distpath}/${bootstrap_distfile}]"

    set webkit_dest ${bun_cache_dir}/${webkit_cache_key}
    xinstall -d ${bun_cache_dir}
    system -W ${workpath} "/usr/bin/tar -xzf [shellescape ${distpath}/${webkit_distfile}]"
    file rename ${workpath}/bun-webkit ${webkit_dest}
    set fd [open ${webkit_dest}/.identity w]
    puts ${fd} ${webkit_version}
    close ${fd}
    # Prebuilt WebKit ships ICU headers that conflict with macOS ICU.
    if {[file isdirectory ${webkit_dest}/include/unicode]} {
        file delete -force ${webkit_dest}/include/unicode
    }
}

build {
    set extra {}
    if {${configure.build_arch} eq "x86_64"} {
        lappend extra --baseline=on
    }
    system -W ${worksrcpath} \
        "env PATH=[shellescape ${workpath}/${bootstrap_dir}:${llvm_bindir}:${prefix}/bin:/usr/bin:/bin] \
        GIT_SHA=[shellescape ${git_sha}] \
        RUSTC_BOOTSTRAP=1 \
        CARGO_HOME=[shellescape ${workpath}/.cargo] \
        CI= \
        SDKROOT=[shellescape ${configure.sdkroot}] \
        MACOSX_DEPLOYMENT_TARGET=[shellescape ${macosx_deployment_target}] \
        CC=[shellescape ${prefix}/bin/clang-mp-${llvm_version}] \
        CXX=[shellescape ${prefix}/bin/clang++-mp-${llvm_version}] \
        AR=[shellescape ${llvm_bindir}/llvm-ar] \
        RANLIB=[shellescape ${llvm_bindir}/llvm-ranlib] \
        [shellescape ${workpath}/${bootstrap_dir}/bun] run build:release --canary=off \
        --cache-dir=[shellescape ${bun_cache_dir}] ${extra}"
}

destroot {
    xinstall -m 0755 ${worksrcpath}/build/release/bun \
        ${destroot}${prefix}/bin/bun
    ln -s bun ${destroot}${prefix}/bin/bunx

    set completions ${worksrcpath}/completions
    if {[file exists ${completions}/bun.bash]} {
        xinstall -d ${destroot}${prefix}/share/bash-completion/completions
        xinstall -m 0644 ${completions}/bun.bash \
            ${destroot}${prefix}/share/bash-completion/completions/bun
    }
    if {[file exists ${completions}/bun.zsh]} {
        xinstall -d ${destroot}${prefix}/share/zsh/site-functions
        xinstall -m 0644 ${completions}/bun.zsh \
            ${destroot}${prefix}/share/zsh/site-functions/_bun
    }
    if {[file exists ${completions}/bun.fish]} {
        xinstall -d ${destroot}${prefix}/share/fish/vendor_completions.d
        xinstall -m 0644 ${completions}/bun.fish \
            ${destroot}${prefix}/share/fish/vendor_completions.d/bun.fish
    }
}

test.run            yes
test.cmd            ${worksrcpath}/build/release/bun
test.target         {}
test.args           --version
