Skip to content

Commit

Permalink
feat(gradle): Add basic Gradle Kotlin DSL support
Browse files Browse the repository at this point in the history
  • Loading branch information
ikesyo committed Jul 27, 2019
1 parent 9bff9e6 commit 6d2bf98
Show file tree
Hide file tree
Showing 8 changed files with 216 additions and 6 deletions.
6 changes: 5 additions & 1 deletion lib/config/definitions.js
Original file line number Diff line number Diff line change
Expand Up @@ -1624,7 +1624,11 @@ const options = [
stage: 'package',
type: 'object',
default: {
fileMatch: ['\\.gradle$', '(^|/)gradle.properties$'],
fileMatch: [
'\\.gradle(\\.kts)?$',
'(^|/)gradle.properties$',
'(^|/)buildSrc/.*',
],
timeout: 300,
versionScheme: 'maven',
},
Expand Down
53 changes: 53 additions & 0 deletions lib/manager/gradle/build-gradle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ export function updateGradleVersion(
updateVersionStringFormat,
updatePluginVersionStringFormat,
updateVersionMapFormat,
updateVersionKotlinNamedArgumentFormat,
updateVersionMapVariableFormat,
updateVersionKotlinNamedArgumentVariableFormat,
updateVersionStringVariableFormat,
updateVersionExpressionVariableFormat,
updateGlobalVariables,
Expand Down Expand Up @@ -68,6 +70,7 @@ export function collectVersionVariables(
moduleStringVariableExpressionVersionFormatMatch(dependency),
moduleStringVariableInterpolationVersionFormatMatch(dependency),
moduleMapVariableVersionFormatMatch(dependency),
moduleKotlinNamedArgumentVariableVersionFormatMatch(dependency),
];

for (const regex of regexes) {
Expand Down Expand Up @@ -119,6 +122,18 @@ function updateVersionMapFormat(
return null;
}

function updateVersionKotlinNamedArgumentFormat(
dependency: GradleDependency,
buildGradleContent: string,
newVersion: string
) {
const regex = moduleKotlinNamedArgumentVersionFormatMatch(dependency);
if (buildGradleContent.match(regex)) {
return buildGradleContent.replace(regex, `$1${newVersion}$2`);
}
return null;
}

function updateVersionMapVariableFormat(
dependency: GradleDependency,
buildGradleContent: string,
Expand All @@ -135,6 +150,22 @@ function updateVersionMapVariableFormat(
return null;
}

function updateVersionKotlinNamedArgumentVariableFormat(
dependency: GradleDependency,
buildGradleContent: string,
newVersion: string
) {
const regex = moduleKotlinNamedArgumentVariableVersionFormatMatch(dependency);
const match = buildGradleContent.match(regex);
if (match) {
return buildGradleContent.replace(
variableDefinitionFormatMatch(match[1]),
`$1${newVersion}$3`
);
}
return null;
}

function updateVersionStringVariableFormat(
dependency: GradleDependency,
buildGradleContent: string,
Expand Down Expand Up @@ -224,6 +255,17 @@ function moduleMapVersionFormatMatch(dependency: GradleDependency) {
);
}

function moduleKotlinNamedArgumentVersionFormatMatch(
dependency: GradleDependency
) {
// prettier-ignore
return new RegExp(
`(group\\s*=\\s*"${dependency.group}"\\s*,\\s*` +
`name\\s*=\\s*"${dependency.name}"\\s*,\\s*` +
`version\\s*=\\s*").*?(")`
);
}

function moduleMapVariableVersionFormatMatch(dependency: GradleDependency) {
// prettier-ignore
return new RegExp(
Expand All @@ -233,6 +275,17 @@ function moduleMapVariableVersionFormatMatch(dependency: GradleDependency) {
);
}

function moduleKotlinNamedArgumentVariableVersionFormatMatch(
dependency: GradleDependency
) {
// prettier-ignore
return new RegExp(
`group\\s*=\\s*"${dependency.group}"\\s*,\\s*` +
`name\\s*=\\s*"${dependency.name}"\\s*,\\s*` +
`version\\s*=\\s*([^\\s"]+?)[\\s\\),]`
);
}

function moduleStringVariableInterpolationVersionFormatMatch(
dependency: GradleDependency
) {
Expand Down
8 changes: 6 additions & 2 deletions lib/manager/gradle/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,12 @@ export async function extractAllPackageFiles(
config: ExtractConfig,
packageFiles: string[]
): Promise<PackageFile[]> {
if (!packageFiles.some(packageFile => packageFile === 'build.gradle')) {
logger.warn('No root build.gradle found - skipping');
if (
!packageFiles.some(packageFile =>
['build.gradle', 'build.gradle.kts'].includes(packageFile)
)
) {
logger.warn('No root build.gradle nor build.gradle.kts found - skipping');
return null;
}
logger.info('Extracting dependencies from all gradle files');
Expand Down
6 changes: 5 additions & 1 deletion renovate-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1117,7 +1117,11 @@
"description": "Configuration object for build.gradle files",
"type": "object",
"default": {
"fileMatch": ["\\.gradle$", "(^|/)gradle.properties$"],
"fileMatch": [
"\\.gradle(\\.kts)?$",
"(^|/)gradle.properties$",
"(^|/)buildSrc/.*"
],
"timeout": 300,
"versionScheme": "maven"
},
Expand Down
79 changes: 79 additions & 0 deletions test/manager/gradle/__snapshots__/index.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,85 @@ Array [
]
`;

exports[`manager/gradle extractPackageFile should return gradle.kts dependencies 1`] = `
Array [
Object {
"datasource": "maven",
"deps": Array [
Object {
"currentValue": null,
"depGroup": "org.springframework.boot",
"depName": "org.springframework.boot:spring-boot-starter-jersey",
"name": "spring-boot-starter-jersey",
"registryUrls": Array [
"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",
"registryUrls": Array [
"https://repo.maven.apache.org/maven2/",
"https://jitpack.io",
],
},
Object {
"currentValue": "3.1",
"depGroup": "cglib",
"depName": "cglib:cglib-nodep",
"name": "cglib-nodep",
"registryUrls": Array [
"https://repo.maven.apache.org/maven2/",
"https://jitpack.io",
],
},
],
"manager": "gradle",
"packageFile": "build.gradle.kts",
},
Object {
"datasource": "maven",
"deps": Array [
Object {
"currentValue": null,
"depGroup": "org.springframework.boot",
"depName": "org.springframework.boot:spring-boot-starter-jersey",
"name": "spring-boot-starter-jersey",
"registryUrls": Array [
"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",
"registryUrls": Array [
"https://repo.maven.apache.org/maven2/",
"https://jitpack.io",
],
},
Object {
"currentValue": "3.1",
"depGroup": "cglib",
"depName": "cglib:cglib-nodep",
"name": "cglib-nodep",
"registryUrls": Array [
"https://repo.maven.apache.org/maven2/",
"https://jitpack.io",
],
},
],
"manager": "gradle",
"packageFile": "subproject/build.gradle.kts",
},
]
`;

exports[`manager/gradle extractPackageFile should throw registry failure if gradle execution fails 1`] = `[Error: registry-failure]`;

exports[`manager/gradle extractPackageFile should use repositories only for current project 1`] = `
Expand Down
58 changes: 58 additions & 0 deletions test/manager/gradle/build-gradle.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,22 @@ describe('lib/manager/gradle/updateGradleVersion', () => {
);
});

it('returns a file updated if the version defined as a Kotlin named argument is found', () => {
const gradleFile = `compile(group = "mysql" ,
name = "mysql-connector-java",
version = "6.0.5")`;
const updatedGradleFile = updateGradleVersion(
gradleFile,
{ group: 'mysql', name: 'mysql-connector-java', version: '6.0.5' },
'7.0.0'
);
expect(updatedGradleFile).toEqual(
`compile(group = "mysql" ,
name = "mysql-connector-java",
version = "7.0.0")`
);
});

it('should returns a file updated if the version defined in a variable as a string is found', () => {
const gradleFile = `String mysqlVersion= "6.0.5"
runtime ( "mysql:mysql-connector-java:$mysqlVersion" )
Expand Down Expand Up @@ -130,6 +146,26 @@ describe('lib/manager/gradle/updateGradleVersion', () => {
);
});

it('should returns a file updated if the version defined in a variable as a Kotlin named argument is found', () => {
const gradleFile = `val mysqlVersion = "6.0.5"
compile(group = "mysql" ,
name = "mysql-connector-java",
version = mysqlVersion)
`;
const updatedGradleFile = updateGradleVersion(
gradleFile,
{ group: 'mysql', name: 'mysql-connector-java', version: '6.0.5' },
'7.0.0'
);
expect(updatedGradleFile).toEqual(
`val mysqlVersion = "7.0.0"
compile(group = "mysql" ,
name = "mysql-connector-java",
version = mysqlVersion)
`
);
});

it('should replace a external groovy variable assigned to a specific dependency', () => {
const gradleFile =
'runtime ( "mysql:mysql-connector-java:${mysqlVersion}" )'; // eslint-disable-line no-template-curly-in-string
Expand Down Expand Up @@ -192,6 +228,28 @@ describe('lib/manager/gradle/updateGradleVersion', () => {
expect(updatedGradleFile).toEqual('String mysqlVersion = "7.0.0"');
});

it('should replace a external variable assigned to a Kotlin named argument dependency', () => {
const gradleFile = `compile(group = "mysql" ,
name = "mysql-connector-java",
version = mysqlVersion)
`;
const mysqlDependency = {
group: 'mysql',
depGroup: 'mysql',
name: 'mysql-connector-java',
version: '6.0.5',
};
collectVersionVariables([mysqlDependency], gradleFile);

const gradleWithVersionFile = 'val mysqlVersion = "6.0.5"';
const updatedGradleFile = updateGradleVersion(
gradleWithVersionFile,
mysqlDependency,
'7.0.0'
);
expect(updatedGradleFile).toEqual('val mysqlVersion = "7.0.0"');
});

it('should replace a external variable assigned to a interpolated dependency', () => {
const gradleFile =
'runtime ( "mysql:mysql-connector-java:$mysqlVersion" )';
Expand Down
8 changes: 8 additions & 0 deletions test/manager/gradle/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ describe('manager/gradle', () => {
expect(dependencies).toMatchSnapshot();
});

it('should return gradle.kts dependencies', async () => {
const dependencies = await manager.extractAllPackageFiles(config, [
'build.gradle.kts',
'subproject/build.gradle.kts',
]);
expect(dependencies).toMatchSnapshot();
});

it('should return empty if there are no dependencies', async () => {
fs.readFile.mockResolvedValue(fsReal.readFileSync(
'test/datasource/gradle/_fixtures/updatesReportEmpty.json',
Expand Down
4 changes: 2 additions & 2 deletions website/docs/java.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ Renovate detects versions specified as string `'group:artifact:version'` and as

### File Support

Renovate can update `build.gradle` files in the root of the repository and any `*.gradle` file inside any subdirectory as multi-project configurations.
Renovate can update `build.gradle`/`build.gradle.kts` files in the root of the repository and any `*.gradle`/`*.gradle.kts` file inside any subdirectory as multi-project configurations.

Renovate does not support:

- Projects without a `build.gradle` file in the root of the repository.
- Projects without neither `build.gradle` nor `build.gradle.kts` file in the root of the repository.
- Android projects that requires extra configuration to run. (e.g. setting the android SDK)

### How It Works
Expand Down

0 comments on commit 6d2bf98

Please sign in to comment.