Skip to content
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

Use separate configuration for extracting included proto from dependencies #366

Merged

Conversation

voidzcy
Copy link
Collaborator

@voidzcy voidzcy commented Dec 12, 2019

Configuration hierarchy for java and java-library plugins are different:

  • In java plugin: compile(deprecated) is the root configuration, implementation extends it and compileClasspath extends implementation.
  • In java-library: api is the root configuration, implementation extends it and compileClasspath extends implementation.

Currently, our plugin extracts included proto for compilation from dependencies in compile configuration. This is wrong even for java plugin. Dependencies added to implementation configuration will not be captured by our plugin. If your proto file imports some dependent proto from an implementation configuration, you will get an import proto file not found error. Plugin tasks should get dependencies from compileClasspath configuration, which inherits all dependencies added to its ancestor configurations. Thus, the plugin is able to capture all dependencies for compilation.

However, extracting included proto from dependencies in compileClasspath configuration is not enough if some dependency uses java-library plugin. Projects depending on some upstream libraries that use java-library plugin will only pull in classes folder instead of the full JAR for compilation. So proto files in the upstream libraries will not be extracted and consumer project's compilation will fail if it imports proto files from upstream libraries.

Our solution, as explained in #363 (comment) is to create an internal configuration that mirrors compileClasspath configuration (which extends compileOnly and implementation) introduced by java/java-library plugin and add an attribute to also include resources (where the proto files are packaged). We are trying to avoid affecting java/java-library by modifying compileClasspath configuration itself. This new configuration is for our plugin's internal usage and users should not directly add dependencies to it.

Related issues: #363 (most clearly reveals the issue), #242, #338, #258

Copy link
Collaborator

@ejona86 ejona86 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bumping the gradle version in this PR doesn't seem right. Everything else seems fine.

gradle/wrapper/gradle-wrapper.properties Show resolved Hide resolved
project.configurations.create(compileProtoConfigName) {
visible = false
transitive = true
extendsFrom = [project.configurations.findByName(compileClasspathConfigName)]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had suggested extending compileOnly+implementation, to mirror compileClasspath. I guess this way works too. Is there any benefit to either approach, or is it basically all the same?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically the same. I was thinking about compileClasspath is a "more extended" configuration, we would be less likely to miss out something. Do you think which approach is more reasonable?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That "more extended" is what bothers me. I don't really like to be using things that I don't know I'm using, as someone could end up depending on them. But I see danger from both options. I'm most worried about all the strange things a user may change.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, let's be conservative and mirror how Java Base Plugin's tasks getting dependencies. I changed it to extend from compileOnly and implementation.

// not exposing resources to consumers for compilation.
// Some Android sourceSet does not have 'compileClasspath' configuration, not even
// 'compile' or 'implementation'.
String compileProtoConfigName = Utils.getConfigName(sourceSetName, 'compileProto')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I mentioned earlier, maybe we could name it compileProtoPath or compileProtoInclude? Doesn't matter much though.

Copy link
Collaborator Author

@voidzcy voidzcy Dec 17, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I had a hard time remembering the name you suggested 😢 when I was writing this ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants