Move to @oclif/core v2

Change-type: patch
This commit is contained in:
Otávio Jacobi 2023-09-06 11:39:31 -03:00
parent 26bc68753b
commit 77906c4152
104 changed files with 835 additions and 2111 deletions

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { Command as OclifCommandClass } from '@oclif/command'; import { Command as OclifCommandClass } from '@oclif/core';
type OclifCommand = typeof OclifCommandClass; type OclifCommand = typeof OclifCommandClass;

View File

@ -62,12 +62,11 @@ class FakeHelpCommand {
'$ balena help os download', '$ balena help os download',
]; ];
args = [ args = {
{ command: {
name: 'command',
description: 'command to show help for', description: 'command to show help for',
}, },
]; };
usage = 'help [command]'; usage = 'help [command]';

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { flagUsages } from '@oclif/parser'; import { Parser } from '@oclif/core';
import * as ent from 'ent'; import * as ent from 'ent';
import * as _ from 'lodash'; import * as _ from 'lodash';
@ -37,8 +37,8 @@ function renderOclifCommand(command: OclifCommand): string[] {
if (!_.isEmpty(command.args)) { if (!_.isEmpty(command.args)) {
result.push('### Arguments'); result.push('### Arguments');
for (const arg of command.args!) { for (const [name, arg] of Object.entries(command.args!)) {
result.push(`#### ${arg.name.toUpperCase()}`, arg.description || ''); result.push(`#### ${name.toUpperCase()}`, arg.description || '');
} }
} }
@ -49,7 +49,7 @@ function renderOclifCommand(command: OclifCommand): string[] {
continue; continue;
} }
flag.name = name; flag.name = name;
const flagUsage = flagUsages([flag]) const flagUsage = Parser.flagUsages([flag])
.map(([usage, _description]) => usage) .map(([usage, _description]) => usage)
.join() .join()
.trim(); .trim();

View File

