Skip to content

Commit

Permalink
fix(matcher): should ignore successfully with multiple ignore patterns (
Browse files Browse the repository at this point in the history
#5643)

Co-authored-by: Zoltan Kochan <z@kochan.io>
  • Loading branch information
await-ovo and zkochan committed Nov 17, 2022
1 parent eb6ccbb commit 969f8a0
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 7 deletions.
6 changes: 6 additions & 0 deletions .changeset/curly-penguins-perform.md
@@ -0,0 +1,6 @@
---
"@pnpm/plugin-commands-installation": patch
"pnpm": patch
---

`pnpm update --latest !foo` should not update anything if the only dependency in the project is the ignored one [#5643](https://github.com/pnpm/pnpm/pull/5643).
6 changes: 6 additions & 0 deletions .changeset/weak-spies-thank.md
@@ -0,0 +1,6 @@
---
"@pnpm/matcher": patch
"pnpm": patch
---

The `pnpm.updateConfig.ignoreDependencies` setting should work with multiple dependencies in the array [#5639](https://github.com/pnpm/pnpm/issues/5639).
11 changes: 9 additions & 2 deletions packages/matcher/src/index.ts
Expand Up @@ -20,17 +20,22 @@ export function createMatcherWithIndex (patterns: string[]): MatcherWithIndex {
}
const matchArr: MatcherFunction[] = []
let hasIgnore = false
let hasInclude = false
for (const pattern of patterns) {
if (isIgnorePattern(pattern)) {
hasIgnore = true
matchArr.push({ ignore: true, match: matcherFromPattern(pattern.substring(1)) })
} else {
hasInclude = true
matchArr.push({ ignore: false, match: matcherFromPattern(pattern) })
}
}
if (!hasIgnore) {
return matchInputWithNonIgnoreMatchers.bind(null, matchArr)
}
if (!hasInclude) {
return matchInputWithoutIgnoreMatchers.bind(null, matchArr)
}
return matchInputWithMatchersArray.bind(null, matchArr)
}

Expand All @@ -41,15 +46,17 @@ function matchInputWithNonIgnoreMatchers (matchArr: MatcherFunction[], input: st
return -1
}

function matchInputWithoutIgnoreMatchers (matchArr: MatcherFunction[], input: string): number {
return matchArr.some(({ match }) => match(input)) ? -1 : 0
}

function matchInputWithMatchersArray (matchArr: MatcherFunction[], input: string): number {
let matchedPatternIndex = -1
for (let i = 0; i < matchArr.length; i++) {
const { ignore, match } = matchArr[i]
if (ignore) {
if (match(input)) {
matchedPatternIndex = -1
} else if (matchedPatternIndex === -1) {
matchedPatternIndex = i
}
} else if (matchedPatternIndex === -1 && match(input)) {
matchedPatternIndex = i
Expand Down
14 changes: 13 additions & 1 deletion packages/matcher/test/index.ts
Expand Up @@ -85,7 +85,7 @@ test('createMatcherWithIndex()', () => {
}
{
const match = createMatcherWithIndex(['!eslint-plugin-bar', 'eslint-*'])
expect(match('eslint-plugin-foo')).toBe(0)
expect(match('eslint-plugin-foo')).toBe(1)
expect(match('eslint-plugin-bar')).toBe(1)
}
{
Expand All @@ -98,4 +98,16 @@ test('createMatcherWithIndex()', () => {
const match = createMatcherWithIndex(['!@pnpm.e2e/peer-*'])
expect(match('@pnpm.e2e/foo')).toBe(0)
}
{
const match = createMatcherWithIndex(['!foo', '!bar'])
expect(match('foo')).toBe(-1)
expect(match('bar')).toBe(-1)
expect(match('baz')).toBe(0)
}
{
const match = createMatcherWithIndex(['!foo', '!bar', 'qar'])
expect(match('foo')).toBe(-1)
expect(match('bar')).toBe(-1)
expect(match('baz')).toBe(-1)
}
})
9 changes: 6 additions & 3 deletions packages/plugin-commands-installation/src/installDeps.ts
Expand Up @@ -214,9 +214,12 @@ when running add/update with the --workspace option')
}
if (updateMatch != null) {
params = matchDependencies(updateMatch, manifest, includeDirect)
if (params.length === 0 && opts.depth === 0) {
throw new PnpmError('NO_PACKAGE_IN_DEPENDENCIES',
'None of the specified packages were found in the dependencies.')
if (params.length === 0) {
if (opts.latest) return
if (opts.depth === 0) {
throw new PnpmError('NO_PACKAGE_IN_DEPENDENCIES',
'None of the specified packages were found in the dependencies.')
}
}
}

Expand Down
39 changes: 38 additions & 1 deletion packages/plugin-commands-installation/test/update/update.ts
Expand Up @@ -217,16 +217,19 @@ test('update should work normal when set empty string version', async () => {
test('ignore packages in package.json > updateConfig.ignoreDependencies fields in update command', async () => {
await addDistTag({ package: '@pnpm.e2e/foo', version: '100.0.0', distTag: 'latest' })
await addDistTag({ package: '@pnpm.e2e/bar', version: '100.0.0', distTag: 'latest' })
await addDistTag({ package: '@pnpm.e2e/qar', version: '100.0.0', distTag: 'latest' })

const project = prepare({
dependencies: {
'@pnpm.e2e/foo': '100.0.0',
'@pnpm.e2e/bar': '100.0.0',
'@pnpm.e2e/qar': '100.0.0',
},
pnpm: {
updateConfig: {
ignoreDependencies: [
'@pnpm.e2e/foo',
'@pnpm.e2e/bar',
],
},
},
Expand All @@ -241,9 +244,11 @@ test('ignore packages in package.json > updateConfig.ignoreDependencies fields i

expect(lockfile.packages['/@pnpm.e2e/foo/100.0.0']).toBeTruthy()
expect(lockfile.packages['/@pnpm.e2e/bar/100.0.0']).toBeTruthy()
expect(lockfile.packages['/@pnpm.e2e/qar/100.0.0']).toBeTruthy()

await addDistTag({ package: '@pnpm.e2e/foo', version: '100.1.0', distTag: 'latest' })
await addDistTag({ package: '@pnpm.e2e/bar', version: '100.1.0', distTag: 'latest' })
await addDistTag({ package: '@pnpm.e2e/qar', version: '100.1.0', distTag: 'latest' })

await update.handler({
...DEFAULT_OPTS,
Expand All @@ -254,7 +259,8 @@ test('ignore packages in package.json > updateConfig.ignoreDependencies fields i
const lockfileUpdated = await project.readLockfile()

expect(lockfileUpdated.packages['/@pnpm.e2e/foo/100.0.0']).toBeTruthy()
expect(lockfileUpdated.packages['/@pnpm.e2e/bar/100.1.0']).toBeTruthy()
expect(lockfileUpdated.packages['/@pnpm.e2e/bar/100.0.0']).toBeTruthy()
expect(lockfileUpdated.packages['/@pnpm.e2e/qar/100.1.0']).toBeTruthy()
})

test('not ignore packages if these are specified in parameter even if these are listed in package.json > pnpm.update.ignoreDependencies fields in update command', async () => {
Expand Down Expand Up @@ -298,3 +304,34 @@ test('not ignore packages if these are specified in parameter even if these are
expect(lockfileUpdated.packages['/@pnpm.e2e/foo/100.1.0']).toBeTruthy()
expect(lockfileUpdated.packages['/@pnpm.e2e/bar/100.1.0']).toBeTruthy()
})

test('do not update anything if all the dependencies are ignored and trying to update to latest', async () => {
await addDistTag({ package: '@pnpm.e2e/foo', version: '100.1.0', distTag: 'latest' })

const project = prepare({
dependencies: {
'@pnpm.e2e/foo': '100.0.0',
},
pnpm: {
updateConfig: {
ignoreDependencies: [
'@pnpm.e2e/foo',
],
},
},
})

await install.handler({
...DEFAULT_OPTS,
dir: process.cwd(),
})

await update.handler({
...DEFAULT_OPTS,
dir: process.cwd(),
latest: true,
}, [])

const lockfileUpdated = await project.readLockfile()
expect(lockfileUpdated.packages['/@pnpm.e2e/foo/100.0.0']).toBeTruthy()
})

0 comments on commit 969f8a0

Please sign in to comment.