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
LoTwT authored Sep 27, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
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'
@@ -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)

@@ -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)
@@ -110,6 +170,7 @@ async function loadGlobalPackage(options: CheckOptions): Promise<PackageMeta> {
)

return {
agent: 'npm',
resolved: [],
raw: null,
version: '',
@@ -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.