From 0926c3c9e961a006687f86f89552c9372d402ed6 Mon Sep 17 00:00:00 2001 From: Yuvaraja Balamurugan Date: Wed, 28 Jul 2021 22:39:32 +0200 Subject: [PATCH 1/6] Add info command to backstage-cli :rocket: Signed-off-by: Yuvaraja Balamurugan --- packages/cli/src/commands/index.ts | 5 +++ packages/cli/src/commands/info.ts | 57 ++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 packages/cli/src/commands/info.ts diff --git a/packages/cli/src/commands/index.ts b/packages/cli/src/commands/index.ts index d21349a4e1..0feff5ad9e 100644 --- a/packages/cli/src/commands/index.ts +++ b/packages/cli/src/commands/index.ts @@ -224,6 +224,11 @@ export function registerCommands(program: CommanderStatic) { .command('create-github-app ') .description('Create new GitHub App in your organization.') .action(lazy(() => import('./create-github-app').then(m => m.default))); + + program + .command('info') + .description('Debug info of dependencies.') + .action(lazy(() => import('./info').then(m => m.default))); } // Wraps an action function so that it always exits and handles errors diff --git a/packages/cli/src/commands/info.ts b/packages/cli/src/commands/info.ts new file mode 100644 index 0000000000..43b3de2c24 --- /dev/null +++ b/packages/cli/src/commands/info.ts @@ -0,0 +1,57 @@ +/* + * Copyright 2020 The Backstage Authors + * + * 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 { promisify } from 'util'; +import { exec } from 'child_process'; +import { version as cliVersion } from '../../package.json'; +import os from 'os'; + +export default async () => { + const promisifiedExec = promisify(exec); + + await new Promise(async () => { + const yarnVersion = await promisifiedExec('yarn --version'); + const npmVersion = await promisifiedExec('npm --version'); + + console.log( + `Operating System - ${os.type}(${os.release}) - ${os.platform}/${os.arch}`, + ); + + console.log('\n------------------\n'); + + console.log('Node.js environment:\n'); + console.log(`Node.js - ${process.version}`); + console.log(`@backstage/cli- ${cliVersion}`); + + console.log('\n------------------\n'); + + console.log('Global environment:\n'); + console.log( + `yarn - ${ + yarnVersion.stderr ? yarnVersion.stderr : yarnVersion.stdout.trim() + }`, + ); + console.log( + `npm - ${ + npmVersion.stderr ? npmVersion.stderr : npmVersion.stdout.trim() + }`, + ); + + // TODO - How to find whether the current repo is a clone or a fork or a create-app generated repo? + + // TODO - How to find actual resolved versions of backstage libraries that the app and backend packages build against? + }); +}; From 09d83321bde204797f68bafd7ffe3ae75bb2f657 Mon Sep 17 00:00:00 2001 From: Yuvaraja Balamurugan Date: Sun, 22 Aug 2021 22:38:51 +0530 Subject: [PATCH 2/6] Use runPlain and add backstage deps output Signed-off-by: Yuvaraja Balamurugan --- packages/cli/src/commands/info.ts | 36 ++++++++++++++++--------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/packages/cli/src/commands/info.ts b/packages/cli/src/commands/info.ts index 43b3de2c24..6c6f692b1f 100644 --- a/packages/cli/src/commands/info.ts +++ b/packages/cli/src/commands/info.ts @@ -14,17 +14,16 @@ * limitations under the License. */ -import { promisify } from 'util'; -import { exec } from 'child_process'; import { version as cliVersion } from '../../package.json'; import os from 'os'; +import { runPlain } from '../lib/run'; +import { paths } from '../lib/paths'; +import { Lockfile } from '../lib/versioning'; export default async () => { - const promisifiedExec = promisify(exec); - await new Promise(async () => { - const yarnVersion = await promisifiedExec('yarn --version'); - const npmVersion = await promisifiedExec('npm --version'); + const yarnVersion = await runPlain('yarn --version'); + const npmVersion = await runPlain('npm --version'); console.log( `Operating System - ${os.type}(${os.release}) - ${os.platform}/${os.arch}`, @@ -39,19 +38,22 @@ export default async () => { console.log('\n------------------\n'); console.log('Global environment:\n'); - console.log( - `yarn - ${ - yarnVersion.stderr ? yarnVersion.stderr : yarnVersion.stdout.trim() - }`, - ); - console.log( - `npm - ${ - npmVersion.stderr ? npmVersion.stderr : npmVersion.stdout.trim() - }`, - ); + console.log(`yarn - ${yarnVersion}`); + console.log(`npm - ${npmVersion}`); // TODO - How to find whether the current repo is a clone or a fork or a create-app generated repo? - // TODO - How to find actual resolved versions of backstage libraries that the app and backend packages build against? + console.log('\n------------------\n'); + + console.log('Backstage deps:\n'); + const lockfilePath = paths.resolveTargetRoot('yarn.lock'); + const lockfile = await Lockfile.load(lockfilePath); + const deps = lockfile.keys(); + + for (const dep of deps) { + if (dep.indexOf('@backstage/') !== -1) { + console.log(dep, lockfile.get(dep)![0].version); + } + } }); }; From 078590b32222ed1238f12deb6e1e090476e43845 Mon Sep 17 00:00:00 2001 From: Yuvaraja Balamurugan Date: Sun, 22 Aug 2021 23:27:52 +0530 Subject: [PATCH 3/6] Add info output for cli type Signed-off-by: Yuvaraja Balamurugan --- packages/cli/src/commands/info.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/cli/src/commands/info.ts b/packages/cli/src/commands/info.ts index 6c6f692b1f..1f74186a2a 100644 --- a/packages/cli/src/commands/info.ts +++ b/packages/cli/src/commands/info.ts @@ -19,6 +19,7 @@ import os from 'os'; import { runPlain } from '../lib/run'; import { paths } from '../lib/paths'; import { Lockfile } from '../lib/versioning'; +import path from 'path'; export default async () => { await new Promise(async () => { @@ -41,7 +42,18 @@ export default async () => { console.log(`yarn - ${yarnVersion}`); console.log(`npm - ${npmVersion}`); - // TODO - How to find whether the current repo is a clone or a fork or a create-app generated repo? + console.log('\n------------------\n'); + + console.log('Backstage CLI type :\n'); + // eslint-disable-next-line no-restricted-syntax + const isLocal = require('fs').existsSync( + path.resolve(__dirname, '../../src'), + ); + console.log( + isLocal + ? 'CLI is running in backstage repo' + : 'CLI is running as a dependency', + ); console.log('\n------------------\n'); From 05c6f8437925487f0226dc98bd5d81249725dea2 Mon Sep 17 00:00:00 2001 From: Yuvaraja Balamurugan Date: Tue, 31 Aug 2021 10:30:06 +0530 Subject: [PATCH 4/6] Change the way backstage cli type is recognised Signed-off-by: Yuvaraja Balamurugan --- packages/cli/src/commands/info.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/cli/src/commands/info.ts b/packages/cli/src/commands/info.ts index 1f74186a2a..6035bbbb02 100644 --- a/packages/cli/src/commands/info.ts +++ b/packages/cli/src/commands/info.ts @@ -46,9 +46,7 @@ export default async () => { console.log('Backstage CLI type :\n'); // eslint-disable-next-line no-restricted-syntax - const isLocal = require('fs').existsSync( - path.resolve(__dirname, '../../src'), - ); + const isLocal = require('fs').existsSync(paths.resolveOwn('./src')); console.log( isLocal ? 'CLI is running in backstage repo' From 07161730ccee8eeccf81b2e72285602d81fd5850 Mon Sep 17 00:00:00 2001 From: Yuvaraja Balamurugan Date: Tue, 31 Aug 2021 10:49:21 +0530 Subject: [PATCH 5/6] Add documentation for info command :book: Signed-off-by: Yuvaraja Balamurugan --- docs/cli/commands.md | 13 +++++++++++++ packages/cli/src/commands/index.ts | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/cli/commands.md b/docs/cli/commands.md index ff61e51c75..b5bb73949e 100644 --- a/docs/cli/commands.md +++ b/docs/cli/commands.md @@ -57,6 +57,7 @@ postpack Restores the changes made by the prepack command create-github-app Create new GitHub App in your organization (experimental) +info Outputs versions of all dependencies for debugging purposes help [command] display help for command ``` @@ -647,3 +648,15 @@ YAML file that can be referenced in the GitHub integration configuration. ```text Usage: backstage-cli create-github-app <github-org> ``` + +## info + +Scope: `root` + +Outputs debug information which is useful when opening an issue. Outputs system +information, node.js and npm versions, CLI version and type (inside backstage +repo or a created app), all `@backstage/*` package dependency versions. + +```text +Usage: backstage-cli info +``` diff --git a/packages/cli/src/commands/index.ts b/packages/cli/src/commands/index.ts index 0feff5ad9e..efade740a3 100644 --- a/packages/cli/src/commands/index.ts +++ b/packages/cli/src/commands/index.ts @@ -227,7 +227,7 @@ export function registerCommands(program: CommanderStatic) { program .command('info') - .description('Debug info of dependencies.') + .description('Debug info of all dependencies.') .action(lazy(() => import('./info').then(m => m.default))); } From 951112c45c5ba4c44e4c474a631f243ae0010024 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 28 Sep 2021 22:48:30 +0200 Subject: [PATCH 6/6] cli: fix build issue and tweak info output format Signed-off-by: Patrik Oldsberg --- docs/cli/commands.md | 2 +- packages/cli/src/commands/index.ts | 2 +- packages/cli/src/commands/info.ts | 45 ++++++++---------------------- 3 files changed, 13 insertions(+), 36 deletions(-) diff --git a/docs/cli/commands.md b/docs/cli/commands.md index b5bb73949e..a27cc62712 100644 --- a/docs/cli/commands.md +++ b/docs/cli/commands.md @@ -57,7 +57,7 @@ postpack Restores the changes made by the prepack command create-github-app Create new GitHub App in your organization (experimental) -info Outputs versions of all dependencies for debugging purposes +info Show helpful information for debugging and reporting bugs help [command] display help for command ``` diff --git a/packages/cli/src/commands/index.ts b/packages/cli/src/commands/index.ts index efade740a3..bcd1509f58 100644 --- a/packages/cli/src/commands/index.ts +++ b/packages/cli/src/commands/index.ts @@ -227,7 +227,7 @@ export function registerCommands(program: CommanderStatic) { program .command('info') - .description('Debug info of all dependencies.') + .description('Show helpful information for debugging and reporting bugs') .action(lazy(() => import('./info').then(m => m.default))); } diff --git a/packages/cli/src/commands/info.ts b/packages/cli/src/commands/info.ts index 6035bbbb02..4042d2cb8e 100644 --- a/packages/cli/src/commands/info.ts +++ b/packages/cli/src/commands/info.ts @@ -19,51 +19,28 @@ import os from 'os'; import { runPlain } from '../lib/run'; import { paths } from '../lib/paths'; import { Lockfile } from '../lib/versioning'; -import path from 'path'; export default async () => { await new Promise(async () => { const yarnVersion = await runPlain('yarn --version'); - const npmVersion = await runPlain('npm --version'); - - console.log( - `Operating System - ${os.type}(${os.release}) - ${os.platform}/${os.arch}`, - ); - - console.log('\n------------------\n'); - - console.log('Node.js environment:\n'); - console.log(`Node.js - ${process.version}`); - console.log(`@backstage/cli- ${cliVersion}`); - - console.log('\n------------------\n'); - - console.log('Global environment:\n'); - console.log(`yarn - ${yarnVersion}`); - console.log(`npm - ${npmVersion}`); - - console.log('\n------------------\n'); - - console.log('Backstage CLI type :\n'); // eslint-disable-next-line no-restricted-syntax const isLocal = require('fs').existsSync(paths.resolveOwn('./src')); - console.log( - isLocal - ? 'CLI is running in backstage repo' - : 'CLI is running as a dependency', - ); - console.log('\n------------------\n'); - - console.log('Backstage deps:\n'); + console.log(`OS: ${os.type} ${os.release} - ${os.platform}/${os.arch}`); + console.log(`node: ${process.version}`); + console.log(`yarn: ${yarnVersion}`); + console.log(`cli: ${cliVersion} (${isLocal ? 'local' : 'installed'})`); + console.log(); + console.log('Dependencies:'); const lockfilePath = paths.resolveTargetRoot('yarn.lock'); const lockfile = await Lockfile.load(lockfilePath); - const deps = lockfile.keys(); + + const deps = [...lockfile.keys()].filter(n => n.startsWith('@backstage/')); + const maxLength = Math.max(...deps.map(d => d.length)); for (const dep of deps) { - if (dep.indexOf('@backstage/') !== -1) { - console.log(dep, lockfile.get(dep)![0].version); - } + const versions = new Set(lockfile.get(dep)!.map(i => i.version)); + console.log(` ${dep.padEnd(maxLength)} ${[...versions].join(', ')}`); } }); };