UNPKG

savory

Version:

A command-line interface for operating your Codefresh account

124 lines (118 loc) 6.28 kB
const fp = require('lodash/fp'), chalk = require('chalk'), moment = require('moment'), jsYaml = require('js-yaml'), { middleware: httpClientMiddleware } = require('../../lib/api_client'), { timeSpanFormatter } = require('../../lib/util'), { errorFormatter, tableFormatter, jsonFormatter } = require('../style'); const DEFAULT_API_RESULT_LIMIT = 25, STATUS_SUCCESS = "success", STATUS_ERROR = "error", STATUS_TERMINATED = "terminated", STATUS_RUNNING = "running", STATUS_ELECTED = "elected", CAPTION_UKNOWN = "Unknown", CAPTION_ALL = "all", CAPTION_NOT_AVAILABLE = "N/A", CHARS_ID = 25, CHARS_REPOSITORY = 100, CHARS_BRANCH = 25; module.exports = { command: ["list [id..]", "ls"], builder: (yargs)=> { return yargs .option('pipeline-id', { type: "string", conflicts: ["pipeline"], describe: "Filter by a pipeline id" }) .option('pipeline', { type: "string", conflicts: ["pipeline-id"], describe: "Filter by a pipeline name" }) .option('trigger', { type: "string", describe: "Filter by a trigger name" }) .option('status', { choices: ["success", "failed", "aborted", "running", "pending"], type: "array", describe: "Filter by a specific build status(es)" }) .option('output', { choices: ["summary", "yaml", "json"], default: "summary", describe: "Choose a output format for the returned data" }) .option('api-limit', { type: "number", default: DEFAULT_API_RESULT_LIMIT, describe: "Limit the amount of results returned from the API" }) .example('$0 builds ls') .example('$0 builds ls --pipeline=mypipeline') .example('$0 builds ls --status=running success') .example('$0 builds ls --trigger=build') .group(["status", "trigger", "pipeline", "pipeline-id"], "Build filter options:"); }, describe: "Retrieve a list of builds", handler: fp.pipe(httpClientMiddleware, ({ _httpClient, apiLimit, output, id, status: statusFilter, pipeline, pipelineId, trigger })=> { Promise .all([pipeline && _httpClient('pipelines', { id: pipeline }).then(fp.pipe(fp.get('docs'), fp.map(fp.get('metadata.id')))), pipelineId]) .then(fp.pipe(fp.flatten, fp.compact)) .then((pipelineFilter)=> { return (id ? Promise.all(fp.uniq(id).map((id)=> _httpClient(`builds/${id}`))) : _httpClient('workflow', Object.assign({ limit: apiLimit, pipeline: pipelineFilter }, trigger && { trigger })).then(fp.get('workflows.docs'))) .then((rawResult)=> { let summary = fp.pipe( fp.sortBy([fp.pipe(fp.get('created'), (str)=> (new Date(str)).getTime())]), fp.reverse, fp.map(({ id, serviceName, status, trigger, started, finished, project, created, branchName } = {})=> [ fp.truncate({ length: CHARS_ID, omission: ".." }, id), { [STATUS_SUCCESS]: chalk.green('SUCCESS ✓'), [STATUS_ERROR]: chalk.red('FAILED ✗'), [STATUS_TERMINATED]: chalk.yellow('ABORTED ✗'), [STATUS_RUNNING]: chalk.whiteBright('RUNNING *'), [STATUS_ELECTED]: chalk.whiteBright('PENDING *') }[status] || chalk.gray(CAPTION_UKNOWN), serviceName, trigger, moment(created).format('DD/MM/YYYY HH:mm'), started ? (([STATUS_RUNNING, STATUS_ELECTED].includes(status)) ? chalk.whiteBright : fp.identity)(timeSpanFormatter([finished || new Date(), started].map((stamp)=> (new Date(stamp)).getTime()).reduce(fp.subtract))) : chalk.gray(CAPTION_NOT_AVAILABLE), fp.truncate({ length: CHARS_REPOSITORY, omission: ".." }, project), fp.truncate({ length: CHARS_BRANCH, omission: ".." }, branchName) ]), (processedResult)=> { return [ processedResult.length ? `\n Displaying ${processedResult.length} build(s) out of ${ rawResult.length } returned value(s):\n` : `No viewable items returned`, processedResult.length && (pipeline || pipelineId) && ` Including results from ${pipelineFilter.length || CAPTION_ALL} pipeline(s)\n`, processedResult.length && tableFormatter({ title: ["Id", "Status", "Pipeline", "Trigger", "Created", "Run-Time\nHH:MM:SS", "Project", "Branch"] }, processedResult), ].filter(Boolean).join('\n'); } ); return { summary, json: jsonFormatter, yaml: jsYaml.safeDump }[output]( (!statusFilter ? fp.identity : (function(statusFilter){ return fp.filter(({ status })=> statusFilter.includes(status)) })(statusFilter.map((caption)=> ({ "success": STATUS_SUCCESS, "failed": STATUS_ERROR, "aborted": STATUS_TERMINATED, "running": STATUS_RUNNING, "pending": STATUS_ELECTED })[caption])))(rawResult) ); }); }) .then(console.log) .catch(fp.pipe(errorFormatter, console.warn)); }) };