Skip to content

Commit

Permalink
feat(dependencies): show only installed package managers in choices (#42
Browse files Browse the repository at this point in the history
)

* feat(dependencies): show only installed package managers in choices

* refactor(dependencies): use execa instead of child_process

* test(dependencies): fix installed package managers detection

now it can check if npm is installed with no issues
  • Loading branch information
6km authored May 29, 2024
1 parent a490d84 commit 8d1e723
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 19 deletions.
24 changes: 8 additions & 16 deletions src/hooks/dependencies.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { cwd } from 'process'
import { execa, execaSync } from 'execa'
import type { ExecaChildProcess } from 'execa'
import { afterAll, describe, expect, it } from 'vitest'
import { checkPackageManagerInstalled } from './dependencies'

let cmdBuffer = ''

Expand All @@ -15,28 +16,19 @@ const packageManagersCommands: { [key: string]: string[] } = {
yarn: 'yarn run bin'.split(' '),
}

const knownPackageManagerNames: string[] = Object.keys(packageManagersCommands)

const packageManagersLockfiles: { [key: string]: string } = {
npm: 'package-lock.json',
bun: 'bun.lockb',
pnpm: 'pnpm-lock.yml',
yarn: 'yarn.lock',
}

const availablePackageManagers = Object.keys(packageManagersCommands).filter(
(p) => {
if (p === 'npm') return true // Skip check for npm because it's most likely here and for some wierd reason, it returns an exitCode of 1 from `npm -h`

let stderr = ''

try {
const { stderr: err } = execaSync(p, ['-h'])
stderr = err
} catch (error) {
stderr = error as string
}

return stderr.length == 0
},
const installedPackageManagerNames = await Promise.all(
knownPackageManagerNames.map(checkPackageManagerInstalled),
).then((results: boolean[]) =>
knownPackageManagerNames.filter((_, index) => results[index]),
)

// Run build to have ./bin
Expand All @@ -49,7 +41,7 @@ describe('dependenciesHook', async () => {
rmSync('bin') // Might be beneficial to remove the bin file
})

describe.each(availablePackageManagers.map((p) => ({ pm: p })))(
describe.each(installedPackageManagerNames.map((p) => ({ pm: p })))(
'$pm',
({ pm }) => {
const proc = execa(
Expand Down
21 changes: 18 additions & 3 deletions src/hooks/dependencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { chdir, exit } from 'process'
import confirm from '@inquirer/confirm'
import select from '@inquirer/select'
import chalk from 'chalk'
import { execa } from 'execa'
import { createSpinner } from 'nanospinner'
import { projectDependenciesHook } from '../hook'

Expand Down Expand Up @@ -42,14 +43,20 @@ const registerInstallationHook = (

if (!installDeps) return

const installedPackageManagerNames = await Promise.all(
knownPackageManagerNames.map(checkPackageManagerInstalled),
).then((results) =>
knownPackageManagerNames.filter((_, index) => results[index]),
)

let packageManager

if (pmArg && knownPackageManagerNames.includes(pmArg)) {
if (pmArg && installedPackageManagerNames.includes(pmArg)) {
packageManager = pmArg
} else {
packageManager = await select({
message: 'Which package manager do you want to use?',
choices: knownPackageManagerNames.map((template: string) => ({
choices: installedPackageManagerNames.map((template: string) => ({
title: template,
value: template,
})),
Expand Down Expand Up @@ -94,4 +101,12 @@ function getCurrentPackageManager(): PackageManager {
return 'npm'
}

export { registerInstallationHook }
function checkPackageManagerInstalled(packageManager: string) {
return new Promise<boolean>((resolve) => {
execa(packageManager, ['--version'])
.then(() => resolve(true))
.catch(() => resolve(false))
})
}

export { registerInstallationHook, checkPackageManagerInstalled }

0 comments on commit 8d1e723

Please sign in to comment.