Skip to content

Conversation

@sidedwards
Copy link
Owner

No description provided.

- Implement function to analyze commit history and extract a minimal style guide
- Store the learned commit style for the repository or per author
- Load previously learned styles and use them as the default
- Add support for different commit formats (Conventional, Semantic, Angular, Kernel)
- Allow resetting the default format

BREAKING CHANGE: Removed the `build.ts` file and related functionality
- Add 'update' task to pull latest changes and install dependencies
- Update dependencies in deno.lock
- Improve commit message generator logic

BREAKING CHANGE: Removed 'install' task, use 'update' instead
- Add support for multiple commit formats (Conventional, Angular, Semantic, Linux Kernel)
- Introduce repository and author-specific commit styles
- Add instructions for updating the tool
- Expand usage examples for different commit formats

BREAKING CHANGE: Remove basic auth support in favor of OAuth2
@sidedwards sidedwards merged commit 48569aa into main Oct 24, 2024
@sidedwards sidedwards deleted the r/0.0.5 branch October 24, 2024 11:10
@sidedwards
Copy link
Owner Author

@CodiumAI-Agent /review

@QodoAI-Agent
Copy link

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 5 🔵🔵🔵🔵🔵
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Possible Issue

The getCommitMessage function has been updated to include post-processing logic for formatting commit messages. Ensure that the logic for separating body lines and breaking changes is robust and handles edge cases, such as unexpected input or malformed commit messages.

async function getCommitMessage(
    diff: string, 
    apiKey: string,
    systemPrompt?: string,
): Promise<string> {
    const loadingId = startLoading('Generating commit message...');

    try {
        const anthropic = new Anthropic({
            apiKey: apiKey,
        });

        const msg = await anthropic.messages.create({
            model: "claude-3-haiku-20240307",
            max_tokens: 1024,
            temperature: 0.2,
            system: systemPrompt,
            messages: [{ 
                role: "user", 
                content: `Generate a commit message for these changes:\n\n${diff}\n\nIMPORTANT: 
1. Generate ONLY the commit message
2. Do not include any explanatory text or formatting
3. Do not repeat the header line
4. Follow this exact structure:
   - One header line
   - One blank line
   - Bullet points for changes
   - Breaking changes (if any)
5. Never include the diff or any git output`
            }],
        });

        const content = msg.content[0];
        if (!('text' in content)) {
            throw new Error('Unexpected response format from Claude');
        }

        // Post-process the message to ensure proper formatting
        const lines = content.text.split('\n').filter(line => line.trim() !== '');
        const headerLine = lines[0];
        const bodyLines = [];
        const breakingChanges = [];

        // Separate body and breaking changes
        let isBreakingChange = false;
        for (const line of lines.slice(1)) {
            if (line.startsWith('BREAKING CHANGE:')) {
                isBreakingChange = true;
                breakingChanges.push(line);
            } else if (isBreakingChange) {
                breakingChanges.push(line);
            } else {
                bodyLines.push(line);
            }
        }

        // Combine with proper spacing
        const parts = [
            headerLine,
            '',  // Blank line after header
            ...bodyLines
        ];

        // Add breaking changes with blank line before them if they exist
        if (breakingChanges.length > 0) {
            parts.push('');  // Extra blank line before breaking changes
            parts.push(...breakingChanges);
        }

        return parts.join('\n');
    } finally {
        stopLoading(loadingId);
    }
}
Error Handling

The checkStagedChanges function now throws an error if no staged changes are found. Validate that this behavior aligns with the intended user experience and does not cause unnecessary interruptions in workflows.

async function checkStagedChanges(): Promise<string> {
    // First get list of staged files
    const stagedFiles = await getStagedFiles();
    let fullDiff = '';

    // Get diff for each staged file
    for (const file of stagedFiles) {
        const command = new Deno.Command("git", {
            args: ["diff", "--staged", "--unified=3", "--", file],
            stdout: "piped",
            stderr: "piped",
        });

        const output = await command.output();

        if (!output.success) {
            const errorMessage = new TextDecoder().decode(output.stderr);
            throw new Error(`Failed to get staged changes for ${file}: ${errorMessage}`);
        }

        fullDiff += new TextDecoder().decode(output.stdout) + '\n';
    }

    if (!fullDiff) {
        throw new Error('No staged changes found');
    }

    return fullDiff;
Installation Script

The new installation script compiles the main script and places it in a specific directory. Verify that the script handles all edge cases, such as missing permissions or unsupported environments, and provides clear error messages.

#!/usr/bin/env -S deno run --allow-read --allow-write --allow-run

import { join } from "https://deno.land/std/path/mod.ts";

async function install() {
    const homeDir = Deno.env.get("HOME") || Deno.env.get("USERPROFILE");
    if (!homeDir) {
        throw new Error("Could not find home directory");
    }

    // Create bin directory if it doesn't exist
    const binDir = join(homeDir, ".local", "bin");
    try {
        await Deno.mkdir(binDir, { recursive: true });
    } catch (error) {
        if (!(error instanceof Deno.errors.AlreadyExists)) {
            throw error;
        }
    }

    // Compile the script
    const scriptPath = join(binDir, "auto-commit");
    await Deno.run({
        cmd: [
            "deno",
            "compile",
            "--allow-net",
            "--allow-read",
            "--allow-write",
            "--allow-env",
            "--allow-run=git,vim",
            "--output",
            scriptPath,
            "main.ts"
        ],
        stdout: "inherit",
        stderr: "inherit",
    }).status();

    console.log(`\n✓ Installed auto-commit to ${scriptPath}`);
    console.log('\nMake sure ~/.local/bin is in your PATH. Add this to your ~/.bashrc or ~/.zshrc:');
    console.log('\nexport PATH="$HOME/.local/bin:$PATH"\n');
}

install().catch(console.error);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants