From 67cbbba80b0ecea25c2f2f575b6cb0c1c72cff76 Mon Sep 17 00:00:00 2001
From: Rhys Arkins <rhys@arkins.net>
Date: Mon, 4 Feb 2019 21:31:04 +0100
Subject: [PATCH] fix: Revert "feat(gradle): use maven datasource (#3062)"

This reverts commit 0a2b212c76fe53925ae13dfa4d2162d563ce9622.
---
 lib/config/definitions.js                     |   1 -
 lib/manager/gradle/gradle-updates-report.js   | 118 ------------------
 lib/manager/gradle/index.js                   | 114 +++++++++++++----
 .../gradle/MultiProjectUpdatesReport.json     |  38 ------
 test/_fixtures/gradle/updatesReport.json      |  89 ++++++++++---
 test/_fixtures/gradle/updatesReportEmpty.json |  32 +++--
 test/datasource/maven.spec.js                 |   5 -
 .../gradle/__snapshots__/index.spec.js.snap   | 113 ++++++++---------
 test/manager/gradle/index.spec.js             |  78 +++++++-----
 9 files changed, 281 insertions(+), 307 deletions(-)
 delete mode 100644 lib/manager/gradle/gradle-updates-report.js
 delete mode 100644 test/_fixtures/gradle/MultiProjectUpdatesReport.json

diff --git a/lib/config/definitions.js b/lib/config/definitions.js
index 66abc9ae7e..24e074f838 100644
--- a/lib/config/definitions.js
+++ b/lib/config/definitions.js
@@ -1364,7 +1364,6 @@ const options = [
       enabled: false,
       fileMatch: ['\\.gradle$', '(^|/)gradle.properties$'],
       timeout: 300,
-      versionScheme: 'maven',
     },
     mergeable: true,
     cli: false,
diff --git a/lib/manager/gradle/gradle-updates-report.js b/lib/manager/gradle/gradle-updates-report.js
deleted file mode 100644
index bef15e6e7c..0000000000
--- a/lib/manager/gradle/gradle-updates-report.js
+++ /dev/null
@@ -1,118 +0,0 @@
-const path = require('path');
-const fs = require('fs-extra');
-
-const GRADLE_DEPENDENCY_REPORT_FILENAME = 'gradle-renovate-report.json';
-
-async function createRenovateGradlePlugin(localDir) {
-  const content = `
-import groovy.json.JsonOutput
-import org.gradle.api.internal.artifacts.dependencies.DefaultExternalModuleDependency
-import java.util.concurrent.ConcurrentLinkedQueue
-
-def output = new ConcurrentLinkedQueue<>();
-
-allprojects {
-  tasks.register("renovate") {
-    doLast {
-        def project = ['project': project.name]
-        output << project
-        def repos = repositories
-           .collect { "$it.url" }
-           .findAll { !it.startsWith('file:') }
-        project.repositories = repos
-        def deps = configurations.collect { config ->
-          config.dependencies
-            .find { it instanceof DefaultExternalModuleDependency }
-            .collect { ['name':it.name, 'group':it.group, 'version':it.version] }
-        }.flatten()
-        project.dependencies = deps
-    }
-  }
-}
-
-gradle.buildFinished {
-   def outputFile = new File('${GRADLE_DEPENDENCY_REPORT_FILENAME}')
-   def json = JsonOutput.toJson(output)
-   outputFile.write json
-}  `;
-  const gradleInitFile = path.join(localDir, 'renovate-plugin.gradle');
-  logger.debug(
-    'Creating renovate-plugin.gradle file with renovate gradle plugin'
-  );
-  await fs.writeFile(gradleInitFile, content);
-}
-
-async function extractDependenciesFromUpdatesReport(localDir) {
-  const gradleProjectConfigurations = await readGradleReport(localDir);
-
-  const dependencies = gradleProjectConfigurations
-    .map(mergeDependenciesWithRepositories, [])
-    .reduce(flatternDependencies, [])
-    .reduce(combineReposOnDuplicatedDependencies, []);
-
-  return dependencies.map(gradleModule => buildDependency(gradleModule));
-}
-
-async function readGradleReport(localDir) {
-  const renovateReportFilename = path.join(
-    localDir,
-    GRADLE_DEPENDENCY_REPORT_FILENAME
-  );
-  if (!(await fs.exists(renovateReportFilename))) {
-    return [];
-  }
-
-  const contents = await fs.readFile(renovateReportFilename, 'utf8');
-  try {
-    return JSON.parse(contents);
-  } catch (e) {
-    logger.error('Invalid JSON', e);
-    return [];
-  }
-}
-
-function mergeDependenciesWithRepositories(project) {
-  if (!project.dependencies) {
-    return [];
-  }
-  return project.dependencies.map(dep => ({
-    ...dep,
-    repos: [...project.repositories],
-  }));
-}
-
-function flatternDependencies(accumulator, currentValue) {
-  accumulator.push(...currentValue);
-  return accumulator;
-}
-
-function combineReposOnDuplicatedDependencies(accumulator, currentValue) {
-  const existingDependency = accumulator.find(
-    dep => dep.name === currentValue.name
-  );
-  if (!existingDependency) {
-    accumulator.push(currentValue);
-  } else {
-    existingDependency.repos.push(...currentValue.repos);
-  }
-  return accumulator;
-}
-
-function buildDependency(gradleModule) {
-  const repositories = gradleModule.repos.join(',');
-  return {
-    name: gradleModule.name,
-    depGroup: gradleModule.group,
-    depName: `${gradleModule.group}:${gradleModule.name}`,
-    currentValue: gradleModule.version,
-    purl: `pkg:maven/${gradleModule.group}/${
-      gradleModule.name
-    }?repository_url=${repositories}`,
-  };
-}
-
-module.exports = {
-  extractDependenciesFromUpdatesReport,
-  createRenovateGradlePlugin,
-  GRADLE_DEPENDENCY_REPORT_FILENAME,
-};
diff --git a/lib/manager/gradle/index.js b/lib/manager/gradle/index.js
index 174bfc5ab1..87b66b226a 100644
--- a/lib/manager/gradle/index.js
+++ b/lib/manager/gradle/index.js
@@ -3,10 +3,10 @@ const fs = require('fs-extra');
 const path = require('path');
 
 const gradle = require('./build-gradle');
