Skip to content

Commit a38497f

Browse files
committed
fix: auto-install deps, python3 symlink, detect full commands in fail_to_pass, language-aware test scripts
1 parent 5dfa0c1 commit a38497f

File tree

2 files changed

+50
-7
lines changed

2 files changed

+50
-7
lines changed

Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ FROM debian:bookworm-slim
1313
RUN apt-get update && apt-get install -y --no-install-recommends \
1414
ca-certificates git curl libssl3 \
1515
python3 python3-pip python3-venv \
16-
build-essential \
16+
build-essential nodejs npm \
17+
&& ln -sf /usr/bin/python3 /usr/bin/python \
1718
&& rm -rf /var/lib/apt/lists/*
1819
COPY --from=builder /build/target/release/term-executor /usr/local/bin/
1920
RUN groupadd --system executor && useradd --system --gid executor --create-home executor \

src/task/registry.rs

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,17 +88,32 @@ fn build_test_script(test_patch: &str, fail_to_pass: Option<&str>) -> String {
8888
if !tests.is_empty() {
8989
script.push_str("# Run fail-to-pass tests\n");
9090
for test in &tests {
91-
script.push_str(&format!("python -m pytest {} -x\n", test));
91+
if is_full_command(test) {
92+
// Entry is a complete command (e.g. "npx playwright test ...")
93+
script.push_str(&format!("{}\n", test));
94+
} else {
95+
// Entry is a pytest path
96+
script.push_str(&format!("python3 -m pytest {} -x\n", test));
97+
}
9298
}
9399
}
94100
} else if !test_patch.is_empty() {
95101
script.push_str("# Run test suite\n");
96-
script.push_str("python -m pytest -x\n");
102+
script.push_str("python3 -m pytest -x\n");
97103
}
98104

99105
script
100106
}
101107

108+
fn is_full_command(test: &str) -> bool {
109+
let cmd_prefixes = [
110+
"npx ", "npm ", "node ", "yarn ", "pnpm ", "python ", "python3 ", "pytest ", "cargo ",
111+
"make ", "go ", "mvn ", "gradle ", "dotnet ", "ruby ", "bundle ", "sh ", "bash ", "./",
112+
];
113+
let t = test.trim();
114+
cmd_prefixes.iter().any(|p| t.starts_with(p))
115+
}
116+
102117
fn parse_test_list(raw: &str) -> Vec<String> {
103118
let trimmed = raw.trim();
104119
if trimmed.is_empty() {
@@ -116,8 +131,33 @@ fn parse_test_list(raw: &str) -> Vec<String> {
116131
.collect()
117132
}
118133

134+
fn auto_install_commands(language: &str) -> Option<Vec<String>> {
135+
match language {
136+
"python" => Some(vec![
137+
"pip install -e '.[dev,test]' 2>/dev/null || pip install -e . 2>/dev/null || true".to_string(),
138+
"pip install pytest 2>/dev/null || true".to_string(),
139+
]),
140+
"javascript" | "typescript" => Some(vec![
141+
"npm install --legacy-peer-deps 2>/dev/null || yarn install --frozen-lockfile 2>/dev/null || true".to_string(),
142+
]),
143+
"go" => Some(vec![
144+
"go mod download 2>/dev/null || true".to_string(),
145+
]),
146+
"rust" => Some(vec![
147+
"cargo fetch 2>/dev/null || true".to_string(),
148+
]),
149+
_ => Some(vec![
150+
"pip install -e . 2>/dev/null || npm install 2>/dev/null || true".to_string(),
151+
]),
152+
}
153+
}
154+
119155
fn convert_dataset_entry_to_task(entry: &DatasetEntry) -> Result<SweForgeTask> {
120156
let repo_url = build_repo_url(&entry.repo);
157+
let language = entry
158+
.language
159+
.clone()
160+
.unwrap_or_else(|| "python".to_string());
121161

122162
let f2p: Option<Vec<String>> = entry
123163
.fail_to_pass
@@ -128,12 +168,14 @@ fn convert_dataset_entry_to_task(entry: &DatasetEntry) -> Result<SweForgeTask> {
128168
.as_deref()
129169
.and_then(|s| serde_json::from_str(s).ok());
130170

171+
let install = auto_install_commands(&language);
172+
131173
let workspace = WorkspaceConfig {
132174
repo: repo_url,
133175
version: entry.version.clone().unwrap_or_default(),
134176
base_commit: Some(entry.base_commit.clone()),
135-
install: None,
136-
language: Some("python".to_string()),
177+
install,
178+
language: Some(language),
137179
fail_to_pass: f2p,
138180
pass_to_pass: p2p,
139181
install_config: None,
@@ -311,7 +353,7 @@ mod tests {
311353
let script = build_test_script("diff --git a/t.py b/t.py", None);
312354
assert!(script.contains("git apply"));
313355
assert!(script.contains("diff --git a/t.py b/t.py"));
314-
assert!(script.contains("python -m pytest -x"));
356+
assert!(script.contains("python3 -m pytest -x"));
315357
}
316358

317359
#[test]
@@ -321,7 +363,7 @@ mod tests {
321363
Some(r#"["tests/test_orm.py::test_query"]"#),
322364
);
323365
assert!(script.contains("git apply"));
324-
assert!(script.contains("python -m pytest tests/test_orm.py::test_query -x"));
366+
assert!(script.contains("python3 -m pytest tests/test_orm.py::test_query -x"));
325367
}
326368

327369
#[test]

0 commit comments

Comments
 (0)