@ -24,6 +24,7 @@ import {
} from './preparser'; } from './preparser';
import { CliSettings } from './utils/bootstrap'; import { CliSettings } from './utils/bootstrap';
import { onceAsync } from './utils/lazy'; import { onceAsync } from './utils/lazy';
import { run as mainRun } from '@oclif/core';
/** /**
* Sentry.io setup * Sentry.io setup
@ -114,10 +115,9 @@ async function oclifRun(command: string[], options: AppOptions) {
} }
const runPromise = (async function (shouldFlush: boolean) { const runPromise = (async function (shouldFlush: boolean) {
const { CustomMain } = await import('./utils/oclif-utils');
let isEEXIT = false; let isEEXIT = false;
try { try {
await CustomMain.run(command); await mainRun(command, options.configPath);
} catch (error) { } catch (error) {
// oclif sometimes exits with ExitError code EEXIT 0 (not an error), // oclif sometimes exits with ExitError code EEXIT 0 (not an error),
// for example the `balena help` command. // for example the `balena help` command.
@ -130,7 +130,7 @@ async function oclifRun(command: string[], options: AppOptions) {
} }
} }
if (shouldFlush) { if (shouldFlush) {
await import('@oclif/command/flush'); await import('@oclif/core/flush');
} }
// TODO: figure out why we need to call fast-boot stop() here, in // TODO: figure out why we need to call fast-boot stop() here, in
// addition to calling it in the main `run()` function in this file. // addition to calling it in the main `run()` function in this file.

View File

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import Command from '@oclif/command'; import { Command } from '@oclif/core';
import { import {
InsufficientPrivilegesError, InsufficientPrivilegesError,
NotAvailableInOfflineModeError, NotAvailableInOfflineModeError,

View File

@ -15,20 +15,12 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Args } from '@oclif/core';
import Command from '../../command'; import Command from '../../command';
import { ExpectedError } from '../../errors'; import { ExpectedError } from '../../errors';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, stripIndent } from '../../utils/lazy';
interface FlagsDef {
help: void;
}
interface ArgsDef {
name: string;
}
export default class GenerateCmd extends Command { export default class GenerateCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Generate a new balenaCloud API key. Generate a new balenaCloud API key.
@ -41,24 +33,23 @@ export default class GenerateCmd extends Command {
`; `;
public static examples = ['$ balena api-key generate "Jenkins Key"']; public static examples = ['$ balena api-key generate "Jenkins Key"'];
public static args = [ public static args = {
{ name: Args.string({
name: 'name',
description: 'the API key name', description: 'the API key name',
required: true, required: true,
}, }),
]; };
public static usage = 'api-key generate <name>'; public static usage = 'api-key generate <name>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
help: cf.help, help: cf.help,
}; };
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params } = this.parse<FlagsDef, ArgsDef>(GenerateCmd); const { args: params } = await this.parse(GenerateCmd);
let key; let key;
try { try {

View File

@ -15,19 +15,11 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Args } from '@oclif/core';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, stripIndent } from '../../utils/lazy';
interface FlagsDef {
help: void;
}
interface ArgsDef {
ids: string;
}
export default class RevokeCmd extends Command { export default class RevokeCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Revoke balenaCloud API keys. Revoke balenaCloud API keys.
@ -42,24 +34,23 @@ export default class RevokeCmd extends Command {
'$ balena api-key revoke 123,124,456', '$ balena api-key revoke 123,124,456',
]; ];
public static args = [ public static args = {
{ ids: Args.string({
name: 'ids',
description: 'the API key ids', description: 'the API key ids',
required: true, required: true,
}, }),
]; };
public static usage = 'api-key revoke <ids>'; public static usage = 'api-key revoke <ids>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
help: cf.help, help: cf.help,
}; };
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params } = this.parse<FlagsDef, ArgsDef>(RevokeCmd); const { args: params } = await this.parse(RevokeCmd);
try { try {
const apiKeyIds = params.ids.split(','); const apiKeyIds = params.ids.split(',');

View File

@ -15,17 +15,11 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags } from '@oclif/core';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
interface FlagsDef {
help: void;
user?: void;
fleet?: string;
}
export default class ApiKeysCmd extends Command { export default class ApiKeysCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Print a list of balenaCloud API keys. Print a list of balenaCloud API keys.
@ -36,13 +30,11 @@ export default class ApiKeysCmd extends Command {
`; `;
public static examples = ['$ balena api-keys']; public static examples = ['$ balena api-keys'];
public static args = [];
public static usage = 'api-keys'; public static usage = 'api-keys';
public static flags: flags.Input<FlagsDef> = { public static flags = {
help: cf.help, help: cf.help,
user: flags.boolean({ user: Flags.boolean({
char: 'u', char: 'u',
description: 'show API keys for your user', description: 'show API keys for your user',
}), }),
@ -52,7 +44,7 @@ export default class ApiKeysCmd extends Command {
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { flags: options } = this.parse<FlagsDef, {}>(ApiKeysCmd); const { flags: options } = await this.parse(ApiKeysCmd);
try { try {
const { getApplication } = await import('../../utils/sdk'); const { getApplication } = await import('../../utils/sdk');

View File

@ -15,12 +15,11 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags, Args } from '@oclif/core';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { stripIndent } from '../../utils/lazy'; import { stripIndent } from '../../utils/lazy';
import { ArgsDef, FlagsDef } from '../../utils/application-create';
export default class AppCreateCmd extends Command { export default class AppCreateCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
@ -50,22 +49,21 @@ export default class AppCreateCmd extends Command {
'$ balena app create MyApp -o myorg --type raspberry-pi', '$ balena app create MyApp -o myorg --type raspberry-pi',
]; ];
public static args = [ public static args = {
{ name: Args.string({
name: 'name',
description: 'app name', description: 'app name',
required: true, required: true,
}, }),
]; };
public static usage = 'app create <name>'; public static usage = 'app create <name>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
organization: flags.string({ organization: Flags.string({
char: 'o', char: 'o',
description: 'handle of the organization the app should belong to', description: 'handle of the organization the app should belong to',
}), }),
type: flags.string({ type: Flags.string({
char: 't', char: 't',
description: description:
'app device type (Check available types with `balena devices supported`)', 'app device type (Check available types with `balena devices supported`)',
@ -76,9 +74,7 @@ export default class AppCreateCmd extends Command {
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(AppCreateCmd);
AppCreateCmd,
);
await ( await (
await import('../../utils/application-create') await import('../../utils/application-create')

View File

@ -15,22 +15,12 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags, Args } from '@oclif/core';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { stripIndent } from '../../utils/lazy'; import { stripIndent } from '../../utils/lazy';
interface FlagsDef {
organization?: string;
type?: string; // application device type
help: void;
}
interface ArgsDef {
name: string;
}
export default class BlockCreateCmd extends Command { export default class BlockCreateCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Create an block. Create an block.
@ -59,22 +49,21 @@ export default class BlockCreateCmd extends Command {
'$ balena block create MyBlock -o myorg --type raspberry-pi', '$ balena block create MyBlock -o myorg --type raspberry-pi',
]; ];
public static args = [ public static args = {
{ name: Args.string({
name: 'name',
description: 'block name', description: 'block name',
required: true, required: true,
}, }),
]; };
public static usage = 'block create <name>'; public static usage = 'block create <name>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
organization: flags.string({ organization: Flags.string({
char: 'o', char: 'o',
description: 'handle of the organization the block should belong to', description: 'handle of the organization the block should belong to',
}), }),
type: flags.string({ type: Flags.string({
char: 't', char: 't',
description: description:
'block device type (Check available types with `balena devices supported`)', 'block device type (Check available types with `balena devices supported`)',
@ -85,9 +74,7 @@ export default class BlockCreateCmd extends Command {
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(BlockCreateCmd);
BlockCreateCmd,
);
await ( await (
await import('../../utils/application-create') await import('../../utils/application-create')

View File

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Args, Flags } from '@oclif/core';
import Command from '../command'; import Command from '../command';
import { getBalenaSdk } from '../utils/lazy'; import { getBalenaSdk } from '../utils/lazy';
import * as cf from '../utils/common-flags'; import * as cf from '../utils/common-flags';
@ -31,6 +31,9 @@ import { buildProject, composeCliFlags } from '../utils/compose_ts';
import type { BuildOpts, DockerCliFlags } from '../utils/docker'; import type { BuildOpts, DockerCliFlags } from '../utils/docker';
import { dockerCliFlags } from '../utils/docker'; import { dockerCliFlags } from '../utils/docker';
// TODO: For this special one we can't use Interfaces.InferredFlags/InferredArgs
// because of the 'registry-secrets' type which is defined in the actual code
// as a path (string | undefined) but then the cli turns it into an object
interface FlagsDef extends ComposeCliFlags, DockerCliFlags { interface FlagsDef extends ComposeCliFlags, DockerCliFlags {
arch?: string; arch?: string;
deviceType?: string; deviceType?: string;
@ -39,10 +42,6 @@ interface FlagsDef extends ComposeCliFlags, DockerCliFlags {
help: void; help: void;
} }
interface ArgsDef {
source?: string;
}
export default class BuildCmd extends Command { export default class BuildCmd extends Command {
public static description = `\ public static description = `\
Build a project locally. Build a project locally.
@ -74,21 +73,18 @@ ${dockerignoreHelp}
'$ balena build --dockerHost my.docker.host --dockerPort 2376 --ca ca.pem --key key.pem --cert cert.pem -f myFleet', '$ balena build --dockerHost my.docker.host --dockerPort 2376 --ca ca.pem --key key.pem --cert cert.pem -f myFleet',
]; ];
public static args = [ public static args = {
{ source: Args.string({ description: 'path of project source directory' }),
name: 'source', };
description: 'path of project source directory',
},
];
public static usage = 'build [source]'; public static usage = 'build [source]';
public static flags: flags.Input<FlagsDef> = { public static flags = {
arch: flags.string({ arch: Flags.string({
description: 'the architecture to build for', description: 'the architecture to build for',
char: 'A', char: 'A',
}), }),
deviceType: flags.string({ deviceType: Flags.string({
description: 'the type of device this build is for', description: 'the type of device this build is for',
char: 'd', char: 'd',
}), }),
@ -97,15 +93,13 @@ ${dockerignoreHelp}
...dockerCliFlags, ...dockerCliFlags,
// NOTE: Not supporting -h for help, because of clash with -h in DockerCliFlags // NOTE: Not supporting -h for help, because of clash with -h in DockerCliFlags
// Revisit this in future release. // Revisit this in future release.
help: flags.help({}), help: Flags.help({}),
}; };
public static primary = true; public static primary = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(BuildCmd);
BuildCmd,
);
await Command.checkLoggedInIf(!!options.fleet); await Command.checkLoggedInIf(!!options.fleet);

View File

@ -15,7 +15,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags } from '@oclif/core';
import type { Interfaces } from '@oclif/core';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getBalenaSdk, getCliForm, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, getCliForm, stripIndent } from '../../utils/lazy';
@ -26,26 +27,6 @@ import {
} from '../../utils/messages'; } from '../../utils/messages';
import type { BalenaSDK, PineDeferred } from 'balena-sdk'; import type { BalenaSDK, PineDeferred } from 'balena-sdk';
interface FlagsDef {
version: string; // OS version
fleet?: string;
dev?: boolean; // balenaOS development variant
secureBoot?: boolean;
device?: string;
deviceApiKey?: string;
deviceType?: string;
'generate-device-api-key': boolean;
output?: string;
// Options for non-interactive configuration
network?: string;
wifiSsid?: string;
wifiKey?: string;
appUpdatePollInterval?: string;
'provisioning-key-name'?: string;
'provisioning-key-expiry-date'?: string;
help: void;
}
export default class ConfigGenerateCmd extends Command { export default class ConfigGenerateCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Generate a config.json file. Generate a config.json file.
@ -81,8 +62,8 @@ export default class ConfigGenerateCmd extends Command {
public static usage = 'config generate'; public static usage = 'config generate';
public static flags: flags.Input<FlagsDef> = { public static flags = {
version: flags.string({ version: Flags.string({
description: 'a balenaOS version', description: 'a balenaOS version',
required: true, required: true,
}), }),
@ -97,44 +78,44 @@ export default class ConfigGenerateCmd extends Command {
'provisioning-key-expiry-date', 'provisioning-key-expiry-date',
], ],
}, },
deviceApiKey: flags.string({ deviceApiKey: Flags.string({
description: description:
'custom device key - note that this is only supported on balenaOS 2.0.3+', 'custom device key - note that this is only supported on balenaOS 2.0.3+',
char: 'k', char: 'k',
}), }),
deviceType: flags.string({ deviceType: Flags.string({
description: description:
"device type slug (run 'balena devices supported' for possible values)", "device type slug (run 'balena devices supported' for possible values)",
}), }),
'generate-device-api-key': flags.boolean({ 'generate-device-api-key': Flags.boolean({
description: 'generate a fresh device key for the device', description: 'generate a fresh device key for the device',
}), }),
output: flags.string({ output: Flags.string({
description: 'path of output file', description: 'path of output file',
char: 'o', char: 'o',
}), }),
// Options for non-interactive configuration // Options for non-interactive configuration
network: flags.string({ network: Flags.string({
description: 'the network type to use: ethernet or wifi', description: 'the network type to use: ethernet or wifi',
options: ['ethernet', 'wifi'], options: ['ethernet', 'wifi'],
}), }),
wifiSsid: flags.string({ wifiSsid: Flags.string({
description: description:
'the wifi ssid to use (used only if --network is set to wifi)', 'the wifi ssid to use (used only if --network is set to wifi)',
}), }),
wifiKey: flags.string({ wifiKey: Flags.string({
description: description:
'the wifi key to use (used only if --network is set to wifi)', 'the wifi key to use (used only if --network is set to wifi)',
}), }),
appUpdatePollInterval: flags.string({ appUpdatePollInterval: Flags.string({
description: description:
'supervisor cloud polling interval in minutes (e.g. for device variables)', 'supervisor cloud polling interval in minutes (e.g. for device variables)',
}), }),
'provisioning-key-name': flags.string({ 'provisioning-key-name': Flags.string({
description: 'custom key name assigned to generated provisioning api key', description: 'custom key name assigned to generated provisioning api key',
exclusive: ['device'], exclusive: ['device'],
}), }),
'provisioning-key-expiry-date': flags.string({ 'provisioning-key-expiry-date': Flags.string({
description: description:
'expiry date assigned to generated provisioning api key (format: YYYY-MM-DD)', 'expiry date assigned to generated provisioning api key (format: YYYY-MM-DD)',
exclusive: ['device'], exclusive: ['device'],
@ -155,7 +136,7 @@ export default class ConfigGenerateCmd extends Command {
} }
public async run() { public async run() {
const { flags: options } = this.parse<FlagsDef, {}>(ConfigGenerateCmd); const { flags: options } = await this.parse(ConfigGenerateCmd);
const balena = getBalenaSdk(); const balena = getBalenaSdk();
await this.validateOptions(options); await this.validateOptions(options);
@ -266,7 +247,9 @@ export default class ConfigGenerateCmd extends Command {
protected readonly deviceTypeNotAllowedMessage = protected readonly deviceTypeNotAllowedMessage =
'The --deviceType option can only be used alongside the --fleet option'; 'The --deviceType option can only be used alongside the --fleet option';
protected async validateOptions(options: FlagsDef) { protected async validateOptions(
options: Interfaces.InferredFlags<typeof ConfigGenerateCmd.flags>,
) {
const { ExpectedError } = await import('../../errors'); const { ExpectedError } = await import('../../errors');
if (options.device == null && options.fleet == null) { if (options.device == null && options.fleet == null) {

View File

@ -15,21 +15,11 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Args } from '@oclif/core';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getVisuals, stripIndent } from '../../utils/lazy'; import { getVisuals, stripIndent } from '../../utils/lazy';
interface FlagsDef {
type?: string;
drive?: string;
help: void;
}
interface ArgsDef {
file: string;
}
export default class ConfigInjectCmd extends Command { export default class ConfigInjectCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Inject a config.json file to a balenaOS image or attached media. Inject a config.json file to a balenaOS image or attached media.
@ -46,17 +36,16 @@ export default class ConfigInjectCmd extends Command {
'$ balena config inject my/config.json --drive /dev/disk2', '$ balena config inject my/config.json --drive /dev/disk2',
]; ];
public static args = [ public static args = {
{ file: Args.string({
name: 'file',
description: 'the path to the config.json file to inject', description: 'the path to the config.json file to inject',
required: true, required: true,
}, }),
]; };
public static usage = 'config inject <file>'; public static usage = 'config inject <file>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
drive: cf.driveOrImg, drive: cf.driveOrImg,
help: cf.help, help: cf.help,
}; };
@ -65,9 +54,7 @@ export default class ConfigInjectCmd extends Command {
public static offlineCompatible = true; public static offlineCompatible = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(ConfigInjectCmd);
ConfigInjectCmd,
);
const { safeUmount } = await import('../../utils/umount'); const { safeUmount } = await import('../../utils/umount');

View File

@ -15,18 +15,10 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getVisuals, stripIndent } from '../../utils/lazy'; import { getVisuals, stripIndent } from '../../utils/lazy';
interface FlagsDef {
type?: string;
drive?: string;
help: void;
json: boolean;
}
export default class ConfigReadCmd extends Command { export default class ConfigReadCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Read the config.json file of a balenaOS image or attached media. Read the config.json file of a balenaOS image or attached media.
@ -46,7 +38,7 @@ export default class ConfigReadCmd extends Command {
public static usage = 'config read'; public static usage = 'config read';
public static flags: flags.Input<FlagsDef> = { public static flags = {
drive: cf.driveOrImg, drive: cf.driveOrImg,
help: cf.help, help: cf.help,
json: cf.json, json: cf.json,
@ -56,7 +48,7 @@ export default class ConfigReadCmd extends Command {
public static offlineCompatible = true; public static offlineCompatible = true;
public async run() { public async run() {
const { flags: options } = this.parse<FlagsDef, {}>(ConfigReadCmd); const { flags: options } = await this.parse(ConfigReadCmd);
const { safeUmount } = await import('../../utils/umount'); const { safeUmount } = await import('../../utils/umount');

View File

@ -15,19 +15,11 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags } from '@oclif/core';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getVisuals, stripIndent } from '../../utils/lazy'; import { getVisuals, stripIndent } from '../../utils/lazy';
interface FlagsDef {
type?: string;
drive?: string;
advanced: boolean;
help: void;
version?: string;
}
export default class ConfigReconfigureCmd extends Command { export default class ConfigReconfigureCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Interactively reconfigure a balenaOS image file or attached media. Interactively reconfigure a balenaOS image file or attached media.
@ -49,14 +41,14 @@ export default class ConfigReconfigureCmd extends Command {
public static usage = 'config reconfigure'; public static usage = 'config reconfigure';
public static flags: flags.Input<FlagsDef> = { public static flags = {
drive: cf.driveOrImg, drive: cf.driveOrImg,
advanced: flags.boolean({ advanced: Flags.boolean({
description: 'show advanced commands', description: 'show advanced commands',
char: 'v', char: 'v',
}), }),
help: cf.help, help: cf.help,
version: flags.string({ version: Flags.string({
description: 'balenaOS version, for example "2.32.0" or "2.44.0+rev1"', description: 'balenaOS version, for example "2.32.0" or "2.44.0+rev1"',
}), }),
}; };
@ -65,7 +57,7 @@ export default class ConfigReconfigureCmd extends Command {
public static root = true; public static root = true;
public async run() { public async run() {
const { flags: options } = this.parse<FlagsDef, {}>(ConfigReconfigureCmd); const { flags: options } = await this.parse(ConfigReconfigureCmd);
const { safeUmount } = await import('../../utils/umount'); const { safeUmount } = await import('../../utils/umount');

View File

@ -15,22 +15,11 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Args } from '@oclif/core';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getVisuals, stripIndent } from '../../utils/lazy'; import { getVisuals, stripIndent } from '../../utils/lazy';
interface FlagsDef {
type?: string;
drive?: string;
help: void;
}
interface ArgsDef {
key: string;
value: string;
}
export default class ConfigWriteCmd extends Command { export default class ConfigWriteCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Write a key-value pair to the config.json file of an OS image or attached media. Write a key-value pair to the config.json file of an OS image or attached media.
@ -48,22 +37,20 @@ export default class ConfigWriteCmd extends Command {
'$ balena config write --drive balena.img os.network.connectivity.interval 300', '$ balena config write --drive balena.img os.network.connectivity.interval 300',
]; ];
public static args = [ public static args = {
{ key: Args.string({
name: 'key',
description: 'the key of the config parameter to write', description: 'the key of the config parameter to write',
required: true, required: true,
}, }),
{ value: Args.string({
name: 'value',
description: 'the value of the config parameter to write', description: 'the value of the config parameter to write',
required: true, required: true,
}, }),
]; };
public static usage = 'config write <key> <value>'; public static usage = 'config write <key> <value>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
drive: cf.driveOrImg, drive: cf.driveOrImg,
help: cf.help, help: cf.help,
}; };
@ -72,9 +59,7 @@ export default class ConfigWriteCmd extends Command {
public static offlineCompatible = true; public static offlineCompatible = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(ConfigWriteCmd);
ConfigWriteCmd,
);
const { denyMount, safeUmount } = await import('../../utils/umount'); const { denyMount, safeUmount } = await import('../../utils/umount');

View File

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Args, Flags } from '@oclif/core';
import type { ImageDescriptor } from '@balena/compose/dist/parse'; import type { ImageDescriptor } from '@balena/compose/dist/parse';
import Command from '../command'; import Command from '../command';
@ -52,6 +52,9 @@ interface ApplicationWithArch {
application_type: [Pick<ApplicationType, 'slug' | 'supports_multicontainer'>]; application_type: [Pick<ApplicationType, 'slug' | 'supports_multicontainer'>];
} }
// TODO: For this special one we can't use Interfaces.InferredFlags/InferredArgs
// because of the 'registry-secrets' type which is defined in the actual code
// as a path (string | undefined) but then the cli turns it into an object
interface FlagsDef extends ComposeCliFlags, DockerCliFlags { interface FlagsDef extends ComposeCliFlags, DockerCliFlags {
source?: string; source?: string;
build: boolean; build: boolean;
@ -62,11 +65,6 @@ interface FlagsDef extends ComposeCliFlags, DockerCliFlags {
help: void; help: void;
} }
interface ArgsDef {
fleet: string;
image?: string;
}
export default class DeployCmd extends Command { export default class DeployCmd extends Command {
public static description = `\ public static description = `\
Deploy a single image or a multicontainer project to a balena fleet. Deploy a single image or a multicontainer project to a balena fleet.
@ -105,31 +103,28 @@ ${dockerignoreHelp}
'$ balena deploy myFleet myRepo/myImage --release-tag key1 "" key2 "value2 with spaces"', '$ balena deploy myFleet myRepo/myImage --release-tag key1 "" key2 "value2 with spaces"',
]; ];
public static args = [ public static args = {
ca.fleetRequired, fleet: ca.fleetRequired,
{ image: Args.string({ description: 'the image to deploy' }),
name: 'image', };
description: 'the image to deploy',
},
];
public static usage = 'deploy <fleet> [image]'; public static usage = 'deploy <fleet> [image]';
public static flags: flags.Input<FlagsDef> = { public static flags = {
source: flags.string({ source: Flags.string({
description: description:
'specify an alternate source directory; default is the working directory', 'specify an alternate source directory; default is the working directory',
char: 's', char: 's',
}), }),
build: flags.boolean({ build: Flags.boolean({
description: 'force a rebuild before deploy', description: 'force a rebuild before deploy',
char: 'b', char: 'b',
}), }),
nologupload: flags.boolean({ nologupload: Flags.boolean({
description: description:
"don't upload build logs to the dashboard with image (if building)", "don't upload build logs to the dashboard with image (if building)",
}), }),
'release-tag': flags.string({ 'release-tag': Flags.string({
description: stripIndent` description: stripIndent`
Set release tags if the image deployment is successful. Multiple Set release tags if the image deployment is successful. Multiple
arguments may be provided, alternating tag keys and values (see examples). arguments may be provided, alternating tag keys and values (see examples).
@ -137,7 +132,7 @@ ${dockerignoreHelp}
`, `,
multiple: true, multiple: true,
}), }),
draft: flags.boolean({ draft: Flags.boolean({
description: stripIndent` description: stripIndent`
Deploy the release as a draft. Draft releases are ignored Deploy the release as a draft. Draft releases are ignored
by the 'track latest' release policy but can be used through release pinning. by the 'track latest' release policy but can be used through release pinning.
@ -145,12 +140,12 @@ ${dockerignoreHelp}
as final by default unless this option is given.`, as final by default unless this option is given.`,
default: false, default: false,
}), }),
note: flags.string({ description: 'The notes for this release' }), note: Flags.string({ description: 'The notes for this release' }),
...composeCliFlags, ...composeCliFlags,
...dockerCliFlags, ...dockerCliFlags,
// NOTE: Not supporting -h for help, because of clash with -h in DockerCliFlags // NOTE: Not supporting -h for help, because of clash with -h in DockerCliFlags
// Revisit this in future release. // Revisit this in future release.
help: flags.help({}), help: Flags.help({}),
}; };
public static authenticated = true; public static authenticated = true;
@ -158,9 +153,7 @@ ${dockerignoreHelp}
public static primary = true; public static primary = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(DeployCmd);
DeployCmd,
);
(await import('events')).defaultMaxListeners = 1000; (await import('events')).defaultMaxListeners = 1000;
@ -190,7 +183,7 @@ ${dockerignoreHelp}
); );
if (image) { if (image) {
options['registry-secrets'] = await getRegistrySecrets( (options as FlagsDef)['registry-secrets'] = await getRegistrySecrets(
sdk, sdk,
options['registry-secrets'], options['registry-secrets'],
); );
@ -203,7 +196,7 @@ ${dockerignoreHelp}
registrySecretsPath: options['registry-secrets'], registrySecretsPath: options['registry-secrets'],
}); });
options.dockerfile = dockerfilePath; options.dockerfile = dockerfilePath;
options['registry-secrets'] = registrySecrets; (options as FlagsDef)['registry-secrets'] = registrySecrets;
} }
const helpers = await import('../utils/helpers'); const helpers = await import('../utils/helpers');
@ -212,7 +205,7 @@ ${dockerignoreHelp}
const dockerUtils = await import('../utils/docker'); const dockerUtils = await import('../utils/docker');
const [docker, buildOpts, composeOpts] = await Promise.all([ const [docker, buildOpts, composeOpts] = await Promise.all([
dockerUtils.getDocker(options), dockerUtils.getDocker(options),
dockerUtils.generateBuildOpts(options), dockerUtils.generateBuildOpts(options as FlagsDef),
compose.generateOpts(options), compose.generateOpts(options),
]); ]);

View File

@ -15,21 +15,11 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Args } from '@oclif/core';
import type { IArg } from '@oclif/parser/lib/args';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, stripIndent } from '../../utils/lazy';
interface FlagsDef {
yes: boolean;
help: void;
}
interface ArgsDef {
uuid: string;
}
export default class DeviceDeactivateCmd extends Command { export default class DeviceDeactivateCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Deactivate a device. Deactivate a device.
@ -44,17 +34,16 @@ export default class DeviceDeactivateCmd extends Command {
'$ balena device deactivate 7cf02a6 --yes', '$ balena device deactivate 7cf02a6 --yes',
]; ];
public static args: Array<IArg<any>> = [ public static args = {
{ uuid: Args.string({
name: 'uuid',
description: 'the UUID of the device to be deactivated', description: 'the UUID of the device to be deactivated',
required: true, required: true,
}, }),
]; };
public static usage = 'device deactivate <uuid>'; public static usage = 'device deactivate <uuid>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
yes: cf.yes, yes: cf.yes,
help: cf.help, help: cf.help,
}; };
@ -62,7 +51,7 @@ export default class DeviceDeactivateCmd extends Command {
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(
DeviceDeactivateCmd, DeviceDeactivateCmd,
); );

View File

@ -15,21 +15,12 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Args } from '@oclif/core';
import type { IArg } from '@oclif/parser/lib/args';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, stripIndent } from '../../utils/lazy';
import { ExpectedError } from '../../errors'; import { ExpectedError } from '../../errors';
interface FlagsDef {
help: void;
}
interface ArgsDef {
uuid: string;
}
export default class DeviceIdentifyCmd extends Command { export default class DeviceIdentifyCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Identify a device. Identify a device.
@ -38,24 +29,23 @@ export default class DeviceIdentifyCmd extends Command {
`; `;
public static examples = ['$ balena device identify 23c73a1']; public static examples = ['$ balena device identify 23c73a1'];
public static args: Array<IArg<any>> = [ public static args = {
{ uuid: Args.string({
name: 'uuid',
description: 'the uuid of the device to identify', description: 'the uuid of the device to identify',
required: true, required: true,
}, }),
]; };
public static usage = 'device identify <uuid>'; public static usage = 'device identify <uuid>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
help: cf.help, help: cf.help,
}; };
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params } = this.parse<FlagsDef, ArgsDef>(DeviceIdentifyCmd); const { args: params } = await this.parse(DeviceIdentifyCmd);
const balena = getBalenaSdk(); const balena = getBalenaSdk();

View File

@ -15,8 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags, Args } from '@oclif/core';
import { IArg } from '@oclif/parser/lib/args';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { expandForAppName } from '../../utils/helpers'; import { expandForAppName } from '../../utils/helpers';
@ -41,15 +40,6 @@ interface ExtendedDevice extends DeviceWithDeviceType {
undervoltage_detected?: boolean; undervoltage_detected?: boolean;
} }
interface FlagsDef {
help: void;
view: boolean;
}
interface ArgsDef {
uuid: string;
}
export default class DeviceCmd extends Command { export default class DeviceCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Show info about a single device. Show info about a single device.
@ -61,19 +51,18 @@ export default class DeviceCmd extends Command {
'$ balena device 7cf02a6 --view', '$ balena device 7cf02a6 --view',
]; ];
public static args: Array<IArg<any>> = [ public static args = {
{ uuid: Args.string({
name: 'uuid',
description: 'the device uuid', description: 'the device uuid',
required: true, required: true,
}, }),
]; };
public static usage = 'device <uuid>'; public static usage = 'device <uuid>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
help: cf.help, help: cf.help,
view: flags.boolean({ view: Flags.boolean({
default: false, default: false,
description: 'open device dashboard page', description: 'open device dashboard page',
}), }),
@ -83,9 +72,7 @@ export default class DeviceCmd extends Command {
public static primary = true; public static primary = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(DeviceCmd);
DeviceCmd,
);
const balena = getBalenaSdk(); const balena = getBalenaSdk();

View File

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags } from '@oclif/core';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, stripIndent } from '../../utils/lazy';
@ -76,14 +76,14 @@ export default class DeviceInitCmd extends Command {
public static usage = 'device init'; public static usage = 'device init';
public static flags: flags.Input<FlagsDef> = { public static flags = {
fleet: cf.fleet, fleet: cf.fleet,
yes: cf.yes, yes: cf.yes,
advanced: flags.boolean({ advanced: Flags.boolean({
char: 'v', char: 'v',
description: 'show advanced configuration options', description: 'show advanced configuration options',
}), }),
'os-version': flags.string({ 'os-version': Flags.string({
description: stripIndent` description: stripIndent`
exact version number, or a valid semver range, exact version number, or a valid semver range,
or 'latest' (includes pre-releases), or 'latest' (includes pre-releases),
@ -93,13 +93,13 @@ export default class DeviceInitCmd extends Command {
`, `,
}), }),
drive: cf.drive, drive: cf.drive,
config: flags.string({ config: Flags.string({
description: 'path to the config JSON file, see `balena os build-config`', description: 'path to the config JSON file, see `balena os build-config`',
}), }),
'provisioning-key-name': flags.string({ 'provisioning-key-name': Flags.string({
description: 'custom key name assigned to generated provisioning api key', description: 'custom key name assigned to generated provisioning api key',
}), }),
'provisioning-key-expiry-date': flags.string({ 'provisioning-key-expiry-date': Flags.string({
description: description:
'expiry date assigned to generated provisioning api key (format: YYYY-MM-DD)', 'expiry date assigned to generated provisioning api key (format: YYYY-MM-DD)',
}), }),
@ -109,7 +109,7 @@ export default class DeviceInitCmd extends Command {
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { flags: options } = this.parse<FlagsDef, {}>(DeviceInitCmd); const { flags: options } = await this.parse(DeviceInitCmd);
// Imports // Imports
const { promisify } = await import('util'); const { promisify } = await import('util');

View File

@ -15,23 +15,11 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags, Args } from '@oclif/core';
import type { IArg } from '@oclif/parser/lib/args';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, stripIndent } from '../../utils/lazy';
interface FlagsDef {
enable: boolean;
disable: boolean;
status: boolean;
help?: void;
}
interface ArgsDef {
uuid: string | number;
}
export default class DeviceLocalModeCmd extends Command { export default class DeviceLocalModeCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Get or manage the local mode status for a device. Get or manage the local mode status for a device.
@ -47,26 +35,25 @@ export default class DeviceLocalModeCmd extends Command {
'$ balena device local-mode 23c73a1 --status', '$ balena device local-mode 23c73a1 --status',
]; ];
public static args: Array<IArg<any>> = [ public static args = {
{ uuid: Args.string({
name: 'uuid',
description: 'the uuid of the device to manage', description: 'the uuid of the device to manage',
required: true, required: true,
}, }),
]; };
public static usage = 'device local-mode <uuid>'; public static usage = 'device local-mode <uuid>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
enable: flags.boolean({ enable: Flags.boolean({
description: 'enable local mode', description: 'enable local mode',
exclusive: ['disable', 'status'], exclusive: ['disable', 'status'],
}), }),
disable: flags.boolean({ disable: Flags.boolean({
description: 'disable local mode', description: 'disable local mode',
exclusive: ['enable', 'status'], exclusive: ['enable', 'status'],
}), }),
status: flags.boolean({ status: Flags.boolean({
description: 'output boolean indicating local mode status', description: 'output boolean indicating local mode status',
exclusive: ['enable', 'disable'], exclusive: ['enable', 'disable'],
}), }),
@ -76,7 +63,7 @@ export default class DeviceLocalModeCmd extends Command {
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(
DeviceLocalModeCmd, DeviceLocalModeCmd,
); );

View File

@ -15,8 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import type { flags } from '@oclif/command'; import { Args } from '@oclif/core';
import type { IArg } from '@oclif/parser/lib/args';
import type { import type {
BalenaSDK, BalenaSDK,
Device, Device,
@ -29,15 +28,6 @@ import { ExpectedError } from '../../errors';
import { getBalenaSdk, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, stripIndent } from '../../utils/lazy';
import { applicationIdInfo } from '../../utils/messages'; import { applicationIdInfo } from '../../utils/messages';
interface FlagsDef {
fleet?: string;
help: void;
}
interface ArgsDef {
uuid: string;
}
export default class DeviceMoveCmd extends Command { export default class DeviceMoveCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Move one or more devices to another fleet. Move one or more devices to another fleet.
@ -56,18 +46,17 @@ export default class DeviceMoveCmd extends Command {
'$ balena device move 7cf02a6 -f myorg/mynewfleet', '$ balena device move 7cf02a6 -f myorg/mynewfleet',
]; ];
public static args: Array<IArg<any>> = [ public static args = {
{ uuid: Args.string({
name: 'uuid',
description: description:
'comma-separated list (no blank spaces) of device UUIDs to be moved', 'comma-separated list (no blank spaces) of device UUIDs to be moved',
required: true, required: true,
}, }),
]; };
public static usage = 'device move <uuid(s)>'; public static usage = 'device move <uuid(s)>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
fleet: cf.fleet, fleet: cf.fleet,
help: cf.help, help: cf.help,
}; };
@ -102,9 +91,7 @@ export default class DeviceMoveCmd extends Command {
} }
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(DeviceMoveCmd);
DeviceMoveCmd,
);
const balena = getBalenaSdk(); const balena = getBalenaSdk();

View File

@ -15,24 +15,13 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags, Args } from '@oclif/core';
import type { IArg } from '@oclif/parser/lib/args';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent, getCliForm } from '../../utils/lazy'; import { getBalenaSdk, stripIndent, getCliForm } from '../../utils/lazy';
import type { Device } from 'balena-sdk'; import type { Device } from 'balena-sdk';
import { ExpectedError } from '../../errors'; import { ExpectedError } from '../../errors';
interface FlagsDef {
version?: string;
yes: boolean;
help: void;
}
interface ArgsDef {
uuid: string;
}
export default class DeviceOsUpdateCmd extends Command { export default class DeviceOsUpdateCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Start a Host OS update for a device. Start a Host OS update for a device.
@ -50,18 +39,17 @@ export default class DeviceOsUpdateCmd extends Command {
'$ balena device os-update 23c73a1 --version 2.31.0+rev1.prod', '$ balena device os-update 23c73a1 --version 2.31.0+rev1.prod',
]; ];
public static args: Array<IArg<any>> = [ public static args = {
{ uuid: Args.string({
name: 'uuid',
description: 'the uuid of the device to update', description: 'the uuid of the device to update',
required: true, required: true,
}, }),
]; };
public static usage = 'device os-update <uuid>'; public static usage = 'device os-update <uuid>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
version: flags.string({ version: Flags.string({
description: 'a balenaOS version', description: 'a balenaOS version',
}), }),
yes: cf.yes, yes: cf.yes,
@ -71,7 +59,7 @@ export default class DeviceOsUpdateCmd extends Command {
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(
DeviceOsUpdateCmd, DeviceOsUpdateCmd,
); );

View File

@ -15,22 +15,12 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Args } from '@oclif/core';
import type { IArg } from '@oclif/parser/lib/args';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, stripIndent } from '../../utils/lazy';
import { getExpandedProp } from '../../utils/pine'; import { getExpandedProp } from '../../utils/pine';
interface FlagsDef {
help: void;
}
interface ArgsDef {
uuid: string;
releaseToPinTo?: string;
}
export default class DevicePinCmd extends Command { export default class DevicePinCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Pin a device to a release. Pin a device to a release.
@ -44,28 +34,26 @@ export default class DevicePinCmd extends Command {
'$ balena device pin 7cf02a6 91165e5', '$ balena device pin 7cf02a6 91165e5',
]; ];
public static args: Array<IArg<any>> = [ public static args = {
{ uuid: Args.string({
name: 'uuid',
description: 'the uuid of the device to pin to a release', description: 'the uuid of the device to pin to a release',
required: true, required: true,
}, }),
{ releaseToPinTo: Args.string({
name: 'releaseToPinTo',
description: 'the commit of the release for the device to get pinned to', description: 'the commit of the release for the device to get pinned to',
}, }),
]; };
public static usage = 'device pin <uuid> [releaseToPinTo]'; public static usage = 'device pin <uuid> [releaseToPinTo]';
public static flags: flags.Input<FlagsDef> = { public static flags = {
help: cf.help, help: cf.help,
}; };
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params } = this.parse<FlagsDef, ArgsDef>(DevicePinCmd); const { args: params } = await this.parse(DevicePinCmd);
const balena = getBalenaSdk(); const balena = getBalenaSdk();

View File

@ -15,24 +15,12 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags, Args } from '@oclif/core';
import type { IArg } from '@oclif/parser/lib/args';
import Command from '../../command'; import Command from '../../command';
import { ExpectedError } from '../../errors'; import { ExpectedError } from '../../errors';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, stripIndent } from '../../utils/lazy';
interface FlagsDef {
enable: boolean;
disable: boolean;
status: boolean;
help?: void;
}
interface ArgsDef {
uuid: string;
}
export default class DevicePublicUrlCmd extends Command { export default class DevicePublicUrlCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Get or manage the public URL for a device. Get or manage the public URL for a device.
@ -49,26 +37,25 @@ export default class DevicePublicUrlCmd extends Command {
'$ balena device public-url 23c73a1 --status', '$ balena device public-url 23c73a1 --status',
]; ];
public static args: Array<IArg<any>> = [ public static args = {
{ uuid: Args.string({
name: 'uuid',
description: 'the uuid of the device to manage', description: 'the uuid of the device to manage',
required: true, required: true,
}, }),
]; };
public static usage = 'device public-url <uuid>'; public static usage = 'device public-url <uuid>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
enable: flags.boolean({ enable: Flags.boolean({
description: 'enable the public URL', description: 'enable the public URL',
exclusive: ['disable', 'status'], exclusive: ['disable', 'status'],
}), }),
disable: flags.boolean({ disable: Flags.boolean({
description: 'disable the public URL', description: 'disable the public URL',
exclusive: ['enable', 'status'], exclusive: ['enable', 'status'],
}), }),
status: flags.boolean({ status: Flags.boolean({
description: 'determine if public URL is enabled', description: 'determine if public URL is enabled',
exclusive: ['enable', 'disable'], exclusive: ['enable', 'disable'],
}), }),
@ -78,7 +65,7 @@ export default class DevicePublicUrlCmd extends Command {
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(
DevicePublicUrlCmd, DevicePublicUrlCmd,
); );

View File

@ -15,20 +15,11 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Args } from '@oclif/core';
import type { IArg } from '@oclif/parser/lib/args';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getBalenaSdk, getCliUx, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, getCliUx, stripIndent } from '../../utils/lazy';
interface FlagsDef {
help: void;
}
interface ArgsDef {
uuid: string;
}
export default class DevicePurgeCmd extends Command { export default class DevicePurgeCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Purge data from a device. Purge data from a device.
@ -46,22 +37,21 @@ export default class DevicePurgeCmd extends Command {
public static usage = 'device purge <uuid>'; public static usage = 'device purge <uuid>';
public static args: Array<IArg<any>> = [ public static args = {
{ uuid: Args.string({
name: 'uuid',
description: 'comma-separated list (no blank spaces) of device UUIDs', description: 'comma-separated list (no blank spaces) of device UUIDs',
required: true, required: true,
}, }),
]; };
public static flags: flags.Input<FlagsDef> = { public static flags = {
help: cf.help, help: cf.help,
}; };
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params } = this.parse<FlagsDef, ArgsDef>(DevicePurgeCmd); const { args: params } = await this.parse(DevicePurgeCmd);
const balena = getBalenaSdk(); const balena = getBalenaSdk();
const ux = getCliUx(); const ux = getCliUx();

View File

@ -15,21 +15,11 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Args } from '@oclif/core';
import type { IArg } from '@oclif/parser/lib/args';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, stripIndent } from '../../utils/lazy';
interface FlagsDef {
force: boolean;
help: void;
}
interface ArgsDef {
uuid: string;
}
export default class DeviceRebootCmd extends Command { export default class DeviceRebootCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Restart a device. Restart a device.
@ -38,17 +28,16 @@ export default class DeviceRebootCmd extends Command {
`; `;
public static examples = ['$ balena device reboot 23c73a1']; public static examples = ['$ balena device reboot 23c73a1'];
public static args: Array<IArg<any>> = [ public static args = {
{ uuid: Args.string({
name: 'uuid',
description: 'the uuid of the device to reboot', description: 'the uuid of the device to reboot',
required: true, required: true,
}, }),
]; };
public static usage = 'device reboot <uuid>'; public static usage = 'device reboot <uuid>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
force: cf.force, force: cf.force,
help: cf.help, help: cf.help,
}; };
@ -56,9 +45,7 @@ export default class DeviceRebootCmd extends Command {
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(DeviceRebootCmd);
DeviceRebootCmd,
);
const balena = getBalenaSdk(); const balena = getBalenaSdk();

View File

@ -15,24 +15,13 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags } from '@oclif/core';
import type { IArg } from '@oclif/parser/lib/args';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import * as ca from '../../utils/common-args'; import * as ca from '../../utils/common-args';
import { getBalenaSdk, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, stripIndent } from '../../utils/lazy';
import { applicationIdInfo } from '../../utils/messages'; import { applicationIdInfo } from '../../utils/messages';
interface FlagsDef {
uuid?: string;
deviceType?: string;
help: void;
}
interface ArgsDef {
fleet: string;
}
export default class DeviceRegisterCmd extends Command { export default class DeviceRegisterCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Register a new device. Register a new device.
@ -51,16 +40,18 @@ export default class DeviceRegisterCmd extends Command {
'$ balena device register myorg/myfleet --uuid <uuid> --deviceType <deviceTypeSlug>', '$ balena device register myorg/myfleet --uuid <uuid> --deviceType <deviceTypeSlug>',
]; ];
public static args: Array<IArg<any>> = [ca.fleetRequired]; public static args = {
fleet: ca.fleetRequired,
};
public static usage = 'device register <fleet>'; public static usage = 'device register <fleet>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
uuid: flags.string({ uuid: Flags.string({
description: 'custom uuid', description: 'custom uuid',
char: 'u', char: 'u',
}), }),
deviceType: flags.string({ deviceType: Flags.string({
description: description:
"device type slug (run 'balena devices supported' for possible values)", "device type slug (run 'balena devices supported' for possible values)",
}), }),
@ -70,7 +61,7 @@ export default class DeviceRegisterCmd extends Command {
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(
DeviceRegisterCmd, DeviceRegisterCmd,
); );

View File

@ -15,21 +15,11 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Args } from '@oclif/core';
import type { IArg } from '@oclif/parser/lib/args';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent, getCliForm } from '../../utils/lazy'; import { getBalenaSdk, stripIndent, getCliForm } from '../../utils/lazy';
interface FlagsDef {
help: void;
}
interface ArgsDef {
uuid: string;
newName?: string;
}
export default class DeviceRenameCmd extends Command { export default class DeviceRenameCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Rename a device. Rename a device.
@ -43,28 +33,26 @@ export default class DeviceRenameCmd extends Command {
'$ balena device rename 7cf02a6 MyPi', '$ balena device rename 7cf02a6 MyPi',
]; ];
public static args: Array<IArg<any>> = [ public static args = {
{ uuid: Args.string({
name: 'uuid',
description: 'the uuid of the device to rename', description: 'the uuid of the device to rename',
required: true, required: true,
}, }),
{ newName: Args.string({
name: 'newName',
description: 'the new name for the device', description: 'the new name for the device',
}, }),
]; };
public static usage = 'device rename <uuid> [newName]'; public static usage = 'device rename <uuid> [newName]';
public static flags: flags.Input<FlagsDef> = { public static flags = {
help: cf.help, help: cf.help,
}; };
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params } = this.parse<FlagsDef, ArgsDef>(DeviceRenameCmd); const { args: params } = await this.parse(DeviceRenameCmd);
const balena = getBalenaSdk(); const balena = getBalenaSdk();

View File

@ -15,8 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags, Args } from '@oclif/core';
import type { IArg } from '@oclif/parser/lib/args';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getBalenaSdk, getCliUx, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, getCliUx, stripIndent } from '../../utils/lazy';
@ -26,15 +25,6 @@ import type {
CurrentServiceWithCommit, CurrentServiceWithCommit,
} from 'balena-sdk'; } from 'balena-sdk';
interface FlagsDef {
help: void;
service?: string;
}
interface ArgsDef {
uuid: string;
}
export default class DeviceRestartCmd extends Command { export default class DeviceRestartCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Restart containers on a device. Restart containers on a device.
@ -55,19 +45,18 @@ export default class DeviceRestartCmd extends Command {
'$ balena device restart 23c73a1 -s myService1,myService2', '$ balena device restart 23c73a1 -s myService1,myService2',
]; ];
public static args: Array<IArg<any>> = [ public static args = {
{ uuid: Args.string({
name: 'uuid',
description: description:
'comma-separated list (no blank spaces) of device UUIDs to restart', 'comma-separated list (no blank spaces) of device UUIDs to restart',
required: true, required: true,
}, }),
]; };
public static usage = 'device restart <uuid>'; public static usage = 'device restart <uuid>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
service: flags.string({ service: Flags.string({
description: description:
'comma-separated list (no blank spaces) of service names to restart', 'comma-separated list (no blank spaces) of service names to restart',
char: 's', char: 's',
@ -78,9 +67,7 @@ export default class DeviceRestartCmd extends Command {
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(DeviceRestartCmd);
DeviceRestartCmd,
);
const balena = getBalenaSdk(); const balena = getBalenaSdk();
const ux = getCliUx(); const ux = getCliUx();

View File

@ -15,21 +15,11 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Args } from '@oclif/core';
import type { IArg } from '@oclif/parser/lib/args';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, stripIndent } from '../../utils/lazy';
interface FlagsDef {
yes: boolean;
help: void;
}
interface ArgsDef {
uuid: string;
}
export default class DeviceRmCmd extends Command { export default class DeviceRmCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Remove one or more devices. Remove one or more devices.
@ -45,18 +35,17 @@ export default class DeviceRmCmd extends Command {
'$ balena device rm 7cf02a6 --yes', '$ balena device rm 7cf02a6 --yes',
]; ];
public static args: Array<IArg<any>> = [ public static args = {
{ uuid: Args.string({
name: 'uuid',
description: description:
'comma-separated list (no blank spaces) of device UUIDs to be removed', 'comma-separated list (no blank spaces) of device UUIDs to be removed',
required: true, required: true,
}, }),
]; };
public static usage = 'device rm <uuid(s)>'; public static usage = 'device rm <uuid(s)>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
yes: cf.yes, yes: cf.yes,
help: cf.help, help: cf.help,
}; };
@ -64,9 +53,7 @@ export default class DeviceRmCmd extends Command {
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(DeviceRmCmd);
DeviceRmCmd,
);
const balena = getBalenaSdk(); const balena = getBalenaSdk();
const patterns = await import('../../utils/patterns'); const patterns = await import('../../utils/patterns');

View File

@ -15,22 +15,12 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Args } from '@oclif/core';
import type { IArg } from '@oclif/parser/lib/args';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, stripIndent } from '../../utils/lazy';
import { ExpectedError } from '../../errors'; import { ExpectedError } from '../../errors';
interface FlagsDef {
force: boolean;
help: void;
}
interface ArgsDef {
uuid: string;
}
export default class DeviceShutdownCmd extends Command { export default class DeviceShutdownCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Shutdown a device. Shutdown a device.
@ -39,17 +29,16 @@ export default class DeviceShutdownCmd extends Command {
`; `;
public static examples = ['$ balena device shutdown 23c73a1']; public static examples = ['$ balena device shutdown 23c73a1'];
public static args: Array<IArg<any>> = [ public static args = {
{ uuid: Args.string({
name: 'uuid',
description: 'the uuid of the device to shutdown', description: 'the uuid of the device to shutdown',
required: true, required: true,
}, }),
]; };
public static usage = 'device shutdown <uuid>'; public static usage = 'device shutdown <uuid>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
force: cf.force, force: cf.force,
help: cf.help, help: cf.help,
}; };
@ -57,7 +46,7 @@ export default class DeviceShutdownCmd extends Command {
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(
DeviceShutdownCmd, DeviceShutdownCmd,
); );

View File

@ -15,20 +15,11 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Args } from '@oclif/core';
import type { IArg } from '@oclif/parser/lib/args';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, stripIndent } from '../../utils/lazy';
interface FlagsDef {
help: void;
}
interface ArgsDef {
uuid: string;
}
export default class DeviceTrackFleetCmd extends Command { export default class DeviceTrackFleetCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Make a device track the fleet's pinned release. Make a device track the fleet's pinned release.
@ -37,24 +28,23 @@ export default class DeviceTrackFleetCmd extends Command {
`; `;
public static examples = ['$ balena device track-fleet 7cf02a6']; public static examples = ['$ balena device track-fleet 7cf02a6'];
public static args: Array<IArg<any>> = [ public static args = {
{ uuid: Args.string({
name: 'uuid',
description: "the uuid of the device to make track the fleet's release", description: "the uuid of the device to make track the fleet's release",
required: true, required: true,
}, }),
]; };
public static usage = 'device track-fleet <uuid>'; public static usage = 'device track-fleet <uuid>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
help: cf.help, help: cf.help,
}; };
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params } = this.parse<FlagsDef, ArgsDef>(DeviceTrackFleetCmd); const { args: params } = await this.parse(DeviceTrackFleetCmd);
const balena = getBalenaSdk(); const balena = getBalenaSdk();

View File

@ -15,7 +15,6 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { expandForAppName } from '../../utils/helpers'; import { expandForAppName } from '../../utils/helpers';
@ -24,12 +23,6 @@ import { applicationIdInfo, jsonInfo } from '../../utils/messages';
import type { Device, PineOptions } from 'balena-sdk'; import type { Device, PineOptions } from 'balena-sdk';
interface FlagsDef {
fleet?: string;
help: void;
json: boolean;
}
const devicesSelectFields = { const devicesSelectFields = {
$select: [ $select: [
'id', 'id',
@ -62,7 +55,7 @@ export default class DevicesCmd extends Command {
public static usage = 'devices'; public static usage = 'devices';
public static flags: flags.Input<FlagsDef> = { public static flags = {
fleet: cf.fleet, fleet: cf.fleet,
json: cf.json, json: cf.json,
help: cf.help, help: cf.help,
@ -73,7 +66,7 @@ export default class DevicesCmd extends Command {
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { flags: options } = this.parse<FlagsDef, {}>(DevicesCmd); const { flags: options } = await this.parse(DevicesCmd);
const balena = getBalenaSdk(); const balena = getBalenaSdk();
const devicesOptions = { const devicesOptions = {

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags } from '@oclif/core';
import type * as BalenaSdk from 'balena-sdk'; import type * as BalenaSdk from 'balena-sdk';
import * as _ from 'lodash'; import * as _ from 'lodash';
import Command from '../../command'; import Command from '../../command';
@ -23,11 +23,6 @@ import * as cf from '../../utils/common-flags';
import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
import { CommandHelp } from '../../utils/oclif-utils'; import { CommandHelp } from '../../utils/oclif-utils';
interface FlagsDef {
help: void;
json?: boolean;
}
export default class DevicesSupportedCmd extends Command { export default class DevicesSupportedCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
List the supported device types (like 'raspberrypi3' or 'intel-nuc'). List the supported device types (like 'raspberrypi3' or 'intel-nuc').
@ -50,16 +45,16 @@ export default class DevicesSupportedCmd extends Command {
new CommandHelp({ args: DevicesSupportedCmd.args }).defaultUsage() new CommandHelp({ args: DevicesSupportedCmd.args }).defaultUsage()
).trim(); ).trim();
public static flags: flags.Input<FlagsDef> = { public static flags = {
help: cf.help, help: cf.help,
json: flags.boolean({ json: Flags.boolean({
char: 'j', char: 'j',
description: 'produce JSON output instead of tabular output', description: 'produce JSON output instead of tabular output',
}), }),
}; };
public async run() { public async run() {
const { flags: options } = this.parse<FlagsDef, {}>(DevicesSupportedCmd); const { flags: options } = await this.parse(DevicesSupportedCmd);
const pineOptions = { const pineOptions = {
$select: ['slug', 'name'], $select: ['slug', 'name'],
$expand: { $expand: {

View File

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Args } from '@oclif/core';
import type * as BalenaSdk from 'balena-sdk'; import type * as BalenaSdk from 'balena-sdk';
import Command from '../../command'; import Command from '../../command';
import { ExpectedError } from '../../errors'; import { ExpectedError } from '../../errors';
@ -78,23 +78,21 @@ export default class EnvAddCmd extends Command {
'$ balena env add EDITOR vim --device 7cf02a6,d6f1433 --service MyService,MyService2', '$ balena env add EDITOR vim --device 7cf02a6,d6f1433 --service MyService,MyService2',
]; ];
public static args = [ public static args = {
{ name: Args.string({
name: 'name',
required: true, required: true,
description: 'environment or config variable name', description: 'environment or config variable name',
}, }),
{ value: Args.string({
name: 'value',
required: false, required: false,
description: description:
"variable value; if omitted, use value from this process' environment", "variable value; if omitted, use value from this process' environment",
}, }),
]; };
public static usage = 'env add <name> [value]'; public static usage = 'env add <name> [value]';
public static flags: flags.Input<FlagsDef> = { public static flags = {
fleet: { ...cf.fleet, exclusive: ['device'] }, fleet: { ...cf.fleet, exclusive: ['device'] },
device: { ...cf.device, exclusive: ['fleet'] }, device: { ...cf.device, exclusive: ['fleet'] },
help: cf.help, help: cf.help,
@ -103,9 +101,7 @@ export default class EnvAddCmd extends Command {
}; };
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(EnvAddCmd);
EnvAddCmd,
);
const cmd = this; const cmd = this;
if (!options.fleet && !options.device) { if (!options.fleet && !options.device) {

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Args } from '@oclif/core';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
@ -22,20 +22,6 @@ import * as ec from '../../utils/env-common';
import { getBalenaSdk, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, stripIndent } from '../../utils/lazy';
import { parseAsInteger } from '../../utils/validation'; import { parseAsInteger } from '../../utils/validation';
type IArg<T> = import('@oclif/parser').args.IArg<T>;
interface FlagsDef {
config: boolean;
device: boolean;
service: boolean;
help: void;
}
interface ArgsDef {
id: number;
value: string;
}
export default class EnvRenameCmd extends Command { export default class EnvRenameCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Change the value of a config or env var for a fleet, device or service. Change the value of a config or env var for a fleet, device or service.
@ -54,24 +40,22 @@ export default class EnvRenameCmd extends Command {
'$ balena env rename 678678 1 --device --config', '$ balena env rename 678678 1 --device --config',
]; ];
public static args: Array<IArg<any>> = [ public static args = {
{ id: Args.integer({
name: 'id',
required: true, required: true,
description: "variable's numeric database ID", description: "variable's numeric database ID",
parse: (input) => parseAsInteger(input, 'id'), parse: async (input) => parseAsInteger(input, 'id'),
}, }),
{ value: Args.string({
name: 'value',
required: true, required: true,
description: description:
"variable value; if omitted, use value from this process' environment", "variable value; if omitted, use value from this process' environment",
}, }),
]; };
public static usage = 'env rename <id> <value>'; public static usage = 'env rename <id> <value>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
config: ec.booleanConfig, config: ec.booleanConfig,
device: ec.booleanDevice, device: ec.booleanDevice,
service: ec.booleanService, service: ec.booleanService,
@ -79,9 +63,7 @@ export default class EnvRenameCmd extends Command {
}; };
public async run() { public async run() {
const { args: params, flags: opt } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: opt } = await this.parse(EnvRenameCmd);
EnvRenameCmd,
);
await Command.checkLoggedIn(); await Command.checkLoggedIn();

View File

@ -15,26 +15,13 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags, Args } from '@oclif/core';
import Command from '../../command'; import Command from '../../command';
import * as ec from '../../utils/env-common'; import * as ec from '../../utils/env-common';
import { getBalenaSdk, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, stripIndent } from '../../utils/lazy';
import { parseAsInteger } from '../../utils/validation'; import { parseAsInteger } from '../../utils/validation';
type IArg<T> = import('@oclif/parser').args.IArg<T>;
interface FlagsDef {
config: boolean;
device: boolean;
service: boolean;
yes: boolean;
}
interface ArgsDef {
id: number;
}
export default class EnvRmCmd extends Command { export default class EnvRmCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Remove a config or env var from a fleet, device or service. Remove a config or env var from a fleet, device or service.
@ -57,22 +44,21 @@ export default class EnvRmCmd extends Command {
'$ balena env rm 789789 --device --service --yes', '$ balena env rm 789789 --device --service --yes',
]; ];
public static args: Array<IArg<any>> = [ public static args = {
{ id: Args.integer({
name: 'id',
required: true, required: true,
description: "variable's numeric database ID", description: "variable's numeric database ID",
parse: (input) => parseAsInteger(input, 'id'), parse: async (input) => parseAsInteger(input, 'id'),
}, }),
]; };
public static usage = 'env rm <id>'; public static usage = 'env rm <id>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
config: ec.booleanConfig, config: ec.booleanConfig,
device: ec.booleanDevice, device: ec.booleanDevice,
service: ec.booleanService, service: ec.booleanService,
yes: flags.boolean({ yes: Flags.boolean({
char: 'y', char: 'y',
description: description:
'do not prompt for confirmation before deleting the variable', 'do not prompt for confirmation before deleting the variable',
@ -81,9 +67,7 @@ export default class EnvRmCmd extends Command {
}; };
public async run() { public async run() {
const { args: params, flags: opt } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: opt } = await this.parse(EnvRmCmd);
EnvRmCmd,
);
await Command.checkLoggedIn(); await Command.checkLoggedIn();

View File

@ -14,7 +14,8 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags } from '@oclif/core';
import type { Interfaces } from '@oclif/core';
import type * as SDK from 'balena-sdk'; import type * as SDK from 'balena-sdk';
import * as _ from 'lodash'; import * as _ from 'lodash';
import Command from '../command'; import Command from '../command';
@ -23,14 +24,7 @@ import * as cf from '../utils/common-flags';
import { getBalenaSdk, getVisuals, stripIndent } from '../utils/lazy'; import { getBalenaSdk, getVisuals, stripIndent } from '../utils/lazy';
import { applicationIdInfo } from '../utils/messages'; import { applicationIdInfo } from '../utils/messages';
interface FlagsDef { type FlagsDef = Interfaces.InferredFlags<typeof EnvsCmd.flags>;
fleet?: string;
config: boolean;
device?: string; // device UUID
json: boolean;
help: void;
service?: string; // service name
}
interface EnvironmentVariableInfo extends SDK.EnvironmentVariableBase { interface EnvironmentVariableInfo extends SDK.EnvironmentVariableBase {
fleet?: string | null; // fleet slug fleet?: string | null; // fleet slug
@ -102,9 +96,9 @@ export default class EnvsCmd extends Command {
public static usage = 'envs'; public static usage = 'envs';
public static flags: flags.Input<FlagsDef> = { public static flags = {
fleet: { ...cf.fleet, exclusive: ['device'] }, fleet: { ...cf.fleet, exclusive: ['device'] },
config: flags.boolean({ config: Flags.boolean({
default: false, default: false,
char: 'c', char: 'c',
description: 'show configuration variables only', description: 'show configuration variables only',
@ -117,7 +111,7 @@ export default class EnvsCmd extends Command {
}; };
public async run() { public async run() {
const { flags: options } = this.parse<FlagsDef, {}>(EnvsCmd); const { flags: options } = await this.parse(EnvsCmd);
const variables: EnvironmentVariableInfo[] = []; const variables: EnvironmentVariableInfo[] = [];

View File

@ -15,12 +15,11 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags, Args } from '@oclif/core';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { stripIndent } from '../../utils/lazy'; import { stripIndent } from '../../utils/lazy';
import { ArgsDef, FlagsDef } from '../../utils/application-create';
export default class FleetCreateCmd extends Command { export default class FleetCreateCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
@ -50,22 +49,21 @@ export default class FleetCreateCmd extends Command {
'$ balena fleet create MyFleet -o myorg --type raspberry-pi', '$ balena fleet create MyFleet -o myorg --type raspberry-pi',
]; ];
public static args = [ public static args = {
{ name: Args.string({
name: 'name',
description: 'fleet name', description: 'fleet name',
required: true, required: true,
}, }),
]; };
public static usage = 'fleet create <name>'; public static usage = 'fleet create <name>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
organization: flags.string({ organization: Flags.string({
char: 'o', char: 'o',
description: 'handle of the organization the fleet should belong to', description: 'handle of the organization the fleet should belong to',
}), }),
type: flags.string({ type: Flags.string({
char: 't', char: 't',
description: description:
'fleet device type (Check available types with `balena devices supported`)', 'fleet device type (Check available types with `balena devices supported`)',
@ -76,9 +74,7 @@ export default class FleetCreateCmd extends Command {
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(FleetCreateCmd);
FleetCreateCmd,
);
await ( await (
await import('../../utils/application-create') await import('../../utils/application-create')

View File

@ -15,24 +15,13 @@
* limitations under the License. * limitations under the License.
*/ */
import type { flags as flagsType } from '@oclif/command'; import { Flags } from '@oclif/core';
import { flags } from '@oclif/command';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import * as ca from '../../utils/common-args'; import * as ca from '../../utils/common-args';
import { getBalenaSdk, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, stripIndent } from '../../utils/lazy';
import { applicationIdInfo } from '../../utils/messages'; import { applicationIdInfo } from '../../utils/messages';
import type { DataOutputOptions } from '../../framework';
interface FlagsDef extends DataOutputOptions {
help: void;
view: boolean;
}
interface ArgsDef {
fleet: string;
}
export default class FleetCmd extends Command { export default class FleetCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
@ -48,13 +37,15 @@ export default class FleetCmd extends Command {
'$ balena fleet myorg/myfleet --view', '$ balena fleet myorg/myfleet --view',
]; ];
public static args = [ca.fleetRequired]; public static args = {
fleet: ca.fleetRequired,
};
public static usage = 'fleet <fleet>'; public static usage = 'fleet <fleet>';
public static flags: flagsType.Input<FlagsDef> = { public static flags = {
help: cf.help, help: cf.help,
view: flags.boolean({ view: Flags.boolean({
default: false, default: false,
description: 'open fleet dashboard page', description: 'open fleet dashboard page',
}), }),
@ -65,9 +56,7 @@ export default class FleetCmd extends Command {
public static primary = true; public static primary = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(FleetCmd);
FleetCmd,
);
const { getApplication } = await import('../../utils/sdk'); const { getApplication } = await import('../../utils/sdk');

View File

@ -15,22 +15,12 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Args } from '@oclif/core';
import type { IArg } from '@oclif/parser/lib/args';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, stripIndent } from '../../utils/lazy';
import { getExpandedProp } from '../../utils/pine'; import { getExpandedProp } from '../../utils/pine';
interface FlagsDef {
help: void;
}
interface ArgsDef {
slug: string;
releaseToPinTo?: string;
}
export default class FleetPinCmd extends Command { export default class FleetPinCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Pin a fleet to a release. Pin a fleet to a release.
@ -44,28 +34,26 @@ export default class FleetPinCmd extends Command {
'$ balena fleet pin myorg/myfleet 91165e5', '$ balena fleet pin myorg/myfleet 91165e5',
]; ];
public static args: Array<IArg<any>> = [ public static args = {
{ slug: Args.string({
name: 'slug',
description: 'the slug of the fleet to pin to a release', description: 'the slug of the fleet to pin to a release',
required: true, required: true,
}, }),
{ releaseToPinTo: Args.string({
name: 'releaseToPinTo',
description: 'the commit of the release for the fleet to get pinned to', description: 'the commit of the release for the fleet to get pinned to',
}, }),
]; };
public static usage = 'fleet pin <slug> [releaseToPinTo]'; public static usage = 'fleet pin <slug> [releaseToPinTo]';
public static flags: flags.Input<FlagsDef> = { public static flags = {
help: cf.help, help: cf.help,
}; };
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params } = this.parse<FlagsDef, ArgsDef>(FleetPinCmd); const { args: params } = await this.parse(FleetPinCmd);
const balena = getBalenaSdk(); const balena = getBalenaSdk();