-const updatesReport = require('./gradle-updates-report');
 
 const GRADLE_DEPENDENCY_REPORT_COMMAND =
-  'gradle --init-script renovate-plugin.gradle renovate';
+  'gradle --init-script init.gradle dependencyUpdates -Drevision=release';
+const GRADLE_DEPENDENCY_REPORT_FILENAME = 'build/dependencyUpdates/report.json';
 const TIMEOUT_CODE = 143;
 
 async function extractAllPackageFiles(config, packageFiles) {
@@ -25,56 +25,125 @@ async function extractAllPackageFiles(config, packageFiles) {
     }
   }
 
-  await updatesReport.createRenovateGradlePlugin(config.localDir);
+  await configureUseLatestVersionPlugin(config.localDir);
   const gradleSuccess = await executeGradle(config);
   if (!gradleSuccess) {
-    logger.warn('No gradle dependencies found');
     return null;
   }
 
   gradle.init();
-
-  const dependencies = await updatesReport.extractDependenciesFromUpdatesReport(
-    config.localDir
-  );
-  if (dependencies.length === 0) {
-    return [];
-  }
-
   const gradleFiles = [];
   for (const packageFile of packageFiles) {
     const content = await platform.getFile(packageFile);
     if (content) {
-      gradleFiles.push({
-        packageFile,
-        manager: 'gradle',
-        deps: dependencies,
-      });
-
-      gradle.collectVersionVariables(dependencies, content);
+      const deps = await extractPackageFile(content, packageFile, config);
+      if (deps) {
+        gradleFiles.push({
+          packageFile,
+          manager: 'gradle',
+          ...deps,
+        });
+      }
     } else {
       logger.info({ packageFile }, 'packageFile has no content');
     }
   }
-
   return gradleFiles;
 }
 
