diff --git a/lib/actions/deploy.coffee b/lib/actions/deploy.coffee index bbc9f43d..f61bc772 100644 --- a/lib/actions/deploy.coffee +++ b/lib/actions/deploy.coffee @@ -22,7 +22,7 @@ dockerUtils = require('../utils/docker') compose = require('../utils/compose') { registrySecretsHelp } = require('../utils/messages') { ExpectedError } = require('../errors') -{ getBalenaSdk } = require('../utils/lazy') +{ getBalenaSdk, getChalk } = require('../utils/lazy') ### Opts must be an object with the following keys: @@ -89,10 +89,9 @@ deployProject = (docker, logger, composeOpts, opts) -> } .then (images) -> if opts.app.application_type?[0]?.is_legacy - chalk = require('chalk') legacyDeploy = require('../utils/deploy-legacy') - msg = chalk.yellow('Target application requires legacy deploy method.') + msg = getChalk().yellow('Target application requires legacy deploy method.') logger.logWarn(msg) return Promise.join( diff --git a/lib/actions/local/common.coffee b/lib/actions/local/common.coffee index 6aaeaa0b..2b04dead 100644 --- a/lib/actions/local/common.coffee +++ b/lib/actions/local/common.coffee @@ -1,9 +1,9 @@ Promise = require('bluebird') _ = require('lodash') -chalk = require('chalk') dockerUtils = require('../../utils/docker') { exitWithExpectedError } = require('../../utils/patterns') +{ getChalk } = require('../../utils/lazy') exports.dockerPort = dockerPort = 2375 exports.dockerTimeout = dockerTimeout = 2000 @@ -56,7 +56,7 @@ exports.pipeContainerStream = Promise.method ({ deviceIp, name, outStream, follo .catch (err) -> err = '' + err.statusCode if err is '404' - return console.log(chalk.red.bold("Container '#{name}' not found.")) + return console.log(getChalk().red.bold("Container '#{name}' not found.")) throw err exports.getSubShellCommand = require('../../utils/helpers').getSubShellCommand diff --git a/lib/actions/local/flash.ts b/lib/actions/local/flash.ts index de0c19c4..7a18608c 100644 --- a/lib/actions/local/flash.ts +++ b/lib/actions/local/flash.ts @@ -15,10 +15,9 @@ limitations under the License. */ import { CommandDefinition } from 'capitano'; -import chalk from 'chalk'; import { stripIndent } from 'common-tags'; import * as SDK from 'etcher-sdk'; -import { getVisuals } from '../../utils/lazy'; +import { getChalk, getVisuals } from '../../utils/lazy'; async function getDrive(options: { drive?: string; @@ -88,7 +87,7 @@ export const flash: CommandDefinition< default: false, })); if (yes !== true) { - console.log(chalk.red.bold('Aborted image flash')); + console.log(getChalk().red.bold('Aborted image flash')); process.exit(0); } @@ -109,7 +108,7 @@ export const flash: CommandDefinition< [drive], (_, error) => { // onFail - console.log(chalk.red.bold(error.message)); + console.log(getChalk().red.bold(error.message)); }, (progress: SDK.multiWrite.MultiDestinationProgress) => { // onProgress diff --git a/lib/actions/local/stop.coffee b/lib/actions/local/stop.coffee index bc4e5dc5..38308d5c 100644 --- a/lib/actions/local/stop.coffee +++ b/lib/actions/local/stop.coffee @@ -20,6 +20,9 @@ limitations under the License. # and `Cygwin` should be encapsulated in a # re-usable package. # + +{ getChalk } = require('../../utils/lazy') + module.exports = signature: 'local stop [deviceIp]' description: 'Stop a running container on a balenaOS device' @@ -46,7 +49,7 @@ module.exports = root: true action: (params, options) -> Promise = require('bluebird') - chalk = require('chalk') + chalk = getChalk() { forms, config, BalenaLocalDockerUtils } = require('balena-sync') { selectContainerFromDevice, filterOutSupervisorContainer } = require('./common') diff --git a/lib/actions/util.ts b/lib/actions/util.ts index 4eea2877..26e6f7cc 100644 --- a/lib/actions/util.ts +++ b/lib/actions/util.ts @@ -20,9 +20,8 @@ limitations under the License. */ import { CommandDefinition } from 'capitano'; -import chalk from 'chalk'; import { stripIndent } from 'common-tags'; -import { getVisuals } from '../utils/lazy'; +import { getChalk, getVisuals } from '../utils/lazy'; export const availableDrives: CommandDefinition<{}, {}> = { signature: 'util available-drives', @@ -49,7 +48,9 @@ export const availableDrives: CommandDefinition<{}, {}> = { if (scanner.drives.size === 0) { console.error( - `${chalk.red('x')} No available drives were detected, plug one in!`, + `${getChalk().red( + 'x', + )} No available drives were detected, plug one in!`, ); } else { console.log( diff --git a/lib/utils/compose.coffee b/lib/utils/compose.coffee index a069c51c..d4a851b3 100644 --- a/lib/utils/compose.coffee +++ b/lib/utils/compose.coffee @@ -17,7 +17,7 @@ Promise = require('bluebird') path = require('path') -{ getBalenaSdk } = require('./lazy') +{ getBalenaSdk, getChalk } = require('./lazy') exports.appendProjectOptions = appendProjectOptions = (opts) -> opts.concat [ @@ -394,7 +394,6 @@ authorizePush = (sdk, logger, tokenAuthEndpoint, registry, images, previousRepos .catchReturn({}) pushAndUpdateServiceImages = (docker, token, images, afterEach) -> - chalk = require('chalk') { DockerProgress } = require('docker-progress') { retry } = require('./helpers') tty = require('./tty')(process.stdout) @@ -402,7 +401,7 @@ pushAndUpdateServiceImages = (docker, token, images, afterEach) -> opts = { authconfig: registrytoken: token } progress = new DockerProgress(dockerToolbelt: docker) - renderer = pushProgressRenderer(tty, chalk.blue('[Push]') + ' ') + renderer = pushProgressRenderer(tty, getChalk().blue('[Push]') + ' ') reporters = progress.aggregateProgress(images.length, renderer) Promise.using tty.cursorHidden(), -> @@ -441,11 +440,10 @@ exports.deployProject = ( skipLogUpload ) -> _ = require('lodash') - chalk = require('chalk') releaseMod = require('resin-release') tty = require('./tty')(process.stdout) - prefix = chalk.cyan('[Info]') + ' ' + prefix = getChalk().cyan('[Info]') + ' ' spinner = createSpinner() runloop = runSpinner(tty, spinner, "#{prefix}Creating release...") @@ -599,7 +597,6 @@ createRunLoop = (tick) -> class BuildProgressUI constructor: (tty, descriptors) -> _ = require('lodash') - chalk = require('chalk') through = require('through2') eventHandler = @_handleEvent @@ -621,7 +618,7 @@ class BuildProgressUI # Logger magically prefixes the log line with [Build] etc., but it doesn't # work well with the spinner we're also showing. Manually build the prefix # here and bypass the logger. - prefix = chalk.blue('[Build]') + ' ' + prefix = getChalk().blue('[Build]') + ' ' offset = 10 # account for escape sequences inserted for colouring @_prefixWidth = offset + prefix.length + _.max(_.map(services, 'length')) @@ -718,7 +715,7 @@ class BuildProgressUI _renderSummary: (serviceToStrMap) -> _ = require('lodash') - chalk = require('chalk') + chalk = getChalk() truncate = require('cli-truncate') strlen = require('string-width') @@ -785,7 +782,6 @@ class BuildProgressInline _renderEvent: (service, event) => _ = require('lodash') - chalk = require('chalk') str = do -> { status, error } = event @@ -796,7 +792,7 @@ class BuildProgressInline else return 'Waiting...' - prefix = _.padEnd(chalk.bold(service), @_prefixWidth) + prefix = _.padEnd(getChalk().bold(service), @_prefixWidth) @_outStream.write(prefix) @_outStream.write(str) @_outStream.write('\n') diff --git a/lib/utils/device/logs.ts b/lib/utils/device/logs.ts index 0a88e2f5..7397ea24 100644 --- a/lib/utils/device/logs.ts +++ b/lib/utils/device/logs.ts @@ -1,9 +1,9 @@ import * as Bluebird from 'bluebird'; -import chalk from 'chalk'; import ColorHash = require('color-hash'); import * as _ from 'lodash'; import { Readable } from 'stream'; +import { getChalk } from '../lazy'; import Logger = require('../logger'); interface Log { @@ -116,5 +116,5 @@ const colorHash = new ColorHash(); function _getServiceColourFn(serviceName: string): (msg: string) => string { const [r, g, b] = colorHash.rgb(serviceName); - return chalk.rgb(r, g, b); + return getChalk().rgb(r, g, b); } diff --git a/lib/utils/helpers.ts b/lib/utils/helpers.ts index 5e394556..d1d71f84 100644 --- a/lib/utils/helpers.ts +++ b/lib/utils/helpers.ts @@ -17,13 +17,12 @@ limitations under the License. import { InitializeEmitter, OperationState } from 'balena-device-init'; import * as BalenaSdk from 'balena-sdk'; import Bluebird = require('bluebird'); -import chalk from 'chalk'; import _ = require('lodash'); import os = require('os'); import * as ShellEscape from 'shell-escape'; import { ExpectedError } from '../errors'; -import { getBalenaSdk, getVisuals } from './lazy'; +import { getBalenaSdk, getChalk, getVisuals } from './lazy'; export function getGroupDefaults(group: { options: Array<{ name: string; default?: string }>; @@ -37,6 +36,7 @@ export function getGroupDefaults(group: { export function stateToString(state: OperationState) { const percentage = _.padStart(`${state.percentage}`, 3, '0'); + const chalk = getChalk(); const result = `${chalk.blue(percentage + '%')} ${chalk.cyan( state.operation.command, )}`; diff --git a/lib/utils/lazy.ts b/lib/utils/lazy.ts index da1f1020..0098b653 100644 --- a/lib/utils/lazy.ts +++ b/lib/utils/lazy.ts @@ -15,6 +15,7 @@ limitations under the License. */ import * as BalenaSdk from 'balena-sdk'; +import chalk from 'chalk'; import * as visuals from 'resin-cli-visuals'; // Equivalent of _.once but avoiding the need to import lodash for lazy deps @@ -35,3 +36,5 @@ export const getBalenaSdk = once(() => export const getVisuals = once( () => require('resin-cli-visuals') as typeof visuals, ); + +export const getChalk = once(() => require('chalk') as typeof chalk); diff --git a/lib/utils/logger.ts b/lib/utils/logger.ts index 44f3a4f8..27c7cfe9 100644 --- a/lib/utils/logger.ts +++ b/lib/utils/logger.ts @@ -14,10 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import chalk from 'chalk'; import _ = require('lodash'); import { EOL as eol } from 'os'; import { StreamLogger } from 'resin-stream-logger'; +import { getChalk } from './lazy'; enum Level { BUILD = 'build', @@ -57,6 +57,7 @@ class Logger { protected constructor() { const logger = new StreamLogger(); + const chalk = getChalk(); logger.addPrefix('build', chalk.blue('[Build]')); logger.addPrefix('info', chalk.cyan('[Info]')); logger.addPrefix('debug', chalk.magenta('[Debug]')); diff --git a/lib/utils/patterns.ts b/lib/utils/patterns.ts index 6e463977..f430a029 100644 --- a/lib/utils/patterns.ts +++ b/lib/utils/patterns.ts @@ -16,13 +16,12 @@ limitations under the License. import { BalenaApplicationNotFound } from 'balena-errors'; import * as BalenaSdk from 'balena-sdk'; import Bluebird = require('bluebird'); -import chalk from 'chalk'; import { stripIndent } from 'common-tags'; import _ = require('lodash'); import _form = require('resin-cli-form'); import { NotLoggedInError } from '../errors'; -import { getBalenaSdk, getVisuals } from './lazy'; +import { getBalenaSdk, getChalk, getVisuals } from './lazy'; import messages = require('./messages'); import validation = require('./validation'); @@ -431,6 +430,7 @@ export function selectFromList( } export function printErrorMessage(message: string) { + const chalk = getChalk(); console.error(chalk.red(message)); console.error(chalk.red(`\n${messages.getHelp}\n`)); } diff --git a/lib/utils/visuals/drive-list.ts b/lib/utils/visuals/drive-list.ts index f29166e9..a5850224 100644 --- a/lib/utils/visuals/drive-list.ts +++ b/lib/utils/visuals/drive-list.ts @@ -1,6 +1,6 @@ -import chalk from 'chalk'; import * as _sdk from 'etcher-sdk'; +import { getChalk } from '../lazy'; import { CustomDynamicList } from './custom-dynamic-list'; export class DriveList extends CustomDynamicList< @@ -9,7 +9,7 @@ export class DriveList extends CustomDynamicList< constructor(private scanner: _sdk.scanner.Scanner) { super( 'Select a drive', - `${chalk.red('x')} No available drives were detected, plug one in!`, + `${getChalk().red('x')} No available drives were detected, plug one in!`, ); const refresh = this.refresh.bind(this); scanner.on('attach', refresh);