Skip to content

Commit

Permalink
feat(datasource/pypi): always fallback to try simple endpoints (#32024)
Browse files Browse the repository at this point in the history
  • Loading branch information
rarkins authored Nov 27, 2024
1 parent 56f79b9 commit c868ed0
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 66 deletions.
42 changes: 0 additions & 42 deletions lib/modules/datasource/pypi/__snapshots__/index.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -1,47 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`modules/datasource/pypi/index getReleases fall back from json and process data from simple endpoint 1`] = `
{
"registryUrl": "https://custom.pypi.net/foo",
"releases": [
{
"version": "0.1.2",
},
{
"version": "0.1.3",
},
{
"version": "0.1.4",
},
{
"version": "0.2.0",
},
{
"version": "0.2.1",
},
{
"version": "0.2.2",
},
{
"version": "0.3.0",
},
{
"version": "0.4.0",
},
{
"version": "0.4.1",
},
{
"version": "0.4.2",
},
{
"isDeprecated": true,
"version": "0.5.0",
},
],
}
`;

exports[`modules/datasource/pypi/index getReleases parses data-requires-python and respects constraints from simple endpoint 1`] = `
{
"registryUrl": "https://some.registry.org/simple",
Expand Down
50 changes: 31 additions & 19 deletions lib/modules/datasource/pypi/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ describe('modules/datasource/pypi/index', () => {
.scope('https://custom.pypi.net/foo')
.get('/azure-cli-monitor/json')
.replyWithError('error');
httpMock
.scope('https://custom.pypi.net/foo')
.get('/azure-cli-monitor/')
.replyWithError('error');
httpMock
.scope('https://second-index/foo')
.get('/azure-cli-monitor/json')
Expand Down Expand Up @@ -308,6 +312,11 @@ describe('modules/datasource/pypi/index', () => {
.get('/not-normalized-package/json')
.reply(200, htmlResponse);

httpMock
.scope(baseUrl)
.get('/not-normalized-package/')
.reply(200, htmlResponse);

await getPkgReleases({
datasource,
registryUrls: [baseUrl],
Expand Down Expand Up @@ -716,25 +725,28 @@ describe('modules/datasource/pypi/index', () => {
).toBeNull();
});

it('fall back from json and process data from simple endpoint', async () => {
httpMock
.scope('https://custom.pypi.net/foo')
.get('/dj-database-url/json')
.reply(404);
httpMock
.scope('https://custom.pypi.net/foo')
.get('/dj-database-url/')
.reply(200, htmlResponse);
const config = {
registryUrls: ['https://custom.pypi.net/foo'],
};
const result = await getPkgReleases({
datasource,
...config,
packageName: 'dj-database-url',
});
expect(result).toMatchSnapshot();
});
it.each([404, 403])(
'fall back from json and process data from simple endpoint',
async (code: number) => {
httpMock
.scope('https://custom.pypi.net/foo')
.get('/dj-database-url/json')
.reply(code);
httpMock
.scope('https://custom.pypi.net/foo')
.get('/dj-database-url/')
.reply(200, htmlResponse);
const config = {
registryUrls: ['https://custom.pypi.net/foo'],
};
const result = await getPkgReleases({
datasource,
...config,
packageName: 'dj-database-url',
});
expect(result).not.toBeNull();
},
);

it('parses data-requires-python and respects constraints from simple endpoint', async () => {
httpMock
Expand Down
6 changes: 1 addition & 5 deletions lib/modules/datasource/pypi/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,9 @@ export class PypiDatasource extends Datasource {
// we need to resolve early here so we can catch any 404s and fallback to a simple lookup
dependency = await this.getDependency(normalizedLookupName, hostUrl);
} catch (err) {
if (err.statusCode !== 404) {
throw err;
}

// error contacting json-style api -- attempt to fallback to a simple-style api
logger.trace(
{ packageName, hostUrl },
{ packageName, hostUrl, err },
'Looking up pypi simple dependency via fallback',
);
dependency = await this.getSimpleDependency(
Expand Down
6 changes: 6 additions & 0 deletions lib/modules/datasource/pypi/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
This datasource uses the following logic to determine lookup URLs:

- If the normalized registryUrl ends in `/simple/` or `/+simple/` then only the simple API will be tried
- Otherwise, the JSON API will be tried first
- If the JSON API returns a result, it will be used
- If the JSON API throws an error (e.g. 403, 404) then the simple API will be tried

0 comments on commit c868ed0

Please sign in to comment.