From bcaaee503c5b2e876d67d5f02c9a9d320daa4ebe Mon Sep 17 00:00:00 2001
From: Maxim Danilov <maxdanilov@users.noreply.github.com>
Date: Tue, 4 Aug 2020 11:12:40 +0200
Subject: [PATCH] feat(jenkins): Add Jenkins plugin manager (#6668)

---
 lib/manager/jenkins/__fixtures__/empty.txt    |  0
 lib/manager/jenkins/__fixtures__/plugins.txt  |  8 +++++
 .../__snapshots__/extract.spec.ts.snap        | 30 +++++++++++++++++++
 lib/manager/jenkins/extract.spec.ts           | 28 +++++++++++++++++
 lib/manager/jenkins/extract.ts                | 28 +++++++++++++++++
 lib/manager/jenkins/index.ts                  |  5 ++++
 lib/manager/jenkins/readme.md                 | 10 +++++++
 7 files changed, 109 insertions(+)
 create mode 100644 lib/manager/jenkins/__fixtures__/empty.txt
 create mode 100644 lib/manager/jenkins/__fixtures__/plugins.txt
 create mode 100644 lib/manager/jenkins/__snapshots__/extract.spec.ts.snap
 create mode 100644 lib/manager/jenkins/extract.spec.ts
 create mode 100644 lib/manager/jenkins/extract.ts
 create mode 100644 lib/manager/jenkins/index.ts
 create mode 100644 lib/manager/jenkins/readme.md

diff --git a/lib/manager/jenkins/__fixtures__/empty.txt b/lib/manager/jenkins/__fixtures__/empty.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/lib/manager/jenkins/__fixtures__/plugins.txt b/lib/manager/jenkins/__fixtures__/plugins.txt
new file mode 100644
index 0000000000..a2a8b2f1b4
--- /dev/null
+++ b/lib/manager/jenkins/__fixtures__/plugins.txt
@@ -0,0 +1,8 @@
+email-ext:1.2.3
+
+apache-httpcomponents-client-4-api:4.4.10-2.0 # comment
+authentication-tokens:1.2
+blueocean:1.21.0 # another comment
+#blueocean:1.22.0
+
+# this line is completely ignored
diff --git a/lib/manager/jenkins/__snapshots__/extract.spec.ts.snap b/lib/manager/jenkins/__snapshots__/extract.spec.ts.snap
new file mode 100644
index 0000000000..c2b0d7e642
--- /dev/null
+++ b/lib/manager/jenkins/__snapshots__/extract.spec.ts.snap
@@ -0,0 +1,30 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`manager/jenkins/extract extractPackageFile() extracts multiple image lines 1`] = `
+Array [
+  Object {
+    "currentValue": "1.2.3",
+    "datasource": "jenkins-plugins",
+    "depName": "email-ext",
+    "versioning": "docker",
+  },
+  Object {
+    "currentValue": "4.4.10-2.0",
+    "datasource": "jenkins-plugins",
+    "depName": "apache-httpcomponents-client-4-api",
+    "versioning": "docker",
+  },
+  Object {
+    "currentValue": "1.2",
+    "datasource": "jenkins-plugins",
+    "depName": "authentication-tokens",
+    "versioning": "docker",
+  },
+  Object {
+    "currentValue": "1.21.0",
+    "datasource": "jenkins-plugins",
+    "depName": "blueocean",
+    "versioning": "docker",
+  },
+]
+`;
diff --git a/lib/manager/jenkins/extract.spec.ts b/lib/manager/jenkins/extract.spec.ts
new file mode 100644
index 0000000000..348e5a60c7
--- /dev/null
+++ b/lib/manager/jenkins/extract.spec.ts
@@ -0,0 +1,28 @@
+import { readFileSync } from 'fs';
+import { getName } from '../../../test/util';
+import { extractPackageFile } from './extract';
+
+const pluginsFile = readFileSync(
+  'lib/manager/jenkins/__fixtures__/plugins.txt',
+  'utf8'
+);
+
+const pluginsEmptyFile = readFileSync(
+  'lib/manager/jenkins/__fixtures__/empty.txt',
+  'utf8'
+);
+
+describe(getName(__filename), () => {
+  describe('extractPackageFile()', () => {
+    it('returns empty list for an empty file', () => {
+      const res = extractPackageFile(pluginsEmptyFile);
+      expect(res.deps).toHaveLength(0);
+    });
+
+    it('extracts multiple image lines', () => {
+      const res = extractPackageFile(pluginsFile);
+      expect(res.deps).toMatchSnapshot();
+      expect(res.deps).toHaveLength(4);
+    });
+  });
+});
diff --git a/lib/manager/jenkins/extract.ts b/lib/manager/jenkins/extract.ts
new file mode 100644
index 0000000000..90206ebe7f
--- /dev/null
+++ b/lib/manager/jenkins/extract.ts
@@ -0,0 +1,28 @@
+import * as datasourceJenkins from '../../datasource/jenkins-plugins';
+import { logger } from '../../logger';
+import * as dockerVersioning from '../../versioning/docker';
+import { PackageDependency, PackageFile } from '../common';
+
+export function extractPackageFile(content: string): PackageFile | null {
+  logger.trace('jenkins.extractPackageFile()');
+  const deps: PackageDependency[] = [];
+  const regex = /^\s*(?<depName>[\d\w-]+):(?<currentValue>[^#\s]+).*$/;
+
+  for (const line of content.split('\n')) {
+    const match = regex.exec(line);
+
+    if (match) {
+      const { depName, currentValue } = match.groups;
+      const dep: PackageDependency = {
+        datasource: datasourceJenkins.id,
+        versioning: dockerVersioning.id,
+        depName,
+        currentValue,
+      };
+
+      deps.push(dep);
+    }
+  }
+
+  return { deps };
+}
diff --git a/lib/manager/jenkins/index.ts b/lib/manager/jenkins/index.ts
new file mode 100644
index 0000000000..c33e432967
--- /dev/null
+++ b/lib/manager/jenkins/index.ts
@@ -0,0 +1,5 @@
+export { extractPackageFile } from './extract';
+
+export const defaultConfig = {
+  fileMatch: ['(^|/)plugins\\.txt'],
+};
diff --git a/lib/manager/jenkins/readme.md b/lib/manager/jenkins/readme.md
new file mode 100644
index 0000000000..6c500dde40
--- /dev/null
+++ b/lib/manager/jenkins/readme.md
@@ -0,0 +1,10 @@
+The Jenkins manager suppports the following format of the plugin list:
+
+```text
+plugin1:1.2.3
+plugin2:4.5 # this is a comment
+
+# this line is ignored
+```
+
+There's no strict specification on the name of the files, but usually it's `plugins.txt`
-- 
GitLab