Compare commits

...

2 Commits

Author SHA1 Message Date
pfg
5c9049409e set cwd for bun run 2025-01-17 20:27:47 -08:00
pfg
477fc87e6a fix bun --bun run folder 2025-01-17 20:18:55 -08:00
6 changed files with 109 additions and 19 deletions

View File

@@ -2271,7 +2271,6 @@ pub const Command = struct {
break :brk null;
};
const force_using_bun = ctx.debug.run_in_bun;
var did_check = false;
if (default_loader) |loader| {
if (loader.canBeRunByBun()) {
@@ -2283,12 +2282,6 @@ pub const Command = struct {
}
}
if (force_using_bun and !did_check) {
if (maybeOpenWithBunJS(ctx)) {
return;
}
}
if (ctx.positionals.len > 0 and extension.len == 0) {
if (ctx.filters.len > 0) {
Output.prettyln("<r><yellow>warn<r>: Filters are ignored for auto command", .{});

View File

@@ -39,7 +39,7 @@ pub const ExecCommand = struct {
};
const script_path = bun.path.join(parts, .auto);
const code = bun.shell.Interpreter.initAndRunFromSource(ctx, mini, script_path, script) catch |err| {
const code = bun.shell.Interpreter.initAndRunFromSource(ctx, mini, script_path, script, null) catch |err| {
Output.err(err, "failed to run script <b>{s}<r>", .{script_path});
Global.exit(1);
};

View File

@@ -301,7 +301,7 @@ pub const RunCommand = struct {
if (!use_system_shell) {
const mini = bun.JSC.MiniEventLoop.initGlobal(env);
const code = bun.shell.Interpreter.initAndRunFromSource(ctx, mini, name, copy_script.items) catch |err| {
const code = bun.shell.Interpreter.initAndRunFromSource(ctx, mini, name, copy_script.items, cwd) catch |err| {
if (!silent) {
Output.prettyErrorln("<r><red>error<r>: Failed to run script <b>{s}<r> due to error <b>{s}<r>", .{ name, @errorName(err) });
}
@@ -1301,12 +1301,12 @@ pub const RunCommand = struct {
return true;
}
if (!did_try_open_with_bun_js and (log_errors or force_using_bun)) {
if (!did_try_open_with_bun_js and log_errors) {
if (script_name_to_search.len > 0) {
possibly_open_with_bun_js: {
const ext = std.fs.path.extension(script_name_to_search);
var has_loader = false;
if (!force_using_bun) {
{
if (options.defaultLoaders.get(ext)) |load| {
has_loader = true;
if (!load.canBeRunByBun())
@@ -1345,7 +1345,7 @@ pub const RunCommand = struct {
const file = file_ catch break :possibly_open_with_bun_js;
if (!force_using_bun) {
{
// Due to preload, we don't know if they intend to run
// this as a script or as a regular file
// once we know it's a file, check if they have any preloads
@@ -1424,6 +1424,10 @@ pub const RunCommand = struct {
if (root_dir_info.enclosing_package_json) |package_json| {
if (package_json.scripts) |scripts| {
if (scripts.get(script_name_to_search)) |script_content| {
const package_json_path = root_dir_info.enclosing_package_json.?.source.path.text;
const package_json_dir = strings.withoutTrailingSlash(strings.withoutSuffixComptime(package_json_path, "package.json"));
log("Running in dir `{s}`", .{package_json_dir});
// allocate enough to hold "post${scriptname}"
var temp_script_buffer = try std.fmt.allocPrint(ctx.allocator, "ppre{s}", .{script_name_to_search});
defer ctx.allocator.free(temp_script_buffer);
@@ -1434,7 +1438,7 @@ pub const RunCommand = struct {
ctx.allocator,
prescript,
temp_script_buffer[1..],
this_transpiler.fs.top_level_dir,
package_json_dir,
this_transpiler.env,
&.{},
ctx.debug.silent,
@@ -1448,7 +1452,7 @@ pub const RunCommand = struct {
ctx.allocator,
script_content,
script_name_to_search,
this_transpiler.fs.top_level_dir,
package_json_dir,
this_transpiler.env,
passthrough,
ctx.debug.silent,
@@ -1464,7 +1468,7 @@ pub const RunCommand = struct {
ctx.allocator,
postscript,
temp_script_buffer,
this_transpiler.fs.top_level_dir,
package_json_dir,
this_transpiler.env,
&.{},
ctx.debug.silent,

View File

@@ -1473,7 +1473,7 @@ pub const Interpreter = struct {
return code;
}
pub fn initAndRunFromSource(ctx: bun.CLI.Command.Context, mini: *JSC.MiniEventLoop, path_for_errors: []const u8, src: []const u8) !ExitCode {
pub fn initAndRunFromSource(ctx: bun.CLI.Command.Context, mini: *JSC.MiniEventLoop, path_for_errors: []const u8, src: []const u8, cwd: ?[]const u8) !ExitCode {
bun.Analytics.Features.standalone_shell += 1;
var shargs = ShellArgs.init();
defer shargs.deinit();
@@ -1505,7 +1505,7 @@ pub const Interpreter = struct {
shargs,
jsobjs,
null,
null,
cwd,
)) {
.err => |*e| {
e.throwMini();

View File

@@ -649,3 +649,96 @@ describe("should handle run case", () => {
});
}
});
describe("should run scripts from the project root (#16169)", async () => {
const dir = tempDirWithFiles("test", {
"run_here": {
"myscript.ts": "console.log('successful run')",
"package.json": JSON.stringify({
scripts: { "sample": "pwd", "runscript": "bun myscript.ts" },
}),
"dont_run_in_here": {
"runme.ts": "console.log('do run this script')",
},
},
});
it("outside", () => {
const run_outside = spawnSync({
cmd: [bunExe(), "run", "sample"],
cwd: dir + "/run_here",
env: bunEnv,
});
expect(run_outside.stdout.toString()).toContain("run_here");
expect(run_outside.stdout.toString()).not.toContain("dont_run_in_here");
expect(run_outside.exitCode).toBe(0);
});
it("inside", () => {
const run_inside = spawnSync({
cmd: [bunExe(), "run", "sample"],
cwd: dir + "/run_here/dont_run_in_here",
env: bunEnv,
});
expect(run_inside.stdout.toString()).toContain("run_here");
expect(run_inside.stdout.toString()).not.toContain("dont_run_in_here");
expect(run_inside.exitCode).toBe(0);
});
it("inside --shell=bun", () => {
const run_inside = spawnSync({
cmd: [bunExe(), "--shell=bun", "run", "sample"],
cwd: dir + "/run_here/dont_run_in_here",
env: bunEnv,
});
expect(run_inside.stdout.toString()).toContain("run_here");
expect(run_inside.stdout.toString()).not.toContain("dont_run_in_here");
expect(run_inside.exitCode).toBe(0);
});
it("inside script", () => {
const run_inside = spawnSync({
cmd: [bunExe(), "run", "runme.ts"],
cwd: dir + "/run_here/dont_run_in_here",
env: bunEnv,
});
expect(run_inside.stdout.toString()).toContain("do run this script");
expect(run_inside.exitCode).toBe(0);
});
it("inside wrong script", () => {
const run_inside = spawnSync({
cmd: [bunExe(), "run", "myscript.ts"],
cwd: dir + "/run_here/dont_run_in_here",
env: bunEnv,
});
const stderr = run_inside.stderr.toString();
if (stderr.includes("myscript.ts") && stderr.includes("EACCES")) {
// for some reason on musl, the run_here folder is in $PATH
// 'error: Failed to run "myscript.ts" due to:\nEACCES: run_here/myscript.ts: Permission denied (posix_spawn())'
} else {
expect(stderr).toBe('error: Script not found "myscript.ts"\n');
}
expect(run_inside.exitCode).toBe(1);
});
it("outside 2", () => {
const run_outside_script = spawnSync({
cmd: [bunExe(), "runscript"],
cwd: dir + "/run_here",
env: bunEnv,
});
expect(run_outside_script.stdout.toString()).toBe("successful run\n");
expect(run_outside_script.exitCode).toBe(0);
});
it("inside 2", () => {
const run_inside_script = spawnSync({
cmd: [bunExe(), "runscript"],
cwd: dir + "/run_here/dont_run_in_here",
env: bunEnv,
});
expect(run_inside_script.stdout.toString()).toBe("successful run\n");
expect(run_inside_script.exitCode).toBe(0);
});
});

View File

@@ -50,14 +50,14 @@ echo My name is bun-hello2
}
});
test("issue #10132, bun run sets cwd", async () => {
test("issue #10132, bun run sets cwd for script, matching npm", async () => {
$.cwd(dir);
const currentPwd = (await $`${bunExe()} run get-pwd`.text()).trim();
expect(currentPwd).toBe(dir);
const currentPwd2 = join(currentPwd, "subdir", "one");
$.cwd(currentPwd2);
expect((await $`${bunExe()} run get-pwd`.text()).trim()).toBe(currentPwd2);
expect((await $`${bunExe()} run get-pwd`.text()).trim()).toBe(dir);
$.cwd(process.cwd());
});