bash: use a shell command for shell integration

Prior to #7044, on macOS, on macOS, our shell-integrated command line
would be executed under `exec -l`, which causes bash to be started as a
login shell. This matches the macOS platform norms.

The change to direct command execution meant that we'd skip that path,
and bash would start as a normal interactive (non-login) shell on macOS.

Restore the previous behavior by returning a shell command from our bash
integration routine. This is consistent with the code path used when
shell integration is disabled.

We could alternatively add `--login` to our shell-integrated bash
command line for the macOS build. That would let us continue using the
direct command strategy, but it would also result in having coordinated,
conditional behavior in two places (shell integration? macOS?).
This commit is contained in:
Jon Parise
2025-05-02 10:37:14 -04:00
parent e79bf71f23
commit 5e8c05a709

View File

@ -326,9 +326,8 @@ fn setupBash(
); );
try env.put("ENV", integ_dir); try env.put("ENV", integ_dir);
// Since we built up a command line, we don't need to wrap it in // Join the accumulated arguments to form the final command string.
// ANOTHER shell anymore and can do a direct command. return .{ .shell = try std.mem.joinZ(alloc, " ", args.items) };
return .{ .direct = try args.toOwnedSlice() };
} }
test "bash" { test "bash" {
@ -342,9 +341,7 @@ test "bash" {
const command = try setupBash(alloc, .{ .shell = "bash" }, ".", &env); const command = try setupBash(alloc, .{ .shell = "bash" }, ".", &env);
try testing.expectEqual(2, command.?.direct.len); try testing.expectEqualStrings("bash --posix", command.?.shell);
try testing.expectEqualStrings("bash", command.?.direct[0]);
try testing.expectEqualStrings("--posix", command.?.direct[1]);
try testing.expectEqualStrings("./shell-integration/bash/ghostty.bash", env.get("ENV").?); try testing.expectEqualStrings("./shell-integration/bash/ghostty.bash", env.get("ENV").?);
try testing.expectEqualStrings("1", env.get("GHOSTTY_BASH_INJECT").?); try testing.expectEqualStrings("1", env.get("GHOSTTY_BASH_INJECT").?);
} }
@ -387,9 +384,7 @@ test "bash: inject flags" {
const command = try setupBash(alloc, .{ .shell = "bash --norc" }, ".", &env); const command = try setupBash(alloc, .{ .shell = "bash --norc" }, ".", &env);
try testing.expectEqual(2, command.?.direct.len); try testing.expectEqualStrings("bash --posix", command.?.shell);
try testing.expectEqualStrings("bash", command.?.direct[0]);
try testing.expectEqualStrings("--posix", command.?.direct[1]);
try testing.expectEqualStrings("1 --norc", env.get("GHOSTTY_BASH_INJECT").?); try testing.expectEqualStrings("1 --norc", env.get("GHOSTTY_BASH_INJECT").?);
} }
@ -400,9 +395,7 @@ test "bash: inject flags" {
const command = try setupBash(alloc, .{ .shell = "bash --noprofile" }, ".", &env); const command = try setupBash(alloc, .{ .shell = "bash --noprofile" }, ".", &env);
try testing.expectEqual(2, command.?.direct.len); try testing.expectEqualStrings("bash --posix", command.?.shell);
try testing.expectEqualStrings("bash", command.?.direct[0]);
try testing.expectEqualStrings("--posix", command.?.direct[1]);
try testing.expectEqualStrings("1 --noprofile", env.get("GHOSTTY_BASH_INJECT").?); try testing.expectEqualStrings("1 --noprofile", env.get("GHOSTTY_BASH_INJECT").?);
} }
} }
@ -419,18 +412,14 @@ test "bash: rcfile" {
// bash --rcfile // bash --rcfile
{ {
const command = try setupBash(alloc, .{ .shell = "bash --rcfile profile.sh" }, ".", &env); const command = try setupBash(alloc, .{ .shell = "bash --rcfile profile.sh" }, ".", &env);
try testing.expectEqual(2, command.?.direct.len); try testing.expectEqualStrings("bash --posix", command.?.shell);
try testing.expectEqualStrings("bash", command.?.direct[0]);
try testing.expectEqualStrings("--posix", command.?.direct[1]);
try testing.expectEqualStrings("profile.sh", env.get("GHOSTTY_BASH_RCFILE").?); try testing.expectEqualStrings("profile.sh", env.get("GHOSTTY_BASH_RCFILE").?);
} }
// bash --init-file // bash --init-file
{ {
const command = try setupBash(alloc, .{ .shell = "bash --init-file profile.sh" }, ".", &env); const command = try setupBash(alloc, .{ .shell = "bash --init-file profile.sh" }, ".", &env);
try testing.expectEqual(2, command.?.direct.len); try testing.expectEqualStrings("bash --posix", command.?.shell);
try testing.expectEqualStrings("bash", command.?.direct[0]);
try testing.expectEqualStrings("--posix", command.?.direct[1]);
try testing.expectEqualStrings("profile.sh", env.get("GHOSTTY_BASH_RCFILE").?); try testing.expectEqualStrings("profile.sh", env.get("GHOSTTY_BASH_RCFILE").?);
} }
} }
@ -476,25 +465,13 @@ test "bash: additional arguments" {
// "-" argument separator // "-" argument separator
{ {
const command = try setupBash(alloc, .{ .shell = "bash - --arg file1 file2" }, ".", &env); const command = try setupBash(alloc, .{ .shell = "bash - --arg file1 file2" }, ".", &env);
try testing.expectEqual(6, command.?.direct.len); try testing.expectEqualStrings("bash --posix - --arg file1 file2", command.?.shell);
try testing.expectEqualStrings("bash", command.?.direct[0]);
try testing.expectEqualStrings("--posix", command.?.direct[1]);
try testing.expectEqualStrings("-", command.?.direct[2]);
try testing.expectEqualStrings("--arg", command.?.direct[3]);
try testing.expectEqualStrings("file1", command.?.direct[4]);
try testing.expectEqualStrings("file2", command.?.direct[5]);
} }
// "--" argument separator // "--" argument separator
{ {
const command = try setupBash(alloc, .{ .shell = "bash -- --arg file1 file2" }, ".", &env); const command = try setupBash(alloc, .{ .shell = "bash -- --arg file1 file2" }, ".", &env);
try testing.expectEqual(6, command.?.direct.len); try testing.expectEqualStrings("bash --posix -- --arg file1 file2", command.?.shell);
try testing.expectEqualStrings("bash", command.?.direct[0]);
try testing.expectEqualStrings("--posix", command.?.direct[1]);
try testing.expectEqualStrings("--", command.?.direct[2]);
try testing.expectEqualStrings("--arg", command.?.direct[3]);
try testing.expectEqualStrings("file1", command.?.direct[4]);
try testing.expectEqualStrings("file2", command.?.direct[5]);
} }
} }