feat: allow to link a directory with no manifest (#3695)

close #3691
This commit is contained in:
Zoltan Kochan
2021-08-22 12:00:04 +03:00
committed by GitHub
parent ee589ab9b0
commit 3f0178b4ce
4 changed files with 34 additions and 10 deletions

View File

@@ -0,0 +1,5 @@
---
"@pnpm/local-resolver": minor
---
Allow to link a directory that has no manifest file.

View File

@@ -1,3 +1,5 @@
import { existsSync } from 'fs'
import path from 'path'
import PnpmError from '@pnpm/error'
import gfs from '@pnpm/graceful-fs'
import { readProjectManifestOnly } from '@pnpm/read-project-manifest'
@@ -50,14 +52,22 @@ export default async function resolveLocal (
try {
localDependencyManifest = await readProjectManifestOnly(spec.fetchSpec) as DependencyManifest
} catch (internalErr) {
if (!existsSync(spec.fetchSpec)) {
throw new PnpmError('LINKED_PKG_DIR_NOT_FOUND',
`Could not install from "${spec.fetchSpec}" as it does not exist.`)
}
switch (internalErr.code) {
case 'ENOTDIR': {
throw new PnpmError('NOT_PACKAGE_DIRECTORY',
`Could not install from "${spec.fetchSpec}" as it is not a directory.`)
}
case 'ERR_PNPM_NO_IMPORTER_MANIFEST_FOUND':
case 'ENOENT': {
throw new PnpmError('DIRECTORY_HAS_NO_PACKAGE_JSON',
`Could not install from "${spec.fetchSpec}" as it does not contain a package.json file.`)
localDependencyManifest = {
name: path.basename(spec.fetchSpec),
version: '0.0.0',
}
break
}
default: {
throw internalErr

View File

@@ -98,14 +98,11 @@ test('fail when resolving tarball specified with the link: protocol', async () =
})
test('fail when resolving from not existing directory', async () => {
try {
const wantedDependency = { pref: 'link:./dir-does-not-exist' }
await resolveFromLocal(wantedDependency, { projectDir: __dirname })
fail()
} catch (err) {
expect(err).toBeDefined()
expect(err.code).toEqual('ERR_PNPM_NO_IMPORTER_MANIFEST_FOUND')
}
const wantedDependency = { pref: 'link:./dir-does-not-exist' }
const projectDir = __dirname
await expect(
resolveFromLocal(wantedDependency, { projectDir })
).rejects.toThrow(`Could not install from "${path.join(projectDir, 'dir-does-not-exist')}" as it does not exist.`)
})
test('throw error when the path: protocol is used', async () => {

View File

@@ -47,6 +47,18 @@ test('local file', async () => {
})
})
test('local directory with no package.json', async () => {
const project = prepareEmpty()
await fs.mkdir('pkg')
await fs.writeFile('pkg/index.js', 'hello', 'utf8')
const manifest = await addDependenciesToPackage({}, ['file:./pkg'], await testDefaults())
const expectedSpecs = { pkg: 'link:pkg' }
expect(manifest.dependencies).toStrictEqual(expectedSpecs)
await project.has('pkg')
})
test('local file via link:', async () => {
const project = prepareEmpty()
await copyFixture('local-pkg', path.resolve('..', 'local-pkg'))