UNPKG

bktide

Version:

Command-line interface for Buildkite CI/CD workflows with rich shell completions (Fish, Bash, Zsh) and Alfred workflow integration for macOS power users

122 lines 5.37 kB
import { BaseFormatter } from './Formatter.js'; import { formatAnnotationBody } from '../../utils/textFormatter.js'; import { SEMANTIC_COLORS, formatEmptyState, formatError } from '../../ui/theme.js'; import { useAscii } from '../../ui/symbols.js'; import { termWidth } from '../../ui/width.js'; export class PlainTextFormatter extends BaseFormatter { name = 'PlainText'; formatAnnotations(annotations, options) { if (options?.hasError) { return formatError(options.errorMessage || 'Failed to fetch annotations', { showHelp: true, helpCommand: 'bktide annotations --help' }); } if (!annotations || annotations.length === 0) { const message = options?.contextFilter ? `No annotations found for this build with context '${options.contextFilter}'` : 'No annotations found for this build'; return formatEmptyState(message, [ 'Annotations are created by build steps', 'Check the build has completed and has annotation steps' ]); } const lines = []; const isAscii = useAscii(); const terminalWidth = termWidth(); // Box drawing characters const boxChars = isAscii ? { horizontal: '-', vertical: '|', topLeft: '+', topRight: '+', bottomLeft: '+', bottomRight: '+', cross: '+', verticalRight: '+', verticalLeft: '+', horizontalDown: '+', horizontalUp: '+' } : { horizontal: '─', vertical: '│', topLeft: '┌', topRight: '┐', bottomLeft: '└', bottomRight: '┘', cross: '┼', verticalRight: '├', verticalLeft: '┤', horizontalDown: '┬', horizontalUp: '┴' }; // Style symbols for different annotation types (handle both cases) const styleSymbols = { error: isAscii ? '[X]' : '✖', ERROR: isAscii ? '[X]' : '✖', warning: isAscii ? '[!]' : '⚠', WARNING: isAscii ? '[!]' : '⚠', info: isAscii ? '[i]' : 'ℹ', INFO: isAscii ? '[i]' : 'ℹ', success: isAscii ? '[✓]' : '✓', SUCCESS: isAscii ? '[✓]' : '✓' }; // Style colors for different annotation types (handle both cases) const styleColors = { error: SEMANTIC_COLORS.error, ERROR: SEMANTIC_COLORS.error, warning: SEMANTIC_COLORS.warning, WARNING: SEMANTIC_COLORS.warning, info: SEMANTIC_COLORS.info, INFO: SEMANTIC_COLORS.info, success: SEMANTIC_COLORS.success, SUCCESS: SEMANTIC_COLORS.success }; // Create a horizontal divider with padding and centering const createDivider = (width = 80) => { const padding = 2; // 1 space on each side const maxWidth = Math.min(width, terminalWidth - padding); const dividerLength = Math.max(20, maxWidth - padding); // Minimum 20 chars const divider = boxChars.horizontal.repeat(dividerLength); // Center the divider within the terminal width const totalPadding = terminalWidth - dividerLength; const leftPadding = Math.floor(totalPadding / 2); const spaces = ' '.repeat(Math.max(0, leftPadding)); return SEMANTIC_COLORS.dim(spaces + divider); }; annotations.forEach((annotation, index) => { const symbol = styleSymbols[annotation.style] || (isAscii ? '*' : '•'); const colorFn = styleColors[annotation.style] || ((s) => s); // Add divider between annotations (but not before the first one) if (index > 0) { lines.push(''); lines.push(createDivider()); lines.push(''); } // Single line header with pipe: "│ ℹ info: test-mapping-build" const pipe = colorFn(boxChars.vertical); const header = `${pipe} ${symbol} ${annotation.style.toLowerCase()}: ${annotation.context}`; lines.push(header); // Add blank line with pipe for visual continuity lines.push(pipe); // Format the body HTML with proper HTML/markdown handling const formattedBody = formatAnnotationBody(annotation.body.html); // Add vertical pipes to the left of the body content for visual continuity // Use the same color as the header for the pipes const bodyLines = formattedBody.split('\n'); bodyLines.forEach((line) => { const paddedLine = line ? ` ${line}` : ''; lines.push(`${pipe}${paddedLine}`); }); }); // Add summary footer if (annotations.length > 1) { lines.push(''); lines.push(createDivider()); lines.push(''); lines.push(SEMANTIC_COLORS.dim(`${SEMANTIC_COLORS.count(annotations.length.toString())} annotations found`)); } return lines.join('\n'); } } //# sourceMappingURL=PlainTextFormatter.js.map