View File

@ -15,22 +15,12 @@
* limitations under the License. * limitations under the License.
*/ */
import type { flags } from '@oclif/command';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import * as ca from '../../utils/common-args'; import * as ca from '../../utils/common-args';
import { getBalenaSdk, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, stripIndent } from '../../utils/lazy';
import { applicationIdInfo } from '../../utils/messages'; import { applicationIdInfo } from '../../utils/messages';
interface FlagsDef {
help: void;
}
interface ArgsDef {
fleet: string;
}
export default class FleetPurgeCmd extends Command { export default class FleetPurgeCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Purge data from a fleet. Purge data from a fleet.
@ -46,18 +36,20 @@ export default class FleetPurgeCmd extends Command {
'$ balena fleet purge myorg/myfleet', '$ balena fleet purge myorg/myfleet',
]; ];
public static args = [ca.fleetRequired]; public static args = {
fleet: ca.fleetRequired,
};
public static usage = 'fleet purge <fleet>'; public static usage = 'fleet purge <fleet>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
help: cf.help, help: cf.help,
}; };
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params } = this.parse<FlagsDef, ArgsDef>(FleetPurgeCmd); const { args: params } = await this.parse(FleetPurgeCmd);
const { getApplication } = await import('../../utils/sdk'); const { getApplication } = await import('../../utils/sdk');

