Ruff after Claude Code
All checks were successful
Run Python tests (through Pytest) / Test (push) Successful in 25s
Verify Python project can be installed, loaded and have version checked / Test (push) Successful in 23s

This commit is contained in:
Jon Michael Aanes 2025-06-09 18:41:10 +02:00
parent 98f6e9e1bc
commit b4a90227e7
3 changed files with 308 additions and 6 deletions

View File

@ -467,6 +467,109 @@ def get_diff(cwd: Path, base_branch: str, current_branch: str) -> str:
return result.stdout.strip()
def contains_only_ruff_changes(
cwd: Path,
base_branch: str,
current_branch: str,
) -> bool:
"""Check if the branch contains only ruff formatting changes.
Args:
cwd: The current working directory (repository path).
base_branch: The name of the base branch to compare against.
current_branch: The name of the current branch to check.
Returns:
True if the branch contains only ruff formatting changes, False otherwise.
"""
# Get all commit messages to check if they're only ruff-related
commit_messages = get_commit_messages(cwd, base_branch, current_branch)
# If no commits, then no changes at all
if not commit_messages:
return True
# Check if all commits are ruff-related
ruff_related_patterns = [
'ruff',
'format',
'lint',
'auto-fix',
'autofix',
'code style',
'formatting',
]
all_ruff_commits = True
for message in commit_messages:
message_lower = message.lower()
# Skip empty messages
if not message.strip():
continue
# Check if this commit message indicates ruff/formatting changes
is_ruff_commit = any(
pattern in message_lower for pattern in ruff_related_patterns
)
if not is_ruff_commit:
all_ruff_commits = False
break
if not all_ruff_commits:
return False
# Additional check: get the actual diff and analyze it
# This helps catch cases where commit messages might be misleading
try:
diff_result = subprocess.run(
['git', 'diff', f'{base_branch}..{current_branch}'],
check=True,
cwd=cwd,
capture_output=True,
text=True,
)
diff_content = diff_result.stdout
# If no diff content, then only ruff changes
if not diff_content.strip():
return True
# Analyze the diff to see if it contains only whitespace/formatting changes
lines = diff_content.split('\n')
substantive_changes = 0
for line in lines:
# Skip diff headers and file markers
if (
line.startswith('diff --git')
or line.startswith('index ')
or line.startswith('+++')
or line.startswith('---')
):
continue
# Skip context lines (no + or -)
if line.startswith(' ') or not line.strip():
continue
# Count added/removed lines
if line.startswith('+') or line.startswith('-'):
# Remove the +/- prefix and check if it's substantive
content = line[1:].strip()
# Skip empty lines
if not content:
continue
# This is a substantive change if it's not just whitespace
if content and not content.isspace():
substantive_changes += 1
# If we have very few substantive changes and all commits are ruff-related,
# it's likely only formatting changes
return substantive_changes <= 2 # Allow for minimal formatting adjustments
except subprocess.CalledProcessError:
logger.exception('Failed to get diff for ruff-only check')
# If we can't get the diff, fall back to commit message analysis
return all_ruff_commits
def push_changes(
repository_config: RepositoryConfig,
cwd: Path,
@ -480,6 +583,14 @@ def push_changes(
logger.info('No commits made on branch %s, skipping push', branch_name)
return IssueResolution(False)
# Check if the branch contains only ruff formatting changes
if contains_only_ruff_changes(cwd, repository_config.base_branch, branch_name):
logger.info(
'Branch %s contains only ruff formatting changes, skipping MR creation to avoid ruff-only PRs',
branch_name,
)
return IssueResolution(False)
# Get commit messages for PR description
commit_messages = get_commit_messages(
cwd,

View File

@ -69,9 +69,10 @@ class TestClaudeCodeIntegration:
'claude',
'-p',
'--output-format',
'json',
'--max-turns',
'10',
'stream-json',
'--debug',
'--verbose',
'--dangerously-skip-permissions',
issue,
]
assert cmd == expected
@ -84,9 +85,10 @@ class TestClaudeCodeIntegration:
'claude',
'-p',
'--output-format',
'json',
'--max-turns',
'10',
'stream-json',
'--debug',
'--verbose',
'--dangerously-skip-permissions',
'--model',
'claude-3-sonnet',
issue,

View File

@ -0,0 +1,189 @@
import subprocess
import tempfile
from pathlib import Path
from aider_gitea import contains_only_ruff_changes
class TestContainsOnlyRuffChanges:
"""Test the contains_only_ruff_changes function."""
def setup_test_repo(self) -> Path:
"""Create a test git repository."""
temp_dir = Path(tempfile.mkdtemp())
# Initialize git repo
subprocess.run(['git', 'init'], cwd=temp_dir, check=True)
subprocess.run(
['git', 'config', 'user.name', 'Test User'],
cwd=temp_dir,
check=True,
)
subprocess.run(
['git', 'config', 'user.email', 'test@example.com'],
cwd=temp_dir,
check=True,
)
# Create initial content and commit
test_file = temp_dir / 'test.py'
test_file.write_text('def hello():\n print("hello")\n')
subprocess.run(['git', 'add', '.'], cwd=temp_dir, check=True)
subprocess.run(
['git', 'commit', '-m', 'Initial commit'],
cwd=temp_dir,
check=True,
)
# Rename master to main for consistency
subprocess.run(
['git', 'branch', '-m', 'master', 'main'],
cwd=temp_dir,
check=True,
)
return temp_dir
def test_no_commits_returns_true(self):
"""Test that branches with no commits return True."""
temp_dir = self.setup_test_repo()
# Create a new branch but don't commit anything
subprocess.run(
['git', 'checkout', '-b', 'test-branch'],
cwd=temp_dir,
check=True,
)
result = contains_only_ruff_changes(temp_dir, 'main', 'test-branch')
assert result is True
def test_only_ruff_commits_returns_true(self):
"""Test that branches with only ruff-related commits return True."""
temp_dir = self.setup_test_repo()
# Create a new branch and make ruff-related commits
subprocess.run(
['git', 'checkout', '-b', 'test-branch'],
cwd=temp_dir,
check=True,
)
# Modify the file with formatting changes
test_file = temp_dir / 'test.py'
test_file.write_text('def hello():\n print("hello")\n\n') # Added newline
subprocess.run(['git', 'add', '.'], cwd=temp_dir, check=True)
subprocess.run(
['git', 'commit', '-m', 'ruff format changes'],
cwd=temp_dir,
check=True,
)
# Another ruff commit
test_file.write_text(
'def hello():\n print("hello")\n',
) # Removed newline again
subprocess.run(['git', 'add', '.'], cwd=temp_dir, check=True)
subprocess.run(
['git', 'commit', '-m', 'auto-fix lint issues'],
cwd=temp_dir,
check=True,
)
result = contains_only_ruff_changes(temp_dir, 'main', 'test-branch')
assert result is True
def test_substantive_changes_returns_false(self):
"""Test that branches with substantive changes return False."""
temp_dir = self.setup_test_repo()
# Create a new branch and make substantive changes
subprocess.run(
['git', 'checkout', '-b', 'test-branch'],
cwd=temp_dir,
check=True,
)
# Add a new function (substantive change)
test_file = temp_dir / 'test.py'
test_file.write_text(
'def hello():\n print("hello")\n\ndef goodbye():\n print("goodbye")\n',
)
subprocess.run(['git', 'add', '.'], cwd=temp_dir, check=True)
subprocess.run(
['git', 'commit', '-m', 'Add goodbye function'],
cwd=temp_dir,
check=True,
)
result = contains_only_ruff_changes(temp_dir, 'main', 'test-branch')
assert result is False
def test_mixed_commits_returns_false(self):
"""Test that branches with both ruff and substantive commits return False."""
temp_dir = self.setup_test_repo()
# Create a new branch
subprocess.run(
['git', 'checkout', '-b', 'test-branch'],
cwd=temp_dir,
check=True,
)
# First, a substantive change
test_file = temp_dir / 'test.py'
test_file.write_text(
'def hello():\n print("hello world")\n',
) # Changed string
subprocess.run(['git', 'add', '.'], cwd=temp_dir, check=True)
subprocess.run(
['git', 'commit', '-m', 'Update greeting message'],
cwd=temp_dir,
check=True,
)
# Then, a ruff change
test_file.write_text(
'def hello():\n print("hello world")\n\n',
) # Added newline
subprocess.run(['git', 'add', '.'], cwd=temp_dir, check=True)
subprocess.run(['git', 'commit', '-m', 'ruff format'], cwd=temp_dir, check=True)
result = contains_only_ruff_changes(temp_dir, 'main', 'test-branch')
assert result is False
def test_ruff_keywords_in_commit_messages(self):
"""Test various ruff-related keywords in commit messages."""
temp_dir = self.setup_test_repo()
ruff_messages = [
'ruff format',
'Ruff after aider',
'auto-fix lint issues',
'code style formatting',
'Apply formatting changes',
'Lint fixes',
]
for i, message in enumerate(ruff_messages):
# Create a branch for each test
branch_name = f'test-branch-{i}'
subprocess.run(['git', 'checkout', 'main'], cwd=temp_dir, check=True)
subprocess.run(
['git', 'checkout', '-b', branch_name],
cwd=temp_dir,
check=True,
)
# Make a minor formatting change that's always different
test_file = temp_dir / 'test.py'
content = test_file.read_text()
# Add a unique comment to make each change different
content += f'# formatting change {i}\n'
test_file.write_text(content)
subprocess.run(['git', 'add', '.'], cwd=temp_dir, check=True)
subprocess.run(['git', 'commit', '-m', message], cwd=temp_dir, check=True)
result = contains_only_ruff_changes(temp_dir, 'main', branch_name)
assert result is True, f'Failed for message: {message}'