Skip to content

Commit 7f954d1

Browse files
refactor: Leverage Python project root detection for jest-runner resolution
Instead of duplicating monorepo detection logic in JavaScript, leverage the existing Python _find_node_project_root and add _find_monorepo_root functions. Pass the detected monorepo root via CODEFLASH_MONOREPO_ROOT environment variable to the loop-runner. This approach: - Reuses existing Python project detection logic - Provides a reliable monorepo root hint to JavaScript - Maintains fallback directory traversal for edge cases Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 8223796 commit 7f954d1

2 files changed

Lines changed: 48 additions & 2 deletions

File tree

codeflash/languages/javascript/test_runner.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,33 @@ def _find_node_project_root(file_path: Path) -> Path | None:
296296
return None
297297

298298

299+
def _find_monorepo_root(start_path: Path) -> Path | None:
300+
"""Find the monorepo workspace root by looking for workspace markers.
301+
302+
Traverses up from the given path to find a directory containing
303+
monorepo workspace markers like yarn.lock, pnpm-workspace.yaml, etc.
304+
305+
Args:
306+
start_path: A path within the monorepo.
307+
308+
Returns:
309+
The monorepo root directory, or None if not found.
310+
311+
"""
312+
monorepo_markers = ["yarn.lock", "pnpm-workspace.yaml", "lerna.json", "package-lock.json"]
313+
current = start_path if start_path.is_dir() else start_path.parent
314+
315+
while current != current.parent:
316+
# Check for monorepo markers
317+
if any((current / marker).exists() for marker in monorepo_markers):
318+
# Verify it has node_modules (it's the workspace root)
319+
if (current / "node_modules").exists():
320+
return current
321+
current = current.parent
322+
323+
return None
324+
325+
299326
def _find_jest_config(project_root: Path) -> Path | None:
300327
"""Find Jest configuration file in the project.
301328
@@ -797,6 +824,12 @@ def run_jest_benchmarking_tests(
797824
jest_env["JEST_JUNIT_SUITE_NAME"] = "{filepath}"
798825
jest_env["JEST_JUNIT_ADD_FILE_ATTRIBUTE"] = "true"
799826
jest_env["JEST_JUNIT_INCLUDE_CONSOLE_OUTPUT"] = "true"
827+
828+
# Pass monorepo root to loop-runner for jest-runner resolution
829+
monorepo_root = _find_monorepo_root(effective_cwd)
830+
if monorepo_root:
831+
jest_env["CODEFLASH_MONOREPO_ROOT"] = str(monorepo_root)
832+
logger.debug(f"Detected monorepo root: {monorepo_root}")
800833
codeflash_sqlite_file = get_run_tmp_file(Path("test_return_values_0.sqlite"))
801834
jest_env["CODEFLASH_OUTPUT_FILE"] = str(codeflash_sqlite_file)
802835
jest_env["CODEFLASH_TEST_ITERATION"] = "0"

packages/codeflash/runtime/loop-runner.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ const fs = require('fs');
3434

3535
/**
3636
* Resolve jest-runner with monorepo support.
37-
* Walks up the directory tree looking for node_modules/jest-runner.
37+
* Uses CODEFLASH_MONOREPO_ROOT environment variable if available,
38+
* otherwise walks up the directory tree looking for node_modules/jest-runner.
3839
*/
3940
function resolveJestRunner() {
4041
// Try standard resolution first (works in simple projects)
@@ -44,7 +45,19 @@ function resolveJestRunner() {
4445
// Standard resolution failed - try monorepo-aware resolution
4546
}
4647

47-
// Walk up from cwd looking for workspace root markers and node_modules
48+
// If Python detected a monorepo root, check there first
49+
const monorepoRoot = process.env.CODEFLASH_MONOREPO_ROOT;
50+
if (monorepoRoot) {
51+
const jestRunnerPath = path.join(monorepoRoot, 'node_modules', 'jest-runner');
52+
if (fs.existsSync(jestRunnerPath)) {
53+
const packageJsonPath = path.join(jestRunnerPath, 'package.json');
54+
if (fs.existsSync(packageJsonPath)) {
55+
return jestRunnerPath;
56+
}
57+
}
58+
}
59+
60+
// Fallback: Walk up from cwd looking for node_modules/jest-runner
4861
const monorepoMarkers = ['yarn.lock', 'pnpm-workspace.yaml', 'lerna.json', 'package-lock.json'];
4962
let currentDir = process.cwd();
5063
const visitedDirs = new Set();

0 commit comments

Comments
 (0)