From d6f1328238c18c77c614f16885366353236ae80c Mon Sep 17 00:00:00 2001 From: Pagan Gazzard Date: Wed, 8 Jul 2020 18:21:37 +0100 Subject: [PATCH] Be lazier with imports in oclif actions Change-type: patch --- lib/actions-oclif/app/create.ts | 8 ++++--- lib/actions-oclif/apps.ts | 2 +- lib/actions-oclif/device/init.ts | 4 ++-- lib/actions-oclif/device/move.ts | 2 +- lib/actions-oclif/device/os-update.ts | 2 +- lib/actions-oclif/env/rm.ts | 4 ++-- lib/actions-oclif/envs.ts | 2 +- lib/actions-oclif/internal/osinit.ts | 6 +++--- lib/actions-oclif/login.ts | 31 ++++++++++++++------------- lib/actions-oclif/logs.ts | 2 +- lib/actions-oclif/os/configure.ts | 4 ++-- lib/actions-oclif/settings.ts | 8 +++---- lib/actions-oclif/ssh.ts | 22 +++++++++---------- lib/utils/patterns.ts | 2 +- tsconfig.json | 3 ++- 15 files changed, 52 insertions(+), 50 deletions(-) diff --git a/lib/actions-oclif/app/create.ts b/lib/actions-oclif/app/create.ts index e3ab5410..beda6cba 100644 --- a/lib/actions-oclif/app/create.ts +++ b/lib/actions-oclif/app/create.ts @@ -20,6 +20,7 @@ import Command from '../../command'; import { ExpectedError } from '../../errors'; import * as cf from '../../utils/common-flags'; import { getBalenaSdk, stripIndent } from '../../utils/lazy'; +import type * as BalenaSDK from 'balena-sdk'; interface FlagsDef { type?: string; // application device type @@ -75,11 +76,12 @@ export default class AppCreateCmd extends Command { ); const balena = getBalenaSdk(); - const patterns = await import('../../utils/patterns'); // Create application - const deviceType = options.type || (await patterns.selectDeviceType()); - let application: import('balena-sdk').Application; + const deviceType = + options.type || + (await (await import('../../utils/patterns')).selectDeviceType()); + let application: BalenaSDK.Application; try { application = await balena.models.application.create({ name: params.name, diff --git a/lib/actions-oclif/apps.ts b/lib/actions-oclif/apps.ts index 8fe74900..6991fd2d 100644 --- a/lib/actions-oclif/apps.ts +++ b/lib/actions-oclif/apps.ts @@ -61,7 +61,6 @@ export default class AppsCmd extends Command { public async run() { const { flags: options } = this.parse(AppsCmd); - const _ = await import('lodash'); const balena = getBalenaSdk(); // Get applications @@ -72,6 +71,7 @@ export default class AppsCmd extends Command { }, ); + const _ = await import('lodash'); // Add extended properties applications.forEach((application) => { application.device_count = application.owns__device?.length ?? 0; diff --git a/lib/actions-oclif/device/init.ts b/lib/actions-oclif/device/init.ts index 25134eeb..9e3c0c44 100644 --- a/lib/actions-oclif/device/init.ts +++ b/lib/actions-oclif/device/init.ts @@ -92,7 +92,6 @@ export default class DeviceInitCmd extends Command { const tmpNameAsync = promisify(tmp.tmpName); tmp.setGracefulCleanup(); const balena = getBalenaSdk(); - const patterns = await import('../../utils/patterns'); const Logger = await import('../../utils/logger'); const logger = Logger.getLogger(); @@ -103,7 +102,8 @@ export default class DeviceInitCmd extends Command { // Get application and const application = await balena.models.application.get( - options['application'] || (await patterns.selectApplication()), + options['application'] || + (await (await import('../../utils/patterns')).selectApplication()), ); // Register new device diff --git a/lib/actions-oclif/device/move.ts b/lib/actions-oclif/device/move.ts index 2accb885..7394a135 100644 --- a/lib/actions-oclif/device/move.ts +++ b/lib/actions-oclif/device/move.ts @@ -77,7 +77,6 @@ export default class DeviceMoveCmd extends Command { ); const balena = getBalenaSdk(); - const patterns = await import('../../utils/patterns'); // Consolidate application options options.application = options.application || options.app; @@ -113,6 +112,7 @@ export default class DeviceMoveCmd extends Command { dt.state !== 'DISCONTINUED', ); + const patterns = await import('../../utils/patterns'); application = await patterns.selectApplication( (app: Application) => compatibleDeviceTypes.some((dt) => dt.slug === app.device_type) && diff --git a/lib/actions-oclif/device/os-update.ts b/lib/actions-oclif/device/os-update.ts index 46f5da4d..a28f2dc6 100644 --- a/lib/actions-oclif/device/os-update.ts +++ b/lib/actions-oclif/device/os-update.ts @@ -77,7 +77,6 @@ export default class DeviceOsUpdateCmd extends Command { ); const sdk = getBalenaSdk(); - const patterns = await import('../../utils/patterns'); // Get device info const { @@ -133,6 +132,7 @@ export default class DeviceOsUpdateCmd extends Command { }); } + const patterns = await import('../../utils/patterns'); // Confirm and start update await patterns.confirm( options.yes || false, diff --git a/lib/actions-oclif/env/rm.ts b/lib/actions-oclif/env/rm.ts index 59d44024..50369405 100644 --- a/lib/actions-oclif/env/rm.ts +++ b/lib/actions-oclif/env/rm.ts @@ -87,11 +87,10 @@ export default class EnvRmCmd extends Command { const { args: params, flags: opt } = this.parse( EnvRmCmd, ); - const balena = getBalenaSdk(); - const { confirm } = await import('../../utils/patterns'); await Command.checkLoggedIn(); + const { confirm } = await import('../../utils/patterns'); await confirm( opt.yes || false, 'Are you sure you want to delete the environment variable?', @@ -99,6 +98,7 @@ export default class EnvRmCmd extends Command { true, ); + const balena = getBalenaSdk(); await balena.pine.delete({ resource: ec.getVarResourceName(opt.config, opt.device, opt.service), id: params.id, diff --git a/lib/actions-oclif/envs.ts b/lib/actions-oclif/envs.ts index 50742099..d32a4926 100644 --- a/lib/actions-oclif/envs.ts +++ b/lib/actions-oclif/envs.ts @@ -201,12 +201,12 @@ export default class EnvsCmd extends Command { } const balena = getBalenaSdk(); - const { getDeviceAndMaybeAppFromUUID } = await import('../utils/cloud'); let appName = options.application; let fullUUID: string | undefined; // as oppposed to the short, 7-char UUID if (options.device) { + const { getDeviceAndMaybeAppFromUUID } = await import('../utils/cloud'); const [device, app] = await getDeviceAndMaybeAppFromUUID( balena, options.device, diff --git a/lib/actions-oclif/internal/osinit.ts b/lib/actions-oclif/internal/osinit.ts index cb08d412..1a523b9a 100644 --- a/lib/actions-oclif/internal/osinit.ts +++ b/lib/actions-oclif/internal/osinit.ts @@ -67,14 +67,14 @@ export default class OsinitCmd extends Command { public async run() { const { args: params } = this.parse<{}, ArgsDef>(OsinitCmd); - const { initialize } = await import('balena-device-init'); + const config = JSON.parse(params.config); + const { getManifest, osProgressHandler } = await import( '../../utils/helpers' ); - - const config = JSON.parse(params.config); const manifest = await getManifest(params.image, params.type); + const { initialize } = await import('balena-device-init'); const initializeEmitter = await initialize(params.image, manifest, config); await osProgressHandler(initializeEmitter); } diff --git a/lib/actions-oclif/login.ts b/lib/actions-oclif/login.ts index ce2039af..83992b52 100644 --- a/lib/actions-oclif/login.ts +++ b/lib/actions-oclif/login.ts @@ -123,6 +123,7 @@ export default class LoginCmd extends Command { console.log(messages.balenaAsciiArt); console.log(`\nLogging in to ${balenaUrl}`); await this.doLogin(options, params.token); + const username = await balena.auth.whoami(); console.info(`Successfully logged in as: ${username}`); @@ -141,9 +142,6 @@ ${messages.reachingOut}`); } async doLogin(loginOptions: FlagsDef, token?: string): Promise { - const patterns = await import('../utils/patterns'); - const balena = getBalenaSdk(); - // Token if (loginOptions.token) { if (!token) { @@ -153,6 +151,7 @@ ${messages.reachingOut}`); type: 'input', }); } + const balena = getBalenaSdk(); await balena.auth.loginWithToken(token!); if (!(await balena.auth.whoami())) { throw new ExpectedError('Token authentication failed'); @@ -161,6 +160,7 @@ ${messages.reachingOut}`); } // Credentials else if (loginOptions.credentials) { + const patterns = await import('../utils/patterns'); return patterns.authenticate(loginOptions); } // Web @@ -168,19 +168,20 @@ ${messages.reachingOut}`); const auth = await import('../auth'); await auth.login(); return; - } + } else { + const patterns = await import('../utils/patterns'); + // User had not selected login preference, prompt interactively + const loginType = await patterns.askLoginType(); + if (loginType === 'register') { + const signupUrl = 'https://dashboard.balena-cloud.com/signup'; + const open = await import('open'); + open(signupUrl, { wait: false }); + throw new ExpectedError(`Please sign up at ${signupUrl}`); + } - // User had not selected login preference, prompt interactively - const loginType = await patterns.askLoginType(); - if (loginType === 'register') { - const signupUrl = 'https://dashboard.balena-cloud.com/signup'; - const open = await import('open'); - open(signupUrl, { wait: false }); - throw new ExpectedError(`Please sign up at ${signupUrl}`); + // Set login options flag from askLoginType, and run again + loginOptions[loginType] = true; + return this.doLogin(loginOptions); } - - // Set login options flag from askLoginType, and run again - loginOptions[loginType] = true; - return this.doLogin(loginOptions); } } diff --git a/lib/actions-oclif/logs.ts b/lib/actions-oclif/logs.ts index 850a69b6..ad187ec7 100644 --- a/lib/actions-oclif/logs.ts +++ b/lib/actions-oclif/logs.ts @@ -102,7 +102,6 @@ export default class LogsCmd extends Command { ); const balena = getBalenaSdk(); - const { ExpectedError } = await import('../errors'); const { serviceIdToName } = await import('../utils/cloud'); const { displayDeviceLogs, displayLogObject } = await import( '../utils/device/logs' @@ -147,6 +146,7 @@ export default class LogsCmd extends Command { try { await deviceApi.ping(); } catch (e) { + const { ExpectedError } = await import('../errors'); throw new ExpectedError( `Cannot access device at address ${params.device}. Device may not be in local mode.`, ); diff --git a/lib/actions-oclif/os/configure.ts b/lib/actions-oclif/os/configure.ts index 54b43d2d..557775d9 100644 --- a/lib/actions-oclif/os/configure.ts +++ b/lib/actions-oclif/os/configure.ts @@ -192,7 +192,6 @@ export default class OsConfigureCmd extends Command { '../../utils/config' ); const helpers = await import('../../utils/helpers'); - const imagefs = await require('resin-image-fs'); let app: BalenaSdk.Application | undefined; let device: BalenaSdk.Device | undefined; let deviceTypeSlug: string; @@ -273,6 +272,7 @@ export default class OsConfigureCmd extends Command { }; }), ); + const imagefs = await import('resin-image-fs'); for (const { name, content } of files) { await imagefs.writeFile( @@ -396,7 +396,6 @@ async function askQuestionsForDeviceType( options: FlagsDef, configJson?: import('../../utils/config').ImgConfig, ): Promise { - const helpers = await import('../../utils/helpers'); const answerSources: any[] = [camelifyConfigOptions(options)]; const defaultAnswers: Partial = {}; const questions: any = deviceType.options; @@ -412,6 +411,7 @@ async function askQuestionsForDeviceType( isGroup: true, }); if (!_.isEmpty(advancedGroup)) { + const helpers = await import('../../utils/helpers'); answerSources.push(helpers.getGroupDefaults(advancedGroup)); } } diff --git a/lib/actions-oclif/settings.ts b/lib/actions-oclif/settings.ts index 72414430..68b77bd0 100644 --- a/lib/actions-oclif/settings.ts +++ b/lib/actions-oclif/settings.ts @@ -41,11 +41,9 @@ export default class SettingsCmd extends Command { public async run() { this.parse(SettingsCmd); - const prettyjson = await import('prettyjson'); + const settings = await getBalenaSdk().settings.getAll(); - return getBalenaSdk() - .settings.getAll() - .then(prettyjson.render) - .then(console.log); + const prettyjson = await import('prettyjson'); + console.log(prettyjson.render(settings)); } } diff --git a/lib/actions-oclif/ssh.ts b/lib/actions-oclif/ssh.ts index 4b4bc81e..050e74dc 100644 --- a/lib/actions-oclif/ssh.ts +++ b/lib/actions-oclif/ssh.ts @@ -123,17 +123,6 @@ export default class NoteCmd extends Command { NoteCmd, ); - const { ExpectedError } = await import('../errors'); - const { getProxyConfig, which } = await import('../utils/helpers'); - const { checkLoggedIn, getOnlineTargetUuid } = await import( - '../utils/patterns' - ); - const { spawnSshAndThrowOnError } = await import('../utils/ssh'); - const sdk = getBalenaSdk(); - - const proxyConfig = getProxyConfig(); - const useProxy = !!proxyConfig && !options.noproxy; - // if we're doing a direct SSH connection locally... if ( validateDotLocalUrl(params.applicationOrDevice) || @@ -149,6 +138,15 @@ export default class NoteCmd extends Command { }); } + const { getProxyConfig, which } = await import('../utils/helpers'); + const { checkLoggedIn, getOnlineTargetUuid } = await import( + '../utils/patterns' + ); + const sdk = getBalenaSdk(); + + const proxyConfig = getProxyConfig(); + const useProxy = !!proxyConfig && !options.noproxy; + // this will be a tunnelled SSH connection... await checkLoggedIn(); const uuid = await getOnlineTargetUuid(sdk, params.applicationOrDevice); @@ -207,6 +205,7 @@ export default class NoteCmd extends Command { const proxyCommand = useProxy ? getSshProxyCommand() : undefined; if (username == null) { + const { ExpectedError } = await import('../errors'); throw new ExpectedError( `Opening an SSH connection to a remote device requires you to be logged in.`, ); @@ -248,6 +247,7 @@ export default class NoteCmd extends Command { username: username!, }); + const { spawnSshAndThrowOnError } = await import('../utils/ssh'); return spawnSshAndThrowOnError(command); } diff --git a/lib/utils/patterns.ts b/lib/utils/patterns.ts index 824d0b2d..c7c402ea 100644 --- a/lib/utils/patterns.ts +++ b/lib/utils/patterns.ts @@ -13,7 +13,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -import { BalenaApplicationNotFound } from 'balena-errors'; import type * as BalenaSdk from 'balena-sdk'; import _ = require('lodash'); @@ -391,6 +390,7 @@ export async function getOnlineTargetUuid( })), }); } catch (err) { + const { BalenaApplicationNotFound } = await import('balena-errors'); if (!instanceOf(err, BalenaApplicationNotFound)) { throw err; } diff --git a/tsconfig.json b/tsconfig.json index c234de56..3875e61e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -21,6 +21,7 @@ "allowJs": true }, "include": [ - "./lib/**/*" + "./lib/**/*", + "./typings/**/*" ] }