From a28103e31aaec01ccaf64ffc11e1d4e8b4438700 Mon Sep 17 00:00:00 2001 From: Jamie Tanna Date: Mon, 27 Apr 2026 11:43:11 +0100 Subject: [PATCH 1/2] chore(datasource): add trace logging for `applyConstraintsFiltering` As a way to provide more additional information to users who are debugging when `constraintsFiltering=strict`, we can add some TRACE logs. We can use the prefix `applyConstraintsFiltering` for all log lines, so we can use `logLevelRemap` more easily. --- lib/modules/datasource/common.ts | 111 +++++++++++++++++++++++++++++-- 1 file changed, 106 insertions(+), 5 deletions(-) diff --git a/lib/modules/datasource/common.ts b/lib/modules/datasource/common.ts index 8d09286f0a1..42741474f47 100644 --- a/lib/modules/datasource/common.ts +++ b/lib/modules/datasource/common.ts @@ -187,9 +187,25 @@ export function applyConstraintsFiltering< const filteredReleases: string[] = []; const startingLength = releaseResult.releases.length; releaseResult.releases = filterMap(releaseResult.releases, (release) => { + logger.trace( + { + release, + versioning: versioningName, + }, + `applyConstraintsFiltering(${release.version})`, + ); const releaseConstraints = release.constraints; delete release.constraints; + logger.trace( + { + release, + versioning: versioningName, + configConstraints: configConstraints ?? 'undefined', + releaseConstraints: releaseConstraints ?? 'undefined', + }, + `applyConstraintsFiltering(${release.version}): checking constraints`, + ); if (!configConstraints || !releaseConstraints) { return release; } @@ -197,7 +213,25 @@ export function applyConstraintsFiltering< for (const [name, configConstraint] of Object.entries( configConstraints, ) as [ConstraintName, string][]) { - if (!versioning.isValid(configConstraint)) { + logger.trace( + { + release, + versioning: versioningName, + constraintName: name, + constraint: configConstraint, + }, + `applyConstraintsFiltering(${release.version}) for constraint ${name}`, + ); + + const isValid = versioning.isValid(configConstraint); + logger.trace( + { + release, + versioning: versioningName, + }, + `applyConstraintsFiltering(${release.version}): versioning.isValid(${configConstraint})=${isValid}`, + ); + if (!isValid) { logger.once.warn( { packageName: config.packageName, @@ -210,6 +244,13 @@ export function applyConstraintsFiltering< } const constraint = releaseConstraints[name]; + logger.trace( + { + release, + versioning: versioningName, + }, + `applyConstraintsFiltering(${release.version}): releaseConstraints[${name}]=${JSON.stringify(constraint)}`, + ); if (!isNonEmptyArray(constraint)) { // A release with no constraints is OK continue; @@ -217,6 +258,14 @@ export function applyConstraintsFiltering< let satisfiesConstraints = false; for (const releaseConstraint of constraint) { + logger.trace( + { + release, + versioning: versioningName, + releaseConstraint, + }, + `applyConstraintsFiltering(${release.version}): releaseConstraint=${releaseConstraint}`, + ); if (!releaseConstraint) { satisfiesConstraints = true; logger.once.debug( @@ -230,7 +279,16 @@ export function applyConstraintsFiltering< break; } - if (!versioning.isValid(releaseConstraint)) { + const isValid = versioning.isValid(releaseConstraint); + logger.trace( + { + release, + versioning: versioningName, + releaseConstraint, + }, + `applyConstraintsFiltering(${release.version}): versioning.isValid(${releaseConstraint})=${isValid}`, + ); + if (!isValid) { logger.once.debug( { packageName: config.packageName, @@ -242,22 +300,65 @@ export function applyConstraintsFiltering< break; } - if (configConstraint === releaseConstraint) { + const isEqual = configConstraint === releaseConstraint; + logger.trace( + { + release, + versioning: versioningName, + configConstraint, + releaseConstraint, + }, + `applyConstraintsFiltering(${release.version}): ${configConstraint} === ${releaseConstraint}=${isValid}`, + ); + if (isEqual) { satisfiesConstraints = true; break; } - if (versioning.subset?.(configConstraint, releaseConstraint)) { + const isSubset = versioning.subset?.( + configConstraint, + releaseConstraint, + ); + logger.trace( + { + release, + versioning: versioningName, + configConstraint, + releaseConstraint, + }, + `applyConstraintsFiltering(${release.version}): versioning.subset?.(${configConstraint}, ${releaseConstraint}=${isSubset}`, + ); + if (isSubset) { satisfiesConstraints = true; break; } - if (versioning.matches(configConstraint, releaseConstraint)) { + const doesMatch = versioning.matches( + configConstraint, + releaseConstraint, + ); + logger.trace( + { + release, + versioning: versioningName, + configConstraint, + releaseConstraint, + }, + `applyConstraintsFiltering(${release.version}): versioning.matches(${configConstraint}, ${releaseConstraint}=${isSubset}`, + ); + if (doesMatch) { satisfiesConstraints = true; break; } } + logger.trace( + { + release, + versioning: versioningName, + }, + `applyConstraintsFiltering(${release.version}): satisfiesConstraints=${satisfiesConstraints}`, + ); if (!satisfiesConstraints) { filteredReleases.push(release.version); return null; From d26abc2cd660999e54329f043af5738dec29011b Mon Sep 17 00:00:00 2001 From: Jamie Tanna Date: Mon, 27 Apr 2026 13:35:28 +0100 Subject: [PATCH 2/2] test(datasource): add coverage Co-authored-by: Claude Sonnet 4.6 --- lib/modules/datasource/common.spec.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lib/modules/datasource/common.spec.ts b/lib/modules/datasource/common.spec.ts index 327057943b1..c516be37aff 100644 --- a/lib/modules/datasource/common.spec.ts +++ b/lib/modules/datasource/common.spec.ts @@ -245,6 +245,24 @@ describe('modules/datasource/common', () => { }); }); + it('should return all releases when no configConstraints', () => { + const config = { + datasource: 'pypi', + packageName: 'bar', + versioning: 'pep440', + constraintsFiltering: 'strict' as const, + }; + const releaseResult = { + releases: [ + { version: '1.0.0', constraints: { python: ['^1.0.0'] } }, + { version: '2.0.0' }, + ], + }; + expect(applyConstraintsFiltering(releaseResult, config)).toEqual({ + releases: [{ version: '1.0.0' }, { version: '2.0.0' }], + }); + }); + it('should match exact constraints', () => { const config = { datasource: 'pypi',