mirror of
https://github.com/pnpm/pnpm.git
synced 2026-05-06 23:19:19 -04:00
feat: copy license files from workspace root when package has none
close #1804
This commit is contained in:
@@ -48,11 +48,13 @@
|
||||
"camelcase-keys": "5.2.0",
|
||||
"chalk": "2.4.2",
|
||||
"common-tags": "1.8.0",
|
||||
"cp-file": "7.0.0",
|
||||
"cross-spawn": "6.0.5",
|
||||
"delay": "4.2.0",
|
||||
"diable": "4.0.2",
|
||||
"dir-is-case-sensitive": "1.0.2",
|
||||
"execa": "1.0.0",
|
||||
"fast-glob": "2.2.6",
|
||||
"find-packages": "5.0.0",
|
||||
"get-port": "5.0.0",
|
||||
"graceful-fs": "4.1.15",
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import readImporterManifest from '@pnpm/read-importer-manifest'
|
||||
import cpFile = require('cp-file')
|
||||
import fg = require('fast-glob')
|
||||
import fs = require('mz/fs')
|
||||
import path = require('path')
|
||||
import rimraf = require('rimraf-then')
|
||||
import writeJsonFile = require('write-json-file')
|
||||
@@ -17,7 +20,7 @@ export default async function (
|
||||
const prefix = args.length && args[0] || process.cwd()
|
||||
|
||||
let _status!: number
|
||||
await fakeRegularManifest(prefix, async () => {
|
||||
await fakeRegularManifest(prefix, opts.workspacePrefix || prefix, async () => {
|
||||
const { status } = await runNpm(['publish', ...opts.argv.original.slice(1)])
|
||||
_status = status
|
||||
})
|
||||
@@ -32,7 +35,7 @@ export async function pack (
|
||||
command: string,
|
||||
) {
|
||||
let _status!: number
|
||||
await fakeRegularManifest(opts.prefix, async () => {
|
||||
await fakeRegularManifest(opts.prefix, opts.workspacePrefix || opts.prefix, async () => {
|
||||
const { status } = await runNpm(['pack', ...opts.argv.original.slice(1)])
|
||||
_status = status
|
||||
})
|
||||
@@ -41,7 +44,15 @@ export async function pack (
|
||||
}
|
||||
}
|
||||
|
||||
async function fakeRegularManifest (prefix: string, fn: () => Promise<void>) {
|
||||
const LICENSE_GLOB = 'LICEN{S,C}E{,.*}'
|
||||
const findLicenses = fg.bind(fg, [LICENSE_GLOB]) as (opts: { cwd: string }) => Promise<string[]>
|
||||
|
||||
async function fakeRegularManifest (prefix: string, workspacePrefix: string, fn: () => Promise<void>) {
|
||||
// If a workspace package has no License of its own,
|
||||
// license files from the root of the workspace are used
|
||||
const copiedLicenses: string[] = prefix !== workspacePrefix && (await findLicenses({ cwd: prefix })).length === 0
|
||||
? await copyLicenses(workspacePrefix, prefix) : []
|
||||
|
||||
const { fileName, manifest, writeImporterManifest } = await readImporterManifest(prefix)
|
||||
const exoticManifestFormat = fileName !== 'package.json'
|
||||
if (exoticManifestFormat) {
|
||||
@@ -53,4 +64,24 @@ async function fakeRegularManifest (prefix: string, fn: () => Promise<void>) {
|
||||
await rimraf(path.join(prefix, 'package.json'))
|
||||
await writeImporterManifest(manifest, true)
|
||||
}
|
||||
await Promise.all(
|
||||
copiedLicenses.map((copiedLicense) => fs.unlink(copiedLicense))
|
||||
)
|
||||
}
|
||||
|
||||
async function copyLicenses (sourceDir: string, destDir: string) {
|
||||
const licenses = await findLicenses({ cwd: sourceDir })
|
||||
if (licenses.length === 0) return []
|
||||
|
||||
const copiedLicenses: string[] = []
|
||||
await Promise.all(
|
||||
licenses
|
||||
.map((licenseRelPath) => path.join(sourceDir, licenseRelPath))
|
||||
.map((licensePath) => {
|
||||
const licenseCopyDest = path.join(destDir, path.basename(licensePath))
|
||||
copiedLicenses.push(licenseCopyDest)
|
||||
return cpFile(licensePath, licenseCopyDest)
|
||||
})
|
||||
)
|
||||
return copiedLicenses
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import prepare from '@pnpm/prepare'
|
||||
import prepare, { preparePackages } from '@pnpm/prepare'
|
||||
import fs = require('mz/fs')
|
||||
import exists = require('path-exists')
|
||||
import tape = require('tape')
|
||||
import promisifyTape from 'tape-promise'
|
||||
import writeYamlFile = require('write-yaml-file')
|
||||
import { execPnpm } from './utils'
|
||||
|
||||
const test = promisifyTape(tape)
|
||||
@@ -59,3 +61,79 @@ test('publish: package with package.json5 running publish from different folder'
|
||||
t.ok(await exists('project/package.json5'))
|
||||
t.notOk(await exists('project/package.json'))
|
||||
})
|
||||
|
||||
test('pack packages with workspace LICENSE if no own LICENSE is present', async (t: tape.Test) => {
|
||||
preparePackages(t, [
|
||||
{
|
||||
name: 'project-1',
|
||||
version: '1.0.0',
|
||||
},
|
||||
{
|
||||
name: 'project-2',
|
||||
version: '1.0.0',
|
||||
},
|
||||
{
|
||||
name: 'target',
|
||||
version: '1.0.0',
|
||||
},
|
||||
], { manifestFormat: 'YAML' })
|
||||
|
||||
await writeYamlFile('pnpm-workspace.yaml', { packages: ['**', '!store/**'] })
|
||||
await fs.writeFile('LICENSE', 'workspace license', 'utf8')
|
||||
await fs.writeFile('project-2/LICENSE', 'project-2 license', 'utf8')
|
||||
|
||||
process.chdir('project-1')
|
||||
await execPnpm('pack')
|
||||
|
||||
process.chdir('../project-2')
|
||||
await execPnpm('pack')
|
||||
|
||||
process.chdir('../target')
|
||||
|
||||
await execPnpm('add', '../project-1/project-1-1.0.0.tgz', '../project-2/project-2-1.0.0.tgz')
|
||||
|
||||
t.equal(await fs.readFile('node_modules/project-1/LICENSE', 'utf8'), 'workspace license')
|
||||
t.equal(await fs.readFile('node_modules/project-2/LICENSE', 'utf8'), 'project-2 license')
|
||||
|
||||
process.chdir('..')
|
||||
t.notOk(await exists('project-1/LICENSE'))
|
||||
t.ok(await exists('project-2/LICENSE'))
|
||||
})
|
||||
|
||||
test('publish packages with workspace LICENSE if no own LICENSE is present', async (t: tape.Test) => {
|
||||
preparePackages(t, [
|
||||
{
|
||||
name: 'project-100',
|
||||
version: '1.0.0',
|
||||
},
|
||||
{
|
||||
name: 'project-200',
|
||||
version: '1.0.0',
|
||||
},
|
||||
{
|
||||
name: 'target',
|
||||
version: '1.0.0',
|
||||
},
|
||||
], { manifestFormat: 'YAML' })
|
||||
|
||||
await writeYamlFile('pnpm-workspace.yaml', { packages: ['**', '!store/**'] })
|
||||
await fs.writeFile('LICENSE', 'workspace license', 'utf8')
|
||||
await fs.writeFile('project-200/LICENSE', 'project-200 license', 'utf8')
|
||||
|
||||
process.chdir('project-100')
|
||||
await execPnpm('publish', ...CREDENTIALS)
|
||||
|
||||
process.chdir('../project-200')
|
||||
await execPnpm('publish', ...CREDENTIALS)
|
||||
|
||||
process.chdir('../target')
|
||||
|
||||
await execPnpm('add', 'project-100', 'project-200', '--no-link-workspace-packages')
|
||||
|
||||
t.equal(await fs.readFile('node_modules/project-100/LICENSE', 'utf8'), 'workspace license')
|
||||
t.equal(await fs.readFile('node_modules/project-200/LICENSE', 'utf8'), 'project-200 license')
|
||||
|
||||
process.chdir('..')
|
||||
t.notOk(await exists('project-100/LICENSE'))
|
||||
t.ok(await exists('project-200/LICENSE'))
|
||||
})
|
||||
|
||||
43
pnpm-lock.yaml
generated
43
pnpm-lock.yaml
generated
@@ -1412,11 +1412,13 @@ importers:
|
||||
camelcase-keys: 5.2.0
|
||||
chalk: 2.4.2
|
||||
common-tags: 1.8.0
|
||||
cp-file: 7.0.0
|
||||
cross-spawn: 6.0.5
|
||||
delay: 4.2.0
|
||||
diable: 4.0.2
|
||||
dir-is-case-sensitive: 1.0.2
|
||||
execa: 1.0.0
|
||||
fast-glob: 2.2.6
|
||||
find-packages: 'link:../find-packages'
|
||||
get-port: 5.0.0
|
||||
graceful-fs: 4.1.15
|
||||
@@ -1540,6 +1542,7 @@ importers:
|
||||
camelcase-keys: 5.2.0
|
||||
chalk: 2.4.2
|
||||
common-tags: 1.8.0
|
||||
cp-file: 7.0.0
|
||||
cross-spawn: 6.0.5
|
||||
deep-require-cwd: 1.0.0
|
||||
delay: 4.2.0
|
||||
@@ -1547,6 +1550,7 @@ importers:
|
||||
dir-is-case-sensitive: 1.0.2
|
||||
execa: 1.0.0
|
||||
exists-link: 2.0.0
|
||||
fast-glob: 2.2.6
|
||||
find-packages: 5.0.0
|
||||
get-port: 5.0.0
|
||||
graceful-fs: 4.1.15
|
||||
@@ -4467,6 +4471,17 @@ packages:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha512-16ZvhVjVhEP75sMflsPtXcwbly+79os1zhBVcpRWNmnwifEbZChW+0URYING/A2ehBwp8i0pOXJYzdpiGO3Ivw==
|
||||
/cp-file/7.0.0:
|
||||
dependencies:
|
||||
graceful-fs: 4.1.15
|
||||
make-dir: 3.0.0
|
||||
nested-error-stacks: 2.1.0
|
||||
p-event: 4.1.0
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=8'
|
||||
resolution:
|
||||
integrity: sha512-0Cbj7gyvFVApzpK/uhCtQ/9kE9UnYpxMzaq5nQQC/Dh4iaj5fxp7iEFIullrYwzj8nf0qnsI1Qsx34hAeAebvw==
|
||||
/cpr/3.0.1:
|
||||
dependencies:
|
||||
graceful-fs: 4.1.15
|
||||
@@ -6811,6 +6826,14 @@ packages:
|
||||
node: '>=6'
|
||||
resolution:
|
||||
integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==
|
||||
/make-dir/3.0.0:
|
||||
dependencies:
|
||||
semver: 6.0.0
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=8'
|
||||
resolution:
|
||||
integrity: sha512-grNJDhb8b1Jm1qeqW5R/O63wUo4UXo2v2HMic6YT9i/HBlF93S8jkMgH7yugvY9ABDShH4VZMn8I+U8+fCNegw==
|
||||
/make-error/1.3.5:
|
||||
dev: true
|
||||
resolution:
|
||||
@@ -7434,6 +7457,10 @@ packages:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-5tq3/r9a2Bbqgc9cYpxaDr3nLBo=
|
||||
/nested-error-stacks/2.1.0:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==
|
||||
/next-path/1.0.0:
|
||||
engines:
|
||||
node: '>=6'
|
||||
@@ -7794,6 +7821,14 @@ packages:
|
||||
node: '>=4'
|
||||
resolution:
|
||||
integrity: sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=
|
||||
/p-event/4.1.0:
|
||||
dependencies:
|
||||
p-timeout: 2.0.1
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=8'
|
||||
resolution:
|
||||
integrity: sha512-4vAd06GCsgflX4wHN1JqrMzBh/8QZ4j+rzp0cd2scXRwuBEv+QR3wrVA5aLhWDLw4y2WgDKvzWF3CCLmVM1UgA==
|
||||
/p-every/2.0.0:
|
||||
dependencies:
|
||||
p-map: 2.1.0
|
||||
@@ -7880,6 +7915,14 @@ packages:
|
||||
node: '>=8'
|
||||
resolution:
|
||||
integrity: sha512-MF/HIbq6GeBqTrTIl5OJubzkGU+qfFhAFi0gnTAK6rgEIJIknEiABHOTtQu4e6JiXjIwuMPMUFQzyHh5QjCl1g==
|
||||
/p-timeout/2.0.1:
|
||||
dependencies:
|
||||
p-finally: 1.0.0
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=4'
|
||||
resolution:
|
||||
integrity: sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==
|
||||
/p-try/1.0.0:
|
||||
dev: true
|
||||
engines:
|
||||
|
||||
Reference in New Issue
Block a user