UNPKG

@aaronshaf/ger

Version:

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

139 lines (124 loc) 4.38 kB
import { Effect } from 'effect' import { type ApiError, GerritApiService } from '@/api/gerrit' import { sanitizeCDATA } from '@/utils/shell-safety' import { getChangeIdFromHead, GitError, NoChangeIdError } from '@/utils/git-commit' export const TOPIC_HELP_TEXT = ` Examples: # View current topic (auto-detect from HEAD) $ ger topic # View topic for specific change $ ger topic 12345 # Set topic on a change $ ger topic 12345 my-feature # Remove topic from a change $ ger topic 12345 --delete $ ger topic --delete # auto-detect from HEAD Note: When no change-id is provided, it will be auto-detected from the HEAD commit.` interface TopicOptions { xml?: boolean json?: boolean delete?: boolean } /** * Manages topic for a Gerrit change. * * - No topic argument: get current topic * - With topic argument: set topic * - With --delete flag: remove topic * * @param changeId - Change number or Change-ID (auto-detects from HEAD if not provided) * @param topic - Optional topic to set * @param options - Configuration options * @returns Effect that completes when the operation finishes */ export const topicCommand = ( changeId: string | undefined, topic: string | undefined, options: TopicOptions = {}, ): Effect.Effect<void, ApiError | GitError | NoChangeIdError, GerritApiService> => Effect.gen(function* () { const gerritApi = yield* GerritApiService // Auto-detect Change-ID from HEAD commit if not provided const resolvedChangeId = changeId?.trim() || (yield* getChangeIdFromHead()) // Handle delete operation if (options.delete) { yield* gerritApi.deleteTopic(resolvedChangeId) if (options.json) { console.log( JSON.stringify( { status: 'success', action: 'deleted', change_id: resolvedChangeId }, null, 2, ), ) } else if (options.xml) { console.log(`<?xml version="1.0" encoding="UTF-8"?>`) console.log(`<topic_result>`) console.log(` <status>success</status>`) console.log(` <action>deleted</action>`) console.log(` <change_id><![CDATA[${sanitizeCDATA(resolvedChangeId)}]]></change_id>`) console.log(`</topic_result>`) } else { console.log(`✓ Removed topic from change ${resolvedChangeId}`) } return } // Handle set operation if (topic !== undefined && topic.trim() !== '') { const newTopic = yield* gerritApi.setTopic(resolvedChangeId, topic) if (options.json) { console.log( JSON.stringify( { status: 'success', action: 'set', change_id: resolvedChangeId, topic: newTopic }, null, 2, ), ) } else if (options.xml) { console.log(`<?xml version="1.0" encoding="UTF-8"?>`) console.log(`<topic_result>`) console.log(` <status>success</status>`) console.log(` <action>set</action>`) console.log(` <change_id><![CDATA[${sanitizeCDATA(resolvedChangeId)}]]></change_id>`) console.log(` <topic><![CDATA[${sanitizeCDATA(newTopic)}]]></topic>`) console.log(`</topic_result>`) } else { console.log(`✓ Set topic on change ${resolvedChangeId}: ${newTopic}`) } return } // Handle get operation (default) const currentTopic = yield* gerritApi.getTopic(resolvedChangeId) if (options.json) { console.log( JSON.stringify( { status: 'success', action: 'get', change_id: resolvedChangeId, topic: currentTopic || null, }, null, 2, ), ) } else if (options.xml) { console.log(`<?xml version="1.0" encoding="UTF-8"?>`) console.log(`<topic_result>`) console.log(` <status>success</status>`) console.log(` <action>get</action>`) console.log(` <change_id><![CDATA[${sanitizeCDATA(resolvedChangeId)}]]></change_id>`) if (currentTopic) { console.log(` <topic><![CDATA[${sanitizeCDATA(currentTopic)}]]></topic>`) } else { console.log(` <topic />`) } console.log(`</topic_result>`) } else { if (currentTopic) { console.log(currentTopic) } else { console.log(`No topic set for change ${resolvedChangeId}`) } } })