diff --git a/lib/actions-oclif/devices/supported.ts b/lib/actions-oclif/devices/supported.ts index a08250ba..07857dcb 100644 --- a/lib/actions-oclif/devices/supported.ts +++ b/lib/actions-oclif/devices/supported.ts @@ -20,7 +20,7 @@ import { stripIndent } from 'common-tags'; import * as _ from 'lodash'; import * as cf from '../../utils/common-flags'; -import { getBalenaSdk } from '../../utils/lazy'; +import { getBalenaSdk, getVisuals } from '../../utils/lazy'; import { CommandHelp } from '../../utils/oclif-utils'; interface FlagsDef { @@ -105,7 +105,7 @@ export default class DevicesSupportedCmd extends Command { if (options.json) { console.log(JSON.stringify(deviceTypes, null, 4)); } else { - const visuals = await import('resin-cli-visuals'); + const visuals = getVisuals(); const output = await visuals.table.horizontal(deviceTypes, fields); console.log(output); } diff --git a/lib/actions-oclif/envs.ts b/lib/actions-oclif/envs.ts index 23b53678..a0a628bc 100644 --- a/lib/actions-oclif/envs.ts +++ b/lib/actions-oclif/envs.ts @@ -21,7 +21,7 @@ import * as _ from 'lodash'; import { ExpectedError } from '../errors'; import * as cf from '../utils/common-flags'; -import { getBalenaSdk } from '../utils/lazy'; +import { getBalenaSdk, getVisuals } from '../utils/lazy'; import { CommandHelp } from '../utils/oclif-utils'; interface FlagsDef { @@ -186,7 +186,6 @@ export default class EnvsCmd extends Command { varArray: EnvironmentVariableInfo[], options: FlagsDef, ) { - const visuals = await import('resin-cli-visuals'); const fields = ['id', 'name', 'value']; if (options.all) { @@ -211,7 +210,7 @@ export default class EnvsCmd extends Command { ); } else { this.log( - visuals.table.horizontal( + getVisuals().table.horizontal( _.sortBy(varArray, (v: SDK.EnvironmentVariableBase) => v.name), fields, ), diff --git a/lib/actions/app.ts b/lib/actions/app.ts index 687e663c..6c87b9df 100644 --- a/lib/actions/app.ts +++ b/lib/actions/app.ts @@ -16,7 +16,7 @@ limitations under the License. import { Application } from 'balena-sdk'; import { CommandDefinition } from 'capitano'; -import { getBalenaSdk } from '../utils/lazy'; +import { getBalenaSdk, getVisuals } from '../utils/lazy'; import * as commandOptions from './command-options'; export const create: CommandDefinition< @@ -104,7 +104,6 @@ Examples: async action() { const _ = await import('lodash'); const balena = getBalenaSdk(); - const visuals = await import('resin-cli-visuals'); return balena.models.application .getAll({ @@ -125,7 +124,7 @@ Examples: }); console.log( - visuals.table.horizontal(applications, [ + getVisuals().table.horizontal(applications, [ 'id', 'app_name', 'device_type', @@ -153,13 +152,11 @@ Examples: permission: 'user', primary: true, async action(params) { - const visuals = await import('resin-cli-visuals'); - return getBalenaSdk() .models.application.get(params.name) .then(application => { console.log( - visuals.table.vertical(application, [ + getVisuals().table.vertical(application, [ `$${application.app_name}$`, 'id', 'device_type', diff --git a/lib/actions/auth.ts b/lib/actions/auth.ts index e0828630..9f2de12e 100644 --- a/lib/actions/auth.ts +++ b/lib/actions/auth.ts @@ -15,7 +15,7 @@ limitations under the License. */ import { CommandDefinition } from 'capitano'; -import { getBalenaSdk } from '../utils/lazy'; +import { getBalenaSdk, getVisuals } from '../utils/lazy'; export const login: CommandDefinition< {}, @@ -179,9 +179,8 @@ Examples: balena.auth.getEmail(), balena.settings.get('balenaUrl'), ]); - const visuals = await import('resin-cli-visuals'); console.log( - visuals.table.vertical({ username, email, url }, [ + getVisuals().table.vertical({ username, email, url }, [ '$account information$', 'username', 'email', diff --git a/lib/actions/config.coffee b/lib/actions/config.coffee index 130a1d16..d098a61a 100644 --- a/lib/actions/config.coffee +++ b/lib/actions/config.coffee @@ -16,7 +16,7 @@ limitations under the License. commandOptions = require('./command-options') { normalizeUuidProp } = require('../utils/normalization') -{ getBalenaSdk } = require('../utils/lazy') +{ getBalenaSdk, getVisuals } = require('../utils/lazy') exports.read = signature: 'config read' @@ -49,12 +49,11 @@ exports.read = action: (params, options) -> Promise = require('bluebird') config = require('balena-config-json') - visuals = require('resin-cli-visuals') umountAsync = Promise.promisify(require('umount').umount) prettyjson = require('prettyjson') Promise.try -> - return options.drive or visuals.drive('Select the device drive') + return options.drive or getVisuals().drive('Select the device drive') .tap(umountAsync) .then (drive) -> return config.read(drive, options.type) @@ -94,11 +93,10 @@ exports.write = Promise = require('bluebird') _ = require('lodash') config = require('balena-config-json') - visuals = require('resin-cli-visuals') umountAsync = Promise.promisify(require('umount').umount) Promise.try -> - return options.drive or visuals.drive('Select the device drive') + return options.drive or getVisuals().drive('Select the device drive') .tap(umountAsync) .then (drive) -> config.read(drive, options.type).then (configJSON) -> @@ -144,12 +142,11 @@ exports.inject = action: (params, options) -> Promise = require('bluebird') config = require('balena-config-json') - visuals = require('resin-cli-visuals') umountAsync = Promise.promisify(require('umount').umount) readFileAsync = Promise.promisify(require('fs').readFile) Promise.try -> - return options.drive or visuals.drive('Select the device drive') + return options.drive or getVisuals().drive('Select the device drive') .tap(umountAsync) .then (drive) -> readFileAsync(params.file, 'utf8').then(JSON.parse).then (configJSON) -> @@ -195,12 +192,11 @@ exports.reconfigure = action: (params, options) -> Promise = require('bluebird') config = require('balena-config-json') - visuals = require('resin-cli-visuals') { runCommand } = require('../utils/helpers') umountAsync = Promise.promisify(require('umount').umount) Promise.try -> - return options.drive or visuals.drive('Select the device drive') + return options.drive or getVisuals().drive('Select the device drive') .tap(umountAsync) .then (drive) -> config.read(drive, options.type).get('uuid') diff --git a/lib/actions/device.coffee b/lib/actions/device.coffee index 76349038..4c51e99f 100644 --- a/lib/actions/device.coffee +++ b/lib/actions/device.coffee @@ -17,7 +17,7 @@ limitations under the License. commandOptions = require('./command-options') _ = require('lodash') { normalizeUuidProp } = require('../utils/normalization') -{ getBalenaSdk } = require('../utils/lazy') +{ getBalenaSdk, getVisuals } = require('../utils/lazy') expandForAppName = { $expand: belongs_to__application: $select: 'app_name' @@ -44,7 +44,6 @@ exports.list = action: (params, options) -> Promise = require('bluebird') balena = getBalenaSdk() - visuals = require('resin-cli-visuals') Promise.try -> if options.application? @@ -59,7 +58,7 @@ exports.list = device.uuid = device.uuid.slice(0, 7) return device - console.log visuals.table.horizontal devices, [ + console.log getVisuals().table.horizontal devices, [ 'id' 'uuid' 'device_name' @@ -87,7 +86,6 @@ exports.info = action: (params, options) -> normalizeUuidProp(params) balena = getBalenaSdk() - visuals = require('resin-cli-visuals') balena.models.device.get(params.uuid, expandForAppName) .then (device) -> @@ -98,7 +96,7 @@ exports.info = if device.belongs_to__application?[0] then device.belongs_to__application[0].app_name else 'N/a' device.commit = device.is_on__commit - console.log visuals.table.vertical device, [ + console.log getVisuals().table.vertical device, [ "$#{device.device_name}$" 'id' 'device_type' diff --git a/lib/actions/keys.ts b/lib/actions/keys.ts index e70f9e7c..9b18094e 100644 --- a/lib/actions/keys.ts +++ b/lib/actions/keys.ts @@ -15,7 +15,7 @@ limitations under the License. */ import { CommandDefinition } from 'capitano'; -import { getBalenaSdk } from '../utils/lazy'; +import { getBalenaSdk, getVisuals } from '../utils/lazy'; import * as commandOptions from './command-options'; export const list: CommandDefinition = { @@ -32,8 +32,7 @@ Examples: async action() { const keys = await getBalenaSdk().models.key.getAll(); - const visuals = await import('resin-cli-visuals'); - console.log(visuals.table.horizontal(keys, ['id', 'title'])); + console.log(getVisuals().table.horizontal(keys, ['id', 'title'])); }, }; @@ -51,8 +50,7 @@ Examples: async action(params) { const key = await getBalenaSdk().models.key.get(params.id); - const visuals = await import('resin-cli-visuals'); - console.log(visuals.table.vertical(key, ['id', 'title'])); + console.log(getVisuals().table.vertical(key, ['id', 'title'])); // Since the public key string is long, it might // wrap to lines below, causing the table layout to break. diff --git a/lib/actions/local/flash.ts b/lib/actions/local/flash.ts index b11c406b..de0c19c4 100644 --- a/lib/actions/local/flash.ts +++ b/lib/actions/local/flash.ts @@ -18,6 +18,7 @@ import { CommandDefinition } from 'capitano'; import chalk from 'chalk'; import { stripIndent } from 'common-tags'; import * as SDK from 'etcher-sdk'; +import { getVisuals } from '../../utils/lazy'; async function getDrive(options: { drive?: string; @@ -73,7 +74,6 @@ export const flash: CommandDefinition< }, ], async action(params, options) { - const visuals = await import('resin-cli-visuals'); const form = await import('resin-cli-form'); const { sourceDestination, multiWrite } = await import('etcher-sdk'); @@ -98,6 +98,7 @@ export const flash: CommandDefinition< ); const source = await file.getInnerSource(); + const visuals = getVisuals(); const progressBars: { [key: string]: any } = { flashing: new visuals.Progress('Flashing'), verifying: new visuals.Progress('Validating'), diff --git a/lib/actions/os.coffee b/lib/actions/os.coffee index 1c2c4d19..dae2e6b8 100644 --- a/lib/actions/os.coffee +++ b/lib/actions/os.coffee @@ -16,7 +16,7 @@ limitations under the License. commandOptions = require('./command-options') _ = require('lodash') -{ getBalenaSdk } = require('../utils/lazy') +{ getBalenaSdk, getVisuals } = require('../utils/lazy') formatVersion = (v, isRecommended) -> result = "v#{v}" @@ -104,7 +104,6 @@ exports.download = fs = require('fs') rindle = require('rindle') manager = require('balena-image-manager') - visuals = require('resin-cli-visuals') console.info("Getting device operating system for #{params.type}") @@ -122,6 +121,7 @@ exports.download = displayVersion = " #{version}" return manager.get(params.type, version) .then (stream) -> + visuals = getVisuals() bar = new visuals.Progress("Downloading Device OS#{displayVersion}") spinner = new visuals.Spinner("Downloading Device OS#{displayVersion} (size unknown)") diff --git a/lib/actions/preload.coffee b/lib/actions/preload.coffee index 3a9d00f6..c55a9070 100644 --- a/lib/actions/preload.coffee +++ b/lib/actions/preload.coffee @@ -15,7 +15,7 @@ limitations under the License. ### _ = require('lodash') -{ getBalenaSdk } = require('../utils/lazy') +{ getBalenaSdk, getVisuals } = require('../utils/lazy') dockerUtils = require('../utils/docker') @@ -67,7 +67,7 @@ getApplicationsWithSuccessfulBuilds = (deviceType) -> $orderby: 'app_name asc' selectApplication = (deviceType) -> - visuals = require('resin-cli-visuals') + visuals = getVisuals() form = require('resin-cli-form') { exitWithExpectedError } = require('../utils/patterns') @@ -209,7 +209,7 @@ module.exports = Promise = require('bluebird') balena = getBalenaSdk() preload = require('balena-preload') - visuals = require('resin-cli-visuals') + visuals = getVisuals() nodeCleanup = require('node-cleanup') { exitWithExpectedError } = require('../utils/patterns') diff --git a/lib/actions/scan.coffee b/lib/actions/scan.coffee index 362bf4f5..5a0a3a9e 100644 --- a/lib/actions/scan.coffee +++ b/lib/actions/scan.coffee @@ -14,6 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. ### +{ getVisuals } = require('../utils/lazy') + dockerInfoProperties = [ 'Containers' 'ContainersRunning' @@ -75,7 +77,7 @@ module.exports = _ = require('lodash') prettyjson = require('prettyjson') { discover } = require('balena-sync') - { SpinnerPromise } = require('resin-cli-visuals') + { SpinnerPromise } = getVisuals() { dockerPort, dockerTimeout } = require('./local/common') dockerUtils = require('../utils/docker') { exitWithExpectedError } = require('../utils/patterns') diff --git a/lib/actions/tags.ts b/lib/actions/tags.ts index 136ebb2f..700ef8e4 100644 --- a/lib/actions/tags.ts +++ b/lib/actions/tags.ts @@ -17,7 +17,7 @@ limitations under the License. import { ApplicationTag, DeviceTag, ReleaseTag } from 'balena-sdk'; import { CommandDefinition } from 'capitano'; import { stripIndent } from 'common-tags'; -import { getBalenaSdk } from '../utils/lazy'; +import { getBalenaSdk, getVisuals } from '../utils/lazy'; import { disambiguateReleaseParam, normalizeUuidProp, @@ -59,7 +59,6 @@ export const list: CommandDefinition< const Bluebird = await import('bluebird'); const _ = await import('lodash'); const balena = getBalenaSdk(); - const visuals = await import('resin-cli-visuals'); const { exitWithExpectedError } = await import('../utils/patterns'); @@ -110,7 +109,7 @@ export const list: CommandDefinition< } console.log( - visuals.table.horizontal(environmentVariables, [ + getVisuals().table.horizontal(environmentVariables, [ 'id', 'tag_key', 'value', diff --git a/lib/actions/util.ts b/lib/actions/util.ts index 093448a8..4eea2877 100644 --- a/lib/actions/util.ts +++ b/lib/actions/util.ts @@ -22,6 +22,7 @@ limitations under the License. import { CommandDefinition } from 'capitano'; import chalk from 'chalk'; import { stripIndent } from 'common-tags'; +import { getVisuals } from '../utils/lazy'; export const availableDrives: CommandDefinition<{}, {}> = { signature: 'util available-drives', @@ -32,7 +33,6 @@ export const availableDrives: CommandDefinition<{}, {}> = { `, async action() { const sdk = await import('etcher-sdk'); - const visuals = await import('resin-cli-visuals'); const adapter = new sdk.scanner.adapters.BlockDeviceAdapter(() => false); const scanner = new sdk.scanner.Scanner([adapter]); @@ -53,11 +53,10 @@ export const availableDrives: CommandDefinition<{}, {}> = { ); } else { console.log( - visuals.table.horizontal(Array.from(scanner.drives).map(formatDrive), [ - 'device', - 'size', - 'description', - ]), + getVisuals().table.horizontal( + Array.from(scanner.drives).map(formatDrive), + ['device', 'size', 'description'], + ), ); } scanner.stop(); diff --git a/lib/utils/deploy-legacy.coffee b/lib/utils/deploy-legacy.coffee index 28d53019..c7acad50 100644 --- a/lib/utils/deploy-legacy.coffee +++ b/lib/utils/deploy-legacy.coffee @@ -1,4 +1,5 @@ Promise = require('bluebird') +{ getVisuals } = require('./lazy') getBuilderPushEndpoint = (baseUrl, owner, app) -> querystring = require('querystring') @@ -23,7 +24,7 @@ bufferImage = (docker, imageId, bufferFile) -> bufferedStream.length = imageSize showPushProgress = (message) -> - visuals = require('resin-cli-visuals') + visuals = getVisuals() progressBar = new visuals.Progress(message) progressBar.update({ percentage: 0 }) return progressBar diff --git a/lib/utils/helpers.ts b/lib/utils/helpers.ts index 5017ee81..5e394556 100644 --- a/lib/utils/helpers.ts +++ b/lib/utils/helpers.ts @@ -20,11 +20,10 @@ import Bluebird = require('bluebird'); import chalk from 'chalk'; import _ = require('lodash'); import os = require('os'); -import visuals = require('resin-cli-visuals'); import * as ShellEscape from 'shell-escape'; import { ExpectedError } from '../errors'; -import { getBalenaSdk } from './lazy'; +import { getBalenaSdk, getVisuals } from './lazy'; export function getGroupDefaults(group: { options: Array<{ name: string; default?: string }>; @@ -129,6 +128,7 @@ export async function osProgressHandler(step: InitializeEmitter) { console.log(exports.stateToString(state)); }); + const visuals = getVisuals(); const progressBars = { write: new visuals.Progress('Writing Device OS'), check: new visuals.Progress('Validating Device OS'), diff --git a/lib/utils/lazy.ts b/lib/utils/lazy.ts index c3eb67fa..da1f1020 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 * as visuals from 'resin-cli-visuals'; // Equivalent of _.once but avoiding the need to import lodash for lazy deps const once = (fn: () => T) => { @@ -30,3 +31,7 @@ const once = (fn: () => T) => { export const getBalenaSdk = once(() => (require('balena-sdk') as typeof BalenaSdk).fromSharedOptions(), ); + +export const getVisuals = once( + () => require('resin-cli-visuals') as typeof visuals, +); diff --git a/lib/utils/patterns.ts b/lib/utils/patterns.ts index 19b0629b..6e463977 100644 --- a/lib/utils/patterns.ts +++ b/lib/utils/patterns.ts @@ -20,15 +20,13 @@ import chalk from 'chalk'; import { stripIndent } from 'common-tags'; import _ = require('lodash'); import _form = require('resin-cli-form'); -import _visuals = require('resin-cli-visuals'); import { NotLoggedInError } from '../errors'; -import { getBalenaSdk } from './lazy'; +import { getBalenaSdk, getVisuals } from './lazy'; import messages = require('./messages'); import validation = require('./validation'); const getForm = _.once((): typeof _form => require('resin-cli-form')); -const getVisuals = _.once((): typeof _visuals => require('resin-cli-visuals')); export function authenticate(options: {}): Bluebird { const balena = getBalenaSdk(); diff --git a/lib/utils/promote.ts b/lib/utils/promote.ts index 5104ca0b..9c1afef2 100644 --- a/lib/utils/promote.ts +++ b/lib/utils/promote.ts @@ -18,6 +18,7 @@ import * as BalenaSdk from 'balena-sdk'; import { stripIndent } from 'common-tags'; import { ExpectedError } from '../errors'; +import { getVisuals } from './lazy'; import Logger = require('./logger'); import { exec, execBuffered, getDeviceOsRelease } from './ssh'; @@ -87,7 +88,7 @@ async function execCommand( msg: string, ): Promise { const through = await import('through2'); - const visuals = await import('resin-cli-visuals'); + const visuals = getVisuals(); const spinner = new visuals.Spinner(`[${deviceIp}] Connecting...`); const innerSpinner = spinner.spinner; diff --git a/lib/utils/remote-build.ts b/lib/utils/remote-build.ts index 12eb8d7a..b619092d 100644 --- a/lib/utils/remote-build.ts +++ b/lib/utils/remote-build.ts @@ -27,6 +27,7 @@ import Logger = require('./logger'); import { exitWithExpectedError } from '../utils/patterns'; import { tarDirectory } from './compose'; +import { getVisuals } from './lazy'; const globalLogger = Logger.getLogger(); @@ -280,7 +281,7 @@ async function getTarStream(build: RemoteBuild): Promise { }, }; if (process.stdout.isTTY) { - const visuals = await import('resin-cli-visuals'); + const visuals = getVisuals(); tarSpinner = new visuals.Spinner('Packaging the project source...'); } @@ -375,7 +376,7 @@ async function getRemoteBuildStream( }; // We only show the spinner when outputting to a tty if (process.stdout.isTTY) { - const visuals = await import('resin-cli-visuals'); + const visuals = getVisuals(); uploadSpinner = new visuals.Spinner( 'Uploading source package to balena cloud', );