mirror of
https://github.com/balena-io/balena-cli.git
synced 2024-12-21 22:47:48 +00:00
02b888f7c1
* Add pkgExec internal command * Patch windosu to be aware of process.pkg and use pkgExec Change-type: patch Signed-off-by: Paulo Castro <paulo@balena.io>
78 lines
2.8 KiB
TypeScript
78 lines
2.8 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2019 Balena Ltd.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* 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.
|
|
*/
|
|
|
|
/**
|
|
* CLI entrypoint, but see also `bin/balena` and `bin/balena-dev` which
|
|
* call this function.
|
|
*/
|
|
export async function run(
|
|
cliArgs = process.argv,
|
|
options: import('./preparser').AppOptions = {},
|
|
) {
|
|
// The 'pkgExec' special/internal command provides a Node.js interpreter
|
|
// for use of the standalone zip package. See pkgExec function.
|
|
if (cliArgs.length > 3 && cliArgs[2] === 'pkgExec') {
|
|
return pkgExec(cliArgs[3], cliArgs.slice(4));
|
|
}
|
|
|
|
const { globalInit } = await import('./app-common');
|
|
const { routeCliFramework } = await import('./preparser');
|
|
|
|
// globalInit() must be called very early on (before other imports) because
|
|
// it sets up Sentry error reporting, global HTTP proxy settings, balena-sdk
|
|
// shared options, and performs node version requirement checks.
|
|
globalInit();
|
|
await routeCliFramework(cliArgs, options);
|
|
}
|
|
|
|
/**
|
|
* Implements the 'pkgExec' command, used as a way to provide a Node.js
|
|
* interpreter for child_process.spawn()-like operations when the CLI is
|
|
* executing as a standalone zip package (built-in Node interpreter) and
|
|
* the system may not have a separate Node.js installation. A present use
|
|
* case is a patched version of the 'windosu' package that requires a
|
|
* Node.js interpreter to spawn a privileged child process.
|
|
*
|
|
* @param modFunc Path to a JS module that will be executed via require().
|
|
* The modFunc argument may optionally contain a function name separated
|
|
* by '::', for example '::main' in:
|
|
* 'C:\\snapshot\\balena-cli\\node_modules\\windosu\\lib\\pipe.js::main'
|
|
* in which case that function is executed in the require'd module.
|
|
* @param args Optional arguments to passed through process.argv and as
|
|
* arguments to the function specified via modFunc.
|
|
*/
|
|
async function pkgExec(modFunc: string, args: string[]) {
|
|
const [modPath, funcName] = modFunc.split('::');
|
|
let replacedModPath = modPath;
|
|
const match = modPath
|
|
.replace(/\\/g, '/')
|
|
.match(/\/snapshot\/balena-cli\/(.+)/);
|
|
if (match) {
|
|
replacedModPath = `../${match[1]}`;
|
|
}
|
|
process.argv = [process.argv[0], process.argv[1], ...args];
|
|
try {
|
|
const mod: any = await import(replacedModPath);
|
|
if (funcName) {
|
|
await mod[funcName](...args);
|
|
}
|
|
} catch (err) {
|
|
console.error(`Error executing pkgExec "${modFunc}" [${args.join()}]`);
|
|
console.error(err);
|
|
}
|
|
}
|