Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions swiftide-docker-executor/Dockerfile.tests
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ COPY . /app

WORKDIR /app/

ENV TEST_VAR="test"
59 changes: 55 additions & 4 deletions swiftide-docker-executor/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,33 @@ async fn test_runs_docker_and_echos() {
);
}

#[test_log::test(tokio::test(flavor = "multi_thread"))]
async fn test_shell_reads_etc_profile() {
let executor = DockerExecutor::default()
.with_dockerfile(TEST_DOCKERFILE)
.with_context_path(".")
.with_image_name("test-etc-profile")
.to_owned()
.start()
.await
.unwrap();

// Append a marker export to /etc/profile inside the container
let append_cmd = r#"printf '\nexport PROFILE_MARKER=from_profile\n' >> /etc/profile && tail -n 5 /etc/profile"#;
let _ = executor
.exec_cmd(&Command::shell(append_cmd))
.await
.unwrap();

// Now run a simple shell command that should see the marker via login shell
let output = executor
.exec_cmd(&Command::shell("echo $PROFILE_MARKER"))
.await
.unwrap();

assert_eq!(output.to_string(), "from_profile");
}

#[test_log::test(tokio::test(flavor = "multi_thread"))]
async fn test_runs_on_alpine() {
let executor = DockerExecutor::default()
Expand Down Expand Up @@ -872,12 +899,36 @@ async fn test_clear_env() {

let output = executor.exec_cmd(&Command::shell("env")).await.unwrap();

// Check that common host env vars are not present
// TEST_VAR is set via Dockerfile.tests; with clear_env it should be absent
let env_output = output.to_string();
dbg!(&env_output);
assert!(!env_output.contains("HOME="), "HOME env propagated");
assert!(!env_output.contains("HOSTNAME="), "HOSTNAME env propagated");
assert!(!env_output.contains("PATH="), "PATH env propagated");
assert!(
!env_output.contains("TEST_VAR=test"),
"TEST_VAR should be cleared when clear_env is set"
);
}

#[test_log::test(tokio::test(flavor = "multi_thread"))]
async fn test_no_clear_env() {
// test that common host env vars are set in the container
let executor = DockerExecutor::default()
.with_dockerfile(TEST_DOCKERFILE)
.with_context_path(".")
.with_image_name("test-no-env")
.to_owned()
.start()
.await
.unwrap();

let output = executor.exec_cmd(&Command::shell("env")).await.unwrap();

// TEST_VAR is set via Dockerfile.tests; without clear_env it should be present
let env_output = output.to_string();
dbg!(&env_output);
assert!(
env_output.contains("TEST_VAR=test"),
"TEST_VAR should be present without clear_env"
);
}

#[test_log::test(tokio::test(flavor = "multi_thread"))]
Expand Down
17 changes: 14 additions & 3 deletions swiftide-docker-service/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,18 @@ impl ShellExecutor for MyShellExecutor {
let workdir = cwd.unwrap_or_else(|| ".".to_string());
let workdir_path = Path::new(&workdir);

let has_bash = Path::new("/bin/bash").exists();

if is_background(&command) {
tracing::info!("Running command in background");
// Don't capture stdout or stderr, and don't wait for child process.
let mut cmd = Command::new("sh");
let mut cmd = Command::new(if has_bash { "/bin/bash" } else { "sh" });
if has_bash {
cmd.arg("--login");
}

apply_env_settings(&mut cmd, env_clear, env_remove, envs);

// Don't capture stdout or stderr, and don't wait for child process.
cmd.arg("-c")
.arg(command)
.current_dir(workdir_path)
Expand Down Expand Up @@ -107,9 +114,13 @@ impl ShellExecutor for MyShellExecutor {
} else {
tracing::info!("no shebang detected; running as command");

let mut cmd = Command::new("sh");
let mut cmd = Command::new(if has_bash { "/bin/bash" } else { "sh" });

apply_env_settings(&mut cmd, env_clear, env_remove, envs);

if has_bash {
cmd.arg("--login");
}
cmd.arg("-c")
.arg(&command)
.current_dir(workdir_path)
Expand Down