From 011a634d787611e9c1f2f1b888212525f1fc096d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Nison?= Date: Mon, 3 Dec 2018 13:57:35 +0100 Subject: [PATCH] Implements optional peer dependencies (#6671) * Implements optional peer dependencies * Implements the new peerDependenciesMeta field * Runs prettier * Updates the changelog * Fixes flow --- CHANGELOG.md | 12 ++++++++++++ __tests__/commands/install/integration.js | 16 ++++++++++++++++ .../missing-opt-peer-dep/foo/package.json | 12 ++++++++++++ .../install/missing-opt-peer-dep/package.json | 6 ++++++ .../install/missing-peer-dep/foo/package.json | 7 +++++++ .../install/missing-peer-dep/package.json | 6 ++++++ src/package-linker.js | 10 +++++++++- src/types.js | 17 +++++++++++++++++ 8 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 __tests__/fixtures/install/missing-opt-peer-dep/foo/package.json create mode 100644 __tests__/fixtures/install/missing-opt-peer-dep/package.json create mode 100644 __tests__/fixtures/install/missing-peer-dep/foo/package.json create mode 100644 __tests__/fixtures/install/missing-peer-dep/package.json diff --git a/CHANGELOG.md b/CHANGELOG.md index c0875f0442..5d38f2f349 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ Please add one entry in this file for each change in Yarn's behavior. Use the sa ## Master +- Implements a new `package.json` field: `peerDependenciesMeta` + + [#6671](https://github.com/yarnpkg/yarn/pull/6671) - [**Maël Nison**](https://twitter.com/arcanis) + +- Adds an `optional` settings to `peerDependenciesMeta` to silence missing peer dependency warnings + + [#6671](https://github.com/yarnpkg/yarn/pull/6671) - [**Maël Nison**](https://twitter.com/arcanis) + - Implements `yarn policies set-version [range]`. Check [the documentation]() for usage & tips. [#6673](https://github.com/yarnpkg/yarn/pull/6673) - [**Maël Nison**](https://twitter.com/arcanis) @@ -16,6 +24,10 @@ Please add one entry in this file for each change in Yarn's behavior. Use the sa [#6683](https://github.com/yarnpkg/yarn/issues/6683) - [**Rowan Lonsdale**](https://github.com/hWorblehat) +- Fixes postinstall scripts for third-party packages when they were referencing a binary from their own dependencies + + [#6712](https://github.com/yarnpkg/yarn/pull/6712) - [**Maël Nison**](https://twitter.com/arcanis) + ## 1.12.3 **Important:** This release contains a cache bump. It will cause the very first install following the upgrade to take slightly more time, especially if you don't use the [Offline Mirror](https://yarnpkg.com/blog/2016/11/24/offline-mirror/) feature. After that everything will be back to normal. diff --git a/__tests__/commands/install/integration.js b/__tests__/commands/install/integration.js index cad6455f0e..116f59c4c4 100644 --- a/__tests__/commands/install/integration.js +++ b/__tests__/commands/install/integration.js @@ -1123,3 +1123,19 @@ test('install will not warn for missing peerDep when both shallower and deeper', const warningMessage = messageParts.every(part => stdout.includes(part)); expect(warningMessage).toBe(false); })); + +test('install will warn for missing peer dependencies', () => + runInstall({}, 'missing-peer-dep', (config, reporter, install, getStdout) => { + const stdout = getStdout(); + const messageParts = reporter.lang('unmetPeer', 'undefined').split('undefined'); + const warningMessage = messageParts.every(part => stdout.includes(part)); + expect(warningMessage).toBe(true); + })); + +test('install will not warn for missing optional peer dependencies', () => + runInstall({}, 'missing-opt-peer-dep', (config, reporter, install, getStdout) => { + const stdout = getStdout(); + const messageParts = reporter.lang('unmetPeer', 'undefined').split('undefined'); + const warningMessage = messageParts.every(part => stdout.includes(part)); + expect(warningMessage).toBe(false); + })); diff --git a/__tests__/fixtures/install/missing-opt-peer-dep/foo/package.json b/__tests__/fixtures/install/missing-opt-peer-dep/foo/package.json new file mode 100644 index 0000000000..5ef4d306d0 --- /dev/null +++ b/__tests__/fixtures/install/missing-opt-peer-dep/foo/package.json @@ -0,0 +1,12 @@ +{ + "name": "foo", + "version": "1.0.0", + "peerDependencies": { + "bar": "*" + }, + "peerDependenciesMeta": { + "bar": { + "optional": true + } + } +} diff --git a/__tests__/fixtures/install/missing-opt-peer-dep/package.json b/__tests__/fixtures/install/missing-opt-peer-dep/package.json new file mode 100644 index 0000000000..eb09afab80 --- /dev/null +++ b/__tests__/fixtures/install/missing-opt-peer-dep/package.json @@ -0,0 +1,6 @@ +{ + "name": "missing-peer-dep", + "dependencies": { + "foo": "file:./foo" + } +} diff --git a/__tests__/fixtures/install/missing-peer-dep/foo/package.json b/__tests__/fixtures/install/missing-peer-dep/foo/package.json new file mode 100644 index 0000000000..4eff210f8f --- /dev/null +++ b/__tests__/fixtures/install/missing-peer-dep/foo/package.json @@ -0,0 +1,7 @@ +{ + "name": "foo", + "version": "1.0.0", + "peerDependencies": { + "bar": "*" + } +} diff --git a/__tests__/fixtures/install/missing-peer-dep/package.json b/__tests__/fixtures/install/missing-peer-dep/package.json new file mode 100644 index 0000000000..eb09afab80 --- /dev/null +++ b/__tests__/fixtures/install/missing-peer-dep/package.json @@ -0,0 +1,6 @@ +{ + "name": "missing-peer-dep", + "dependencies": { + "foo": "file:./foo" + } +} diff --git a/src/package-linker.js b/src/package-linker.js index 463a9835ce..66308d2221 100644 --- a/src/package-linker.js +++ b/src/package-linker.js @@ -595,11 +595,15 @@ export default class PackageLinker { resolvePeerModules() { for (const pkg of this.resolver.getManifests()) { const peerDeps = pkg.peerDependencies; + const peerDepsMeta = pkg.peerDependenciesMeta; + if (!peerDeps) { continue; } + const ref = pkg._reference; invariant(ref, 'Package reference is missing'); + // TODO: We are taking the "shortest" ref tree but there may be multiple ref trees with the same length const refTree = ref.requests.map(req => req.parentNames).sort((arr1, arr2) => arr1.length - arr2.length)[0]; @@ -618,6 +622,10 @@ export default class PackageLinker { for (const peerDepName in peerDeps) { const range = peerDeps[peerDepName]; + const meta = peerDepsMeta && peerDepsMeta[peerDepName]; + + const isOptional = !!(meta && meta.optional); + const peerPkgs = this.resolver.getAllInfoForPackageName(peerDepName); let peerError = 'unmetPeer'; @@ -649,7 +657,7 @@ export default class PackageLinker { resolvedPeerPkg.level, ), ); - } else { + } else if (!isOptional) { this.reporter.warn( this.reporter.lang( peerError, diff --git a/src/types.js b/src/types.js index 092e9b20cd..442b54ff7d 100644 --- a/src/types.js +++ b/src/types.js @@ -13,6 +13,20 @@ export type CLIFunction = (config: Config, reporter: Reporter, flags: Object, ar type _CLIFunctionReturn = boolean; export type CLIFunctionReturn = ?_CLIFunctionReturn | Promise; +export type DependencyMeta = {}; + +export type DependenciesMeta = { + [name: string]: DependencyMeta, +}; + +export type PeerDependencyMeta = { + optional?: boolean, +}; + +export type PeerDependenciesMeta = { + [name: string]: PeerDependencyMeta, +}; + // dependency request pattern data structure that's used to request dependencies from a // PackageResolver export type DependencyRequestPattern = { @@ -132,6 +146,9 @@ export type Manifest = { peerDependencies?: Dependencies, optionalDependencies?: Dependencies, + dependenciesMeta?: DependenciesMeta, + peerDependenciesMeta?: PeerDependenciesMeta, + bundleDependencies?: Array, bundledDependencies?: Array,