Skip to content

Commit 6530bef

Browse files
authored
Migrate build steps to Gradle build (#46)
Currently, certain Gradle tasks (like 'build', 'check') don't work without running 'make generate' first. Instead of splitting logic in between Gradle and the Makefile, migrate logic for generating code, running license-header, and other details to the Gradle build so they can happen in the correct order automatically. This has the side effect that new users can use Gradle commands they are familiar with ('./gradlew build') and not have to learn the makefile conventions separately.
1 parent 3fd22bf commit 6530bef

File tree

13 files changed

+195
-77
lines changed

13 files changed

+195
-77
lines changed

.github/workflows/conformance.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,5 @@ jobs:
2424
distribution: 'temurin'
2525
java-version: '17'
2626
cache: 'gradle'
27-
- name: Generate
28-
run: make checkgenerate
2927
- name: Test conformance
3028
run: make conformance

Makefile

Lines changed: 6 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,6 @@ SHELL := bash
66
MAKEFLAGS += --warn-undefined-variables
77
MAKEFLAGS += --no-builtin-rules
88
MAKEFLAGS += --no-print-directory
9-
BIN := .tmp/bin
10-
COPYRIGHT_YEARS := 2023
11-
LICENSE_IGNORE := --ignore src/main/java/build/buf/validate/ --ignore conformance/src/main/java/build/buf/validate/conformance/
12-
JAVA = java
13-
GO ?= go
14-
ARGS ?= --strict_message
15-
# When updating, also update src/test/resources/proto/buf.yaml and re-run 'buf mod update'.
16-
PROTOVALIDATE_VERSION ?= v0.4.3
179

1810
.PHONY: all
1911
all: lint generate build docs conformance ## Run all tests and lint (default)
@@ -33,32 +25,19 @@ checkgenerate: generate ## Checks if `make generate` produces a diff.
3325

3426
.PHONY: clean
3527
clean: ## Delete intermediate build artifacts
36-
@# -X only removes untracked files, -d recurses into directories, -f actually removes files/dirs
37-
git clean -Xdf
28+
./gradlew clean
3829

3930
.PHONY: conformance
40-
conformance: build $(BIN)/protovalidate-conformance generate ## Execute conformance tests.
41-
./gradlew conformance:jar
42-
$(BIN)/protovalidate-conformance $(ARGS) ./conformance/conformance.sh
43-
44-
.PHONY: generate-license
45-
generate-license: $(BIN)/license-header ## Generates license headers for all source files.
46-
$(BIN)/license-header \
47-
--license-type apache \
48-
--copyright-holder "Buf Technologies, Inc." \
49-
--year-range "$(COPYRIGHT_YEARS)" $(LICENSE_IGNORE)
31+
conformance: ## Execute conformance tests.
32+
./gradlew conformance:conformance
5033

5134
.PHONY: help
52-
help: ## Describe useful make targets
35+
help: ## Describe useful make targets
5336
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "%-15s %s\n", $$1, $$2}'
5437

5538
.PHONY: generate
56-
generate: $(BIN)/buf generate-license ## Regenerate code and license headers
57-
$(BIN)/buf export buf.build/bufbuild/protovalidate:$(PROTOVALIDATE_VERSION) --output src/main/resources
58-
$(BIN)/buf generate --template buf.gen.yaml src/main/resources
59-
$(BIN)/buf generate --template conformance/buf.gen.yaml -o conformance/ buf.build/bufbuild/protovalidate-testing:$(PROTOVALIDATE_VERSION)
60-
$(BIN)/buf generate --template src/test/resources/proto/buf.gen.imports.yaml src/test/resources/proto --include-imports
61-
$(BIN)/buf generate --template src/test/resources/proto/buf.gen.noimports.yaml src/test/resources/proto
39+
generate: ## Regenerate code and license headers
40+
./gradlew generate
6241

6342
.PHONY: lint
6443
lint: ## Lint code
@@ -80,19 +59,3 @@ releaselocal: ## Release artifacts to local maven repository.
8059
.PHONY: test
8160
test: ## Run all tests.
8261
./gradlew test
83-
84-
$(BIN):
85-
@mkdir -p $(BIN)
86-
87-
$(BIN)/buf: $(BIN) Makefile
88-
GOBIN=$(abspath $(@D)) $(GO) install \
89-
github.com/bufbuild/buf/cmd/buf@latest
90-
91-
$(BIN)/license-header: $(BIN) Makefile
92-
GOBIN=$(abspath $(@D)) $(GO) install \
93-
github.com/bufbuild/buf/private/pkg/licenseheader/cmd/license-header@latest
94-
95-
$(BIN)/protovalidate-conformance: $(BIN) Makefile
96-
GOBIN=$(abspath $(BIN)) $(GO) install \
97-
github.com/bufbuild/protovalidate/tools/protovalidate-conformance@$(PROTOVALIDATE_VERSION)
98-

