Refactor dependency import in utils/helpers.ts for performance

Change-type: patch
This commit is contained in:
Paulo Castro 2021-04-09 22:39:23 +01:00
parent 83a23d9f30
commit 06f7683837

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2020 Balena Copyright 2016-2021 Balena Ltd.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -16,16 +16,11 @@ limitations under the License.
import type { InitializeEmitter, OperationState } from 'balena-device-init'; import type { InitializeEmitter, OperationState } from 'balena-device-init';
import type * as BalenaSdk from 'balena-sdk'; import type * as BalenaSdk from 'balena-sdk';
import { spawn, SpawnOptions } from 'child_process';
import * as _ from 'lodash';
import * as os from 'os';
import type * as ShellEscape from 'shell-escape';
import type { Device, PineOptions } from 'balena-sdk'; import * as _ from 'lodash';
import { ExpectedError, SIGINTError } from '../errors';
import { getBalenaSdk, getChalk, getVisuals } from './lazy';
import { promisify } from 'util'; import { promisify } from 'util';
import { isSubcommand } from '../preparser';
import { getBalenaSdk, getChalk, getVisuals } from './lazy';
export function getGroupDefaults(group: { export function getGroupDefaults(group: {
options: Array<{ name: string; default: string | number }>; options: Array<{ name: string; default: string | number }>;
@ -84,7 +79,7 @@ export async function sudo(
) { ) {
const { executeWithPrivileges } = await import('./sudo'); const { executeWithPrivileges } = await import('./sudo');
if (os.platform() !== 'win32') { if (process.platform !== 'win32') {
console.log( console.log(
msg || msg ||
'Admin privileges required: you may be asked for your computer password to continue.', 'Admin privileges required: you may be asked for your computer password to continue.',
@ -95,6 +90,9 @@ export async function sudo(
} }
export function runCommand<T>(commandArgs: string[]): Promise<T> { export function runCommand<T>(commandArgs: string[]): Promise<T> {
const {
isSubcommand,
} = require('../preparser') as typeof import('../preparser');
if (isSubcommand(commandArgs)) { if (isSubcommand(commandArgs)) {
commandArgs = [ commandArgs = [
commandArgs[0] + ':' + commandArgs[1], commandArgs[0] + ':' + commandArgs[1],
@ -238,6 +236,7 @@ export async function retry<T>({
backoffScaler?: number; backoffScaler?: number;
maxSingleDelayMs?: number; maxSingleDelayMs?: number;
}): Promise<T> { }): Promise<T> {
const { SIGINTError } = await import('../errors');
let delayMs = initialDelayMs; let delayMs = initialDelayMs;
for (let count = 0; count < maxAttempts - 1; count++) { for (let count = 0; count < maxAttempts - 1; count++) {
const lastAttemptMs = Date.now(); const lastAttemptMs = Date.now();
@ -348,7 +347,7 @@ export function shellEscape(args: string[], detectShell = false): string[] {
if (isCmdExe) { if (isCmdExe) {
return args.map((v) => windowsCmdExeEscapeArg(v)); return args.map((v) => windowsCmdExeEscapeArg(v));
} else { } else {
const shellEscapeFunc: typeof ShellEscape = require('shell-escape'); const shellEscapeFunc: typeof import('shell-escape') = require('shell-escape');
return args.map((v) => shellEscapeFunc([v])); return args.map((v) => shellEscapeFunc([v]));
} }
} }
@ -392,6 +391,7 @@ export async function which(
} catch (err) { } catch (err) {
if (err.code === 'ENOENT') { if (err.code === 'ENOENT') {
if (rejectOnMissing) { if (rejectOnMissing) {
const { ExpectedError } = await import('../errors');
throw new ExpectedError( throw new ExpectedError(
`'${program}' program not found. Is it installed?`, `'${program}' program not found. Is it installed?`,
); );
@ -422,9 +422,10 @@ export async function which(
export async function whichSpawn( export async function whichSpawn(
programName: string, programName: string,
args: string[], args: string[],
options: SpawnOptions = { stdio: 'inherit' }, options: import('child_process').SpawnOptions = { stdio: 'inherit' },
returnExitCodeOrSignal = false, returnExitCodeOrSignal = false,
): Promise<[number | undefined, string | undefined]> { ): Promise<[number | undefined, string | undefined]> {
const { spawn } = await import('child_process');
const program = await which(programName); const program = await which(programName);
if (process.env.DEBUG) { if (process.env.DEBUG) {
console.error(`[debug] [${program}, ${args.join(', ')}]`); console.error(`[debug] [${program}, ${args.join(', ')}]`);
@ -510,7 +511,7 @@ export function getProxyConfig(): ProxyConfig | undefined {
} }
} }
export const expandForAppName: PineOptions<Device> = { export const expandForAppName: BalenaSdk.PineOptions<BalenaSdk.Device> = {
$expand: { $expand: {
belongs_to__application: { $select: 'app_name' }, belongs_to__application: { $select: 'app_name' },
is_of__device_type: { $select: 'slug' }, is_of__device_type: { $select: 'slug' },
@ -565,6 +566,9 @@ export async function awaitInterruptibleTask<
let sigintHandler: () => void = () => undefined; let sigintHandler: () => void = () => undefined;
const sigintPromise = new Promise<T>((_resolve, reject) => { const sigintPromise = new Promise<T>((_resolve, reject) => {
sigintHandler = () => { sigintHandler = () => {
const {
SIGINTError,
} = require('../errors') as typeof import('../errors');
reject(new SIGINTError('Task aborted on SIGINT signal')); reject(new SIGINTError('Task aborted on SIGINT signal'));
}; };
addSIGINTHandler(sigintHandler); addSIGINTHandler(sigintHandler);