mirror of
https://github.com/oven-sh/bun
synced 2026-02-06 00:48:55 +00:00
Compare commits
244 Commits
dylan/ref-
...
buildkite-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
783b307cc8 | ||
|
|
53a184bb66 | ||
|
|
da15e38866 | ||
|
|
6e81b5c868 | ||
|
|
9e634f3d56 | ||
|
|
f8716b4161 | ||
|
|
7911830b3a | ||
|
|
8f16e08deb | ||
|
|
f4dd562adf | ||
|
|
850b70cc89 | ||
|
|
387064b514 | ||
|
|
32d71720e4 | ||
|
|
a38032c72c | ||
|
|
8fab507762 | ||
|
|
117f6f5ad2 | ||
|
|
9e1ecd4ba4 | ||
|
|
77198cd1e4 | ||
|
|
eb8ee73ba1 | ||
|
|
2fa6f85c31 | ||
|
|
06e8619a8f | ||
|
|
777c706e07 | ||
|
|
aaec8ecc68 | ||
|
|
e8523f7246 | ||
|
|
2fc5ab5235 | ||
|
|
dfc3805903 | ||
|
|
4efd9e6e4c | ||
|
|
e735d4a860 | ||
|
|
6198559b21 | ||
|
|
d8ca88a351 | ||
|
|
103a9bd561 | ||
|
|
826c4cbd28 | ||
|
|
8e33a1af7d | ||
|
|
d83f383690 | ||
|
|
c8c79c88f0 | ||
|
|
665e6052aa | ||
|
|
4cb16b3581 | ||
|
|
16ee28ff57 | ||
|
|
07e86cb949 | ||
|
|
c62ba235ab | ||
|
|
7a055c89be | ||
|
|
566957250c | ||
|
|
cd4c5694d4 | ||
|
|
78655a06fc | ||
|
|
85eadb4c38 | ||
|
|
473f67aff7 | ||
|
|
6dd48a134f | ||
|
|
ba1d8c7529 | ||
|
|
f7830585c8 | ||
|
|
458a753a9b | ||
|
|
21d27e9c54 | ||
|
|
4f9bdb632c | ||
|
|
fb59ca732f | ||
|
|
800dd81a67 | ||
|
|
155b6519f4 | ||
|
|
e1ae632b60 | ||
|
|
8217c26164 | ||
|
|
fc14d91500 | ||
|
|
27d9b5a763 | ||
|
|
4b8036f37d | ||
|
|
189d251878 | ||
|
|
ff811eca01 | ||
|
|
2355d4e667 | ||
|
|
68dac5ff9a | ||
|
|
6c3bc83107 | ||
|
|
0b8dc54af5 | ||
|
|
8115477883 | ||
|
|
3c4c253001 | ||
|
|
70e9c3287f | ||
|
|
8ca8e98629 | ||
|
|
d91b030f06 | ||
|
|
9a37d11305 | ||
|
|
01ad121868 | ||
|
|
2d2c3a137f | ||
|
|
950aa0c4a7 | ||
|
|
69c3dfbca4 | ||
|
|
17f2183024 | ||
|
|
d77483c741 | ||
|
|
8e5f2e52b8 | ||
|
|
93f5d690e7 | ||
|
|
f752f3aa71 | ||
|
|
97a6cf9cfe | ||
|
|
2825ad9862 | ||
|
|
028c5ebfd1 | ||
|
|
45ced96cf2 | ||
|
|
95f9476ae2 | ||
|
|
17e2599dc5 | ||
|
|
24b81efdfd | ||
|
|
23de00c9f3 | ||
|
|
231ecd543d | ||
|
|
f8eb92edfd | ||
|
|
d3f6006668 | ||
|
|
bb74106d0c | ||
|
|
ebb3b47e73 | ||
|
|
737ef25ba2 | ||
|
|
dac79ff62c | ||
|
|
5cb105ecc4 | ||
|
|
6cc35cf091 | ||
|
|
3050be235e | ||
|
|
81b70cd543 | ||
|
|
8b7f14677d | ||
|
|
fe8c918bdf | ||
|
|
f2b86b1bd1 | ||
|
|
3793149279 | ||
|
|
ef99e7e2fb | ||
|
|
22cf802ece | ||
|
|
5b05c42462 | ||
|
|
7f5cd2676e | ||
|
|
9dbe19ca38 | ||
|
|
da09200e53 | ||
|
|
87a1da93d5 | ||
|
|
56f912e999 | ||
|
|
29b864dec2 | ||
|
|
b482def1ab | ||
|
|
4b5422e349 | ||
|
|
f97991cdea | ||
|
|
a6e4700932 | ||
|
|
025d501b53 | ||
|
|
aa4a344a7b | ||
|
|
dcc18fb355 | ||
|
|
3fa68ecf30 | ||
|
|
945ab91288 | ||
|
|
4e659ef489 | ||
|
|
494bb322a8 | ||
|
|
297730a285 | ||
|
|
42f6e931e5 | ||
|
|
1fbd66a57f | ||
|
|
ea156d3b11 | ||
|
|
4384b1fa9b | ||
|
|
67bb248e1b | ||
|
|
fa57f10250 | ||
|
|
3133fbe3fc | ||
|
|
3a08c2198e | ||
|
|
3250fa5f92 | ||
|
|
63928a0cdb | ||
|
|
d5e5efddac | ||
|
|
2991faba81 | ||
|
|
ffaae41a13 | ||
|
|
4a0c44df83 | ||
|
|
a1402f3511 | ||
|
|
1baca0b9e4 | ||
|
|
92775854ba | ||
|
|
770a62b320 | ||
|
|
5ec7ac73ef | ||
|
|
491e6f0369 | ||
|
|
d39f59ef51 | ||
|
|
ac8bc955eb | ||
|
|
f7bac5e2d3 | ||
|
|
9f3a4ddb96 | ||
|
|
579cf03158 | ||
|
|
9db7294e0a | ||
|
|
02f887cf97 | ||
|
|
f43fcb8bd1 | ||
|
|
e3dfdc55b3 | ||
|
|
e38ef49e33 | ||
|
|
7b693576bb | ||
|
|
37277334d5 | ||
|
|
16e802ad08 | ||
|
|
f7532a6277 | ||
|
|
9ab089bf87 | ||
|
|
67634b95be | ||
|
|
7f6c1f9ab6 | ||
|
|
6334a0e61b | ||
|
|
3881c1ae3b | ||
|
|
9ae59fb624 | ||
|
|
04eb1b61e7 | ||
|
|
cb3c86e583 | ||
|
|
e511eef751 | ||
|
|
4c2fae3dab | ||
|
|
1a1c9d3782 | ||
|
|
828438d01a | ||
|
|
bd8551e76a | ||
|
|
4c7233d0c2 | ||
|
|
46099a1639 | ||
|
|
5efa10cbfa | ||
|
|
5a74da4a40 | ||
|
|
978f314a1a | ||
|
|
1110a76bfe | ||
|
|
082b11524a | ||
|
|
3a61d995cb | ||
|
|
79e6abfd6c | ||
|
|
af2d51c9fc | ||
|
|
e92df427ca | ||
|
|
28d5560ea0 | ||
|
|
2455bf1fa4 | ||
|
|
8ce7eae1a3 | ||
|
|
1fe8af2e20 | ||
|
|
edcea7e31b | ||
|
|
511b97d599 | ||
|
|
0123a2b0d7 | ||
|
|
4b14b2fc2d | ||
|
|
1a0921b2e9 | ||
|
|
db06c601af | ||
|
|
feef707998 | ||
|
|
ab213165f0 | ||
|
|
08b1aae387 | ||
|
|
07ff957644 | ||
|
|
429c396976 | ||
|
|
46e48bffd5 | ||
|
|
213f0f57b5 | ||
|
|
532d7cd8ed | ||
|
|
8cce4eed79 | ||
|
|
d22048d75b | ||
|
|
ab8f665c03 | ||
|
|
84f1e8889f | ||
|
|
6a5b7d909c | ||
|
|
6692405d9c | ||
|
|
48dc7d720a | ||
|
|
13841ffc93 | ||
|
|
bc589af1ad | ||
|
|
886852fb26 | ||
|
|
8580dbc00b | ||
|
|
7f761b0f76 | ||
|
|
6090562cf5 | ||
|
|
57fe9b877c | ||
|
|
4df9aff4c2 | ||
|
|
30912bc982 | ||
|
|
8df928642e | ||
|
|
09f2e69b2e | ||
|
|
c04d9d270d | ||
|
|
03b40f89b6 | ||
|
|
05fcb18759 | ||
|
|
ffa8f5328c | ||
|
|
bebdf06247 | ||
|
|
58ebe0e469 | ||
|
|
d16ad17fd9 | ||
|
|
327c047a68 | ||
|
|
9294d9b287 | ||
|
|
c2402d10e9 | ||
|
|
ef583214e6 | ||
|
|
05515f5e21 | ||
|
|
102f04bc30 | ||
|
|
e0214e1a67 | ||
|
|
b6b601f175 | ||
|
|
c185021018 | ||
|
|
1ce8d42914 | ||
|
|
dc5844db14 | ||
|
|
4171a3258e | ||
|
|
942f64ddd1 | ||
|
|
0329469e2a | ||
|
|
cc82876d05 | ||
|
|
5db74e74ba | ||
|
|
16733733cc | ||
|
|
2765542e1e | ||
|
|
e0a2b0cf0a |
11
.buildkite/bootstrap.yml
Normal file
11
.buildkite/bootstrap.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
# Uploads the latest CI workflow to Buildkite.
|
||||
# https://buildkite.com/docs/pipelines/defining-steps
|
||||
#
|
||||
# Changes to this file must be manually edited here:
|
||||
# https://buildkite.com/bun/bun/settings/steps
|
||||
steps:
|
||||
- label: ":pipeline:"
|
||||
command:
|
||||
- "buildkite-agent pipeline upload .buildkite/ci.yml"
|
||||
agents:
|
||||
queue: "build-linux"
|
||||
63
.buildkite/ci.md
Normal file
63
.buildkite/ci.md
Normal file
@@ -0,0 +1,63 @@
|
||||
## CI
|
||||
|
||||
How does CI work?
|
||||
|
||||
### Building
|
||||
|
||||
Bun is built on macOS, Linux, and Windows. The process is split into the following steps, the first 3 of which are able to run in parallel:
|
||||
|
||||
#### 1. `build-deps`
|
||||
|
||||
Builds the static libaries in `src/deps` and outputs a directory: `build/bun-deps`.
|
||||
|
||||
- on Windows, this runs the script: [`scripts/all-dependencies.ps1`](scripts/all-dependencies.ps1)
|
||||
- on macOS and Linux, this runs the script: [`scripts/all-dependencies.sh`](scripts/all-dependencies.sh)
|
||||
|
||||
#### 2. `build-zig`
|
||||
|
||||
Builds the Zig object file: `build/bun-zig.o`. Since `zig build` supports cross-compiling, this step is run on macOS aarch64 since we have observed it to be the fastest.
|
||||
|
||||
- on macOS and Linux, this runs the script: [`scripts/build-bun-zig.sh`](scripts/build-bun-zig.sh)
|
||||
|
||||
#### 3. `build-cpp`
|
||||
|
||||
Builds the C++ object file: `build/bun-cpp-objects.a`.
|
||||
|
||||
- on Windows, this runs the script: [`scripts/build-bun-cpp.ps1`](scripts/build-bun-cpp.ps1)
|
||||
- on macOS and Linux, this runs the script: [`scripts/build-bun-cpp.sh`](scripts/build-bun-cpp.sh)
|
||||
|
||||
#### 4. `link` / `build-bun`
|
||||
|
||||
After the `build-deps`, `build-zig`, and `build-cpp` steps have completed, this step links the Zig object file and C++ object file into a single binary: `bun-<os>-<arch>.zip`.
|
||||
|
||||
- on Windows, this runs the script: [`scripts/buildkite-link-bun.ps1`](scripts/buildkite-link-bun.ps1)
|
||||
- on macOS and Linux, this runs the script: [`scripts/buildkite-link-bun.sh`](scripts/buildkite-link-bun.sh)
|
||||
|
||||
To speed up the build, thare are two options:
|
||||
|
||||
- `--fast`: This disables the LTO (link-time optimization) step.
|
||||
- without `--fast`: This runs the LTO step, which is the default. The binaries that are release to Github are always built with LTO.
|
||||
|
||||
### Testing
|
||||
|
||||
### FAQ
|
||||
|
||||
> How do I add a new CI agent?
|
||||
|
||||
> How do I add/modify system dependencies?
|
||||
|
||||
> How do I SSH into a CI agent?
|
||||
|
||||
### Known issues
|
||||
|
||||
These are things that we know about, but haven't fixed or optimized yet.
|
||||
|
||||
- There is no `scripts/build-bun-zig.ps1` for Windows.
|
||||
|
||||
- The `build-deps` step does not cache in CI, so it re-builds each time (though it does use ccache). It attempts to check the `BUN_DEPS_CACHE_DIR` environment variable, but for some reason it doesn't work.
|
||||
|
||||
- Windows and Linux machines sometimes take up to 1-2 minutes to start tests. This is because robobun is listening for when the job is scheduled to provision the VM. Instead, it can start provisioning during the link step, or keep a pool of idle VMs around (but it's unclear how more expensive this is).
|
||||
|
||||
- There are a limited number of macOS VMs. This is because they are expensive and manually provisioned, mostly through MacStadium. If wait times are too long we can just provision more, or buy some.
|
||||
|
||||
- To prevent idle machines, robobun periodically checks for idle machines and terminates them. Before doing this, it checks to see if the machine is connected as an agent to Buildkite. However, sometimes the machine picks up a job in-between this time, and the job is terminated.
|
||||
1700
.buildkite/ci.yml
Normal file
1700
.buildkite/ci.yml
Normal file
File diff suppressed because it is too large
Load Diff
97
.github/actions/setup-bun/action.yml
vendored
97
.github/actions/setup-bun/action.yml
vendored
@@ -6,45 +6,112 @@ inputs:
|
||||
type: string
|
||||
description: "The version of bun to install: 'latest', 'canary', 'bun-v1.0.0', etc."
|
||||
default: latest
|
||||
required: false
|
||||
workflow-run-id:
|
||||
type: string
|
||||
description: "The workflow run ID where to download bun."
|
||||
baseline:
|
||||
type: boolean
|
||||
description: "Whether to use the baseline version of bun."
|
||||
default: false
|
||||
required: false
|
||||
add-to-path:
|
||||
type: boolean
|
||||
description: "Whether to add bun to PATH."
|
||||
default: true
|
||||
download-url:
|
||||
type: string
|
||||
description: "The base URL to download bun from."
|
||||
default: "https://pub-5e11e972747a44bf9aaf9394f185a982.r2.dev/releases"
|
||||
required: false
|
||||
|
||||
outputs:
|
||||
os:
|
||||
description: "Operating system: 'darwin', 'linux', or 'windows'."
|
||||
value: ${{ steps.setup.outputs.os }}
|
||||
arch:
|
||||
description: "Architecture: 'aarch64' or 'x64'."
|
||||
value: ${{ steps.setup.outputs.arch }}
|
||||
target:
|
||||
description: "Target: 'bun-{os}-{arch}-[baseline]'."
|
||||
value: ${{ steps.setup.outputs.target }}
|
||||
release:
|
||||
description: "Release: 'latest', 'canary', or 'bun-v1.x.x'."
|
||||
value: ${{ steps.setup.outputs.release }}
|
||||
bun-path:
|
||||
description: "The path to Bun."
|
||||
value: ${{ steps.unpack.outputs.bun-path }}
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Setup Bun
|
||||
- id: setup
|
||||
name: Setup Bun
|
||||
shell: bash
|
||||
run: |
|
||||
set -x
|
||||
case "$(uname -s)" in
|
||||
Linux*) os=linux;;
|
||||
Darwin*) os=darwin;;
|
||||
*) os=windows;;
|
||||
esac
|
||||
echo "os=${os}" >> $GITHUB_OUTPUT
|
||||
case "$(uname -m)" in
|
||||
arm64 | aarch64) arch=aarch64;;
|
||||
*) arch=x64;;
|
||||
esac
|
||||
echo "arch=${arch}" >> $GITHUB_OUTPUT
|
||||
case "${{ inputs.baseline }}" in
|
||||
true | 1) target="bun-${os}-${arch}-baseline";;
|
||||
*) target="bun-${os}-${arch}";;
|
||||
true | 1) target="bun-${os}-${arch}-baseline" ;;
|
||||
*) target="bun-${os}-${arch}" ;;
|
||||
esac
|
||||
echo "target=${target}" >> $GITHUB_OUTPUT
|
||||
case "${{ inputs.bun-version }}" in
|
||||
latest) release="latest";;
|
||||
canary) release="canary";;
|
||||
*) release="bun-v${{ inputs.bun-version }}";;
|
||||
latest) release="latest" ;;
|
||||
canary) release="canary" ;;
|
||||
*) release="bun-v${{ inputs.bun-version }}" ;;
|
||||
esac
|
||||
curl -LO "${{ inputs.download-url }}/${release}/${target}.zip"
|
||||
unzip ${target}.zip
|
||||
mkdir -p ${{ runner.temp }}/.bun/bin
|
||||
mv ${target}/bun* ${{ runner.temp }}/.bun/bin/
|
||||
chmod +x ${{ runner.temp }}/.bun/bin/*
|
||||
echo "${{ runner.temp }}/.bun/bin" >> ${GITHUB_PATH}
|
||||
if [[ "${{ inputs.workflow-run-id }}" ]]; then
|
||||
release="workflow-${{ inputs.workflow-run-id }}"
|
||||
fi
|
||||
echo "release=${release}" >> $GITHUB_OUTPUT
|
||||
|
||||
- if: ${{ inputs.workflow-run-id }}
|
||||
name: Download Bun from Github Actions
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
github-token: ${{ github.token }}
|
||||
run-id: ${{ inputs.workflow-run-id }}
|
||||
name: ${{ steps.setup.outputs.target }}
|
||||
|
||||
- if: ${{ !inputs.workflow-run-id }}
|
||||
name: Download Bun from URL
|
||||
shell: bash
|
||||
run: |
|
||||
set -x
|
||||
curl -LO ${{ inputs.download-url }}/${{ steps.setup.outputs.release }}/${{ steps.setup.outputs.target }}.zip
|
||||
|
||||
- id: unpack
|
||||
name: Unpack Bun
|
||||
shell: bash
|
||||
run: |
|
||||
set -x
|
||||
target="${{ steps.setup.outputs.target }}"
|
||||
release="${{ steps.setup.outputs.release }}"
|
||||
mkdir -p ${target}/${release}
|
||||
unzip ${target}.zip -d ${target}
|
||||
mv ${target}/${target}/* ${target}/${release}/
|
||||
rm -rf ${target}/${target}
|
||||
rm -f ${target}.zip
|
||||
bin="$(pwd)/${target}/${release}"
|
||||
path="${bin}/bun"
|
||||
if [[ "${{ runner.os }}" == "Windows" ]]; then
|
||||
bin=$(cygpath -w ${bin})
|
||||
path=$(cygpath -w ${path})
|
||||
fi
|
||||
echo "bun-bin=${bin}" >> $GITHUB_OUTPUT
|
||||
echo "bun-path=${path}" >> ${GITHUB_OUTPUT}
|
||||
|
||||
- if: ${{ inputs.add-to-path == 'true' }}
|
||||
name: Add Bun to Path
|
||||
shell: bash
|
||||
run: |
|
||||
set -x
|
||||
echo "${{ steps.unpack.outputs.bun-bin }}" >> ${GITHUB_PATH}
|
||||
|
||||
131
.github/workflows/build-bun.yml
vendored
Normal file
131
.github/workflows/build-bun.yml
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
name: Build Bun
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
actions: write
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
no-cache:
|
||||
type: boolean
|
||||
canary:
|
||||
type: boolean
|
||||
assertions:
|
||||
type: boolean
|
||||
zig-optimize:
|
||||
type: string
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
no-cache:
|
||||
type: boolean
|
||||
canary:
|
||||
type: boolean
|
||||
assertions:
|
||||
type: boolean
|
||||
zig-optimize:
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
linux-x64:
|
||||
name: Build linux-x64
|
||||
uses: ./.github/workflows/build-linux.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
runs-on: ${{ github.repository_owner == 'oven-sh' && 'namespace-profile-bun-ci-linux-x64' || 'ubuntu-latest' }}
|
||||
tag: linux-x64
|
||||
arch: x64
|
||||
cpu: haswell
|
||||
no-cache: ${{ inputs.no-cache }}
|
||||
canary: ${{ inputs.canary }}
|
||||
assertions: ${{ inputs.assertions }}
|
||||
zig-optimize: ${{ inputs.zig-optimize }}
|
||||
|
||||
linux-x64-baseline:
|
||||
name: Build linux-x64-baseline
|
||||
uses: ./.github/workflows/build-linux.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
runs-on: ${{ github.repository_owner == 'oven-sh' && 'namespace-profile-bun-ci-linux-x64' || 'ubuntu-latest' }}
|
||||
tag: linux-x64-baseline
|
||||
arch: x64
|
||||
cpu: nehalem
|
||||
no-cache: ${{ inputs.no-cache }}
|
||||
canary: ${{ inputs.canary }}
|
||||
assertions: ${{ inputs.assertions }}
|
||||
zig-optimize: ${{ inputs.zig-optimize }}
|
||||
|
||||
linux-aarch64:
|
||||
if: ${{ github.repository_owner == 'oven-sh' }}
|
||||
name: Build linux-aarch64
|
||||
uses: ./.github/workflows/build-linux.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
runs-on: namespace-profile-bun-ci-linux-aarch64
|
||||
tag: linux-aarch64
|
||||
arch: aarch64
|
||||
cpu: native
|
||||
no-cache: ${{ inputs.no-cache }}
|
||||
canary: ${{ inputs.canary }}
|
||||
assertions: ${{ inputs.assertions }}
|
||||
zig-optimize: ${{ inputs.zig-optimize }}
|
||||
|
||||
darwin-x64:
|
||||
name: Build darwin-x64
|
||||
uses: ./.github/workflows/build-darwin.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
runs-on: ${{ github.repository_owner == 'oven-sh' && 'macos-12-large' || 'macos-12' }}
|
||||
tag: darwin-x64
|
||||
arch: x64
|
||||
cpu: haswell
|
||||
no-cache: ${{ inputs.no-cache }}
|
||||
canary: ${{ inputs.canary }}
|
||||
assertions: ${{ inputs.assertions }}
|
||||
zig-optimize: ${{ inputs.zig-optimize }}
|
||||
|
||||
darwin-aarch64:
|
||||
name: Build darwin-aarch64
|
||||
uses: ./.github/workflows/build-darwin.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
runs-on: ${{ github.repository_owner == 'oven-sh' && 'namespace-profile-bun-ci-darwin-aarch64' || 'macos-12' }}
|
||||
tag: darwin-aarch64
|
||||
arch: aarch64
|
||||
cpu: native
|
||||
no-cache: ${{ inputs.no-cache }}
|
||||
canary: ${{ inputs.canary }}
|
||||
assertions: ${{ inputs.assertions }}
|
||||
zig-optimize: ${{ inputs.zig-optimize }}
|
||||
|
||||
windows-x64:
|
||||
name: Build windows-x64
|
||||
uses: ./.github/workflows/build-windows.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
runs-on: windows
|
||||
tag: windows-x64
|
||||
arch: x64
|
||||
cpu: haswell
|
||||
no-cache: ${{ inputs.no-cache }}
|
||||
canary: ${{ inputs.canary }}
|
||||
assertions: ${{ inputs.assertions }}
|
||||
zig-optimize: ${{ inputs.zig-optimize }}
|
||||
|
||||
windows-x64-baseline:
|
||||
name: Build windows-x64-baseline
|
||||
uses: ./.github/workflows/build-windows.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
runs-on: windows
|
||||
tag: windows-x64-baseline
|
||||
arch: x64
|
||||
cpu: nehalem
|
||||
no-cache: ${{ inputs.no-cache }}
|
||||
canary: ${{ inputs.canary }}
|
||||
assertions: ${{ inputs.assertions }}
|
||||
zig-optimize: ${{ inputs.zig-optimize }}
|
||||
3
.github/workflows/build-darwin.yml
vendored
3
.github/workflows/build-darwin.yml
vendored
@@ -21,6 +21,8 @@ on:
|
||||
required: true
|
||||
assertions:
|
||||
type: boolean
|
||||
zig-optimize:
|
||||
type: string
|
||||
canary:
|
||||
type: boolean
|
||||
no-cache:
|
||||
@@ -189,6 +191,7 @@ jobs:
|
||||
arch: ${{ inputs.arch }}
|
||||
cpu: ${{ inputs.cpu }}
|
||||
assertions: ${{ inputs.assertions }}
|
||||
zig-optimize: ${{ inputs.zig-optimize }}
|
||||
canary: ${{ inputs.canary }}
|
||||
no-cache: ${{ inputs.no-cache }}
|
||||
link:
|
||||
|
||||
1
.github/workflows/build-linux.yml
vendored
1
.github/workflows/build-linux.yml
vendored
@@ -43,6 +43,7 @@ jobs:
|
||||
zig-optimize: ${{ inputs.zig-optimize }}
|
||||
canary: ${{ inputs.canary }}
|
||||
no-cache: ${{ inputs.no-cache }}
|
||||
|
||||
on-failure:
|
||||
if: ${{ github.repository_owner == 'oven-sh' && failure() }}
|
||||
name: On Failure
|
||||
|
||||
15
.github/workflows/build-windows.yml
vendored
15
.github/workflows/build-windows.yml
vendored
@@ -21,6 +21,8 @@ on:
|
||||
required: true
|
||||
assertions:
|
||||
type: boolean
|
||||
zig-optimize:
|
||||
type: string
|
||||
canary:
|
||||
type: boolean
|
||||
no-cache:
|
||||
@@ -48,6 +50,7 @@ jobs:
|
||||
run: |
|
||||
git config --global core.autocrlf false
|
||||
git config --global core.eol lf
|
||||
git config --system core.longpaths true
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -108,6 +111,7 @@ jobs:
|
||||
name: bun-${{ inputs.tag }}-deps
|
||||
path: bun-deps
|
||||
if-no-files-found: error
|
||||
|
||||
codegen:
|
||||
name: Codegen
|
||||
runs-on: ubuntu-latest
|
||||
@@ -116,6 +120,7 @@ jobs:
|
||||
run: |
|
||||
git config --global core.autocrlf false
|
||||
git config --global core.eol lf
|
||||
git config --system core.longpaths true
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup Bun
|
||||
@@ -136,6 +141,7 @@ jobs:
|
||||
name: bun-${{ inputs.tag }}-codegen
|
||||
path: build-codegen-win32-x64
|
||||
if-no-files-found: error
|
||||
|
||||
build-cpp:
|
||||
name: Build C++
|
||||
needs: codegen
|
||||
@@ -147,6 +153,7 @@ jobs:
|
||||
run: |
|
||||
git config --global core.autocrlf false
|
||||
git config --global core.eol lf
|
||||
git config --system core.longpaths true
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -200,19 +207,23 @@ jobs:
|
||||
name: bun-${{ inputs.tag }}-cpp
|
||||
path: build/bun-cpp-objects.a
|
||||
if-no-files-found: error
|
||||
|
||||
build-zig:
|
||||
name: Build Zig
|
||||
uses: ./.github/workflows/build-zig.yml
|
||||
with:
|
||||
os: windows
|
||||
zig-optimize: ReleaseSafe
|
||||
only-zig: true
|
||||
tag: ${{ inputs.tag }}
|
||||
arch: ${{ inputs.arch }}
|
||||
cpu: ${{ inputs.cpu }}
|
||||
assertions: ${{ inputs.assertions }}
|
||||
zig-optimize: ReleaseSafe
|
||||
# Windows is always ReleaseSafe for now
|
||||
# zig-optimize: ${{ inputs.zig-optimize }}
|
||||
canary: ${{ inputs.canary }}
|
||||
no-cache: ${{ inputs.no-cache }}
|
||||
|
||||
link:
|
||||
name: Link
|
||||
runs-on: ${{ inputs.runs-on }}
|
||||
@@ -228,6 +239,7 @@ jobs:
|
||||
run: |
|
||||
git config --global core.autocrlf false
|
||||
git config --global core.eol lf
|
||||
git config --system core.longpaths true
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -323,6 +335,7 @@ jobs:
|
||||
path: features.json
|
||||
if-no-files-found: error
|
||||
overwrite: true
|
||||
|
||||
on-failure:
|
||||
if: ${{ github.repository_owner == 'oven-sh' && failure() }}
|
||||
name: On Failure
|
||||
|
||||
237
.github/workflows/ci.yml
vendored
237
.github/workflows/ci.yml
vendored
@@ -2,244 +2,27 @@ name: CI
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
statuses: read
|
||||
actions: write
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event_name == 'workflow_dispatch' && inputs.run-id || github.ref }}
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
run-id:
|
||||
type: string
|
||||
description: The workflow ID to download artifacts (skips the build step)
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- .vscode/**/*
|
||||
- docs/**/*
|
||||
- examples/**/*
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths-ignore:
|
||||
- .vscode/**/*
|
||||
- docs/**/*
|
||||
- examples/**/*
|
||||
|
||||
jobs:
|
||||
format:
|
||||
if: ${{ !inputs.run-id }}
|
||||
name: Format
|
||||
uses: ./.github/workflows/run-format.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
zig-version: 0.13.0
|
||||
permissions:
|
||||
contents: write
|
||||
lint:
|
||||
if: ${{ !inputs.run-id }}
|
||||
name: Lint
|
||||
uses: ./.github/workflows/run-lint.yml
|
||||
secrets: inherit
|
||||
linux-x64:
|
||||
if: ${{ !inputs.run-id }}
|
||||
name: Build linux-x64
|
||||
uses: ./.github/workflows/build-linux.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
runs-on: ${{ github.repository_owner == 'oven-sh' && 'namespace-profile-bun-ci-linux-x64' || 'ubuntu-latest' }}
|
||||
tag: linux-x64
|
||||
arch: x64
|
||||
cpu: haswell
|
||||
canary: true
|
||||
no-cache: true
|
||||
linux-x64-baseline:
|
||||
if: ${{ !inputs.run-id }}
|
||||
name: Build linux-x64-baseline
|
||||
uses: ./.github/workflows/build-linux.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
runs-on: ${{ github.repository_owner == 'oven-sh' && 'namespace-profile-bun-ci-linux-x64' || 'ubuntu-latest' }}
|
||||
tag: linux-x64-baseline
|
||||
arch: x64
|
||||
cpu: nehalem
|
||||
canary: true
|
||||
no-cache: true
|
||||
linux-aarch64:
|
||||
if: ${{ !inputs.run-id && github.repository_owner == 'oven-sh' }}
|
||||
name: Build linux-aarch64
|
||||
uses: ./.github/workflows/build-linux.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
runs-on: namespace-profile-bun-ci-linux-aarch64
|
||||
tag: linux-aarch64
|
||||
arch: aarch64
|
||||
cpu: native
|
||||
canary: true
|
||||
no-cache: true
|
||||
darwin-x64:
|
||||
if: ${{ !inputs.run-id }}
|
||||
name: Build darwin-x64
|
||||
uses: ./.github/workflows/build-darwin.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
runs-on: ${{ github.repository_owner == 'oven-sh' && 'macos-12-large' || 'macos-12' }}
|
||||
tag: darwin-x64
|
||||
arch: x64
|
||||
cpu: haswell
|
||||
canary: true
|
||||
darwin-x64-baseline:
|
||||
if: ${{ !inputs.run-id }}
|
||||
name: Build darwin-x64-baseline
|
||||
uses: ./.github/workflows/build-darwin.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
runs-on: ${{ github.repository_owner == 'oven-sh' && 'macos-12-large' || 'macos-12' }}
|
||||
tag: darwin-x64-baseline
|
||||
arch: x64
|
||||
cpu: nehalem
|
||||
canary: true
|
||||
darwin-aarch64:
|
||||
if: ${{ !inputs.run-id }}
|
||||
name: Build darwin-aarch64
|
||||
uses: ./.github/workflows/build-darwin.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
runs-on: ${{ github.repository_owner == 'oven-sh' && 'namespace-profile-bun-ci-darwin-aarch64' || 'macos-12' }}
|
||||
tag: darwin-aarch64
|
||||
arch: aarch64
|
||||
cpu: native
|
||||
canary: true
|
||||
windows-x64:
|
||||
if: ${{ !inputs.run-id }}
|
||||
name: Build windows-x64
|
||||
uses: ./.github/workflows/build-windows.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
runs-on: windows
|
||||
tag: windows-x64
|
||||
arch: x64
|
||||
cpu: haswell
|
||||
canary: true
|
||||
windows-x64-baseline:
|
||||
if: ${{ !inputs.run-id }}
|
||||
name: Build windows-x64-baseline
|
||||
uses: ./.github/workflows/build-windows.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
runs-on: windows
|
||||
tag: windows-x64-baseline
|
||||
arch: x64
|
||||
cpu: nehalem
|
||||
canary: true
|
||||
linux-x64-test:
|
||||
if: ${{ inputs.run-id || github.event_name == 'pull_request' }}
|
||||
name: Test linux-x64
|
||||
needs: linux-x64
|
||||
uses: ./.github/workflows/run-test.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
run-id: ${{ inputs.run-id }}
|
||||
pr-number: ${{ github.event.number }}
|
||||
runs-on: ${{ github.repository_owner == 'oven-sh' && 'namespace-profile-bun-ci-linux-x64' || 'ubuntu-latest' }}
|
||||
tag: linux-x64
|
||||
linux-x64-baseline-test:
|
||||
if: ${{ inputs.run-id || github.event_name == 'pull_request' }}
|
||||
name: Test linux-x64-baseline
|
||||
needs: linux-x64-baseline
|
||||
uses: ./.github/workflows/run-test.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
run-id: ${{ inputs.run-id }}
|
||||
pr-number: ${{ github.event.number }}
|
||||
runs-on: ${{ github.repository_owner == 'oven-sh' && 'namespace-profile-bun-ci-linux-x64' || 'ubuntu-latest' }}
|
||||
tag: linux-x64-baseline
|
||||
linux-aarch64-test:
|
||||
if: ${{ inputs.run-id || github.event_name == 'pull_request' && github.repository_owner == 'oven-sh'}}
|
||||
name: Test linux-aarch64
|
||||
needs: linux-aarch64
|
||||
uses: ./.github/workflows/run-test.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
run-id: ${{ inputs.run-id }}
|
||||
pr-number: ${{ github.event.number }}
|
||||
runs-on: namespace-profile-bun-ci-linux-aarch64
|
||||
tag: linux-aarch64
|
||||
darwin-x64-test:
|
||||
if: ${{ inputs.run-id || github.event_name == 'pull_request' }}
|
||||
name: Test darwin-x64
|
||||
needs: darwin-x64
|
||||
uses: ./.github/workflows/run-test.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
run-id: ${{ inputs.run-id }}
|
||||
pr-number: ${{ github.event.number }}
|
||||
runs-on: ${{ github.repository_owner == 'oven-sh' && 'macos-12-large' || 'macos-12' }}
|
||||
tag: darwin-x64
|
||||
darwin-x64-baseline-test:
|
||||
if: ${{ inputs.run-id || github.event_name == 'pull_request' }}
|
||||
name: Test darwin-x64-baseline
|
||||
needs: darwin-x64-baseline
|
||||
uses: ./.github/workflows/run-test.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
run-id: ${{ inputs.run-id }}
|
||||
pr-number: ${{ github.event.number }}
|
||||
runs-on: ${{ github.repository_owner == 'oven-sh' && 'macos-12-large' || 'macos-12' }}
|
||||
tag: darwin-x64-baseline
|
||||
darwin-aarch64-test:
|
||||
if: ${{ inputs.run-id || github.event_name == 'pull_request' }}
|
||||
name: Test darwin-aarch64
|
||||
needs: darwin-aarch64
|
||||
uses: ./.github/workflows/run-test.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
run-id: ${{ inputs.run-id }}
|
||||
pr-number: ${{ github.event.number }}
|
||||
runs-on: ${{ github.repository_owner == 'oven-sh' && 'namespace-profile-bun-ci-darwin-aarch64' || 'macos-12' }}
|
||||
tag: darwin-aarch64
|
||||
windows-x64-test:
|
||||
if: ${{ inputs.run-id || github.event_name == 'pull_request' }}
|
||||
name: Test windows-x64
|
||||
needs: windows-x64
|
||||
uses: ./.github/workflows/run-test.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
run-id: ${{ inputs.run-id }}
|
||||
pr-number: ${{ github.event.number }}
|
||||
runs-on: windows
|
||||
tag: windows-x64
|
||||
windows-x64-baseline-test:
|
||||
if: ${{ inputs.run-id || github.event_name == 'pull_request' }}
|
||||
name: Test windows-x64-baseline
|
||||
needs: windows-x64-baseline
|
||||
uses: ./.github/workflows/run-test.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
run-id: ${{ inputs.run-id }}
|
||||
pr-number: ${{ github.event.number }}
|
||||
runs-on: windows
|
||||
tag: windows-x64-baseline
|
||||
cleanup:
|
||||
if: ${{ always() }}
|
||||
name: Cleanup
|
||||
needs:
|
||||
- linux-x64
|
||||
- linux-x64-baseline
|
||||
- linux-aarch64
|
||||
- darwin-x64
|
||||
- darwin-x64-baseline
|
||||
- darwin-aarch64
|
||||
- windows-x64
|
||||
- windows-x64-baseline
|
||||
trigger:
|
||||
name: CI
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Cleanup Artifacts
|
||||
uses: geekyeggo/delete-artifact@v5
|
||||
- id: ci
|
||||
name: Start CI
|
||||
uses: buildkite/trigger-pipeline-action@v2.2.0
|
||||
with:
|
||||
name: |
|
||||
bun-*-cpp
|
||||
bun-*-zig
|
||||
bun-*-deps
|
||||
bun-*-codegen
|
||||
buildkite_api_access_token: ${{ secrets.BUILDKITE_TOKEN }}
|
||||
pipeline: "bun/sandbox"
|
||||
send_pull_request: true
|
||||
|
||||
9
.github/workflows/lint-cpp.yml
vendored
9
.github/workflows/lint-cpp.yml
vendored
@@ -14,10 +14,11 @@ on:
|
||||
type: string
|
||||
description: The workflow ID to download artifacts (skips the build step)
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- .vscode/**/*
|
||||
- docs/**/*
|
||||
- examples/**/*
|
||||
paths:
|
||||
- ".github/workflows/lint-cpp.yml"
|
||||
- "**/*.cpp"
|
||||
- "src/deps/**/*"
|
||||
- "CMakeLists.txt"
|
||||
|
||||
jobs:
|
||||
lint-cpp:
|
||||
|
||||
303
.github/workflows/run-test.yml
vendored
303
.github/workflows/run-test.yml
vendored
@@ -13,23 +13,42 @@ on:
|
||||
tag:
|
||||
type: string
|
||||
required: true
|
||||
pr-number:
|
||||
github-id:
|
||||
type: string
|
||||
required: true
|
||||
run-id:
|
||||
release-name:
|
||||
type: string
|
||||
buildkite-url:
|
||||
type: string
|
||||
default: ${{ github.run_id }}
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Tests
|
||||
name: ${{ matrix.label }}
|
||||
runs-on: ${{ inputs.runs-on }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- label: Bundler tests
|
||||
include: bundler/,transpiler/
|
||||
- label: CLI tests
|
||||
include: cli/
|
||||
- label: Node tests
|
||||
include: js/node/
|
||||
- label: Bun tests
|
||||
include: js/bun/
|
||||
- label: Web tests
|
||||
include: js/web/
|
||||
- label: Integration tests
|
||||
include: integration/,third_party/
|
||||
- label: Other tests
|
||||
exclude: bundler/,transpiler/,cli/,integration/,third_party/,js/node/,js/bun/,js/web/
|
||||
steps:
|
||||
- if: ${{ runner.os == 'Windows' }}
|
||||
name: Setup Git
|
||||
run: |
|
||||
git config --global core.autocrlf false
|
||||
git config --global core.eol lf
|
||||
git config --system core.autocrlf false
|
||||
git config --system core.eol lf
|
||||
git config --system core.longpaths true
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -37,188 +56,122 @@ jobs:
|
||||
package.json
|
||||
bun.lockb
|
||||
test
|
||||
packages/bun-internal-test
|
||||
packages/bun-types
|
||||
- name: Setup Environment
|
||||
shell: bash
|
||||
run: |
|
||||
echo "${{ inputs.pr-number }}" > pr-number.txt
|
||||
- name: Download Bun
|
||||
uses: actions/download-artifact@v4
|
||||
scripts
|
||||
.github
|
||||
- name: Setup Bun
|
||||
uses: ./.github/actions/setup-bun
|
||||
with:
|
||||
name: bun-${{ inputs.tag }}
|
||||
path: bun
|
||||
github-token: ${{ github.token }}
|
||||
run-id: ${{ inputs.run-id || github.run_id }}
|
||||
- name: Download pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
bun-version: latest
|
||||
baseline: ${{ contains(inputs.tag, '-baseline') }}
|
||||
- id: setup-release
|
||||
if: ${{ inputs.release-name }}
|
||||
name: Setup Bun from Release
|
||||
uses: ./.github/actions/setup-bun
|
||||
with:
|
||||
version: 8
|
||||
- if: ${{ runner.os != 'Windows' }}
|
||||
name: Setup Bun
|
||||
shell: bash
|
||||
run: |
|
||||
unzip bun/bun-*.zip
|
||||
cd bun-*
|
||||
pwd >> $GITHUB_PATH
|
||||
- if: ${{ runner.os == 'Windows' }}
|
||||
name: Setup Cygwin
|
||||
uses: secondlife/setup-cygwin@v3
|
||||
bun-version: ${{ inputs.release-name }}
|
||||
baseline: ${{ contains(inputs.tag, '-baseline') }}
|
||||
add-to-path: false
|
||||
- id: setup-github
|
||||
if: ${{ inputs.github-id }}
|
||||
name: Setup Bun from Github Actions
|
||||
uses: ./.github/actions/setup-bun
|
||||
with:
|
||||
packages: bash
|
||||
- if: ${{ runner.os == 'Windows' }}
|
||||
name: Setup Bun (Windows)
|
||||
run: |
|
||||
unzip bun/bun-*.zip
|
||||
cd bun-*
|
||||
pwd >> $env:GITHUB_PATH
|
||||
workflow-run-id: ${{ inputs.github-id }}
|
||||
baseline: ${{ contains(inputs.tag, '-baseline') }}
|
||||
add-to-path: false
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
- name: Install Dependencies
|
||||
timeout-minutes: 5
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
bun install
|
||||
- name: Install Dependencies (test)
|
||||
timeout-minutes: 5
|
||||
run: |
|
||||
bun install --cwd test
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Install Dependencies (runner)
|
||||
timeout-minutes: 5
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
bun install --cwd packages/bun-internal-test
|
||||
node-version: 22
|
||||
- name: Run Tests
|
||||
id: test
|
||||
timeout-minutes: 90
|
||||
shell: bash
|
||||
timeout-minutes: 30
|
||||
env:
|
||||
IS_BUN_CI: 1
|
||||
TMPDIR: ${{ runner.temp }}
|
||||
BUN_TAG: ${{ inputs.tag }}
|
||||
BUN_FEATURE_FLAG_INTERNAL_FOR_TESTING: "true"
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SMTP_SENDGRID_SENDER: ${{ secrets.SMTP_SENDGRID_SENDER }}
|
||||
TLS_MONGODB_DATABASE_URL: ${{ secrets.TLS_MONGODB_DATABASE_URL }}
|
||||
TLS_POSTGRES_DATABASE_URL: ${{ secrets.TLS_POSTGRES_DATABASE_URL }}
|
||||
TEST_INFO_STRIPE: ${{ secrets.TEST_INFO_STRIPE }}
|
||||
TEST_INFO_AZURE_SERVICE_BUS: ${{ secrets.TEST_INFO_AZURE_SERVICE_BUS }}
|
||||
SHELLOPTS: igncr
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
node packages/bun-internal-test/src/runner.node.mjs $(which bun)
|
||||
- if: ${{ always() }}
|
||||
name: Upload Results
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: bun-${{ inputs.tag }}-tests
|
||||
path: |
|
||||
test-report.*
|
||||
comment.md
|
||||
pr-number.txt
|
||||
if-no-files-found: error
|
||||
overwrite: true
|
||||
- if: ${{ always() && steps.test.outputs.failing_tests != '' && github.event.pull_request && github.repository_owner == 'oven-sh' }}
|
||||
name: Send Message
|
||||
uses: sarisia/actions-status-discord@v1
|
||||
with:
|
||||
webhook: ${{ secrets.DISCORD_WEBHOOK }}
|
||||
nodetail: true
|
||||
color: "#FF0000"
|
||||
title: ""
|
||||
description: |
|
||||
### ❌ [${{ github.event.pull_request.title }}](${{ github.event.pull_request.html_url }})
|
||||
node scripts/runner.node.mjs --exec-path "${{ steps.setup-github.outputs.bun-path || steps.setup-release.outputs.bun-path }}" --include "${{ matrix.include }}" --exclude "${{ matrix.exclude }}"
|
||||
|
||||
@${{ github.actor }}, there are ${{ steps.test.outputs.failing_tests_count || 'some' }} failing tests on bun-${{ inputs.tag }}.
|
||||
|
||||
${{ steps.test.outputs.failing_tests }}
|
||||
|
||||
**[View logs](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})**
|
||||
- name: Fail
|
||||
if: ${{ failure() || always() && steps.test.outputs.failing_tests != '' }}
|
||||
run: |
|
||||
echo "There are ${{ steps.test.outputs.failing_tests_count || 'some' }} failing tests on bun-${{ inputs.tag }}."
|
||||
exit 1
|
||||
test-node:
|
||||
name: Node.js Tests
|
||||
# TODO: enable when we start paying attention to the results. In the meantime, this causes CI to queue jobs wasting developer time.
|
||||
if: 0
|
||||
runs-on: ${{ inputs.runs-on }}
|
||||
steps:
|
||||
- if: ${{ runner.os == 'Windows' }}
|
||||
name: Setup Git
|
||||
run: |
|
||||
git config --global core.autocrlf false
|
||||
git config --global core.eol lf
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
sparse-checkout: |
|
||||
test/node.js
|
||||
- name: Setup Environment
|
||||
shell: bash
|
||||
run: |
|
||||
echo "${{ inputs.pr-number }}" > pr-number.txt
|
||||
- name: Download Bun
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: bun-${{ inputs.tag }}
|
||||
path: bun
|
||||
github-token: ${{ github.token }}
|
||||
run-id: ${{ inputs.run-id || github.run_id }}
|
||||
- if: ${{ runner.os != 'Windows' }}
|
||||
name: Setup Bun
|
||||
shell: bash
|
||||
run: |
|
||||
unzip bun/bun-*.zip
|
||||
cd bun-*
|
||||
pwd >> $GITHUB_PATH
|
||||
- if: ${{ runner.os == 'Windows' }}
|
||||
name: Setup Cygwin
|
||||
uses: secondlife/setup-cygwin@v3
|
||||
with:
|
||||
packages: bash
|
||||
- if: ${{ runner.os == 'Windows' }}
|
||||
name: Setup Bun (Windows)
|
||||
run: |
|
||||
unzip bun/bun-*.zip
|
||||
cd bun-*
|
||||
pwd >> $env:GITHUB_PATH
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
- name: Checkout Tests
|
||||
shell: bash
|
||||
working-directory: test/node.js
|
||||
run: |
|
||||
node runner.mjs --pull
|
||||
- name: Install Dependencies
|
||||
timeout-minutes: 5
|
||||
shell: bash
|
||||
working-directory: test/node.js
|
||||
run: |
|
||||
bun install
|
||||
- name: Run Tests
|
||||
timeout-minutes: 10 # Increase when more tests are added
|
||||
shell: bash
|
||||
working-directory: test/node.js
|
||||
env:
|
||||
TMPDIR: ${{ runner.temp }}
|
||||
BUN_GARBAGE_COLLECTOR_LEVEL: "0"
|
||||
BUN_FEATURE_FLAG_INTERNAL_FOR_TESTING: "true"
|
||||
run: |
|
||||
node runner.mjs
|
||||
- name: Upload Results
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: bun-${{ inputs.tag }}-node-tests
|
||||
path: |
|
||||
test/node.js/summary/*.json
|
||||
if-no-files-found: error
|
||||
overwrite: true
|
||||
# TODO: Enable when we start running the Node.js test suite
|
||||
# test-node:
|
||||
# name: Node.js Tests
|
||||
# runs-on: ${{ inputs.runs-on }}
|
||||
# steps:
|
||||
# - if: ${{ runner.os == 'Windows' }}
|
||||
# name: Setup Git
|
||||
# run: |
|
||||
# git config --global core.autocrlf false
|
||||
# git config --global core.eol lf
|
||||
# git config --system core.longpaths true
|
||||
# - name: Checkout
|
||||
# uses: actions/checkout@v4
|
||||
# with:
|
||||
# sparse-checkout: |
|
||||
# test/node.js
|
||||
# - name: Setup Environment
|
||||
# shell: bash
|
||||
# run: |
|
||||
# echo "${{ inputs.pr-number }}" > pr-number.txt
|
||||
# - name: Download Bun
|
||||
# uses: actions/download-artifact@v4
|
||||
# with:
|
||||
# name: bun-${{ inputs.tag }}
|
||||
# path: bun
|
||||
# github-token: ${{ github.token }}
|
||||
# run-id: ${{ inputs.run-id || github.run_id }}
|
||||
# - if: ${{ runner.os != 'Windows' }}
|
||||
# name: Setup Bun
|
||||
# shell: bash
|
||||
# run: |
|
||||
# unzip bun/bun-*.zip
|
||||
# cd bun-*
|
||||
# pwd >> $GITHUB_PATH
|
||||
# - if: ${{ runner.os == 'Windows' }}
|
||||
# name: Setup Cygwin
|
||||
# uses: secondlife/setup-cygwin@v3
|
||||
# with:
|
||||
# packages: bash
|
||||
# - if: ${{ runner.os == 'Windows' }}
|
||||
# name: Setup Bun (Windows)
|
||||
# run: |
|
||||
# unzip bun/bun-*.zip
|
||||
# cd bun-*
|
||||
# pwd >> $env:GITHUB_PATH
|
||||
# - name: Setup Node.js
|
||||
# uses: actions/setup-node@v4
|
||||
# with:
|
||||
# node-version: 20
|
||||
# - name: Checkout Tests
|
||||
# shell: bash
|
||||
# working-directory: test/node.js
|
||||
# run: |
|
||||
# node runner.mjs --pull
|
||||
# - name: Install Dependencies
|
||||
# timeout-minutes: 5
|
||||
# shell: bash
|
||||
# working-directory: test/node.js
|
||||
# run: |
|
||||
# bun install
|
||||
# - name: Run Tests
|
||||
# timeout-minutes: 10 # Increase when more tests are added
|
||||
# shell: bash
|
||||
# working-directory: test/node.js
|
||||
# env:
|
||||
# TMPDIR: ${{ runner.temp }}
|
||||
# BUN_GARBAGE_COLLECTOR_LEVEL: "0"
|
||||
# BUN_FEATURE_FLAG_INTERNAL_FOR_TESTING: "true"
|
||||
# run: |
|
||||
# node runner.mjs
|
||||
# - name: Upload Results
|
||||
# uses: actions/upload-artifact@v4
|
||||
# with:
|
||||
# name: bun-${{ inputs.tag }}-node-tests
|
||||
# path: |
|
||||
# test/node.js/summary/*.json
|
||||
# if-no-files-found: error
|
||||
# overwrite: true
|
||||
|
||||
100
.github/workflows/test-bun.yml
vendored
Normal file
100
.github/workflows/test-bun.yml
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
name: Test Bun
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
actions: write
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ inputs.workflow-run-id || inputs.buildkite-url || inputs.bun-version || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
workflow-run-id:
|
||||
type: string
|
||||
buildkite-url:
|
||||
type: string
|
||||
bun-version:
|
||||
type: string
|
||||
workflow_call:
|
||||
inputs:
|
||||
workflow-run-id:
|
||||
type: string
|
||||
buildkite-url:
|
||||
type: string
|
||||
bun-version:
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
linux-x64-test:
|
||||
name: Test linux-x64
|
||||
uses: ./.github/workflows/run-test.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
runs-on: ubuntu-latest
|
||||
tag: linux-x64
|
||||
workflow-run-id: ${{ inputs.workflow-run-id }}
|
||||
buildkite-url: ${{ inputs.buildkite-url }}
|
||||
bun-version: ${{ inputs.bun-version }}
|
||||
linux-x64-baseline-test:
|
||||
name: Test linux-x64-baseline
|
||||
uses: ./.github/workflows/run-test.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
runs-on: ubuntu-latest
|
||||
tag: linux-x64-baseline
|
||||
workflow-run-id: ${{ inputs.workflow-run-id }}
|
||||
buildkite-url: ${{ inputs.buildkite-url }}
|
||||
bun-version: ${{ inputs.bun-version }}
|
||||
linux-aarch64-test:
|
||||
if: ${{ github.repository_owner == 'oven-sh' }}
|
||||
name: Test linux-aarch64
|
||||
uses: ./.github/workflows/run-test.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
runs-on: namespace-profile-bun-ci-linux-aarch64
|
||||
tag: linux-aarch64
|
||||
workflow-run-id: ${{ inputs.workflow-run-id }}
|
||||
buildkite-url: ${{ inputs.buildkite-url }}
|
||||
bun-version: ${{ inputs.bun-version }}
|
||||
darwin-x64-test:
|
||||
name: Test darwin-x64
|
||||
uses: ./.github/workflows/run-test.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
runs-on: macos-12
|
||||
tag: darwin-x64
|
||||
workflow-run-id: ${{ inputs.workflow-run-id }}
|
||||
buildkite-url: ${{ inputs.buildkite-url }}
|
||||
bun-version: ${{ inputs.bun-version }}
|
||||
darwin-aarch64-test:
|
||||
name: Test darwin-aarch64
|
||||
uses: ./.github/workflows/run-test.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
runs-on: macos-12
|
||||
tag: darwin-aarch64
|
||||
workflow-run-id: ${{ inputs.workflow-run-id }}
|
||||
buildkite-url: ${{ inputs.buildkite-url }}
|
||||
bun-version: ${{ inputs.bun-version }}
|
||||
windows-x64-test:
|
||||
name: Test windows-x64
|
||||
uses: ./.github/workflows/run-test.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
runs-on: windows-latest
|
||||
tag: windows-x64
|
||||
workflow-run-id: ${{ inputs.workflow-run-id }}
|
||||
buildkite-url: ${{ inputs.buildkite-url }}
|
||||
bun-version: ${{ inputs.bun-version }}
|
||||
windows-x64-baseline-test:
|
||||
name: Test windows-x64-baseline
|
||||
uses: ./.github/workflows/run-test.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
runs-on: windows-latest
|
||||
tag: windows-x64-baseline
|
||||
workflow-run-id: ${{ inputs.workflow-run-id }}
|
||||
buildkite-url: ${{ inputs.buildkite-url }}
|
||||
bun-version: ${{ inputs.bun-version }}
|
||||
8
.vscode/launch.json
generated
vendored
8
.vscode/launch.json
generated
vendored
@@ -445,8 +445,8 @@
|
||||
"request": "launch",
|
||||
"name": "bun test [*] (ci)",
|
||||
"program": "node",
|
||||
"args": ["src/runner.node.mjs"],
|
||||
"cwd": "${workspaceFolder}/packages/bun-internal-test",
|
||||
"args": ["test/runner.node.mjs"],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"console": "internalConsole",
|
||||
},
|
||||
// Windows: bun test [file]
|
||||
@@ -1093,8 +1093,8 @@
|
||||
"request": "launch",
|
||||
"name": "Windows: bun test [*] (ci)",
|
||||
"program": "node",
|
||||
"args": ["src/runner.node.mjs"],
|
||||
"cwd": "${workspaceFolder}/packages/bun-internal-test",
|
||||
"args": ["test/runner.node.mjs"],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"console": "internalConsole",
|
||||
},
|
||||
],
|
||||
|
||||
@@ -614,7 +614,7 @@ set(BUN_DEPS_DIR "${BUN_SRC}/deps")
|
||||
set(BUN_CODEGEN_SRC "${BUN_SRC}/codegen")
|
||||
|
||||
if(NOT BUN_DEPS_OUT_DIR)
|
||||
set(BUN_DEPS_OUT_DIR "${BUN_DEPS_DIR}")
|
||||
set(BUN_DEPS_OUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/build/bun-deps")
|
||||
endif()
|
||||
|
||||
set(BUN_RAW_SOURCES, "")
|
||||
|
||||
2
Makefile
2
Makefile
@@ -129,7 +129,7 @@ SED = $(shell which gsed 2>/dev/null || which sed 2>/dev/null)
|
||||
|
||||
BUN_DIR ?= $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
|
||||
BUN_DEPS_DIR ?= $(shell pwd)/src/deps
|
||||
BUN_DEPS_OUT_DIR ?= $(BUN_DEPS_DIR)
|
||||
BUN_DEPS_OUT_DIR ?= $(shell pwd)/build/bun-deps
|
||||
CPU_COUNT = 2
|
||||
ifeq ($(OS_NAME),darwin)
|
||||
CPU_COUNT = $(shell sysctl -n hw.logicalcpu)
|
||||
|
||||
30
package.json
30
package.json
@@ -5,23 +5,23 @@
|
||||
"./packages/bun-types"
|
||||
],
|
||||
"dependencies": {
|
||||
"@vscode/debugadapter": "^1.61.0",
|
||||
"esbuild": "^0.17.15",
|
||||
"eslint": "^8.20.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"mitata": "^0.1.3",
|
||||
"@vscode/debugadapter": "^1.65.0",
|
||||
"esbuild": "^0.21.4",
|
||||
"eslint": "^9.4.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"mitata": "^0.1.11",
|
||||
"peechy": "0.4.34",
|
||||
"prettier": "^3.2.5",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"source-map-js": "^1.0.2",
|
||||
"typescript": "^5.0.2"
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"source-map-js": "^1.2.0",
|
||||
"typescript": "^5.4.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.1.2",
|
||||
"@types/react": "^18.0.25",
|
||||
"@typescript-eslint/eslint-plugin": "^5.31.0",
|
||||
"@typescript-eslint/parser": "^5.31.0"
|
||||
"@types/bun": "^1.1.3",
|
||||
"@types/react": "^18.3.3",
|
||||
"@typescript-eslint/eslint-plugin": "^7.11.0",
|
||||
"@typescript-eslint/parser": "^7.11.0"
|
||||
},
|
||||
"resolutions": {
|
||||
"bun-types": "workspace:packages/bun-types"
|
||||
@@ -43,8 +43,8 @@
|
||||
"fmt:zig": "zig fmt src/*.zig src/*/*.zig src/*/*/*.zig src/*/*/*/*.zig",
|
||||
"lint": "eslint './**/*.d.ts' --cache",
|
||||
"lint:fix": "eslint './**/*.d.ts' --cache --fix",
|
||||
"test": "node packages/bun-internal-test/src/runner.node.mjs ./build/bun-debug",
|
||||
"test:release": "node packages/bun-internal-test/src/runner.node.mjs ./build-release/bun",
|
||||
"test": "node scripts/runner.node.mjs ./build/bun-debug",
|
||||
"test:release": "node scripts/runner.node.mjs ./build-release/bun",
|
||||
"zig-check": ".cache/zig/zig.exe build check --summary new",
|
||||
"zig-check-all": ".cache/zig/zig.exe build check-all --summary new",
|
||||
"zig": ".cache/zig/zig.exe "
|
||||
|
||||
@@ -1,606 +0,0 @@
|
||||
import * as action from "@actions/core";
|
||||
import { spawn, spawnSync } from "child_process";
|
||||
import { rmSync, writeFileSync, readFileSync, mkdirSync, openSync, closeSync } from "fs";
|
||||
import { readdirSync } from "node:fs";
|
||||
import { resolve, basename } from "node:path";
|
||||
import { cpus, hostname, tmpdir, totalmem, userInfo } from "os";
|
||||
import { join, normalize, posix, relative } from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
import PQueue from "p-queue";
|
||||
|
||||
const run_start = new Date();
|
||||
const TIMEOUT_DURATION = 1000 * 60 * 5;
|
||||
const SHORT_TIMEOUT_DURATION = Math.ceil(TIMEOUT_DURATION / 5);
|
||||
|
||||
function defaultConcurrency() {
|
||||
// This causes instability due to the number of open file descriptors / sockets in some tests
|
||||
// Windows has higher limits
|
||||
if (process.platform !== "win32") {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return Math.min(Math.floor((cpus().length - 2) / 2), 2);
|
||||
}
|
||||
const windows = process.platform === "win32";
|
||||
const nativeMemory = totalmem();
|
||||
const force_ram_size_input = parseInt(process.env["BUN_JSC_forceRAMSize"] || "0", 10);
|
||||
let force_ram_size = Number(BigInt(nativeMemory) >> BigInt(2)) + "";
|
||||
if (!(Number.isSafeInteger(force_ram_size_input) && force_ram_size_input > 0)) {
|
||||
force_ram_size = force_ram_size_input + "";
|
||||
}
|
||||
function uncygwinTempDir() {
|
||||
if (process.platform === "win32") {
|
||||
for (let key of ["TMPDIR", "TEMP", "TEMPDIR", "TMP"]) {
|
||||
let TMPDIR = process.env[key] || "";
|
||||
if (!/^\/[a-zA-Z]\//.test(TMPDIR)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const driveLetter = TMPDIR[1];
|
||||
TMPDIR = path.win32.normalize(`${driveLetter.toUpperCase()}:` + TMPDIR.substring(2));
|
||||
process.env[key] = TMPDIR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uncygwinTempDir();
|
||||
|
||||
const cwd = resolve(fileURLToPath(import.meta.url), "../../../../");
|
||||
process.chdir(cwd);
|
||||
|
||||
const ci = !!process.env["GITHUB_ACTIONS"];
|
||||
const enableProgressBar = false;
|
||||
|
||||
const dirPrefix = "bun-test-tmp-" + ((Math.random() * 100_000_0) | 0).toString(36) + "_";
|
||||
const run_concurrency = Math.max(Number(process.env["BUN_TEST_CONCURRENCY"] || defaultConcurrency(), 10), 1);
|
||||
const queue = new PQueue({ concurrency: run_concurrency });
|
||||
|
||||
var prevTmpdir = "";
|
||||
function maketemp() {
|
||||
prevTmpdir = join(
|
||||
tmpdir(),
|
||||
dirPrefix + (Date.now() | 0).toString() + "_" + ((Math.random() * 100_000_0) | 0).toString(36),
|
||||
);
|
||||
mkdirSync(prevTmpdir, { recursive: true });
|
||||
return prevTmpdir;
|
||||
}
|
||||
|
||||
const extensions = [".js", ".ts", ".jsx", ".tsx", ".mjs", ".cjs", ".mts", ".cts", ".mjsx", ".cjsx", ".mtsx", ".ctsx"];
|
||||
|
||||
const git_sha =
|
||||
process.env["GITHUB_SHA"] ?? spawnSync("git", ["rev-parse", "HEAD"], { encoding: "utf-8" }).stdout.trim();
|
||||
|
||||
const TEST_FILTER = process.env.BUN_TEST_FILTER;
|
||||
|
||||
function isTest(path) {
|
||||
if (!basename(path).includes(".test.") || !extensions.some(ext => path.endsWith(ext))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (TEST_FILTER) {
|
||||
if (!path.includes(TEST_FILTER)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function* findTests(dir, query) {
|
||||
for (const entry of readdirSync(resolve(dir), { encoding: "utf-8", withFileTypes: true })) {
|
||||
const path = resolve(dir, entry.name);
|
||||
if (entry.isDirectory() && entry.name !== "node_modules" && entry.name !== ".git") {
|
||||
yield* findTests(path, query);
|
||||
} else if (isTest(path)) {
|
||||
yield path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let bunExe = "bun";
|
||||
|
||||
if (process.argv.length > 2) {
|
||||
bunExe = resolve(process.argv.at(-1));
|
||||
} else if (process.env.BUN_PATH) {
|
||||
const { BUN_PATH_BASE, BUN_PATH } = process.env;
|
||||
bunExe = resolve(normalize(BUN_PATH_BASE), normalize(BUN_PATH));
|
||||
}
|
||||
|
||||
const { error, stdout: revision_stdout } = spawnSync(bunExe, ["--revision"], {
|
||||
env: { ...process.env, BUN_DEBUG_QUIET_LOGS: 1 },
|
||||
});
|
||||
if (error) {
|
||||
if (error.code !== "ENOENT") throw error;
|
||||
console.error(`\x1b[31merror\x1b[0;2m:\x1b[0m Could not find Bun executable at '${bunExe}'`);
|
||||
process.exit(1);
|
||||
}
|
||||
const revision = revision_stdout.toString().trim();
|
||||
|
||||
const { error: error2, stdout: argv0_stdout } = spawnSync(bunExe, ["-e", "console.log(process.argv[0])"], {
|
||||
env: { ...process.env, BUN_DEBUG_QUIET_LOGS: 1 },
|
||||
});
|
||||
if (error2) throw error2;
|
||||
const argv0 = argv0_stdout.toString().trim();
|
||||
|
||||
console.log(`Testing ${argv0} v${revision}`);
|
||||
|
||||
const ntStatusPath = "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.22621.0\\shared\\ntstatus.h";
|
||||
let ntstatus_header_cache = null;
|
||||
function lookupWindowsError(code) {
|
||||
if (ntstatus_header_cache === null) {
|
||||
try {
|
||||
ntstatus_header_cache = readFileSync(ntStatusPath, "utf-8");
|
||||
} catch {
|
||||
console.error(`could not find ntstatus.h to lookup error code: ${ntStatusPath}`);
|
||||
ntstatus_header_cache = "";
|
||||
}
|
||||
}
|
||||
const match = ntstatus_header_cache.match(new RegExp(`(STATUS_\\w+).*0x${code.toString(16)}`, "i"));
|
||||
if (match) {
|
||||
return match[1];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
const failing_tests = [];
|
||||
const passing_tests = [];
|
||||
let maxFd = -1;
|
||||
function getMaxFileDescriptor(path) {
|
||||
if (process.platform === "win32") {
|
||||
return -1;
|
||||
}
|
||||
|
||||
hasInitialMaxFD = true;
|
||||
|
||||
if (process.platform === "linux" || process.platform === "darwin") {
|
||||
try {
|
||||
readdirSync(process.platform === "darwin" ? "/dev/fd" : "/proc/self/fd").forEach(name => {
|
||||
const fd = parseInt(name.trim(), 10);
|
||||
if (Number.isSafeInteger(fd) && fd >= 0) {
|
||||
maxFd = Math.max(maxFd, fd);
|
||||
}
|
||||
});
|
||||
|
||||
return maxFd;
|
||||
} catch {}
|
||||
}
|
||||
|
||||
const devnullfd = openSync("/dev/null", "r");
|
||||
closeSync(devnullfd);
|
||||
maxFd = devnullfd + 1;
|
||||
return maxFd;
|
||||
}
|
||||
let hasInitialMaxFD = false;
|
||||
|
||||
const activeTests = new Map();
|
||||
|
||||
let slowTestCount = 0;
|
||||
function checkSlowTests() {
|
||||
const now = Date.now();
|
||||
const prevSlowTestCount = slowTestCount;
|
||||
slowTestCount = 0;
|
||||
for (const [path, { start, proc }] of activeTests) {
|
||||
if (proc && now - start >= TIMEOUT_DURATION) {
|
||||
console.error(
|
||||
`\x1b[31merror\x1b[0;2m:\x1b[0m Killing test ${JSON.stringify(path)} after ${Math.ceil((now - start) / 1000)}s`,
|
||||
);
|
||||
proc?.stdout?.destroy?.();
|
||||
proc?.stderr?.destroy?.();
|
||||
proc?.kill?.(9);
|
||||
} else if (now - start > SHORT_TIMEOUT_DURATION) {
|
||||
console.error(
|
||||
`\x1b[33mwarning\x1b[0;2m:\x1b[0m Test ${JSON.stringify(path)} has been running for ${Math.ceil(
|
||||
(now - start) / 1000,
|
||||
)}s`,
|
||||
);
|
||||
slowTestCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (slowTestCount > prevSlowTestCount && queue.concurrency > 1) {
|
||||
queue.concurrency += 1;
|
||||
}
|
||||
}
|
||||
|
||||
setInterval(checkSlowTests, SHORT_TIMEOUT_DURATION).unref();
|
||||
var currentTestNumber = 0;
|
||||
async function runTest(path) {
|
||||
const pathOnDisk = resolve(path);
|
||||
const thisTestNumber = currentTestNumber++;
|
||||
const testFileName = posix.normalize(relative(cwd, path).replaceAll("\\", "/"));
|
||||
let exitCode, signal, err, output;
|
||||
|
||||
const start = Date.now();
|
||||
|
||||
const activeTestObject = { start, proc: undefined };
|
||||
activeTests.set(testFileName, activeTestObject);
|
||||
|
||||
try {
|
||||
await new Promise((finish, reject) => {
|
||||
const chunks = [];
|
||||
process.stderr.write(
|
||||
`
|
||||
at ${((start - run_start.getTime()) / 1000).toFixed(2)}s, file ${thisTestNumber
|
||||
.toString()
|
||||
.padStart(total.toString().length, "0")}/${total}, ${failing_tests.length} failing files
|
||||
Starting "${testFileName}"
|
||||
|
||||
`,
|
||||
);
|
||||
const TMPDIR = maketemp();
|
||||
const proc = spawn(bunExe, ["test", pathOnDisk], {
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
env: {
|
||||
...process.env,
|
||||
FORCE_COLOR: "1",
|
||||
BUN_GARBAGE_COLLECTOR_LEVEL: "1",
|
||||
BUN_JSC_forceRAMSize: force_ram_size,
|
||||
BUN_RUNTIME_TRANSPILER_CACHE_PATH: "0",
|
||||
GITHUB_ACTIONS: process.env.GITHUB_ACTIONS ?? "true",
|
||||
BUN_DEBUG_QUIET_LOGS: "1",
|
||||
BUN_INSTALL_CACHE_DIR: join(TMPDIR, ".bun-install-cache"),
|
||||
BUN_ENABLE_CRASH_REPORTING: "1",
|
||||
[windows ? "TEMP" : "TMPDIR"]: TMPDIR,
|
||||
},
|
||||
});
|
||||
activeTestObject.proc = proc;
|
||||
proc.stdout.once("end", () => {
|
||||
done();
|
||||
});
|
||||
|
||||
let doneCalls = 0;
|
||||
var done = () => {
|
||||
// TODO: wait for stderr as well
|
||||
// spawn.test currently causes it to hang
|
||||
if (doneCalls++ === 1) {
|
||||
actuallyDone();
|
||||
}
|
||||
};
|
||||
var actuallyDone = function () {
|
||||
actuallyDone = done = () => {};
|
||||
proc?.stderr?.unref?.();
|
||||
proc?.stdout?.unref?.();
|
||||
proc?.unref?.();
|
||||
output = Buffer.concat(chunks).toString();
|
||||
finish();
|
||||
};
|
||||
|
||||
// if (!KEEP_TMPDIR)
|
||||
// proc.once("close", () => {
|
||||
// rm(TMPDIR, { recursive: true, force: true }).catch(() => {});
|
||||
// });
|
||||
|
||||
proc.stdout.on("data", chunk => {
|
||||
chunks.push(chunk);
|
||||
if (run_concurrency === 1) process.stdout.write(chunk);
|
||||
});
|
||||
proc.stderr.on("data", chunk => {
|
||||
chunks.push(chunk);
|
||||
if (run_concurrency === 1) process.stderr.write(chunk);
|
||||
});
|
||||
|
||||
proc.once("close", () => {
|
||||
activeTestObject.proc = undefined;
|
||||
});
|
||||
|
||||
proc.once("exit", (code_, signal_) => {
|
||||
activeTestObject.proc = undefined;
|
||||
exitCode = code_;
|
||||
signal = signal_;
|
||||
if (signal || exitCode !== 0) {
|
||||
actuallyDone();
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
});
|
||||
proc.once("error", err_ => {
|
||||
activeTestObject.proc = undefined;
|
||||
err = err_;
|
||||
actuallyDone();
|
||||
});
|
||||
});
|
||||
} finally {
|
||||
activeTests.delete(testFileName);
|
||||
}
|
||||
|
||||
if (!hasInitialMaxFD) {
|
||||
getMaxFileDescriptor();
|
||||
} else if (maxFd > 0) {
|
||||
const prevMaxFd = maxFd;
|
||||
maxFd = getMaxFileDescriptor();
|
||||
if (maxFd > prevMaxFd + queue.concurrency * 2) {
|
||||
process.stderr.write(
|
||||
`\n\x1b[31mewarn\x1b[0;2m:\x1b[0m file descriptor leak in ${testFileName}, delta: ${
|
||||
maxFd - prevMaxFd
|
||||
}, current: ${maxFd}, previous: ${prevMaxFd}\n`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const passed = exitCode === 0 && !err && !signal;
|
||||
|
||||
let reason = "";
|
||||
if (!passed) {
|
||||
let match;
|
||||
if (err && err.message.includes("timed")) {
|
||||
reason = "hang";
|
||||
} else if ((match = output && output.match(/thread \d+ panic: (.*)\n/))) {
|
||||
reason = 'panic "' + match[1] + '"';
|
||||
} else if (err) {
|
||||
reason = (err.name || "Error") + ": " + err.message;
|
||||
} else if (signal) {
|
||||
reason = signal;
|
||||
} else if (exitCode === 1) {
|
||||
const failMatch = output.match(/\x1b\[31m\s(\d+) fail/);
|
||||
if (failMatch) {
|
||||
reason = failMatch[1] + " failing";
|
||||
} else {
|
||||
reason = "code 1";
|
||||
}
|
||||
} else {
|
||||
const x = windows && lookupWindowsError(exitCode);
|
||||
if (x) {
|
||||
if (x === "STATUS_BREAKPOINT") {
|
||||
if (output.includes("Segmentation fault at address")) {
|
||||
reason = "STATUS_ACCESS_VIOLATION";
|
||||
}
|
||||
}
|
||||
reason = x;
|
||||
} else {
|
||||
reason = "code " + exitCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const duration = (Date.now() - start) / 1000;
|
||||
|
||||
if (run_concurrency !== 1 && enableProgressBar) {
|
||||
// clear line
|
||||
process.stdout.write("\x1b[2K\r");
|
||||
}
|
||||
|
||||
console.log(
|
||||
`\x1b[2m${formatTime(duration).padStart(6, " ")}\x1b[0m ${
|
||||
passed ? "\x1b[32m✔" : "\x1b[31m✖"
|
||||
} ${testFileName}\x1b[0m${reason ? ` (${reason})` : ""}`,
|
||||
);
|
||||
|
||||
finished++;
|
||||
|
||||
if (run_concurrency !== 1 && enableProgressBar) {
|
||||
writeProgressBar();
|
||||
}
|
||||
|
||||
if (run_concurrency > 1 && ci) {
|
||||
process.stderr.write(output);
|
||||
}
|
||||
|
||||
if (!passed) {
|
||||
failing_tests.push({ path: testFileName, reason, output });
|
||||
process.exitCode = 1;
|
||||
if (err) console.error(err);
|
||||
} else {
|
||||
passing_tests.push(testFileName);
|
||||
}
|
||||
|
||||
return passed;
|
||||
}
|
||||
|
||||
var finished = 0;
|
||||
|
||||
function writeProgressBar() {
|
||||
const barWidth = Math.min(process.stdout.columns || 40, 80) - 2;
|
||||
const percent = (finished / total) * 100;
|
||||
const bar = "=".repeat(Math.floor(percent / 2));
|
||||
const str1 = `[${finished}/${total}] [${bar}`;
|
||||
process.stdout.write(`\r${str1}${" ".repeat(barWidth - str1.length)}]`);
|
||||
}
|
||||
|
||||
const allTests = [...findTests(resolve(cwd, "test"))];
|
||||
console.log(`Starting ${allTests.length} tests with ${run_concurrency} concurrency...`);
|
||||
let total = allTests.length;
|
||||
for (const path of allTests) {
|
||||
queue.add(
|
||||
async () =>
|
||||
await runTest(path).catch(e => {
|
||||
console.error("Bug in bun-internal-test");
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
}),
|
||||
);
|
||||
}
|
||||
await queue.onIdle();
|
||||
console.log(`
|
||||
Completed ${total} tests with ${failing_tests.length} failing tests
|
||||
`);
|
||||
console.log("\n");
|
||||
|
||||
function linkToGH(linkTo) {
|
||||
return `https://github.com/oven-sh/bun/blob/${git_sha}/${linkTo}`;
|
||||
}
|
||||
|
||||
failing_tests.sort((a, b) => a.path.localeCompare(b.path));
|
||||
passing_tests.sort((a, b) => a.localeCompare(b));
|
||||
|
||||
const failingTestDisplay = failing_tests.map(({ path, reason }) => `- \`${path}\` ${reason}`).join("\n");
|
||||
|
||||
// const passingTestDisplay = passing_tests.map(path => `- \`${path}\``).join("\n");
|
||||
|
||||
rmSync("report.md", { force: true });
|
||||
|
||||
const uptime = process.uptime();
|
||||
|
||||
function formatTime(seconds) {
|
||||
if (seconds < 60) {
|
||||
return seconds.toFixed(1) + "s";
|
||||
} else if (seconds < 60 * 60) {
|
||||
return (seconds / 60).toFixed(0) + "m " + formatTime(seconds % 60);
|
||||
} else {
|
||||
return (seconds / 60 / 60).toFixed(0) + "h " + formatTime(seconds % (60 * 60));
|
||||
}
|
||||
}
|
||||
|
||||
const header = `
|
||||
host: ${process.env["GITHUB_RUN_ID"] ? "GitHub Actions: " : ""}${userInfo().username}@${hostname()}
|
||||
platform: ${process.platform} ${process.arch}
|
||||
bun: ${argv0}
|
||||
version: v${revision}
|
||||
|
||||
date: ${run_start.toISOString()}
|
||||
duration: ${formatTime(uptime)}
|
||||
|
||||
total: ${total} files
|
||||
failing: ${failing_tests.length} files
|
||||
passing: ${passing_tests.length} files
|
||||
|
||||
percent: ${((passing_tests.length / total) * 100).toFixed(2)}%
|
||||
`.trim();
|
||||
|
||||
console.log("\n" + "-".repeat(Math.min(process.stdout.columns || 40, 80)) + "\n");
|
||||
console.log(header);
|
||||
console.log("\n" + "-".repeat(Math.min(process.stdout.columns || 40, 80)) + "\n");
|
||||
|
||||
let report = `# bun test on ${
|
||||
process.env["GITHUB_REF"] ??
|
||||
spawnSync("git", ["rev-parse", "--abbrev-ref", "HEAD"], { encoding: "utf-8" }).stdout.trim()
|
||||
}
|
||||
|
||||
\`\`\`
|
||||
${header}
|
||||
\`\`\`
|
||||
|
||||
`;
|
||||
|
||||
if (failingTestDisplay.length > 0) {
|
||||
report += `## Failing tests\n\n`;
|
||||
report += failingTestDisplay;
|
||||
report += "\n\n";
|
||||
}
|
||||
|
||||
// if(passingTestDisplay.length > 0) {
|
||||
// report += `## Passing tests\n\n`;
|
||||
// report += passingTestDisplay;
|
||||
// report += "\n\n";
|
||||
// }
|
||||
|
||||
if (failing_tests.length) {
|
||||
report += `## Failing tests log output\n\n`;
|
||||
for (const { path, output, reason } of failing_tests) {
|
||||
report += `### ${path}\n\n`;
|
||||
report += "[Link to file](" + linkToGH(path) + ")\n\n";
|
||||
report += `${reason}\n\n`;
|
||||
report += "```\n";
|
||||
|
||||
let failing_output = output
|
||||
.replace(/\x1b\[[0-9;]*m/g, "")
|
||||
.replace(/^::(group|endgroup|error|warning|set-output|add-matcher|remove-matcher).*$/gm, "");
|
||||
|
||||
if (failing_output.length > 1024 * 64) {
|
||||
failing_output = failing_output.slice(0, 1024 * 64) + `\n\n[truncated output (length: ${failing_output.length})]`;
|
||||
}
|
||||
|
||||
report += failing_output;
|
||||
|
||||
report += "```\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
writeFileSync("test-report.md", report);
|
||||
writeFileSync(
|
||||
"test-report.json",
|
||||
JSON.stringify({
|
||||
failing_tests,
|
||||
passing_tests,
|
||||
}),
|
||||
);
|
||||
|
||||
function mabeCapitalize(str) {
|
||||
str = str.toLowerCase();
|
||||
if (str.includes("arm64") || str.includes("aarch64")) {
|
||||
return str.toUpperCase();
|
||||
}
|
||||
|
||||
if (str.includes("x64")) {
|
||||
return "x64";
|
||||
}
|
||||
|
||||
if (str.includes("baseline")) {
|
||||
return str;
|
||||
}
|
||||
|
||||
return str[0].toUpperCase() + str.slice(1);
|
||||
}
|
||||
|
||||
console.log("-> test-report.md, test-report.json");
|
||||
function linkify(text, url) {
|
||||
if (url?.startsWith?.("https://")) {
|
||||
return `[${text}](${url})`;
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
if (ci) {
|
||||
if (failing_tests.length > 0) {
|
||||
action.setFailed(`${failing_tests.length} files with failing tests`);
|
||||
}
|
||||
action.setOutput("failing_tests", failingTestDisplay);
|
||||
action.setOutput("failing_tests_count", failing_tests.length);
|
||||
if (failing_tests.length) {
|
||||
const { env } = process;
|
||||
const tag = process.env.BUN_TAG || "unknown";
|
||||
const url = `${env.GITHUB_SERVER_URL}/${env.GITHUB_REPOSITORY}/actions/runs/${env.GITHUB_RUN_ID}`;
|
||||
|
||||
let comment = `## ${linkify(`${emojiTag(tag)}${failing_tests.length} failing tests`, url)} ${tag
|
||||
.split("-")
|
||||
.map(mabeCapitalize)
|
||||
.join(" ")}
|
||||
|
||||
${failingTestDisplay}
|
||||
|
||||
`;
|
||||
writeFileSync("comment.md", comment);
|
||||
}
|
||||
let truncated_report = report;
|
||||
if (truncated_report.length > 512 * 1000) {
|
||||
truncated_report = truncated_report.slice(0, 512 * 1000) + "\n\n...truncated...";
|
||||
}
|
||||
action.summary.addRaw(truncated_report);
|
||||
await action.summary.write();
|
||||
}
|
||||
|
||||
function emojiTag(tag) {
|
||||
let emojiText = "";
|
||||
tag = tag.toLowerCase();
|
||||
if (tag.includes("win32") || tag.includes("windows")) {
|
||||
emojiText += "🪟";
|
||||
}
|
||||
|
||||
if (tag.includes("linux")) {
|
||||
emojiText += "🐧";
|
||||
}
|
||||
|
||||
if (tag.includes("macos") || tag.includes("darwin")) {
|
||||
emojiText += "";
|
||||
}
|
||||
|
||||
if (tag.includes("x86") || tag.includes("x64") || tag.includes("_64") || tag.includes("amd64")) {
|
||||
if (!tag.includes("linux")) {
|
||||
emojiText += "💻";
|
||||
} else {
|
||||
emojiText += "🖥";
|
||||
}
|
||||
}
|
||||
|
||||
if (tag.includes("arm64") || tag.includes("aarch64")) {
|
||||
emojiText += "💪";
|
||||
}
|
||||
|
||||
if (emojiText) {
|
||||
emojiText += " ";
|
||||
}
|
||||
|
||||
return emojiText;
|
||||
}
|
||||
|
||||
process.exit(failing_tests.length ? 1 : process.exitCode);
|
||||
9
scripts/all-dependencies.ps1
Normal file → Executable file
9
scripts/all-dependencies.ps1
Normal file → Executable file
@@ -3,13 +3,14 @@ param(
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
. (Join-Path $PSScriptRoot "env.ps1")
|
||||
|
||||
if ($env:CI) {
|
||||
& (Join-Path $PSScriptRoot "update-submodules.ps1")
|
||||
}
|
||||
|
||||
$DidAnything = $false;
|
||||
|
||||
$BUN_BASE_DIR = if ($env:BUN_BASE_DIR) { $env:BUN_BASE_DIR } else { Join-Path $PSScriptRoot '..' }
|
||||
$BUN_DEPS_DIR = if ($env:BUN_DEPS_DIR) { $env:BUN_DEPS_DIR } else { Join-Path $BUN_BASE_DIR 'src\deps' }
|
||||
$BUN_DEPS_OUT_DIR = if ($env:BUN_DEPS_OUT_DIR) { $env:BUN_DEPS_OUT_DIR } else { $BUN_DEPS_DIR }
|
||||
|
||||
function Build-Dependency {
|
||||
param(
|
||||
$Script,
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
set -eo pipefail
|
||||
source "$(dirname -- "${BASH_SOURCE[0]}")/env.sh"
|
||||
|
||||
if [[ "$CI" ]]; then
|
||||
$(dirname -- "${BASH_SOURCE[0]}")/update-submodules.sh
|
||||
fi
|
||||
|
||||
FORCE=
|
||||
|
||||
while getopts "f" opt; do
|
||||
@@ -19,16 +24,35 @@ while getopts "f" opt; do
|
||||
done
|
||||
|
||||
BUILT_ANY=0
|
||||
SUBMODULES=
|
||||
CACHE_DIR=
|
||||
CACHE=0
|
||||
if [ -n "$BUN_DEPS_CACHE_DIR" ]; then
|
||||
CACHE_DIR="$BUN_DEPS_CACHE_DIR"
|
||||
CACHE=1
|
||||
SUBMODULES="$(git submodule status)"
|
||||
fi
|
||||
|
||||
dep() {
|
||||
local script="$1"
|
||||
local submodule="$1"
|
||||
local script="$2"
|
||||
CACHE_KEY=
|
||||
if [ "$CACHE" == "1" ]; then
|
||||
CACHE_KEY="$submodule/$(echo "$SUBMODULES" | grep "$submodule" | git hash-object --stdin)"
|
||||
fi
|
||||
if [ -z "$FORCE" ]; then
|
||||
HAS_ALL_DEPS=1
|
||||
shift
|
||||
for lib in "$@"; do
|
||||
for lib in "${@:2}"; do
|
||||
if [ ! -f "$BUN_DEPS_OUT_DIR/$lib" ]; then
|
||||
HAS_ALL_DEPS=0
|
||||
break
|
||||
if [[ "$CACHE" == "1" && -f "$CACHE_DIR/$CACHE_KEY/$lib" ]]; then
|
||||
mkdir -p "$BUN_DEPS_OUT_DIR"
|
||||
cp "$CACHE_DIR/$CACHE_KEY/$lib" "$BUN_DEPS_OUT_DIR/$lib"
|
||||
printf "%s %s - already cached\n" "$script" "$lib"
|
||||
else
|
||||
HAS_ALL_DEPS=0
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
if [ "$HAS_ALL_DEPS" == "1" ]; then
|
||||
@@ -41,27 +65,34 @@ dep() {
|
||||
set +e
|
||||
bash "$SCRIPT_DIR/build-$script.sh"
|
||||
EXIT=$?
|
||||
set -e
|
||||
|
||||
if [ "$EXIT" -ne 0 ]; then
|
||||
printf "Failed to build %s\n" "$script"
|
||||
exit "$EXIT"
|
||||
fi
|
||||
|
||||
set -e
|
||||
if [ "$CACHE" == "1" ]; then
|
||||
mkdir -p "$CACHE_DIR/$CACHE_KEY"
|
||||
for lib in "${@:2}"; do
|
||||
cp "$BUN_DEPS_OUT_DIR/$lib" "$CACHE_DIR/$CACHE_KEY/$lib"
|
||||
printf "%s %s - cached\n" "$script" "$lib"
|
||||
done
|
||||
fi
|
||||
|
||||
BUILT_ANY=1
|
||||
}
|
||||
|
||||
dep boringssl libcrypto.a libssl.a libdecrepit.a
|
||||
dep cares libcares.a
|
||||
dep libarchive libarchive.a
|
||||
dep lolhtml liblolhtml.a
|
||||
dep mimalloc-debug libmimalloc-debug.a libmimalloc-debug.o
|
||||
dep mimalloc libmimalloc.a libmimalloc.o
|
||||
dep tinycc libtcc.a
|
||||
dep zlib libz.a
|
||||
dep zstd libzstd.a
|
||||
dep lshpack liblshpack.a
|
||||
dep boringssl boringssl libcrypto.a libssl.a libdecrepit.a
|
||||
dep c-ares cares libcares.a
|
||||
dep libarchive libarchive libarchive.a
|
||||
dep lol-html lolhtml liblolhtml.a
|
||||
dep mimalloc mimalloc-debug libmimalloc-debug.a libmimalloc-debug.o
|
||||
dep mimalloc mimalloc libmimalloc.a libmimalloc.o
|
||||
dep tinycc tinycc libtcc.a
|
||||
dep zlib zlib libz.a
|
||||
dep zstd zstd libzstd.a
|
||||
dep ls-hpack lshpack liblshpack.a
|
||||
|
||||
if [ "$BUILT_ANY" -eq 0 ]; then
|
||||
printf "(run with -f to rebuild)\n"
|
||||
|
||||
0
scripts/build-boringssl.ps1
Normal file → Executable file
0
scripts/build-boringssl.ps1
Normal file → Executable file
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euxo pipefail
|
||||
set -exo pipefail
|
||||
source $(dirname -- "${BASH_SOURCE[0]}")/env.sh
|
||||
|
||||
cd $BUN_DEPS_DIR/boringssl
|
||||
|
||||
29
scripts/build-bun-cpp.ps1
Executable file
29
scripts/build-bun-cpp.ps1
Executable file
@@ -0,0 +1,29 @@
|
||||
param (
|
||||
[switch] $Baseline = $False,
|
||||
[switch] $Fast = $False
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop' # Setting strict mode, similar to 'set -euo pipefail' in bash
|
||||
|
||||
$Tag = If ($Baseline) { "-Baseline" } Else { "" }
|
||||
$UseBaselineBuild = If ($Baseline) { "ON" } Else { "OFF" }
|
||||
$UseLto = If ($Fast) { "OFF" } Else { "ON" }
|
||||
|
||||
# $CANARY_REVISION = if (Test-Path build/.canary_revision) { Get-Content build/.canary_revision } else { "0" }
|
||||
$CANARY_REVISION = 0
|
||||
.\scripts\env.ps1 $Tag
|
||||
.\scripts\update-submodules.ps1
|
||||
.\scripts\build-libuv.ps1 -CloneOnly $True
|
||||
cd build
|
||||
|
||||
cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release `
|
||||
-DNO_CODEGEN=0 `
|
||||
-DNO_CONFIGURE_DEPENDS=1 `
|
||||
"-DUSE_BASELINE_BUILD=${UseBaselineBuild}" `
|
||||
"-DUSE_LTO=${UseLto}" `
|
||||
"-DCANARY=${CANARY_REVISION}" `
|
||||
-DBUN_CPP_ONLY=1 $Flags
|
||||
if ($LASTEXITCODE -ne 0) { throw "CMake configuration failed" }
|
||||
|
||||
.\compile-cpp-only.ps1 -v
|
||||
if ($LASTEXITCODE -ne 0) { throw "C++ compilation failed" }
|
||||
48
scripts/build-bun-cpp.sh
Executable file
48
scripts/build-bun-cpp.sh
Executable file
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env bash
|
||||
set -exo pipefail
|
||||
source $(dirname -- "${BASH_SOURCE[0]}")/env.sh
|
||||
|
||||
export USE_LTO="${USE_LTO:-ON}"
|
||||
case "$(uname -m)" in
|
||||
aarch64|arm64)
|
||||
export CPU_TARGET="${CPU_TARGET:-native}"
|
||||
;;
|
||||
*)
|
||||
export CPU_TARGET="${CPU_TARGET:-haswell}"
|
||||
;;
|
||||
esac
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--fast|--no-lto)
|
||||
export USE_LTO="OFF"
|
||||
shift
|
||||
;;
|
||||
--baseline)
|
||||
export CPU_TARGET="nehalem"
|
||||
shift
|
||||
;;
|
||||
--cpu)
|
||||
export CPU_TARGET="$2"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
*|-*|--*)
|
||||
echo "Unknown option $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
mkdir -p build
|
||||
cd build
|
||||
mkdir -p tmp_modules tmp_functions js codegen
|
||||
cmake .. \
|
||||
-GNinja \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DUSE_LTO=${USE_LTO} \
|
||||
-DCPU_TARGET=${CPU_TARGET} \
|
||||
-DBUN_CPP_ONLY=1 \
|
||||
-DNO_CONFIGURE_DEPENDS=1
|
||||
chmod +x ./compile-cpp-only.sh
|
||||
bash ./compile-cpp-only.sh -v
|
||||
95
scripts/build-bun-zig.sh
Executable file
95
scripts/build-bun-zig.sh
Executable file
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env bash
|
||||
set -exo pipefail
|
||||
source $(dirname -- "${BASH_SOURCE[0]}")/env.sh
|
||||
|
||||
cwd=$(pwd)
|
||||
zig=
|
||||
|
||||
if [[ "$CI" ]]; then
|
||||
# Since the zig build depends on files from the zig submodule,
|
||||
# make sure to update the submodule before building.
|
||||
git submodule update --init --recursive --progress --depth=1 --checkout src/deps/zig
|
||||
|
||||
# Also update the correct version of zig in the submodule.
|
||||
$(dirname -- "${BASH_SOURCE[0]}")/download-zig.sh
|
||||
fi
|
||||
|
||||
if [ -f "$cwd/.cache/zig/zig" ]; then
|
||||
zig="$cwd/.cache/zig/zig"
|
||||
else
|
||||
zig=$(which zig)
|
||||
fi
|
||||
|
||||
ZIG_OPTIMIZE="${ZIG_OPTIMIZE:-ReleaseFast}"
|
||||
CANARY="${CANARY:-0}"
|
||||
GIT_SHA="${GIT_SHA:-$(git rev-parse HEAD)}"
|
||||
|
||||
BUILD_MACHINE_ARCH="${BUILD_MACHINE_ARCH:-$(uname -m)}"
|
||||
DOCKER_MACHINE_ARCH=""
|
||||
if [[ "$BUILD_MACHINE_ARCH" == "x86_64" || "$BUILD_MACHINE_ARCH" == "amd64" ]]; then
|
||||
BUILD_MACHINE_ARCH="x86_64"
|
||||
DOCKER_MACHINE_ARCH="amd64"
|
||||
elif [[ "$BUILD_MACHINE_ARCH" == "aarch64" || "$BUILD_MACHINE_ARCH" == "arm64" ]]; then
|
||||
BUILD_MACHINE_ARCH="aarch64"
|
||||
DOCKER_MACHINE_ARCH="arm64"
|
||||
fi
|
||||
|
||||
TARGET_OS="${1:-linux}"
|
||||
TARGET_ARCH="${2:-x64}"
|
||||
TARGET_CPU="${3:-${CPU_TARGET:-native}}"
|
||||
|
||||
BUILDARCH=""
|
||||
if [[ "$TARGET_ARCH" == "x64" || "$TARGET_ARCH" == "x86_64" || "$TARGET_ARCH" == "amd64" ]]; then
|
||||
TARGET_ARCH="x86_64"
|
||||
BUILDARCH="amd64"
|
||||
elif [[ "$TARGET_ARCH" == "aarch64" || "$TARGET_ARCH" == "arm64" ]]; then
|
||||
TARGET_ARCH="aarch64"
|
||||
BUILDARCH="arm64"
|
||||
fi
|
||||
|
||||
TRIPLET=""
|
||||
if [[ "$TARGET_OS" == "linux" ]]; then
|
||||
TRIPLET="$TARGET_ARCH-linux-gnu"
|
||||
elif [[ "$TARGET_OS" == "darwin" ]]; then
|
||||
TRIPLET="$TARGET_ARCH-macos-none"
|
||||
elif [[ "$TARGET_OS" == "windows" ]]; then
|
||||
TRIPLET="$TARGET_ARCH-windows-msvc"
|
||||
fi
|
||||
|
||||
echo "--- Building identifier-cache"
|
||||
$zig run src/js_lexer/identifier_data.zig
|
||||
|
||||
echo "--- Building node-fallbacks"
|
||||
cd src/node-fallbacks
|
||||
bun install --frozen-lockfile
|
||||
bun run build
|
||||
cd "$cwd"
|
||||
|
||||
echo "--- Building codegen"
|
||||
bun install --frozen-lockfile
|
||||
make runtime_js fallback_decoder bun_error
|
||||
|
||||
echo "--- Building modules"
|
||||
mkdir -p build
|
||||
bun run src/codegen/bundle-modules.ts --debug=OFF build
|
||||
|
||||
echo "--- Building zig"
|
||||
cd build
|
||||
cmake .. \
|
||||
-GNinja \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DUSE_LTO=ON \
|
||||
-DZIG_OPTIMIZE="${ZIG_OPTIMIZE}" \
|
||||
-DGIT_SHA="${GIT_SHA}" \
|
||||
-DARCH="${TARGET_ARCH}" \
|
||||
-DBUILDARCH="${BUILDARCH}" \
|
||||
-DCPU_TARGET="${TARGET_CPU}" \
|
||||
-DZIG_TARGET="${TRIPLET}" \
|
||||
-DASSERTIONS="OFF" \
|
||||
-DWEBKIT_DIR="omit" \
|
||||
-DNO_CONFIGURE_DEPENDS=1 \
|
||||
-DNO_CODEGEN=1 \
|
||||
-DBUN_ZIG_OBJ_DIR="$cwd/build" \
|
||||
-DCANARY="$CANARY" \
|
||||
-DZIG_LIB_DIR=src/deps/zig/lib
|
||||
ONLY_ZIG=1 ninja "$cwd/build/bun-zig.o" -v
|
||||
0
scripts/build-cares.ps1
Normal file → Executable file
0
scripts/build-cares.ps1
Normal file → Executable file
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euxo pipefail
|
||||
set -exo pipefail
|
||||
source $(dirname -- "${BASH_SOURCE[0]}")/env.sh
|
||||
|
||||
cd $BUN_DEPS_DIR/c-ares
|
||||
|
||||
0
scripts/build-libarchive.ps1
Normal file → Executable file
0
scripts/build-libarchive.ps1
Normal file → Executable file
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euxo pipefail
|
||||
set -exo pipefail
|
||||
source $(dirname -- "${BASH_SOURCE[0]}")/env.sh
|
||||
|
||||
mkdir -p $BUN_DEPS_OUT_DIR
|
||||
|
||||
0
scripts/build-libuv.ps1
Normal file → Executable file
0
scripts/build-libuv.ps1
Normal file → Executable file
0
scripts/build-lolhtml.ps1
Normal file → Executable file
0
scripts/build-lolhtml.ps1
Normal file → Executable file
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euxo pipefail
|
||||
set -exo pipefail
|
||||
source $(dirname -- "${BASH_SOURCE[0]}")/env.sh
|
||||
|
||||
cd $BUN_DEPS_DIR/lol-html/c-api
|
||||
|
||||
0
scripts/build-lshpack.ps1
Normal file → Executable file
0
scripts/build-lshpack.ps1
Normal file → Executable file
2
scripts/build-lshpack.sh
Normal file → Executable file
2
scripts/build-lshpack.sh
Normal file → Executable file
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euxo pipefail
|
||||
set -exo pipefail
|
||||
source $(dirname -- "${BASH_SOURCE[0]}")/env.sh
|
||||
|
||||
mkdir -p $BUN_DEPS_OUT_DIR
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euxo pipefail
|
||||
set -exo pipefail
|
||||
source "$(dirname -- "${BASH_SOURCE[0]}")/env.sh"
|
||||
|
||||
MIMALLOC_OVERRIDE_FLAG=${MIMALLOC_OVERRIDE_FLAG:-}
|
||||
|
||||
0
scripts/build-mimalloc.ps1
Normal file → Executable file
0
scripts/build-mimalloc.ps1
Normal file → Executable file
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euxo pipefail
|
||||
set -exo pipefail
|
||||
source "$(dirname -- "${BASH_SOURCE[0]}")/env.sh"
|
||||
|
||||
MIMALLOC_OVERRIDE_FLAG=${MIMALLOC_OVERRIDE_FLAG:-}
|
||||
|
||||
0
scripts/build-tinycc.ps1
Normal file → Executable file
0
scripts/build-tinycc.ps1
Normal file → Executable file
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euxo pipefail
|
||||
set -exo pipefail
|
||||
source $(dirname -- "${BASH_SOURCE[0]}")/env.sh
|
||||
|
||||
mkdir -p $BUN_DEPS_OUT_DIR
|
||||
|
||||
0
scripts/build-zlib.ps1
Normal file → Executable file
0
scripts/build-zlib.ps1
Normal file → Executable file
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euxo pipefail
|
||||
set -exo pipefail
|
||||
source $(dirname -- "${BASH_SOURCE[0]}")/env.sh
|
||||
|
||||
mkdir -p $BUN_DEPS_OUT_DIR
|
||||
|
||||
0
scripts/build-zstd.ps1
Normal file → Executable file
0
scripts/build-zstd.ps1
Normal file → Executable file
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euxo pipefail
|
||||
set -exo pipefail
|
||||
source $(dirname -- "${BASH_SOURCE[0]}")/env.sh
|
||||
|
||||
mkdir -p $BUN_DEPS_OUT_DIR
|
||||
|
||||
0
scripts/build.ps1
Normal file → Executable file
0
scripts/build.ps1
Normal file → Executable file
59
scripts/buildkite-link-bun.ps1
Executable file
59
scripts/buildkite-link-bun.ps1
Executable file
@@ -0,0 +1,59 @@
|
||||
param (
|
||||
[switch] $Baseline = $False,
|
||||
[switch] $Fast = $False
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop' # Setting strict mode, similar to 'set -euo pipefail' in bash
|
||||
|
||||
$Target = If ($Baseline) { "windows-x64-baseline" } Else { "windows-x64" }
|
||||
$Tag = "bun-$Target"
|
||||
$TagSuffix = If ($Baseline) { "-Baseline" } Else { "" }
|
||||
$UseBaselineBuild = If ($Baseline) { "ON" } Else { "OFF" }
|
||||
$UseLto = If ($Fast) { "OFF" } Else { "ON" }
|
||||
|
||||
.\scripts\env.ps1 $TagSuffix
|
||||
|
||||
mkdir -Force build
|
||||
buildkite-agent artifact download "**" build --step "${Target}-build-zig"
|
||||
buildkite-agent artifact download "**" build --step "${Target}-build-cpp"
|
||||
buildkite-agent artifact download "**" build --step "${Target}-build-deps"
|
||||
mv -Force -ErrorAction SilentlyContinue build\build\bun-deps\* build\bun-deps
|
||||
mv -Force -ErrorAction SilentlyContinue build\build\* build
|
||||
|
||||
Set-Location build
|
||||
$CANARY_REVISION = 0
|
||||
cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release `
|
||||
-DNO_CODEGEN=1 `
|
||||
-DNO_CONFIGURE_DEPENDS=1 `
|
||||
"-DCPU_TARGET=${CPU_TARGET}" `
|
||||
"-DCANARY=${CANARY_REVISION}" `
|
||||
-DBUN_LINK_ONLY=1 `
|
||||
"-DUSE_BASELINE_BUILD=${UseBaselineBuild}" `
|
||||
"-DUSE_LTO=${UseLto}" `
|
||||
"-DBUN_DEPS_OUT_DIR=$(Resolve-Path bun-deps)" `
|
||||
"-DBUN_CPP_ARCHIVE=$(Resolve-Path bun-cpp-objects.a)" `
|
||||
"-DBUN_ZIG_OBJ_DIR=$(Resolve-Path .)" `
|
||||
"$Flags"
|
||||
if ($LASTEXITCODE -ne 0) { throw "CMake configuration failed" }
|
||||
|
||||
ninja -v
|
||||
if ($LASTEXITCODE -ne 0) { throw "Link failed!" }
|
||||
|
||||
ls
|
||||
if ($UseLto -eq "OFF") {
|
||||
$Tag = "$Tag-nolto"
|
||||
}
|
||||
|
||||
Set-Location ..
|
||||
$Dist = mkdir -Force "${Tag}"
|
||||
cp -r build\bun.exe "$Dist\bun.exe"
|
||||
Compress-Archive -Force "$Dist" "${Dist}.zip"
|
||||
$Dist = "$Dist-profile"
|
||||
MkDir -Force "$Dist"
|
||||
cp -r build\bun.exe "$Dist\bun.exe"
|
||||
cp -r build\bun.pdb "$Dist\bun.pdb"
|
||||
Compress-Archive -Force "$Dist" "$Dist.zip"
|
||||
|
||||
$env:BUN_GARBAGE_COLLECTOR_LEVEL = "1"
|
||||
$env:BUN_FEATURE_FLAG_INTERNAL_FOR_TESTING = "1"
|
||||
.\build\bun.exe --print "JSON.stringify(require('bun:internal-for-testing').crash_handler.getFeatureData())" > .\features.json
|
||||
80
scripts/buildkite-link-bun.sh
Executable file
80
scripts/buildkite-link-bun.sh
Executable file
@@ -0,0 +1,80 @@
|
||||
#!/usr/bin/env bash
|
||||
set -exo pipefail
|
||||
source $(dirname -- "${BASH_SOURCE[0]}")/env.sh
|
||||
|
||||
export USE_LTO="${USE_LTO:-ON}"
|
||||
case "$(uname -m)" in
|
||||
aarch64|arm64)
|
||||
export CPU_TARGET="${CPU_TARGET:-native}"
|
||||
;;
|
||||
*)
|
||||
export CPU_TARGET="${CPU_TARGET:-haswell}"
|
||||
;;
|
||||
esac
|
||||
|
||||
export TAG=""
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--tag)
|
||||
export TAG="$2"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
--fast|--no-lto)
|
||||
export USE_LTO="OFF"
|
||||
shift
|
||||
;;
|
||||
--baseline)
|
||||
export CPU_TARGET="nehalem"
|
||||
shift
|
||||
;;
|
||||
--cpu)
|
||||
export CPU_TARGET="$2"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
*|-*|--*)
|
||||
echo "Unknown option $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ -z "$TAG" ]]; then
|
||||
echo "--tag <name> is required"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm -rf release
|
||||
mkdir -p release
|
||||
buildkite-agent artifact download '**' release --step $TAG-build-deps
|
||||
buildkite-agent artifact download '**' release --step $TAG-build-zig
|
||||
buildkite-agent artifact download '**' release --step $TAG-build-cpp
|
||||
|
||||
cd release
|
||||
cmake .. \
|
||||
-GNinja \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCPU_TARGET=${CPU_TARGET} \
|
||||
-DUSE_LTO=${USE_LTO} \
|
||||
-DBUN_LINK_ONLY=1 \
|
||||
-DBUN_ZIG_OBJ_DIR="$(pwd)/build" \
|
||||
-DBUN_CPP_ARCHIVE="$(pwd)/build/bun-cpp-objects.a" \
|
||||
-DBUN_DEPS_OUT_DIR="$(pwd)/build/bun-deps" \
|
||||
-DNO_CONFIGURE_DEPENDS=1
|
||||
ninja -v
|
||||
|
||||
if [[ "${USE_LTO}" == "OFF" ]]; then
|
||||
TAG="${TAG}-nolto"
|
||||
fi
|
||||
|
||||
chmod +x bun-profile bun
|
||||
mkdir -p bun-$TAG-profile/ bun-$TAG/
|
||||
mv bun-profile bun-$TAG-profile/bun-profile
|
||||
mv bun bun-$TAG/bun
|
||||
zip -r bun-$TAG-profile.zip bun-$TAG-profile
|
||||
zip -r bun-$TAG.zip bun-$TAG
|
||||
|
||||
cd ..
|
||||
mv release/bun-$TAG.zip bun-$TAG.zip
|
||||
mv release/bun-$TAG-profile.zip bun-$TAG-profile.zip
|
||||
0
scripts/clean-dependencies.ps1
Normal file → Executable file
0
scripts/clean-dependencies.ps1
Normal file → Executable file
0
scripts/download-webkit.ps1
Normal file → Executable file
0
scripts/download-webkit.ps1
Normal file → Executable file
0
scripts/download-webkit.sh
Normal file → Executable file
0
scripts/download-webkit.sh
Normal file → Executable file
2
scripts/download-zig.ps1
Normal file → Executable file
2
scripts/download-zig.ps1
Normal file → Executable file
@@ -23,7 +23,7 @@ try {
|
||||
if (!(Test-Path $TarPath)) {
|
||||
try {
|
||||
Write-Host "-- Downloading Zig"
|
||||
Invoke-WebRequest $Url -OutFile $TarPath
|
||||
Invoke-RestMethod $Url -OutFile $TarPath
|
||||
} catch {
|
||||
Write-Error "Failed to fetch Zig from: $Url"
|
||||
throw $_
|
||||
|
||||
0
scripts/download-zls.ps1
Normal file → Executable file
0
scripts/download-zls.ps1
Normal file → Executable file
31
scripts/env.ps1
Normal file → Executable file
31
scripts/env.ps1
Normal file → Executable file
@@ -20,8 +20,12 @@ if ($env:VSINSTALLDIR -eq $null) {
|
||||
}
|
||||
$vsDir = (& $vswhere -prerelease -latest -property installationPath)
|
||||
if ($vsDir -eq $null) {
|
||||
throw "Visual Studio directory not found."
|
||||
}
|
||||
$vsDir = Get-ChildItem -Path "C:\Program Files\Microsoft Visual Studio\2022" -Directory
|
||||
if ($vsDir -eq $null) {
|
||||
throw "Visual Studio directory not found."
|
||||
}
|
||||
$vsDir = $vsDir.FullName;
|
||||
}
|
||||
Push-Location $vsDir
|
||||
try {
|
||||
Import-Module 'C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\Common7\Tools\Microsoft.VisualStudio.DevShell.dll'
|
||||
@@ -41,19 +45,20 @@ $ENV:BUN_DEV_ENV_SET = "Baseline=$Baseline";
|
||||
|
||||
$BUN_BASE_DIR = if ($env:BUN_BASE_DIR) { $env:BUN_BASE_DIR } else { Join-Path $ScriptDir '..' }
|
||||
$BUN_DEPS_DIR = if ($env:BUN_DEPS_DIR) { $env:BUN_DEPS_DIR } else { Join-Path $BUN_BASE_DIR 'src\deps' }
|
||||
$BUN_DEPS_OUT_DIR = if ($env:BUN_DEPS_OUT_DIR) { $env:BUN_DEPS_OUT_DIR } else { $BUN_DEPS_DIR }
|
||||
$BUN_DEPS_OUT_DIR = if ($env:BUN_DEPS_OUT_DIR) { $env:BUN_DEPS_OUT_DIR } else { Join-Path $BUN_BASE_DIR 'build\bun-deps' }
|
||||
|
||||
$CPUS = if ($env:CPUS) { $env:CPUS } else { (Get-CimInstance -Class Win32_Processor).NumberOfCores }
|
||||
|
||||
$CC = "clang-cl"
|
||||
$CXX = "clang-cl"
|
||||
|
||||
$CFLAGS = '/O2'
|
||||
# $CFLAGS = '/O2 /MT'
|
||||
$CXXFLAGS = '/O2'
|
||||
# $CXXFLAGS = '/O2 /MT'
|
||||
$CFLAGS = '/O2 /Zi'
|
||||
# $CFLAGS = '/O2 /Z7 /MT'
|
||||
$CXXFLAGS = '/O2 /Zi'
|
||||
# $CXXFLAGS = '/O2 /Z7 /MT'
|
||||
|
||||
$CPU_NAME = if ($Baseline) { "nehalem" } else { "haswell" };
|
||||
$env:CPU_TARGET = $CPU_NAME
|
||||
|
||||
$CFLAGS += " -march=${CPU_NAME}"
|
||||
$CXXFLAGS += " -march=${CPU_NAME}"
|
||||
@@ -76,6 +81,16 @@ if ($Baseline) {
|
||||
$CMAKE_FLAGS += "-DUSE_BASELINE_BUILD=ON"
|
||||
}
|
||||
|
||||
if (Get-Command sccache -ErrorAction SilentlyContinue) {
|
||||
# Continue with local compiler if sccache has an error
|
||||
$env:SCCACHE_IGNORE_SERVER_IO_ERROR = "1"
|
||||
|
||||
$CMAKE_FLAGS += "-DCMAKE_C_COMPILER_LAUNCHER=sccache"
|
||||
$CMAKE_FLAGS += "-DCMAKE_CXX_COMPILER_LAUNCHER=sccache"
|
||||
$CMAKE_FLAGS += "-DCMAKE_MSVC_DEBUG_INFORMATION_FORMAT=Embedded"
|
||||
$CMAKE_FLAGS += "-DCMAKE_POLICY_CMP0141=NEW"
|
||||
}
|
||||
|
||||
$null = New-Item -ItemType Directory -Force -Path $BUN_DEPS_OUT_DIR
|
||||
|
||||
function Run() {
|
||||
@@ -99,4 +114,4 @@ function Run() {
|
||||
if ($result -ne 0) {
|
||||
throw "$command $commandArgs exited with code $result."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Hack for Buildkite sometimes not having the right path
|
||||
if [[ "${CI:-}" == "1" || "${CI:-}" == "true" ]]; then
|
||||
if [ -f ~/.bashrc ]; then
|
||||
source ~/.bashrc
|
||||
fi
|
||||
fi
|
||||
|
||||
# this is the environment script for building bun's dependencies
|
||||
# it sets c compiler and flags
|
||||
export SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
|
||||
export BUN_BASE_DIR=${BUN_BASE_DIR:-$(cd $SCRIPT_DIR && cd .. && pwd)}
|
||||
export BUN_DEPS_DIR=${BUN_DEPS_DIR:-$BUN_BASE_DIR/src/deps/}
|
||||
export BUN_DEPS_OUT_DIR=${BUN_DEPS_OUT_DIR:-$BUN_BASE_DIR/src/deps/}
|
||||
export BUN_DEPS_DIR=${BUN_DEPS_DIR:-$BUN_BASE_DIR/src/deps}
|
||||
export BUN_DEPS_OUT_DIR=${BUN_DEPS_OUT_DIR:-$BUN_BASE_DIR/build/bun-deps}
|
||||
|
||||
# Silence a perl script warning
|
||||
export LC_CTYPE="en_US.UTF-8"
|
||||
@@ -23,20 +31,28 @@ export CFLAGS='-O3 -fno-exceptions -fvisibility=hidden -fvisibility-inlines-hidd
|
||||
export CXXFLAGS='-O3 -fno-exceptions -fno-rtti -fvisibility=hidden -fvisibility-inlines-hidden -mno-omit-leaf-frame-pointer -fno-omit-frame-pointer'
|
||||
|
||||
export CMAKE_FLAGS=(
|
||||
-DCMAKE_C_COMPILER="${CC}"
|
||||
-DCMAKE_CXX_COMPILER="${CXX}"
|
||||
-DCMAKE_C_FLAGS="$CFLAGS"
|
||||
-DCMAKE_CXX_FLAGS="$CXXFLAGS"
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
-DCMAKE_CXX_STANDARD=20
|
||||
-DCMAKE_C_STANDARD=17
|
||||
-DCMAKE_CXX_STANDARD_REQUIRED=ON
|
||||
-DCMAKE_C_STANDARD_REQUIRED=ON
|
||||
-DCMAKE_C_COMPILER="${CC}"
|
||||
-DCMAKE_CXX_COMPILER="${CXX}"
|
||||
-DCMAKE_C_FLAGS="$CFLAGS"
|
||||
-DCMAKE_CXX_FLAGS="$CXXFLAGS"
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
-DCMAKE_CXX_STANDARD=20
|
||||
-DCMAKE_C_STANDARD=17
|
||||
-DCMAKE_CXX_STANDARD_REQUIRED=ON
|
||||
-DCMAKE_C_STANDARD_REQUIRED=ON
|
||||
)
|
||||
|
||||
CCACHE=$(which ccache || which sccache || echo "")
|
||||
if [ -n "$CCACHE" ]; then
|
||||
CMAKE_FLAGS+=(
|
||||
-DCMAKE_C_COMPILER_LAUNCHER="$CCACHE"
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER="$CCACHE"
|
||||
)
|
||||
fi
|
||||
|
||||
if [[ $(uname -s) == 'Linux' ]]; then
|
||||
# Ensure we always use -std=gnu++20 on Linux
|
||||
export CMAKE_FLAGS+=(-DCMAKE_CXX_EXTENSIONS=ON)
|
||||
# Ensure we always use -std=gnu++20 on Linux
|
||||
CMAKE_FLAGS+=(-DCMAKE_CXX_EXTENSIONS=ON)
|
||||
fi
|
||||
|
||||
if [[ $(uname -s) == 'Darwin' ]]; then
|
||||
@@ -52,7 +68,10 @@ mkdir -p $BUN_DEPS_OUT_DIR
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
echo "C Compiler: ${CC}"
|
||||
echo "C++ Compiler: ${CXX}"
|
||||
if [ -n "$CCACHE" ]; then
|
||||
echo "Ccache: ${CCACHE}"
|
||||
fi
|
||||
if [[ $(uname -s) == 'Darwin' ]]; then
|
||||
echo "OSX Deployment Target: ${CMAKE_OSX_DEPLOYMENT_TARGET}"
|
||||
echo "OSX Deployment Target: ${CMAKE_OSX_DEPLOYMENT_TARGET}"
|
||||
fi
|
||||
fi
|
||||
|
||||
300
scripts/experimental-build.mjs
Executable file
300
scripts/experimental-build.mjs
Executable file
@@ -0,0 +1,300 @@
|
||||
#! /usr/bin/env node
|
||||
|
||||
import {} from "node:fs/promises";
|
||||
import { spawn, spawnSync } from "node:child_process";
|
||||
import { copyFileSync, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
|
||||
import { basename, dirname, join } from "node:path";
|
||||
import { tmpdir } from "node:os";
|
||||
|
||||
const projectPath = dirname(import.meta.dirname);
|
||||
const vendorPath = process.env.BUN_VENDOR_PATH || join(projectPath, "vendor");
|
||||
|
||||
const isWindows = process.platform === "win32";
|
||||
const isMacOS = process.platform === "darwin";
|
||||
const isLinux = process.platform === "linux";
|
||||
|
||||
const spawnSyncTimeout = 1000 * 60;
|
||||
const spawnTimeout = 1000 * 60 * 3;
|
||||
|
||||
async function spawnSafe(command, args, options = {}) {
|
||||
const result = new Promise((resolve, reject) => {
|
||||
let stdout = "";
|
||||
let stderr = "";
|
||||
let subprocess;
|
||||
try {
|
||||
subprocess = spawn(command, args, {
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
timeout: spawnTimeout,
|
||||
...options,
|
||||
});
|
||||
subprocess.on("error", reject);
|
||||
subprocess.on("exit", (exitCode, signalCode) => {
|
||||
if (exitCode !== 0 || signalCode) {
|
||||
const reason = signalCode || `code ${exitCode}`;
|
||||
const cause = stderr || stdout;
|
||||
reject(new Error(`Process exited with ${reason}`, { cause }));
|
||||
} else {
|
||||
resolve({ exitCode, signalCode, stdout, stderr });
|
||||
}
|
||||
});
|
||||
subprocess?.stdout?.on("data", chunk => {
|
||||
process.stdout.write(chunk);
|
||||
stdout += chunk.toString("utf-8");
|
||||
});
|
||||
subprocess?.stderr?.on("data", chunk => {
|
||||
process.stderr.write(chunk);
|
||||
stderr += chunk.toString("utf-8");
|
||||
});
|
||||
} catch (cause) {
|
||||
reject(cause);
|
||||
}
|
||||
});
|
||||
try {
|
||||
return await result;
|
||||
} catch (cause) {
|
||||
if (options.throwOnError === false) {
|
||||
return;
|
||||
}
|
||||
const description = `${command} ${args.join(" ")}`;
|
||||
throw new Error(`Command failed: ${description}`, { cause });
|
||||
}
|
||||
}
|
||||
|
||||
function spawnSyncSafe(command, args, options = {}) {
|
||||
try {
|
||||
const { error, status, signal, stdout, stderr } = spawnSync(command, args, {
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
encoding: "utf-8",
|
||||
timeout: spawnSyncTimeout,
|
||||
...options,
|
||||
});
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
if (signal || status !== 0) {
|
||||
const reason = signal || `code ${status}`;
|
||||
const cause = stderr || stdout;
|
||||
throw new Error(`Process exited with ${reason}`, { cause });
|
||||
}
|
||||
return stdout;
|
||||
} catch (cause) {
|
||||
if (options.throwOnError === false) {
|
||||
return;
|
||||
}
|
||||
const description = `${command} ${args.join(" ")}`;
|
||||
throw new Error(`Command failed: ${description}`, { cause });
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchSafe(url, options = {}) {
|
||||
let response;
|
||||
try {
|
||||
response = await fetch(url, options);
|
||||
if (!response.ok) {
|
||||
const { status, statusText } = response;
|
||||
const body = await response.text();
|
||||
throw new Error(`${status} ${statusText}`, { cause: body });
|
||||
}
|
||||
switch (options.format) {
|
||||
case "json":
|
||||
return await response.json();
|
||||
case "text":
|
||||
return await response.text();
|
||||
case "bytes":
|
||||
return new Uint8Array(await response.arrayBuffer());
|
||||
default:
|
||||
return response;
|
||||
}
|
||||
} catch (cause) {
|
||||
if (options.throwOnError === false) {
|
||||
return response;
|
||||
}
|
||||
throw new Error(`Fetch failed: ${url}`, { cause });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} command
|
||||
* @param {string} [path]
|
||||
* @returns {string | undefined}
|
||||
*/
|
||||
function which(command, path) {
|
||||
const cmd = isWindows ? "where" : "which";
|
||||
const result = spawnSyncSafe(cmd, [command], {
|
||||
throwOnError: false,
|
||||
env: {
|
||||
PATH: path || process.env.PATH,
|
||||
},
|
||||
});
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
if (isWindows) {
|
||||
// On Windows, multiple paths can be returned from `where`.
|
||||
for (const line of result.split("\r\n")) {
|
||||
return line;
|
||||
}
|
||||
}
|
||||
return result.trimEnd();
|
||||
}
|
||||
|
||||
function getZigTarget(os = process.platform, arch = process.arch) {
|
||||
if (arch === "x64") {
|
||||
if (os === "linux") return "linux-x86_64";
|
||||
if (os === "darwin") return "macos-x86_64";
|
||||
if (os === "win32") return "windows-x86_64";
|
||||
}
|
||||
if (arch === "arm64") {
|
||||
if (os === "linux") return "linux-aarch64";
|
||||
if (os === "darwin") return "macos-aarch64";
|
||||
}
|
||||
throw new Error(`Unsupported zig target: os=${os}, arch=${arch}`);
|
||||
}
|
||||
|
||||
function getRecommendedZigVersion() {
|
||||
const scriptPath = join(projectPath, "build.zig");
|
||||
try {
|
||||
const scriptContent = readFileSync(scriptPath, "utf-8");
|
||||
const match = scriptContent.match(/recommended_zig_version = "([^"]+)"/);
|
||||
if (!match) {
|
||||
throw new Error("File does not contain string: 'recommended_zig_version'");
|
||||
}
|
||||
return match[1];
|
||||
} catch (cause) {
|
||||
throw new Error("Failed to find recommended Zig version", { cause });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
async function getLatestZigVersion() {
|
||||
try {
|
||||
const response = await fetchSafe("https://ziglang.org/download/index.json", { format: "json" });
|
||||
const { master } = response;
|
||||
const { version } = master;
|
||||
return version;
|
||||
} catch (cause) {
|
||||
throw new Error("Failed to get latest Zig version", { cause });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} execPath
|
||||
* @returns {string | undefined}
|
||||
*/
|
||||
function getVersion(execPath) {
|
||||
const args = /(?:zig)(?:\.exe)?/i.test(execPath) ? ["version"] : ["--version"];
|
||||
const result = spawnSyncSafe(execPath, args, { throwOnError: false });
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
return result.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
function getTmpdir() {
|
||||
if (isMacOS && existsSync("/tmp")) {
|
||||
return "/tmp";
|
||||
}
|
||||
return tmpdir();
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
function mkTmpdir() {
|
||||
return mkdtempSync(join(getTmpdir(), "bun-"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} url
|
||||
* @param {string} [path]
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
async function downloadFile(url, path) {
|
||||
const outPath = path || join(mkTmpdir(), basename(url));
|
||||
const bytes = await fetchSafe(url, { format: "bytes" });
|
||||
mkdirSync(dirname(outPath), { recursive: true });
|
||||
writeFileSync(outPath, bytes);
|
||||
return outPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} tarPath
|
||||
* @param {string} [path]
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
async function extractFile(tarPath, path) {
|
||||
const outPath = path || join(mkTmpdir(), basename(tarPath));
|
||||
mkdirSync(outPath, { recursive: true });
|
||||
await spawnSafe("tar", ["-xf", tarPath, "-C", outPath, "--strip-components=1"]);
|
||||
return outPath;
|
||||
}
|
||||
|
||||
const dependencies = [
|
||||
{
|
||||
name: "zig",
|
||||
version: getRecommendedZigVersion(),
|
||||
download: downloadZig,
|
||||
},
|
||||
];
|
||||
|
||||
async function getDependencyPath(name) {
|
||||
let dependency;
|
||||
for (const entry of dependencies) {
|
||||
if (name === entry.name) {
|
||||
dependency = entry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!dependency) {
|
||||
throw new Error(`Unknown dependency: ${name}`);
|
||||
}
|
||||
const { version, download } = dependency;
|
||||
mkdirSync(vendorPath, { recursive: true });
|
||||
for (const path of readdirSync(vendorPath)) {
|
||||
if (!path.startsWith(name)) {
|
||||
continue;
|
||||
}
|
||||
const dependencyPath = join(vendorPath, path);
|
||||
const dependencyVersion = getVersion(dependencyPath);
|
||||
if (dependencyVersion === version) {
|
||||
return dependencyPath;
|
||||
}
|
||||
}
|
||||
if (!download) {
|
||||
throw new Error(`Dependency not found: ${name}`);
|
||||
}
|
||||
return await download(version);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} [version]
|
||||
*/
|
||||
async function downloadZig(version) {
|
||||
const target = getZigTarget();
|
||||
const expectedVersion = version || getRecommendedZigVersion();
|
||||
const url = `https://ziglang.org/builds/zig-${target}-${expectedVersion}.tar.xz`;
|
||||
const tarPath = await downloadFile(url);
|
||||
const extractedPath = await extractFile(tarPath);
|
||||
const zigPath = join(extractedPath, exePath("zig"));
|
||||
const actualVersion = getVersion(zigPath);
|
||||
const outPath = join(vendorPath, exePath(`zig-${actualVersion}`));
|
||||
mkdirSync(dirname(outPath), { recursive: true });
|
||||
copyFileSync(zigPath, outPath);
|
||||
return outPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} path
|
||||
* @returns {string}
|
||||
*/
|
||||
function exePath(path) {
|
||||
return isWindows ? `${path}.exe` : path;
|
||||
}
|
||||
|
||||
const execPath = await getDependencyPath("zig");
|
||||
console.log(execPath);
|
||||
@@ -2,7 +2,7 @@
|
||||
# this script is the magic script to configure your devenv for making a patch to WebKit
|
||||
# once you are done with the patch you can run this again with --undo
|
||||
# you can also run this with --danger-reset to force reset the submodule (danger)
|
||||
set -euo pipefail
|
||||
set -exo pipefail
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
|
||||
0
scripts/internal-test.ps1
Normal file → Executable file
0
scripts/internal-test.ps1
Normal file → Executable file
0
scripts/make-old-js.ps1
Normal file → Executable file
0
scripts/make-old-js.ps1
Normal file → Executable file
1682
scripts/runner.node.mjs
Executable file
1682
scripts/runner.node.mjs
Executable file
File diff suppressed because it is too large
Load Diff
0
scripts/set-webkit-submodule-to-cmake.ps1
Normal file → Executable file
0
scripts/set-webkit-submodule-to-cmake.ps1
Normal file → Executable file
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
set -exo pipefail
|
||||
|
||||
cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.."
|
||||
|
||||
|
||||
0
scripts/setup.ps1
Normal file → Executable file
0
scripts/setup.ps1
Normal file → Executable file
@@ -10,5 +10,5 @@ if ! [ "$1" == '--webkit' ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
set -euxo pipefail
|
||||
set -exo pipefail
|
||||
git submodule update --init --recursive --progress --depth=1 --checkout $NAMES
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -euxo pipefail
|
||||
set -exo pipefail
|
||||
|
||||
WEBKIT_VERSION=$(git rev-parse HEAD:./src/bun.js/WebKit)
|
||||
MIMALLOC_VERSION=$(git rev-parse HEAD:./src/deps/mimalloc)
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
// @ts-nocheck
|
||||
import path from "path";
|
||||
import type { Field, ClassDefinition } from "./class-definitions";
|
||||
import { writeIfNotChanged } from "./helpers";
|
||||
import { camelCase, pascalCase } from "change-case";
|
||||
import { writeIfNotChanged, camelCase, pascalCase } from "./helpers";
|
||||
|
||||
if (process.env.BUN_SILENT === "1") {
|
||||
console.log = () => {};
|
||||
|
||||
@@ -105,3 +105,13 @@ export function pathToUpperSnakeCase(filepath: string) {
|
||||
.join("_")
|
||||
.toUpperCase();
|
||||
}
|
||||
|
||||
export function camelCase(string: string) {
|
||||
return string
|
||||
.split(/[\s_]/)
|
||||
.map((e, i) => (i ? e.charAt(0).toUpperCase() + e.slice(1).toLowerCase() : e.toLowerCase()));
|
||||
}
|
||||
|
||||
export function pascalCase(string: string) {
|
||||
return string.split(/[\s_]/).map((e, i) => (i ? e.charAt(0).toUpperCase() + e.slice(1) : e.toLowerCase()));
|
||||
}
|
||||
|
||||
BIN
test/bun.lockb
BIN
test/bun.lockb
Binary file not shown.
@@ -79,7 +79,7 @@ describe("Bun.build", () => {
|
||||
test("rebuilding busts the directory entries cache", () => {
|
||||
Bun.gc(true);
|
||||
const { exitCode, stderr } = Bun.spawnSync({
|
||||
cmd: [bunExe(), join(import.meta.dir, "bundler-reloader-script.ts")],
|
||||
cmd: [bunExe(), join(import.meta.dir, "fixtures", "bundler-reloader-script.ts")],
|
||||
env: bunEnv,
|
||||
stderr: "pipe",
|
||||
stdout: "inherit",
|
||||
@@ -263,34 +263,6 @@ describe("Bun.build", () => {
|
||||
expect(x.logs[0].position).toBeTruthy();
|
||||
});
|
||||
|
||||
test("test bun target", async () => {
|
||||
const x = await Bun.build({
|
||||
entrypoints: [join(import.meta.dir, "./fixtures/trivial/bundle-ws.ts")],
|
||||
target: "bun",
|
||||
});
|
||||
expect(x.success).toBe(true);
|
||||
const [blob] = x.outputs;
|
||||
const content = await blob.text();
|
||||
|
||||
// use bun's ws
|
||||
expect(content).toContain('import {WebSocket} from "ws"');
|
||||
expect(content).not.toContain("var websocket = __toESM(require_websocket(), 1);");
|
||||
});
|
||||
|
||||
test("test node target, issue #3844", async () => {
|
||||
const x = await Bun.build({
|
||||
entrypoints: [join(import.meta.dir, "./fixtures/trivial/bundle-ws.ts")],
|
||||
target: "node",
|
||||
});
|
||||
expect(x.success).toBe(true);
|
||||
const [blob] = x.outputs;
|
||||
const content = await blob.text();
|
||||
|
||||
expect(content).not.toContain('import {WebSocket} from "ws"');
|
||||
// depends on the ws package in the test/node_modules.
|
||||
expect(content).toContain("var websocket = __toESM(require_websocket(), 1);");
|
||||
});
|
||||
|
||||
test("module() throws error", async () => {
|
||||
expect(() =>
|
||||
Bun.build({
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import assert from "assert";
|
||||
import dedent from "dedent";
|
||||
import { itBundled, testForFile } from "./expectBundled";
|
||||
var { describe, test, expect } = testForFile(import.meta.path);
|
||||
import { itBundled } from "./expectBundled";
|
||||
import { describe, expect } from "bun:test";
|
||||
|
||||
describe("bundler", () => {
|
||||
const nodePolyfillList = {
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import assert from "assert";
|
||||
import dedent from "dedent";
|
||||
import { ESBUILD, itBundled, testForFile } from "./expectBundled";
|
||||
import { itBundled } from "./expectBundled";
|
||||
import { Database } from "bun:sqlite";
|
||||
import { isWindows } from "harness";
|
||||
var { describe, test, expect } = testForFile(import.meta.path);
|
||||
import { describe, expect } from "bun:test";
|
||||
|
||||
describe("bundler", () => {
|
||||
itBundled("bun/embedded-sqlite-file", {
|
||||
@@ -82,9 +79,8 @@ describe("bundler", () => {
|
||||
run: {
|
||||
exitCode: 1,
|
||||
validate({ stderr }) {
|
||||
assert(
|
||||
stderr.startsWith(
|
||||
`1 | // this file has comments and weird whitespace, intentionally
|
||||
expect(stderr).toStartWith(
|
||||
`1 | // this file has comments and weird whitespace, intentionally
|
||||
2 | // to make it obvious if sourcemaps were generated and mapped properly
|
||||
3 | if (true) code();
|
||||
4 | function code() {
|
||||
@@ -92,7 +88,6 @@ describe("bundler", () => {
|
||||
6 | throw new
|
||||
^
|
||||
error: Hello World`,
|
||||
) || void console.error(stderr),
|
||||
);
|
||||
expect(stderr).toInclude("entry.ts:6:19");
|
||||
},
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import assert from "assert";
|
||||
import dedent from "dedent";
|
||||
import { itBundled, testForFile } from "./expectBundled";
|
||||
var { describe, test, expect } = testForFile(import.meta.path);
|
||||
import { itBundled } from "./expectBundled";
|
||||
import { describe, expect } from "bun:test";
|
||||
|
||||
const fakeReactNodeModules = {
|
||||
"/node_modules/react/index.js": /* js */ `
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import assert from "assert";
|
||||
import dedent from "dedent";
|
||||
import { ESBUILD, itBundled, testForFile } from "./expectBundled";
|
||||
import { itBundled } from "./expectBundled";
|
||||
import { Database } from "bun:sqlite";
|
||||
import { fillRepeating } from "harness";
|
||||
var { describe, test, expect } = testForFile(import.meta.path);
|
||||
import { describe } from "bun:test";
|
||||
|
||||
describe("bundler", () => {
|
||||
itBundled("compile/HelloWorld", {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import assert from "assert";
|
||||
import { itBundled, testForFile } from "./expectBundled";
|
||||
var { describe, test, expect } = testForFile(import.meta.path);
|
||||
import { itBundled } from "./expectBundled";
|
||||
import { describe } from "bun:test";
|
||||
|
||||
const reflectMetadata = `
|
||||
var Reflect2;
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import assert from "assert";
|
||||
import dedent from "dedent";
|
||||
import { sep, join } from "path";
|
||||
import { itBundled, testForFile } from "./expectBundled";
|
||||
var { describe, test, expect } = testForFile(import.meta.path);
|
||||
import { join } from "node:path";
|
||||
import { itBundled } from "./expectBundled";
|
||||
import { describe, expect } from "bun:test";
|
||||
|
||||
describe("bundler", () => {
|
||||
itBundled("edgecase/EmptyFile", {
|
||||
@@ -37,7 +35,7 @@ describe("bundler", () => {
|
||||
},
|
||||
target: "bun",
|
||||
run: {
|
||||
stdout: `a${sep}b`,
|
||||
stdout: join("a", "b"),
|
||||
},
|
||||
});
|
||||
itBundled("edgecase/ImportStarFunction", {
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import assert from "assert";
|
||||
import dedent from "dedent";
|
||||
import { BundlerTestInput, itBundled, testForFile } from "./expectBundled";
|
||||
var { describe, test, expect } = testForFile(import.meta.path);
|
||||
import { BundlerTestInput, itBundled } from "./expectBundled";
|
||||
import { describe, expect } from "bun:test";
|
||||
|
||||
const helpers = {
|
||||
"/node_modules/bun-test-helpers/index.js": /* js */ `
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { fileURLToPath, pathToFileURL } from "bun";
|
||||
import { itBundled, testForFile } from "./expectBundled";
|
||||
var { describe, test, expect } = testForFile(import.meta.path);
|
||||
import { fileURLToPath } from "bun";
|
||||
import { itBundled } from "./expectBundled";
|
||||
import { describe } from "bun:test";
|
||||
|
||||
describe("bundler", async () => {
|
||||
for (let target of ["bun", "node"] as const) {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import assert from "assert";
|
||||
import { itBundled, testForFile } from "./expectBundled";
|
||||
var { describe, test, expect } = testForFile(import.meta.path);
|
||||
import { itBundled } from "./expectBundled";
|
||||
import { describe, expect } from "bun:test";
|
||||
|
||||
describe("bundler", () => {
|
||||
itBundled("minify/TemplateStringFolding", {
|
||||
@@ -122,7 +121,7 @@ describe("bundler", () => {
|
||||
run: { stdout: "4 2 3\n4 5 3\n4 5 6" },
|
||||
onAfterBundle(api) {
|
||||
const code = api.readFile("/out.js");
|
||||
assert([...code.matchAll(/var /g)].length === 1, "expected only 1 variable declaration statement");
|
||||
expect([...code.matchAll(/var /g)]).toHaveLength(1);
|
||||
},
|
||||
});
|
||||
itBundled("minify/Infinity", {
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import assert from "assert";
|
||||
import dedent from "dedent";
|
||||
import { ESBUILD, itBundled, testForFile } from "./expectBundled";
|
||||
var { describe, test, expect } = testForFile(import.meta.path);
|
||||
import { ESBUILD, itBundled } from "./expectBundled";
|
||||
import { describe } from "bun:test";
|
||||
|
||||
describe("bundler", () => {
|
||||
itBundled("naming/EntryNamingCollission", {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { ESBUILD, itBundled, testForFile } from "./expectBundled";
|
||||
var { describe, test, expect } = testForFile(import.meta.path);
|
||||
import { itBundled } from "./expectBundled";
|
||||
import { describe } from "bun:test";
|
||||
import { isWindows } from "harness";
|
||||
|
||||
describe("bundler", () => {
|
||||
itBundled("npm/ReactSSR", {
|
||||
todo: process.platform === "win32", // TODO(@paperdave)
|
||||
todo: isWindows, // TODO(@paperdave)
|
||||
install: ["react@18.3.1", "react-dom@18.3.1"],
|
||||
files: {
|
||||
"/entry.tsx": /* tsx */ `
|
||||
@@ -25,14 +26,14 @@ describe("bundler", () => {
|
||||
</html>
|
||||
);
|
||||
|
||||
const port = 42001;
|
||||
const port = 0;
|
||||
using server = Bun.serve({
|
||||
port,
|
||||
async fetch(req) {
|
||||
return new Response(await renderToReadableStream(<App />), headers);
|
||||
},
|
||||
});
|
||||
const res = await fetch("http://localhost:" + port);
|
||||
const res = await fetch("http://localhost:" + server.port);
|
||||
if (res.status !== 200) throw "status error";
|
||||
console.log(await res.text());
|
||||
`,
|
||||
@@ -61,7 +62,7 @@ describe("bundler", () => {
|
||||
["react.development.js:696:''Component'", '1:7470:\'Component "%s"'],
|
||||
["entry.tsx:6:'\"Content-Type\"'", '1:221669:"Content-Type"'],
|
||||
["entry.tsx:11:'<html>'", "1:221925:void"],
|
||||
["entry.tsx:23:'await'", "1:222030:await"],
|
||||
["entry.tsx:23:'await'", "1:222026:await"],
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import assert from "assert";
|
||||
import dedent from "dedent";
|
||||
import path from "path";
|
||||
import { itBundled, testForFile } from "./expectBundled";
|
||||
var { describe, test, expect } = testForFile(import.meta.path);
|
||||
import { join, resolve, dirname } from "node:path";
|
||||
import { itBundled } from "./expectBundled";
|
||||
import { describe, expect } from "bun:test";
|
||||
|
||||
describe("bundler", () => {
|
||||
const loadFixture = {
|
||||
@@ -35,7 +33,7 @@ describe("bundler", () => {
|
||||
plugins(builder) {
|
||||
builder.onResolve({ filter: /\.magic$/ }, args => {
|
||||
return {
|
||||
path: path.resolve(path.dirname(args.importer), args.path.replace(/\.magic$/, ".ts")),
|
||||
path: resolve(dirname(args.importer), args.path.replace(/\.magic$/, ".ts")),
|
||||
};
|
||||
});
|
||||
},
|
||||
@@ -817,7 +815,7 @@ describe("bundler", () => {
|
||||
plugins(build) {
|
||||
const opts = (build as any).initialOptions;
|
||||
expect(opts.bundle).toEqual(true);
|
||||
expect(opts.entryPoints).toEqual([root + path.sep + "index.ts"]);
|
||||
expect(opts.entryPoints).toEqual([join(root, "index.ts")]);
|
||||
expect(opts.external).toEqual(["esbuild"]);
|
||||
expect(opts.format).toEqual(undefined);
|
||||
expect(opts.minify).toEqual(false);
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import assert from "assert";
|
||||
import dedent from "dedent";
|
||||
import { itBundled, testForFile } from "./expectBundled";
|
||||
var { describe, test, expect } = testForFile(import.meta.path);
|
||||
import { itBundled } from "./expectBundled";
|
||||
import { describe } from "bun:test";
|
||||
|
||||
describe("bundler", () => {
|
||||
// https://x.com/jeroendotdot/status/1740651288239460384?s=46&t=0Uhw6mmGT650_9M2pXUsCw
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import assert from "assert";
|
||||
import dedent from "dedent";
|
||||
import { itBundled, testForFile } from "./expectBundled";
|
||||
var { describe, test, expect } = testForFile(import.meta.path);
|
||||
import { itBundled, dedent } from "./expectBundled";
|
||||
import { describe } from "bun:test";
|
||||
|
||||
interface TemplateStringTest {
|
||||
expr: string;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { bunEnv, bunExe, tmpdirSync } from "harness";
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import fs from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import path from "node:path";
|
||||
|
||||
describe("bun build", () => {
|
||||
@@ -18,34 +17,34 @@ describe("bun build", () => {
|
||||
|
||||
test("generating a standalone binary in nested path, issue #4195", () => {
|
||||
function testCompile(outfile: string) {
|
||||
const { exitCode } = Bun.spawnSync({
|
||||
cmd: [
|
||||
bunExe(),
|
||||
"build",
|
||||
path.join(import.meta.dir, "./fixtures/trivial/index.js"),
|
||||
"--compile",
|
||||
"--outfile",
|
||||
outfile,
|
||||
],
|
||||
env: bunEnv,
|
||||
});
|
||||
expect(exitCode).toBe(0);
|
||||
expect([
|
||||
"build",
|
||||
path.join(import.meta.dir, "./fixtures/trivial/index.js"),
|
||||
"--compile",
|
||||
"--outfile",
|
||||
outfile,
|
||||
]).toRun();
|
||||
}
|
||||
function testExec(outfile: string) {
|
||||
const { exitCode } = Bun.spawnSync({
|
||||
const { exitCode, stderr } = Bun.spawnSync({
|
||||
cmd: [outfile],
|
||||
env: bunEnv,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
});
|
||||
expect(stderr.toString("utf8")).toBeEmpty();
|
||||
expect(exitCode).toBe(0);
|
||||
}
|
||||
const tmpdir = tmpdirSync();
|
||||
{
|
||||
const baseDir = `${tmpdir()}/bun-build-outfile-${Date.now()}`;
|
||||
const baseDir = `${tmpdir}/bun-build-outfile-${Date.now()}`;
|
||||
const outfile = path.join(baseDir, "index.exe");
|
||||
testCompile(outfile);
|
||||
testExec(outfile);
|
||||
fs.rmSync(baseDir, { recursive: true, force: true });
|
||||
}
|
||||
{
|
||||
const baseDir = `${tmpdir()}/bun-build-outfile2-${Date.now()}`;
|
||||
const baseDir = `${tmpdir}/bun-build-outfile2-${Date.now()}`;
|
||||
const outfile = path.join(baseDir, "b/u/n", "index.exe");
|
||||
testCompile(outfile);
|
||||
testExec(outfile);
|
||||
@@ -57,15 +56,12 @@ describe("bun build", () => {
|
||||
const tmp = tmpdirSync();
|
||||
const src = path.join(tmp, "index.js");
|
||||
fs.writeFileSync(src, '\ufeffconsole.log("hello world");', { encoding: "utf8" });
|
||||
const { exitCode } = Bun.spawnSync({
|
||||
cmd: [bunExe(), "build", src],
|
||||
env: bunEnv,
|
||||
});
|
||||
expect(exitCode).toBe(0);
|
||||
expect(["build", src]).toRun();
|
||||
});
|
||||
|
||||
test("__dirname and __filename are printed correctly", () => {
|
||||
const baseDir = `${tmpdir()}/bun-build-dirname-filename-${Date.now()}`;
|
||||
const tmpdir = tmpdirSync();
|
||||
const baseDir = `${tmpdir}/bun-build-dirname-filename-${Date.now()}`;
|
||||
fs.mkdirSync(baseDir, { recursive: true });
|
||||
fs.mkdirSync(path.join(baseDir, "我")), { recursive: true };
|
||||
fs.writeFileSync(path.join(baseDir, "我", "我.ts"), "console.log(__dirname); console.log(__filename);");
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,5 @@
|
||||
import assert from "assert";
|
||||
import dedent from "dedent";
|
||||
import { ESBUILD, itBundled, testForFile } from "../expectBundled";
|
||||
var { describe, test, expect } = testForFile(import.meta.path);
|
||||
import { itBundled, dedent } from "../expectBundled";
|
||||
import { describe, expect } from "bun:test";
|
||||
|
||||
// Tests ported from:
|
||||
// https://github.com/evanw/esbuild/blob/main/internal/bundler_tests/bundler_dce_test.go
|
||||
@@ -1019,8 +1017,8 @@ describe("bundler", () => {
|
||||
},
|
||||
onAfterBundle(api) {
|
||||
const code = api.readFile("/out.js");
|
||||
assert(!code.includes("_yes"), "should not contain any *_yes variables");
|
||||
assert(code.includes("var bare = foo(bar)"), "should contain `var bare = foo(bar)`");
|
||||
expect(code).not.toContain("_yes"); // should not contain any *_yes variables
|
||||
expect(code).toContain("var bare = foo(bar)"); // should contain `var bare = foo(bar)`
|
||||
const keep = [
|
||||
["at_no", true],
|
||||
["new_at_no", true],
|
||||
@@ -1048,8 +1046,8 @@ describe("bundler", () => {
|
||||
for (const [name, pureComment] of keep) {
|
||||
const regex = new RegExp(`${name}\\s*=[^\/\n]*(\\/\\*.*?\\*\\/)?`, "g");
|
||||
const match = regex.exec(code);
|
||||
assert(!!match, `should contain ${name}`);
|
||||
assert(pureComment ? !!match[1] : !match[1], `should contain a pure comment for ${name}`);
|
||||
expect(match).toBeTruthy(); // should contain ${name}
|
||||
expect(pureComment ? !!match[1] : !match[1]).toBeTruthy(); // should contain a pure comment for ${name}
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -1204,10 +1202,7 @@ describe("bundler", () => {
|
||||
dce: true,
|
||||
onAfterBundle(api) {
|
||||
const code = api.readFile("/out.js");
|
||||
assert(
|
||||
[...code.matchAll(/return/g)].length === 2,
|
||||
"should remove 3 trailing returns and the arrow function return",
|
||||
);
|
||||
expect([...code.matchAll(/return/g)]).toHaveLength(2); // should remove 3 trailing returns and the arrow function return
|
||||
},
|
||||
});
|
||||
itBundled("dce/ImportReExportOfNamespaceImport", {
|
||||
@@ -2813,7 +2808,7 @@ describe("bundler", () => {
|
||||
dce: true,
|
||||
onAfterBundle(api) {
|
||||
const code = api.readFile("/out.js");
|
||||
assert([...code.matchAll(/\[\.\.\.args\]/g)].length === 2, "spread should be preserved");
|
||||
expect([...code.matchAll(/\[\.\.\.args\]/g)]).toHaveLength(2); // spread should be preserved
|
||||
},
|
||||
});
|
||||
itBundled("dce/TopLevelFunctionInliningWithSpread", {
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import assert from "assert";
|
||||
import dedent from "dedent";
|
||||
|
||||
import { ESBUILD_PATH, RUN_UNCHECKED_TESTS, itBundled, testForFile } from "../expectBundled";
|
||||
import { ESBUILD_PATH, itBundled, dedent } from "../expectBundled";
|
||||
import { osSlashes } from "harness";
|
||||
var { describe, test, expect } = testForFile(import.meta.path);
|
||||
import { describe, expect } from "bun:test";
|
||||
|
||||
// Tests ported from:
|
||||
// https://github.com/evanw/esbuild/blob/main/internal/bundler_tests/bundler_default_test.go
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import assert from "assert";
|
||||
import dedent from "dedent";
|
||||
import { itBundled, testForFile } from "../expectBundled";
|
||||
var { describe, test, expect } = testForFile(import.meta.path);
|
||||
import { itBundled } from "../expectBundled";
|
||||
import { describe } from "bun:test";
|
||||
|
||||
// Tests ported from:
|
||||
// https://github.com/evanw/esbuild
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import assert from "assert";
|
||||
import { itBundled, testForFile } from "../expectBundled";
|
||||
var { describe, test, expect } = testForFile(import.meta.path);
|
||||
import { itBundled } from "../expectBundled";
|
||||
import { describe } from "bun:test";
|
||||
|
||||
// Tests ported from:
|
||||
// https://github.com/evanw/esbuild/blob/main/internal/bundler_tests/bundler_importstar_test.go
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import assert from "assert";
|
||||
import { itBundled, testForFile } from "../expectBundled";
|
||||
var { describe, test, expect } = testForFile(import.meta.path);
|
||||
import { itBundled } from "../expectBundled";
|
||||
import { describe } from "bun:test";
|
||||
|
||||
// Tests ported from:
|
||||
// https://github.com/evanw/esbuild/blob/main/internal/bundler_tests/bundler_importstar_ts_test.go
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import fs from "fs";
|
||||
import { itBundled, testForFile } from "../expectBundled";
|
||||
var { describe, test, expect } = testForFile(import.meta.path);
|
||||
import { itBundled } from "../expectBundled";
|
||||
import { describe } from "bun:test";
|
||||
|
||||
// Tests ported from:
|
||||
// https://github.com/evanw/esbuild/blob/main/internal/bundler_tests/bundler_loader_test.go
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import { itBundled, testForFile } from "../expectBundled";
|
||||
var { describe, test, expect } = testForFile(import.meta.path);
|
||||
import { itBundled } from "../expectBundled";
|
||||
import { describe } from "bun:test";
|
||||
|
||||
// Tests ported from:
|
||||
// https://github.com/evanw/esbuild/blob/main/internal/bundler_tests/bundler_lower_test.go
|
||||
|
||||
// For debug, all files are written to $TEMP/bun-bundle-tests/lower
|
||||
|
||||
describe("bundler", () => {
|
||||
return;
|
||||
describe.todo("bundler", () => {
|
||||
itBundled("lower/LowerOptionalCatchNameCollisionNoBundle", {
|
||||
// GENERATED
|
||||
files: {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { itBundled, testForFile } from "../expectBundled";
|
||||
var { describe, test, expect } = testForFile(import.meta.path);
|
||||
import { itBundled } from "../expectBundled";
|
||||
import { describe } from "bun:test";
|
||||
|
||||
// Tests ported from:
|
||||
// https://github.com/evanw/esbuild/blob/main/internal/bundler_tests/bundler_packagejson_test.go
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import assert from "assert";
|
||||
import { readdirSync } from "fs";
|
||||
import { itBundled, testForFile } from "../expectBundled";
|
||||
var { describe, test, expect } = testForFile(import.meta.path);
|
||||
import { describe, expect } from "bun:test";
|
||||
|
||||
// Tests ported from:
|
||||
// https://github.com/evanw/esbuild/blob/main/internal/bundler_tests/bundler_splitting_test.go
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import assert from "assert";
|
||||
import { itBundled, testForFile } from "../expectBundled";
|
||||
var { describe, test, expect } = testForFile(import.meta.path);
|
||||
import { itBundled } from "../expectBundled";
|
||||
import { describe, expect } from "bun:test";
|
||||
|
||||
// Tests ported from:
|
||||
// https://github.com/evanw/esbuild/blob/main/internal/bundler_tests/bundler_ts_test.go
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { itBundled, testForFile } from "../expectBundled";
|
||||
var { describe, test, expect } = testForFile(import.meta.path);
|
||||
import { itBundled } from "../expectBundled";
|
||||
import { describe, test } from "bun:test";
|
||||
|
||||
// Tests ported from:
|
||||
// https://github.com/evanw/esbuild/blob/main/internal/bundler_tests/bundler_tsconfig_test.go
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync, readdirSync, realpathSync } from "fs";
|
||||
import path from "path";
|
||||
import { bunEnv, bunExe, joinP } from "harness";
|
||||
import { bunEnv, bunExe, isDebug } from "harness";
|
||||
import { tmpdir } from "os";
|
||||
import { callerSourceOrigin } from "bun:jsc";
|
||||
import { BuildConfig, BunPlugin, fileURLToPath } from "bun";
|
||||
@@ -13,7 +13,7 @@ import * as esbuild from "esbuild";
|
||||
import { SourceMapConsumer } from "source-map";
|
||||
|
||||
/** Dedent module does a bit too much with their stuff. we will be much simpler */
|
||||
function dedent(str: string | TemplateStringsArray, ...args: any[]) {
|
||||
export function dedent(str: string | TemplateStringsArray, ...args: any[]) {
|
||||
// https://github.com/tc39/proposal-string-cooked#motivation
|
||||
let single_string = String.raw({ raw: str }, ...args);
|
||||
single_string = single_string.trim();
|
||||
@@ -564,7 +564,8 @@ function expectBundled(
|
||||
cwd: root,
|
||||
});
|
||||
if (!installProcess.success) {
|
||||
throw new Error("Failed to install dependencies");
|
||||
const reason = installProcess.signalCode || `code ${installProcess.exitCode}`;
|
||||
throw new Error(`Failed to install dependencies: ${reason}`);
|
||||
}
|
||||
}
|
||||
for (const [file, contents] of Object.entries(files)) {
|
||||
@@ -1546,7 +1547,7 @@ export function itBundled(
|
||||
id,
|
||||
() => expectBundled(id, opts as any),
|
||||
// sourcemap code is slow
|
||||
opts.snapshotSourceMap ? 20_000 : undefined,
|
||||
isDebug ? Infinity : opts.snapshotSourceMap ? 30_000 : undefined,
|
||||
);
|
||||
}
|
||||
return ref;
|
||||
|
||||
@@ -5,10 +5,12 @@
|
||||
// That way, if the developer changes a file, we will see the change.
|
||||
//
|
||||
// 2. Checks the file descriptor count to make sure we're not leaking any files between re-builds.
|
||||
|
||||
import { tmpdir } from "os";
|
||||
import { realpathSync, unlinkSync } from "fs";
|
||||
import { join } from "path";
|
||||
import { openSync, closeSync } from "fs";
|
||||
|
||||
const tmp = realpathSync(tmpdir());
|
||||
const input = join(tmp, "input.js");
|
||||
const mutate = join(tmp, "mutate.js");
|
||||
@@ -1,9 +1,12 @@
|
||||
import { spawn } from "bun";
|
||||
import { beforeEach, expect, it } from "bun:test";
|
||||
import { bunExe, bunEnv, tmpdirSync, isDebug, isWindows } from "harness";
|
||||
import { bunExe, bunEnv, tmpdirSync, isDebug } from "harness";
|
||||
import { cpSync, readFileSync, renameSync, rmSync, unlinkSync, writeFileSync, copyFileSync } from "fs";
|
||||
import { join } from "path";
|
||||
|
||||
const timeout = isDebug ? Infinity : 10_000;
|
||||
const longTimeout = isDebug ? Infinity : 30_000;
|
||||
|
||||
let hotRunnerRoot: string = "",
|
||||
cwd = "";
|
||||
beforeEach(() => {
|
||||
@@ -14,311 +17,331 @@ beforeEach(() => {
|
||||
cwd = hotPath;
|
||||
});
|
||||
|
||||
it("should hot reload when file is overwritten", async () => {
|
||||
const root = hotRunnerRoot;
|
||||
try {
|
||||
var runner = spawn({
|
||||
cmd: [bunExe(), "--hot", "run", root],
|
||||
env: bunEnv,
|
||||
cwd,
|
||||
stdout: "pipe",
|
||||
stderr: "inherit",
|
||||
stdin: "ignore",
|
||||
});
|
||||
it(
|
||||
"should hot reload when file is overwritten",
|
||||
async () => {
|
||||
const root = hotRunnerRoot;
|
||||
try {
|
||||
var runner = spawn({
|
||||
cmd: [bunExe(), "--hot", "run", root],
|
||||
env: bunEnv,
|
||||
cwd,
|
||||
stdout: "pipe",
|
||||
stderr: "inherit",
|
||||
stdin: "ignore",
|
||||
});
|
||||
|
||||
var reloadCounter = 0;
|
||||
var reloadCounter = 0;
|
||||
|
||||
async function onReload() {
|
||||
writeFileSync(root, readFileSync(root, "utf-8"));
|
||||
}
|
||||
|
||||
var str = "";
|
||||
for await (const line of runner.stdout) {
|
||||
str += new TextDecoder().decode(line);
|
||||
var any = false;
|
||||
if (!/\[#!root\].*[0-9]\n/g.test(str)) continue;
|
||||
|
||||
for (let line of str.split("\n")) {
|
||||
if (!line.includes("[#!root]")) continue;
|
||||
reloadCounter++;
|
||||
str = "";
|
||||
|
||||
if (reloadCounter === 3) {
|
||||
runner.unref();
|
||||
runner.kill();
|
||||
break;
|
||||
}
|
||||
|
||||
expect(line).toContain(`[#!root] Reloaded: ${reloadCounter}`);
|
||||
any = true;
|
||||
async function onReload() {
|
||||
writeFileSync(root, readFileSync(root, "utf-8"));
|
||||
}
|
||||
|
||||
if (any) await onReload();
|
||||
}
|
||||
var str = "";
|
||||
for await (const line of runner.stdout) {
|
||||
str += new TextDecoder().decode(line);
|
||||
var any = false;
|
||||
if (!/\[#!root\].*[0-9]\n/g.test(str)) continue;
|
||||
|
||||
expect(reloadCounter).toBe(3);
|
||||
} finally {
|
||||
// @ts-ignore
|
||||
runner?.unref?.();
|
||||
// @ts-ignore
|
||||
runner?.kill?.(9);
|
||||
}
|
||||
});
|
||||
for (let line of str.split("\n")) {
|
||||
if (!line.includes("[#!root]")) continue;
|
||||
reloadCounter++;
|
||||
str = "";
|
||||
|
||||
it("should recover from errors", async () => {
|
||||
const root = hotRunnerRoot;
|
||||
try {
|
||||
var runner = spawn({
|
||||
cmd: [bunExe(), "--hot", "run", root],
|
||||
env: bunEnv,
|
||||
cwd,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
stdin: "ignore",
|
||||
});
|
||||
|
||||
let reloadCounter = 0;
|
||||
const input = readFileSync(root, "utf-8");
|
||||
function onReloadGood() {
|
||||
writeFileSync(root, input);
|
||||
}
|
||||
|
||||
function onReloadError() {
|
||||
writeFileSync(root, "throw new Error('error');\n");
|
||||
}
|
||||
|
||||
var queue = [onReloadError, onReloadGood, onReloadError, onReloadGood];
|
||||
var errors: string[] = [];
|
||||
var onError: (...args: any[]) => void;
|
||||
(async () => {
|
||||
for await (let line of runner.stderr) {
|
||||
var str = new TextDecoder().decode(line);
|
||||
errors.push(str);
|
||||
// @ts-ignore
|
||||
onError && onError(str);
|
||||
}
|
||||
})();
|
||||
|
||||
var str = "";
|
||||
for await (const line of runner.stdout) {
|
||||
str += new TextDecoder().decode(line);
|
||||
var any = false;
|
||||
if (!/\[#!root\].*[0-9]\n/g.test(str)) continue;
|
||||
|
||||
for (let line of str.split("\n")) {
|
||||
if (!line.includes("[#!root]")) continue;
|
||||
reloadCounter++;
|
||||
str = "";
|
||||
|
||||
if (reloadCounter === 3) {
|
||||
runner.unref();
|
||||
runner.kill();
|
||||
break;
|
||||
}
|
||||
|
||||
expect(line).toContain(`[#!root] Reloaded: ${reloadCounter}`);
|
||||
any = true;
|
||||
}
|
||||
|
||||
if (any) {
|
||||
queue.shift()!();
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
if (errors.length > 0) {
|
||||
errors.length = 0;
|
||||
resolve();
|
||||
return;
|
||||
if (reloadCounter === 3) {
|
||||
runner.unref();
|
||||
runner.kill();
|
||||
break;
|
||||
}
|
||||
|
||||
onError = resolve;
|
||||
});
|
||||
|
||||
queue.shift()!();
|
||||
}
|
||||
}
|
||||
|
||||
expect(reloadCounter).toBe(3);
|
||||
} finally {
|
||||
// @ts-ignore
|
||||
runner?.unref?.();
|
||||
// @ts-ignore
|
||||
runner?.kill?.(9);
|
||||
}
|
||||
});
|
||||
|
||||
it("should not hot reload when a random file is written", async () => {
|
||||
const root = hotRunnerRoot;
|
||||
try {
|
||||
var runner = spawn({
|
||||
cmd: [bunExe(), "--hot", "run", root],
|
||||
env: bunEnv,
|
||||
cwd,
|
||||
stdout: "pipe",
|
||||
stderr: "inherit",
|
||||
stdin: "ignore",
|
||||
});
|
||||
|
||||
let reloadCounter = 0;
|
||||
const code = readFileSync(root, "utf-8");
|
||||
async function onReload() {
|
||||
writeFileSync(root + ".another.yet.js", code);
|
||||
unlinkSync(root + ".another.yet.js");
|
||||
}
|
||||
var finished = false;
|
||||
await Promise.race([
|
||||
Bun.sleep(200),
|
||||
(async () => {
|
||||
if (finished) {
|
||||
return;
|
||||
expect(line).toContain(`[#!root] Reloaded: ${reloadCounter}`);
|
||||
any = true;
|
||||
}
|
||||
var str = "";
|
||||
for await (const line of runner.stdout) {
|
||||
|
||||
if (any) await onReload();
|
||||
}
|
||||
|
||||
expect(reloadCounter).toBeGreaterThanOrEqual(3);
|
||||
} finally {
|
||||
// @ts-ignore
|
||||
runner?.unref?.();
|
||||
// @ts-ignore
|
||||
runner?.kill?.(9);
|
||||
}
|
||||
},
|
||||
timeout,
|
||||
);
|
||||
|
||||
it(
|
||||
"should recover from errors",
|
||||
async () => {
|
||||
const root = hotRunnerRoot;
|
||||
try {
|
||||
var runner = spawn({
|
||||
cmd: [bunExe(), "--hot", "run", root],
|
||||
env: bunEnv,
|
||||
cwd,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
stdin: "ignore",
|
||||
});
|
||||
|
||||
let reloadCounter = 0;
|
||||
const input = readFileSync(root, "utf-8");
|
||||
function onReloadGood() {
|
||||
writeFileSync(root, input);
|
||||
}
|
||||
|
||||
function onReloadError() {
|
||||
writeFileSync(root, "throw new Error('error');\n");
|
||||
}
|
||||
|
||||
var queue = [onReloadError, onReloadGood, onReloadError, onReloadGood];
|
||||
var errors: string[] = [];
|
||||
var onError: (...args: any[]) => void;
|
||||
(async () => {
|
||||
for await (let line of runner.stderr) {
|
||||
var str = new TextDecoder().decode(line);
|
||||
errors.push(str);
|
||||
// @ts-ignore
|
||||
onError && onError(str);
|
||||
}
|
||||
})();
|
||||
|
||||
var str = "";
|
||||
for await (const line of runner.stdout) {
|
||||
str += new TextDecoder().decode(line);
|
||||
var any = false;
|
||||
if (!/\[#!root\].*[0-9]\n/g.test(str)) continue;
|
||||
|
||||
for (let line of str.split("\n")) {
|
||||
if (!line.includes("[#!root]")) continue;
|
||||
reloadCounter++;
|
||||
str = "";
|
||||
|
||||
if (reloadCounter === 3) {
|
||||
runner.unref();
|
||||
runner.kill();
|
||||
break;
|
||||
}
|
||||
|
||||
expect(line).toContain(`[#!root] Reloaded: ${reloadCounter}`);
|
||||
any = true;
|
||||
}
|
||||
|
||||
if (any) {
|
||||
queue.shift()!();
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
if (errors.length > 0) {
|
||||
errors.length = 0;
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
onError = resolve;
|
||||
});
|
||||
|
||||
queue.shift()!();
|
||||
}
|
||||
}
|
||||
|
||||
expect(reloadCounter).toBe(3);
|
||||
} finally {
|
||||
// @ts-ignore
|
||||
runner?.unref?.();
|
||||
// @ts-ignore
|
||||
runner?.kill?.(9);
|
||||
}
|
||||
},
|
||||
timeout,
|
||||
);
|
||||
|
||||
it(
|
||||
"should not hot reload when a random file is written",
|
||||
async () => {
|
||||
const root = hotRunnerRoot;
|
||||
try {
|
||||
var runner = spawn({
|
||||
cmd: [bunExe(), "--hot", "run", root],
|
||||
env: bunEnv,
|
||||
cwd,
|
||||
stdout: "pipe",
|
||||
stderr: "inherit",
|
||||
stdin: "ignore",
|
||||
});
|
||||
|
||||
let reloadCounter = 0;
|
||||
const code = readFileSync(root, "utf-8");
|
||||
async function onReload() {
|
||||
writeFileSync(root + ".another.yet.js", code);
|
||||
unlinkSync(root + ".another.yet.js");
|
||||
}
|
||||
var finished = false;
|
||||
await Promise.race([
|
||||
Bun.sleep(200),
|
||||
(async () => {
|
||||
if (finished) {
|
||||
return;
|
||||
}
|
||||
|
||||
str += new TextDecoder().decode(line);
|
||||
if (!/\[#!root\].*[0-9]\n/g.test(str)) continue;
|
||||
|
||||
for (let line of str.split("\n")) {
|
||||
if (!line.includes("[#!root]")) continue;
|
||||
var str = "";
|
||||
for await (const line of runner.stdout) {
|
||||
if (finished) {
|
||||
return;
|
||||
}
|
||||
await onReload();
|
||||
|
||||
reloadCounter++;
|
||||
str = "";
|
||||
expect(line).toContain(`[#!root] Reloaded: ${reloadCounter}`);
|
||||
str += new TextDecoder().decode(line);
|
||||
if (!/\[#!root\].*[0-9]\n/g.test(str)) continue;
|
||||
|
||||
for (let line of str.split("\n")) {
|
||||
if (!line.includes("[#!root]")) continue;
|
||||
if (finished) {
|
||||
return;
|
||||
}
|
||||
await onReload();
|
||||
|
||||
reloadCounter++;
|
||||
str = "";
|
||||
expect(line).toContain(`[#!root] Reloaded: ${reloadCounter}`);
|
||||
}
|
||||
}
|
||||
})(),
|
||||
]);
|
||||
finished = true;
|
||||
runner.kill(0);
|
||||
runner.unref();
|
||||
|
||||
expect(reloadCounter).toBe(1);
|
||||
} finally {
|
||||
// @ts-ignore
|
||||
runner?.unref?.();
|
||||
// @ts-ignore
|
||||
runner?.kill?.(9);
|
||||
}
|
||||
},
|
||||
timeout,
|
||||
);
|
||||
|
||||
it(
|
||||
"should hot reload when a file is deleted and rewritten",
|
||||
async () => {
|
||||
try {
|
||||
const root = hotRunnerRoot + ".tmp.js";
|
||||
copyFileSync(hotRunnerRoot, root);
|
||||
var runner = spawn({
|
||||
cmd: [bunExe(), "--hot", "run", root],
|
||||
env: bunEnv,
|
||||
cwd,
|
||||
stdout: "pipe",
|
||||
stderr: "inherit",
|
||||
stdin: "ignore",
|
||||
});
|
||||
|
||||
var reloadCounter = 0;
|
||||
|
||||
async function onReload() {
|
||||
const contents = readFileSync(root, "utf-8");
|
||||
rmSync(root);
|
||||
writeFileSync(root, contents);
|
||||
}
|
||||
|
||||
var str = "";
|
||||
for await (const line of runner.stdout) {
|
||||
str += new TextDecoder().decode(line);
|
||||
var any = false;
|
||||
if (!/\[#!root\].*[0-9]\n/g.test(str)) continue;
|
||||
|
||||
for (let line of str.split("\n")) {
|
||||
if (!line.includes("[#!root]")) continue;
|
||||
reloadCounter++;
|
||||
str = "";
|
||||
|
||||
if (reloadCounter === 3) {
|
||||
runner.unref();
|
||||
runner.kill();
|
||||
break;
|
||||
}
|
||||
|
||||
expect(line).toContain(`[#!root] Reloaded: ${reloadCounter}`);
|
||||
any = true;
|
||||
}
|
||||
})(),
|
||||
]);
|
||||
finished = true;
|
||||
runner.kill(0);
|
||||
runner.unref();
|
||||
|
||||
expect(reloadCounter).toBe(1);
|
||||
} finally {
|
||||
// @ts-ignore
|
||||
runner?.unref?.();
|
||||
// @ts-ignore
|
||||
runner?.kill?.(9);
|
||||
}
|
||||
});
|
||||
if (any) await onReload();
|
||||
}
|
||||
rmSync(root);
|
||||
expect(reloadCounter).toBe(3);
|
||||
} finally {
|
||||
// @ts-ignore
|
||||
runner?.unref?.();
|
||||
// @ts-ignore
|
||||
runner?.kill?.(9);
|
||||
}
|
||||
},
|
||||
timeout,
|
||||
);
|
||||
|
||||
it("should hot reload when a file is deleted and rewritten", async () => {
|
||||
try {
|
||||
it(
|
||||
"should hot reload when a file is renamed() into place",
|
||||
async () => {
|
||||
const root = hotRunnerRoot + ".tmp.js";
|
||||
copyFileSync(hotRunnerRoot, root);
|
||||
var runner = spawn({
|
||||
cmd: [bunExe(), "--hot", "run", root],
|
||||
env: bunEnv,
|
||||
cwd,
|
||||
stdout: "pipe",
|
||||
stderr: "inherit",
|
||||
stdin: "ignore",
|
||||
});
|
||||
try {
|
||||
var runner = spawn({
|
||||
cmd: [bunExe(), "--hot", "run", root],
|
||||
env: bunEnv,
|
||||
cwd,
|
||||
stdout: "pipe",
|
||||
stderr: "inherit",
|
||||
stdin: "ignore",
|
||||
});
|
||||
|
||||
var reloadCounter = 0;
|
||||
var reloadCounter = 0;
|
||||
|
||||
async function onReload() {
|
||||
const contents = readFileSync(root, "utf-8");
|
||||
rmSync(root);
|
||||
writeFileSync(root, contents);
|
||||
}
|
||||
|
||||
var str = "";
|
||||
for await (const line of runner.stdout) {
|
||||
str += new TextDecoder().decode(line);
|
||||
var any = false;
|
||||
if (!/\[#!root\].*[0-9]\n/g.test(str)) continue;
|
||||
|
||||
for (let line of str.split("\n")) {
|
||||
if (!line.includes("[#!root]")) continue;
|
||||
reloadCounter++;
|
||||
str = "";
|
||||
|
||||
if (reloadCounter === 3) {
|
||||
runner.unref();
|
||||
runner.kill();
|
||||
break;
|
||||
}
|
||||
|
||||
expect(line).toContain(`[#!root] Reloaded: ${reloadCounter}`);
|
||||
any = true;
|
||||
async function onReload() {
|
||||
const contents = readFileSync(root, "utf-8");
|
||||
rmSync(root + ".tmpfile", { force: true });
|
||||
await 1;
|
||||
writeFileSync(root + ".tmpfile", contents);
|
||||
await 1;
|
||||
rmSync(root);
|
||||
await 1;
|
||||
renameSync(root + ".tmpfile", root);
|
||||
await 1;
|
||||
}
|
||||
|
||||
if (any) await onReload();
|
||||
}
|
||||
rmSync(root);
|
||||
expect(reloadCounter).toBe(3);
|
||||
} finally {
|
||||
// @ts-ignore
|
||||
runner?.unref?.();
|
||||
// @ts-ignore
|
||||
runner?.kill?.(9);
|
||||
}
|
||||
});
|
||||
var str = "";
|
||||
for await (const line of runner.stdout) {
|
||||
str += new TextDecoder().decode(line);
|
||||
var any = false;
|
||||
if (!/\[#!root\].*[0-9]\n/g.test(str)) continue;
|
||||
|
||||
it("should hot reload when a file is renamed() into place", async () => {
|
||||
const root = hotRunnerRoot + ".tmp.js";
|
||||
copyFileSync(hotRunnerRoot, root);
|
||||
try {
|
||||
var runner = spawn({
|
||||
cmd: [bunExe(), "--hot", "run", root],
|
||||
env: bunEnv,
|
||||
cwd,
|
||||
stdout: "pipe",
|
||||
stderr: "inherit",
|
||||
stdin: "ignore",
|
||||
});
|
||||
for (let line of str.split("\n")) {
|
||||
if (!line.includes("[#!root]")) continue;
|
||||
reloadCounter++;
|
||||
str = "";
|
||||
|
||||
var reloadCounter = 0;
|
||||
if (reloadCounter === 3) {
|
||||
runner.unref();
|
||||
runner.kill();
|
||||
break;
|
||||
}
|
||||
|
||||
async function onReload() {
|
||||
const contents = readFileSync(root, "utf-8");
|
||||
rmSync(root + ".tmpfile", { force: true });
|
||||
await 1;
|
||||
writeFileSync(root + ".tmpfile", contents);
|
||||
await 1;
|
||||
rmSync(root);
|
||||
await 1;
|
||||
renameSync(root + ".tmpfile", root);
|
||||
await 1;
|
||||
}
|
||||
|
||||
var str = "";
|
||||
for await (const line of runner.stdout) {
|
||||
str += new TextDecoder().decode(line);
|
||||
var any = false;
|
||||
if (!/\[#!root\].*[0-9]\n/g.test(str)) continue;
|
||||
|
||||
for (let line of str.split("\n")) {
|
||||
if (!line.includes("[#!root]")) continue;
|
||||
reloadCounter++;
|
||||
str = "";
|
||||
|
||||
if (reloadCounter === 3) {
|
||||
runner.unref();
|
||||
runner.kill();
|
||||
break;
|
||||
expect(line).toContain(`[#!root] Reloaded: ${reloadCounter}`);
|
||||
any = true;
|
||||
}
|
||||
|
||||
expect(line).toContain(`[#!root] Reloaded: ${reloadCounter}`);
|
||||
any = true;
|
||||
if (any) await onReload();
|
||||
}
|
||||
|
||||
if (any) await onReload();
|
||||
rmSync(root);
|
||||
expect(reloadCounter).toBe(3);
|
||||
} finally {
|
||||
// @ts-ignore
|
||||
runner?.unref?.();
|
||||
// @ts-ignore
|
||||
runner?.kill?.(9);
|
||||
}
|
||||
rmSync(root);
|
||||
expect(reloadCounter).toBe(3);
|
||||
} finally {
|
||||
// @ts-ignore
|
||||
runner?.unref?.();
|
||||
// @ts-ignore
|
||||
runner?.kill?.(9);
|
||||
}
|
||||
});
|
||||
},
|
||||
timeout,
|
||||
);
|
||||
|
||||
const comment_spam = ("//" + "B".repeat(2000) + "\n").repeat(1000);
|
||||
it(
|
||||
@@ -385,81 +408,85 @@ ${" ".repeat(reloadCounter * 2)}throw new Error(${reloadCounter});`,
|
||||
await runner.exited;
|
||||
expect(reloadCounter).toBe(50);
|
||||
},
|
||||
isDebug ? Infinity : 10_000,
|
||||
timeout,
|
||||
);
|
||||
|
||||
it("should work with sourcemap loading", async () => {
|
||||
let bundleIn = join(cwd, "bundle_in.ts");
|
||||
rmSync(hotRunnerRoot);
|
||||
writeFileSync(
|
||||
bundleIn,
|
||||
`// source content
|
||||
//
|
||||
//
|
||||
throw new Error('0');`,
|
||||
);
|
||||
await using bundler = spawn({
|
||||
cmd: [bunExe(), "build", "--watch", bundleIn, "--target=bun", "--sourcemap", "--outfile", hotRunnerRoot],
|
||||
env: bunEnv,
|
||||
cwd,
|
||||
stdout: "inherit",
|
||||
stderr: "inherit",
|
||||
stdin: "ignore",
|
||||
});
|
||||
await using runner = spawn({
|
||||
cmd: [bunExe(), "--hot", "run", hotRunnerRoot],
|
||||
env: bunEnv,
|
||||
cwd,
|
||||
stdout: "ignore",
|
||||
stderr: "pipe",
|
||||
stdin: "ignore",
|
||||
});
|
||||
let reloadCounter = 0;
|
||||
function onReload() {
|
||||
it(
|
||||
"should work with sourcemap loading",
|
||||
async () => {
|
||||
let bundleIn = join(cwd, "bundle_in.ts");
|
||||
rmSync(hotRunnerRoot);
|
||||
writeFileSync(
|
||||
bundleIn,
|
||||
`// source content
|
||||
//
|
||||
//
|
||||
throw new Error('0');`,
|
||||
);
|
||||
await using bundler = spawn({
|
||||
cmd: [bunExe(), "build", "--watch", bundleIn, "--target=bun", "--sourcemap", "--outfile", hotRunnerRoot],
|
||||
env: bunEnv,
|
||||
cwd,
|
||||
stdout: "inherit",
|
||||
stderr: "inherit",
|
||||
stdin: "ignore",
|
||||
});
|
||||
await using runner = spawn({
|
||||
cmd: [bunExe(), "--hot", "run", hotRunnerRoot],
|
||||
env: bunEnv,
|
||||
cwd,
|
||||
stdout: "ignore",
|
||||
stderr: "pipe",
|
||||
stdin: "ignore",
|
||||
});
|
||||
let reloadCounter = 0;
|
||||
function onReload() {
|
||||
writeFileSync(
|
||||
bundleIn,
|
||||
`// source content
|
||||
// etc etc
|
||||
// etc etc
|
||||
${" ".repeat(reloadCounter * 2)}throw new Error(${reloadCounter});`,
|
||||
);
|
||||
}
|
||||
let str = "";
|
||||
outer: for await (const chunk of runner.stderr) {
|
||||
str += new TextDecoder().decode(chunk);
|
||||
var any = false;
|
||||
if (!/error: .*[0-9]\n.*?\n/g.test(str)) continue;
|
||||
|
||||
let it = str.split("\n");
|
||||
let line;
|
||||
while ((line = it.shift())) {
|
||||
if (!line.includes("error")) continue;
|
||||
str = "";
|
||||
|
||||
if (reloadCounter === 50) {
|
||||
runner.kill();
|
||||
break;
|
||||
}
|
||||
|
||||
if (line.includes(`error: ${reloadCounter - 1}`)) {
|
||||
onReload(); // re-save file to prevent deadlock
|
||||
continue outer;
|
||||
}
|
||||
expect(line).toContain(`error: ${reloadCounter}`);
|
||||
reloadCounter++;
|
||||
|
||||
let next = it.shift()!;
|
||||
expect(next).toInclude("bundle_in.ts");
|
||||
const col = next.match(/\s*at.*?:4:(\d+)$/)![1];
|
||||
expect(Number(col)).toBe(1 + "throw ".length + (reloadCounter - 1) * 2);
|
||||
any = true;
|
||||
);
|
||||
}
|
||||
let str = "";
|
||||
outer: for await (const chunk of runner.stderr) {
|
||||
str += new TextDecoder().decode(chunk);
|
||||
var any = false;
|
||||
if (!/error: .*[0-9]\n.*?\n/g.test(str)) continue;
|
||||
|
||||
if (any) await onReload();
|
||||
}
|
||||
expect(reloadCounter).toBe(50);
|
||||
bundler.kill();
|
||||
});
|
||||
let it = str.split("\n");
|
||||
let line;
|
||||
while ((line = it.shift())) {
|
||||
if (!line.includes("error")) continue;
|
||||
str = "";
|
||||
|
||||
if (reloadCounter === 50) {
|
||||
runner.kill();
|
||||
break;
|
||||
}
|
||||
|
||||
if (line.includes(`error: ${reloadCounter - 1}`)) {
|
||||
onReload(); // re-save file to prevent deadlock
|
||||
continue outer;
|
||||
}
|
||||
expect(line).toContain(`error: ${reloadCounter}`);
|
||||
reloadCounter++;
|
||||
|
||||
let next = it.shift()!;
|
||||
expect(next).toInclude("bundle_in.ts");
|
||||
const col = next.match(/\s*at.*?:4:(\d+)$/)![1];
|
||||
expect(Number(col)).toBe(1 + "throw ".length + (reloadCounter - 1) * 2);
|
||||
any = true;
|
||||
}
|
||||
|
||||
if (any) await onReload();
|
||||
}
|
||||
expect(reloadCounter).toBe(50);
|
||||
bundler.kill();
|
||||
},
|
||||
timeout,
|
||||
);
|
||||
|
||||
const long_comment = "BBBB".repeat(100000);
|
||||
|
||||
@@ -566,5 +593,5 @@ ${" ".repeat(reloadCounter * 2)}throw new Error(${reloadCounter});`,
|
||||
// TODO: bun has a memory leak when --hot is used on very large files
|
||||
// console.log({ sampleMemory10, sampleMemory100 });
|
||||
},
|
||||
isDebug ? Infinity : 20_000,
|
||||
longTimeout,
|
||||
);
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
root_url,
|
||||
setHandler,
|
||||
} from "./dummy.registry";
|
||||
import { cpSync, rmSync } from "js/node/fs/export-star-from";
|
||||
import { cpSync } from "node:fs";
|
||||
|
||||
beforeAll(dummyBeforeAll);
|
||||
afterAll(dummyAfterAll);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user