Skip to content

Commit

Permalink
Merge branch 'main' into ciro/fix-socket
Browse files Browse the repository at this point in the history
  • Loading branch information
Jarred-Sumner authored Apr 13, 2024
2 parents ccef10c + 4627af5 commit fe8e92d
Show file tree
Hide file tree
Showing 179 changed files with 3,300 additions and 1,385 deletions.
3 changes: 3 additions & 0 deletions .clangd
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Index:
Background: Skip # Disable slow background indexing of these files.

2 changes: 1 addition & 1 deletion .github/workflows/bun-linux-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ jobs:
mode: upsert
create_if_not_exists: false
message: |
✅ test failures on ${{ matrix.tag }} have been resolved.
✅ test failures on ${{ matrix.tag }} have been resolved. Thank you.
<sup>[#${{github.sha}}](https://github.com/oven-sh/bun/commits/${{github.sha}})</sup>
- id: fail
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/bun-mac-aarch64.yml
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ jobs:
mode: upsert
create_if_not_exists: false
message: |
✅ test failures on ${{ matrix.tag }} have been resolved.
✅ test failures on ${{ matrix.tag }} have been resolved. Thank you.
<sup>[#${{github.sha}}](https://github.com/oven-sh/bun/commits/${{github.sha}})</sup>
- id: fail
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/bun-mac-x64-baseline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ jobs:
mode: upsert
create_if_not_exists: false
message: |
✅ test failures on ${{ matrix.tag }} have been resolved.
✅ test failures on ${{ matrix.tag }} have been resolved. Thank you.
<sup>[#${{github.sha}}](https://github.com/oven-sh/bun/commits/${{github.sha}})</sup>
- id: fail
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/bun-mac-x64.yml
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ jobs:
mode: upsert
create_if_not_exists: false
message: |
✅ test failures on ${{ matrix.tag }} have been resolved.
✅ test failures on ${{ matrix.tag }} have been resolved. Thank you.
<sup>[#${{github.sha}}](https://github.com/oven-sh/bun/commits/${{github.sha}})</sup>
- id: fail
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/bun-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ jobs:
mode: upsert
create_if_not_exists: false
message: |
✅🪟 Test regressions on Windows ${{ matrix.arch }}${{ matrix.cpu == 'nehalem' && ' Baseline' || '' }} have been resolved.
✅🪟 Test regressions on Windows ${{ matrix.arch }}${{ matrix.cpu == 'nehalem' && ' Baseline' || '' }} have been resolved. Thank you.
- id: fail
name: Fail the build
if: steps.test.outputs.failing_tests != ''
Expand Down
86 changes: 86 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
name: lint

permissions:
contents: read

on:
workflow_dispatch:
pull_request:
push:
branches:
- main
- jarred/assert
paths:
- ".github/workflows/lint.yml"
- "src/**/*.zig"
- "src/*.zig"

jobs:
format:
name: lint
runs-on: ${{ vars.RUNNER_LINUX_X64 || 'ubuntu-latest' }}
if: github.repository_owner == 'oven-sh'
permissions: write-all
outputs:
text_output: ${{ steps.lint.outputs.text_output }}
json_output: ${{ steps.lint.outputs.json_output }}
count: ${{ steps.lint.outputs.count }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Bun
uses: ./.github/actions/setup-bun
with:
bun-version: "1.1.3"
- name: Install Dependencies
run: |
bun --cwd=./packages/bun-internal-test install
- name: Lint
id: lint
run: |
bun ./packages/bun-internal-test/src/linter.ts || true
- uses: sarisia/actions-status-discord@v1
if: always() && steps.lint.outputs.text_output != '' && github.event_name == 'pull_request'
with:
title: ""
webhook: ${{ secrets.DISCORD_WEBHOOK }}
status: "failure"
noprefix: true
nocontext: true
description: |
Pull Request
### ❌ [${{github.event.pull_request.title}}](https://github.com/oven-sh/bun/pull/${{github.event.number}})
@${{ github.actor }}, there are ${{ steps.lint.outputs.count }} lint errors on ${{ github.ref_name }}
${{ steps.lint.outputs.text_output }}
**[View linter output](https://github.com/oven-sh/bun/actions/runs/${{github.run_id}})**
- name: Comment on PR
if: steps.lint.outputs.text_output != '' && github.event_name == 'pull_request'
uses: thollander/actions-comment-pull-request@v2
with:
comment_tag: lint-failures
message: |
❌ @${{ github.actor }} ${{ steps.lint.outputs.count }} lint errors
${{ steps.lint.outputs.text_output }}
**[View linter output](https://github.com/oven-sh/bun/actions/runs/${{github.run_id}})**
<sup>[#${{github.sha}}](https://github.com/oven-sh/bun/commits/${{github.sha}})</sup>
- name: Uncomment on PR
if: steps.lint.outputs.text_output == '' && github.event_name == 'pull_request'
uses: thollander/actions-comment-pull-request@v2
with:
comment_tag: lint-failures
mode: upsert
create_if_not_exists: false
message: |
✅ lint failures have been resolved. Thank you.
<sup>[#${{github.sha}}](https://github.com/oven-sh/bun/commits/${{github.sha}})</sup>
- id: fail
name: Fail the build
if: steps.lint.outputs.text_output != ''
run: exit 1
2 changes: 2 additions & 0 deletions docs/api/file-io.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ A `BunFile` can point to a location on disk where a file does not exist.
const notreal = Bun.file("notreal.txt");
notreal.size; // 0
notreal.type; // "text/plain;charset=utf-8"
const exists = await notreal.exists(); // false
```

The default MIME type is `text/plain;charset=utf-8`, but it can be overridden by passing a second argument to `Bun.file`.
Expand Down Expand Up @@ -340,6 +341,7 @@ interface BunFile {
arrayBuffer(): Promise<ArrayBuffer>;
json(): Promise<any>;
writer(params: { highWaterMark?: number }): FileSink;
exists(): Promise<boolean>;
}

export interface FileSink {
Expand Down
58 changes: 58 additions & 0 deletions docs/cli/filter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
Use the `--filter` flag to execute lifecycle scripts in multiple packages at once:

```bash
bun --filter <pattern> <script>
```

Say you have a monorepo with two packages: `packages/api` and `packages/frontend`, both with a `dev` script that will start a local development server. Normally, you would have to open two separate terminal tabs, cd into each package directory, and run `bun dev`:

```bash
cd packages/api
bun dev

# in another terminal
cd packages/frontend
bun dev
```

Using `--filter`, you can run the `dev` script in both packages at once:

```bash
bun --filter '*' dev
```

Both commands will be run in parallel, and you will see a nice terminal UI showing their respective outputs:
![Terminal Output](https://github.com/oven-sh/bun/assets/48869301/2a103e42-9921-4c33-948f-a1ad6e6bac71)


## Matching

`--filter` accepts a pattern to match specific packages, either by name or by path. Patterns have full support for glob syntax.

### Package Name `--filter <pattern>`

Name patterns select packages based on the package name, as specified in `package.json`. For example, if you have packages `pkga`, `pkgb` and `other`, you can match all packages with `*`, only `pkga` and `pkgb` with `pkg*`, and a specific package by providing the full name of the package.

### Package Path `--filter ./<glob>`

Path patterns are specified by starting the pattern with `./`, and will select all packages in directories that match the pattern. For example, to match all packages in subdirectories of `packages`, you can use `--filter './packages/**'`. To match a package located in `pkgs/foo`, use `--filter ./pkgs/foo`.

## Workspaces

Filters respect your [workspace configuration](/docs/install/workspaces.md): If you have a `package.json` file that specifies which packages are part of the workspace,
`--filter` will be restricted to only these packages. Also, in a workspace you can use `--filter` to run scripts in packages that are located anywhere in the workspace:

```bash
# Packages
# src/foo
# src/bar

# in src/bar: runs myscript in src/foo, no need to cd!
bun run --filter foo myscript
```

## Dependency Order
Bun will respect package dependency order when running scripts. Say you have a package `foo` that depends on another package `bar` in your workspace, and both packages have a `build` script. When you run `bun --filter '*' build`, you will notice that `foo` will only start running once `bar` is done.

### Cyclic Dependencies

13 changes: 13 additions & 0 deletions docs/cli/run.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,19 @@ By default, Bun respects this shebang and executes the script with `node`. Howev
$ bun run --bun vite
```

### Filtering

in monorepos containing multiple packages, you can use the `--filter` argument to execute scripts in many packages at once.

Use `bun run --filter <name_pattern> <script>` to execute `<script>` in all packages whose name matches `<name_pattern>`.
For example, if you have subdirectories containing packages named `foo`, `bar` and `baz`, running
```bash
bun run --filter 'ba*' <script>
```
will execute `<script>` in both `bar` and `baz`, but not in `foo`.

Find more details in the docs page for [filter](/docs/cli/filter.md).

## `bun run -` to pipe code from stdin

`bun run -` lets you read JavaScript, TypeScript, TSX, or JSX from stdin and execute it without writing to a temporary file first.
Expand Down
1 change: 1 addition & 0 deletions docs/install/workspaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ Workspaces have a couple major benefits.

- **Code can be split into logical parts.** If one package relies on another, you can simply add it as a dependency in `package.json`. If package `b` depends on `a`, `bun install` will install your local `packages/a` directory into `node_modules` instead of downloading it from the npm registry.
- **Dependencies can be de-duplicated.** If `a` and `b` share a common dependency, it will be _hoisted_ to the root `node_modules` directory. This reduces redundant disk usage and minimizes "dependency hell" issues associated with having multiple versions of a package installed simultaneously.
- **Run scripts in multiple pacakges.** You can use the [`--filter` flag](/docs/cli/filter.md) to easily run `package.json` scripts in multiple packages in your workspace.

{% callout %}
⚡️ **Speed** — Installs are fast, even for big monorepos. Bun installs the [Remix](https://github.com/remix-run/remix) monorepo in about `500ms` on Linux.
Expand Down
3 changes: 3 additions & 0 deletions docs/nav.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,9 @@ export default {
page("install/lifecycle", "Lifecycle scripts", {
description: "How Bun handles package lifecycle scripts with trustedDependencies",
}),
page("cli/filter", "Filter", {
description: "Run scripts in multiple packages in parallel",
}),
page("install/lockfile", "Lockfile", {
description:
"Bun's binary lockfile `bun.lockb` tracks your resolved dependency tree, making future installs fast and repeatable.",
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"build:release": "cmake . -DCMAKE_BUILD_TYPE=Release -GNinja -Bbuild-release && ninja -Cbuild-release",
"build:debug-zig-release": "cmake . -DCMAKE_BUILD_TYPE=Release -DZIG_OPTIMIZE=Debug -GNinja -Bbuild-debug-zig-release && ninja -Cbuild-debug-zig-release",
"build:safe": "cmake . -DZIG_OPTIMIZE=ReleaseSafe -DUSE_DEBUG_JSC=ON -DCMAKE_BUILD_TYPE=Release -GNinja -Bbuild-safe && ninja -Cbuild-safe",
"build:windows": "cmake -B build -S . -G Ninja -DCMAKE_BUILD_TYPE=Debug && ninja -Cbuild",
"typecheck": "tsc --noEmit && cd test && bun run typecheck",
"fmt": "prettier --write --cache './{.vscode,src,test,bench,packages/{bun-types,bun-inspector-*,bun-vscode,bun-debug-adapter-protocol}}/**/*.{mjs,ts,tsx,js,jsx}'",
"fmt:zig": "zig fmt src/*.zig src/*/*.zig src/*/*/*.zig src/*/*/*/*.zig",
Expand Down
7 changes: 7 additions & 0 deletions packages/bun-internal-test/src/banned.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"std.debug.assert": "Use bun.assert instead",
"@import(\"root\").bun.": "Only import 'bun' once",
"std.mem.indexOfAny": "Use bun.strings.indexAny or bun.strings.indexAnyComptime",
"std.debug.print": "Don't let this be committed",
"": ""
}
72 changes: 72 additions & 0 deletions packages/bun-internal-test/src/linter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { $ } from "bun";
import BANNED from "./banned.json";
import * as action from "@actions/core";

const IGNORED_FOLDERS = [
// list of folders to ignore
"windows-shim",
];

const ci = !!process.env["GITHUB_ACTIONS"];
process.chdir(require("path").join(import.meta.dir, "../../../"));
let bad = [];
let report = "";
const write = (text: string) => {
process.stdout.write(text);
report += text;
};
for (const [banned, suggestion] of Object.entries(BANNED)) {
if (banned.length === 0) continue;
// Run git grep to find occurrences of std.debug.assert in .zig files
// .nothrow() is here since git will exit with non-zero if no matches are found.
let stdout = await $`git grep -n -F "${banned}" "src/**/**.zig" | grep -v -F '//' | grep -v -F bench`
.nothrow()
.text();

stdout = stdout.trim();
if (stdout.length === 0) continue;

let lines = stdout.split("\n");
// Parse each line to extract filename and line number
const matches = lines
.filter(line => !IGNORED_FOLDERS.some(folder => line.includes(folder)))
.map(line => {
const [path, lineNumber, ...text] = line.split(":");
return { path, lineNumber, banned, suggestion, text: text.join(":") };
});
// Check if we got any output
// Split the output into lines
if (matches.length === 0) continue;

write(`Banned **'${banned}'** found in the following locations:` + "\n");
matches.forEach(match => {
write(`${match.path}:${match.lineNumber}: ${match.text.trim()}` + "\n");
});
bad = bad.concat(matches);
}

if (report.length === 0) {
process.exit(0);
}

function link({ path, lineNumber, suggestion, banned }) {
action.error(`Lint failure: ${banned} is banned, ${suggestion}`, {
file: path,
startLine: Number(lineNumber),
endLine: Number(lineNumber),
});
return `[\`${path}:${lineNumber}\`](https://github.com/oven-sh/bun/blob/${process.env.GITHUB_SHA}/${path}#L${lineNumber})`;
}

if (ci) {
if (report.length > 0) {
action.setFailed(`${bad.length} lint failures`);
}
action.setOutput("count", bad.length);
action.setOutput("text_output", bad.map(m => `- ${link(m)}: ${m.banned} is banned, ${m.suggestion}`).join("\n"));
action.setOutput("json_output", JSON.stringify(bad));
action.summary.addRaw(report);
await action.summary.write();
}

process.exit(1);
10 changes: 9 additions & 1 deletion packages/bun-internal-test/src/runner.node.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -497,9 +497,17 @@ if (failing_tests.length) {
report += "[Link to file](" + linkToGH(path) + ")\n\n";
report += `${reason}\n\n`;
report += "```\n";
report += output

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";
}
}
Expand Down
5 changes: 5 additions & 0 deletions packages/bun-types/bun.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4145,6 +4145,11 @@ declare module "bun" {
*/
windowsHide?: boolean;

/**
* If true, no quoting or escaping of arguments is done on Windows.
*/
windowsVerbatimArguments?: boolean;

/**
* Path to the executable to run in the subprocess. This defaults to `cmds[0]`.
*
Expand Down
8 changes: 7 additions & 1 deletion packages/bun-usockets/src/loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,13 @@ void us_internal_dispatch_ready_poll(struct us_poll_t *p, int error, int events)

do {
const struct us_loop_t* loop = s->context->loop;
int length = bsd_recv(us_poll_fd(&s->p), loop->data.recv_buf + LIBUS_RECV_BUFFER_PADDING, LIBUS_RECV_BUFFER_LENGTH, MSG_DONTWAIT);
#ifdef _WIN32
const int recv_flags = MSG_PUSH_IMMEDIATE;
#else
const int recv_flags = MSG_DONTWAIT | MSG_NOSIGNAL;
#endif

int length = bsd_recv(us_poll_fd(&s->p), loop->data.recv_buf + LIBUS_RECV_BUFFER_PADDING, LIBUS_RECV_BUFFER_LENGTH, recv_flags);

if (length > 0) {
s = s->context->on_data(s, loop->data.recv_buf + LIBUS_RECV_BUFFER_PADDING, length);
Expand Down
4 changes: 2 additions & 2 deletions src/ArenaAllocator.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const std = @import("std");
const assert = std.debug.assert;
const assert = @import("root").bun.assert;
const mem = std.mem;
const Allocator = std.mem.Allocator;

Expand Down Expand Up @@ -132,7 +132,7 @@ pub const ArenaAllocator = struct {
self.child_allocator.rawFree(alloc_buf, align_bits, @returnAddress());
it = next_it;
} else null;
std.debug.assert(maybe_first_node == null or maybe_first_node.?.next == null);
assert(maybe_first_node == null or maybe_first_node.?.next == null);
// reset the state before we try resizing the buffers, so we definitely have reset the arena to 0.
self.state.end_index = 0;
if (maybe_first_node) |first_node| {
Expand Down
Loading

0 comments on commit fe8e92d

Please sign in to comment.