From bc3fe296243a2e7d49e707b520f923f161205d9d Mon Sep 17 00:00:00 2001 From: Scott Lowe Date: Thu, 2 Apr 2020 15:26:52 +0200 Subject: [PATCH] Convert `internal scandevices`, `internal osinit` to typescript & oclif Change-type: patch Signed-off-by: Scott Lowe --- lib/actions-oclif/internal/osinit.ts | 81 +++++++++++++++++++++++ lib/actions-oclif/internal/scandevices.ts | 46 +++++++++++++ lib/actions/help_ts.ts | 10 +-- lib/actions/index.coffee | 1 - lib/actions/internal.coffee | 54 --------------- lib/app-capitano.coffee | 4 -- lib/preparser.ts | 2 + typings/balena-sync/index.d.ts | 6 ++ typings/capitano/index.d.ts | 1 + 9 files changed, 142 insertions(+), 63 deletions(-) create mode 100644 lib/actions-oclif/internal/osinit.ts create mode 100644 lib/actions-oclif/internal/scandevices.ts delete mode 100644 lib/actions/internal.coffee diff --git a/lib/actions-oclif/internal/osinit.ts b/lib/actions-oclif/internal/osinit.ts new file mode 100644 index 00000000..af657943 --- /dev/null +++ b/lib/actions-oclif/internal/osinit.ts @@ -0,0 +1,81 @@ +/** + * @license + * Copyright 2016-2020 Balena Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { stripIndent } from 'common-tags'; +import Command from '../../command'; +import { CommandHelp } from '../../utils/oclif-utils'; + +// 'Internal' commands are called during the execution of other commands. +// `osinit` is called during `os initialize` +// TODO: These should be refactored to modules/functions, and removed +// See previous `internal sudo` refactor: +// - https://github.com/balena-io/balena-cli/pull/1455/files +// - https://github.com/balena-io/balena-cli/pull/1455#discussion_r334308357 +// - 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 { + public static description = stripIndent` + Do actual init of the device with the preconfigured os image. + + Don't use this command directly! + Use \`balena os initialize \` instead. + `; + + public static args = [ + { + name: 'image', + required: true, + }, + { + name: 'type', + required: true, + }, + { + name: 'config', + required: true, + }, + ]; + + public static usage = ( + 'internal osinit ' + + new CommandHelp({ args: OsinitCmd.args }).defaultUsage() + ).trim(); + + public static hidden = true; + public static root = true; + + public async run() { + const { args: params } = this.parse<{}, ArgsDef>(OsinitCmd); + + const { initialize } = await import('balena-device-init'); + const { getManifest, osProgressHandler } = await import( + '../../utils/helpers' + ); + + const config = JSON.parse(params.config); + const manifest = await getManifest(params.image, params.type); + + const initializeEmitter = await initialize(params.image, manifest, config); + await osProgressHandler(initializeEmitter); + } +} diff --git a/lib/actions-oclif/internal/scandevices.ts b/lib/actions-oclif/internal/scandevices.ts new file mode 100644 index 00000000..00578408 --- /dev/null +++ b/lib/actions-oclif/internal/scandevices.ts @@ -0,0 +1,46 @@ +/** + * @license + * Copyright 2016-2020 Balena Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { stripIndent } from 'common-tags'; +import Command from '../../command'; + +// 'Internal' commands are called during the execution of other commands. +// `scandevices` is called during by `join`,`leave'. +// TODO: These should be refactored to modules/functions, and removed +// See previous `internal sudo` refactor: +// - https://github.com/balena-io/balena-cli/pull/1455/files +// - https://github.com/balena-io/balena-cli/pull/1455#discussion_r334308357 +// - https://github.com/balena-io/balena-cli/pull/1455#discussion_r334308526 + +export default class ScandevicesCmd extends Command { + public static description = stripIndent` + Scan for local balena-enabled devices and show a picker to choose one. + + Don't use this command directly! + `; + + public static usage = 'internal scandevices'; + + public static root = true; + public static hidden = true; + + public async run() { + const { forms } = await import('balena-sync'); + const hostnameOrIp = await forms.selectLocalBalenaOsDevice(); + return console.error(`==> Selected device: ${hostnameOrIp}`); + } +} diff --git a/lib/actions/help_ts.ts b/lib/actions/help_ts.ts index c8c94677..8d3cd3d3 100644 --- a/lib/actions/help_ts.ts +++ b/lib/actions/help_ts.ts @@ -36,10 +36,12 @@ export async function getOclifHelpLinePairs() { const cmdModule = await import(path.join(...pathComponents)); const command: typeof Command = cmdModule.default; - if (command.primary) { - primary.push(getCmdUsageDescriptionLinePair(command)); - } else { - secondary.push(getCmdUsageDescriptionLinePair(command)); + if (!command.hidden) { + if (command.primary) { + primary.push(getCmdUsageDescriptionLinePair(command)); + } else { + secondary.push(getCmdUsageDescriptionLinePair(command)); + } } } diff --git a/lib/actions/index.coffee b/lib/actions/index.coffee index 1cdbfff1..5d885d61 100644 --- a/lib/actions/index.coffee +++ b/lib/actions/index.coffee @@ -28,7 +28,6 @@ module.exports = os: require('./os') config: require('./config') ssh: require('./ssh') - internal: require('./internal') build: require('./build') deploy: require('./deploy') util: require('./util') diff --git a/lib/actions/internal.coffee b/lib/actions/internal.coffee deleted file mode 100644 index 528e8470..00000000 --- a/lib/actions/internal.coffee +++ /dev/null @@ -1,54 +0,0 @@ -### -Copyright 2016-2017 Balena - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -### - -# These are internal commands we want to be runnable from the outside -# One use-case for this is spawning the minimal operation with root priviledges - -exports.osInit = - signature: 'internal osinit ' - description: 'do actual init of the device with the preconfigured os image' - help: ''' - Don't use this command directly! Use `balena os initialize ` instead. - ''' - hidden: true - root: true - action: (params) -> - Promise = require('bluebird') - init = require('balena-device-init') - helpers = require('../utils/helpers') - - configPromise = Promise.try -> JSON.parse(params.config) - manifestPromise = helpers.getManifest(params.image, params.type) - Promise.join configPromise, manifestPromise, (config, manifest) -> - init.initialize(params.image, manifest, config) - .then(helpers.osProgressHandler) - -exports.scanDevices = - signature: 'internal scandevices' - description: 'scan for local balena-enabled devices and show a picker to choose one' - help: ''' - Don't use this command directly! - ''' - hidden: true - root: true - action: -> - Promise = require('bluebird') - { forms } = require('balena-sync') - - return Promise.try -> - forms.selectLocalBalenaOsDevice() - .then (hostnameOrIp) -> - console.error("==> Selected device: #{hostnameOrIp}") diff --git a/lib/app-capitano.coffee b/lib/app-capitano.coffee index 82be2dc2..4bf8b290 100644 --- a/lib/app-capitano.coffee +++ b/lib/app-capitano.coffee @@ -118,10 +118,6 @@ capitano.command(actions.scan) # ---------- Public utils ---------- capitano.command(actions.util.availableDrives) -# ---------- Internal utils ---------- -capitano.command(actions.internal.osInit) -capitano.command(actions.internal.scanDevices) - #------------ Local build and deploy ------- capitano.command(actions.build) capitano.command(actions.deploy) diff --git a/lib/preparser.ts b/lib/preparser.ts index a5e588c4..79c4c034 100644 --- a/lib/preparser.ts +++ b/lib/preparser.ts @@ -131,6 +131,8 @@ export const convertedCommands = [ 'env:add', 'env:rename', 'env:rm', + 'internal:scandevices', + 'internal:osinit', 'note', 'os:configure', 'settings', diff --git a/typings/balena-sync/index.d.ts b/typings/balena-sync/index.d.ts index 6d4c9d3e..7d8af80a 100644 --- a/typings/balena-sync/index.d.ts +++ b/typings/balena-sync/index.d.ts @@ -19,4 +19,10 @@ declare module 'balena-sync' { import { CommandDefinition } from 'capitano'; export function capitano(tool: 'balena-cli'): CommandDefinition; + + declare namespace forms { + export function selectLocalBalenaOsDevice( + timeout?: number, + ): Promise; + } } diff --git a/typings/capitano/index.d.ts b/typings/capitano/index.d.ts index 393f5af4..1a8d21a3 100644 --- a/typings/capitano/index.d.ts +++ b/typings/capitano/index.d.ts @@ -41,6 +41,7 @@ declare module 'capitano' { permission?: 'user'; root?: boolean; primary?: boolean; + hidden?: boolean; action(params: P, options: Partial, done: () => void): void; }