Skip to content

Commit

Permalink
feat: create licenses-command for PNPM
Browse files Browse the repository at this point in the history
Introduces a new command `licenses`-command which allows to list
the licenses of the packages

refs pnpm#2825
  • Loading branch information
Weyert de Boer authored and zkochan committed Nov 17, 2022
1 parent 1c8bf24 commit adb9999
Show file tree
Hide file tree
Showing 11 changed files with 1,528 additions and 153 deletions.
67 changes: 67 additions & 0 deletions packages/licenses/src/licensesDepsOfProjects.ts
@@ -0,0 +1,67 @@
import path from 'path'
import {
readCurrentLockfile,
readWantedLockfile,
} from '@pnpm/lockfile-file'
import { createMatcher } from '@pnpm/matcher'
import { readModulesManifest } from '@pnpm/modules-yaml'
import {
IncludedDependencies,
ProjectManifest,
Registries,
} from '@pnpm/types'
import unnest from 'ramda/src/unnest'
import { licences, LicensePackage } from './licenses'
import { ClientOptions } from '@pnpm/client'

interface GetManifestOpts {
dir: string
lockfileDir: string
virtualStoreDir: string
rawConfig: object
registries: Registries
}

export type ManifestGetterOptions = Omit<ClientOptions, 'authConfig'>
& GetManifestOpts
& { fullMetadata: boolean, rawConfig: Record<string, string> }

export async function licensesDepsOfProjects (
pkgs: Array<{ dir: string, manifest: ProjectManifest }>,
args: string[],
opts: Omit<ManifestGetterOptions, 'fullMetadata' | 'lockfileDir' | 'virtualStoreDir'> & {
compatible?: boolean
ignoreDependencies?: Set<string>
include: IncludedDependencies
} & Partial<Pick<ManifestGetterOptions, 'fullMetadata' | 'lockfileDir' | 'virtualStoreDir'>>
): Promise<LicensePackage[][]> {
if (!opts.lockfileDir) {
return unnest(await Promise.all(
pkgs.map(async (pkg) => {
return licensesDepsOfProjects([pkg], args, { ...opts, lockfileDir: pkg.dir })
}
)
))
}

const lockfileDir = opts.lockfileDir ?? opts.dir
const modules = await readModulesManifest(path.join(lockfileDir, 'node_modules'))
const virtualStoreDir = modules?.virtualStoreDir ?? path.join(lockfileDir, 'node_modules/.pnpm')
const currentLockfile = await readCurrentLockfile(virtualStoreDir, { ignoreIncompatible: false })
const wantedLockfile = await readWantedLockfile(lockfileDir, { ignoreIncompatible: false }) ?? currentLockfile
return Promise.all(pkgs.map(async ({ dir, manifest }) => {
const match = (args.length > 0) && createMatcher(args) || undefined
return licences({
compatible: opts.compatible,
currentLockfile,
ignoreDependencies: opts.ignoreDependencies,
include: opts.include,
lockfileDir,
manifest,
match,
prefix: dir,
registries: opts.registries,
wantedLockfile,
})
}))
}
56 changes: 56 additions & 0 deletions packages/licenses/test/getManifest.spec.ts
@@ -0,0 +1,56 @@
import { ResolveFunction } from '@pnpm/client'
import { getManifest } from '../lib/createManifestGetter'

test('getManifest()', async () => {
const opts = {
dir: '',
lockfileDir: '',
rawConfig: {},
registries: {
'@scope': 'https://pnpm.io/',
default: 'https://registry.npmjs.org/',
},
}

const resolve: ResolveFunction = async function (wantedPackage, opts) {
expect(opts.registry).toEqual('https://registry.npmjs.org/')
return {
id: 'foo/1.0.0',
latest: '1.0.0',
manifest: {
name: 'foo',
version: '1.0.0',
},
resolution: {
type: 'tarball',
},
resolvedVia: 'npm-registry',
}
}

expect(await getManifest(resolve, opts, 'foo', 'latest')).toStrictEqual({
name: 'foo',
version: '1.0.0',
})

const resolve2: ResolveFunction = async function (wantedPackage, opts) {
expect(opts.registry).toEqual('https://pnpm.io/')
return {
id: 'foo/2.0.0',
latest: '2.0.0',
manifest: {
name: 'foo',
version: '2.0.0',
},
resolution: {
type: 'tarball',
},
resolvedVia: 'npm-registry',
}
}

expect(await getManifest(resolve2, opts, '@scope/foo', 'latest')).toStrictEqual({
name: 'foo',
version: '2.0.0',
})
})

0 comments on commit adb9999

Please sign in to comment.