From 48278ad247faeb7666a940f85c7cc9935705c4fc Mon Sep 17 00:00:00 2001
From: Ayoub Kaanich <kayoub5@live.com>
Date: Fri, 9 Nov 2018 13:51:23 +0100
Subject: [PATCH] fix(pip): requirements.txt extras (#2773)

---
 lib/manager/pip_requirements/extract.js          | 16 ++++++----------
 lib/manager/pip_requirements/update.js           |  6 ++++--
 .../__snapshots__/update.spec.js.snap            |  6 +++---
 test/manager/pip_requirements/update.spec.js     |  4 ++--
 4 files changed, 15 insertions(+), 17 deletions(-)

diff --git a/lib/manager/pip_requirements/extract.js b/lib/manager/pip_requirements/extract.js
index 70525fbdf3..ec6db816d4 100644
--- a/lib/manager/pip_requirements/extract.js
+++ b/lib/manager/pip_requirements/extract.js
@@ -3,13 +3,12 @@ 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(
-  /\?<\w+>/g,
-  '?:'
-)}\\s*`;
-const specifierPattern = `${specifierPartPattern}(?:,${specifierPartPattern})*`;
+const specifierPartPattern = `\\s*${rangePattern.replace(/\?<\w+>/g, '?:')}`;
+const specifierPattern = `${specifierPartPattern}(?:\\s*,${specifierPartPattern})*`;
+const dependencyPattern = `(${packagePattern})(${extrasPattern})(${specifierPattern})`;
 
 module.exports = {
+  dependencyPattern,
   packagePattern,
   extractPackageFile,
 };
@@ -25,10 +24,7 @@ function extractPackageFile(content) {
     }
   });
 
-  const regex = new RegExp(
-    `^(${packagePattern})${extrasPattern}(${specifierPattern})$`,
-    'g'
-  );
+  const regex = new RegExp(`^${dependencyPattern}$`, 'g');
   const deps = content
     .split('\n')
     .map((rawline, lineNumber) => {
@@ -50,7 +46,7 @@ function extractPackageFile(content) {
       if (!matches) {
         return null;
       }
-      const [, depName, currentValue] = matches;
+      const [, depName, , currentValue] = matches;
       dep = {
         ...dep,
         depName,
diff --git a/lib/manager/pip_requirements/update.js b/lib/manager/pip_requirements/update.js
index 8d8140ead1..7abccae162 100644
--- a/lib/manager/pip_requirements/update.js
+++ b/lib/manager/pip_requirements/update.js
@@ -1,3 +1,5 @@
+const { dependencyPattern } = require('./extract');
+
 module.exports = {
   updateDependency,
 };
@@ -8,8 +10,8 @@ function updateDependency(fileContent, upgrade) {
     const lines = fileContent.split('\n');
     const oldValue = lines[upgrade.lineNumber];
     const newValue = oldValue.replace(
-      /^.+?(\s.*)?$/,
-      `${upgrade.depName}${upgrade.newValue}$1`
+      new RegExp(dependencyPattern),
+      `$1$2${upgrade.newValue}`
     );
     lines[upgrade.lineNumber] = newValue;
     return lines.join('\n');
diff --git a/test/manager/pip_requirements/__snapshots__/update.spec.js.snap b/test/manager/pip_requirements/__snapshots__/update.spec.js.snap
index dd8609c522..70e8df81c7 100644
--- a/test/manager/pip_requirements/__snapshots__/update.spec.js.snap
+++ b/test/manager/pip_requirements/__snapshots__/update.spec.js.snap
@@ -3,7 +3,7 @@
 exports[`manager/pip_requirements/update updateDependency replaces existing value 1`] = `
 "--index-url http://example.com/private-pypi/
 # simple comment
-url==1.0.1
+some-package==1.0.1
 some-other-package==1.0.0
 not_semver==1.9
 
@@ -21,7 +21,7 @@ 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
+celery [redis]==4.1.2
+foo [bar] == 3.2.1 # handles extra white space
 "
 `;
diff --git a/test/manager/pip_requirements/update.spec.js b/test/manager/pip_requirements/update.spec.js
index bf82236d41..8e5bad7fad 100644
--- a/test/manager/pip_requirements/update.spec.js
+++ b/test/manager/pip_requirements/update.spec.js
@@ -22,7 +22,7 @@ describe('manager/pip_requirements/update', () => {
   describe('updateDependency', () => {
     it('replaces existing value', () => {
       const upgrade = {
-        depName: 'url',
+        depName: 'some-package',
         lineNumber: 2,
         newValue: '==1.0.1',
       };
@@ -50,7 +50,7 @@ describe('manager/pip_requirements/update', () => {
     it('replaces existing value with extras', () => {
       const upgrade = {
         depName: 'celery',
-        lineNumber: 2,
+        lineNumber: 1,
         newValue: '==4.1.2',
       };
       const res = updateDependency(requirements4, upgrade);
-- 
GitLab