diff --git a/src/cli/options/info.ts b/src/cli/options/info.ts index 0332c06..e55ef6c 100644 --- a/src/cli/options/info.ts +++ b/src/cli/options/info.ts @@ -1,6 +1,5 @@ const info = { describe: 'show information and versions', - type: 'boolean', conflicts: ['pin', 'unpin', 'use', 'test', 'alias'] } as const diff --git a/src/cli/swpm.ts b/src/cli/swpm.ts index 2d55341..f5f6b3a 100644 --- a/src/cli/swpm.ts +++ b/src/cli/swpm.ts @@ -2,23 +2,23 @@ import yargs from './swpm/config.js' -import prompts from 'prompts' import chalk from 'chalk' import { stripIndent } from 'common-tags' import { exit } from 'node:process' +import prompts from 'prompts' import { autoUpdate } from '../libs/autoUpdate.js' -import { pinPackageManager } from '../flags/pin.js' -import { unpinPackageManager } from '../flags/unpin.js' -import { showNoPackageDetected, showPackageInformation } from '../flags/info.js' import { showCommandAlias } from '../flags/alias.js' +import { showNoPackageDetected, showPackageInformation, showPackageInformationJson, showPackageInformationSelect } from '../flags/info.js' +import { pinPackageManager } from '../flags/pin.js' import { testCommand } from '../flags/test.js' +import { unpinPackageManager } from '../flags/unpin.js' -import { showCommand, runCommand } from '../helpers/cmds.js' -import { setPackageVersion } from '../helpers/set.js' +import { runCommand, showCommand } from '../helpers/cmds.js' import { debug } from '../helpers/debug.js' import { commandVerification } from '../helpers/get.js' +import { setPackageVersion } from '../helpers/set.js' import cmdr from '../translator/commander.js' @@ -73,7 +73,13 @@ if (yargs?.test) { } if (yargs?.info) { - await showPackageInformation(cmdr) + if (yargs.json) { + await showPackageInformationJson(cmdr) + } else if (typeof yargs.info === 'string') { + await showPackageInformationSelect(cmdr, yargs.info) + } else { + await showPackageInformation(cmdr) + } } if (yargs?.alias) { diff --git a/src/flags/info.ts b/src/flags/info.ts index d27c013..77002c4 100644 --- a/src/flags/info.ts +++ b/src/flags/info.ts @@ -1,14 +1,26 @@ -import { exit } from 'node:process' -import { stripIndents } from 'common-tags' import chalk from 'chalk' +import { stripIndents } from 'common-tags' +import { exit } from 'node:process' import { getCommandResult } from '../helpers/cmds.js' +import { commandVerification, get } from '../helpers/get.js' import { getOriginIcon } from '../helpers/icons.js' import { getSwpmInfo } from '../helpers/info.js' -import { commandVerification } from '../helpers/get.js' import type { CommanderPackage } from '../translator/commander.types.js' +type Info = { + _: CommanderPackage['cmd'], + using: CommanderPackage['cmd'], + error: string | null, + ready: boolean, + origin: CommanderPackage['origin'], + volta: boolean, + versions: Partial<{ + [key in NonNullable | "swpm" | "node"]: string + }> +} + export const showNoPackageDetected = () => { console.error(stripIndents` ${chalk.red.bold('Error')}: no Package Manager or Environment Variable was found. @@ -19,14 +31,38 @@ export const showNoPackageDetected = () => { exit(1) } -export const showPackageInformation = async ({ cmd, origin, config, volta }: CommanderPackage) => { +export const getPackageInformation = async ({ cmd, origin, config, volta }: CommanderPackage): Promise => { const nodeVersion = getCommandResult({ command: 'node --version', volta }) - const { version: swpmVersion } = await getSwpmInfo() + const url = config?.url ?? '' + const isInstalled = !!cmd && await commandVerification(cmd) + const packageVersion = isInstalled ? getCommandResult({ command: `${cmd} --version`, volta }) : 'not found' + + const errorNoCmdFound = !cmd && 'No Package Manager or Environment Variable was found.' + const errorCmdNotInstalled = !isInstalled && config?.cmd && url && `Command not installed. Visit ${url} for more information.` + + const output = { + _: cmd, + using: cmd, + error: errorNoCmdFound || errorCmdNotInstalled || null, + ready: !!cmd && isInstalled, + origin, + volta: !!volta, + versions: { + swpm: swpmVersion, + node: nodeVersion?.replace(/v/, ''), + ...(config?.cmd && { [config.cmd]: packageVersion }), + } + } + return output +} +export const renderInfoMessage = async (info: Info, { config }: CommanderPackage) => { const color = config?.color ?? chalk.reset() const url = config?.url ?? '' + const { _: cmd, origin, volta, versions } = info + let message = '' if (cmd) { message += `${chalk.bold('using')}: \t${chalk.hex(color).bold(cmd)} \n` @@ -50,8 +86,8 @@ export const showPackageInformation = async ({ cmd, origin, config, volta }: Com message += ` ${chalk.bold('Versions:')} - ${chalk.hex('#368fb9').bold('s')}${chalk.hex('#4e4e4e').bold('w')}${chalk.hex('#f8ae01').bold('p')}${chalk.hex('#e32e37').bold('m')}: \t${swpmVersion} - ${chalk.hex('#689e65').bold('Node')}: \t${nodeVersion?.replace(/v/, '')} + ${chalk.hex('#368fb9').bold('s')}${chalk.hex('#4e4e4e').bold('w')}${chalk.hex('#f8ae01').bold('p')}${chalk.hex('#e32e37').bold('m')}: \t${versions.swpm} + ${chalk.hex('#689e65').bold('Node')}: \t${versions.node?.replace(/v/, '')} ` const isInstalled = !!cmd && await commandVerification(cmd) @@ -69,6 +105,30 @@ export const showPackageInformation = async ({ cmd, origin, config, volta }: Com } console.log(stripIndents`${message}`) +} + +export const showPackageInformation = async (cmdr: CommanderPackage) => { + const output = await getPackageInformation(cmdr) + await renderInfoMessage(output, cmdr) + exit(0) +} +export const showPackageInformationJson = async (cmdr: CommanderPackage) => { + const output = await getPackageInformation(cmdr) + console.log(JSON.stringify(output, null, 2)) exit(0) } + + + export const showPackageInformationSelect = async (cmdr: CommanderPackage, pick: string) => { + const info = await getPackageInformation(cmdr) + const output = get(info, pick) + if (output) { + console.log(output) + exit (0) + } + console.log(stripIndents`Invalid value - ${pick} doesn't match any available value`) + await renderInfoMessage(info, cmdr) + exit(1) + } + diff --git a/src/helpers/get.test.ts b/src/helpers/get.test.ts index 4d35226..d9c96e6 100644 --- a/src/helpers/get.test.ts +++ b/src/helpers/get.test.ts @@ -1,7 +1,7 @@ -import { it, expect, describe, vi } from 'vitest' -import { commandVerification, detectVoltaPin } from './get' +import { describe, expect, it, vi } from 'vitest' import { CommanderPackage, PackageJson } from '../translator/commander.types' import { getPackageJson } from './files.js' +import { commandVerification, detectVoltaPin, get } from './get' vi.mock('./files.ts', async () => { const mod = await vi.importActual('./files.ts') @@ -83,3 +83,21 @@ describe('detectVoltaPin', () => { expect(isVoltaInstalled && result).toBe(false) }) }) + +describe('get()', () => { + it('should return the selected properties value from a passed object', () => { + const obj = { + a: 1, + b: 2, + c: { + one: 'one', + two: 'two' + } + } + expect(get(obj, 'a')).toBe(1) + expect(get(obj, 'b')).toBe(2) + expect(get(obj, 'c')).toBe(obj.c) + expect(get(obj, 'c.one')).toBe('one') + expect(get(obj, 'd')).toBeUndefined() + }) +}) diff --git a/src/helpers/get.ts b/src/helpers/get.ts index e1267cd..e503156 100644 --- a/src/helpers/get.ts +++ b/src/helpers/get.ts @@ -1,8 +1,8 @@ -import { exit, env } from 'node:process' -import { stripIndents } from 'common-tags' import chalk from 'chalk' -import semver from 'semver' import commandExists from 'command-exists' +import { stripIndents } from 'common-tags' +import { env, exit } from 'node:process' +import semver from 'semver' import { getPackageJson, lockFileExists } from '../helpers/files.js' import packagesList, { packageExists } from '../packages/list.js' @@ -131,3 +131,20 @@ export const commandVerification = async (cmd: PackageManagerList) => { return false } } + +export const get = ( + value: any, + path: string, +): unknown | undefined => { + const segments = path.split(/[\.\[\]]/g) + let current: any = value + for (const key of segments) { + if (current === null) return undefined + if (current === undefined) return undefined + const dequoted = key.replace(/['"]/g, '') + if (dequoted.trim() === '') continue + current = current[dequoted] + } + if (current === undefined) return undefined + return current +}