Skip to content

Commit

Permalink
feat(gradle): use java image for docker mode (#11316)
Browse files Browse the repository at this point in the history
  • Loading branch information
viceice authored Aug 19, 2021
1 parent 68ebe08 commit ae0ac14
Show file tree
Hide file tree
Showing 13 changed files with 426 additions and 163 deletions.
18 changes: 9 additions & 9 deletions lib/manager/gradle-wrapper/artifacts-real.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type { RepoGlobalConfig } from '../../config/types';
import type { StatusResult } from '../../util/git';
import { ifSystemSupportsGradle } from '../gradle/deep/__testutil__/gradle';
import type { UpdateArtifactsConfig } from '../types';
import * as dcUpdate from '.';
import * as gradleWrapper from '.';

jest.mock('../../util/git');

Expand Down Expand Up @@ -60,7 +60,7 @@ describe('manager/gradle-wrapper/artifacts-real', () => {
],
} as StatusResult);

const res = await dcUpdate.updateArtifacts({
const res = await gradleWrapper.updateArtifacts({
packageFileName: 'gradle/wrapper/gradle-wrapper.properties',
updatedDeps: [],
newPackageFileContent: await readString(
Expand Down Expand Up @@ -100,7 +100,7 @@ describe('manager/gradle-wrapper/artifacts-real', () => {
})
);

const result = await dcUpdate.updateArtifacts({
const result = await gradleWrapper.updateArtifacts({
packageFileName: 'gradle/wrapper/gradle-wrapper.properties',
updatedDeps: [],
newPackageFileContent: ``,
Expand All @@ -118,7 +118,7 @@ describe('manager/gradle-wrapper/artifacts-real', () => {
modified: [],
} as StatusResult);

const res = await dcUpdate.updateArtifacts({
const res = await gradleWrapper.updateArtifacts({
packageFileName: 'gradle/wrapper/gradle-wrapper.properties',
updatedDeps: [],
newPackageFileContent: await readString(
Expand All @@ -142,7 +142,7 @@ describe('manager/gradle-wrapper/artifacts-real', () => {
throw new Error('failed');
});

const res = await dcUpdate.updateArtifacts({
const res = await gradleWrapper.updateArtifacts({
packageFileName: 'gradle/wrapper/gradle-wrapper.properties',
updatedDeps: [],
newPackageFileContent: await readString(
Expand All @@ -169,7 +169,7 @@ describe('manager/gradle-wrapper/artifacts-real', () => {
};

setGlobalConfig(wrongCmdConfig);
const res = await dcUpdate.updateArtifacts({
const res = await gradleWrapper.updateArtifacts({
packageFileName: 'gradle/wrapper/gradle-wrapper.properties',
updatedDeps: [],
newPackageFileContent: await readString(
Expand All @@ -192,7 +192,7 @@ describe('manager/gradle-wrapper/artifacts-real', () => {

it('gradlew not found', async () => {
setGlobalConfig({ localDir: 'some-dir' });
const res = await dcUpdate.updateArtifacts({
const res = await gradleWrapper.updateArtifacts({
packageFileName: 'gradle-wrapper.properties',
updatedDeps: [],
newPackageFileContent: undefined,
Expand All @@ -219,7 +219,7 @@ describe('manager/gradle-wrapper/artifacts-real', () => {

const newContent = await readString(`./gradle-wrapper-sum.properties`);

const result = await dcUpdate.updateArtifacts({
const result = await gradleWrapper.updateArtifacts({
packageFileName: 'gradle/wrapper/gradle-wrapper.properties',
updatedDeps: [],
newPackageFileContent: newContent.replace(
Expand Down Expand Up @@ -263,7 +263,7 @@ describe('manager/gradle-wrapper/artifacts-real', () => {
.get('/distributions/gradle-6.3-bin.zip.sha256')
.reply(404);

const result = await dcUpdate.updateArtifacts({
const result = await gradleWrapper.updateArtifacts({
packageFileName: 'gradle/wrapper/gradle-wrapper.properties',
updatedDeps: [],
newPackageFileContent: `distributionSha256Sum=336b6898b491f6334502d8074a6b8c2d73ed83b92123106bd4bf837f04111043\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-6.3-bin.zip`,
Expand Down
20 changes: 9 additions & 11 deletions lib/manager/gradle-wrapper/artifacts.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
/* eslint jest/no-standalone-expect: 0 */
import { exec as _exec } from 'child_process';
import { readFile } from 'fs-extra';
import { readFile, stat } from 'fs-extra';
import { resolve } from 'upath';
import { envMock, mockExecAll } from '../../../test/exec-util';
import { envMock, exec, mockExecAll } from '../../../test/exec-util';
import * as httpMock from '../../../test/http-mock';
import {
addReplacingSerializer,
Expand All @@ -16,14 +14,13 @@ import type { RepoGlobalConfig } from '../../config/types';
import { resetPrefetchedImages } from '../../util/exec/docker';
import type { StatusResult } from '../../util/git';
import type { UpdateArtifactsConfig } from '../types';
import * as dcUpdate from '.';
import * as gradleWrapper from '.';

jest.mock('child_process');
jest.mock('../../util/fs');
jest.mock('../../util/git');
jest.mock('../../util/exec/env');

const exec: jest.Mock<typeof _exec> = _exec as any;
const fixtures = resolve(__dirname, './__fixtures__');

const adminConfig: RepoGlobalConfig = {
Expand Down Expand Up @@ -57,6 +54,7 @@ describe('manager/gradle-wrapper/artifacts', () => {
resetPrefetchedImages();

fs.readLocalFile.mockResolvedValue('test');
fs.stat.mockImplementation((p) => stat(p));
});

afterEach(() => {
Expand All @@ -74,7 +72,7 @@ describe('manager/gradle-wrapper/artifacts', () => {

const execSnapshots = mockExecAll(exec);

const res = await dcUpdate.updateArtifacts({
const res = await gradleWrapper.updateArtifacts({
packageFileName: 'gradle/wrapper/gradle-wrapper.properties',
updatedDeps: [],
newPackageFileContent: await readString(
Expand All @@ -100,7 +98,7 @@ describe('manager/gradle-wrapper/artifacts', () => {

it('gradlew not found', async () => {
setGlobalConfig({ ...adminConfig, localDir: 'some-dir' });
const res = await dcUpdate.updateArtifacts({
const res = await gradleWrapper.updateArtifacts({
packageFileName: 'gradle-wrapper.properties',
updatedDeps: [],
newPackageFileContent: undefined,
Expand All @@ -117,7 +115,7 @@ describe('manager/gradle-wrapper/artifacts', () => {
modified: [],
})
);
const res = await dcUpdate.updateArtifacts({
const res = await gradleWrapper.updateArtifacts({
packageFileName: 'gradle-wrapper.properties',
updatedDeps: [],
newPackageFileContent: '',
Expand Down Expand Up @@ -145,7 +143,7 @@ describe('manager/gradle-wrapper/artifacts', () => {

const execSnapshots = mockExecAll(exec);

const result = await dcUpdate.updateArtifacts({
const result = await gradleWrapper.updateArtifacts({
packageFileName: 'gradle-wrapper.properties',
updatedDeps: [],
newPackageFileContent: `distributionSha256Sum=336b6898b491f6334502d8074a6b8c2d73ed83b92123106bd4bf837f04111043\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-6.3-bin.zip`,
Expand Down Expand Up @@ -179,7 +177,7 @@ describe('manager/gradle-wrapper/artifacts', () => {
.get('/distributions/gradle-6.3-bin.zip.sha256')
.reply(404);

const result = await dcUpdate.updateArtifacts({
const result = await gradleWrapper.updateArtifacts({
packageFileName: 'gradle-wrapper.properties',
updatedDeps: [],
newPackageFileContent: `distributionSha256Sum=336b6898b491f6334502d8074a6b8c2d73ed83b92123106bd4bf837f04111043\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-6.3-bin.zip`,
Expand Down
16 changes: 10 additions & 6 deletions lib/manager/gradle-wrapper/artifacts.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import { stat } from 'fs-extra';
import { resolve } from 'upath';
import { getGlobalConfig } from '../../config/global';
import { TEMPORARY_ERROR } from '../../constants/error-messages';
import { logger } from '../../logger';
import { ExecOptions, exec } from '../../util/exec';
import { readLocalFile, writeLocalFile } from '../../util/fs';
import { readLocalFile, stat, writeLocalFile } from '../../util/fs';
import { StatusResult, getRepoStatus } from '../../util/git';
import { Http } from '../../util/http';
import type { UpdateArtifact, UpdateArtifactsResult } from '../types';
import {
extraEnv,
getJavaContraint,
getJavaVersioning,
gradleWrapperFileName,
prepareGradleCommand,
} from '../gradle/deep/utils';
import type { UpdateArtifact, UpdateArtifactsResult } from '../types';
} from './utils';

const http = new Http('gradle-wrapper');

Expand Down Expand Up @@ -57,7 +58,7 @@ export async function updateArtifacts({
try {
const { localDir: projectDir } = getGlobalConfig();
logger.debug({ updatedDeps }, 'gradle-wrapper.updateArtifacts()');
const gradlew = gradleWrapperFileName(config);
const gradlew = gradleWrapperFileName();
const gradlewPath = resolve(projectDir, `./${gradlew}`);
let cmd = await prepareGradleCommand(
gradlew,
Expand Down Expand Up @@ -87,7 +88,10 @@ export async function updateArtifacts({
logger.debug(`Updating gradle wrapper: "${cmd}"`);
const execOptions: ExecOptions = {
docker: {
image: 'gradle',
image: 'java',
tagConstraint:
config.constraints?.java ?? getJavaContraint(config.currentValue),
tagScheme: getJavaVersioning(),
},
extraEnv,
};
Expand Down
34 changes: 12 additions & 22 deletions lib/manager/gradle-wrapper/extract.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,20 @@
import { GradleVersionDatasource } from '../../datasource/gradle-version';
import { logger } from '../../logger';
import { regEx } from '../../util/regex';
import * as gradleVersioning from '../../versioning/gradle';
import { id as versioning } from '../../versioning/gradle';
import type { PackageDependency, PackageFile } from '../types';

// https://regex101.com/r/1GaQ2X/1
const DISTRIBUTION_URL_REGEX = regEx(
'^(?:distributionUrl\\s*=\\s*)\\S*-(?<version>\\d+\\.\\d+(?:\\.\\d+)?(?:-\\w+)*)-(?<type>bin|all)\\.zip\\s*$'
);
import { extractGradleVersion } from './utils';

export function extractPackageFile(fileContent: string): PackageFile | null {
logger.debug('gradle-wrapper.extractPackageFile()');
const lines = fileContent.split('\n');

for (const line of lines) {
const distributionUrlMatch = DISTRIBUTION_URL_REGEX.exec(line);
if (distributionUrlMatch) {
const dependency: PackageDependency = {
depName: 'gradle',
currentValue: distributionUrlMatch.groups.version,
datasource: GradleVersionDatasource.id,
versioning: gradleVersioning.id,
};
logger.debug(dependency, 'Gradle Wrapper');
return { deps: [dependency] };
}
logger.trace('gradle-wrapper.extractPackageFile()');
const currentValue = extractGradleVersion(fileContent);
if (currentValue) {
const dependency: PackageDependency = {
depName: 'gradle',
currentValue,
datasource: GradleVersionDatasource.id,
versioning,
};
return { deps: [dependency] };
}
return null;
}
36 changes: 36 additions & 0 deletions lib/manager/gradle-wrapper/util.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { setGlobalConfig } from '../../config/global';
import { extractGradleVersion, getJavaContraint } from './utils';

describe('manager/gradle-wrapper/util', () => {
describe('getJavaContraint()', () => {
it('return null for global mode', () => {
expect(getJavaContraint(undefined)).toBeNull();
});

it('return ^11.0.0 for docker mode and undefined gradle', () => {
setGlobalConfig({ binarySource: 'docker' });
expect(getJavaContraint(undefined)).toEqual('^11.0.0');
});

it('return ^8.0.0 for docker gradle < 5', () => {
setGlobalConfig({ binarySource: 'docker' });
expect(getJavaContraint('4.9')).toEqual('^8.0.0');
});

it('return ^11.0.0 for docker gradle >=5 && <7', () => {
setGlobalConfig({ binarySource: 'docker' });
expect(getJavaContraint('6.0')).toEqual('^11.0.0');
});

it('return ^16.0.0 for docker gradle >= 7', () => {
setGlobalConfig({ binarySource: 'docker' });
expect(getJavaContraint('7.0.1')).toEqual('^16.0.0');
});
});

describe('extractGradleVersion()', () => {
it('works for undefined', () => {
expect(extractGradleVersion(undefined)).toBeNull();
});
});
});
91 changes: 91 additions & 0 deletions lib/manager/gradle-wrapper/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import type { Stats } from 'fs';
import os from 'os';
import upath from 'upath';
import { getGlobalConfig } from '../../config/global';
import { chmod } from '../../util/fs';
import { regEx } from '../../util/regex';
import gradleVersioning from '../../versioning/gradle';
import { id as npmVersioning } from '../../versioning/npm';

export const extraEnv = {
GRADLE_OPTS:
'-Dorg.gradle.parallel=true -Dorg.gradle.configureondemand=true -Dorg.gradle.daemon=false -Dorg.gradle.caching=false',
};

export function gradleWrapperFileName(): string {
if (
os.platform() === 'win32' &&
getGlobalConfig()?.binarySource !== 'docker'
) {
return 'gradlew.bat';
}
return './gradlew';
}

export async function prepareGradleCommand(
gradlewName: string,
cwd: string,
gradlew: Stats | null,
args: string | null
): Promise<string> {
/* eslint-disable no-bitwise */
// istanbul ignore if
if (gradlew?.isFile() === true) {
// if the file is not executable by others
if ((gradlew.mode & 0o1) === 0) {
// add the execution permission to the owner, group and others
await chmod(upath.join(cwd, gradlewName), gradlew.mode | 0o111);
}
if (args === null) {
return gradlewName;
}
return `${gradlewName} ${args}`;
}
/* eslint-enable no-bitwise */
return null;
}

/**
* Find compatible java version for gradle.
* see https://docs.gradle.org/current/userguide/compatibility.html
* @param gradleVersion current gradle version
* @returns A Java semver range
*/
export function getJavaContraint(gradleVersion: string): string | null {
if (getGlobalConfig()?.binarySource !== 'docker') {
// ignore
return null;
}

const major = gradleVersioning.getMajor(gradleVersion);
if (major >= 7) {
return '^16.0.0';
}
// first public gradle version was 2.0
if (major > 0 && major < 5) {
return '^8.0.0';
}
return '^11.0.0';
}

export function getJavaVersioning(): string {
return npmVersioning;
}

// https://regex101.com/r/1GaQ2X/1
const DISTRIBUTION_URL_REGEX = regEx(
'^(?:distributionUrl\\s*=\\s*)\\S*-(?<version>\\d+\\.\\d+(?:\\.\\d+)?(?:-\\w+)*)-(?<type>bin|all)\\.zip\\s*$'
);

export function extractGradleVersion(fileContent: string): string | null {
const lines = fileContent?.split('\n') ?? [];

for (const line of lines) {
const distributionUrlMatch = DISTRIBUTION_URL_REGEX.exec(line);
if (distributionUrlMatch) {
return distributionUrlMatch.groups.version;
}
}

return null;
}
Loading

0 comments on commit ae0ac14

Please sign in to comment.