This commit is contained in:
@@ -115,6 +115,13 @@ class GitWorkspace:
|
|||||||
deleted += int(remove) if remove.isdigit() else 0
|
deleted += int(remove) if remove.isdigit() else 0
|
||||||
return ChangeSummary(tuple(files), added, deleted)
|
return ChangeSummary(tuple(files), added, deleted)
|
||||||
|
|
||||||
|
def diff(self, limit: int = 12_000) -> str:
|
||||||
|
output = self._git("diff", "--no-ext-diff", "--unified=3").stdout
|
||||||
|
if len(output) <= limit:
|
||||||
|
return output
|
||||||
|
half = limit // 2
|
||||||
|
return output[:half] + "\n...[diff middle omitted]...\n" + output[-half:]
|
||||||
|
|
||||||
def commit(self, report_id: int) -> str:
|
def commit(self, report_id: int) -> str:
|
||||||
self._git("add", "--all")
|
self._git("add", "--all")
|
||||||
self._git("commit", "-m", f"Fix failure report #{report_id}")
|
self._git("commit", "-m", f"Fix failure report #{report_id}")
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ class AutomationWorker:
|
|||||||
report.id,
|
report.id,
|
||||||
attempt,
|
attempt,
|
||||||
)
|
)
|
||||||
|
discarded_diff = workspace.diff()
|
||||||
workspace.restore_checkpoint(valid_checkpoint)
|
workspace.restore_checkpoint(valid_checkpoint)
|
||||||
restored_state = (
|
restored_state = (
|
||||||
"The last syntax-valid changes were restored. Correct them without recreating "
|
"The last syntax-valid changes were restored. Correct them without recreating "
|
||||||
@@ -131,7 +132,8 @@ class AutomationWorker:
|
|||||||
report,
|
report,
|
||||||
RuntimeError(
|
RuntimeError(
|
||||||
f"{exception}\n{restored_state} Make smaller edits and run php -l on each "
|
f"{exception}\n{restored_state} Make smaller edits and run php -l on each "
|
||||||
"changed PHP file."
|
"changed PHP file. Reconstruct the intended application fix from this discarded "
|
||||||
|
f"patch excerpt, correcting its syntax:\n{discarded_diff}"
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -83,4 +83,25 @@ def test_checkpoint_restores_last_valid_changes(tmp_path) -> None:
|
|||||||
workspace.restore_checkpoint(checkpoint)
|
workspace.restore_checkpoint(checkpoint)
|
||||||
|
|
||||||
assert tracked.read_text() == "<?php\nreturn ['valid'];\n"
|
assert tracked.read_text() == "<?php\nreturn ['valid'];\n"
|
||||||
assert added.exists()
|
assert added.exists()
|
||||||
|
|
||||||
|
|
||||||
|
def test_diff_returns_discarded_patch_excerpt(tmp_path) -> None:
|
||||||
|
workspace = GitWorkspace(settings(workspace_root=tmp_path), 5)
|
||||||
|
workspace.path.mkdir()
|
||||||
|
subprocess.run(["git", "init"], cwd=workspace.path, check=True, capture_output=True)
|
||||||
|
tracked = workspace.path / "service.php"
|
||||||
|
tracked.write_text("<?php\nreturn 'old';\n")
|
||||||
|
subprocess.run(["git", "add", "."], cwd=workspace.path, check=True)
|
||||||
|
subprocess.run(
|
||||||
|
["git", "-c", "user.email=test@example.invalid", "-c", "user.name=Test", "commit", "-m", "base"],
|
||||||
|
cwd=workspace.path,
|
||||||
|
check=True,
|
||||||
|
capture_output=True,
|
||||||
|
)
|
||||||
|
tracked.write_text("<?php\nreturn 'new';\n")
|
||||||
|
|
||||||
|
patch = workspace.diff()
|
||||||
|
|
||||||
|
assert "-return 'old';" in patch
|
||||||
|
assert "+return 'new';" in patch
|
||||||
@@ -158,6 +158,7 @@ def test_php_syntax_failure_discards_attempt_before_full_validation() -> None:
|
|||||||
Mock(returncode=0, stdout="No syntax errors", stderr=""),
|
Mock(returncode=0, stdout="No syntax errors", stderr=""),
|
||||||
Mock(returncode=0, stdout="No syntax errors", stderr=""),
|
Mock(returncode=0, stdout="No syntax errors", stderr=""),
|
||||||
]
|
]
|
||||||
|
workspace.diff.return_value = "--- app/Service.php\n+++ app/Service.php\n+intended fix"
|
||||||
workspace.checkpoint.return_value = "valid-checkpoint"
|
workspace.checkpoint.return_value = "valid-checkpoint"
|
||||||
workspace.commit.return_value = "commit-id"
|
workspace.commit.return_value = "commit-id"
|
||||||
|
|
||||||
@@ -167,6 +168,7 @@ def test_php_syntax_failure_discards_attempt_before_full_validation() -> None:
|
|||||||
assert worker.agent.run.call_count == 2
|
assert worker.agent.run.call_count == 2
|
||||||
assert "unexpected token" in worker.agent.run.call_args_list[1].args[1]
|
assert "unexpected token" in worker.agent.run.call_args_list[1].args[1]
|
||||||
assert "clean repository" in worker.agent.run.call_args_list[1].args[1]
|
assert "clean repository" in worker.agent.run.call_args_list[1].args[1]
|
||||||
|
assert "intended fix" in worker.agent.run.call_args_list[1].args[1]
|
||||||
workspace.restore_checkpoint.assert_called_once_with(None)
|
workspace.restore_checkpoint.assert_called_once_with(None)
|
||||||
worker._run_tests.assert_called_once()
|
worker._run_tests.assert_called_once()
|
||||||
|
|
||||||
@@ -207,6 +209,7 @@ def test_malformed_retry_restores_last_syntax_valid_attempt() -> None:
|
|||||||
Mock(returncode=0, stdout="No syntax errors", stderr=""),
|
Mock(returncode=0, stdout="No syntax errors", stderr=""),
|
||||||
Mock(returncode=0, stdout="No syntax errors", stderr=""),
|
Mock(returncode=0, stdout="No syntax errors", stderr=""),
|
||||||
]
|
]
|
||||||
|
workspace.diff.return_value = "--- app/Service.php\n+++ app/Service.php\n+application repair"
|
||||||
workspace.checkpoint.side_effect = ["checkpoint-1", "checkpoint-3"]
|
workspace.checkpoint.side_effect = ["checkpoint-1", "checkpoint-3"]
|
||||||
workspace.commit.return_value = "commit-id"
|
workspace.commit.return_value = "commit-id"
|
||||||
|
|
||||||
@@ -216,6 +219,7 @@ def test_malformed_retry_restores_last_syntax_valid_attempt() -> None:
|
|||||||
assert worker.agent.run.call_count == 3
|
assert worker.agent.run.call_count == 3
|
||||||
workspace.restore_checkpoint.assert_called_once_with("checkpoint-1")
|
workspace.restore_checkpoint.assert_called_once_with("checkpoint-1")
|
||||||
assert "last syntax-valid changes were restored" in worker.agent.run.call_args_list[2].args[1]
|
assert "last syntax-valid changes were restored" in worker.agent.run.call_args_list[2].args[1]
|
||||||
|
assert "application repair" in worker.agent.run.call_args_list[2].args[1]
|
||||||
assert worker._run_tests.call_count == 2
|
assert worker._run_tests.call_count == 2
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user