Skip to content
Snippets Groups Projects
Unverified Commit 20c25d93 authored by Christopher Frieler's avatar Christopher Frieler Committed by GitHub
Browse files

fix(pypi): Normalize package names before lookup (#12273)

parent eef0a00c
Branches
Tags 28.20.0
No related merge requests found
......@@ -172,6 +172,53 @@ describe('datasource/pypi/index', () => {
expect(result.changelogUrl).toBe(info.project_urls.changelog);
expect(httpMock.getTrace()).toMatchSnapshot();
});
it('normalizes the package name according to PEP 503', async () => {
const expectedHttpCall = httpMock
.scope(baseUrl)
.get('/not-normalized-package/json')
.reply(200, htmlResponse);
await getPkgReleases({
datasource,
registryUrls: [baseUrl],
depName: 'not_normalized.Package',
});
expect(expectedHttpCall.isDone()).toBeTrue();
});
it('normalizes the package name according to PEP 503 when falling back to simple endpoint', async () => {
httpMock
.scope(baseUrl)
.get('/not-normalized-package/json')
.reply(404, '');
const expectedFallbackHttpCall = httpMock
.scope(baseUrl)
.get('/not-normalized-package/')
.reply(200, htmlResponse);
await getPkgReleases({
datasource,
registryUrls: [baseUrl],
depName: 'not_normalized.Package',
});
expect(expectedFallbackHttpCall.isDone()).toBeTrue();
});
it('normalizes the package name according to PEP 503 querying a simple endpoint', async () => {
const simpleRegistryUrl = 'https://pypi.org/simple/';
const expectedHttpCall = httpMock
.scope(simpleRegistryUrl)
.get('/not-normalized-package/')
.reply(200, htmlResponse);
await getPkgReleases({
datasource,
registryUrls: [simpleRegistryUrl],
depName: 'not_normalized.Package',
});
expect(expectedHttpCall.isDone()).toBeTrue();
});
it('respects constraints', async () => {
httpMock
......
......@@ -36,6 +36,7 @@ export class PypiDatasource extends Datasource {
}: GetReleasesConfig): Promise<ReleaseResult | null> {
let dependency: ReleaseResult = null;
const hostUrl = ensureTrailingSlash(registryUrl);
const normalizedLookupName = PypiDatasource.normalizeName(lookupName);
// not all simple indexes use this identifier, but most do
if (hostUrl.endsWith('/simple/') || hostUrl.endsWith('/+simple/')) {
......@@ -43,12 +44,15 @@ export class PypiDatasource extends Datasource {
{ lookupName, hostUrl },
'Looking up pypi simple dependency'
);
dependency = await this.getSimpleDependency(lookupName, hostUrl);
dependency = await this.getSimpleDependency(
normalizedLookupName,
hostUrl
);
} else {
logger.trace({ lookupName, hostUrl }, 'Looking up pypi api dependency');
try {
// we need to resolve early here so we can catch any 404s and fallback to a simple lookup
dependency = await this.getDependency(lookupName, hostUrl);
dependency = await this.getDependency(normalizedLookupName, hostUrl);
} catch (err) {
if (err.statusCode !== 404) {
throw err;
......@@ -59,12 +63,19 @@ export class PypiDatasource extends Datasource {
{ lookupName, hostUrl },
'Looking up pypi simple dependency via fallback'
);
dependency = await this.getSimpleDependency(lookupName, hostUrl);
dependency = await this.getSimpleDependency(
normalizedLookupName,
hostUrl
);
}
}
return dependency;
}
private static normalizeName(input: string): string {
return input.toLowerCase().replace(regEx(/(_|\.|-)+/g), '-');
}
private async getDependency(
packageName: string,
hostUrl: string
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment