scai
Version:
> AI-powered CLI tool for commit messages **and** pull request reviews — using local models.
88 lines (87 loc) • 3.34 kB
JavaScript
// src/commands/ChangeLogUpdateCmd.ts
import { execSync } from 'child_process';
import fs from 'fs/promises';
import path from 'path';
import { runModulePipeline } from '../pipeline/runModulePipeline.js';
import { changelogModule } from '../pipeline/modules/changeLogModule.js';
import { askChangelogApproval } from '../utils/changeLogPrompt.js';
export async function handleStandaloneChangelogUpdate() {
let diff = execSync("git diff", { encoding: "utf-8", stdio: "pipe" }).trim();
if (!diff) {
diff = execSync("git diff --cached", { encoding: "utf-8", stdio: "pipe" }).trim();
}
if (!diff) {
console.log('⚠️ No changes detected for changelog.');
return;
}
let entry = await generateChangelogEntry(diff);
if (!entry) {
console.log('⚠️ No significant changes found.');
return;
}
while (true) {
const userChoice = await askChangelogApproval(entry);
if (userChoice === 'yes') {
const path = await updateChangelogFile(entry);
console.log(`✅ CHANGELOG.md updated: ${path}`);
break;
}
else if (userChoice === 'redo') {
console.log('🔁 Regenerating changelog...');
entry = await generateChangelogEntry(diff);
if (!entry) {
console.log('⚠️ Could not regenerate entry. Exiting.');
break;
}
}
else {
console.log('❌ Skipped changelog update.');
break;
}
}
}
export async function generateChangelogEntry(diff) {
try {
// If no diff is provided, fetch the current diff from git silently
if (!diff) {
diff = execSync("git diff", { encoding: "utf-8", stdio: 'pipe' }).trim();
// If no unstaged changes, fall back to staged changes
if (!diff) {
diff = execSync("git diff --cached", { encoding: "utf-8", stdio: 'pipe' }).trim();
}
}
if (!diff) {
// No changes found, auto cancel by returning null
console.log('⚠️ No changes detected for the changelog.');
return null;
}
// Generate the changelog entry using the diff silently
const result = await runModulePipeline([changelogModule], { content: diff });
const output = result?.summary?.trim();
if (!output || output === 'NO UPDATE') {
// Auto-cancel if no update
console.log('⚠️ No significant changes detected for changelog.');
return null;
}
return output;
}
catch (err) {
console.error("❌ Failed to generate changelog entry:", err.message);
return null;
}
}
export async function updateChangelogFile(entry) {
const root = execSync("git rev-parse --show-toplevel", { encoding: "utf-8" }).trim();
const changelogPath = path.join(root, "CHANGELOG.md");
let existing = '';
try {
existing = await fs.readFile(changelogPath, 'utf-8');
}
catch {
console.log("📄 Creating new CHANGELOG.md");
}
const today = new Date().toISOString().split("T")[0];
const newEntry = `\n\n## ${today}\n\n${entry.trim()}`;
await fs.writeFile(changelogPath, existing + newEntry, 'utf-8');
return changelogPath;
}