build.gradle.kts

Lines changed: 122 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import com.vanniktech.maven.publish.JavaLibrary
2-
import com.vanniktech.maven.publish.SonatypeHost
31
import com.diffplug.gradle.spotless.SpotlessExtension
2+
import com.vanniktech.maven.publish.JavaLibrary
43
import com.vanniktech.maven.publish.JavadocJar
4+
import com.vanniktech.maven.publish.SonatypeHost
55
import net.ltgt.gradle.errorprone.CheckSeverity
66
import net.ltgt.gradle.errorprone.errorprone
77

@@ -18,9 +18,116 @@ java {
1818
targetCompatibility = JavaVersion.VERSION_1_8
1919
}
2020

21+
val bufCLIFile = project.layout.buildDirectory.file("gobin/buf").get().asFile
22+
val bufCLIPath: String = bufCLIFile.absolutePath
23+
val bufLicenseHeaderCLIFile = project.layout.buildDirectory.file("gobin/license-header").get().asFile
24+
val bufLicenseHeaderCLIPath: String = bufLicenseHeaderCLIFile.absolutePath
25+
26+
tasks.register<Exec>("installBuf") {
27+
description = "Installs the Buf CLI."
28+
environment("GOBIN", bufCLIFile.parentFile.absolutePath)
29+
outputs.file(bufCLIFile)
30+
commandLine("go", "install", "github.com/bufbuild/buf/cmd/buf@latest")
31+
}
32+
33+
tasks.register<Exec>("installLicenseHeader") {
34+
description = "Installs the Buf license-header CLI."
35+
environment("GOBIN", bufLicenseHeaderCLIFile.parentFile.absolutePath)
36+
outputs.file(bufLicenseHeaderCLIFile)
37+
commandLine("go", "install", "github.com/bufbuild/buf/private/pkg/licenseheader/cmd/license-header@latest")
38+
}
39+
40+
tasks.register<Exec>("licenseHeader") {
41+
dependsOn("installLicenseHeader")
42+
description = "Runs the Buf license-header CLI."
43+
commandLine(
44+
bufLicenseHeaderCLIPath,
45+
"--license-type",
46+
"apache",
47+
"--copyright-holder",
48+
"Buf Technologies, Inc.",
49+
"--year-range",
50+
project.findProperty("license-header.years")!!.toString(),
51+
"--ignore",
52+
"src/main/java/build/buf/validate/",
53+
"--ignore",
54+
"conformance/src/main/java/build/buf/validate/conformance/",
55+
)
56+
}
57+
58+
tasks.register<Exec>("generateTestSourcesImports") {
59+
dependsOn("installBuf")
60+
description = "Generates code with buf generate --include-imports for unit tests."
61+
commandLine(
62+
bufCLIPath,
63+
"generate",
64+
"--template",
65+
"src/test/resources/proto/buf.gen.imports.yaml",
66+
"src/test/resources/proto",
67+
"--include-imports",
68+
)
69+
}
70+
71+
tasks.register<Exec>("generateTestSourcesNoImports") {
72+
dependsOn("installBuf")
73+
description = "Generates code with buf generate --include-imports for unit tests."
74+
commandLine(bufCLIPath, "generate", "--template", "src/test/resources/proto/buf.gen.noimports.yaml", "src/test/resources/proto")
75+
}
76+
77+
tasks.register("generateTestSources") {
78+
dependsOn("generateTestSourcesImports", "generateTestSourcesNoImports")
79+
description = "Generates code with buf generate for unit tests"
80+
}
81+
82+
tasks.register<Exec>("exportProtovalidateModule") {
83+
dependsOn("installBuf")
84+
description = "Exports the bufbuild/protovalidate module sources to src/main/resources."
85+
commandLine(
86+
bufCLIPath,
87+
"export",
88+
"buf.build/bufbuild/protovalidate:${project.findProperty("protovalidate.version")}",
89+
"--output",
90+
"src/main/resources",
91+
)
92+
}
93+
94+
tasks.register<Exec>("generateSources") {
95+
dependsOn("installBuf")
96+
description = "Generates sources for the bufbuild/protovalidate module sources to src/main/java."
97+
commandLine(bufCLIPath, "generate", "--template", "buf.gen.yaml", "src/main/resources")
98+
}
99+
100+
tasks.register<Exec>("generateConformance") {
101+
dependsOn("installBuf")
102+
description = "Generates sources for the bufbuild/protovalidate-testing module to conformance/src/main/java."
103+
commandLine(
104+
bufCLIPath,
105+
"generate",
106+
"--template",
107+
"conformance/buf.gen.yaml",
108+
"-o",
109+
"conformance/",
110+
"buf.build/bufbuild/protovalidate-testing:${project.findProperty("protovalidate.version")}",
111+
)
112+
}
113+
114+
tasks.register("generate") {
115+
description = "Generates sources with buf generate and buf export."
116+
dependsOn(
117+
"generateTestSources",
118+
"exportProtovalidateModule",
119+
"generateSources",
120+
"generateConformance",
121+
"licenseHeader",
122+
)
123+
}
124+
21125
tasks.withType<JavaCompile> {
22-
if (JavaVersion.current().isJava9Compatible) doFirst {
23-
options.compilerArgs = mutableListOf("--release", "8")
126+
dependsOn("generateTestSources")
127+
if (JavaVersion.current().isJava9Compatible) {
128+
doFirst {
129+
options.compilerArgs = mutableListOf("--release", "8")
130+
}
24131
}
25132
// Disable errorprone on generated code
26133
options.errorprone.excludedPaths.set("(.*/src/main/java/build/buf/validate/.*|.*/build/generated/.*)")
@@ -60,7 +167,11 @@ sourceSets {
60167
apply(plugin = "com.diffplug.spotless")
61168
configure<SpotlessExtension> {
62169
java {
63-
targetExclude("src/main/java/build/buf/validate/**/*.java")
170+
targetExclude("src/main/java/build/buf/validate/**/*.java", "build/generated/test-sources/bufgen/**/*.java")
171+
}
172+
kotlinGradle {
173+
ktlint()
174+
target("**/*.kts")
64175
}
65176
}
66177

@@ -94,28 +205,28 @@ mavenPublishing {
94205
val releaseVersion = project.findProperty("releaseVersion") as String? ?: System.getenv("VERSION")
95206
coordinates("build.buf", "protovalidate", releaseVersion ?: "0.0.0-SNAPSHOT")
96207
pomFromGradleProperties()
97-
configure(JavaLibrary(
208+
configure(
209+
JavaLibrary(
98210
// configures the -javadoc artifact, possible values:
99211
// - `JavadocJar.None()` don't publish this artifact
100-
// - `JavadocJar.Empty()` publish an emprt jar
212+
// - `JavadocJar.Empty()` publish an empty jar
101213
// - `JavadocJar.Javadoc()` to publish standard javadocs
102214
javadocJar = JavadocJar.Javadoc(),
103215
// whether to publish a sources jar
104216
sourcesJar = true,
105-
)
217+
),
106218
)
107219
pom {
108-
name.set("connect-library") // This is overwritten in subprojects.
220+
name.set("protovalidate-java")
109221
group = "build.buf"
110-
val releaseVersion = project.findProperty("releaseVersion") as String?
111222
// Default to snapshot versioning for local publishing.
112223
version = releaseVersion ?: "0.0.0-SNAPSHOT"
113224
description.set("Protocol Buffer Validation")
114225
url.set("https://github.com/bufbuild/protovalidate-java")
115226
licenses {
116227
license {
117228
name.set("The Apache Software License, Version 2.0")
118-
url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
229+
url.set("https://www.apache.org/licenses/LICENSE-2.0.txt")
119230
distribution.set("repo")
120231
}
121232
}
@@ -131,7 +242,6 @@ mavenPublishing {
131242
developerConnection.set("scm:git:ssh://[email protected]/bufbuild/protovalidate-java.git")
132243
}
133244
}
134-
135245
}
136246

137247
dependencies {

conformance/build.gradle.kts

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,38 @@ import net.ltgt.gradle.errorprone.errorprone
44
plugins {
55
`version-catalog`
66

7+
application
78
java
89
alias(libs.plugins.errorprone)
910
}
1011

12+
val conformanceCLIFile = project.layout.buildDirectory.file("gobin/protovalidate-conformance").get().asFile
13+
val conformanceCLIPath: String = conformanceCLIFile.absolutePath
14+
val conformanceAppScript: String = project.layout.buildDirectory.file("install/conformance/bin/conformance").get().asFile.absolutePath
15+
val conformanceArgs = (project.findProperty("protovalidate.conformance.args")?.toString() ?: "").split("\\s+".toRegex())
16+
17+
tasks.register<Exec>("installProtovalidateConformance") {
18+
description = "Installs the Protovalidate Conformance CLI."
19+
environment("GOBIN", conformanceCLIFile.parentFile.absolutePath)
20+
outputs.file(conformanceCLIFile)
21+
commandLine(
22+
"go",
23+
"install",
24+
"github.com/bufbuild/protovalidate/tools/protovalidate-conformance@${project.findProperty("protovalidate.version")}",
25+
)
26+
}
27+
28+
tasks.register<Exec>("conformance") {
29+
dependsOn("installDist", "installProtovalidateConformance")
30+
description = "Runs protovalidate conformance tests."
31+
commandLine(*(listOf(conformanceCLIPath) + conformanceArgs + listOf(conformanceAppScript)).toTypedArray())
32+
}
33+
1134
tasks.withType<JavaCompile> {
12-
if (JavaVersion.current().isJava9Compatible) doFirst {
13-
options.compilerArgs = mutableListOf("--release", "8")
35+
if (JavaVersion.current().isJava9Compatible) {
36+
doFirst {
37+
options.compilerArgs = mutableListOf("--release", "8")
38+
}
1439
}
1540
// Disable errorprone on generated code
1641
options.errorprone.excludedPaths.set(".*/src/main/java/build/buf/validate/conformance/.*")
@@ -21,18 +46,24 @@ tasks.withType<Javadoc> {
2146
enabled = false
2247
}
2348

49+
application {
50+
mainClass.set("build.buf.protovalidate.conformance.Main")
51+
}
52+
2453
tasks {
2554
jar {
55+
dependsOn(":jar")
2656
manifest {
27-
attributes(mapOf("Main-Class" to "build.buf.Main"))
57+
attributes(mapOf("Main-Class" to "build.buf.protovalidate.conformance.Main"))
2858
}
2959
duplicatesStrategy = DuplicatesStrategy.INCLUDE
3060
// This line of code recursively collects and copies all of a project's files
3161
// and adds them to the JAR itself. One can extend this task, to skip certain
3262
// files or particular types at will
3363
val sourcesMain = sourceSets.main.get()
34-
val contents = configurations.runtimeClasspath.get()
35-
.map { if (it.isDirectory) it else zipTree(it) } +
64+
val contents =
65+
configurations.runtimeClasspath.get()
66+
.map { if (it.isDirectory) it else zipTree(it) } +
3667
sourcesMain.output
3768
from(contents)
3869
}

conformance/conformance.sh

Lines changed: 0 additions & 3 deletions
This file was deleted.

conformance/src/main/java/build/buf/FileDescriptorUtil.java renamed to conformance/src/main/java/build/buf/protovalidate/conformance/FileDescriptorUtil.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
package build.buf;
15+
package build.buf.protovalidate.conformance;
1616

1717
import com.google.protobuf.DescriptorProtos;
1818
import com.google.protobuf.Descriptors;

conformance/src/main/java/build/buf/Main.java renamed to conformance/src/main/java/build/buf/protovalidate/conformance/Main.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
package build.buf;
15+
package build.buf.protovalidate.conformance;
1616

1717
import build.buf.protovalidate.Config;
1818
import build.buf.protovalidate.ValidationResult;

gradle.properties

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# When updating, also update src/test/resources/proto/buf.yaml and re-run 'buf mod update'.
2+
protovalidate.version = v0.4.3
3+
4+
# Arguments to the protovalidate-conformance CLI
5+
protovalidate.conformance.args = --strict_message
6+
7+
# Argument to the license-header CLI
8+
license-header.years = 2023

gradle/wrapper/gradle-wrapper.jar

2.56 KB
Binary file not shown.
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
4+
networkTimeout=10000
5+
validateDistributionUrl=true
46
zipStoreBase=GRADLE_USER_HOME
57
zipStorePath=wrapper/dists

0 commit comments

Comments
 (0)