Skip to content

Commit e6514e7

Browse files
Merge branch 'main' into update-docs
2 parents 9c8fe2d + a307d81 commit e6514e7

File tree

7 files changed

+67
-56
lines changed

7 files changed

+67
-56
lines changed

.github/workflows/e2e-topological-sort.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: E2E - Topological Sort
1+
name: E2E - Topological Sort (Worktree)
22

33
on:
44
pull_request:
@@ -8,7 +8,7 @@ on:
88
workflow_dispatch:
99

1010
jobs:
11-
topological-sort-optimization:
11+
topological-sort-worktree-optimization:
1212
# Dynamically determine if environment is needed only when workflow files change and contributor is external
1313
environment: ${{ (github.event_name == 'workflow_dispatch' || (contains(toJSON(github.event.pull_request.files.*.filename), '.github/workflows/') && github.event.pull_request.user.login != 'misrasaurabh1' && github.event.pull_request.user.login != 'KRRT7')) && 'external-trusted-contributors' || '' }}
1414
runs-on: ubuntu-latest
@@ -90,4 +90,4 @@ jobs:
9090
- name: Run Codeflash to optimize code
9191
id: optimize_code
9292
run: |
93-
uv run python tests/scripts/end_to_end_test_topological_sort.py
93+
uv run python tests/scripts/end_to_end_test_topological_sort_worktree.py

codeflash/cli_cmds/cmd_init.py

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -155,20 +155,30 @@ def ask_run_end_to_end_test(args: Namespace) -> None:
155155
run_end_to_end_test(args, bubble_sort_path, bubble_sort_test_path)
156156

157157

158-
def is_valid_pyproject_toml(pyproject_toml_path: Path) -> dict[str, Any] | None:
158+
def is_valid_pyproject_toml(pyproject_toml_path: Path) -> tuple[dict[str, Any] | None, str]: # noqa: PLR0911
159159
if not pyproject_toml_path.exists():
160-
return None
160+
return None, f"Configuration file not found: {pyproject_toml_path}"
161+
161162
try:
162163
config, _ = parse_config_file(pyproject_toml_path)
163-
except Exception:
164-
return None
164+
except Exception as e:
165+
return None, f"Failed to parse configuration: {e}"
166+
167+
module_root = config.get("module_root")
168+
if not module_root:
169+
return None, "Missing required field: 'module_root'"
170+
171+
if not Path(module_root).is_dir():
172+
return None, f"Invalid 'module_root': directory does not exist at {module_root}"
173+
174+
tests_root = config.get("tests_root")
175+
if not tests_root:
176+
return None, "Missing required field: 'tests_root'"
165177

166-
if "module_root" not in config or config["module_root"] is None or not Path(config["module_root"]).is_dir():
167-
return None
168-
if "tests_root" not in config or config["tests_root"] is None or not Path(config["tests_root"]).is_dir():
169-
return None
178+
if not Path(tests_root).is_dir():
179+
return None, f"Invalid 'tests_root': directory does not exist at {tests_root}"
170180

171-
return config
181+
return config, ""
172182

173183

174184
def should_modify_pyproject_toml() -> tuple[bool, dict[str, Any] | None]:
@@ -180,7 +190,7 @@ def should_modify_pyproject_toml() -> tuple[bool, dict[str, Any] | None]:
180190

181191
pyproject_toml_path = Path.cwd() / "pyproject.toml"
182192

183-
config = is_valid_pyproject_toml(pyproject_toml_path)
193+
config, _message = is_valid_pyproject_toml(pyproject_toml_path)
184194
if config is None:
185195
return True, None
186196

@@ -631,7 +641,7 @@ def check_for_toml_or_setup_file() -> str | None:
631641

632642
def install_github_actions(override_formatter_check: bool = False) -> None: # noqa: FBT001, FBT002
633643
try:
634-
config, config_file_path = parse_config_file(override_formatter_check=override_formatter_check)
644+
config, _config_file_path = parse_config_file(override_formatter_check=override_formatter_check)
635645

636646
ph("cli-github-actions-install-started")
637647
try:

codeflash/code_utils/git_worktree_utils.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ def get_git_project_id() -> str:
3434

3535
def create_worktree_snapshot_commit(worktree_dir: Path, commit_message: str) -> None:
3636
repository = git.Repo(worktree_dir, search_parent_directories=True)
37+
with repository.config_writer() as cw:
38+
if not cw.has_option("user", "name"):
39+
cw.set_value("user", "name", "Codeflash Bot")
40+
if not cw.has_option("user", "email"):
41+
cw.set_value("user", "email", "[email protected]")
42+
3743
repository.git.add(".")
3844
repository.git.commit("-m", commit_message, "--no-verify")
3945

