Skip to content

Commit

Permalink
chore: use package-manager-detector (#227)
Browse files Browse the repository at this point in the history
  • Loading branch information
userquin authored Aug 14, 2024
1 parent a1a2cf2 commit 8133faa
Show file tree
Hide file tree
Showing 12 changed files with 42 additions and 216 deletions.
13 changes: 7 additions & 6 deletions build.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@ import { defineBuildConfig } from 'unbuild'
import fg from 'fast-glob'

export default defineBuildConfig({
entries: [
...fg.sync('src/commands/*.ts').map(i => ({
input: i.slice(0, -3),
name: basename(i).slice(0, -3),
})),
],
entries: fg.sync('src/commands/*.ts').map(i => ({
input: i.slice(0, -3),
name: basename(i).slice(0, -3),
})),
clean: true,
declaration: true,
rollup: {
emitCJS: true,
inlineDependencies: true,
commonjs: {
exclude: ['**/*.d.ts'],
},
},
})
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
},
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
}
Expand Down Expand Up @@ -58,10 +57,10 @@
"bumpp": "^9.4.2",
"eslint": "^9.8.0",
"fast-glob": "^3.3.2",
"find-up": "^6.3.0",
"fs-extra": "^11.2.0",
"fzf": "^0.5.2",
"ini": "^4.1.3",
"package-manager-detector": "^0.1.1",
"picocolors": "^1.0.1",
"taze": "^0.16.3",
"terminal-link": "^3.0.0",
Expand Down
56 changes: 8 additions & 48 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

106 changes: 4 additions & 102 deletions src/agents.ts
Original file line number Diff line number Diff line change
@@ -1,104 +1,6 @@
function npmRun(agent: string) {
return (args: string[]) => {
if (args.length > 1)
return `${agent} run ${args[0]} -- ${args.slice(1).join(' ')}`
else return `${agent} run ${args[0]}`
}
}
import type { Agent, Command } from 'package-manager-detector/agents'
import { AGENTS, COMMANDS, INSTALL_PAGE, LOCKS } from 'package-manager-detector/agents'

const yarn = {
'agent': 'yarn {0}',
'run': 'yarn run {0}',
'install': 'yarn install {0}',
'frozen': 'yarn install --frozen-lockfile',
'global': 'yarn global add {0}',
'add': 'yarn add {0}',
'upgrade': 'yarn upgrade {0}',
'upgrade-interactive': 'yarn upgrade-interactive {0}',
'execute': 'npx {0}',
'uninstall': 'yarn remove {0}',
'global_uninstall': 'yarn global remove {0}',
}
const pnpm = {
'agent': 'pnpm {0}',
'run': 'pnpm run {0}',
'install': 'pnpm i {0}',
'frozen': 'pnpm i --frozen-lockfile',
'global': 'pnpm add -g {0}',
'add': 'pnpm add {0}',
'upgrade': 'pnpm update {0}',
'upgrade-interactive': 'pnpm update -i {0}',
'execute': 'pnpm dlx {0}',
'uninstall': 'pnpm remove {0}',
'global_uninstall': 'pnpm remove --global {0}',
}
const bun = {
'agent': 'bun {0}',
'run': 'bun run {0}',
'install': 'bun install {0}',
'frozen': 'bun install --frozen-lockfile',
'global': 'bun add -g {0}',
'add': 'bun add {0}',
'upgrade': 'bun update {0}',
'upgrade-interactive': 'bun update {0}',
'execute': 'bun x {0}',
'uninstall': 'bun remove {0}',
'global_uninstall': 'bun remove -g {0}',
}
export { AGENTS, COMMANDS, INSTALL_PAGE, LOCKS }

