Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/cli/options/info.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
const info = {
describe: 'show information and versions',
type: 'boolean',
conflicts: ['pin', 'unpin', 'use', 'test', 'alias']
} as const

Expand Down
20 changes: 13 additions & 7 deletions src/cli/swpm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand Down Expand Up @@ -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) {
Expand Down
74 changes: 67 additions & 7 deletions src/flags/info.ts
Original file line number Diff line number Diff line change
@@ -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<CommanderPackage['cmd']> | "swpm" | "node"]: string
}>
}

export const showNoPackageDetected = () => {
console.error(stripIndents`
${chalk.red.bold('Error')}: no Package Manager or Environment Variable was found.
Expand All @@ -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<Info> => {
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`
Expand All @@ -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)
Expand All @@ -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)
}

22 changes: 20 additions & 2 deletions src/helpers/get.test.ts
Original file line number Diff line number Diff line change
@@ -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<typeof import('./files.ts')>('./files.ts')
Expand Down Expand Up @@ -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()
})
})
23 changes: 20 additions & 3 deletions src/helpers/get.ts
Original file line number Diff line number Diff line change
@@ -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'

Expand Down Expand Up @@ -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
}