diff --git a/lib/manager/nvm/__snapshots__/update.spec.ts.snap b/lib/manager/nvm/__snapshots__/update.spec.ts.snap deleted file mode 100644 index 104c1cac2fd62eaa5314cd230d7bdf0d91b36b58..0000000000000000000000000000000000000000 --- a/lib/manager/nvm/__snapshots__/update.spec.ts.snap +++ /dev/null @@ -1,6 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`manager/nvm/update updateDependency updates values 1`] = ` -"8.9.1 -" -`; diff --git a/lib/manager/pip_requirements/__snapshots__/extract.spec.ts.snap b/lib/manager/pip_requirements/__snapshots__/extract.spec.ts.snap index bd52f16253f1481f88195ad473e17811e3886002..32eb886babd26f65b1438a76cd6814b8f5eeb68f 100644 --- a/lib/manager/pip_requirements/__snapshots__/extract.spec.ts.snap +++ b/lib/manager/pip_requirements/__snapshots__/extract.spec.ts.snap @@ -8,27 +8,18 @@ Object { "datasource": "pypi", "depName": "some-package", "fromVersion": "0.3.1", - "managerData": Object { - "lineNumber": 2, - }, }, Object { "currentValue": "==1.0.0", "datasource": "pypi", "depName": "some-other-package", "fromVersion": "1.0.0", - "managerData": Object { - "lineNumber": 3, - }, }, Object { "currentValue": "==1.9", "datasource": "pypi", "depName": "not_semver", "fromVersion": "1.9", - "managerData": Object { - "lineNumber": 4, - }, }, ], "registryUrls": Array [ @@ -44,45 +35,30 @@ Array [ "datasource": "pypi", "depName": "Django", "fromVersion": "1", - "managerData": Object { - "lineNumber": 0, - }, }, Object { "currentValue": "==0.6.27", "datasource": "pypi", "depName": "distribute", "fromVersion": "0.6.27", - "managerData": Object { - "lineNumber": 1, - }, }, Object { "currentValue": "==0.2", "datasource": "pypi", "depName": "dj-database-url", "fromVersion": "0.2", - "managerData": Object { - "lineNumber": 2, - }, }, Object { "currentValue": "==2.4.5", "datasource": "pypi", "depName": "psycopg2", "fromVersion": "2.4.5", - "managerData": Object { - "lineNumber": 3, - }, }, Object { "currentValue": "==0.1.2", "datasource": "pypi", "depName": "wsgiref", "fromVersion": "0.1.2", - "managerData": Object { - "lineNumber": 4, - }, }, ] `; @@ -94,18 +70,12 @@ Array [ "datasource": "pypi", "depName": "Django", "fromVersion": "1.11.23", - "managerData": Object { - "lineNumber": 0, - }, }, Object { "currentValue": "==0.6.27", "datasource": "pypi", "depName": "distribute", "fromVersion": "0.6.27", - "managerData": Object { - "lineNumber": 1, - }, "skipReason": "ignored", }, Object { @@ -113,27 +83,18 @@ Array [ "datasource": "pypi", "depName": "dj-database-url", "fromVersion": "0.2", - "managerData": Object { - "lineNumber": 2, - }, }, Object { "currentValue": "==2.4.5", "datasource": "pypi", "depName": "psycopg2", "fromVersion": "2.4.5", - "managerData": Object { - "lineNumber": 3, - }, }, Object { "currentValue": "==0.1.2", "datasource": "pypi", "depName": "wsgiref", "fromVersion": "0.1.2", - "managerData": Object { - "lineNumber": 4, - }, }, ] `; @@ -146,53 +107,35 @@ Object { "datasource": "pypi", "depName": "Django", "fromVersion": "2.0.12", - "managerData": Object { - "lineNumber": 4, - }, }, Object { "currentValue": "==4.1.1", "datasource": "pypi", "depName": "celery", "fromVersion": "4.1.1", - "managerData": Object { - "lineNumber": 5, - }, }, Object { "currentValue": " == 3.2.1", "datasource": "pypi", "depName": "foo", - "managerData": Object { - "lineNumber": 6, - }, }, Object { "currentValue": "==0.3.1", "datasource": "pypi", "depName": "some-package", "fromVersion": "0.3.1", - "managerData": Object { - "lineNumber": 7, - }, }, Object { "currentValue": "==1.0.0", "datasource": "pypi", "depName": "some-other-package", "fromVersion": "1.0.0", - "managerData": Object { - "lineNumber": 8, - }, }, Object { "currentValue": "==1.9", "datasource": "pypi", "depName": "not_semver", "fromVersion": "1.9", - "managerData": Object { - "lineNumber": 9, - }, }, ], "registryUrls": Array [ @@ -210,53 +153,35 @@ Object { "datasource": "pypi", "depName": "Django", "fromVersion": "2.0.12", - "managerData": Object { - "lineNumber": 3, - }, }, Object { "currentValue": "==4.1.1", "datasource": "pypi", "depName": "celery", "fromVersion": "4.1.1", - "managerData": Object { - "lineNumber": 4, - }, }, Object { "currentValue": " == 3.2.1", "datasource": "pypi", "depName": "foo", - "managerData": Object { - "lineNumber": 5, - }, }, Object { "currentValue": "==0.3.1", "datasource": "pypi", "depName": "some-package", "fromVersion": "0.3.1", - "managerData": Object { - "lineNumber": 6, - }, }, Object { "currentValue": "==1.0.0", "datasource": "pypi", "depName": "some-other-package", "fromVersion": "1.0.0", - "managerData": Object { - "lineNumber": 7, - }, }, Object { "currentValue": "==1.9", "datasource": "pypi", "depName": "not_semver", "fromVersion": "1.9", - "managerData": Object { - "lineNumber": 8, - }, }, ], "registryUrls": Array [ @@ -274,53 +199,35 @@ Object { "datasource": "pypi", "depName": "Django", "fromVersion": "2.0.12", - "managerData": Object { - "lineNumber": 3, - }, }, Object { "currentValue": "==4.1.1", "datasource": "pypi", "depName": "celery", "fromVersion": "4.1.1", - "managerData": Object { - "lineNumber": 4, - }, }, Object { "currentValue": " == 3.2.1", "datasource": "pypi", "depName": "foo", - "managerData": Object { - "lineNumber": 5, - }, }, Object { "currentValue": "==0.3.1", "datasource": "pypi", "depName": "some-package", "fromVersion": "0.3.1", - "managerData": Object { - "lineNumber": 6, - }, }, Object { "currentValue": "==1.0.0", "datasource": "pypi", "depName": "some-other-package", "fromVersion": "1.0.0", - "managerData": Object { - "lineNumber": 7, - }, }, Object { "currentValue": "==1.9", "datasource": "pypi", "depName": "not_semver", "fromVersion": "1.9", - "managerData": Object { - "lineNumber": 8, - }, }, ], "registryUrls": Array [ @@ -338,26 +245,17 @@ Object { "datasource": "pypi", "depName": "Django", "fromVersion": "2.0.12", - "managerData": Object { - "lineNumber": 1, - }, }, Object { "currentValue": "==4.1.1", "datasource": "pypi", "depName": "celery", "fromVersion": "4.1.1", - "managerData": Object { - "lineNumber": 2, - }, }, Object { "currentValue": " == 3.2.1", "datasource": "pypi", "depName": "foo", - "managerData": Object { - "lineNumber": 3, - }, }, ], "registryUrls": Array [ diff --git a/lib/manager/pip_requirements/__snapshots__/update.spec.ts.snap b/lib/manager/pip_requirements/__snapshots__/update.spec.ts.snap deleted file mode 100644 index 7b70c02ad6292040ca1d567549929d3cb4123281..0000000000000000000000000000000000000000 --- a/lib/manager/pip_requirements/__snapshots__/update.spec.ts.snap +++ /dev/null @@ -1,205 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`manager/pip_requirements/update updateDependency handles dependencies in different lines in setup.py 1`] = ` -" -try: - from setuptools import setup -except ImportError: - from distutils.core import setup - -setup( - author='Simon Davy', - author_email='simon.davy@canonical.com', - classifiers=[ - 'License :: OSI Approved :: Apache Software License', - 'Development Status :: 4 - Beta', - 'Intended Audience :: Developers', - 'Natural Language :: English', - 'Topic :: Internet :: WWW/HTTP :: WSGI', - 'Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware', - 'Topic :: System :: Logging', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: Implementation :: CPython', - ], - description='A common WSGI stack', - entry_points=dict( - console_scripts=[ - 'talisker=talisker:run_gunicorn', - 'talisker.run=talisker:run', - 'talisker.gunicorn=talisker:run_gunicorn', - 'talisker.gunicorn.eventlet=talisker:run_gunicorn_eventlet', - 'talisker.gunicorn.gevent=talisker:run_gunicorn_gevent', - 'talisker.celery=talisker:run_celery', - ], - ), - extras_require=dict( - celery=[ - 'celery>=3.1.13.0,<5.0', - ], - dev=[ - 'logging_tree>=1.7', - 'pygments>=2.2', - 'psutil>=5.0', - 'objgraph>=3.0', - ], - django=[ - 'django>=1.11.23,<2.0', - ], - flask=[ - 'flask>=0.11,<2.0', - 'blinker>=1.4,<2.0', - ], - pg=[ - 'sqlparse', - 'psycopg2', - ], - prometheus=[ - 'prometheus-client>=0.2.0,<0.5.0' + ',!=0.4.0,!=0.4.1', - ], - ), - include_package_data=True, - install_requires=[ - 'gunicorn>=19.7.0,<20.0', - 'Werkzeug>=0.15.3,<0.16', 'statsd>=3.2.1,<4.0', - 'requests>=2.10.0,<3.0', # renovate: ignore - 'raven>=2.11.0', # pyup: nothing - 'future>=0.15.2,<0.17', - 'ipaddress>=1.0.16,<2.0;python_version<\\"3.3\\"', - ], - keywords=[ - 'talisker', - ], - name='talisker', - package_data=dict( - talisker=[ - 'logstash/*', - ], - ), - package_dir=dict( - talisker='talisker', - ), - packages=[ - 'talisker', - ], - test_suite='tests', - url='https://github.com/canonical-ols/talisker', - version='0.9.16', - zip_safe=False, -) -" -`; - -exports[`manager/pip_requirements/update updateDependency handles multiple dependencies in same lines in setup.py 1`] = ` -" -try: - from setuptools import setup -except ImportError: - from distutils.core import setup - -setup( - author='Simon Davy', - author_email='simon.davy@canonical.com', - classifiers=[ - 'License :: OSI Approved :: Apache Software License', - 'Development Status :: 4 - Beta', - 'Intended Audience :: Developers', - 'Natural Language :: English', - 'Topic :: Internet :: WWW/HTTP :: WSGI', - 'Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware', - 'Topic :: System :: Logging', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: Implementation :: CPython', - ], - description='A common WSGI stack', - entry_points=dict( - console_scripts=[ - 'talisker=talisker:run_gunicorn', - 'talisker.run=talisker:run', - 'talisker.gunicorn=talisker:run_gunicorn', - 'talisker.gunicorn.eventlet=talisker:run_gunicorn_eventlet', - 'talisker.gunicorn.gevent=talisker:run_gunicorn_gevent', - 'talisker.celery=talisker:run_celery', - ], - ), - extras_require=dict( - celery=[ - 'celery>=3.1.13.0,<5.0', - ], - dev=[ - 'logging_tree>=1.7', - 'pygments>=2.2', - 'psutil>=5.0', - 'objgraph>=3.0', - ], - django=[ - 'django>=1.11.23,<2.0', - ], - flask=[ - 'flask>=0.11,<2.0', - 'blinker>=1.4,<2.0', - ], - pg=[ - 'sqlparse', - 'psycopg2', - ], - prometheus=[ - 'prometheus-client>=0.2.0,<0.5.0' + ',!=0.4.0,!=0.4.1', - ], - ), - include_package_data=True, - install_requires=['gunicorn>=19.7.0,<20.0', 'Werkzeug>=0.15.3,<0.16', 'pycryptodome==3.8.0','statsd>=3.2.1,<4.0', 'requests>=2.10.0,<3.0', 'raven>=5.27.1,<7.0','future>=0.15.2,<0.17',], - keywords=[ - 'talisker', - ], - name='talisker', - package_data=dict( - talisker=[ - 'logstash/*', - ], - ), - package_dir=dict( - talisker='talisker', - ), - packages=[ - 'talisker', - ], - test_suite='tests', - url='https://github.com/canonical-ols/talisker', - version='0.9.16', - zip_safe=False, -) -" -`; - -exports[`manager/pip_requirements/update updateDependency replaces existing value 1`] = ` -"--index-url http://example.com/private-pypi/ -# simple comment -some-package==1.0.1 -some-other-package==1.0.0 -not_semver==1.9 - -" -`; - -exports[`manager/pip_requirements/update updateDependency replaces existing value with comment 1`] = ` -"Django==1.11.23 # renovate -distribute==0.6.27 # renovate: ignore -dj-database-url==0.2 # pyup: nothing -psycopg2==2.4.6 # renovate: -wsgiref==0.1.2 # something else -" -`; - -exports[`manager/pip_requirements/update updateDependency replaces existing value with extras 1`] = ` -"--index-url https://artifactory.company.com/artifactory/api/pypi/python/simple --trusted-host artifactory.company.com --default-timeout 600 -Django[argon2]==4.1.2 -celery [redis]==4.1.1 -foo [bar] == 3.2.1 # handles extra white space -" -`; diff --git a/lib/manager/pip_requirements/extract.ts b/lib/manager/pip_requirements/extract.ts index 4274a71a28eb51b20a18c45a94ca7af382b2ac50..3e5efc48dd3a5459e1f7ca16624c2a13eecbc170 100644 --- a/lib/manager/pip_requirements/extract.ts +++ b/lib/manager/pip_requirements/extract.ts @@ -50,7 +50,7 @@ export function extractPackageFile( const regex = new RegExp(`^${dependencyPattern}$`, 'g'); const deps = content .split('\n') - .map((rawline, lineNumber) => { + .map(rawline => { let dep: PackageDependency = {}; const [line, comment] = rawline.split('#').map(part => part.trim()); if (isSkipComment(comment)) { @@ -66,7 +66,6 @@ export function extractPackageFile( ...dep, depName, currentValue, - managerData: { lineNumber }, datasource: datasourcePypi.id, }; if (currentValue && currentValue.startsWith('==')) { diff --git a/lib/manager/pip_requirements/index.ts b/lib/manager/pip_requirements/index.ts index 545cb990f99787e11d7dde547b37fa5851fc4b5a..5c9b72905095f50109b29fc3431bbc09e2716708 100644 --- a/lib/manager/pip_requirements/index.ts +++ b/lib/manager/pip_requirements/index.ts @@ -1,11 +1,12 @@ import { LANGUAGE_PYTHON } from '../../constants/languages'; export { extractPackageFile } from './extract'; -export { updateDependency } from './update'; export { getRangeStrategy } from './range'; export const language = LANGUAGE_PYTHON; +export const autoReplace = true; + export const defaultConfig = { fileMatch: ['(^|/)([\\w-]*)requirements.(txt|pip)$'], }; diff --git a/lib/manager/pip_requirements/update.spec.ts b/lib/manager/pip_requirements/update.spec.ts deleted file mode 100644 index 19a31a0030e7c2683463b36f91c4b2a065c8fb34..0000000000000000000000000000000000000000 --- a/lib/manager/pip_requirements/update.spec.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { readFileSync } from 'fs'; -import { updateDependency } from './update'; - -const requirements = readFileSync( - 'lib/manager/pip_requirements/__fixtures__/requirements1.txt', - 'utf8' -); - -const requirements3 = readFileSync( - 'lib/manager/pip_requirements/__fixtures__/requirements3.txt', - 'utf8' -); - -const requirements4 = readFileSync( - 'lib/manager/pip_requirements/__fixtures__/requirements4.txt', - 'utf8' -); - -const setupPy1 = readFileSync( - 'lib/manager/pip_setup/__fixtures__/setup.py', - 'utf-8' -); - -const setupPy2 = readFileSync( - 'lib/manager/pip_setup/__fixtures__/setup-2.py', - 'utf-8' -); - -describe('manager/pip_requirements/update', () => { - describe('updateDependency', () => { - it('replaces existing value', () => { - const upgrade = { - depName: 'some-package', - managerData: { lineNumber: 2 }, - newValue: '==1.0.1', - }; - const res = updateDependency({ - fileContent: requirements, - upgrade, - }); - expect(res).toMatchSnapshot(); - expect(res).not.toEqual(requirements); - expect(res.includes(upgrade.newValue)).toBe(true); - }); - it('returns null if error', () => { - const res = updateDependency({ fileContent: null, upgrade: null }); - expect(res).toBeNull(); - }); - it('replaces existing value with comment', () => { - const upgrade = { - depName: 'psycopg2', - managerData: { lineNumber: 3 }, - newValue: '==2.4.6', - }; - const res = updateDependency({ - fileContent: requirements3, - upgrade, - }); - expect(res).toMatchSnapshot(); - expect(res).not.toEqual(requirements3); - expect(res.includes(upgrade.newValue)).toBe(true); - }); - - it('replaces existing value with extras', () => { - const upgrade = { - depName: 'celery', - managerData: { lineNumber: 1 }, - newValue: '==4.1.2', - }; - const res = updateDependency({ - fileContent: requirements4, - upgrade, - }); - expect(res).toMatchSnapshot(); - expect(res).not.toEqual(requirements4); - expect(res.includes(upgrade.newValue)).toBe(true); - }); - it('handles dependencies in different lines in setup.py', () => { - const upgrade = { - depName: 'requests', - managerData: { lineNumber: 64 }, - newValue: '>=2.11.0', - }; - const res = updateDependency({ fileContent: setupPy1, upgrade }); - expect(res).toMatchSnapshot(); - expect(res).not.toEqual(setupPy1); - expect(res.includes(upgrade.newValue)).toBe(true); - }); - it('handles multiple dependencies in same lines in setup.py', () => { - const upgrade = { - depName: 'pycryptodome', - managerData: { lineNumber: 60 }, - newValue: '==3.8.0', - }; - const res = updateDependency({ fileContent: setupPy2, upgrade }); - expect(res).toMatchSnapshot(); - expect(res).not.toEqual(setupPy2); - const expectedUpdate = - "install_requires=['gunicorn>=19.7.0,<20.0', 'Werkzeug>=0.15.3,<0.16', 'pycryptodome==3.8.0','statsd>=3.2.1,<4.0', 'requests>=2.10.0,<3.0', 'raven>=5.27.1,<7.0','future>=0.15.2,<0.17',],"; - expect(res).toContain(expectedUpdate); - expect(res.includes(upgrade.newValue)).toBe(true); - }); - }); -}); diff --git a/lib/manager/pip_requirements/update.ts b/lib/manager/pip_requirements/update.ts deleted file mode 100644 index 0ee2b8d1f3d7191e28662ae1f7f2bc3723b01b5f..0000000000000000000000000000000000000000 --- a/lib/manager/pip_requirements/update.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { logger } from '../../logger'; -import { dependencyPattern } from './extract'; -import { UpdateDependencyConfig } from '../common'; - -export function updateDependency({ - fileContent, - upgrade, -}: UpdateDependencyConfig): string | null { - try { - logger.debug(`pip_requirements.updateDependency(): ${upgrade.newValue}`); - const lines = fileContent.split('\n'); - const oldValue = lines[upgrade.managerData.lineNumber]; - let newValue; - const multiDependencyRegex = new RegExp( - `(install_requires\\s*[=]\\s*\\[.*)(${upgrade.depName}.+?(?='))(.*])`, - 'g' - ); - const multipleDependencyMatch = multiDependencyRegex.exec(oldValue); - if (multipleDependencyMatch) { - const dependency = multipleDependencyMatch[2]; - const updatedDependency = dependency.replace( - new RegExp(dependencyPattern), - `$1$2${upgrade.newValue}` - ); - newValue = oldValue.replace( - multiDependencyRegex, - `$1${updatedDependency}$3` - ); - } else { - newValue = oldValue.replace( - new RegExp(dependencyPattern), - `$1$2${upgrade.newValue}` - ); - } - lines[upgrade.managerData.lineNumber] = newValue; - return lines.join('\n'); - } catch (err) { - logger.debug({ err }, 'Error setting new package version'); - return null; - } -} diff --git a/lib/manager/pip_setup/index.ts b/lib/manager/pip_setup/index.ts index 2fea579e20a0a01ce38767c709b374402450b367..854761c722224c2d1000a4770b2490f86b339741 100644 --- a/lib/manager/pip_setup/index.ts +++ b/lib/manager/pip_setup/index.ts @@ -1,10 +1,11 @@ import { LANGUAGE_PYTHON } from '../../constants/languages'; export { extractPackageFile } from './extract'; -export { updateDependency } from '../pip_requirements/update'; export const language = LANGUAGE_PYTHON; +export const autoReplace = true; + export const defaultConfig = { fileMatch: ['(^|/)setup.py$'], };