export const AGENTS = {
'npm': {
'agent': 'npm {0}',
'run': npmRun('npm'),
'install': 'npm i {0}',
'frozen': 'npm ci',
'global': 'npm i -g {0}',
'add': 'npm i {0}',
'upgrade': 'npm update {0}',
'upgrade-interactive': null,
'execute': 'npx {0}',
'uninstall': 'npm uninstall {0}',
'global_uninstall': 'npm uninstall -g {0}',
},
'yarn': yarn,
'yarn@berry': {
...yarn,
'frozen': 'yarn install --immutable',
'upgrade': 'yarn up {0}',
'upgrade-interactive': 'yarn up -i {0}',
'execute': 'yarn dlx {0}',
// Yarn 2+ removed 'global', see https://github.com/yarnpkg/berry/issues/821
'global': 'npm i -g {0}',
'global_uninstall': 'npm uninstall -g {0}',
},
'pnpm': pnpm,
// pnpm v6.x or below
'pnpm@6': {
...pnpm,
run: npmRun('pnpm'),
},
'bun': bun,
}

export type Agent = keyof typeof AGENTS
export type Command = keyof typeof AGENTS.npm

export const agents = Object.keys(AGENTS) as Agent[]

// the order here matters, more specific one comes first
export const LOCKS: Record<string, Agent> = {
'bun.lockb': 'bun',
'pnpm-lock.yaml': 'pnpm',
'yarn.lock': 'yarn',
'package-lock.json': 'npm',
'npm-shrinkwrap.json': 'npm',
}

export const INSTALL_PAGE: Record<Agent, string> = {
'bun': 'https://bun.sh',
'pnpm': 'https://pnpm.io/installation',
'pnpm@6': 'https://pnpm.io/6.x/installation',
'yarn': 'https://classic.yarnpkg.com/en/docs/install',
'yarn@berry': 'https://yarnpkg.com/getting-started/install',
'npm': 'https://docs.npmjs.com/cli/v8/configuring-npm/install',
}
export type { Agent, Command }
54 changes: 11 additions & 43 deletions src/detect.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import fs from 'node:fs'
import path from 'node:path'
import process from 'node:process'
import { async as ezspawn } from '@jsdevtools/ez-spawn'
import { findUp } from 'find-up'
import { detect as detectPM } from 'package-manager-detector'
import terminalLink from 'terminal-link'
import prompts from '@posva/prompts'
import type { Agent } from './agents'
import { AGENTS, INSTALL_PAGE, LOCKS } from './agents'
import { INSTALL_PAGE } from './agents'
import { cmdExists } from './utils'

export interface DetectOptions {
Expand All @@ -16,46 +13,17 @@ export interface DetectOptions {
}

export async function detect({ autoInstall, programmatic, cwd }: DetectOptions = {}) {
let agent: Agent | null = null
let version: string | null = null

const lockPath = await findUp(Object.keys(LOCKS), { cwd })
let packageJsonPath: string | undefined

if (lockPath)
packageJsonPath = path.resolve(lockPath, '../package.json')
else
packageJsonPath = await findUp('package.json', { cwd })

// read `packageManager` field in package.json
if (packageJsonPath && fs.existsSync(packageJsonPath)) {
try {
const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'))
if (typeof pkg.packageManager === 'string') {
const [name, ver] = pkg.packageManager.replace(/^\^/, '').split('@')
version = ver
if (name === 'yarn' && Number.parseInt(ver) > 1) {
agent = 'yarn@berry'
// the version in packageManager isn't the actual yarn package version
version = 'berry'
}
else if (name === 'pnpm' && Number.parseInt(ver) < 7) {
agent = 'pnpm@6'
}
else if (name in AGENTS) {
agent = name
}
else if (!programmatic) {
console.warn('[ni] Unknown packageManager:', pkg.packageManager)
}
const pmDetection = await detectPM({
cwd,
onUnknown: (packageManager) => {
if (!programmatic) {
console.warn('[ni] Unknown packageManager:', packageManager)
}
}
catch {}
}
},
})

// detect based on lock
if (!agent && lockPath)
agent = LOCKS[path.basename(lockPath)]
const agent = pmDetection?.agent ?? null
const version = pmDetection?.version ?? null

// auto install
if (agent && !cmdExists(agent.split('@')[0]) && !programmatic) {
Expand Down
Loading

0 comments on commit 8133faa

Please sign in to comment.