Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions codemcp/code_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import tomli

from .common import normalize_file_path, truncate_output_content
from .file_utils import async_open_text
from .git import commit_changes, get_repository_root, is_git_repository
from .shell import run_command

Expand Down Expand Up @@ -218,14 +219,15 @@ async def run_code_command(
return f"Error: {error_msg}"


async def run_formatter_without_commit(file_path: str) -> Tuple[bool, str]:
async def run_formatter_without_commit(file_path: str) -> Tuple[bool, str, str]:
"""Run the formatter on a specific file without performing pre/post commit operations.

Args:
file_path: Absolute path to the file to format

Returns:
A tuple containing (success_status, message)
A tuple containing (success_status, message, post_format_content)
The post_format_content will be an empty string if formatting failed

Raises:
Propagates any unexpected errors during formatting
Expand All @@ -236,7 +238,7 @@ async def run_formatter_without_commit(file_path: str) -> Tuple[bool, str]:
# Get the format command from config - this is the only expected failure mode
format_command = get_command_from_config(project_dir, "format")
if not format_command:
return False, "No format command configured in codemcp.toml"
return False, "No format command configured in codemcp.toml", ""

# Use relative path from project_dir for the formatting command
rel_path = os.path.relpath(file_path, project_dir)
Expand All @@ -251,6 +253,18 @@ async def run_formatter_without_commit(file_path: str) -> Tuple[bool, str]:
text=True,
)

# Read the file after formatting to get the current content
post_format_content = ""
if os.path.exists(file_path):
try:
post_format_content = await async_open_text(file_path, encoding="utf-8")
except Exception as e:
logging.warning(f"Failed to read formatted file: {e}")

# If we get here, the formatter ran successfully
truncated_stdout = truncate_output_content(result.stdout, prefer_end=True)
return True, f"File formatted successfully:\n{truncated_stdout}"
return (
True,
f"File formatted successfully:\n{truncated_stdout}",
post_format_content,
)
20 changes: 18 additions & 2 deletions codemcp/tools/write_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,27 @@ async def write_file_content(

# Try to run the formatter on the file
format_message = ""
formatter_success, formatter_output = await run_formatter_without_commit(file_path)
post_format_content = content
(
formatter_success,
formatter_output,
post_format_content,
) = await run_formatter_without_commit(file_path)
if formatter_success:
logging.info(f"Auto-formatted {file_path}")
if formatter_output.strip():
format_message = f"\nAuto-formatted the file"
# If the file was actually changed by the formatter
if post_format_content and post_format_content != content:
# Update the content in memory (it's already updated on disk)
content = post_format_content

# Show a snippet of the formatted content (first few lines)
lines = post_format_content.split("\n")
snippet_lines = min(7, len(lines)) # Show up to 7 lines
snippet = "\n".join(lines[:snippet_lines])
format_message = (
f"\nAuto-formatted the file. Here's how it looks now:\n{snippet}"
)
else:
# Only log warning if there was actually a format command configured but it failed
if not "No format command configured" in formatter_output:
Expand Down
Loading