diff --git a/lib/manager/pip_requirements/extract.js b/lib/manager/pip_requirements/extract.js index 5288056399632be04a51ca5139b33c77ebd0a2ba..7637e469d2345f41a773c9d046fea77ca0f4dfc6 100644 --- a/lib/manager/pip_requirements/extract.js +++ b/lib/manager/pip_requirements/extract.js @@ -1,5 +1,6 @@ // based on https://www.python.org/dev/peps/pep-0508/#names const packagePattern = '[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9]'; +const extrasPattern = '(?:\\s*\\[[^\\]]+\\])?'; const rangePattern = require('@renovate/pep440/lib/specifier').RANGE_PATTERN; const specifierPartPattern = `\\s*${rangePattern.replace( @@ -24,7 +25,10 @@ function extractDependencies(content) { } }); - const regex = new RegExp(`^(${packagePattern})(${specifierPattern})$`, 'g'); + const regex = new RegExp( + `^(${packagePattern})${extrasPattern}(${specifierPattern})$`, + 'g' + ); const deps = content .split('\n') .map((rawline, lineNumber) => { diff --git a/test/_fixtures/pip_requirements/requirements4.txt b/test/_fixtures/pip_requirements/requirements4.txt new file mode 100644 index 0000000000000000000000000000000000000000..7f992217f4b1678ca216a280165878af505635b5 --- /dev/null +++ b/test/_fixtures/pip_requirements/requirements4.txt @@ -0,0 +1,3 @@ +Django[argon2]==2.0.8 +celery [redis]==4.1.1 +foo [bar] == 3.2.1 # handles extra white space diff --git a/test/manager/pip_requirements/__snapshots__/extract.spec.js.snap b/test/manager/pip_requirements/__snapshots__/extract.spec.js.snap index 57ff0f6f86d81a1a56435650a31a053095f4939b..c62ba779ffd9a440087554921444a7317c01c1af 100644 --- a/test/manager/pip_requirements/__snapshots__/extract.spec.js.snap +++ b/test/manager/pip_requirements/__snapshots__/extract.spec.js.snap @@ -115,3 +115,29 @@ Array [ }, ] `; + +exports[`lib/manager/pip_requirements/extract extractDependencies() handles extras 1`] = ` +Array [ + Object { + "currentValue": "==2.0.8", + "depName": "Django", + "lineNumber": 0, + "purl": "pkg:pypi/Django", + "versionScheme": "pep440", + }, + Object { + "currentValue": "==4.1.1", + "depName": "celery", + "lineNumber": 1, + "purl": "pkg:pypi/celery", + "versionScheme": "pep440", + }, + Object { + "currentValue": " == 3.2.1", + "depName": "foo", + "lineNumber": 2, + "purl": "pkg:pypi/foo", + "versionScheme": "pep440", + }, +] +`; diff --git a/test/manager/pip_requirements/__snapshots__/update.spec.js.snap b/test/manager/pip_requirements/__snapshots__/update.spec.js.snap index aa8a297378a1d7ad89af74b4343a1ddd93efb20f..dd8609c522c75ad0ebb5ba1d6201e1024bd5b746 100644 --- a/test/manager/pip_requirements/__snapshots__/update.spec.js.snap +++ b/test/manager/pip_requirements/__snapshots__/update.spec.js.snap @@ -18,3 +18,10 @@ psycopg2==2.4.6 # renovate: wsgiref==0.1.2 # something else " `; + +exports[`manager/pip_requirements/update updateDependency replaces existing value with extras 1`] = ` +"Django[argon2]==2.0.8 +celery [redis]==4.1.1 +celery==4.1.2 [bar] == 3.2.1 # handles extra white space +" +`; diff --git a/test/manager/pip_requirements/extract.spec.js b/test/manager/pip_requirements/extract.spec.js index 9904e56da42773c291e62011e2b22aca2c8101ac..d08463120e13e163fc63b9d514a57d155dc8ba2a 100644 --- a/test/manager/pip_requirements/extract.spec.js +++ b/test/manager/pip_requirements/extract.spec.js @@ -16,6 +16,11 @@ const requirements3 = fs.readFileSync( 'utf8' ); +const requirements4 = fs.readFileSync( + 'test/_fixtures/pip_requirements/requirements4.txt', + 'utf8' +); + describe('lib/manager/pip_requirements/extract', () => { describe('extractDependencies()', () => { let config; @@ -40,5 +45,10 @@ describe('lib/manager/pip_requirements/extract', () => { expect(res).toMatchSnapshot(); expect(res).toHaveLength(5); }); + it('handles extras', () => { + const res = extractDependencies(requirements4, config).deps; + expect(res).toMatchSnapshot(); + expect(res).toHaveLength(3); + }); }); }); diff --git a/test/manager/pip_requirements/update.spec.js b/test/manager/pip_requirements/update.spec.js index 3caa64fb2f1b32b8663089792f96a3d5c9de7453..bf82236d41296cd4b398e8526743d15c6e6b09a6 100644 --- a/test/manager/pip_requirements/update.spec.js +++ b/test/manager/pip_requirements/update.spec.js @@ -13,6 +13,11 @@ const requirements3 = fs.readFileSync( 'utf8' ); +const requirements4 = fs.readFileSync( + 'test/_fixtures/pip_requirements/requirements4.txt', + 'utf8' +); + describe('manager/pip_requirements/update', () => { describe('updateDependency', () => { it('replaces existing value', () => { @@ -41,5 +46,17 @@ describe('manager/pip_requirements/update', () => { expect(res).not.toEqual(requirements3); expect(res.includes(upgrade.newValue)).toBe(true); }); + + it('replaces existing value with extras', () => { + const upgrade = { + depName: 'celery', + lineNumber: 2, + newValue: '==4.1.2', + }; + const res = updateDependency(requirements4, upgrade); + expect(res).toMatchSnapshot(); + expect(res).not.toEqual(requirements4); + expect(res.includes(upgrade.newValue)).toBe(true); + }); }); });