mirror of
https://github.com/pnpm/pnpm.git
synced 2026-02-02 19:22:52 -05:00
fix: pnpm outdated should work with catalog: protocol (#8304)
* fix: pnpm outdated works with catalog: protocol * test: add has-outdated-deps-using-catalog-protocol fixture * test: add pnpm outdated catalog protocol test * chore: changeset * refactor: outdated --------- Co-authored-by: Zoltan Kochan <z@kochan.io>
This commit is contained in:
7
.changeset/dull-rats-cheer.md
Normal file
7
.changeset/dull-rats-cheer.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"@pnpm/plugin-commands-outdated": patch
|
||||
"@pnpm/outdated": patch
|
||||
pnpm: patch
|
||||
---
|
||||
|
||||
The `pnpm outdated` command now supports the [`catalog:` protocol](https://pnpm.io/catalogs).
|
||||
2
__fixtures__/has-outdated-deps-using-catalog-protocol/.gitignore
vendored
Normal file
2
__fixtures__/has-outdated-deps-using-catalog-protocol/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
!**/node_modules/**/*
|
||||
!/node_modules/
|
||||
@@ -0,0 +1 @@
|
||||
shared-workspace-lockfile=false
|
||||
22
__fixtures__/has-outdated-deps-using-catalog-protocol/node_modules/.modules.yaml
generated
vendored
Normal file
22
__fixtures__/has-outdated-deps-using-catalog-protocol/node_modules/.modules.yaml
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
hoistPattern:
|
||||
- '*'
|
||||
hoistedDependencies: {}
|
||||
included:
|
||||
dependencies: true
|
||||
devDependencies: true
|
||||
optionalDependencies: true
|
||||
injectedDeps: {}
|
||||
layoutVersion: 5
|
||||
nodeLinker: isolated
|
||||
packageManager: pnpm@9.5.0
|
||||
pendingBuilds: []
|
||||
prunedAt: Fri, 12 Jul 2024 05:02:19 GMT
|
||||
publicHoistPattern:
|
||||
- '*eslint*'
|
||||
- '*prettier*'
|
||||
registries:
|
||||
default: https://registry.npmjs.org/
|
||||
skipped: []
|
||||
storeDir: /Users/gluxon/Library/pnpm/store/v3
|
||||
virtualStoreDir: .pnpm
|
||||
virtualStoreDirMaxLength: 120
|
||||
9
__fixtures__/has-outdated-deps-using-catalog-protocol/node_modules/.pnpm/is-negative@1.0.0/node_modules/is-negative/index.js
generated
vendored
Normal file
9
__fixtures__/has-outdated-deps-using-catalog-protocol/node_modules/.pnpm/is-negative@1.0.0/node_modules/is-negative/index.js
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = function (n) {
|
||||
if (typeof n !== 'number') {
|
||||
throw new TypeError('Expected a number');
|
||||
}
|
||||
|
||||
return n < 0;
|
||||
};
|
||||
21
__fixtures__/has-outdated-deps-using-catalog-protocol/node_modules/.pnpm/is-negative@1.0.0/node_modules/is-negative/license
generated
vendored
Normal file
21
__fixtures__/has-outdated-deps-using-catalog-protocol/node_modules/.pnpm/is-negative@1.0.0/node_modules/is-negative/license
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Kevin Martensson <kevinmartensson@gmail.com> (github.com/kevva)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
29
__fixtures__/has-outdated-deps-using-catalog-protocol/node_modules/.pnpm/is-negative@1.0.0/node_modules/is-negative/package.json
generated
vendored
Normal file
29
__fixtures__/has-outdated-deps-using-catalog-protocol/node_modules/.pnpm/is-negative@1.0.0/node_modules/is-negative/package.json
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "is-negative",
|
||||
"version": "1.0.0",
|
||||
"description": "Test if a number is negative",
|
||||
"license": "MIT",
|
||||
"repository": "kevva/is-negative",
|
||||
"author": {
|
||||
"name": "Kevin Martensson",
|
||||
"email": "kevinmartensson@gmail.com",
|
||||
"url": "github.com/kevva"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node test.js"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"keywords": [
|
||||
"negative",
|
||||
"number",
|
||||
"test"
|
||||
],
|
||||
"devDependencies": {
|
||||
"ava": "^0.0.4"
|
||||
}
|
||||
}
|
||||
31
__fixtures__/has-outdated-deps-using-catalog-protocol/node_modules/.pnpm/is-negative@1.0.0/node_modules/is-negative/readme.md
generated
vendored
Normal file
31
__fixtures__/has-outdated-deps-using-catalog-protocol/node_modules/.pnpm/is-negative@1.0.0/node_modules/is-negative/readme.md
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
# is-negative [](https://travis-ci.org/kevva/is-negative)
|
||||
|
||||
> Test if a number is positive
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
$ npm install --save is-negative
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var isNegative = require('is-negative');
|
||||
|
||||
isNegative(-1);
|
||||
//=> true
|
||||
|
||||
isNegative(1);
|
||||
//=> false
|
||||
|
||||
isNegative(0);
|
||||
//=> false
|
||||
```
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Kevin Martensson](http://github.com/kevva)
|
||||
9
__fixtures__/has-outdated-deps-using-catalog-protocol/node_modules/.pnpm/is-negative@1.0.1/node_modules/is-negative/index.js
generated
vendored
Normal file
9
__fixtures__/has-outdated-deps-using-catalog-protocol/node_modules/.pnpm/is-negative@1.0.1/node_modules/is-negative/index.js
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = function (n) {
|
||||
if (typeof n !== 'number') {
|
||||
throw new TypeError('Expected a number');
|
||||
}
|
||||
|
||||
return n < 0;
|
||||
};
|
||||
21
__fixtures__/has-outdated-deps-using-catalog-protocol/node_modules/.pnpm/is-negative@1.0.1/node_modules/is-negative/license
generated
vendored
Normal file
21
__fixtures__/has-outdated-deps-using-catalog-protocol/node_modules/.pnpm/is-negative@1.0.1/node_modules/is-negative/license
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Kevin Martensson <kevinmartensson@gmail.com> (github.com/kevva)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
29
__fixtures__/has-outdated-deps-using-catalog-protocol/node_modules/.pnpm/is-negative@1.0.1/node_modules/is-negative/package.json
generated
vendored
Normal file
29
__fixtures__/has-outdated-deps-using-catalog-protocol/node_modules/.pnpm/is-negative@1.0.1/node_modules/is-negative/package.json
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "is-negative",
|
||||
"version": "1.0.1",
|
||||
"description": "Test if a number is negative",
|
||||
"license": "MIT",
|
||||
"repository": "kevva/is-negative",
|
||||
"author": {
|
||||
"name": "Kevin Martensson",
|
||||
"email": "kevinmartensson@gmail.com",
|
||||
"url": "github.com/kevva"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node test.js"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"keywords": [
|
||||
"negative",
|
||||
"number",
|
||||
"test"
|
||||
],
|
||||
"devDependencies": {
|
||||
"ava": "^0.0.4"
|
||||
}
|
||||
}
|
||||
31
__fixtures__/has-outdated-deps-using-catalog-protocol/node_modules/.pnpm/is-negative@1.0.1/node_modules/is-negative/readme.md
generated
vendored
Normal file
31
__fixtures__/has-outdated-deps-using-catalog-protocol/node_modules/.pnpm/is-negative@1.0.1/node_modules/is-negative/readme.md
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
# is-negative [](https://travis-ci.org/kevva/is-negative)
|
||||
|
||||
> Test if a number is negative
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
$ npm install --save is-negative
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var isNegative = require('is-negative');
|
||||
|
||||
isNegative(-1);
|
||||
//=> true
|
||||
|
||||
isNegative(1);
|
||||
//=> false
|
||||
|
||||
isNegative(0);
|
||||
//=> false
|
||||
```
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Kevin Martensson](http://github.com/kevva)
|
||||
29
__fixtures__/has-outdated-deps-using-catalog-protocol/node_modules/.pnpm/lock.yaml
generated
vendored
Normal file
29
__fixtures__/has-outdated-deps-using-catalog-protocol/node_modules/.pnpm/lock.yaml
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
lockfileVersion: '9.0'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
catalogs:
|
||||
default:
|
||||
is-negative:
|
||||
specifier: ^1.0.0
|
||||
version: 1.0.0
|
||||
|
||||
importers:
|
||||
|
||||
.:
|
||||
dependencies:
|
||||
is-negative:
|
||||
specifier: 'catalog:'
|
||||
version: 1.0.0
|
||||
|
||||
packages:
|
||||
|
||||
is-negative@1.0.0:
|
||||
resolution: {integrity: sha512-1aKMsFUc7vYQGzt//8zhkjRWPoYkajY/I5MJEvrc0pDoHXrW7n5ri8DYxhy3rR+Dk0QFl7GjHHsZU1sppQrWtw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
snapshots:
|
||||
|
||||
is-negative@1.0.0: {}
|
||||
1
__fixtures__/has-outdated-deps-using-catalog-protocol/node_modules/is-negative
generated
vendored
Symbolic link
1
__fixtures__/has-outdated-deps-using-catalog-protocol/node_modules/is-negative
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
.pnpm/is-negative@1.0.0/node_modules/is-negative
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"is-negative": "catalog:"
|
||||
}
|
||||
}
|
||||
29
__fixtures__/has-outdated-deps-using-catalog-protocol/pnpm-lock.yaml
generated
Normal file
29
__fixtures__/has-outdated-deps-using-catalog-protocol/pnpm-lock.yaml
generated
Normal file
@@ -0,0 +1,29 @@
|
||||
lockfileVersion: '9.0'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
catalogs:
|
||||
default:
|
||||
is-negative:
|
||||
specifier: ^1.0.0
|
||||
version: 1.0.0
|
||||
|
||||
importers:
|
||||
|
||||
.:
|
||||
dependencies:
|
||||
is-negative:
|
||||
specifier: 'catalog:'
|
||||
version: 1.0.0
|
||||
|
||||
packages:
|
||||
|
||||
is-negative@1.0.0:
|
||||
resolution: {integrity: sha512-1aKMsFUc7vYQGzt//8zhkjRWPoYkajY/I5MJEvrc0pDoHXrW7n5ri8DYxhy3rR+Dk0QFl7GjHHsZU1sppQrWtw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
snapshots:
|
||||
|
||||
is-negative@1.0.0: {}
|
||||
@@ -0,0 +1,5 @@
|
||||
packages:
|
||||
- '.'
|
||||
|
||||
catalog:
|
||||
is-negative: ^1.0.0
|
||||
6
pnpm-lock.yaml
generated
6
pnpm-lock.yaml
generated
@@ -6228,6 +6228,12 @@ importers:
|
||||
|
||||
reviewing/outdated:
|
||||
dependencies:
|
||||
'@pnpm/catalogs.resolver':
|
||||
specifier: workspace:*
|
||||
version: link:../../catalogs/resolver
|
||||
'@pnpm/catalogs.types':
|
||||
specifier: workspace:*
|
||||
version: link:../../catalogs/types
|
||||
'@pnpm/client':
|
||||
specifier: workspace:*
|
||||
version: link:../../pkg-manager/client
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
"@pnpm/logger": "^5.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@pnpm/catalogs.resolver": "workspace:*",
|
||||
"@pnpm/catalogs.types": "workspace:*",
|
||||
"@pnpm/client": "workspace:*",
|
||||
"@pnpm/constants": "workspace:*",
|
||||
"@pnpm/dependency-path": "workspace:*",
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
import {
|
||||
matchCatalogResolveResult,
|
||||
resolveFromCatalog,
|
||||
type CatalogResolutionFound,
|
||||
type WantedDependency,
|
||||
} from '@pnpm/catalogs.resolver'
|
||||
import { type Catalogs } from '@pnpm/catalogs.types'
|
||||
import { LOCKFILE_VERSION, WANTED_LOCKFILE } from '@pnpm/constants'
|
||||
import { PnpmError } from '@pnpm/error'
|
||||
import {
|
||||
@@ -38,6 +45,7 @@ export interface OutdatedPackage {
|
||||
|
||||
export async function outdated (
|
||||
opts: {
|
||||
catalogs?: Catalogs
|
||||
compatible?: boolean
|
||||
currentLockfile: Lockfile | null
|
||||
getLatestManifest: GetLatestManifestFunction
|
||||
@@ -91,6 +99,8 @@ export async function outdated (
|
||||
pkgs = pkgs.filter((pkgName) => opts.match!(pkgName))
|
||||
}
|
||||
|
||||
const _replaceCatalogProtocolIfNecessary = replaceCatalogProtocolIfNecessary.bind(null, opts.catalogs ?? {})
|
||||
|
||||
await Promise.all(
|
||||
pkgs.map(async (alias) => {
|
||||
if (!allDeps[alias]) return
|
||||
@@ -121,11 +131,12 @@ export async function outdated (
|
||||
const { name: packageName } = nameVerFromPkgSnapshot(relativeDepPath, pkgSnapshot)
|
||||
const name = dp.parse(relativeDepPath).name ?? packageName
|
||||
|
||||
const pref = _replaceCatalogProtocolIfNecessary({ alias, pref: allDeps[alias] })
|
||||
// If the npm resolve parser cannot parse the spec of the dependency,
|
||||
// it means that the package is not from a npm-compatible registry.
|
||||
// In that case, we can't check whether the package is up-to-date
|
||||
if (
|
||||
parsePref(allDeps[alias], alias, 'latest', pickRegistryForPackage(opts.registries, name)) == null
|
||||
parsePref(pref, alias, 'latest', pickRegistryForPackage(opts.registries, name)) == null
|
||||
) {
|
||||
if (current !== wanted) {
|
||||
outdated.push({
|
||||
@@ -190,3 +201,13 @@ function packageHasNoDeps (manifest: ProjectManifest): boolean {
|
||||
function isEmpty (obj: object): boolean {
|
||||
return Object.keys(obj).length === 0
|
||||
}
|
||||
|
||||
function replaceCatalogProtocolIfNecessary (catalogs: Catalogs, wantedDependency: WantedDependency) {
|
||||
return matchCatalogResolveResult(resolveFromCatalog(catalogs, wantedDependency), {
|
||||
unused: () => wantedDependency.pref,
|
||||
found: (found: CatalogResolutionFound) => found.resolution.specifier,
|
||||
misconfiguration: (misconfiguration) => {
|
||||
throw misconfiguration.error
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import path from 'path'
|
||||
import { type Catalogs } from '@pnpm/catalogs.types'
|
||||
import {
|
||||
readCurrentLockfile,
|
||||
readWantedLockfile,
|
||||
@@ -18,6 +19,7 @@ export async function outdatedDepsOfProjects (
|
||||
pkgs: Array<{ rootDir: ProjectRootDir, manifest: ProjectManifest }>,
|
||||
args: string[],
|
||||
opts: Omit<ManifestGetterOptions, 'fullMetadata' | 'lockfileDir'> & {
|
||||
catalogs?: Catalogs
|
||||
compatible?: boolean
|
||||
ignoreDependencies?: string[]
|
||||
include: IncludedDependencies
|
||||
@@ -43,6 +45,7 @@ export async function outdatedDepsOfProjects (
|
||||
return Promise.all(pkgs.map(async ({ rootDir, manifest }): Promise<OutdatedPackage[]> => {
|
||||
const match = (args.length > 0) && createMatcher(args) || undefined
|
||||
return outdated({
|
||||
catalogs: opts.catalogs,
|
||||
compatible: opts.compatible,
|
||||
currentLockfile,
|
||||
getLatestManifest,
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
"../../__typings__/**/*.d.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "../../catalogs/resolver"
|
||||
},
|
||||
{
|
||||
"path": "../../catalogs/types"
|
||||
},
|
||||
{
|
||||
"path": "../../config/matcher"
|
||||
},
|
||||
|
||||
@@ -129,6 +129,7 @@ export type OutdatedCommandOptions = {
|
||||
| 'allProjects'
|
||||
| 'ca'
|
||||
| 'cacheDir'
|
||||
| 'catalogs'
|
||||
| 'cert'
|
||||
| 'dev'
|
||||
| 'dir'
|
||||
|
||||
@@ -17,6 +17,7 @@ const hasNotOutdatedDepsFixture = f.find('has-not-outdated-deps')
|
||||
const hasMajorOutdatedDepsFixture = f.find('has-major-outdated-deps')
|
||||
const hasNoLockfileFixture = f.find('has-no-lockfile')
|
||||
const withPnpmUpdateIgnore = f.find('with-pnpm-update-ignore')
|
||||
const hasOutdatedDepsUsingCatalogProtocol = f.find('has-outdated-deps-using-catalog-protocol')
|
||||
|
||||
const REGISTRY_URL = `http://localhost:${REGISTRY_MOCK_PORT}`
|
||||
|
||||
@@ -386,3 +387,24 @@ test('ignore packages in package.json > pnpm.updateConfig.ignoreDependencies in
|
||||
└─────────────┴─────────┴────────┘
|
||||
`)
|
||||
})
|
||||
|
||||
test('pnpm outdated: catalog protocol', async () => {
|
||||
const { output, exitCode } = await outdated.handler({
|
||||
...OUTDATED_OPTIONS,
|
||||
catalogs: {
|
||||
// Duplicating the catalog config in the pnpm-workspace.yaml inline to
|
||||
// avoid an async read and catalog config normalization call.
|
||||
default: { 'is-negative': '^1.0.0' },
|
||||
},
|
||||
dir: hasOutdatedDepsUsingCatalogProtocol,
|
||||
})
|
||||
|
||||
expect(exitCode).toBe(1)
|
||||
expect(stripAnsi(output)).toBe(`\
|
||||
┌─────────────┬─────────┬────────┐
|
||||
│ Package │ Current │ Latest │
|
||||
├─────────────┼─────────┼────────┤
|
||||
│ is-negative │ 1.0.0 │ 2.1.0 │
|
||||
└─────────────┴─────────┴────────┘
|
||||
`)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user