UNPKG

savory

Version:

A command-line interface for operating your Codefresh account

117 lines (114 loc) 6.08 kB
const _ = require('lodash'), fp = require('lodash/fp'), yargs = require('yargs'), https = require('https'), kefir = require('kefir'), chalk = require('chalk'), Firebase = require('firebase'), stripAnsi = require('strip-ansi'), { simpleHash } = require('../../lib/util'), { middleware: httpClientMiddleware } = require('../../lib/api_client'), { errorFormatter } = require('../style'); const MIN_SIDEBAR_WIDTH = 5, MAX_SIDEBAR_WIDTH = 12, DEFAULT_WIDTH = 80, COLOR_WHEEL = ["yellow", "blueBright", "magentaBright", "cyanBright", "whiteBright", "redBright"].map((color)=> chalk[color]), MONITOR_TIMEOUT = 10 * 60 * 1000; module.exports = { command: "dump <build-id>", description: "Dumps all the logs associated with a build", builder: (yargs)=> { return yargs.positional('build-id', { type: "string" }); }, handler: fp.pipe(httpClientMiddleware, ({ _httpClient, buildId })=> { kefir .fromPromise(_httpClient(["builds", buildId].join('/'))) .flatMap(fp.pipe(fp.get('progress_id'), (id)=> ["progress", id].join('/'), _httpClient, kefir.fromPromise)) .flatMap((progress)=> { const [type, url, progressId] = fp.at(["location.type", "location.url", "_id"], progress); return ({ "gcs": ()=> { let req = https.get(url); return kefir .merge([ kefir.fromEvents(req, 'error').flatMap(kefir.constantError), kefir .fromEvents(req, 'response') .take(1) .flatMap( (res)=> kefir .fromEvents(res, 'data') .takeUntilBy(kefir.fromEvents(res, 'end').take(1)) .scan(fp.concat, []) .last() .map(fp.pipe( Buffer.concat, (buf)=> buf.toString(), JSON.parse, fp.get('steps'), fp.map(({ name, logs })=> logs.map((line)=> ({ name, line }))) )) ) .flatten() ]) .flatten() .takeUntilBy(kefir.fromEvents(req, 'end').take(1)); }, "firebase": ()=> { return kefir .fromPromise(_httpClient('user/firebaseAuth')) .flatMap(({ url: applicationUrl, accessToken })=> { const firebaseClient = new Firebase(`${applicationUrl}`); return kefir.fromNodeCallback((cb)=> firebaseClient.authWithCustomToken(accessToken, cb)).map(()=> firebaseClient); }) .flatMap((client)=> { let progressClient = client.child(`/build-logs/${progressId}`); return kefir .fromEvents(progressClient.child('steps'), 'child_added') .flatMap((stepSnapshot)=> { let stepName = _.get(stepSnapshot.val(), 'name'); return kefir .fromEvents(stepSnapshot.ref().child('logs'), 'child_added') .map((snapshot)=> ({ line: snapshot.val(), name: stepName })); }) .takeUntilBy( kefir .fromEvents(progressClient.child('status'), 'value') .map((snapshot)=> snapshot.val()) .filter((status)=> ['success', 'error', 'terminated'].includes(status)) .merge(kefir.later(MONITOR_TIMEOUT)) .take(1) ); }); } }[type] || (()=> kefir.constantError(new Error('Unsupported log source'))))(url); }) .takeErrors(1) .map(function(sidebarWidth){ return ({ name, line })=> _(line) .thru(stripAnsi) .split(/\r?\n|\r/g) .compact() .flatMap((line)=> { return _(line) .chunk((yargs.terminalWidth() || DEFAULT_WIDTH) - (sidebarWidth + 3)) .map(fp.join('')) .value(); }) .map((line)=> [ _(name).chain().truncate({ length: sidebarWidth, omission: ".." }).padEnd(sidebarWidth).thru(COLOR_WHEEL[Math.abs(simpleHash(name) % COLOR_WHEEL.length)]).value(), line ].join(' | ')) .join('\n'); }(_.clamp(~~((yargs.terminalWidth() || DEFAULT_WIDTH) / 10), MIN_SIDEBAR_WIDTH, MAX_SIDEBAR_WIDTH))) .filter(Boolean) .onValue(console.log) .onError(fp.pipe(errorFormatter, console.warn)) .onEnd(()=> process.exit()); // <-- Firebase keeps connection open }) };