Skip to content

Commit

Permalink
Allow specification of a buf.gen.yaml template file (#107)
Browse files Browse the repository at this point in the history
  • Loading branch information
nkhoshini authored Feb 23, 2023
1 parent 3d5b1e9 commit 2e6d8e1
Show file tree
Hide file tree
Showing 33 changed files with 727 additions and 12 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ This plugin supports straightforward usage of `buf lint`, `buf format`, and `buf
* [Artifact details](#artifact-details)
* [bufGenerate](#bufgenerate)
* [Generating Dependencies](#generating-dependencies)
* [Further Configuration](#further-configuration)
* [Additional Configuration](#additional-configuration)

<!-- Created by https://github.com/ekalinin/github-markdown-toc -->
Expand Down Expand Up @@ -272,6 +273,21 @@ buf {

Ensure you have an up-to-date `buf.lock` file generated by `buf mod update` or this generation will fail.


#### Further Configuration

By default `bufGenerate` will read the `buf.gen.yaml` template file from the project root directory. You can override the location of the template file:

``` kotlin
// build.gradle.kts

buf {
generate {
templateFileLocation = rootProject.file("subdir/buf.gen.yaml")
}
}
```

## Additional Configuration

The version of Buf used can be configured using the `toolVersion` property on the extension:
Expand Down
7 changes: 6 additions & 1 deletion src/main/kotlin/com/parmet/buf/gradle/BufExtension.kt
Original file line number Diff line number Diff line change
Expand Up @@ -87,5 +87,10 @@ class GenerateOptions(
* If you specify any dependencies in `buf.yaml`, you must create a `buf.lock` file using `buf mod update` for
* dependency resolution to succeed.
*/
var includeImports: Boolean? = null
var includeImports: Boolean? = null,

/**
* Specify the location of buf.gen.yaml if not using one in the project root.
*/
var templateFileLocation: File? = null
)
13 changes: 4 additions & 9 deletions src/main/kotlin/com/parmet/buf/gradle/GenerateConfiguration.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,10 @@ const val BUF_GENERATE_TASK_NAME = "bufGenerate"
const val GENERATED_DIR = "generated"

internal fun Project.configureGenerate() {
if (hasGenerate()) {
registerBufTask<GenerateTask>(BUF_GENERATE_TASK_NAME) {
group = BUILD_GROUP
description = "Generates code from a Protobuf schema."
registerBufTask<GenerateTask>(BUF_GENERATE_TASK_NAME) {
group = BUILD_GROUP
description = "Generates code from a Protobuf schema."

createsOutput()
}
createsOutput()
}
}

private fun Project.hasGenerate() =
file("buf.gen.yaml").let { it.exists() && it.isFile }
36 changes: 34 additions & 2 deletions src/main/kotlin/com/parmet/buf/gradle/GenerateTask.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,42 @@ abstract class GenerateTask : DefaultTask() {
execBuf(args + additionalArgs())
}

private fun additionalArgs() =
if (getExtension().generateOptions?.includeImports == true) {
private fun additionalArgs(): List<String> {
val generateOptions = getExtension().generateOptions
val importOptions = if (generateOptions?.includeImports == true) {
listOf("--include-imports")
} else {
emptyList()
}

val templateFileOption = resolveTemplateFile()?.let {
listOf("--template", it.absolutePath)
} ?: emptyList()

return importOptions + templateFileOption
}

private fun resolveTemplateFile(): File? {
return getExtension().generateOptions?.let { generateOptions ->
val defaultTemplateFile = project.file("buf.gen.yaml").validOrNull()
if (generateOptions.templateFileLocation != null) {
val specifiedTemplateFile = generateOptions.templateFileLocation.validOrNull()
check(specifiedTemplateFile != null) {
"Specified templateFileLocation does not exist."
}
check(defaultTemplateFile == null) {
"Buf gen template file specified in the project directory as well as with templateFileLocation; pick one."
}
specifiedTemplateFile
} else {
check(defaultTemplateFile != null) {
"No buf.gen.yaml file found in the project directory."
}
defaultTemplateFile
}
}
}

private fun File?.validOrNull() =
this?.takeIf { it.isFile && it.exists() }
}
33 changes: 33 additions & 0 deletions src/test/kotlin/com/parmet/buf/gradle/AbstractGenerateTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,37 @@ abstract class AbstractGenerateTest : AbstractBufIntegrationTest() {
listOf("build", "bufbuild", "generated", "java", "com", "google", "type", "DateTime.java")
assertThat(Paths.get(projectDir.absolutePath, *generatedPathElements.toTypedArray()).toFile().exists()).isTrue()
}

@Test
fun `buf generate with buf gen template file override`() {
gradleRunner().withArguments(BUILD_TASK_NAME).build()
}

@Test
fun `buf generate fails with a nonexistent specified template file`() {
val result = gradleRunner().withArguments(BUF_GENERATE_TASK_NAME).buildAndFail()
assertThat(result.output).contains("Specified templateFileLocation does not exist.")
}

@Test
fun `buf generate fails with no default template file and no override specified`() {
val result = gradleRunner().withArguments(BUF_GENERATE_TASK_NAME).buildAndFail()
assertThat(result.output).contains("No buf.gen.yaml file found in the project directory.")
}

@Test
fun `buf generate fails with both default and specified buf gen template files`() {
val result = gradleRunner().withArguments(BUF_GENERATE_TASK_NAME).buildAndFail()
assertThat(result.output).contains("Buf gen template file specified in the project directory as well as with templateFileLocation")
}

@Test
fun `buf generate fails when a specified template file does not exist but a default one does`() {
gradleRunner().withArguments(BUF_GENERATE_TASK_NAME).build()

buildFile.replace("//", "")

val result = gradleRunner().withArguments(BUF_GENERATE_TASK_NAME).buildAndFail()
assertThat(result.output).contains("Specified templateFileLocation does not exist.")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright (c) 2022 Andrew Parmet
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

version: v1
plugins:
- remote: buf.build/protocolbuffers/plugins/java:v3.20.0-1
out: java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2022 Andrew Parmet
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

plugins {
id 'java'
id 'com.parmet.buf'
}

repositories {
mavenCentral()
}

buf {
generate {
//templateFileLocation = project.file("subdir/buf.gen.yaml")
}
}

compileJava.dependsOn 'bufGenerate'

sourceSets.main.java {
srcDir 'build/bufbuild/generated/java'
}

dependencies {
implementation "com.google.protobuf:protobuf-java:$protobufVersion"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) 2022 Andrew Parmet
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package parmet.buf.test.v1;

option java_package = "com.parmet.buf.test.v1";

message BasicMessage {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright (c) 2022 Andrew Parmet
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.parmet.buf.test.v1;

public class Foo {
public static void test() {
Test.BasicMessage.newBuilder().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright (c) 2022 Andrew Parmet
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

plugins {
id 'com.parmet.buf'
}

buf {
generate {
templateFileLocation = project.file("subdir/buf.gen.yaml")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright (c) 2022 Andrew Parmet
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

version: v1
plugins:
- remote: buf.build/protocolbuffers/plugins/java:v3.20.0-1
out: java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright (c) 2022 Andrew Parmet
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

plugins {
id 'com.parmet.buf'
}

buf {
generate {
templateFileLocation = project.file("subdir/buf.gen.yaml")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright (c) 2022 Andrew Parmet
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

version: v1
plugins:
- remote: buf.build/protocolbuffers/plugins/java:v3.20.0-1
out: java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright (c) 2022 Andrew Parmet
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

plugins {
id 'com.parmet.buf'
}

buf {
generate {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2022 Andrew Parmet
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

plugins {
id 'java'
id 'com.parmet.buf'
}

repositories {
mavenCentral()
}

buf {
generate {
templateFileLocation = project.file("subdir/buf.gen.yaml")
}
}

compileJava.dependsOn 'bufGenerate'

sourceSets.main.java {
srcDir 'build/bufbuild/generated/java'
}

dependencies {
implementation "com.google.protobuf:protobuf-java:$protobufVersion"
}
Loading

0 comments on commit 2e6d8e1

Please sign in to comment.