+async function extractPackageFile(content, fileName, config) {
+  logger.debug(`gradle.extractPackageFile(filename=${fileName})`);
+  const gradleFile = path.join(config.localDir, fileName);
+  const baseDir = path.dirname(gradleFile);
+
+  const deps = await extractDependenciesFromUpdatesReport(baseDir);
+  gradle.collectVersionVariables(deps, content);
+  return deps.length > 0 ? { deps } : null;
+}
+
+function getPackageUpdates(config) {
+  logger.debug(`gradle.getPackageUpdates(depName=${config.depName})`);
+
+  if (config.available) {
+    return [
+      {
+        depName: config.depName,
+        newValue: config.available.release,
+      },
+    ];
+  }
+  return [];
+}
+
 function updateDependency(fileContent, upgrade) {
   // prettier-ignore
   logger.debug(`gradle.updateDependency(): packageFile:${upgrade.packageFile} depName:${upgrade.depName}, version:${upgrade.version} ==> ${upgrade.newValue}`);
 
-  return gradle.updateGradleVersion(
+  const newFileContent = gradle.updateGradleVersion(
     fileContent,
     buildGradleDependency(upgrade),
-    upgrade.newValue
+    upgrade.available.release
   );
+  return newFileContent;
+}
+
+async function configureUseLatestVersionPlugin(localDir) {
+  const content = `
+gradle.projectsLoaded {
+    rootProject.allprojects {
+        buildscript {
+            repositories {
+                maven {
+                 url "https://plugins.gradle.org/m2/"
+                }
+            }
+           dependencies {
+            classpath "gradle.plugin.se.patrikerdes:gradle-use-latest-versions-plugin:0.2.3"
+            classpath 'com.github.ben-manes:gradle-versions-plugin:0.17.0'
+          }
+        }
+        afterEvaluate { project ->
+          project.apply plugin: 'com.github.ben-manes.versions'
+          project.apply plugin: 'se.patrikerdes.use-latest-versions'
+        }
+    }
+}
+  `;
+  const gradleInitFile = path.join(localDir, 'init.gradle');
+  logger.debug('Creating init.gradle file');
+  await fs.writeFile(gradleInitFile, content);
 }
 
 function buildGradleDependency(config) {
   return { group: config.depGroup, name: config.name, version: config.version };
 }
 
+async function extractDependenciesFromUpdatesReport(localDir) {
+  const filename = path.join(localDir, GRADLE_DEPENDENCY_REPORT_FILENAME);
+  if (!(await fs.exists(filename))) {
+    return [];
+  }
+
+  const contents = await fs.readFile(
+    path.join(localDir, GRADLE_DEPENDENCY_REPORT_FILENAME),
+    'utf8'
+  );
+  const dependencies = JSON.parse(contents);
+  const combinedGradleDeps = dependencies.current.dependencies.concat(
+    dependencies.exceeded.dependencies,
+    dependencies.outdated.dependencies,
+    dependencies.unresolved.dependencies
+  );
+  return combinedGradleDeps.map(gradleModule => {
+    const dependency = { ...gradleModule };
+    delete dependency.group;
+    dependency.depGroup = gradleModule.group;
+    dependency.depName = `${gradleModule.group}:${gradleModule.name}`;
+    dependency.currentValue = gradleModule.version;
+    return dependency;
+  });
+}
+
 async function executeGradle(config) {
   let stdout;
   let stderr;
@@ -115,6 +184,7 @@ function getDockerRenovateGradleCommandLine(localDir) {
 
 module.exports = {
   extractAllPackageFiles,
+  getPackageUpdates,
   updateDependency,
   language: 'java',
 };
diff --git a/test/_fixtures/gradle/MultiProjectUpdatesReport.json b/test/_fixtures/gradle/MultiProjectUpdatesReport.json
deleted file mode 100644
index 962e19376f..0000000000
--- a/test/_fixtures/gradle/MultiProjectUpdatesReport.json
+++ /dev/null
@@ -1,38 +0,0 @@
-[
-  {
-    "project": "project1",
-    "repositories": [
-      "https://repo.maven.apache.org/maven2/"
-    ],
-    "dependencies": [
-      {
-        "name": "spring-boot-starter-jersey",
-        "group": "org.springframework.boot",
-        "version": null
-      },
-      {
-        "name": "cglib-nodep",
-        "group": "cglib",
-        "version": "3.1"
-      }
-    ]
-  },
-  {
-    "project": "project2",
-    "repositories": [
-      "https://jitpack.io"
-    ],
-    "dependencies": [
-      {
-        "name": "spring-boot-starter-jersey",
-        "group": "org.springframework.boot",
-        "version": null
-      },
-      {
-        "name": "spock-core",
-        "group": "org.spockframework",
-        "version": "1.0-groovy-2.4"
-      }
-    ]
-  }
-]
diff --git a/test/_fixtures/gradle/updatesReport.json b/test/_fixtures/gradle/updatesReport.json
index c11002de59..6e315ec129 100644
--- a/test/_fixtures/gradle/updatesReport.json
+++ b/test/_fixtures/gradle/updatesReport.json
@@ -1,26 +1,79 @@
-[
-  {
-    "project": "telegram-images",
-    "repositories": [
-      "https://repo.maven.apache.org/maven2/",
-      "https://jitpack.io"
-    ],
+{
+  "current": {
     "dependencies": [
       {
-        "name": "spring-boot-starter-jersey",
-        "group": "org.springframework.boot",
-        "version": null
+        "group": "com.fkorotkov",
+        "version": "0.1",
+        "name": "gradle-libraries-plugin"
       },
       {
-        "name": "spock-core",
-        "group": "org.spockframework",
-        "version": "1.0-groovy-2.4"
+        "group": "gradle.plugin.se.patrikerdes",
+        "version": "0.2.3",
+        "name": "gradle-use-latest-versions-plugin"
       },
       {
-        "name": "cglib-nodep",
+        "group": "org.hamcrest",
+        "version": "1.3",
+        "name": "hamcrest-core"
+      }
+    ],
+    "count": 3
+  },
+  "exceeded": {
+    "dependencies": [
+    ],
+    "count": 0
+  },
+  "outdated": {
+    "dependencies": [
+      {
         "group": "cglib",
-        "version": "3.1"
+        "available": {
+          "release": "3.2.8",
+          "milestone": null,
+          "integration": null
+        },
+        "version": "3.1",
+        "name": "cglib-nodep"
+      },
+      {
+        "group": "org.grails",
+        "available": {
+          "release": "6.1.10.RELEASE",
+          "milestone": null,
+          "integration": null
+        },
+        "version": "6.0.9.RELEASE",
+        "name": "gorm-hibernate5-spring-boot"
+      },
+      {
+        "group": "mysql",
+        "available": {
+          "release": "8.0.12",
+          "milestone": null,
+          "integration": null
+        },
+        "version": "5.1.41",
+        "name": "mysql-connector-java"
+      },
+      {
+        "group": "org.springframework.boot",
+        "available": {
+          "release": "2.0.5.RELEASE",
+          "milestone": null,
+          "integration": null
+        },
+        "version": "1.5.2.RELEASE",
+        "name": "spring-boot-starter-test"
       }
-    ]
-  }
-]
+    ],
+    "count": 4
+  },
+  "unresolved": {
+    "dependencies": [
+
+    ],
+    "count": 0
+  },
+  "count": 7
+}
diff --git a/test/_fixtures/gradle/updatesReportEmpty.json b/test/_fixtures/gradle/updatesReportEmpty.json
index 7a6996ca94..2825737569 100644
--- a/test/_fixtures/gradle/updatesReportEmpty.json
+++ b/test/_fixtures/gradle/updatesReportEmpty.json
@@ -1,9 +1,23 @@
-[
-  {
-    "project": "telegram-images",
-    "repositories": [
-      "https://repo.maven.apache.org/maven2/",
-      "https://jitpack.io"
-    ]
-  }
-]
+{
+  "current": {
+    "dependencies": [
+    ],
+    "count": 0
+  },
+  "exceeded": {
+    "dependencies": [
+    ],
+    "count": 0
+  },
+  "outdated": {
+    "dependencies": [
+    ],
+    "count": 0
+  },
+  "unresolved": {
+    "dependencies": [
+    ],
+    "count": 0
+  },
+  "count": 0
+}
diff --git a/test/datasource/maven.spec.js b/test/datasource/maven.spec.js
index 4fbac0bf3d..56b42d72a1 100644
--- a/test/datasource/maven.spec.js
+++ b/test/datasource/maven.spec.js
@@ -33,7 +33,6 @@ const config = {
 
 describe('datasource/maven', () => {
   beforeEach(() => {
-    nock.disableNetConnect();
     nock('http://central.maven.org')
       .get('/maven2/mysql/mysql-connector-java/maven-metadata.xml')
       .reply(200, MYSQL_MAVEN_METADATA);
@@ -50,10 +49,6 @@ describe('datasource/maven', () => {
       .reply(200, 'non-sense');
   });
 
-  afterEach(() => {
-    nock.enableNetConnect();
-  });
-
   describe('getPkgReleases', () => {
     it('should return empty if library is not found', async () => {
       const releases = await datasource.getPkgReleases({
diff --git a/test/manager/gradle/__snapshots__/index.spec.js.snap b/test/manager/gradle/__snapshots__/index.spec.js.snap
index 1c690178c7..53ed5f5d71 100644
--- a/test/manager/gradle/__snapshots__/index.spec.js.snap
+++ b/test/manager/gradle/__snapshots__/index.spec.js.snap
@@ -5,84 +5,73 @@ Array [
   Object {
     "deps": Array [
       Object {
-        "currentValue": null,
-        "depGroup": "org.springframework.boot",
-        "depName": "org.springframework.boot:spring-boot-starter-jersey",
-        "name": "spring-boot-starter-jersey",
-        "purl": "pkg:maven/org.springframework.boot/spring-boot-starter-jersey?repository_url=https://repo.maven.apache.org/maven2/,https://jitpack.io",
-      },
-      Object {
-        "currentValue": "1.0-groovy-2.4",
-        "depGroup": "org.spockframework",
-        "depName": "org.spockframework:spock-core",
-        "name": "spock-core",
-        "purl": "pkg:maven/org.spockframework/spock-core?repository_url=https://repo.maven.apache.org/maven2/,https://jitpack.io",
-      },
-      Object {
-        "currentValue": "3.1",
-        "depGroup": "cglib",
-        "depName": "cglib:cglib-nodep",
-        "name": "cglib-nodep",
-        "purl": "pkg:maven/cglib/cglib-nodep?repository_url=https://repo.maven.apache.org/maven2/,https://jitpack.io",
+        "currentValue": "0.1",
+        "depGroup": "com.fkorotkov",
+        "depName": "com.fkorotkov:gradle-libraries-plugin",
+        "name": "gradle-libraries-plugin",
+        "version": "0.1",
       },
-    ],
-    "manager": "gradle",
-    "packageFile": "build.gradle",
-  },
-  Object {
-    "deps": Array [
       Object {
-        "currentValue": null,
-        "depGroup": "org.springframework.boot",
-        "depName": "org.springframework.boot:spring-boot-starter-jersey",
-        "name": "spring-boot-starter-jersey",
-        "purl": "pkg:maven/org.springframework.boot/spring-boot-starter-jersey?repository_url=https://repo.maven.apache.org/maven2/,https://jitpack.io",
+        "currentValue": "0.2.3",
+        "depGroup": "gradle.plugin.se.patrikerdes",
+        "depName": "gradle.plugin.se.patrikerdes:gradle-use-latest-versions-plugin",
+        "name": "gradle-use-latest-versions-plugin",
+        "version": "0.2.3",
       },
       Object {
-        "currentValue": "1.0-groovy-2.4",
-        "depGroup": "org.spockframework",
-        "depName": "org.spockframework:spock-core",
-        "name": "spock-core",
-        "purl": "pkg:maven/org.spockframework/spock-core?repository_url=https://repo.maven.apache.org/maven2/,https://jitpack.io",
+        "currentValue": "1.3",
+        "depGroup": "org.hamcrest",
+        "depName": "org.hamcrest:hamcrest-core",
+        "name": "hamcrest-core",
+        "version": "1.3",
       },
       Object {
+        "available": Object {
+          "integration": null,
+          "milestone": null,
+          "release": "3.2.8",
+        },
         "currentValue": "3.1",
         "depGroup": "cglib",
         "depName": "cglib:cglib-nodep",
         "name": "cglib-nodep",
-        "purl": "pkg:maven/cglib/cglib-nodep?repository_url=https://repo.maven.apache.org/maven2/,https://jitpack.io",
+        "version": "3.1",
       },
-    ],
-    "manager": "gradle",
-    "packageFile": "subproject/build.gradle",
-  },
-]
-`;
-
-exports[`manager/gradle extractPackageFile should use repositories only for current project 1`] = `
-Array [
-  Object {
-    "deps": Array [
       Object {
-        "currentValue": null,
-        "depGroup": "org.springframework.boot",
-        "depName": "org.springframework.boot:spring-boot-starter-jersey",
-        "name": "spring-boot-starter-jersey",
-        "purl": "pkg:maven/org.springframework.boot/spring-boot-starter-jersey?repository_url=https://repo.maven.apache.org/maven2/,https://jitpack.io",
+        "available": Object {
+          "integration": null,
+          "milestone": null,
+          "release": "6.1.10.RELEASE",
+        },
+        "currentValue": "6.0.9.RELEASE",
+        "depGroup": "org.grails",
+        "depName": "org.grails:gorm-hibernate5-spring-boot",
+        "name": "gorm-hibernate5-spring-boot",
+        "version": "6.0.9.RELEASE",
       },
       Object {
-        "currentValue": "3.1",
-        "depGroup": "cglib",
-        "depName": "cglib:cglib-nodep",
-        "name": "cglib-nodep",
-        "purl": "pkg:maven/cglib/cglib-nodep?repository_url=https://repo.maven.apache.org/maven2/",
+        "available": Object {
+          "integration": null,
+          "milestone": null,
+          "release": "8.0.12",
+        },
+        "currentValue": "5.1.41",
+        "depGroup": "mysql",
+        "depName": "mysql:mysql-connector-java",
+        "name": "mysql-connector-java",
+        "version": "5.1.41",
       },
       Object {
-        "currentValue": "1.0-groovy-2.4",
-        "depGroup": "org.spockframework",
-        "depName": "org.spockframework:spock-core",
-        "name": "spock-core",
-        "purl": "pkg:maven/org.spockframework/spock-core?repository_url=https://jitpack.io",
+        "available": Object {
+          "integration": null,
+          "milestone": null,
+          "release": "2.0.5.RELEASE",
+        },
+        "currentValue": "1.5.2.RELEASE",
+        "depGroup": "org.springframework.boot",
+        "depName": "org.springframework.boot:spring-boot-starter-test",
+        "name": "spring-boot-starter-test",
+        "version": "1.5.2.RELEASE",
       },
     ],
     "manager": "gradle",
diff --git a/test/manager/gradle/index.spec.js b/test/manager/gradle/index.spec.js
index 3f3fe529a3..4351bdc866 100644
--- a/test/manager/gradle/index.spec.js
+++ b/test/manager/gradle/index.spec.js
@@ -5,9 +5,6 @@ const { toUnix } = require('upath');
 const fs = require('fs-extra');
 const fsReal = require('fs');
 const { exec } = require('child-process-promise');
-const { initLogger } = require('../../../lib/logger');
-
-initLogger();
 
 const manager = require('../../../lib/manager/gradle/index');
 
@@ -37,7 +34,6 @@ describe('manager/gradle', () => {
     it('should return gradle dependencies', async () => {
       const dependencies = await manager.extractAllPackageFiles(config, [
         'build.gradle',
-        'subproject/build.gradle',
       ]);
       expect(dependencies).toMatchSnapshot();
     });
@@ -76,36 +72,11 @@ describe('manager/gradle', () => {
       expect(dependencies).toEqual([]);
     });
 
-    it('should return empty if renovate report is invalid', async () => {
-      const renovateReport = `
-        Invalid JSON]
-      `;
-      fs.readFile.mockReturnValue(renovateReport);
-
-      const dependencies = await manager.extractAllPackageFiles(config, [
-        'build.gradle',
-      ]);
-      expect(dependencies).toEqual([]);
-    });
-
-    it('should use repositories only for current project', async () => {
-      const multiProjectUpdatesReport = fsReal.readFileSync(
-        'test/_fixtures/gradle/MultiProjectUpdatesReport.json',
-        'utf8'
-      );
-      fs.readFile.mockReturnValue(multiProjectUpdatesReport);
-
-      const dependencies = await manager.extractAllPackageFiles(config, [
-        'build.gradle',
-      ]);
-      expect(dependencies).toMatchSnapshot();
-    });
-
     it('should execute gradle with the proper parameters', async () => {
       await manager.extractAllPackageFiles(config, ['build.gradle']);
 
       expect(exec.mock.calls[0][0]).toBe(
-        'gradle --init-script renovate-plugin.gradle renovate'
+        'gradle --init-script init.gradle dependencyUpdates -Drevision=release'
       );
       expect(exec.mock.calls[0][1]).toMatchObject({
         cwd: 'localDir',
@@ -122,6 +93,14 @@ describe('manager/gradle', () => {
       expect(exec.mock.calls.length).toBe(0);
     });
 
+    it('should return empty if not content', async () => {
+      platform.getFile.mockReturnValue(null);
+      const res = await manager.extractAllPackageFiles(config, [
+        'build.gradle',
+      ]);
+      expect(res).toEqual([]);
+    });
+
     it('should write files before extracting', async () => {
       const packageFiles = ['build.gradle', 'foo/build.gradle'];
       await manager.extractAllPackageFiles(config, packageFiles);
@@ -146,11 +125,11 @@ describe('manager/gradle', () => {
       expect(fs.outputFile.mock.calls.length).toBe(0);
     });
 
-    it('should configure the renovate report plugin', async () => {
+    it('should configure the useLatestVersion plugin', async () => {
       await manager.extractAllPackageFiles(config, ['build.gradle']);
 
       expect(toUnix(fs.writeFile.mock.calls[0][0])).toBe(
-        'localDir/renovate-plugin.gradle'
+        'localDir/init.gradle'
       );
     });
 
@@ -162,11 +141,41 @@ describe('manager/gradle', () => {
       await manager.extractAllPackageFiles(configWithDocker, ['build.gradle']);
 
       expect(exec.mock.calls[0][0]).toBe(
-        'docker run --rm -v localDir:localDir -w localDir renovate/gradle gradle --init-script renovate-plugin.gradle renovate'
+        'docker run --rm -v localDir:localDir -w localDir renovate/gradle gradle --init-script init.gradle dependencyUpdates -Drevision=release'
       );
     });
   });
 
+  describe('getPackageUpdates', () => {
+    it('should return the new version if it is available', async () => {
+      const newVersion = {
+        ...config,
+        depName: 'cglib:cglib-nodep',
+        available: {
+          release: '3.2.8',
+        },
+      };
+      const outdatedDependencies = await manager.getPackageUpdates(newVersion);
+
+      expect(outdatedDependencies).toMatchObject([
+        {
+          depName: 'cglib:cglib-nodep',
+          newValue: '3.2.8',
+        },
+      ]);
+    });
+
+    it('should return empty if there is no new version', async () => {
+      const newVersion = {
+        ...config,
+        depName: 'cglib:cglib-nodep',
+      };
+      const outdatedDependencies = await manager.getPackageUpdates(newVersion);
+
+      expect(outdatedDependencies).toMatchObject([]);
+    });
+  });
+
   describe('updateDependency', () => {
     it('should update an existing dependency', () => {
       const buildGradleContent = fsReal.readFileSync(
@@ -175,7 +184,8 @@ describe('manager/gradle', () => {
       );
       // prettier-ignore
       const upgrade = {
-        depGroup: 'cglib', name: 'cglib-nodep', version: '3.1', newValue: '3.2.8'
+        depGroup: 'cglib', name: 'cglib-nodep', version: '3.1',
+        available: { release: '3.2.8', milestone: null, integration: null },
       };
       const buildGradleContentUpdated = manager.updateDependency(
         buildGradleContent,
-- 
GitLab