View File

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import type { flags } from '@oclif/command'; import { Args } from '@oclif/core';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
@ -23,15 +23,6 @@ import * as ca from '../../utils/common-args';
import { getBalenaSdk, stripIndent, getCliForm } from '../../utils/lazy'; import { getBalenaSdk, stripIndent, getCliForm } from '../../utils/lazy';
import { applicationIdInfo } from '../../utils/messages'; import { applicationIdInfo } from '../../utils/messages';
interface FlagsDef {
help: void;
}
interface ArgsDef {
fleet: string;
newName?: string;
}
export default class FleetRenameCmd extends Command { export default class FleetRenameCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Rename a fleet. Rename a fleet.
@ -50,24 +41,23 @@ export default class FleetRenameCmd extends Command {
'$ balena fleet rename myorg/oldname NewName', '$ balena fleet rename myorg/oldname NewName',
]; ];
public static args = [ public static args = {
ca.fleetRequired, fleet: ca.fleetRequired,
{ newName: Args.string({
name: 'newName',
description: 'the new name for the fleet', description: 'the new name for the fleet',
}, }),
]; };
public static usage = 'fleet rename <fleet> [newName]'; public static usage = 'fleet rename <fleet> [newName]';
public static flags: flags.Input<FlagsDef> = { public static flags = {
help: cf.help, help: cf.help,
}; };
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params } = this.parse<FlagsDef, ArgsDef>(FleetRenameCmd); const { args: params } = await this.parse(FleetRenameCmd);
const { validateApplicationName } = await import('../../utils/validation'); const { validateApplicationName } = await import('../../utils/validation');
const { ExpectedError } = await import('../../errors'); const { ExpectedError } = await import('../../errors');

View File

@ -15,22 +15,12 @@
* limitations under the License. * limitations under the License.
*/ */
import type { flags } from '@oclif/command';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import * as ca from '../../utils/common-args'; import * as ca from '../../utils/common-args';
import { getBalenaSdk, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, stripIndent } from '../../utils/lazy';
import { applicationIdInfo } from '../../utils/messages'; import { applicationIdInfo } from '../../utils/messages';
interface FlagsDef {
help: void;
}
interface ArgsDef {
fleet: string;
}
export default class FleetRestartCmd extends Command { export default class FleetRestartCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Restart a fleet. Restart a fleet.
@ -45,18 +35,20 @@ export default class FleetRestartCmd extends Command {
'$ balena fleet restart myorg/myfleet', '$ balena fleet restart myorg/myfleet',
]; ];
public static args = [ca.fleetRequired]; public static args = {
fleet: ca.fleetRequired,
};
public static usage = 'fleet restart <fleet>'; public static usage = 'fleet restart <fleet>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
help: cf.help, help: cf.help,
}; };
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params } = this.parse<FlagsDef, ArgsDef>(FleetRestartCmd); const { args: params } = await this.parse(FleetRestartCmd);
const { getApplication } = await import('../../utils/sdk'); const { getApplication } = await import('../../utils/sdk');

View File

@ -15,23 +15,12 @@
* limitations under the License. * limitations under the License.
*/ */
import type { flags } from '@oclif/command';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import * as ca from '../../utils/common-args'; import * as ca from '../../utils/common-args';
import { getBalenaSdk, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, stripIndent } from '../../utils/lazy';
import { applicationIdInfo } from '../../utils/messages'; import { applicationIdInfo } from '../../utils/messages';
interface FlagsDef {
yes: boolean;
help: void;
}
interface ArgsDef {
fleet: string;
}
export default class FleetRmCmd extends Command { export default class FleetRmCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Remove a fleet. Remove a fleet.
@ -49,11 +38,13 @@ export default class FleetRmCmd extends Command {
'$ balena fleet rm myorg/myfleet', '$ balena fleet rm myorg/myfleet',
]; ];
public static args = [ca.fleetRequired]; public static args = {
fleet: ca.fleetRequired,
};
public static usage = 'fleet rm <fleet>'; public static usage = 'fleet rm <fleet>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
yes: cf.yes, yes: cf.yes,
help: cf.help, help: cf.help,
}; };
@ -61,9 +52,7 @@ export default class FleetRmCmd extends Command {
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(FleetRmCmd);
FleetRmCmd,
);
const { confirm } = await import('../../utils/patterns'); const { confirm } = await import('../../utils/patterns');
const { getApplication } = await import('../../utils/sdk'); const { getApplication } = await import('../../utils/sdk');

View File

@ -15,20 +15,11 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Args } from '@oclif/core';
import type { IArg } from '@oclif/parser/lib/args';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, stripIndent } from '../../utils/lazy';
interface FlagsDef {
help: void;
}
interface ArgsDef {
slug: string;
}
export default class FleetTrackLatestCmd extends Command { export default class FleetTrackLatestCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Make this fleet track the latest release. Make this fleet track the latest release.
@ -40,24 +31,23 @@ export default class FleetTrackLatestCmd extends Command {
'$ balena fleet track-latest myfleet', '$ balena fleet track-latest myfleet',
]; ];
public static args: Array<IArg<any>> = [ public static args = {
{ slug: Args.string({
name: 'slug',
description: 'the slug of the fleet to make track the latest release', description: 'the slug of the fleet to make track the latest release',
required: true, required: true,
}, }),
]; };
public static usage = 'fleet track-latest <slug>'; public static usage = 'fleet track-latest <slug>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
help: cf.help, help: cf.help,
}; };
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params } = this.parse<FlagsDef, ArgsDef>(FleetTrackLatestCmd); const { args: params } = await this.parse(FleetTrackLatestCmd);
const balena = getBalenaSdk(); const balena = getBalenaSdk();

View File

