Skip to content

Commit

Permalink
chore: implement rust support (#12)
Browse files Browse the repository at this point in the history
* chore: implement rust support

* chore: remove commented code
  • Loading branch information
nully0x authored Nov 29, 2024
1 parent 29fa715 commit 7b629e0
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 63 deletions.
16 changes: 8 additions & 8 deletions src/utils/dockerUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,20 @@ export async function buildDockerImage(
export async function runInDocker(
imageName: string,
command: string,
): Promise<string> {
): Promise<{ stdout: string; stderr: string; exitCode: number }> {
const containerName = `container-${Date.now()}-${Math.random().toString(36).substring(7)}`;
try {
const { stdout, stderr } = await execAsync(
`docker run --name ${containerName} --rm ${imageName} ${command}`,
);
return stdout + stderr;
return { stdout, stderr, exitCode: 0 };
} catch (error: any) {
// For test failures, we want to capture the output rather than treat it as an error
if (error.stdout || error.stderr) {
return error.stdout + error.stderr;
}
// For actual Docker errors, return an error message
return `Docker execution error: ${error.message}`;
// For test or compilation failures, return the output and error code
return {
stdout: error.stdout || "",
stderr: error.stderr || "",
exitCode: error.code || 1,
};
} finally {
// Ensure the container is removed even if there's an error
await removeContainer(containerName).catch(console.error);
Expand Down
80 changes: 31 additions & 49 deletions src/utils/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,21 +60,31 @@ export async function runTestProcess(request: TestRunRequest): Promise<void> {
progress.progress_details.current_step,
);

const appDir = path.join(repoDir, "app");
await fs.mkdir(appDir, { recursive: true });

const testFileName = `stage${progress.progress_details.current_step}${TestRepoManager.getTestExtension(language)}`;
await fs.writeFile(path.join(appDir, testFileName), testContent);
logger.info("Test file written", { testFileName });
if (language === "rust") {
const testsDir = path.join(repoDir, "tests");
await fs.mkdir(testsDir, { recursive: true });
const testFileName = `stage${progress.progress_details.current_step}${TestRepoManager.getTestExtension(language)}`;
await fs.writeFile(path.join(testsDir, testFileName), testContent);
} else {
const appDir = path.join(repoDir, "app");
await fs.mkdir(appDir, { recursive: true });
const testFileName = `stage${progress.progress_details.current_step}${TestRepoManager.getTestExtension(language)}`;
await fs.writeFile(path.join(appDir, testFileName), testContent);
}

// Create run.sh with modified commands
const runScript = `#!/bin/bash
set -e # Exit on any error
# Run the tests based on the language
if [ -f "requirements.txt" ]; then
# For Python projects
pytest ./app/stage${progress.progress_details.current_step}${TestRepoManager.getTestExtension(language)} -v
elif [ -f "Cargo.toml" ]; then
# For Rust projects
# Build first (quietly)
cargo build > /dev/null 2>&1
# Run tests and show only test output
cargo test --test stage${progress.progress_details.current_step}_test
else
# For TypeScript projects
bun test ./app/stage${progress.progress_details.current_step}${TestRepoManager.getTestExtension(language)}
Expand All @@ -94,23 +104,28 @@ export async function runTestProcess(request: TestRunRequest): Promise<void> {
stage: progress.progress_details.current_step,
});

const testOutput = await runInDocker(imageName, languageConfig.runCommand);
const testResult = await runInDocker(imageName, languageConfig.runCommand);
logger.info("Test execution completed", { commitSha });
logger.info("Test output:", { testOutput });
logger.info("Test output:", {
stdout: testResult.stdout,
stderr: testResult.stderr,
exitCode: testResult.exitCode,
});

// Clean and parse the test output
const cleanedOutput = cleanTestOutput(testOutput);
const success = isTestSuccessful(testOutput);
// Success is now determined by exit code(using this to avoid having to parse stdout/stderr for success/failure)
const success = testResult.exitCode === 0;
const output = success
? testResult.stdout
: `${testResult.stderr}\n${testResult.stdout}`;

const testResult: TestResult = {
const result: TestResult = {
event_type: EVENT_TYPE,
repoUrl,
commitSha,
success,
output: cleanedOutput,
output: output.trim(),
};

await reportResults(commitSha, testResult);
await reportResults(commitSha, result);
} catch (error: any) {
logger.error("Error during test process", { error, commitSha });
const errorMessage =
Expand All @@ -134,36 +149,3 @@ export async function runTestProcess(request: TestRunRequest): Promise<void> {
}
}
}

function isTestSuccessful(output: string): boolean {
if (output.includes("pytest")) {
// For Python tests - check for failures and errors
const hasFailed =
output.includes(" FAILED ") ||
output.includes("= FAILURES =") ||
output.includes(" ERROR ") ||
output.includes("!!!!!!!!!!!!!!!!!!!! Interrupted:");
return !hasFailed;
} else {
// For TypeScript tests (unchanged)
const failMatch = output.match(/(\d+)\s+fail/);
const failCount = failMatch ? parseInt(failMatch[1]) : 0;
return failCount === 0;
}
}

function cleanTestOutput(output: string): string {
if (output.includes("pytest")) {
// For Python tests, return the complete test output
return output.trim();
} else {
// Handle TypeScript test output (unchanged)
const testRunMatch = output.match(
/app\/stage\d+\.test\.ts:[\s\S]+?Ran \d+ tests across \d+ files\./,
);
if (testRunMatch) {
return testRunMatch[0].trim();
}
}
return output.trim();
}
2 changes: 1 addition & 1 deletion src/utils/testRepoManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export class TestRepoManager {
public static getTestExtension(language: string): string {
const extensions: Record<string, string> = {
typescript: ".test.ts",
rust: ".test.rs",
rust: "_test.rs",
python: "_test.py",
// Add more languages as needed
};
Expand Down
6 changes: 1 addition & 5 deletions supportedLanguageDockerfiles/rust/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@ WORKDIR /app
# Copy the entire application
COPY . .

# Build dependencies to cache them
RUN cargo build --release

# Make the run.sh script executable
RUN chmod +x /app/.hxckr/run.sh

# Make the run.sh script executable
ENTRYPOINT ["/bin/bash"]
CMD ["/bin/bash"]

0 comments on commit 7b629e0

Please sign in to comment.