-
Notifications
You must be signed in to change notification settings - Fork 570
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Get Gradle to do more of the work in our Gradle plugin #2838
Conversation
1009bd5
to
9b51f6b
Compare
In particular leave more of the dependency management up to Gradle.
9b51f6b
to
14f19a3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very exciting.
@@ -218,7 +197,16 @@ class WirePlugin : Plugin<Project> { | |||
val task = project.tasks.register(taskName, WireTask::class.java) { task: WireTask -> | |||
task.group = GROUP | |||
task.description = "Generate protobuf implementation for ${source.name}" | |||
task.source(protoSourceInput.configuration) | |||
|
|||
// Flatten all the input files here. Changes to any of them will cause the task to re-run. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it even required? Given there is sourceInput
and protoInput
below, might be possible for WireTask
to extend DefaultTask
instead of DefaultTask
?
Edit I read below we want NO-SOURCE
if no source is found. In which case, I think protoSource
should be in source and protoPath
passed out of the band? in a regular task property?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you’re strictly correct, and also I don’t think it’ll matter much in practice?
Both skipping the task and running it when there’s no sources will both be super fast and rare.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed 👍
fun sourcePathDirDoesNotExist() { | ||
val fixtureRoot = File("src/test/projects/sourcepath-nonexistent-dir") | ||
|
||
val result = gradleRunner.runFixture(fixtureRoot) { buildAndFail() } | ||
val result = gradleRunner.runFixture(fixtureRoot) { build() } | ||
|
||
assertThat(result.task(":generateProtos")).isNull() | ||
assertThat(result.output).contains( | ||
""" | ||
|Invalid path string: "src/main/proto". | ||
|For individual files, use the following syntax: | ||
|wire { | ||
| sourcePath { | ||
| srcDir 'dirPath' | ||
| include 'relativePath' | ||
| } | ||
|} | ||
""".trimMargin(), | ||
) | ||
assertThat(result.task(":generateMainProtos")?.getOutcome()) | ||
.isEqualTo(TaskOutcome.NO_SOURCE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm cool with it
I pushed a commit with spotless and apiDump |
dbfed0e
to
3151263
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left a few non-blocking comments, mainly for possible future improvements.
This change is a nice simplification 👍
public final fun getSourceJars ()Ljava/util/Set; | ||
public final fun getSourcePaths ()Ljava/util/Set; | ||
public final fun getSourceTrees ()Ljava/util/Set; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically breaking but I'm assuming these APIs that are really supposed to be called from user land?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, exactly. These should have always been implementation details.
(protoSourceInput.dependencies + protoPathInput.dependencies).filterIsInstance<ProjectDependency>() | ||
for (projectDependency in projectDependencies) { | ||
projectDependenciesJvmConfiguration.dependencies.add(projectDependency) | ||
if (extension.protoSourceProtoRootSets.all { it.roots.isEmpty() }) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: this probably resolves configurations eagerly. I think this is the case already so not a huge deal in the grand scheme of things but would be a good candidate for future improvements.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great idea. We can move this behaviour to execution time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In follow-up!
| srcDir 'dirPath' | ||
| include 'relativePath' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For those cases, I like using a syntax that works in both Groovy and Kotlin:
| srcDir 'dirPath' | |
| include 'relativePath' | |
| srcDir("dirPath") | |
| include("relativePath") |
It's less "idiomatic" in Groovy though so either work with me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great idea.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -218,7 +197,16 @@ class WirePlugin : Plugin<Project> { | |||
val task = project.tasks.register(taskName, WireTask::class.java) { task: WireTask -> | |||
task.group = GROUP | |||
task.description = "Generate protobuf implementation for ${source.name}" | |||
task.source(protoSourceInput.configuration) | |||
|
|||
// Flatten all the input files here. Changes to any of them will cause the task to re-run. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it even required? Given there is sourceInput
and protoInput
below, might be possible for WireTask
to extend DefaultTask
instead of DefaultTask
?
Edit I read below we want NO-SOURCE
if no source is found. In which case, I think protoSource
should be in source and protoPath
passed out of the band? in a regular task property?
// We store [file] relative to the [project] in order to not invalidate the cache when we don't | ||
// have to. | ||
return InputLocation(project.relativePath(file.path), includes, excludes) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: It's technically ok to move the directory around as long as its contents stay the same so there might still be spurious cache invalidations here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remote caching is the big thing I wanna preserve. I think we get that as long as the paths are relative to the project.
Build failure in samples means I’ve made an unintentional behaviour change and our tests didn’t catch it! Yikes!
|
Samples are also used as tests. Way simpler to work with than testing against the plugin directly. |
Ugh, the failing Windows build shows me I’ve made a design error in my implementation. The string I’m passing to Unfortunately if my path isn’t in the project directory, the result I’m producing is bananas and won’t work with Gradle’s cache: I think instead I need to change Ugh. |
Here’s a tracking issue to fix that path problem: #2842 |
In particular leave more of the dependency management up to Gradle.