UNPKG

@aaronshaf/ger

Version:

Gerrit CLI and SDK - A modern CLI tool and TypeScript SDK for Gerrit Code Review, built with Effect-TS

104 lines (89 loc) 2.89 kB
import { Effect } from 'effect' import { type ApiError, GerritApiService } from '@/api/gerrit' import type { FileDiffContent } from '@/schemas/gerrit' export interface DiffContext { before: string[] line?: string after: string[] } /** * Extracts context around a specific line number from a diff. * This is a more accurate implementation that properly tracks line numbers * across different diff sections. */ export const extractDiffContext = ( diff: FileDiffContent, targetLine: number, contextLines: number = 2, ): DiffContext => { const context: DiffContext = { before: [], after: [], } let currentNewLine = 1 const _foundTarget = false const collectedLines: Array<{ line: string; lineNum: number; type: 'context' | 'added' }> = [] for (const section of diff.content) { // Context lines (present in both old and new) if (section.ab) { for (const line of section.ab) { collectedLines.push({ line, lineNum: currentNewLine, type: 'context' }) currentNewLine++ } } // Added lines (only in new file) if (section.b) { for (const line of section.b) { collectedLines.push({ line, lineNum: currentNewLine, type: 'added' }) currentNewLine++ } } // Skip lines (large unchanged sections) if (section.skip) { // If target is in skipped section, we can't show context if (currentNewLine <= targetLine && targetLine < currentNewLine + section.skip) { return context // Return empty context } currentNewLine += section.skip } // Removed lines don't affect new file line numbers // section.a is ignored for line counting } // Find the target line and extract context const targetIndex = collectedLines.findIndex((item) => item.lineNum === targetLine) if (targetIndex !== -1) { // Get before context for (let i = Math.max(0, targetIndex - contextLines); i < targetIndex; i++) { context.before.push(collectedLines[i].line) } // Get target line context.line = collectedLines[targetIndex].line // Get after context for ( let i = targetIndex + 1; i < Math.min(collectedLines.length, targetIndex + contextLines + 1); i++ ) { context.after.push(collectedLines[i].line) } } return context } export const getDiffContext = ( changeId: string, path: string, line?: number, ): Effect.Effect<DiffContext, ApiError, GerritApiService> => Effect.gen(function* () { if (!line || path === 'Commit Message' || path === '/COMMIT_MSG') { return { before: [], after: [] } } const gerritApi = yield* GerritApiService try { const diff = yield* gerritApi.getFileDiff(changeId, path) return extractDiffContext(diff, line) } catch { // Return empty context on error return { before: [], after: [] } } })