-
Notifications
You must be signed in to change notification settings - Fork 25.6k
[Gradle] Some tweaks to transport related build logic #133413
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
Conversation
Pinging @elastic/es-delivery (Team:Delivery) |
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.
A couple questions about the subscriber setup
|
||
public abstract class ProjectSubscribeBuildService implements BuildService<BuildServiceParameters.None> { | ||
|
||
public static final String TRANSPORT_REFERENCES_TOPIC = "transportReferences"; |
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.
nit: since this class should be generic, could this topic string be moved into the transport version classes, perhaps in TransportVersionResourcesPlugin?
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.
fixed
private Map<String, Collection<String>> versionsByTopic = new HashMap<>(); | ||
|
||
public Collection<String> getProjectsByTopic(String topic) { | ||
return versionsByTopic.get(topic); |
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.
Can you add a javadoc explaining the expectation of the returned collection? It appears it's supposed to be live, right?
Separately, I think this also needs to be a computeIfAbsent. Otherwise if getProjectsByTopic is called before any register, it will return null rather than an empty list that will be updated.
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.
Yeah, "live" isn't really the write term here. We are just returning a mutable collection, which seems wrong. To me I think it would make sense to return a Provider
which wraps and immutable collection representing that registered projects at the time whenever you call get()
.
I also think we should standardize on using Provider
-based APIs pretty much anytime we have "lazy" stuff like this, or when we want to make it obvious that eagerly resolving this might (a) have performance impacts or (b) might give you incomplete results.
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.
good point
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.
fixed
c.setCanBeConsumed(false); | ||
c.setCanBeResolved(true); | ||
c.attributes(TransportVersionReference::addArtifactAttribute); | ||
c.defaultDependencies(t -> { |
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.
When will this be called relative to other projects? Can there not be projects added later?
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.
this will be called when the configuration is resolved. usually thats part of the taskgraph calculation when using configuration cache or even later when evaluating inputs of the task required.
At this point all projects should be evaluated.
At one point we want to support only partial gradle configuration so we don't need to reevaluate the world when just triggering subprojects. then we probably need an approach to handle those scenario. but we and gradle is not there yet
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.
As I mentioned above, I think if we make ProjectSubscribeBuildService
a Provider
-based API this becomes a lot less confusing. You can then just use DependencyHandler.addProvider
and use .map()
to have it be providers all the way down. IMO calling get()
anywhere in configuration logic is a smell. It means we're relying on some kind of implicit deferral to happen or we're forced to awkwardly integrate with another non-Provider API.
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 theory thats nice and the way to go. unfortunately (again) the provider based interfaces in Gradle often break that by themself. In this case we have a Provider<Collection> but DependencyHandler.addProvider
only takes a Provider<String>
representing a dependencyNotation. To have that working nicely we would need DependencyHandler.addProvider(String, Collection<Object>)
. Alternatively we return a Collection<Provider<String>>
:/
We still can be good citizens but we're limited by the reality that the provider api in Gradle is lacking proper coverage in certain places.
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 found a different api by now that is closer to idomatic provider usage
var tvReferencesConfig = project.getConfigurations().create("globalTvReferences", c -> {
c.setCanBeConsumed(false);
c.setCanBeResolved(true);
c.attributes(TransportVersionReference::addArtifactAttribute);
c.getDependencies()
.addAllLater(
psService.flatMap(t -> t.getProjectsByTopic(TRANSPORT_REFERENCES_TOPIC))
.map(projectPaths -> projectPaths.stream().map(path -> depsHandler.project(Map.of("path", path))).toList())
);
});
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.
Nice.
*/ | ||
@CacheableTask | ||
public abstract class ValidateTransportVersionResourcesTask extends DefaultTask { | ||
public abstract class ValidateTransportVersionResourcesTask extends DefaultTask implements VerificationTask { |
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.
Are we throwing error messages that align with this expecation? My understanding was that Develocity also requires the failure message to match a certain pattern. See https://docs.gradle.com/develocity/failure-classification/
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.
good catch! I was too naive here thinking using the task interface is enough. I'll have a quick look 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.
I fixed the throwing exceptions here
- We want to avoid project.allprojects - Implementing Verification task in the transport validation tasks - Allows better filtering for verification vs. other build failures. e.g. in Develocity Failures Overview - Use project.layout.settingsDirectory instead of project.rootProject.projectDir - Avoiding accessing other projects properties
54b1a8c
to
86fc83b
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.
LGTM
* The values are LinkedHashSet to preserve the order of registration mostly to provide a predicatable order | ||
* when running consecutive builds. | ||
* */ | ||
private Map<String, Collection<String>> versionsByTopic = new HashMap<>(); |
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.
nit: this can be final
* [Gradle] Some tweaks to transport related build logic - We want to avoid project.allprojects - Implementing Verification task in the transport validation tasks - Allows better filtering for verification vs. other build failures. e.g. in Develocity Failures Overview - Use project.layout.settingsDirectory instead of project.rootProject.projectDir - Avoiding accessing other projects properties * Address some review feedback * Rework mapping project path list to dependencies * Some more review feedback * Minor tweak after review feedback
* [Gradle] Some tweaks to transport related build logic - We want to avoid project.allprojects - Implementing Verification task in the transport validation tasks - Allows better filtering for verification vs. other build failures. e.g. in Develocity Failures Overview - Use project.layout.settingsDirectory instead of project.rootProject.projectDir - Avoiding accessing other projects properties * Address some review feedback * Rework mapping project path list to dependencies * Some more review feedback * Minor tweak after review feedback
* [Gradle] Some tweaks to transport related build logic - We want to avoid project.allprojects - Implementing Verification task in the transport validation tasks - Allows better filtering for verification vs. other build failures. e.g. in Develocity Failures Overview - Use project.layout.settingsDirectory instead of project.rootProject.projectDir - Avoiding accessing other projects properties * Address some review feedback * Rework mapping project path list to dependencies * Some more review feedback * Minor tweak after review feedback
* [Gradle] Some tweaks to transport related build logic - We want to avoid project.allprojects - Implementing Verification task in the transport validation tasks - Allows better filtering for verification vs. other build failures. e.g. in Develocity Failures Overview - Use project.layout.settingsDirectory instead of project.rootProject.projectDir - Avoiding accessing other projects properties * Address some review feedback * Rework mapping project path list to dependencies * Some more review feedback * Minor tweak after review feedback
) * [Gradle] Some tweaks to transport related build logic - We want to avoid project.allprojects - Implementing Verification task in the transport validation tasks - Allows better filtering for verification vs. other build failures. e.g. in Develocity Failures Overview - Use project.layout.settingsDirectory instead of project.rootProject.projectDir - Avoiding accessing other projects properties * Address some review feedback * Rework mapping project path list to dependencies * Some more review feedback * Minor tweak after review feedback
) * [Gradle] Some tweaks to transport related build logic - We want to avoid project.allprojects - Implementing Verification task in the transport validation tasks - Allows better filtering for verification vs. other build failures. e.g. in Develocity Failures Overview - Use project.layout.settingsDirectory instead of project.rootProject.projectDir - Avoiding accessing other projects properties * Address some review feedback * Rework mapping project path list to dependencies * Some more review feedback * Minor tweak after review feedback
) * [Gradle] Some tweaks to transport related build logic - We want to avoid project.allprojects - Implementing Verification task in the transport validation tasks - Allows better filtering for verification vs. other build failures. e.g. in Develocity Failures Overview - Use project.layout.settingsDirectory instead of project.rootProject.projectDir - Avoiding accessing other projects properties * Address some review feedback * Rework mapping project path list to dependencies * Some more review feedback * Minor tweak after review feedback
) * [Gradle] Some tweaks to transport related build logic - We want to avoid project.allprojects - Implementing Verification task in the transport validation tasks - Allows better filtering for verification vs. other build failures. e.g. in Develocity Failures Overview - Use project.layout.settingsDirectory instead of project.rootProject.projectDir - Avoiding accessing other projects properties * Address some review feedback * Rework mapping project path list to dependencies * Some more review feedback * Minor tweak after review feedback
elastic#133695) * [Gradle] Some tweaks to transport related build logic - We want to avoid project.allprojects - Implementing Verification task in the transport validation tasks - Allows better filtering for verification vs. other build failures. e.g. in Develocity Failures Overview - Use project.layout.settingsDirectory instead of project.rootProject.projectDir - Avoiding accessing other projects properties * Address some review feedback * Rework mapping project path list to dependencies * Some more review feedback * Minor tweak after review feedback
elastic#133695) * [Gradle] Some tweaks to transport related build logic - We want to avoid project.allprojects - Implementing Verification task in the transport validation tasks - Allows better filtering for verification vs. other build failures. e.g. in Develocity Failures Overview - Use project.layout.settingsDirectory instead of project.rootProject.projectDir - Avoiding accessing other projects properties * Address some review feedback * Rework mapping project path list to dependencies * Some more review feedback * Minor tweak after review feedback
e.g. in Develocity Failures Overview