mirror of
https://github.com/oven-sh/bun
synced 2026-02-15 05:12:29 +00:00
This PR refactors git operations in `bun install` from blocking threadpool calls using `std.process.Child` to non-blocking event loop integration using `bun.spawn`. ## Changes - Created `GitCommandRunner` for async git command execution with event loop integration - Replaced blocking `fork()` calls with async `bun.spawn` - Implemented proper two-phase checkout (clone --no-checkout, then checkout) - Moved post-checkout operations (.git deletion, .bun-tag creation) to appropriate places - Fixed argv construction to use "git" instead of hardcoded paths - Added comprehensive tests for git dependencies ## Technical Details The new implementation: - Uses tagged pointer unions for process exit handlers - Properly manages pending task counting for event loop - Handles both clone and checkout operations asynchronously - Maintains backward compatibility with existing URL handling All git operations now integrate properly with Bun's event loop, eliminating blocking operations and improving performance. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
90 lines
2.5 KiB
TypeScript
90 lines
2.5 KiB
TypeScript
import { spawnSync } from "bun";
|
|
import { expect, test } from "bun:test";
|
|
import { bunEnv, bunExe, tempDirWithFiles } from "harness";
|
|
import { join } from "path";
|
|
import { existsSync } from "fs";
|
|
|
|
test("install github dependency", async () => {
|
|
const dir = tempDirWithFiles("test-github-install", {
|
|
"package.json": JSON.stringify({
|
|
name: "test-github-install",
|
|
dependencies: {
|
|
// Using github: shorthand which downloads as tarball
|
|
"awesome-bun": "github:oven-sh/awesome-bun",
|
|
},
|
|
}),
|
|
});
|
|
|
|
const result = spawnSync({
|
|
cmd: [bunExe(), "install"],
|
|
env: bunEnv,
|
|
cwd: dir,
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
|
|
expect(result.exitCode).toBe(0);
|
|
expect(result.stderr.toString()).not.toContain("error");
|
|
|
|
// Check that the package was installed
|
|
const packagePath = join(dir, "node_modules", "awesome-bun");
|
|
expect(existsSync(packagePath)).toBe(true);
|
|
|
|
// Should have README.md
|
|
const readmePath = join(packagePath, "README.md");
|
|
expect(existsSync(readmePath)).toBe(true);
|
|
});
|
|
|
|
test("install git+https URL dependency", async () => {
|
|
const dir = tempDirWithFiles("test-git-url", {
|
|
"package.json": JSON.stringify({
|
|
name: "test-git-url",
|
|
dependencies: {
|
|
// Using git+ prefix which triggers git clone
|
|
"bun-types": "git+https://github.com/oven-sh/bun.git#main",
|
|
},
|
|
}),
|
|
});
|
|
|
|
const result = spawnSync({
|
|
cmd: [bunExe(), "install"],
|
|
env: bunEnv,
|
|
cwd: dir,
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
|
|
expect(result.exitCode).toBe(0);
|
|
expect(result.stderr.toString()).not.toContain("error");
|
|
|
|
// Check that the package was installed
|
|
const packagePath = join(dir, "node_modules", "bun-types");
|
|
expect(existsSync(packagePath)).toBe(true);
|
|
});
|
|
|
|
test("install git URL without commit hash", async () => {
|
|
const dir = tempDirWithFiles("test-git-no-hash", {
|
|
"package.json": JSON.stringify({
|
|
name: "test-git-no-hash",
|
|
dependencies: {
|
|
// Using HEAD of default branch
|
|
"awesome-bun-2": "git+https://github.com/oven-sh/awesome-bun.git",
|
|
},
|
|
}),
|
|
});
|
|
|
|
const result = spawnSync({
|
|
cmd: [bunExe(), "install"],
|
|
env: bunEnv,
|
|
cwd: dir,
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
|
|
expect(result.exitCode).toBe(0);
|
|
expect(result.stderr.toString()).not.toContain("error");
|
|
|
|
// Check that the package was installed
|
|
const packagePath = join(dir, "node_modules", "awesome-bun-2");
|
|
expect(existsSync(packagePath)).toBe(true);
|
|
}); |