diff --git a/lib/datasource/nuget/v2.js b/lib/datasource/nuget/v2.js index 5580462410fb830c17a9ae44ddee97dec3c55f82..7021db5f7dde74c30f967ff0471aba974634d409 100644 --- a/lib/datasource/nuget/v2.js +++ b/lib/datasource/nuget/v2.js @@ -7,42 +7,53 @@ module.exports = { }; async function getPkgReleases(feedUrl, pkgName) { - const pkgUrlList = `${feedUrl}/FindPackagesById()?id=%27${pkgName}%27&$select=Version,IsLatestVersion,ProjectUrl`; const dep = { pkgName, }; try { - const pkgVersionsListRaw = await got(pkgUrlList, { platform: 'nuget' }); - if (pkgVersionsListRaw.statusCode !== 200) { - logger.debug( - { dependency: pkgName, pkgVersionsListRaw }, - `nuget registry failure: status code != 200` - ); - return null; - } - const pkgInfoList = new XmlDocument( - pkgVersionsListRaw.body - ).children.filter(node => node.name === 'entry'); - dep.releases = []; - for (const pkgInfo of pkgInfoList || []) { - const pkgVersion = getPkgProp(pkgInfo, 'Version'); - dep.releases.push({ - version: pkgVersion, - }); - try { - const pkgIsLatestVersion = getPkgProp(pkgInfo, 'IsLatestVersion'); - if (pkgIsLatestVersion === 'true') { - dep.sourceUrl = parse(getPkgProp(pkgInfo, 'ProjectUrl')); - } - } catch (err) /* istanbul ignore next */ { + let pkgUrlList = `${feedUrl}/FindPackagesById()?id=%27${pkgName}%27&$select=Version,IsLatestVersion,ProjectUrl`; + do { + const pkgVersionsListRaw = await got(pkgUrlList, { platform: 'nuget' }); + if (pkgVersionsListRaw.statusCode !== 200) { logger.debug( - { err, pkgName, feedUrl }, - `nuget registry failure: can't parse pkg info for project url` + { dependency: pkgName, pkgVersionsListRaw }, + `nuget registry failure: status code != 200` ); + return null; + } + + const pkgVersionsListDoc = new XmlDocument(pkgVersionsListRaw.body); + + const pkgInfoList = pkgVersionsListDoc.children.filter( + node => node.name === 'entry' + ); + + for (const pkgInfo of pkgInfoList || []) { + const pkgVersion = getPkgProp(pkgInfo, 'Version'); + dep.releases.push({ + version: pkgVersion, + }); + try { + const pkgIsLatestVersion = getPkgProp(pkgInfo, 'IsLatestVersion'); + if (pkgIsLatestVersion === 'true') { + dep.sourceUrl = parse(getPkgProp(pkgInfo, 'ProjectUrl')); + } + } catch (err) /* istanbul ignore next */ { + logger.debug( + { err, pkgName, feedUrl }, + `nuget registry failure: can't parse pkg info for project url` + ); + } } - } + + const nextPkgUrlListLink = pkgVersionsListDoc.children.find( + node => node.name === 'link' && node.attr.rel === 'next' + ); + + pkgUrlList = nextPkgUrlListLink ? nextPkgUrlListLink.attr.href : null; + } while (pkgUrlList !== null); return dep; } catch (err) { diff --git a/test/datasource/__snapshots__/nuget.spec.js.snap b/test/datasource/__snapshots__/nuget.spec.js.snap index 83950cda1ace69d77d7d435ae013c73602c08669..d69907b1dd78f66b57fd0de0ecac612dce551217 100644 --- a/test/datasource/__snapshots__/nuget.spec.js.snap +++ b/test/datasource/__snapshots__/nuget.spec.js.snap @@ -1,5 +1,19 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`datasource/nuget getPkgReleases handles paginated results (v2) 1`] = ` +Object { + "pkgName": "nunit", + "releases": Array [ + Object { + "version": "1.0.0", + }, + Object { + "version": "2.0.0", + }, + ], +} +`; + exports[`datasource/nuget getPkgReleases processes real data (v2) 1`] = ` Object { "pkgName": "nunit", diff --git a/test/datasource/nuget.spec.js b/test/datasource/nuget.spec.js index 0ef9a60c854cc6a865500b00a0e18a2464367996..f50944eee8947450c54527a628b8030943f0021b 100644 --- a/test/datasource/nuget.spec.js +++ b/test/datasource/nuget.spec.js @@ -27,6 +27,15 @@ const pkgListV2WithoutProjectUrl = fs.readFileSync( 'utf8' ); +const pkgListV2Page1of2 = fs.readFileSync( + 'test/datasource/nuget/_fixtures/nunitV2_paginated_1.xml', + 'utf8' +); +const pkgListV2Page2of2 = fs.readFileSync( + 'test/datasource/nuget/_fixtures/nunitV2_paginated_2.xml', + 'utf8' +); + const nugetIndexV3 = fs.readFileSync( 'test/datasource/nuget/_fixtures/indexV3.json', 'utf8' @@ -323,5 +332,20 @@ describe('datasource/nuget', () => { expect(res).toMatchSnapshot(); expect(res.sourceUrl).not.toBeDefined(); }); + it('handles paginated results (v2)', async () => { + got.mockReturnValueOnce({ + body: pkgListV2Page1of2, + statusCode: 200, + }); + got.mockReturnValueOnce({ + body: pkgListV2Page2of2, + statusCode: 200, + }); + const res = await datasource.getPkgReleases({ + ...configV2, + }); + expect(res).not.toBeNull(); + expect(res).toMatchSnapshot(); + }); }); }); diff --git a/test/datasource/nuget/_fixtures/nunitV2_paginated_1.xml b/test/datasource/nuget/_fixtures/nunitV2_paginated_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..f791385720baa3e21abc30e11ed00d19db5ef05e --- /dev/null +++ b/test/datasource/nuget/_fixtures/nunitV2_paginated_1.xml @@ -0,0 +1,12 @@ + +<feed xml:base="https://www.nuget.org/api/v2" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml"> + <id>http://schemas.datacontract.org/2004/07/</id> + <link rel="self" href="https://www.nuget.org/api/v2/Packages"/> + <link rel="next" href="https://example.org"/> + <entry> + <m:properties> + <d:Version>1.0.0</d:Version> + <d:IsLatestVersion>false</d:IsLatestVersion> + </m:properties> + </entry> +</feed> \ No newline at end of file diff --git a/test/datasource/nuget/_fixtures/nunitV2_paginated_2.xml b/test/datasource/nuget/_fixtures/nunitV2_paginated_2.xml new file mode 100644 index 0000000000000000000000000000000000000000..c507e9c5594de00df1a7afd022d2e6436bb0b41c --- /dev/null +++ b/test/datasource/nuget/_fixtures/nunitV2_paginated_2.xml @@ -0,0 +1,10 @@ +<feed xml:base="https://www.nuget.org/api/v2" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml"> + <id>http://schemas.datacontract.org/2004/07/</id> + <link rel="self" href="https://www.nuget.org/api/v2/Packages"/> + <entry> + <m:properties> + <d:Version>2.0.0</d:Version> + <d:IsLatestVersion>true</d:IsLatestVersion> + </m:properties> + </entry> +</feed>