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

114 lines 5.04 kB
import { BaseCommand } from './BaseCommand.js'; import { logger } from '../services/logger.js'; import { parseBuildRef } from '../utils/parseBuildRef.js'; import { FormatterFactory, FormatterType } from '../formatters/index.js'; import { Progress } from '../ui/progress.js'; export class ShowBuild extends BaseCommand { static requiresToken = true; async execute(options) { if (options.debug) { logger.debug('Starting ShowBuild command execution', options); } if (!options.buildArg) { logger.error('Build reference is required'); return 1; } // Adjust options based on implications const adjustedOptions = { ...options }; if (options.failed) { adjustedOptions.jobs = true; // --failed implies --jobs } if (options.annotationsFull) { adjustedOptions.annotations = true; // --annotations-full implies --annotations } if (options.allJobs) { adjustedOptions.jobs = true; // --all-jobs implies --jobs } if (options.full) { // --full shows everything adjustedOptions.jobs = true; adjustedOptions.annotations = true; adjustedOptions.allJobs = true; // --full shows all jobs } // Initialize spinner early const format = options.format || 'plain'; const spinner = Progress.spinner('Fetching build details…', { format }); try { // Ensure the command is initialized await this.ensureInitialized(); // Parse build reference const buildRef = parseBuildRef(options.buildArg); if (options.debug) { logger.debug('Parsed build reference:', buildRef); } // Construct build slug for GraphQL const buildSlug = `${buildRef.org}/${buildRef.pipeline}/${buildRef.number}`; // Fetch build data based on what's needed const buildData = await this.fetchBuildData(buildSlug, adjustedOptions); spinner.stop(); // Get the appropriate formatter const formatter = FormatterFactory.getFormatter(FormatterType.BUILD_DETAIL, options.format || 'plain'); // Format and output the results const output = formatter.formatBuildDetail(buildData, adjustedOptions); logger.console(output); return 0; } catch (error) { spinner.stop(); logger.error('Failed to fetch build:', error); // Handle the error with the formatter const formatter = FormatterFactory.getFormatter(FormatterType.BUILD_DETAIL, options.format || 'plain'); const errorOutput = formatter.formatBuildDetail(null, { ...adjustedOptions, hasError: true, errorMessage: error instanceof Error ? error.message : 'Unknown error occurred', errorType: 'api', }); logger.console(errorOutput); return 1; } } async fetchBuildData(buildSlug, options) { // Determine what data we need to fetch based on options const needsAllJobs = options.jobs || options.failed || options.full; const needsAnnotations = options.annotations || options.annotationsFull || options.full; if (options.debug) { logger.debug('Fetching build data', { buildSlug, needsAllJobs, needsAnnotations, full: options.full }); } // Use the new pagination-aware method when we need all jobs if (needsAllJobs) { // Show progress when fetching many jobs (only in plain format) const progressCallback = options.format === 'plain' || !options.format ? (fetched, total) => { const totalStr = total ? `/${total}` : ''; process.stderr.write(`\rFetching jobs: ${fetched}${totalStr}...`); } : undefined; const buildData = await this.client.getBuildSummaryWithAllJobs(buildSlug, { fetchAllJobs: true, onProgress: progressCallback }); // Clear the progress line if (progressCallback) { process.stderr.write('\r\x1b[K'); // Clear the line } // If we need full details (like command text), fetch that separately if (options.full) { // For now, getBuildFull still provides more detailed fields // In the future, we could enhance the pagination query to include these return await this.client.getBuildFull(buildSlug); } return buildData; } else { // Just get the summary with first 100 jobs return await this.client.getBuildSummary(buildSlug); } } } //# sourceMappingURL=ShowBuild.js.map