@ -16,12 +16,10 @@
*/ */
import type * as BalenaSdk from 'balena-sdk'; import type * as BalenaSdk from 'balena-sdk';
import { flags } from '@oclif/command';
import Command from '../command'; import Command from '../command';
import * as cf from '../utils/common-flags'; import * as cf from '../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../utils/lazy'; import { getBalenaSdk, stripIndent } from '../utils/lazy';
import type { DataSetOutputOptions } from '../framework';
interface ExtendedApplication extends ApplicationWithDeviceTypeSlug { interface ExtendedApplication extends ApplicationWithDeviceTypeSlug {
device_count: number; device_count: number;
@ -29,11 +27,6 @@ interface ExtendedApplication extends ApplicationWithDeviceTypeSlug {
device_type?: string; device_type?: string;
} }
interface FlagsDef extends DataSetOutputOptions {
help: void;
verbose?: boolean;
}
export default class FleetsCmd extends Command { export default class FleetsCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
List all fleets. List all fleets.
@ -48,7 +41,7 @@ export default class FleetsCmd extends Command {
public static usage = 'fleets'; public static usage = 'fleets';
public static flags: flags.Input<FlagsDef> = { public static flags = {
...cf.dataSetOutputFlags, ...cf.dataSetOutputFlags,
help: cf.help, help: cf.help,
}; };
@ -57,7 +50,7 @@ export default class FleetsCmd extends Command {
public static primary = true; public static primary = true;
public async run() { public async run() {
const { flags: options } = this.parse<FlagsDef, {}>(FleetsCmd); const { flags: options } = await this.parse(FleetsCmd);
const balena = getBalenaSdk(); const balena = getBalenaSdk();

View File

@ -15,6 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { Args } from '@oclif/core';
import Command from '../../command'; import Command from '../../command';
import { stripIndent } from '../../utils/lazy'; import { stripIndent } from '../../utils/lazy';
import { CommandHelp } from '../../utils/oclif-utils'; import { CommandHelp } from '../../utils/oclif-utils';
@ -27,12 +28,6 @@ import { CommandHelp } from '../../utils/oclif-utils';
// - https://github.com/balena-io/balena-cli/pull/1455#discussion_r334308357 // - https://github.com/balena-io/balena-cli/pull/1455#discussion_r334308357
// - https://github.com/balena-io/balena-cli/pull/1455#discussion_r334308526 // - https://github.com/balena-io/balena-cli/pull/1455#discussion_r334308526
interface ArgsDef {
image: string;
type: string;
config: string;
}
export default class OsinitCmd extends Command { export default class OsinitCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Do actual init of the device with the preconfigured os image. Do actual init of the device with the preconfigured os image.
@ -41,20 +36,17 @@ export default class OsinitCmd extends Command {
Use \`balena os initialize <image>\` instead. Use \`balena os initialize <image>\` instead.
`; `;
public static args = [ public static args = {
{ image: Args.string({
name: 'image',
required: true, required: true,
}, }),
{ type: Args.string({
name: 'type',
required: true, required: true,
}, }),
{ config: Args.string({
name: 'config',
required: true, required: true,
}, }),
]; };
public static usage = ( public static usage = (
'internal osinit ' + 'internal osinit ' +
@ -66,7 +58,7 @@ export default class OsinitCmd extends Command {
public static offlineCompatible = true; public static offlineCompatible = true;
public async run() { public async run() {
const { args: params } = this.parse<{}, ArgsDef>(OsinitCmd); const { args: params } = await this.parse(OsinitCmd);
const config = JSON.parse(params.config); const config = JSON.parse(params.config);

View File

@ -15,23 +15,13 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Args, Flags } from '@oclif/core';
import Command from '../command'; import Command from '../command';
import * as cf from '../utils/common-flags'; import * as cf from '../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../utils/lazy'; import { getBalenaSdk, stripIndent } from '../utils/lazy';
import { applicationIdInfo } from '../utils/messages'; import { applicationIdInfo } from '../utils/messages';
import { parseAsLocalHostnameOrIp } from '../utils/validation'; import { parseAsLocalHostnameOrIp } from '../utils/validation';
interface FlagsDef {
fleet?: string;
pollInterval?: number;
help?: void;
}
interface ArgsDef {
deviceIpOrHostname?: string;
}
export default class JoinCmd extends Command { export default class JoinCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Move a local device to a fleet on another balena server. Move a local device to a fleet on another balena server.
@ -63,20 +53,19 @@ export default class JoinCmd extends Command {
'$ balena join 192.168.1.25 --fleet MyFleet', '$ balena join 192.168.1.25 --fleet MyFleet',
]; ];
public static args = [ public static args = {
{ deviceIpOrHostname: Args.string({
name: 'deviceIpOrHostname',
description: 'the IP or hostname of device', description: 'the IP or hostname of device',
parse: parseAsLocalHostnameOrIp, parse: parseAsLocalHostnameOrIp,
}, }),
]; };
// Hardcoded to preserve camelcase // Hardcoded to preserve camelcase
public static usage = 'join [deviceIpOrHostname]'; public static usage = 'join [deviceIpOrHostname]';
public static flags: flags.Input<FlagsDef> = { public static flags = {
fleet: cf.fleet, fleet: cf.fleet,
pollInterval: flags.integer({ pollInterval: Flags.integer({
description: 'the interval in minutes to check for updates', description: 'the interval in minutes to check for updates',
char: 'i', char: 'i',
}), }),
@ -87,9 +76,7 @@ export default class JoinCmd extends Command {
public static primary = true; public static primary = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(JoinCmd);
JoinCmd,
);
const promote = await import('../utils/promote'); const promote = await import('../utils/promote');
const sdk = getBalenaSdk(); const sdk = getBalenaSdk();

View File

@ -15,21 +15,12 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Args } from '@oclif/core';
import Command from '../../command'; import Command from '../../command';
import { ExpectedError } from '../../errors'; import { ExpectedError } from '../../errors';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, stripIndent } from '../../utils/lazy';
interface FlagsDef {
help: void;
}
interface ArgsDef {
name: string;
path: string;
}
export default class KeyAddCmd extends Command { export default class KeyAddCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Add an SSH key to balenaCloud. Add an SSH key to balenaCloud.
@ -60,21 +51,19 @@ export default class KeyAddCmd extends Command {
'$ balena key add Main %userprofile%.sshid_rsa.pub', '$ balena key add Main %userprofile%.sshid_rsa.pub',
]; ];
public static args = [ public static args = {
{ name: Args.string({
name: 'name',
description: 'the SSH key name', description: 'the SSH key name',
required: true, required: true,
}, }),
{ path: Args.string({
name: `path`,
description: `the path to the public key file`, description: `the path to the public key file`,
}, }),
]; };
public static usage = 'key add <name> [path]'; public static usage = 'key add <name> [path]';
public static flags: flags.Input<FlagsDef> = { public static flags = {
help: cf.help, help: cf.help,
}; };
@ -83,7 +72,7 @@ export default class KeyAddCmd extends Command {
public static readStdin = true; public static readStdin = true;
public async run() { public async run() {
const { args: params } = this.parse<FlagsDef, ArgsDef>(KeyAddCmd); const { args: params } = await this.parse(KeyAddCmd);
let key: string; let key: string;
if (params.path != null) { if (params.path != null) {

View File

@ -15,22 +15,12 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Args } from '@oclif/core';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
import { parseAsInteger } from '../../utils/validation'; import { parseAsInteger } from '../../utils/validation';
type IArg<T> = import('@oclif/parser').args.IArg<T>;
interface FlagsDef {
help: void;
}
interface ArgsDef {
id: number;
}
export default class KeyCmd extends Command { export default class KeyCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Display an SSH key. Display an SSH key.
@ -40,25 +30,24 @@ export default class KeyCmd extends Command {
public static examples = ['$ balena key 17']; public static examples = ['$ balena key 17'];
public static args: Array<IArg<any>> = [ public static args = {
{ id: Args.integer({
name: 'id',
description: 'balenaCloud ID for the SSH key', description: 'balenaCloud ID for the SSH key',
parse: (x) => parseAsInteger(x, 'id'), parse: async (x) => parseAsInteger(x, 'id'),
required: true, required: true,
}, }),
]; };
public static usage = 'key <id>'; public static usage = 'key <id>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
help: cf.help, help: cf.help,
}; };
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params } = this.parse<{}, ArgsDef>(KeyCmd); const { args: params } = await this.parse(KeyCmd);
const key = await getBalenaSdk().models.key.get(params.id); const key = await getBalenaSdk().models.key.get(params.id);

View File

@ -15,23 +15,12 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Args } from '@oclif/core';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, stripIndent } from '../../utils/lazy';
import { parseAsInteger } from '../../utils/validation'; import { parseAsInteger } from '../../utils/validation';
type IArg<T> = import('@oclif/parser').args.IArg<T>;
interface FlagsDef {
yes: boolean;
help: void;
}
interface ArgsDef {
id: number;
}
export default class KeyRmCmd extends Command { export default class KeyRmCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Remove an SSH key from balenaCloud. Remove an SSH key from balenaCloud.
@ -43,18 +32,17 @@ export default class KeyRmCmd extends Command {
public static examples = ['$ balena key rm 17', '$ balena key rm 17 --yes']; public static examples = ['$ balena key rm 17', '$ balena key rm 17 --yes'];
public static args: Array<IArg<any>> = [ public static args = {
{ id: Args.integer({
name: 'id',
description: 'balenaCloud ID for the SSH key', description: 'balenaCloud ID for the SSH key',
parse: (x) => parseAsInteger(x, 'id'), parse: async (x) => parseAsInteger(x, 'id'),
required: true, required: true,
}, }),
]; };
public static usage = 'key rm <id>'; public static usage = 'key rm <id>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
yes: cf.yes, yes: cf.yes,
help: cf.help, help: cf.help,
}; };
@ -62,9 +50,7 @@ export default class KeyRmCmd extends Command {
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(KeyRmCmd);
KeyRmCmd,
);
const patterns = await import('../../utils/patterns'); const patterns = await import('../../utils/patterns');

View File

@ -15,15 +15,10 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command';
import Command from '../command'; import Command from '../command';
import * as cf from '../utils/common-flags'; import * as cf from '../utils/common-flags';
import { getBalenaSdk, getVisuals, stripIndent } from '../utils/lazy'; import { getBalenaSdk, getVisuals, stripIndent } from '../utils/lazy';
interface FlagsDef {
help: void;
}
export default class KeysCmd extends Command { export default class KeysCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
List the SSH keys in balenaCloud. List the SSH keys in balenaCloud.
@ -34,14 +29,14 @@ export default class KeysCmd extends Command {
public static usage = 'keys'; public static usage = 'keys';
public static flags: flags.Input<FlagsDef> = { public static flags = {
help: cf.help, help: cf.help,
}; };
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
this.parse<FlagsDef, {}>(KeysCmd); await this.parse(KeysCmd);
const keys = await getBalenaSdk().models.key.getAll(); const keys = await getBalenaSdk().models.key.getAll();

View File

@ -15,20 +15,12 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Args } from '@oclif/core';
import Command from '../command'; import Command from '../command';
import * as cf from '../utils/common-flags'; import * as cf from '../utils/common-flags';
import { stripIndent } from '../utils/lazy'; import { stripIndent } from '../utils/lazy';
import { parseAsLocalHostnameOrIp } from '../utils/validation'; import { parseAsLocalHostnameOrIp } from '../utils/validation';
interface FlagsDef {
help?: void;
}
interface ArgsDef {
deviceIpOrHostname?: string;
}
export default class LeaveCmd extends Command { export default class LeaveCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Remove a local device from its balena fleet. Remove a local device from its balena fleet.
@ -51,17 +43,16 @@ export default class LeaveCmd extends Command {
'$ balena leave 192.168.1.25', '$ balena leave 192.168.1.25',
]; ];
public static args = [ public static args = {
{ deviceIpOrHostname: Args.string({
name: 'deviceIpOrHostname',
description: 'the device IP or hostname', description: 'the device IP or hostname',
parse: parseAsLocalHostnameOrIp, parse: parseAsLocalHostnameOrIp,
}, }),
]; };
public static usage = 'leave [deviceIpOrHostname]'; public static usage = 'leave [deviceIpOrHostname]';
public static flags: flags.Input<FlagsDef> = { public static flags = {
help: cf.help, help: cf.help,
}; };
@ -69,7 +60,7 @@ export default class LeaveCmd extends Command {
public static primary = true; public static primary = true;
public async run() { public async run() {
const { args: params } = this.parse<FlagsDef, ArgsDef>(LeaveCmd); const { args: params } = await this.parse(LeaveCmd);
const promote = await import('../utils/promote'); const promote = await import('../utils/promote');
const logger = await Command.getLogger(); const logger = await Command.getLogger();

View File

@ -15,20 +15,12 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Args } from '@oclif/core';
import { promisify } from 'util'; import { promisify } from 'util';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { stripIndent } from '../../utils/lazy'; import { stripIndent } from '../../utils/lazy';
interface FlagsDef {
help: void;
}
interface ArgsDef {
target: string;
}
export default class LocalConfigureCmd extends Command { export default class LocalConfigureCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
(Re)configure a balenaOS drive or image. (Re)configure a balenaOS drive or image.
@ -41,17 +33,16 @@ export default class LocalConfigureCmd extends Command {
'$ balena local configure path/to/image.img', '$ balena local configure path/to/image.img',
]; ];
public static args = [ public static args = {
{ target: Args.string({
name: 'target',
description: 'path of drive or image to configure', description: 'path of drive or image to configure',
required: true, required: true,
}, }),
]; };
public static usage = 'local configure <target>'; public static usage = 'local configure <target>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
help: cf.help, help: cf.help,
}; };
@ -59,7 +50,7 @@ export default class LocalConfigureCmd extends Command {
public static offlineCompatible = true; public static offlineCompatible = true;
public async run() { public async run() {
const { args: params } = this.parse<FlagsDef, ArgsDef>(LocalConfigureCmd); const { args: params } = await this.parse(LocalConfigureCmd);
const reconfix = await import('reconfix'); const reconfix = await import('reconfix');
const { denyMount, safeUmount } = await import('../../utils/umount'); const { denyMount, safeUmount } = await import('../../utils/umount');

View File

@ -15,23 +15,13 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Args } from '@oclif/core';
import type { BlockDevice } from 'etcher-sdk/build/source-destination'; import type { BlockDevice } from 'etcher-sdk/build/source-destination';
import Command from '../../command'; import Command from '../../command';
import { ExpectedError } from '../../errors'; import { ExpectedError } from '../../errors';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getChalk, getVisuals, stripIndent } from '../../utils/lazy'; import { getChalk, getVisuals, stripIndent } from '../../utils/lazy';
interface FlagsDef {
yes: boolean;
drive?: string;
help: void;
}
interface ArgsDef {
image: string;
}
export default class LocalFlashCmd extends Command { export default class LocalFlashCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Flash an image to a drive. Flash an image to a drive.
@ -49,17 +39,16 @@ export default class LocalFlashCmd extends Command {
'$ balena local flash path/to/balenaos.img --drive /dev/disk2 --yes', '$ balena local flash path/to/balenaos.img --drive /dev/disk2 --yes',
]; ];
public static args = [ public static args = {
{ image: Args.string({
name: 'image',
description: 'path to OS image', description: 'path to OS image',
required: true, required: true,
}, }),
]; };
public static usage = 'local flash <image>'; public static usage = 'local flash <image>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
drive: cf.drive, drive: cf.drive,
yes: cf.yes, yes: cf.yes,
help: cf.help, help: cf.help,
@ -68,9 +57,7 @@ export default class LocalFlashCmd extends Command {
public static offlineCompatible = true; public static offlineCompatible = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(LocalFlashCmd);
LocalFlashCmd,
);
if (process.platform === 'linux') { if (process.platform === 'linux') {
const { promisify } = await import('util'); const { promisify } = await import('util');

View File

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags, Args } from '@oclif/core';
import Command from '../command'; import Command from '../command';
import * as cf from '../utils/common-flags'; import * as cf from '../utils/common-flags';
import { getBalenaSdk, stripIndent, getCliForm } from '../utils/lazy'; import { getBalenaSdk, stripIndent, getCliForm } from '../utils/lazy';
@ -34,10 +34,6 @@ interface FlagsDef {
hideExperimentalWarning: boolean; hideExperimentalWarning: boolean;
} }
interface ArgsDef {
token?: string;
}
export default class LoginCmd extends Command { export default class LoginCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Login to balena. Login to balena.
@ -61,37 +57,34 @@ export default class LoginCmd extends Command {
'$ balena login --credentials --email johndoe@gmail.com --password secret', '$ balena login --credentials --email johndoe@gmail.com --password secret',
]; ];
public static args = [ public static args = {
{ token: Args.string({
// Capitano allowed -t to be type boolean|string, which oclif does not.
// So -t is now bool, and we check first arg for token content.
name: 'token',
hidden: true, hidden: true,
}, }),
]; };
public static usage = 'login'; public static usage = 'login';
public static flags: flags.Input<FlagsDef> = { public static flags = {
web: flags.boolean({ web: Flags.boolean({
default: false, default: false,
char: 'w', char: 'w',
description: 'web-based login', description: 'web-based login',
exclusive: ['token', 'credentials'], exclusive: ['token', 'credentials'],
}), }),
token: flags.boolean({ token: Flags.boolean({
default: false, default: false,
char: 't', char: 't',
description: 'session token or API key', description: 'session token or API key',
exclusive: ['web', 'credentials'], exclusive: ['web', 'credentials'],
}), }),
credentials: flags.boolean({ credentials: Flags.boolean({
default: false, default: false,
char: 'c', char: 'c',
description: 'credential-based login', description: 'credential-based login',
exclusive: ['web', 'token'], exclusive: ['web', 'token'],
}), }),
email: flags.string({ email: Flags.string({
char: 'e', char: 'e',
description: 'email', description: 'email',
exclusive: ['user'], exclusive: ['user'],
@ -99,24 +92,24 @@ export default class LoginCmd extends Command {
}), }),
// Capitano version of this command had a second alias for email, 'u'. // Capitano version of this command had a second alias for email, 'u'.
// Using an oclif hidden flag to support the same behaviour. // Using an oclif hidden flag to support the same behaviour.
user: flags.string({ user: Flags.string({
char: 'u', char: 'u',
hidden: true, hidden: true,
exclusive: ['email'], exclusive: ['email'],
dependsOn: ['credentials'], dependsOn: ['credentials'],
}), }),
password: flags.string({ password: Flags.string({
char: 'p', char: 'p',
description: 'password', description: 'password',
dependsOn: ['credentials'], dependsOn: ['credentials'],
}), }),
port: flags.integer({ port: Flags.integer({
char: 'P', char: 'P',
description: description:
'TCP port number of local HTTP login server (--web auth only)', 'TCP port number of local HTTP login server (--web auth only)',
dependsOn: ['web'], dependsOn: ['web'],
}), }),
hideExperimentalWarning: flags.boolean({ hideExperimentalWarning: Flags.boolean({
char: 'H', char: 'H',
default: false, default: false,
description: 'Hides warning for experimental features', description: 'Hides warning for experimental features',
@ -127,9 +120,7 @@ export default class LoginCmd extends Command {
public static primary = true; public static primary = true;
public async run() { public async run() {
const { flags: options, args: params } = this.parse<FlagsDef, ArgsDef>( const { flags: options, args: params } = await this.parse(LoginCmd);
LoginCmd,
);
const balena = getBalenaSdk(); const balena = getBalenaSdk();
const messages = await import('../utils/messages'); const messages = await import('../utils/messages');

View File

@ -29,7 +29,7 @@ export default class LogoutCmd extends Command {
public static usage = 'logout'; public static usage = 'logout';
public async run() { public async run() {
this.parse<{}, {}>(LogoutCmd); await this.parse(LogoutCmd);
await getBalenaSdk().auth.logout(); await getBalenaSdk().auth.logout();
} }
} }

View File

@ -15,24 +15,11 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags, Args } from '@oclif/core';
import Command from '../command'; import Command from '../command';
import * as cf from '../utils/common-flags'; import * as cf from '../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../utils/lazy'; import { getBalenaSdk, stripIndent } from '../utils/lazy';
import { LogMessage } from 'balena-sdk'; import { LogMessage } from 'balena-sdk';
import { IArg } from '@oclif/parser/lib/args';
interface FlagsDef {
'max-retry'?: number;
tail?: boolean;
service?: string[];
system?: boolean;
help: void;
}
interface ArgsDef {
device: string;
}
const MAX_RETRY = 1000; const MAX_RETRY = 1000;
@ -67,35 +54,34 @@ export default class LogsCmd extends Command {
'$ balena logs 23c73a1.local --system --service my-service', '$ balena logs 23c73a1.local --system --service my-service',
]; ];
public static args: Array<IArg<any>> = [ public static args = {
{ device: Args.string({
name: 'device',
description: 'device UUID, IP, or .local address', description: 'device UUID, IP, or .local address',
required: true, required: true,
}, }),
]; };
public static usage = 'logs <device>'; public static usage = 'logs <device>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
'max-retry': flags.integer({ 'max-retry': Flags.integer({
description: stripIndent` description: stripIndent`
Maximum number of reconnection attempts on "connection lost" errors Maximum number of reconnection attempts on "connection lost" errors
(use 0 to disable auto reconnection).`, (use 0 to disable auto reconnection).`,
}), }),
tail: flags.boolean({ tail: Flags.boolean({
default: false, default: false,
description: 'continuously stream output', description: 'continuously stream output',
char: 't', char: 't',
}), }),
service: flags.string({ service: Flags.string({
description: stripIndent` description: stripIndent`
Reject logs not originating from this service. Reject logs not originating from this service.
This can be used in combination with --system or other --service flags.`, This can be used in combination with --system or other --service flags.`,
char: 's', char: 's',
multiple: true, multiple: true,
}), }),
system: flags.boolean({ system: Flags.boolean({
default: false, default: false,
description: description:
'Only show system logs. This can be used in combination with --service.', 'Only show system logs. This can be used in combination with --service.',
@ -107,9 +93,7 @@ export default class LogsCmd extends Command {
public static primary = true; public static primary = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(LogsCmd);
LogsCmd,
);
const balena = getBalenaSdk(); const balena = getBalenaSdk();
const { serviceIdToName } = await import('../utils/cloud'); const { serviceIdToName } = await import('../utils/cloud');

View File

@ -15,22 +15,12 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags, Args } from '@oclif/core';
import Command from '../command'; import Command from '../command';
import { ExpectedError } from '../errors'; import { ExpectedError } from '../errors';
import * as cf from '../utils/common-flags'; import * as cf from '../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../utils/lazy'; import { getBalenaSdk, stripIndent } from '../utils/lazy';
interface FlagsDef {
device?: string; // device UUID
dev?: string; // Alias for device.
help: void;
}
interface ArgsDef {
note: string;
}
export default class NoteCmd extends Command { export default class NoteCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Set a device note. Set a device note.
@ -46,18 +36,17 @@ export default class NoteCmd extends Command {
'$ cat note.txt | balena note --device 7cf02a6', '$ cat note.txt | balena note --device 7cf02a6',
]; ];
public static args = [ public static args = {
{ note: Args.string({
name: 'note',
description: 'note content', description: 'note content',
}, }),
]; };
public static usage = 'note <|note>'; public static usage = 'note <|note>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
device: { exclusive: ['dev'], ...cf.device }, device: { exclusive: ['dev'], ...cf.device },
dev: flags.string({ dev: Flags.string({
exclusive: ['device'], exclusive: ['device'],
hidden: true, hidden: true,
}), }),
@ -69,9 +58,7 @@ export default class NoteCmd extends Command {
public static readStdin = true; public static readStdin = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(NoteCmd);
NoteCmd,
);
params.note = params.note || this.stdin; params.note = params.note || this.stdin;

View File

@ -15,15 +15,10 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command';
import Command from '../command'; import Command from '../command';
import * as cf from '../utils/common-flags'; import * as cf from '../utils/common-flags';
import { getBalenaSdk, getVisuals, stripIndent } from '../utils/lazy'; import { getBalenaSdk, getVisuals, stripIndent } from '../utils/lazy';
interface FlagsDef {
help: void;
}
export default class OrgsCmd extends Command { export default class OrgsCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
List all organizations. List all organizations.
@ -34,14 +29,14 @@ export default class OrgsCmd extends Command {
public static usage = 'orgs'; public static usage = 'orgs';
public static flags: flags.Input<FlagsDef> = { public static flags = {
help: cf.help, help: cf.help,
}; };
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
this.parse<FlagsDef, {}>(OrgsCmd); await this.parse(OrgsCmd);
const { getOwnOrganizations } = await import('../utils/sdk'); const { getOwnOrganizations } = await import('../utils/sdk');

View File

@ -15,24 +15,13 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags, Args } from '@oclif/core';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getCliForm, stripIndent } from '../../utils/lazy'; import { getCliForm, stripIndent } from '../../utils/lazy';
import * as _ from 'lodash'; import * as _ from 'lodash';
import type { DeviceTypeJson } from 'balena-sdk'; import type { DeviceTypeJson } from 'balena-sdk';
interface FlagsDef {
advanced: boolean;
output: string;
help: void;
}
interface ArgsDef {
image: string;
'device-type': string;
}
export default class OsBuildConfigCmd extends Command { export default class OsBuildConfigCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Prepare a configuration file for use by the 'os configure' command. Prepare a configuration file for use by the 'os configure' command.
@ -46,27 +35,25 @@ export default class OsBuildConfigCmd extends Command {
'$ balena os configure ../path/rpi3.img --device 7cf02a6 --config rpi3-config.json', '$ balena os configure ../path/rpi3.img --device 7cf02a6 --config rpi3-config.json',
]; ];
public static args = [ public static args = {
{ image: Args.string({
name: 'image',
description: 'os image', description: 'os image',
required: true, required: true,
}, }),
{ 'device-type': Args.string({
name: 'device-type',
description: 'device type', description: 'device type',
required: true, required: true,
}, }),
]; };
public static usage = 'os build-config <image> <device-type>'; public static usage = 'os build-config <image> <device-type>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
advanced: flags.boolean({ advanced: Flags.boolean({
description: 'show advanced configuration options', description: 'show advanced configuration options',
char: 'v', char: 'v',
}), }),
output: flags.string({ output: Flags.string({
description: 'path to output JSON file', description: 'path to output JSON file',
char: 'o', char: 'o',
required: true, required: true,
@ -77,9 +64,7 @@ export default class OsBuildConfigCmd extends Command {
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(OsBuildConfigCmd);
OsBuildConfigCmd,
);
const { writeFile } = (await import('fs')).promises; const { writeFile } = (await import('fs')).promises;

View File

@ -15,7 +15,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags, Args } from '@oclif/core';
import type { Interfaces } from '@oclif/core';
import type * as BalenaSdk from 'balena-sdk'; import type * as BalenaSdk from 'balena-sdk';
import { promisify } from 'util'; import { promisify } from 'util';
import * as _ from 'lodash'; import * as _ from 'lodash';
@ -31,29 +32,7 @@ import {
const CONNECTIONS_FOLDER = '/system-connections'; const CONNECTIONS_FOLDER = '/system-connections';
interface FlagsDef { type FlagsDef = Interfaces.InferredFlags<typeof OsConfigureCmd.flags>;
advanced?: boolean;
fleet?: string;
config?: string;
'config-app-update-poll-interval'?: number;
'config-network'?: string;
'config-wifi-key'?: string;
'config-wifi-ssid'?: string;
dev?: boolean; // balenaOS development variant
secureBoot?: boolean;
device?: string; // device UUID
'device-type'?: string;
help?: void;
version?: string;
'system-connection': string[];
'initial-device-name'?: string;
'provisioning-key-name'?: string;
'provisioning-key-expiry-date'?: string;
}
interface ArgsDef {
image: string;
}
interface Answers { interface Answers {
appUpdatePollInterval: number; // in minutes appUpdatePollInterval: number; // in minutes
@ -111,40 +90,39 @@ export default class OsConfigureCmd extends Command {
'$ balena os configure ../path/rpi3.img -f MyFinFleet --device-type raspberrypi3 --config myWifiConfig.json', '$ balena os configure ../path/rpi3.img -f MyFinFleet --device-type raspberrypi3 --config myWifiConfig.json',
]; ];
public static args = [ public static args = {
{ image: Args.string({
name: 'image',
required: true, required: true,
description: 'path to a balenaOS image file, e.g. "rpi3.img"', description: 'path to a balenaOS image file, e.g. "rpi3.img"',
}, }),
]; };
public static usage = 'os configure <image>'; public static usage = 'os configure <image>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
advanced: flags.boolean({ advanced: Flags.boolean({
char: 'v', char: 'v',
description: description:
'ask advanced configuration questions (when in interactive mode)', 'ask advanced configuration questions (when in interactive mode)',
}), }),
fleet: { ...cf.fleet, exclusive: ['device'] }, fleet: { ...cf.fleet, exclusive: ['device'] },
config: flags.string({ config: Flags.string({
description: description:
'path to a pre-generated config.json file to be injected in the OS image', 'path to a pre-generated config.json file to be injected in the OS image',
exclusive: ['provisioning-key-name', 'provisioning-key-expiry-date'], exclusive: ['provisioning-key-name', 'provisioning-key-expiry-date'],
}), }),
'config-app-update-poll-interval': flags.integer({ 'config-app-update-poll-interval': Flags.integer({
description: description:
'supervisor cloud polling interval in minutes (e.g. for variable updates)', 'supervisor cloud polling interval in minutes (e.g. for variable updates)',
}), }),
'config-network': flags.string({ 'config-network': Flags.string({
description: 'device network type (non-interactive configuration)', description: 'device network type (non-interactive configuration)',
options: ['ethernet', 'wifi'], options: ['ethernet', 'wifi'],
}), }),
'config-wifi-key': flags.string({ 'config-wifi-key': Flags.string({
description: 'WiFi key (password) (non-interactive configuration)', description: 'WiFi key (password) (non-interactive configuration)',
}), }),
'config-wifi-ssid': flags.string({ 'config-wifi-ssid': Flags.string({
description: 'WiFi SSID (network name) (non-interactive configuration)', description: 'WiFi SSID (network name) (non-interactive configuration)',
}), }),
dev: cf.dev, dev: cf.dev,
@ -157,29 +135,29 @@ export default class OsConfigureCmd extends Command {
'provisioning-key-expiry-date', 'provisioning-key-expiry-date',
], ],
}, },
'device-type': flags.string({ 'device-type': Flags.string({
description: description:
'device type slug (e.g. "raspberrypi3") to override the fleet device type', 'device type slug (e.g. "raspberrypi3") to override the fleet device type',
}), }),
'initial-device-name': flags.string({ 'initial-device-name': Flags.string({
description: description:
'This option will set the device name when the device provisions', 'This option will set the device name when the device provisions',
}), }),
version: flags.string({ version: Flags.string({
description: 'balenaOS version, for example "2.32.0" or "2.44.0+rev1"', description: 'balenaOS version, for example "2.32.0" or "2.44.0+rev1"',
}), }),
'system-connection': flags.string({ 'system-connection': Flags.string({
multiple: true, multiple: true,
char: 'c', char: 'c',
required: false, required: false,
description: description:
"paths to local files to place into the 'system-connections' directory", "paths to local files to place into the 'system-connections' directory",
}), }),
'provisioning-key-name': flags.string({ 'provisioning-key-name': Flags.string({
description: 'custom key name assigned to generated provisioning api key', description: 'custom key name assigned to generated provisioning api key',
exclusive: ['config', 'device'], exclusive: ['config', 'device'],
}), }),
'provisioning-key-expiry-date': flags.string({ 'provisioning-key-expiry-date': Flags.string({
description: description:
'expiry date assigned to generated provisioning api key (format: YYYY-MM-DD)', 'expiry date assigned to generated provisioning api key (format: YYYY-MM-DD)',
exclusive: ['config', 'device'], exclusive: ['config', 'device'],
@ -190,9 +168,7 @@ export default class OsConfigureCmd extends Command {
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(OsConfigureCmd);
OsConfigureCmd,
);
await validateOptions(options); await validateOptions(options);

View File

@ -15,21 +15,11 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags, Args } from '@oclif/core';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { stripIndent } from '../../utils/lazy'; import { stripIndent } from '../../utils/lazy';
interface FlagsDef {
output: string;
version?: string;
help: void;
}
interface ArgsDef {
type: string;
}
export default class OsDownloadCmd extends Command { export default class OsDownloadCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Download an unconfigured OS image. Download an unconfigured OS image.
@ -65,23 +55,22 @@ export default class OsDownloadCmd extends Command {
'$ balena os download raspberrypi3 -o ../foo/bar/raspberry-pi.img --version menu-esr', '$ balena os download raspberrypi3 -o ../foo/bar/raspberry-pi.img --version menu-esr',
]; ];
public static args = [ public static args = {
{ type: Args.string({
name: 'type',
description: 'the device type', description: 'the device type',
required: true, required: true,
}, }),
]; };
public static usage = 'os download <type>'; public static usage = 'os download <type>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
output: flags.string({ output: Flags.string({
description: 'output path', description: 'output path',
char: 'o', char: 'o',
required: true, required: true,
}), }),
version: flags.string({ version: Flags.string({
description: stripIndent` description: stripIndent`
version number (ESR or non-ESR versions), version number (ESR or non-ESR versions),
or semver range (non-ESR versions only), or semver range (non-ESR versions only),
@ -96,9 +85,7 @@ export default class OsDownloadCmd extends Command {
}; };
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(OsDownloadCmd);
OsDownloadCmd,
);
// balenaOS ESR versions require user authentication // balenaOS ESR versions require user authentication
if (options.version) { if (options.version) {

View File

@ -15,22 +15,11 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Args } from '@oclif/core';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getCliForm, stripIndent } from '../../utils/lazy'; import { getCliForm, stripIndent } from '../../utils/lazy';
interface FlagsDef {
type: string;
drive?: string;
yes: boolean;
help: void;
}
interface ArgsDef {
image: string;
}
const INIT_WARNING_MESSAGE = ` const INIT_WARNING_MESSAGE = `
Note: Initializing the device may ask for administrative permissions Note: Initializing the device may ask for administrative permissions
@ -52,17 +41,16 @@ export default class OsInitializeCmd extends Command {
'$ balena os initialize ../path/rpi.img --type raspberry-pi', '$ balena os initialize ../path/rpi.img --type raspberry-pi',
]; ];
public static args = [ public static args = {
{ image: Args.string({
name: 'image',
description: 'path to OS image', description: 'path to OS image',
required: true, required: true,
}, }),
]; };
public static usage = 'os initialize <image>'; public static usage = 'os initialize <image>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
type: cf.deviceType, type: cf.deviceType,
drive: cf.drive, drive: cf.drive,
yes: cf.yes, yes: cf.yes,
@ -72,9 +60,7 @@ export default class OsInitializeCmd extends Command {
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(OsInitializeCmd);
OsInitializeCmd,
);
const { getManifest, sudo } = await import('../../utils/helpers'); const { getManifest, sudo } = await import('../../utils/helpers');

View File

@ -15,20 +15,11 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags, Args } from '@oclif/core';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { stripIndent } from '../../utils/lazy'; import { stripIndent } from '../../utils/lazy';
interface FlagsDef {
esr?: boolean;
help: void;
}
interface ArgsDef {
type: string;
}
export default class OsVersionsCmd extends Command { export default class OsVersionsCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Show available balenaOS versions for the given device type. Show available balenaOS versions for the given device type.
@ -42,28 +33,25 @@ export default class OsVersionsCmd extends Command {
public static examples = ['$ balena os versions raspberrypi3']; public static examples = ['$ balena os versions raspberrypi3'];
public static args = [ public static args = {
{ type: Args.string({
name: 'type',
description: 'device type', description: 'device type',
required: true, required: true,
}, }),
]; };
public static usage = 'os versions <type>'; public static usage = 'os versions <type>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
help: cf.help, help: cf.help,
esr: flags.boolean({ esr: Flags.boolean({
description: 'select balenaOS ESR versions', description: 'select balenaOS ESR versions',
default: false, default: false,
}), }),
}; };
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(OsVersionsCmd);
OsVersionsCmd,
);
const { formatOsVersion, getOsVersions } = await import( const { formatOsVersion, getOsVersions } = await import(
'../../utils/cloud' '../../utils/cloud'

View File

@ -25,11 +25,10 @@ import {
stripIndent, stripIndent,
} from '../utils/lazy'; } from '../utils/lazy';
import { applicationIdInfo } from '../utils/messages'; import { applicationIdInfo } from '../utils/messages';
import type { DockerConnectionCliFlags } from '../utils/docker';
import { dockerConnectionCliFlags } from '../utils/docker'; import { dockerConnectionCliFlags } from '../utils/docker';
import { parseAsInteger } from '../utils/validation'; import { parseAsInteger } from '../utils/validation';
import { flags } from '@oclif/command'; import { Flags, Args } from '@oclif/core';
import * as _ from 'lodash'; import * as _ from 'lodash';
import type { import type {
Application, Application,
@ -41,21 +40,6 @@ import type {
} from 'balena-sdk'; } from 'balena-sdk';
import type { Preloader } from 'balena-preload'; import type { Preloader } from 'balena-preload';
interface FlagsDef extends DockerConnectionCliFlags {
fleet?: string;
commit?: string;
'splash-image'?: string;
'dont-check-arch': boolean;
'pin-device-to-release'?: boolean;
'additional-space'?: number;
'add-certificate'?: string[];
help: void;
}
interface ArgsDef {
image: string;
}
export default class PreloadCmd extends Command { export default class PreloadCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Preload a release on a disk image (or Edison zip archive). Preload a release on a disk image (or Edison zip archive).
@ -89,19 +73,18 @@ export default class PreloadCmd extends Command {
'$ balena preload balena.img', '$ balena preload balena.img',
]; ];
public static args = [ public static args = {
{ image: Args.string({
name: 'image',
description: 'the image file path', description: 'the image file path',
required: true, required: true,
}, }),
]; };
public static usage = 'preload <image>'; public static usage = 'preload <image>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
fleet: cf.fleet, fleet: cf.fleet,
commit: flags.string({ commit: Flags.string({
description: `\ description: `\
The commit hash of the release to preload. Use "current" to specify the current The commit hash of the release to preload. Use "current" to specify the current
release (ignored if no appId is given). The current release is usually also the release (ignored if no appId is given). The current release is usually also the
@ -112,27 +95,27 @@ https://github.com/balena-io-examples/staged-releases\
`, `,
char: 'c', char: 'c',
}), }),
'splash-image': flags.string({ 'splash-image': Flags.string({
description: 'path to a png image to replace the splash screen', description: 'path to a png image to replace the splash screen',
char: 's', char: 's',
}), }),
'dont-check-arch': flags.boolean({ 'dont-check-arch': Flags.boolean({
default: false, default: false,
description: description:
'disable architecture compatibility check between image and fleet', 'disable architecture compatibility check between image and fleet',
}), }),
'pin-device-to-release': flags.boolean({ 'pin-device-to-release': Flags.boolean({
allowNo: true, allowNo: true,
description: description:
'pin the preloaded device to the preloaded release on provision', 'pin the preloaded device to the preloaded release on provision',
char: 'p', char: 'p',
}), }),
'additional-space': flags.integer({ 'additional-space': Flags.integer({
description: description:
'expand the image by this amount of bytes instead of automatically estimating the required amount', 'expand the image by this amount of bytes instead of automatically estimating the required amount',
parse: (x) => parseAsInteger(x, 'additional-space'), parse: async (x) => parseAsInteger(x, 'additional-space'),
}), }),
'add-certificate': flags.string({ 'add-certificate': Flags.string({
description: `\ description: `\
Add the given certificate (in PEM format) to /etc/ssl/certs in the preloading container. Add the given certificate (in PEM format) to /etc/ssl/certs in the preloading container.
The file name must end with '.crt' and must not be already contained in the preloader's The file name must end with '.crt' and must not be already contained in the preloader's
@ -144,14 +127,14 @@ Can be repeated to add multiple certificates.\
...dockerConnectionCliFlags, ...dockerConnectionCliFlags,
// Redefining --dockerPort here (defined already in dockerConnectionCliFlags) // Redefining --dockerPort here (defined already in dockerConnectionCliFlags)
// without -p alias, to avoid clash with -p alias of pin-device-to-release // without -p alias, to avoid clash with -p alias of pin-device-to-release
dockerPort: flags.integer({ dockerPort: Flags.integer({
description: description:
'Docker daemon TCP port number (hint: 2375 for balena devices)', 'Docker daemon TCP port number (hint: 2375 for balena devices)',
parse: (p) => parseAsInteger(p, 'dockerPort'), parse: async (p) => parseAsInteger(p, 'dockerPort'),
}), }),
// Not supporting -h for help, because of clash with -h in DockerCliFlags // Not supporting -h for help, because of clash with -h in DockerCliFlags
// Revisit this in future release. // Revisit this in future release.
help: flags.help({}), help: Flags.help({}),
}; };
public static authenticated = true; public static authenticated = true;
@ -159,9 +142,7 @@ Can be repeated to add multiple certificates.\
public static primary = true; public static primary = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(PreloadCmd);
PreloadCmd,
);
const balena = getBalenaSdk(); const balena = getBalenaSdk();
const balenaPreload = await import('balena-preload'); const balenaPreload = await import('balena-preload');

View File

@ -15,7 +15,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags, Args } from '@oclif/core';
import type { Interfaces } from '@oclif/core';
import Command from '../command'; import Command from '../command';
import * as cf from '../utils/common-flags'; import * as cf from '../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../utils/lazy'; import { getBalenaSdk, stripIndent } from '../utils/lazy';
@ -34,30 +35,7 @@ enum BuildTarget {
Device, Device,
} }
interface ArgsDef { type FlagsDef = Interfaces.InferredFlags<typeof PushCmd.flags>;
fleetOrDevice: string;
}
interface FlagsDef {
source: string;
emulated: boolean;
dockerfile?: string; // DeviceDeployOptions.dockerfilePath (alternative Dockerfile)
nocache: boolean;
pull: boolean;
'noparent-check': boolean;
'registry-secrets'?: string;
nolive: boolean;
detached: boolean;
service?: string[];
system: boolean;
env?: string[];
'noconvert-eol': boolean;
'multi-dockerignore': boolean;
'release-tag'?: string[];
draft: boolean;
note?: string;
help: void;
}
export default class PushCmd extends Command { export default class PushCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
@ -112,27 +90,26 @@ export default class PushCmd extends Command {
'$ balena push 23c73a1.local --system --service my-service', '$ balena push 23c73a1.local --system --service my-service',
]; ];
public static args = [ public static args = {
{ fleetOrDevice: Args.string({
name: 'fleetOrDevice',
description: description:
'fleet name or slug, or local device IP address or ".local" hostname', 'fleet name or slug, or local device IP address or ".local" hostname',
required: true, required: true,
parse: lowercaseIfSlug, parse: lowercaseIfSlug,
}, }),
]; };
public static usage = 'push <fleetOrDevice>'; public static usage = 'push <fleetOrDevice>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
source: flags.string({ source: Flags.string({
description: stripIndent` description: stripIndent`
Source directory to be sent to balenaCloud or balenaOS device Source directory to be sent to balenaCloud or balenaOS device
(default: current working dir)`, (default: current working dir)`,
char: 's', char: 's',
default: '.', default: '.',
}), }),
emulated: flags.boolean({ emulated: Flags.boolean({
description: stripIndent` description: stripIndent`
Don't use the faster, native balenaCloud ARM builders; force slower QEMU ARM Don't use the faster, native balenaCloud ARM builders; force slower QEMU ARM
emulation on Intel x86-64 builders. This flag is sometimes used to investigate emulation on Intel x86-64 builders. This flag is sometimes used to investigate
@ -140,11 +117,11 @@ export default class PushCmd extends Command {
char: 'e', char: 'e',
default: false, default: false,
}), }),
dockerfile: flags.string({ dockerfile: Flags.string({
description: description:
'Alternative Dockerfile name/path, relative to the source folder', 'Alternative Dockerfile name/path, relative to the source folder',
}), }),
nocache: flags.boolean({ nocache: Flags.boolean({
description: stripIndent` description: stripIndent`
Don't use cached layers of previously built images for this project. This Don't use cached layers of previously built images for this project. This
ensures that the latest base image and packages are pulled. Note that build ensures that the latest base image and packages are pulled. Note that build
@ -155,18 +132,18 @@ export default class PushCmd extends Command {
char: 'c', char: 'c',
default: false, default: false,
}), }),
pull: flags.boolean({ pull: Flags.boolean({
description: stripIndent` description: stripIndent`
When pushing to a local device, force the base images to be pulled again. When pushing to a local device, force the base images to be pulled again.
Currently this option is ignored when pushing to the balenaCloud builders.`, Currently this option is ignored when pushing to the balenaCloud builders.`,
default: false, default: false,
}), }),
'noparent-check': flags.boolean({ 'noparent-check': Flags.boolean({
description: stripIndent` description: stripIndent`
Disable project validation check of 'docker-compose.yml' file in parent folder`, Disable project validation check of 'docker-compose.yml' file in parent folder`,
default: false, default: false,
}), }),
'registry-secrets': flags.string({ 'registry-secrets': Flags.string({
description: stripIndent` description: stripIndent`
Path to a local YAML or JSON file containing Docker registry passwords used Path to a local YAML or JSON file containing Docker registry passwords used
to pull base images. Note that if registry-secrets are not provided on the to pull base images. Note that if registry-secrets are not provided on the
@ -174,7 +151,7 @@ export default class PushCmd extends Command {
used (usually $HOME/.balena/secrets.yml|.json)`, used (usually $HOME/.balena/secrets.yml|.json)`,
char: 'R', char: 'R',
}), }),
nolive: flags.boolean({ nolive: Flags.boolean({
description: stripIndent` description: stripIndent`
Don't run a live session on this push. The filesystem will not be monitored, Don't run a live session on this push. The filesystem will not be monitored,
and changes will not be synchronized to any running containers. Note that both and changes will not be synchronized to any running containers. Note that both
@ -182,7 +159,7 @@ export default class PushCmd extends Command {
initial build has completed.`, initial build has completed.`,
default: false, default: false,
}), }),
detached: flags.boolean({ detached: Flags.boolean({
description: stripIndent` description: stripIndent`
When pushing to the cloud, this option will cause the build to start, then When pushing to the cloud, this option will cause the build to start, then
return execution back to the shell, with the status and release ID (if return execution back to the shell, with the status and release ID (if
@ -191,20 +168,20 @@ export default class PushCmd extends Command {
char: 'd', char: 'd',
default: false, default: false,
}), }),
service: flags.string({ service: Flags.string({
description: stripIndent` description: stripIndent`
Reject logs not originating from this service. Reject logs not originating from this service.
This can be used in combination with --system and other --service flags. This can be used in combination with --system and other --service flags.
Only valid when pushing to a local mode device.`, Only valid when pushing to a local mode device.`,
multiple: true, multiple: true,
}), }),
system: flags.boolean({ system: Flags.boolean({
description: stripIndent` description: stripIndent`
Only show system logs. This can be used in combination with --service. Only show system logs. This can be used in combination with --service.
Only valid when pushing to a local mode device.`, Only valid when pushing to a local mode device.`,
default: false, default: false,
}), }),
env: flags.string({ env: Flags.string({
description: stripIndent` description: stripIndent`
When performing a push to device, run the built containers with environment When performing a push to device, run the built containers with environment
variables provided with this argument. Environment variables can be applied variables provided with this argument. Environment variables can be applied
@ -216,17 +193,17 @@ export default class PushCmd extends Command {
`, `,
multiple: true, multiple: true,
}), }),
'noconvert-eol': flags.boolean({ 'noconvert-eol': Flags.boolean({
description: `Don't convert line endings from CRLF (Windows format) to LF (Unix format).`, description: `Don't convert line endings from CRLF (Windows format) to LF (Unix format).`,
default: false, default: false,
}), }),
'multi-dockerignore': flags.boolean({ 'multi-dockerignore': Flags.boolean({
description: description:
'Have each service use its own .dockerignore file. See "balena help push".', 'Have each service use its own .dockerignore file. See "balena help push".',
char: 'm', char: 'm',
default: false, default: false,
}), }),
'release-tag': flags.string({ 'release-tag': Flags.string({
description: stripIndent` description: stripIndent`
Set release tags if the image build is successful (balenaCloud only). Multiple Set release tags if the image build is successful (balenaCloud only). Multiple
arguments may be provided, alternating tag keys and values (see examples). arguments may be provided, alternating tag keys and values (see examples).
@ -235,7 +212,7 @@ export default class PushCmd extends Command {
multiple: true, multiple: true,
exclusive: ['detached'], exclusive: ['detached'],
}), }),
draft: flags.boolean({ draft: Flags.boolean({
description: stripIndent` description: stripIndent`
Instruct the builder to create the release as a draft. Draft releases are ignored Instruct the builder to create the release as a draft. Draft releases are ignored
by the 'track latest' release policy but can be used through release pinning. by the 'track latest' release policy but can be used through release pinning.
@ -243,16 +220,14 @@ export default class PushCmd extends Command {
as final by default unless this option is given.`, as final by default unless this option is given.`,
default: false, default: false,
}), }),
note: flags.string({ description: 'The notes for this release' }), note: Flags.string({ description: 'The notes for this release' }),
help: cf.help, help: cf.help,
}; };
public static primary = true; public static primary = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(PushCmd);
PushCmd,
);
const logger = await Command.getLogger(); const logger = await Command.getLogger();
logger.logDebug(`Using build source directory: ${options.source} `); logger.logDebug(`Using build source directory: ${options.source} `);

View File

@ -15,19 +15,10 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { commitOrIdArg } from '.';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, stripIndent } from '../../utils/lazy';
import { tryAsInteger } from '../../utils/validation';
interface FlagsDef {
help: void;
}
interface ArgsDef {
commitOrId: string | number;
}
export default class ReleaseFinalizeCmd extends Command { export default class ReleaseFinalizeCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
@ -51,23 +42,21 @@ export default class ReleaseFinalizeCmd extends Command {
public static usage = 'release finalize <commitOrId>'; public static usage = 'release finalize <commitOrId>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
help: cf.help, help: cf.help,
}; };
public static args = [ public static args = {
{ commitOrId: commitOrIdArg({
name: 'commitOrId',
description: 'the commit or ID of the release to finalize', description: 'the commit or ID of the release to finalize',
required: true, required: true,
parse: (commitOrId: string) => tryAsInteger(commitOrId), }),
}, };
];
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params } = this.parse<FlagsDef, ArgsDef>(ReleaseFinalizeCmd); const { args: params } = await this.parse(ReleaseFinalizeCmd);
const balena = getBalenaSdk(); const balena = getBalenaSdk();

View File

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags, Args } from '@oclif/core';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
@ -23,14 +23,9 @@ import type * as BalenaSdk from 'balena-sdk';
import jsyaml = require('js-yaml'); import jsyaml = require('js-yaml');
import { tryAsInteger } from '../../utils/validation'; import { tryAsInteger } from '../../utils/validation';
interface FlagsDef { export const commitOrIdArg = Args.custom({
help: void; parse: async (commitOrId: string) => tryAsInteger(commitOrId),
composition?: boolean; });
}
interface ArgsDef {
commitOrId: string | number;
}
export default class ReleaseCmd extends Command { export default class ReleaseCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
@ -43,30 +38,26 @@ export default class ReleaseCmd extends Command {
public static usage = 'release <commitOrId>'; public static usage = 'release <commitOrId>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
help: cf.help, help: cf.help,
composition: flags.boolean({ composition: Flags.boolean({
default: false, default: false,
char: 'c', char: 'c',
description: 'Return the release composition', description: 'Return the release composition',
}), }),
}; };
public static args = [ public static args = {
{ commitOrId: commitOrIdArg({
name: 'commitOrId',
description: 'the commit or ID of the release to get information', description: 'the commit or ID of the release to get information',
required: true, required: true,
parse: (commitOrId: string) => tryAsInteger(commitOrId), }),
}, };
];
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(ReleaseCmd);
ReleaseCmd,
);
const balena = getBalenaSdk(); const balena = getBalenaSdk();
if (options.composition) { if (options.composition) {

View File

@ -15,19 +15,10 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { commitOrIdArg } from '.';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, stripIndent } from '../../utils/lazy';
import { tryAsInteger } from '../../utils/validation';
interface FlagsDef {
help: void;
}
interface ArgsDef {
commitOrId: string | number;
}
export default class ReleaseInvalidateCmd extends Command { export default class ReleaseInvalidateCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
@ -46,25 +37,21 @@ export default class ReleaseInvalidateCmd extends Command {
public static usage = 'release invalidate <commitOrId>'; public static usage = 'release invalidate <commitOrId>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
help: cf.help, help: cf.help,
}; };
public static args = [ public static args = {
{ commitOrId: commitOrIdArg({
name: 'commitOrId',
description: 'the commit or ID of the release to invalidate', description: 'the commit or ID of the release to invalidate',
required: true, required: true,
parse: (commitOrId: string) => tryAsInteger(commitOrId), }),
}, };
];
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params } = this.parse<FlagsDef, ArgsDef>( const { args: params } = await this.parse(ReleaseInvalidateCmd);
ReleaseInvalidateCmd,
);
const balena = getBalenaSdk(); const balena = getBalenaSdk();

View File

@ -15,19 +15,10 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { commitOrIdArg } from '.';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, stripIndent } from '../../utils/lazy';
import { tryAsInteger } from '../../utils/validation';
interface FlagsDef {
help: void;
}
interface ArgsDef {
commitOrId: string | number;
}
export default class ReleaseValidateCmd extends Command { export default class ReleaseValidateCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
@ -45,23 +36,21 @@ export default class ReleaseValidateCmd extends Command {
public static usage = 'release validate <commitOrId>'; public static usage = 'release validate <commitOrId>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
help: cf.help, help: cf.help,
}; };
public static args = [ public static args = {
{ commitOrId: commitOrIdArg({
name: 'commitOrId',
description: 'the commit or ID of the release to validate', description: 'the commit or ID of the release to validate',
required: true, required: true,
parse: (commitOrId: string) => tryAsInteger(commitOrId), }),
}, };
];
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params } = this.parse<FlagsDef, ArgsDef>(ReleaseValidateCmd); const { args: params } = await this.parse(ReleaseValidateCmd);
const balena = getBalenaSdk(); const balena = getBalenaSdk();

View File

@ -15,21 +15,13 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Args } from '@oclif/core';
import Command from '../command'; import Command from '../command';
import * as cf from '../utils/common-flags'; import * as cf from '../utils/common-flags';
import { getBalenaSdk, getVisuals, stripIndent } from '../utils/lazy'; import { getBalenaSdk, getVisuals, stripIndent } from '../utils/lazy';
import { applicationNameNote } from '../utils/messages'; import { applicationNameNote } from '../utils/messages';
import type * as BalenaSdk from 'balena-sdk'; import type * as BalenaSdk from 'balena-sdk';
interface FlagsDef {
help: void;
}
interface ArgsDef {
fleet: string;
}
export default class ReleasesCmd extends Command { export default class ReleasesCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
List all releases of a fleet. List all releases of a fleet.
@ -42,22 +34,21 @@ export default class ReleasesCmd extends Command {
public static usage = 'releases <fleet>'; public static usage = 'releases <fleet>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
help: cf.help, help: cf.help,
}; };
public static args = [ public static args = {
{ fleet: Args.string({
name: 'fleet',
description: 'fleet name or slug (preferred)', description: 'fleet name or slug (preferred)',
required: true, required: true,
}, }),
]; };
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params } = this.parse<FlagsDef, ArgsDef>(ReleasesCmd); const { args: params } = await this.parse(ReleasesCmd);
const fields: Array<keyof BalenaSdk.Release> = [ const fields: Array<keyof BalenaSdk.Release> = [
'id', 'id',

View File

@ -15,18 +15,11 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags } from '@oclif/core';
import Command from '../command'; import Command from '../command';
import * as cf from '../utils/common-flags'; import * as cf from '../utils/common-flags';
import { getCliUx, stripIndent } from '../utils/lazy'; import { getCliUx, stripIndent } from '../utils/lazy';
interface FlagsDef {
json?: boolean;
verbose: boolean;
timeout?: number;
help: void;
}
export default class ScanCmd extends Command { export default class ScanCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Scan for balenaOS devices on your local network. Scan for balenaOS devices on your local network.
@ -47,18 +40,18 @@ export default class ScanCmd extends Command {
public static usage = 'scan'; public static usage = 'scan';
public static flags: flags.Input<FlagsDef> = { public static flags = {
verbose: flags.boolean({ verbose: Flags.boolean({
default: false, default: false,
char: 'v', char: 'v',
description: 'display full info', description: 'display full info',
}), }),
timeout: flags.integer({ timeout: Flags.integer({
char: 't', char: 't',
description: 'scan timeout in seconds', description: 'scan timeout in seconds',
}), }),
help: cf.help, help: cf.help,
json: flags.boolean({ json: Flags.boolean({
default: false, default: false,
char: 'j', char: 'j',
description: 'produce JSON output instead of tabular output', description: 'produce JSON output instead of tabular output',
@ -78,7 +71,7 @@ export default class ScanCmd extends Command {
const dockerPort = 2375; const dockerPort = 2375;
const dockerTimeout = 2000; const dockerTimeout = 2000;
const { flags: options } = this.parse<FlagsDef, {}>(ScanCmd); const { flags: options } = await this.parse(ScanCmd);
const discoverTimeout = const discoverTimeout =
options.timeout != null ? options.timeout * 1000 : undefined; options.timeout != null ? options.timeout * 1000 : undefined;

View File

@ -15,15 +15,10 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command';
import Command from '../command'; import Command from '../command';
import * as cf from '../utils/common-flags'; import * as cf from '../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../utils/lazy'; import { getBalenaSdk, stripIndent } from '../utils/lazy';
interface FlagsDef {
help: void;
}
export default class SettingsCmd extends Command { export default class SettingsCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Print current settings. Print current settings.
@ -34,12 +29,12 @@ export default class SettingsCmd extends Command {
public static usage = 'settings'; public static usage = 'settings';
public static flags: flags.Input<FlagsDef> = { public static flags = {
help: cf.help, help: cf.help,
}; };
public async run() { public async run() {
this.parse<FlagsDef, {}>(SettingsCmd); await this.parse(SettingsCmd);
const settings = await getBalenaSdk().settings.getAll(); const settings = await getBalenaSdk().settings.getAll();

View File

@ -15,25 +15,12 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags, Args } from '@oclif/core';
import Command from '../command'; import Command from '../command';
import * as cf from '../utils/common-flags'; import * as cf from '../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../utils/lazy'; import { getBalenaSdk, stripIndent } from '../utils/lazy';
import { parseAsInteger, validateLocalHostnameOrIp } from '../utils/validation'; import { parseAsInteger, validateLocalHostnameOrIp } from '../utils/validation';
interface FlagsDef {
port?: number;
tty: boolean;
verbose: boolean;
noproxy: boolean;
help: void;
}
interface ArgsDef {
fleetOrDevice: string;
service?: string;
}
export default class SshCmd extends Command { export default class SshCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Open a SSH prompt on a device's host OS or service container. Open a SSH prompt on a device's host OS or service container.
@ -73,41 +60,39 @@ export default class SshCmd extends Command {
'$ echo "uptime; exit;" | balena ssh 192.168.0.1 myService', '$ echo "uptime; exit;" | balena ssh 192.168.0.1 myService',
]; ];
public static args = [ public static args = {
{ fleetOrDevice: Args.string({
name: 'fleetOrDevice',
description: 'fleet name/slug, device uuid, or address of local device', description: 'fleet name/slug, device uuid, or address of local device',
required: true, required: true,
}, }),
{ service: Args.string({
name: 'service',
description: 'service name, if connecting to a container', description: 'service name, if connecting to a container',
required: false, required: false,
}, }),
]; };
public static usage = 'ssh <fleetOrDevice> [service]'; public static usage = 'ssh <fleetOrDevice> [service]';
public static flags: flags.Input<FlagsDef> = { public static flags = {
port: flags.integer({ port: Flags.integer({
description: stripIndent` description: stripIndent`
SSH server port number (default 22222) if the target is an IP address or .local SSH server port number (default 22222) if the target is an IP address or .local
hostname. Otherwise, port number for the balenaCloud gateway (default 22).`, hostname. Otherwise, port number for the balenaCloud gateway (default 22).`,
char: 'p', char: 'p',
parse: (p) => parseAsInteger(p, 'port'), parse: async (p) => parseAsInteger(p, 'port'),
}), }),
tty: flags.boolean({ tty: Flags.boolean({
default: false, default: false,
description: description:
'force pseudo-terminal allocation (bypass TTY autodetection for stdin)', 'force pseudo-terminal allocation (bypass TTY autodetection for stdin)',
char: 't', char: 't',
}), }),
verbose: flags.boolean({ verbose: Flags.boolean({
default: false, default: false,
description: 'increase verbosity', description: 'increase verbosity',
char: 'v', char: 'v',
}), }),
noproxy: flags.boolean({ noproxy: Flags.boolean({
default: false, default: false,
description: 'bypass global proxy configuration for the ssh connection', description: 'bypass global proxy configuration for the ssh connection',
}), }),
@ -118,9 +103,7 @@ export default class SshCmd extends Command {
public static offlineCompatible = true; public static offlineCompatible = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(SshCmd);
SshCmd,
);
// Local connection // Local connection
if (validateLocalHostnameOrIp(params.fleetOrDevice)) { if (validateLocalHostnameOrIp(params.fleetOrDevice)) {

View File

@ -15,24 +15,13 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags, Args } from '@oclif/core';
import Command from '../command'; import Command from '../command';
import { ExpectedError } from '../errors'; import { ExpectedError } from '../errors';
import * as cf from '../utils/common-flags'; import * as cf from '../utils/common-flags';
import { getBalenaSdk, getCliUx, stripIndent } from '../utils/lazy'; import { getBalenaSdk, getCliUx, stripIndent } from '../utils/lazy';
import { applicationIdInfo } from '../utils/messages'; import { applicationIdInfo } from '../utils/messages';
interface FlagsDef {
fleet?: string;
device?: string;
duration?: string;
help: void;
}
interface ArgsDef {
action: string;
}
export default class SupportCmd extends Command { export default class SupportCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Grant or revoke support access for devices or fleets. Grant or revoke support access for devices or fleets.
@ -56,18 +45,17 @@ export default class SupportCmd extends Command {
'balena support disable -f myorg/myfleet', 'balena support disable -f myorg/myfleet',
]; ];
public static args = [ public static args = {
{ action: Args.string({
name: 'action',
description: 'enable|disable support access', description: 'enable|disable support access',
options: ['enable', 'disable'], options: ['enable', 'disable'],
}, }),
]; };
public static usage = 'support <action>'; public static usage = 'support <action>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
device: flags.string({ device: Flags.string({
description: 'comma-separated list (no spaces) of device UUIDs', description: 'comma-separated list (no spaces) of device UUIDs',
char: 'd', char: 'd',
}), }),
@ -76,7 +64,7 @@ export default class SupportCmd extends Command {
description: description:
'comma-separated list (no spaces) of fleet names or slugs (preferred)', 'comma-separated list (no spaces) of fleet names or slugs (preferred)',
}, },
duration: flags.string({ duration: Flags.string({
description: description:
'length of time to enable support for, in (h)ours or (d)ays, e.g. 12h, 2d', 'length of time to enable support for, in (h)ours or (d)ays, e.g. 12h, 2d',
char: 't', char: 't',
@ -87,9 +75,7 @@ export default class SupportCmd extends Command {
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(SupportCmd);
SupportCmd,
);
const balena = getBalenaSdk(); const balena = getBalenaSdk();
const ux = getCliUx(); const ux = getCliUx();

View File

@ -15,23 +15,12 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Args } from '@oclif/core';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, stripIndent } from '../../utils/lazy';
import { applicationIdInfo } from '../../utils/messages'; import { applicationIdInfo } from '../../utils/messages';
interface FlagsDef {
fleet?: string;
device?: string;
release?: string;
help: void;
}
interface ArgsDef {
tagKey: string;
}
export default class TagRmCmd extends Command { export default class TagRmCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Remove a tag from a fleet, device or release. Remove a tag from a fleet, device or release.
@ -49,17 +38,16 @@ export default class TagRmCmd extends Command {
'$ balena tag rm myTagKey --release b376b0e544e9429483b656490e5b9443b4349bd6', '$ balena tag rm myTagKey --release b376b0e544e9429483b656490e5b9443b4349bd6',
]; ];
public static args = [ public static args = {
{ tagKey: Args.string({
name: 'tagKey',
description: 'the key string of the tag', description: 'the key string of the tag',
required: true, required: true,
}, }),
]; };
public static usage = 'tag rm <tagKey>'; public static usage = 'tag rm <tagKey>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
fleet: { fleet: {
...cf.fleet, ...cf.fleet,
exclusive: ['device', 'release'], exclusive: ['device', 'release'],
@ -78,9 +66,7 @@ export default class TagRmCmd extends Command {
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(TagRmCmd);
TagRmCmd,
);
const balena = getBalenaSdk(); const balena = getBalenaSdk();

View File

@ -15,24 +15,12 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Args } from '@oclif/core';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../../utils/lazy'; import { getBalenaSdk, stripIndent } from '../../utils/lazy';
import { applicationIdInfo } from '../../utils/messages'; import { applicationIdInfo } from '../../utils/messages';
interface FlagsDef {
fleet?: string;
device?: string;
release?: string;
help: void;
}
interface ArgsDef {
tagKey: string;
value?: string;
}
export default class TagSetCmd extends Command { export default class TagSetCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Set a tag on a fleet, device or release. Set a tag on a fleet, device or release.
@ -57,22 +45,20 @@ export default class TagSetCmd extends Command {
'$ balena tag set myCompositeTag --release b376b0e544e9429483b656490e5b9443b4349bd6', '$ balena tag set myCompositeTag --release b376b0e544e9429483b656490e5b9443b4349bd6',
]; ];
public static args = [ public static args = {
{ tagKey: Args.string({
name: 'tagKey',
description: 'the key string of the tag', description: 'the key string of the tag',
required: true, required: true,
}, }),
{ value: Args.string({
name: 'value',
description: 'the optional value associated with the tag', description: 'the optional value associated with the tag',
required: false, required: false,
}, }),
]; };
public static usage = 'tag set <tagKey> [value]'; public static usage = 'tag set <tagKey> [value]';
public static flags: flags.Input<FlagsDef> = { public static flags = {
fleet: { fleet: {
...cf.fleet, ...cf.fleet,
exclusive: ['device', 'release'], exclusive: ['device', 'release'],
@ -91,9 +77,7 @@ export default class TagSetCmd extends Command {
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(TagSetCmd);
TagSetCmd,
);
const balena = getBalenaSdk(); const balena = getBalenaSdk();

View File

@ -15,20 +15,12 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command';
import Command from '../command'; import Command from '../command';
import { ExpectedError } from '../errors'; import { ExpectedError } from '../errors';
import * as cf from '../utils/common-flags'; import * as cf from '../utils/common-flags';
import { getBalenaSdk, getVisuals, stripIndent } from '../utils/lazy'; import { getBalenaSdk, getVisuals, stripIndent } from '../utils/lazy';
import { applicationIdInfo } from '../utils/messages'; import { applicationIdInfo } from '../utils/messages';
interface FlagsDef {
fleet?: string;
device?: string;
release?: string;
help: void;
}
export default class TagsCmd extends Command { export default class TagsCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
List all tags for a fleet, device or release. List all tags for a fleet, device or release.
@ -48,7 +40,7 @@ export default class TagsCmd extends Command {
public static usage = 'tags'; public static usage = 'tags';
public static flags: flags.Input<FlagsDef> = { public static flags = {
fleet: { fleet: {
...cf.fleet, ...cf.fleet,
exclusive: ['device', 'release'], exclusive: ['device', 'release'],
@ -67,7 +59,7 @@ export default class TagsCmd extends Command {
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { flags: options } = this.parse<FlagsDef, {}>(TagsCmd); const { flags: options } = await this.parse(TagsCmd);
const balena = getBalenaSdk(); const balena = getBalenaSdk();

View File

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags, Args } from '@oclif/core';
import Command from '../command'; import Command from '../command';
import { import {
NoPortsDefinedError, NoPortsDefinedError,
@ -28,15 +28,6 @@ import { lowercaseIfSlug } from '../utils/normalization';
import type { Server, Socket } from 'net'; import type { Server, Socket } from 'net';
interface FlagsDef {
port: string[];
help: void;
}
interface ArgsDef {
deviceOrFleet: string;
}
export default class TunnelCmd extends Command { export default class TunnelCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
Tunnel local ports to your balenaOS device. Tunnel local ports to your balenaOS device.
@ -79,19 +70,18 @@ export default class TunnelCmd extends Command {
'$ balena tunnel myFleet -p 8080:3000 -p 8081:9000', '$ balena tunnel myFleet -p 8080:3000 -p 8081:9000',
]; ];
public static args = [ public static args = {
{ deviceOrFleet: Args.string({
name: 'deviceOrFleet',
description: 'device UUID or fleet name/slug', description: 'device UUID or fleet name/slug',
required: true, required: true,
parse: lowercaseIfSlug, parse: lowercaseIfSlug,
}, }),
]; };
public static usage = 'tunnel <deviceOrFleet>'; public static usage = 'tunnel <deviceOrFleet>';
public static flags: flags.Input<FlagsDef> = { public static flags = {
port: flags.string({ port: Flags.string({
description: description:
'port mapping in the format <remotePort>[:[localIP:]localPort]', 'port mapping in the format <remotePort>[:[localIP:]localPort]',
char: 'p', char: 'p',
@ -104,9 +94,7 @@ export default class TunnelCmd extends Command {
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>( const { args: params, flags: options } = await this.parse(TunnelCmd);
TunnelCmd,
);
const logger = await Command.getLogger(); const logger = await Command.getLogger();
const sdk = getBalenaSdk(); const sdk = getBalenaSdk();

View File

@ -15,15 +15,10 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command';
import Command from '../../command'; import Command from '../../command';
import * as cf from '../../utils/common-flags'; import * as cf from '../../utils/common-flags';
import { stripIndent, getChalk, getVisuals } from '../../utils/lazy'; import { stripIndent, getChalk, getVisuals } from '../../utils/lazy';
interface FlagsDef {
help: void;
}
export default class UtilAvailableDrivesCmd extends Command { export default class UtilAvailableDrivesCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
List available drives. List available drives.
@ -34,14 +29,14 @@ export default class UtilAvailableDrivesCmd extends Command {
public static usage = 'util available-drives'; public static usage = 'util available-drives';
public static flags: flags.Input<FlagsDef> = { public static flags = {
help: cf.help, help: cf.help,
}; };
public static offlineCompatible = true; public static offlineCompatible = true;
public async run() { public async run() {
this.parse<FlagsDef, {}>(UtilAvailableDrivesCmd); await this.parse(UtilAvailableDrivesCmd);
const sdk = await import('etcher-sdk'); const sdk = await import('etcher-sdk');

View File

@ -15,16 +15,10 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags } from '@oclif/core';
import Command from '../command'; import Command from '../command';
import { stripIndent } from '../utils/lazy'; import { stripIndent } from '../utils/lazy';
interface FlagsDef {
all: boolean;
json: boolean;
help: void;
}
export interface JsonVersions { export interface JsonVersions {
'balena-cli': string; 'balena-cli': string;
'Node.js': string; 'Node.js': string;
@ -59,24 +53,24 @@ export default class VersionCmd extends Command {
public static offlineCompatible = true; public static offlineCompatible = true;
public static flags: flags.Input<FlagsDef> = { public static flags = {
all: flags.boolean({ all: Flags.boolean({
default: false, default: false,
char: 'a', char: 'a',
description: description:
'include version information for additional components (Node.js)', 'include version information for additional components (Node.js)',
}), }),
json: flags.boolean({ json: Flags.boolean({
default: false, default: false,
char: 'j', char: 'j',
description: description:
'output version information in JSON format for programmatic use', 'output version information in JSON format for programmatic use',
}), }),
help: flags.help({ char: 'h' }), help: Flags.help({ char: 'h' }),
}; };
public async run() { public async run() {
const { flags: options } = this.parse<FlagsDef, {}>(VersionCmd); const { flags: options } = await this.parse(VersionCmd);
const versions: JsonVersions = { const versions: JsonVersions = {
'balena-cli': (await import('../../package.json')).version, 'balena-cli': (await import('../../package.json')).version,
'Node.js': 'Node.js':

View File

@ -32,7 +32,7 @@ export default class WhoamiCmd extends Command {
public static authenticated = true; public static authenticated = true;
public async run() { public async run() {
this.parse<{}, {}>(WhoamiCmd); await this.parse(WhoamiCmd);
const balena = getBalenaSdk(); const balena = getBalenaSdk();

View File

@ -15,7 +15,6 @@
* limitations under the License. * limitations under the License.
*/ */
import { Help } from '@oclif/core'; import { Help } from '@oclif/core';
import { HelpFormatter } from '@oclif/core/lib/help/formatter';
import * as indent from 'indent-string'; import * as indent from 'indent-string';
import { getChalk } from './utils/lazy'; import { getChalk } from './utils/lazy';
@ -38,8 +37,6 @@ function getHelpSubject(args: string[]): string | undefined {
} }
export default class BalenaHelp extends Help { export default class BalenaHelp extends Help {
public helpFormatter = new HelpFormatter(this.config);
public static usage: 'help [command]'; public static usage: 'help [command]';
public async showHelp(argv: string[]) { public async showHelp(argv: string[]) {
@ -53,15 +50,20 @@ export default class BalenaHelp extends Help {
const command = this.config.findCommand(subject); const command = this.config.findCommand(subject);
if (command) { if (command) {
await this.showCommandHelp(command); await this.showCommandHelp(await command.load());
return; return;
} }
// If they've typed a topic (e.g. `balena os`) that isn't also a command (e.g. `balena device`) // If they've typed a topic (e.g. `balena os`) that isn't also a command (e.g. `balena device`)
// then list the associated commands. // then list the associated commands.
const topicCommands = this.config.commands.filter((c) => { const topicCommands = await Promise.all(
return c.id.startsWith(`${subject}:`); this.config.commands
}); .filter((c) => {
return c.id.startsWith(`${subject}:`);
})
.map((topic) => topic.load()),
);
if (topicCommands.length > 0) { if (topicCommands.length > 0) {
console.log(`${chalk.yellow(subject)} commands include:`); console.log(`${chalk.yellow(subject)} commands include:`);
console.log(this.formatCommands(topicCommands)); console.log(this.formatCommands(topicCommands));
@ -188,7 +190,7 @@ See: https://git.io/JRHUW#deprecation-policy`,
return ''; return '';
} }
const body = this.helpFormatter.renderList( const body = this.renderList(
commands commands
.filter((c) => c.usage != null && c.usage !== '') .filter((c) => c.usage != null && c.usage !== '')
.map((c) => [c.usage, this.formatDescription(c.description)]), .map((c) => [c.usage, this.formatDescription(c.description)]),

View File

@ -20,6 +20,7 @@ export let unsupportedFlag = false;
export interface AppOptions { export interface AppOptions {
// Prevent the default behavior of flushing stdout after running a command // Prevent the default behavior of flushing stdout after running a command
noFlush?: boolean; noFlush?: boolean;
configPath?: string;
} }
export async function preparseArgs(argv: string[]): Promise<string[]> { export async function preparseArgs(argv: string[]): Promise<string[]> {

View File

@ -14,11 +14,11 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { Args } from '@oclif/core';
import { lowercaseIfSlug } from './normalization'; import { lowercaseIfSlug } from './normalization';
export const fleetRequired = { export const fleetRequired = Args.string({
name: 'fleet',
description: 'fleet name or slug (preferred)', description: 'fleet name or slug (preferred)',
required: true, required: true,
parse: lowercaseIfSlug, parse: lowercaseIfSlug,
}; });

View File

@ -15,72 +15,69 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags } from '@oclif/core';
import { stripIndent } from './lazy'; import { stripIndent } from './lazy';
import { lowercaseIfSlug } from './normalization'; import { lowercaseIfSlug } from './normalization';
import type { IBooleanFlag } from '@oclif/parser/lib/flags'; export const fleet = Flags.string({
import type { DataOutputOptions, DataSetOutputOptions } from '../framework';
export const fleet = flags.string({
char: 'f', char: 'f',
description: 'fleet name or slug (preferred)', description: 'fleet name or slug (preferred)',
parse: lowercaseIfSlug, parse: lowercaseIfSlug,
}); });
export const device = flags.string({ export const device = Flags.string({
char: 'd', char: 'd',
description: 'device UUID', description: 'device UUID',
}); });
export const help: IBooleanFlag<void> = flags.help({ char: 'h' }); export const help = Flags.help({ char: 'h' });
export const quiet: IBooleanFlag<boolean> = flags.boolean({ export const quiet = Flags.boolean({
char: 'q', char: 'q',
description: 'suppress warning messages', description: 'suppress warning messages',
default: false, default: false,
}); });
export const release = flags.string({ export const release = Flags.string({
char: 'r', char: 'r',
description: 'release id', description: 'release id',
}); });
export const service = flags.string({ export const service = Flags.string({
char: 's', char: 's',
description: 'service name', description: 'service name',
}); });
export const verbose: IBooleanFlag<boolean> = flags.boolean({ export const verbose = Flags.boolean({
char: 'v', char: 'v',
description: 'produce verbose output', description: 'produce verbose output',
default: false, default: false,
}); });
export const yes: IBooleanFlag<boolean> = flags.boolean({ export const yes = Flags.boolean({
char: 'y', char: 'y',
description: 'answer "yes" to all questions (non interactive use)', description: 'answer "yes" to all questions (non interactive use)',
default: false, default: false,
}); });
export const force: IBooleanFlag<boolean> = flags.boolean({ export const force = Flags.boolean({
char: 'f', char: 'f',
description: 'force action if the update lock is set', description: 'force action if the update lock is set',
default: false, default: false,
}); });
export const dev: IBooleanFlag<boolean> = flags.boolean({ export const dev = Flags.boolean({
description: 'Configure balenaOS to operate in development mode', description: 'Configure balenaOS to operate in development mode',
default: false, default: false,
}); });
export const secureBoot: IBooleanFlag<boolean> = flags.boolean({ export const secureBoot = Flags.boolean({
description: description:
'Configure balenaOS installer to opt-in secure boot and disk encryption', 'Configure balenaOS installer to opt-in secure boot and disk encryption',
default: false, default: false,
}); });
export const drive = flags.string({ export const drive = Flags.string({
char: 'd', char: 'd',
description: stripIndent` description: stripIndent`
the drive to write the image to, eg. \`/dev/sdb\` or \`/dev/mmcblk0\`. the drive to write the image to, eg. \`/dev/sdb\` or \`/dev/mmcblk0\`.
@ -89,30 +86,30 @@ export const drive = flags.string({
`, `,
}); });
export const driveOrImg = flags.string({ export const driveOrImg = Flags.string({
char: 'd', char: 'd',
description: description:
'path to OS image file (e.g. balena.img) or block device (e.g. /dev/disk2)', 'path to OS image file (e.g. balena.img) or block device (e.g. /dev/disk2)',
}); });
export const deviceType = flags.string({ export const deviceType = Flags.string({
description: description:
'device type (Check available types with `balena devices supported`)', 'device type (Check available types with `balena devices supported`)',
char: 't', char: 't',
required: true, required: true,
}); });
export const json: IBooleanFlag<boolean> = flags.boolean({ export const json = Flags.boolean({
char: 'j', char: 'j',
description: 'produce JSON output instead of tabular output', description: 'produce JSON output instead of tabular output',
default: false, default: false,
}); });
export const dataOutputFlags: flags.Input<DataOutputOptions> = { export const dataOutputFlags = {
fields: flags.string({ fields: Flags.string({
description: 'only show provided fields (comma-separated)', description: 'only show provided fields (comma-separated)',
}), }),
json: flags.boolean({ json: Flags.boolean({
char: 'j', char: 'j',
exclusive: ['no-truncate'], exclusive: ['no-truncate'],
description: 'output in json format', description: 'output in json format',
@ -120,24 +117,23 @@ export const dataOutputFlags: flags.Input<DataOutputOptions> = {
}), }),
}; };
export const dataSetOutputFlags: flags.Input<DataOutputOptions> & export const dataSetOutputFlags = {
flags.Input<DataSetOutputOptions> = {
...dataOutputFlags, ...dataOutputFlags,
filter: flags.string({ filter: Flags.string({
description: description:
'filter results by substring matching of a given field, eg: --filter field=foo', 'filter results by substring matching of a given field, eg: --filter field=foo',
}), }),
'no-header': flags.boolean({ 'no-header': Flags.boolean({
exclusive: ['json'], exclusive: ['json'],
description: 'hide table header from output', description: 'hide table header from output',
default: false, default: false,
}), }),
'no-truncate': flags.boolean({ 'no-truncate': Flags.boolean({
exclusive: ['json'], exclusive: ['json'],
description: 'do not truncate output to fit screen', description: 'do not truncate output to fit screen',
default: false, default: false,
}), }),
sort: flags.string({ sort: Flags.string({
description: `field to sort by (prepend '-' for descending order)`, description: `field to sort by (prepend '-' for descending order)`,
}), }),
}; };

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags } from '@oclif/core';
import { BalenaSDK } from 'balena-sdk'; import { BalenaSDK } from 'balena-sdk';
import type { TransposeOptions } from '@balena/compose/dist/emulate'; import type { TransposeOptions } from '@balena/compose/dist/emulate';
import type * as Dockerode from 'dockerode'; import type * as Dockerode from 'dockerode';
@ -35,7 +35,6 @@ import type { Pack } from 'tar-stream';
import { ExpectedError } from '../errors'; import { ExpectedError } from '../errors';
import { import {
BuiltImage, BuiltImage,
ComposeCliFlags,
ComposeOpts, ComposeOpts,
ComposeProject, ComposeProject,
TaggedImage, TaggedImage,
@ -1643,39 +1642,39 @@ function truncateString(str: string, len: number): string {
return str.slice(0, str.lastIndexOf('\n')); return str.slice(0, str.lastIndexOf('\n'));
} }
export const composeCliFlags: flags.Input<ComposeCliFlags> = { export const composeCliFlags = {
emulated: flags.boolean({ emulated: Flags.boolean({
description: description:
'Use QEMU for ARM architecture emulation during the image build', 'Use QEMU for ARM architecture emulation during the image build',
char: 'e', char: 'e',
}), }),
dockerfile: flags.string({ dockerfile: Flags.string({
description: description:
'Alternative Dockerfile name/path, relative to the source folder', 'Alternative Dockerfile name/path, relative to the source folder',
}), }),
nologs: flags.boolean({ nologs: Flags.boolean({
description: description:
'Hide the image build log output (produce less verbose output)', 'Hide the image build log output (produce less verbose output)',
}), }),
'multi-dockerignore': flags.boolean({ 'multi-dockerignore': Flags.boolean({
description: description:
'Have each service use its own .dockerignore file. See "balena help build".', 'Have each service use its own .dockerignore file. See "balena help build".',
char: 'm', char: 'm',
}), }),
'noparent-check': flags.boolean({ 'noparent-check': Flags.boolean({
description: description:
"Disable project validation check of 'docker-compose.yml' file in parent folder", "Disable project validation check of 'docker-compose.yml' file in parent folder",
}), }),
'registry-secrets': flags.string({ 'registry-secrets': Flags.string({
description: description:
'Path to a YAML or JSON file with passwords for a private Docker registry', 'Path to a YAML or JSON file with passwords for a private Docker registry',
char: 'R', char: 'R',
}), }),
'noconvert-eol': flags.boolean({ 'noconvert-eol': Flags.boolean({
description: description:
"Don't convert line endings from CRLF (Windows format) to LF (Unix format).", "Don't convert line endings from CRLF (Windows format) to LF (Unix format).",
}), }),
projectName: flags.string({ projectName: Flags.string({
description: stripIndent`\ description: stripIndent`\
Name prefix for locally built images. This is the 'projectName' portion Name prefix for locally built images. This is the 'projectName' portion
in 'projectName_serviceName:tag'. The default is the directory name.`, in 'projectName_serviceName:tag'. The default is the directory name.`,

View File

@ -16,7 +16,7 @@
*/ */
import type * as dockerode from 'dockerode'; import type * as dockerode from 'dockerode';
import { flags } from '@oclif/command'; import { Flags } from '@oclif/core';
import { ExpectedError } from '../errors'; import { ExpectedError } from '../errors';
import { parseAsInteger } from './validation'; import { parseAsInteger } from './validation';
@ -43,58 +43,58 @@ export interface DockerCliFlags extends DockerConnectionCliFlags {
squash: boolean; squash: boolean;
} }
export const dockerConnectionCliFlags: flags.Input<DockerConnectionCliFlags> = { export const dockerConnectionCliFlags = {
docker: flags.string({ docker: Flags.string({
description: 'Path to a local docker socket (e.g. /var/run/docker.sock)', description: 'Path to a local docker socket (e.g. /var/run/docker.sock)',
char: 'P', char: 'P',
}), }),
dockerHost: flags.string({ dockerHost: Flags.string({
description: description:
'Docker daemon hostname or IP address (dev machine or balena device) ', 'Docker daemon hostname or IP address (dev machine or balena device) ',
char: 'h', char: 'h',
}), }),
dockerPort: flags.integer({ dockerPort: Flags.integer({
description: description:
'Docker daemon TCP port number (hint: 2375 for balena devices)', 'Docker daemon TCP port number (hint: 2375 for balena devices)',
char: 'p', char: 'p',
parse: (p) => parseAsInteger(p, 'dockerPort'), parse: async (p) => parseAsInteger(p, 'dockerPort'),
}), }),
ca: flags.string({ ca: Flags.string({
description: 'Docker host TLS certificate authority file', description: 'Docker host TLS certificate authority file',
}), }),
cert: flags.string({ cert: Flags.string({
description: 'Docker host TLS certificate file', description: 'Docker host TLS certificate file',
}), }),
key: flags.string({ key: Flags.string({
description: 'Docker host TLS key file', description: 'Docker host TLS key file',
}), }),
}; };
export const dockerCliFlags: flags.Input<DockerCliFlags> = { export const dockerCliFlags = {
tag: flags.string({ tag: Flags.string({
description: `\ description: `\
Tag locally built Docker images. This is the 'tag' portion Tag locally built Docker images. This is the 'tag' portion
in 'projectName_serviceName:tag'. The default is 'latest'.`, in 'projectName_serviceName:tag'. The default is 'latest'.`,
char: 't', char: 't',
}), }),
buildArg: flags.string({ buildArg: Flags.string({
description: description:
'[Deprecated] Set a build-time variable (eg. "-B \'ARG=value\'"). Can be specified multiple times.', '[Deprecated] Set a build-time variable (eg. "-B \'ARG=value\'"). Can be specified multiple times.',
char: 'B', char: 'B',
multiple: true, multiple: true,
}), }),
'cache-from': flags.string({ 'cache-from': Flags.string({
description: `\ description: `\
Comma-separated list (no spaces) of image names for build cache resolution. \ Comma-separated list (no spaces) of image names for build cache resolution. \
Implements the same feature as the "docker build --cache-from" option.`, Implements the same feature as the "docker build --cache-from" option.`,
}), }),
nocache: flags.boolean({ nocache: Flags.boolean({
description: "Don't use docker layer caching when building", description: "Don't use docker layer caching when building",
}), }),
pull: flags.boolean({ pull: Flags.boolean({
description: 'Pull the base images again even if they exist locally', description: 'Pull the base images again even if they exist locally',
}), }),
squash: flags.boolean({ squash: Flags.boolean({
description: 'Squash newly built layers into a single new layer', description: 'Squash newly built layers into a single new layer',
}), }),
...dockerConnectionCliFlags, ...dockerConnectionCliFlags,

View File

@ -15,14 +15,12 @@
* limitations under the License. * limitations under the License.
*/ */
import { flags } from '@oclif/command'; import { Flags } from '@oclif/core';
import { stripIndent } from './lazy'; import { stripIndent } from './lazy';
import { ExpectedError } from '../errors'; import { ExpectedError } from '../errors';
import type { IBooleanFlag } from '@oclif/parser/lib/flags'; export const booleanConfig = Flags.boolean({
export const booleanConfig: IBooleanFlag<boolean> = flags.boolean({
char: 'c', char: 'c',
description: description:
'select a configuration variable (may be used together with the --device option)', 'select a configuration variable (may be used together with the --device option)',
@ -30,13 +28,13 @@ export const booleanConfig: IBooleanFlag<boolean> = flags.boolean({
exclusive: ['service'], exclusive: ['service'],
}); });
export const booleanDevice: IBooleanFlag<boolean> = flags.boolean({ export const booleanDevice = Flags.boolean({
char: 'd', char: 'd',
description: 'select a device-specific variable instead of a fleet variable', description: 'select a device-specific variable instead of a fleet variable',
default: false, default: false,
}); });
export const booleanService: IBooleanFlag<boolean> = flags.boolean({ export const booleanService = Flags.boolean({
char: 's', char: 's',
description: description:
'select a service variable (may be used together with the --device option)', 'select a service variable (may be used together with the --device option)',

View File

@ -98,8 +98,9 @@ export async function runCommand<T>(commandArgs: string[]): Promise<T> {
...commandArgs.slice(2), ...commandArgs.slice(2),
]; ];
} }
const { run } = require('@oclif/command');
return run(commandArgs); const { run } = require('@oclif/core') as typeof import('@oclif/core');
return run(commandArgs) as Promise<T>;
} }
export async function getManifest( export async function getManifest(

View File

@ -78,6 +78,6 @@ export async function disambiguateReleaseParam(
/** /**
* Convert to lowercase if looks like slug * Convert to lowercase if looks like slug
*/ */
export function lowercaseIfSlug(s: string) { export async function lowercaseIfSlug(s: string) {
return s.includes('/') ? s.toLowerCase() : s; return s.includes('/') ? s.toLowerCase() : s;
} }

View File

@ -15,48 +15,29 @@
* limitations under the License. * limitations under the License.
*/ */
import { Main } from '@oclif/command';
import type { Command } from '@oclif/core';
/** /**
* This class is a partial copy-and-paste of * This class is a partial copy-and-paste of
* @oclif/plugin-help/command/CommandHelp, which is used to generate oclif's * @oclif/plugin-help/command/CommandHelp, which is used to generate oclif's
* command help output. * command help output.
*/ */
export class CommandHelp { export class CommandHelp {
constructor(public command: { args?: any[] }) {} constructor(public command: { args?: { [name: string]: any } }) {}
protected arg(arg: Command.Arg.Any): string { protected arg(name: string, required: boolean): string {
const name = arg.name.toUpperCase(); name = name.toUpperCase();
if (arg.required) { if (required) {
return `${name}`; return `${name}`;
} }
return `[${name}]`; return `[${name}]`;
} }
public defaultUsage(): string { public defaultUsage(): string {
return CommandHelp.compact([ const argsObject = this.command.args ?? {};
// this.command.id,
(this.command.args || [])
.filter((a) => !a.hidden)
.map((a) => this.arg(a))
.join(' '),
]).join(' ');
}
public static compact<T>(array: Array<T | undefined>): T[] { return Object.entries(argsObject)
return array.filter((a): a is T => !!a); .filter(([_name, { hidden }]) => !hidden)
} .map(([name, { required }]) => this.arg(name, required))
} .join(' ');
export class CustomMain extends Main {
protected _helpOverride(): boolean {
// Disable oclif's default handler for the 'version' command
if (['-v', '--version', 'version'].includes(this.argv[0])) {
return false;
} else {
return super._helpOverride();
}
} }
} }

View File

@ -105,16 +105,12 @@ export function tryAsInteger(input: string): number | string {
} }
} }
export function parseAsLocalHostnameOrIp(input: string, paramName?: string) { export async function parseAsLocalHostnameOrIp(input: string) {
if (input && !validateLocalHostnameOrIp(input)) { if (input && !validateLocalHostnameOrIp(input)) {
const message = throw new ExpectedError(
paramName == null 'The parameter must be a local hostname or IP address.',
? 'The parameter must be a local hostname or IP address.' );
: `The parameter '${paramName}' must be a local hostname or IP address.`;
throw new ExpectedError(message);
} }
return input; return input;
} }

388
npm-shrinkwrap.json generated
View File

@ -13,7 +13,6 @@
"@balena/compose": "^3.0.2", "@balena/compose": "^3.0.2",
"@balena/dockerignore": "^1.0.2", "@balena/dockerignore": "^1.0.2",
"@balena/es-version": "^1.0.1", "@balena/es-version": "^1.0.1",
"@oclif/command": "^1.8.16",
"@oclif/core": "^2.15.0", "@oclif/core": "^2.15.0",
"@resin.io/valid-email": "^0.1.0", "@resin.io/valid-email": "^0.1.0",
"@sentry/node": "^6.16.1", "@sentry/node": "^6.16.1",
@ -102,7 +101,6 @@
"devDependencies": { "devDependencies": {
"@balena/lint": "^6.2.2", "@balena/lint": "^6.2.2",
"@electron/notarize": "^2.0.0", "@electron/notarize": "^2.0.0",
"@oclif/parser": "^3.8.6",
"@octokit/plugin-throttling": "^3.5.1", "@octokit/plugin-throttling": "^3.5.1",
"@octokit/rest": "^18.6.7", "@octokit/rest": "^18.6.7",
"@types/archiver": "^5.1.1", "@types/archiver": "^5.1.1",
@ -169,7 +167,7 @@
"mocha": "^8.4.0", "mocha": "^8.4.0",
"mock-require": "^3.0.3", "mock-require": "^3.0.3",
"nock": "^13.2.1", "nock": "^13.2.1",
"oclif": "^3.9.1", "oclif": "^3.15.0",
"parse-link-header": "^2.0.0", "parse-link-header": "^2.0.0",
"pkg": "^5.8.1", "pkg": "^5.8.1",
"publish-release": "^1.6.1", "publish-release": "^1.6.1",
@ -2139,43 +2137,6 @@
"url": "https://github.com/chalk/supports-color?sponsor=1" "url": "https://github.com/chalk/supports-color?sponsor=1"
} }
}, },
"node_modules/@oclif/command": {
"version": "1.8.36",
"resolved": "https://registry.npmjs.org/@oclif/command/-/command-1.8.36.tgz",
"integrity": "sha512-/zACSgaYGtAQRzc7HjzrlIs14FuEYAZrMOEwicRoUnZVyRunG4+t5iSEeQu0Xy2bgbCD0U1SP/EdeNZSTXRwjQ==",
"deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
"dependencies": {
"@oclif/config": "^1.18.2",
"@oclif/errors": "^1.3.6",
"@oclif/help": "^1.0.1",
"@oclif/parser": "^3.8.17",
"debug": "^4.1.1",
"semver": "^7.5.4"
},
"engines": {
"node": ">=12.0.0"
},
"peerDependencies": {
"@oclif/config": "^1"
}
},
"node_modules/@oclif/config": {
"version": "1.18.16",
"resolved": "https://registry.npmjs.org/@oclif/config/-/config-1.18.16.tgz",
"integrity": "sha512-VskIxVcN22qJzxRUq+raalq6Q3HUde7sokB7/xk5TqRZGEKRVbFeqdQBxDWwQeudiJEgcNiMvIFbMQ43dY37FA==",
"deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
"dependencies": {
"@oclif/errors": "^1.3.6",
"@oclif/parser": "^3.8.16",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-wsl": "^2.1.1",
"tslib": "^2.6.1"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/@oclif/core": { "node_modules/@oclif/core": {
"version": "2.15.0", "version": "2.15.0",
"resolved": "https://registry.npmjs.org/@oclif/core/-/core-2.15.0.tgz", "resolved": "https://registry.npmjs.org/@oclif/core/-/core-2.15.0.tgz",
@ -2320,179 +2281,13 @@
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
"integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q=="
}, },
"node_modules/@oclif/errors": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/@oclif/errors/-/errors-1.3.6.tgz",
"integrity": "sha512-fYaU4aDceETd89KXP+3cLyg9EHZsLD3RxF2IU9yxahhBpspWjkWi3Dy3bTgcwZ3V47BgxQaGapzJWDM33XIVDQ==",
"deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
"dependencies": {
"clean-stack": "^3.0.0",
"fs-extra": "^8.1",
"indent-string": "^4.0.0",
"strip-ansi": "^6.0.1",
"wrap-ansi": "^7.0.0"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/@oclif/errors/node_modules/fs-extra": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
"dependencies": {
"graceful-fs": "^4.2.0",
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
},
"engines": {
"node": ">=6 <7 || >=8"
}
},
"node_modules/@oclif/errors/node_modules/jsonfile": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
"integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
"optionalDependencies": {
"graceful-fs": "^4.1.6"
}
},
"node_modules/@oclif/errors/node_modules/universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
"engines": {
"node": ">= 4.0.0"
}
},
"node_modules/@oclif/help": {
"version": "1.0.15",
"resolved": "https://registry.npmjs.org/@oclif/help/-/help-1.0.15.tgz",
"integrity": "sha512-Yt8UHoetk/XqohYX76DfdrUYLsPKMc5pgkzsZVHDyBSkLiGRzujVaGZdjr32ckVZU9q3a47IjhWxhip7Dz5W/g==",
"deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
"dependencies": {
"@oclif/config": "1.18.16",
"@oclif/errors": "1.3.6",
"chalk": "^4.1.2",
"indent-string": "^4.0.0",
"lodash": "^4.17.21",
"string-width": "^4.2.0",
"strip-ansi": "^6.0.0",
"widest-line": "^3.1.0",
"wrap-ansi": "^6.2.0"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/@oclif/help/node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/@oclif/help/node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"engines": {
"node": ">=8"
}
},
"node_modules/@oclif/help/node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dependencies": {
"has-flag": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@oclif/help/node_modules/wrap-ansi": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
"dependencies": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@oclif/linewrap": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@oclif/linewrap/-/linewrap-1.0.0.tgz",
"integrity": "sha512-Ups2dShK52xXa8w6iBWLgcjPJWjais6KPJQq3gQ/88AY6BXoTX+MIGFPrWQO1KLMiQfoTpcLnUwloN4brrVUHw=="
},
"node_modules/@oclif/parser": {
"version": "3.8.17",
"resolved": "https://registry.npmjs.org/@oclif/parser/-/parser-3.8.17.tgz",
"integrity": "sha512-l04iSd0xoh/16TGVpXb81Gg3z7tlQGrEup16BrVLsZBK6SEYpYHRJZnM32BwZrHI97ZSFfuSwVlzoo6HdsaK8A==",
"deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
"dependencies": {
"@oclif/errors": "^1.3.6",
"@oclif/linewrap": "^1.0.0",
"chalk": "^4.1.0",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/@oclif/parser/node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/@oclif/parser/node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"engines": {
"node": ">=8"
}
},
"node_modules/@oclif/parser/node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dependencies": {
"has-flag": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@oclif/plugin-help": { "node_modules/@oclif/plugin-help": {
"version": "5.2.17", "version": "5.2.19",
"resolved": "https://registry.npmjs.org/@oclif/plugin-help/-/plugin-help-5.2.17.tgz", "resolved": "https://registry.npmjs.org/@oclif/plugin-help/-/plugin-help-5.2.19.tgz",
"integrity": "sha512-8dhvATZZnkD8uq3etsvbVjjpdxiTqXTPjkMlU8ToQz09DL5BBzYApm65iTHFE0Vn9DPbKcNxX1d8YiF3ilgMOQ==", "integrity": "sha512-gf6/dFtzMJ8RA4ovlBCBGJsZsd4jPXhYWJho+Gh6KmA+Ev9LupoExbE0qT+a2uHJyHEvIg4uX/MBW3qdERD/8g==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@oclif/core": "^2.11.8" "@oclif/core": "^2.15.0"
}, },
"engines": { "engines": {
"node": ">=12.0.0" "node": ">=12.0.0"
@ -14327,9 +14122,9 @@
} }
}, },
"node_modules/oclif": { "node_modules/oclif": {
"version": "3.11.3", "version": "3.15.0",
"resolved": "https://registry.npmjs.org/oclif/-/oclif-3.11.3.tgz", "resolved": "https://registry.npmjs.org/oclif/-/oclif-3.15.0.tgz",
"integrity": "sha512-6bUVTbTflu+IN9UnuIt5S4ba052oqLqsZF6zV2U8bx6ZH+hzgc3aXPTJ5JHU2MbDUg1B9PG5zHAbmvoX7V+16Q==", "integrity": "sha512-iwIjseO6Zuw1X66bN268yVuT6U7Qfwcp4CP4FZ/fd/a81eqQ6CTSCfeInjn/uDhfC/U01KrbNZPIZCMkjWHzxA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@oclif/core": "^2.11.4", "@oclif/core": "^2.11.4",
@ -24758,32 +24553,6 @@
} }
} }
}, },
"@oclif/command": {
"version": "1.8.36",
"resolved": "https://registry.npmjs.org/@oclif/command/-/command-1.8.36.tgz",
"integrity": "sha512-/zACSgaYGtAQRzc7HjzrlIs14FuEYAZrMOEwicRoUnZVyRunG4+t5iSEeQu0Xy2bgbCD0U1SP/EdeNZSTXRwjQ==",
"requires": {
"@oclif/config": "^1.18.2",
"@oclif/errors": "^1.3.6",
"@oclif/help": "^1.0.1",
"@oclif/parser": "^3.8.17",
"debug": "^4.1.1",
"semver": "^7.5.4"
}
},
"@oclif/config": {
"version": "1.18.16",
"resolved": "https://registry.npmjs.org/@oclif/config/-/config-1.18.16.tgz",
"integrity": "sha512-VskIxVcN22qJzxRUq+raalq6Q3HUde7sokB7/xk5TqRZGEKRVbFeqdQBxDWwQeudiJEgcNiMvIFbMQ43dY37FA==",
"requires": {
"@oclif/errors": "^1.3.6",
"@oclif/parser": "^3.8.16",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-wsl": "^2.1.1",
"tslib": "^2.6.1"
}
},
"@oclif/core": { "@oclif/core": {
"version": "2.15.0", "version": "2.15.0",
"resolved": "https://registry.npmjs.org/@oclif/core/-/core-2.15.0.tgz", "resolved": "https://registry.npmjs.org/@oclif/core/-/core-2.15.0.tgz",
@ -24890,140 +24659,13 @@
} }
} }
}, },
"@oclif/errors": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/@oclif/errors/-/errors-1.3.6.tgz",
"integrity": "sha512-fYaU4aDceETd89KXP+3cLyg9EHZsLD3RxF2IU9yxahhBpspWjkWi3Dy3bTgcwZ3V47BgxQaGapzJWDM33XIVDQ==",
"requires": {
"clean-stack": "^3.0.0",
"fs-extra": "^8.1",
"indent-string": "^4.0.0",
"strip-ansi": "^6.0.1",
"wrap-ansi": "^7.0.0"
},
"dependencies": {
"fs-extra": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
"requires": {
"graceful-fs": "^4.2.0",
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
}
},
"jsonfile": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
"integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
"requires": {
"graceful-fs": "^4.1.6"
}
},
"universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
}
}
},
"@oclif/help": {
"version": "1.0.15",
"resolved": "https://registry.npmjs.org/@oclif/help/-/help-1.0.15.tgz",
"integrity": "sha512-Yt8UHoetk/XqohYX76DfdrUYLsPKMc5pgkzsZVHDyBSkLiGRzujVaGZdjr32ckVZU9q3a47IjhWxhip7Dz5W/g==",
"requires": {
"@oclif/config": "1.18.16",
"@oclif/errors": "1.3.6",
"chalk": "^4.1.2",
"indent-string": "^4.0.0",
"lodash": "^4.17.21",
"string-width": "^4.2.0",
"strip-ansi": "^6.0.0",
"widest-line": "^3.1.0",
"wrap-ansi": "^6.2.0"
},
"dependencies": {
"chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"requires": {
"has-flag": "^4.0.0"
}
},
"wrap-ansi": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
"requires": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
}
}
}
},
"@oclif/linewrap": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@oclif/linewrap/-/linewrap-1.0.0.tgz",
"integrity": "sha512-Ups2dShK52xXa8w6iBWLgcjPJWjais6KPJQq3gQ/88AY6BXoTX+MIGFPrWQO1KLMiQfoTpcLnUwloN4brrVUHw=="
},
"@oclif/parser": {
"version": "3.8.17",
"resolved": "https://registry.npmjs.org/@oclif/parser/-/parser-3.8.17.tgz",
"integrity": "sha512-l04iSd0xoh/16TGVpXb81Gg3z7tlQGrEup16BrVLsZBK6SEYpYHRJZnM32BwZrHI97ZSFfuSwVlzoo6HdsaK8A==",
"requires": {
"@oclif/errors": "^1.3.6",
"@oclif/linewrap": "^1.0.0",
"chalk": "^4.1.0",
"tslib": "^2.6.2"
},
"dependencies": {
"chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"requires": {
"has-flag": "^4.0.0"
}
}
}
},
"@oclif/plugin-help": { "@oclif/plugin-help": {
"version": "5.2.17", "version": "5.2.19",
"resolved": "https://registry.npmjs.org/@oclif/plugin-help/-/plugin-help-5.2.17.tgz", "resolved": "https://registry.npmjs.org/@oclif/plugin-help/-/plugin-help-5.2.19.tgz",
"integrity": "sha512-8dhvATZZnkD8uq3etsvbVjjpdxiTqXTPjkMlU8ToQz09DL5BBzYApm65iTHFE0Vn9DPbKcNxX1d8YiF3ilgMOQ==", "integrity": "sha512-gf6/dFtzMJ8RA4ovlBCBGJsZsd4jPXhYWJho+Gh6KmA+Ev9LupoExbE0qT+a2uHJyHEvIg4uX/MBW3qdERD/8g==",
"dev": true, "dev": true,
"requires": { "requires": {
"@oclif/core": "^2.11.8" "@oclif/core": "^2.15.0"
} }
}, },
"@oclif/plugin-not-found": { "@oclif/plugin-not-found": {
@ -34524,9 +34166,9 @@
} }
}, },
"oclif": { "oclif": {
"version": "3.11.3", "version": "3.15.0",
"resolved": "https://registry.npmjs.org/oclif/-/oclif-3.11.3.tgz", "resolved": "https://registry.npmjs.org/oclif/-/oclif-3.15.0.tgz",
"integrity": "sha512-6bUVTbTflu+IN9UnuIt5S4ba052oqLqsZF6zV2U8bx6ZH+hzgc3aXPTJ5JHU2MbDUg1B9PG5zHAbmvoX7V+16Q==", "integrity": "sha512-iwIjseO6Zuw1X66bN268yVuT6U7Qfwcp4CP4FZ/fd/a81eqQ6CTSCfeInjn/uDhfC/U01KrbNZPIZCMkjWHzxA==",
"dev": true, "dev": true,
"requires": { "requires": {
"@oclif/core": "^2.11.4", "@oclif/core": "^2.11.4",

View File

@ -103,6 +103,9 @@
"prerun": "./build/hooks/prerun/track", "prerun": "./build/hooks/prerun/track",
"command_not_found": "./build/hooks/command-not-found/suggest" "command_not_found": "./build/hooks/command-not-found/suggest"
}, },
"additionalHelpFlags": [
"help"
],
"macos": { "macos": {
"identifier": "io.balena.cli", "identifier": "io.balena.cli",
"sign": "Developer ID Installer: Balena Ltd (66H43P8FRG)" "sign": "Developer ID Installer: Balena Ltd (66H43P8FRG)"
@ -111,7 +114,6 @@
"devDependencies": { "devDependencies": {
"@balena/lint": "^6.2.2", "@balena/lint": "^6.2.2",
"@electron/notarize": "^2.0.0", "@electron/notarize": "^2.0.0",
"@oclif/parser": "^3.8.6",
"@octokit/plugin-throttling": "^3.5.1", "@octokit/plugin-throttling": "^3.5.1",
"@octokit/rest": "^18.6.7", "@octokit/rest": "^18.6.7",
"@types/archiver": "^5.1.1", "@types/archiver": "^5.1.1",
@ -178,6 +180,7 @@
"mocha": "^8.4.0", "mocha": "^8.4.0",
"mock-require": "^3.0.3", "mock-require": "^3.0.3",
"nock": "^13.2.1", "nock": "^13.2.1",
"oclif": "^3.15.0",
"parse-link-header": "^2.0.0", "parse-link-header": "^2.0.0",
"pkg": "^5.8.1", "pkg": "^5.8.1",
"publish-release": "^1.6.1", "publish-release": "^1.6.1",
@ -185,14 +188,12 @@
"simple-git": "^3.14.1", "simple-git": "^3.14.1",
"sinon": "^11.1.2", "sinon": "^11.1.2",
"ts-node": "^10.4.0", "ts-node": "^10.4.0",
"oclif": "^3.9.1",
"typescript": "^5.1.3" "typescript": "^5.1.3"
}, },
"dependencies": { "dependencies": {
"@balena/compose": "^3.0.2", "@balena/compose": "^3.0.2",
"@balena/dockerignore": "^1.0.2", "@balena/dockerignore": "^1.0.2",
"@balena/es-version": "^1.0.1", "@balena/es-version": "^1.0.1",
"@oclif/command": "^1.8.16",
"@oclif/core": "^2.15.0", "@oclif/core": "^2.15.0",
"@resin.io/valid-email": "^0.1.0", "@resin.io/valid-email": "^0.1.0",
"@sentry/node": "^6.16.1", "@sentry/node": "^6.16.1",

View File

@ -1,15 +0,0 @@
diff --git a/node_modules/@oclif/config/lib/config.js b/node_modules/@oclif/config/lib/config.js
index aba1da9..830f800 100644
--- a/node_modules/@oclif/config/lib/config.js
+++ b/node_modules/@oclif/config/lib/config.js
@@ -165,7 +165,9 @@ class Config {
debug('runCommand %s %o', id, argv);
const c = this.findCommand(id);
if (!c) {
- await this.runHook('command_not_found', { id });
+ // argv added to command_not_found hook
+ // We should try to upstream this change
+ await this.runHook('command_not_found', { id, argv });
throw new errors_1.CLIError(`command ${id} not found`);
}
const command = c.load();

Some files were not shown because too many files have changed in this diff Show More