codeflash/lsp/beta.py

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
from pathlib import Path
77
from typing import TYPE_CHECKING, Optional
88

9-
import git
109
from pygls import uris
1110

1211
from codeflash.api.cfapi import get_codeflash_api_key, get_user_id
@@ -155,11 +154,13 @@ def _find_pyproject_toml(workspace_path: str) -> tuple[Path | None, bool]:
155154

156155
# should be called the first thing to initialize and validate the project
157156
@server.feature("initProject")
158-
def init_project(server: CodeflashLanguageServer, params: ValidateProjectParams) -> dict[str, str]: # noqa: PLR0911
157+
def init_project(server: CodeflashLanguageServer, params: ValidateProjectParams) -> dict[str, str]:
159158
from codeflash.cli_cmds.cmd_init import is_valid_pyproject_toml
160159

161-
pyproject_toml_path: Path | None = getattr(params, "config_file", None) or getattr(server.args, "config_file", None)
160+
# Always process args in the init project, the extension can call
161+
server.args_processed_before = False
162162

163+
pyproject_toml_path: Path | None = getattr(params, "config_file", None) or getattr(server.args, "config_file", None)
163164
if pyproject_toml_path is not None:
164165
# if there is a config file provided use it
165166
server.prepare_optimizer_arguments(pyproject_toml_path)
@@ -190,20 +191,12 @@ def init_project(server: CodeflashLanguageServer, params: ValidateProjectParams)
190191
}
191192

192193
server.show_message_log("Validating project...", "Info")
193-
config = is_valid_pyproject_toml(pyproject_toml_path)
194+
config, reason = is_valid_pyproject_toml(pyproject_toml_path)
194195
if config is None:
195196
server.show_message_log("pyproject.toml is not valid", "Error")
196-
return {"status": "error", "message": "not valid", "pyprojectPath": pyproject_toml_path}
197+
return {"status": "error", "message": f"reason: {reason}", "pyprojectPath": pyproject_toml_path}
197198

198199
args = process_args(server)
199-
repo = git.Repo(args.module_root, search_parent_directories=True)
200-
if repo.bare:
201-
return {"status": "error", "message": "Repository is in bare state"}
202-
203-
try:
204-
_ = repo.head.commit
205-
except Exception:
206-
return {"status": "error", "message": "Repository has no commits (unborn HEAD)"}
207200

208201
return {"status": "success", "moduleRoot": args.module_root, "pyprojectPath": pyproject_toml_path, "root": root}
209202

tests/scripts/end_to_end_test_topological_sort.py

Lines changed: 0 additions & 29 deletions
This file was deleted.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import os
2+
import pathlib
3+
4+
from end_to_end_test_utilities import CoverageExpectation, TestConfig, run_codeflash_command, run_with_retries
5+
6+
7+
def run_test(expected_improvement_pct: int) -> bool:
8+
config = TestConfig(
9+
file_path="topological_sort.py",
10+
function_name="Graph.topologicalSort",
11+
test_framework="pytest",
12+
min_improvement_x=0.05,
13+
use_worktree=True,
14+
coverage_expectations=[
15+
CoverageExpectation(
16+
function_name="Graph.topologicalSort",
17+
expected_coverage=100.0,
18+
expected_lines=[25, 26, 27, 28, 29, 30, 31],
19+
)
20+
],
21+
)
22+
cwd = (pathlib.Path(__file__).parent.parent.parent / "code_to_optimize").resolve()
23+
return_var = run_codeflash_command(cwd, config, expected_improvement_pct)
24+
return return_var
25+
26+
27+
if __name__ == "__main__":
28+
exit(run_with_retries(run_test, int(os.getenv("EXPECTED_IMPROVEMENT_PCT", 5))))

tests/scripts/end_to_end_test_utilities.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class TestConfig:
2828
coverage_expectations: list[CoverageExpectation] = field(default_factory=list)
2929
benchmarks_root: Optional[pathlib.Path] = None
3030
enable_async: bool = False
31+
use_worktree: bool = False
3132

3233

3334
def clear_directory(directory_path: str | pathlib.Path) -> None:
@@ -137,6 +138,8 @@ def build_command(
137138
base_command.extend(["--benchmark", "--benchmarks-root", str(benchmarks_root)])
138139
if config.enable_async:
139140
base_command.append("--async")
141+
if config.use_worktree:
142+
base_command.append("--worktree")
140143
return base_command
141144

142145

0 commit comments

Comments
 (0)