From b0d1de8e595b482cc11a6275ba1ab47ab989e3d2 Mon Sep 17 00:00:00 2001
From: Michael Kriese <michael.kriese@visualon.de>
Date: Sun, 25 Aug 2019 14:29:51 +0200
Subject: [PATCH] fix: optional re2 package (#4367)

---
 lib/util/regex.ts             | 22 ++++++++++++++++++++++
 lib/versioning/regex/index.ts |  4 ++--
 package.json                  |  4 +++-
 test/util/regex.spec.ts       | 21 +++++++++++++++++++++
 4 files changed, 48 insertions(+), 3 deletions(-)
 create mode 100644 lib/util/regex.ts
 create mode 100644 test/util/regex.spec.ts

diff --git a/lib/util/regex.ts b/lib/util/regex.ts
new file mode 100644
index 0000000000..b109ffde07
--- /dev/null
+++ b/lib/util/regex.ts
@@ -0,0 +1,22 @@
+import { logger } from '../logger';
+
+export interface RegExConstructor {
+  new (pattern: RegExp | string): RegExp;
+  new (pattern: string, flags?: string): RegExp;
+}
+
+const RegEx: RegExConstructor = (() => {
+  try {
+    // eslint-disable-next-line
+    const RE2 = require('re2');
+    // Test if native is working
+    new RE2('.*').exec('test');
+    logger.debug('Using RE2 as regex engine');
+    return RE2;
+  } catch (err) {
+    logger.warn({ err }, 'RE2 not usable, falling back to RegExp');
+    return RegExp;
+  }
+})();
+
+export { RegEx };
diff --git a/lib/versioning/regex/index.ts b/lib/versioning/regex/index.ts
index 2f201f35bc..94e2c1c672 100644
--- a/lib/versioning/regex/index.ts
+++ b/lib/versioning/regex/index.ts
@@ -1,8 +1,8 @@
 import { compare, satisfies, ltr, minSatisfying, maxSatisfying } from 'semver';
-import RE2 from 're2';
 import { VersioningApiConstructor } from '../common';
 import { GenericVersion, GenericVersioningApi } from '../loose/generic';
 import { logger } from '../../logger';
+import { RegEx } from '../../util/regex';
 
 export interface RegExpVersion extends GenericVersion {
   /** prereleases are treated in the standard semver manner, if present */
@@ -50,7 +50,7 @@ export class RegExpVersioningApi extends GenericVersioningApi<RegExpVersion> {
     // capture groups?
 
     try {
-      this._config = new RE2(new_config);
+      this._config = new RegEx(new_config);
     } catch (e) {
       logger.debug({ err: e }, 'regex error');
       const error = new Error('config-validation');
diff --git a/package.json b/package.json
index 808ebd0587..d3d24f7430 100644
--- a/package.json
+++ b/package.json
@@ -137,7 +137,6 @@
     "parse-diff": "0.5.1",
     "parse-link-header": "1.0.1",
     "pnpm": "3.7.5",
-    "re2": "1.10.0",
     "registry-auth-token": "4.0.0",
     "safe-regex": "2.0.2",
     "semver": "6.3.0",
@@ -155,6 +154,9 @@
     "yarn": "1.17.3",
     "yawn-yaml": "1.4.0"
   },
+  "optionalDependencies": {
+    "re2": "1.10.0"
+  },
   "devDependencies": {
     "@babel/cli": "7.5.5",
     "@babel/core": "7.5.5",
diff --git a/test/util/regex.spec.ts b/test/util/regex.spec.ts
new file mode 100644
index 0000000000..f99dd32510
--- /dev/null
+++ b/test/util/regex.spec.ts
@@ -0,0 +1,21 @@
+import RE2 from 're2';
+import { RegEx } from '../../lib/util/regex';
+
+describe('util/regex', () => {
+  beforeEach(() => {
+    jest.resetModules();
+  });
+
+  it('uses RE2', () => {
+    expect(RegEx).toEqual(RE2);
+  });
+
+  it('Falls back to RegExp', () => {
+    jest.doMock('re2', () => {
+      throw new Error();
+    });
+
+    const regex = require('../../lib/util/regex');
+    expect(regex.RegEx).toEqual(RegExp);
+  });
+});
-- 
GitLab