Skip to content

Commit

Permalink
feat: support to update deps globally installed by pnpm (#79)
Browse files Browse the repository at this point in the history
  • Loading branch information
LoTwT authored Sep 27, 2023
1 parent 883b001 commit 1fdbbe4
Showing 1 changed file with 79 additions and 17 deletions.
96 changes: 79 additions & 17 deletions src/commands/check/checkGlobal.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/* eslint-disable no-console */
import { execa } from 'execa'
import { execa, execaCommand } from 'execa'
import c from 'picocolors'
import prompts from 'prompts'
import { type Agent, getCommand } from '@antfu/ni'
import { createMultiProgressBar } from '../../log'
import type { CheckOptions, PackageMeta, RawDep } from '../../types'
import { dumpDependencies } from '../../io/dependencies'
Expand All @@ -18,26 +19,45 @@ interface NpmOut {
}
}

interface PnpmOut {
path: string
dependencies: {
[name: string]: {
version: string
}
}
}

interface GlobalPackageMeta extends PackageMeta {
agent: Agent
}

export async function checkGlobal(options: CheckOptions) {
let exitCode = 0
let resolvePkgs: PackageMeta[] = []
let resolvePkgs: GlobalPackageMeta[] = []

const globalPkgs = await Promise.all([
loadGlobalNpmPackage(options),
loadGlobalPnpmPackage(options),
])
const pkgs = globalPkgs.flat(1)

const pkg = await loadGlobalPackage(options)
const bars = options.loglevel === 'silent' ? null : createMultiProgressBar()
const depBar = bars?.create(pkg.deps.length, 0, { type: c.green('dep') })

await resolvePackage(
pkg,
options,
() => true,
(_pkgName, name, progress) => depBar?.update(progress, { name }),
)
await Promise.all(pkgs.map(async (pkg) => {
const depBar = bars?.create(pkg.deps.length, 0, { type: c.green(pkg.agent) })
await resolvePackage(
pkg,
options,
() => true,
(_pkgName, name, progress) => depBar?.update(progress, { name }),
)
}))
bars?.stop()

resolvePkgs = [pkg]
resolvePkgs = pkgs

if (options.interactive)
resolvePkgs = await promptInteractive(resolvePkgs, options)
resolvePkgs = await promptInteractive(resolvePkgs, options) as GlobalPackageMeta[]

const { lines, errLines } = renderPackages(resolvePkgs, options)

Expand Down Expand Up @@ -87,13 +107,53 @@ export async function checkGlobal(options: CheckOptions) {
console.log(c.magenta('installing...'))
console.log()

await installPkg(resolvePkgs[0])
for (const pkg of resolvePkgs)
await installPkg(pkg)
}

return exitCode
}

async function loadGlobalPackage(options: CheckOptions): Promise<PackageMeta> {
async function loadGlobalPnpmPackage(options: CheckOptions): Promise<GlobalPackageMeta[]> {
let pnpmStdout

try {
pnpmStdout = (await execa('pnpm', ['ls', '--global', '--depth=0', '--json'], { stdio: 'pipe' })).stdout
}
catch (error) {
return []
}

const pnpmOuts = JSON.parse(pnpmStdout) as PnpmOut[]
const filter = createDependenciesFilter(options.include, options.exclude)

const pkgMetas: GlobalPackageMeta[] = pnpmOuts.map(
pnpmOut =>
Object.entries(pnpmOut.dependencies)
.filter(([_name, i]) => i?.version)
.map(([name, i]) =>
({
name,
currentVersion: `^${i.version}`,
update: filter(name),
source: 'dependencies',
} satisfies RawDep),
))
.map((deps, i) => ({
agent: 'pnpm',
resolved: [],
raw: null,
version: '',
filepath: '',
relative: '',
deps,
name: c.red('pnpm') + c.gray(c.dim(' (global)')) + c.gray(c.dim(` ${pnpmOuts[i].path}`)),
}))

return pkgMetas
}

async function loadGlobalNpmPackage(options: CheckOptions): Promise<GlobalPackageMeta> {
const { stdout } = await execa('npm', ['ls', '--global', '--depth=0', '--json'], { stdio: 'pipe' })
const npmOut = JSON.parse(stdout) as NpmOut
const filter = createDependenciesFilter(options.include, options.exclude)
Expand All @@ -110,6 +170,7 @@ async function loadGlobalPackage(options: CheckOptions): Promise<PackageMeta> {
)

return {
agent: 'npm',
resolved: [],
raw: null,
version: '',
Expand All @@ -120,9 +181,10 @@ async function loadGlobalPackage(options: CheckOptions): Promise<PackageMeta> {
}
}

async function installPkg(pkg: PackageMeta) {
async function installPkg(pkg: GlobalPackageMeta) {
const changes = pkg.resolved.filter(i => i.update)
const dependencies = dumpDependencies(changes, 'dependencies')
const updateArgs = Object.entries(dependencies).map(([name, version]) => `${name}@${version}`)
await execa('npm', ['install', '-g', ...updateArgs], { stdio: 'inherit' })
const installCommand = getCommand(pkg.agent, 'global', [...updateArgs])
await execaCommand(installCommand, { stdio: 'inherit' })
}

0 comments on commit 1fdbbe4

Please sign in to comment.