Conversation
…ter to know if we have a custom filter set. Simplify lint configurator by extracting methods
a51339a
to
3a5b7bb
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.
Left a couple of remarks. We can discuss this IRL if you prefer.
|
||
trait VariantAware { | ||
|
||
private boolean hasFilter = false |
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.
why don't we keep out of the trait
API and we just keep the getFiltered*()
? this way we can choose in the configurator how to deal with that, for instance only Lint needs to know whether the filter is set or not, right?
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.
trait
allows me to have implementation and fields here. I don't want to lose that.
The other option is to make it nullable. Let me try and see how that goes actually. hasFilter
is not necessary.
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.
Oh, addressing here, I pushed to clean-up
branch. That looks much nicer.
trait VariantAware { | ||
|
||
private boolean hasFilter = false | ||
Closure<Boolean> includeVariantsFilter = { true } |
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 can be just Closure<Boolean> getIncludeVariantsFilter()
that we'll leave to the configurators to implement.
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.
setter
is also used in subclasses. I can of course do this but the beauty of a trait is to encapsulate the variant behavior all here.
If I implement getIncludeVariantsFilter
in the subclasses, then I would need a property there.
|
||
private void configureWithVariants(Closure config, DomainObjectSet variants) { | ||
configureLint(config) | ||
if (hasFilter) { |
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.
where hasFilter
is coming from now? not sure how this is working now - if it's working even
} | ||
} | ||
|
||
private File getXmlOutputFile() { | ||
project.android.lintOptions.xmlOutput ?: new File(defaultOutputFolder, 'lint-results.xml') | ||
private File xmlOutputFileFor(reportSuffix) { |
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 would prefer to push the report name directly and take the decision up two levels from here, so to keep it close to where we call configureCollectViolationsTask()
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 not sure what you mean by 2 level. Do mean the with
clause above just after we create the task. The xmlReportFile
property of the task is better to be configured while it is created.
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.
what I mean is that instead of adding this suffix logic you can move the decision of specifying what task name and what report name to use up to L36 and L38 (in that case no need of if anymore, right?)
retest this please |
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, just some questions
import org.gradle.api.DomainObjectSet | ||
import org.gradle.api.NamedDomainObjectSet | ||
|
||
trait VariantAware { |
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.
Personally I would haven chosen composition over inheritance here since we mostly expose fields and methods to be shared.
project.plugins.withId('com.android.library') { | ||
configureWithVariants(config, filteredLibraryVariants) | ||
} | ||
|
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: empty line
} | ||
} | ||
|
||
private void configureLint(Closure config) { | ||
project.android.lintOptions.ext.includeVariants = { Closure<Boolean> filter -> |
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.
@mr-archano
Could u explain us what exactly happens in this closure?
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 not sure what you're asking @tobiasheine (as I didn't write this), but I will try to explain what I can see going on here: L54 adds an extension method to lintOptions
that takes a filter
predicate, used by VariantAware.variantSelector
to actually filter in only the variants for which filter
is evaluated as true
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.
Right, he was asking because this is a copy paste from the other ones.
I was also wondering how this works exactly. One question comes to mind, there is no mention of the input of the closure. We expect the input to be a variant but I guess there is no limit? Can it be anything?
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 understand that we define a extension includeVariants
with a Closure<Boolean>
and what it is used for.
What is confusing to me is the assignment includeVariantsFilter = filter
within the closure or when it is executed. Is it like a callback that is triggered when the user specifies the extension?
|
||
Closure<Boolean> includeVariantsFilter | ||
|
||
final variantSelector = { variants -> |
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't this just be a normal private method then? it's weird to see it defined it like this...
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.
Method didn't work how I wanted it to be with this trait thingy. I guess I can do Tobi's suggestion and make this a real collaborator class.
private File getXmlOutputFile() { | ||
project.android.lintOptions.xmlOutput ?: new File(defaultOutputFolder, 'lint-results.xml') | ||
private File xmlOutputFileFor(reportSuffix) { | ||
project.android.lintOptions.xmlOutput ?: new File(defaultOutputFolder, "lint-results${reportSuffix}.xml") |
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.
does this mean that when the user sets xmlOutput
then every variant task will output to the same report file?
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.
No idea. ☺ Good question. Only way to find out is to try. I don't think the documentation mentions that.
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.
It overrides the files. If you have xmlOuput defined, you get a single output no matter which lint task you run. So this seems to be the right way to do. But also we should do it for HTML report actually. Same happens for that too.
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.
that's weird behaviour. I agree that this is in line with the default reporting, but I wonder if we should provide a better way to handle that when using variant-aware lint tasks (ie: log a warning/error, or ignore that, or try to generate variant-aware reports from xmlOutput
).
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 agree. We can talk to Android team about this.
I don't think it is possible to do variant-aware custom xmlOutput
at the moment. It is because this configuration is done only once in the configuration phase. Whatever you do overrides the file name. You can only have 1 single name for the output. If it is null, they generate file names with variant name in it.
to have less logic in the task creation Also changed html output to be the same as the xml one
retest this please |
@mr-archano please have another look. |
import org.gradle.api.NamedDomainObjectSet | ||
import org.gradle.api.Project | ||
|
||
final class VariantFilter { |
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.
✨
private void configureWithVariants(DomainObjectSet variants) { | ||
if (variantFilter.includeVariantsFilter != null) { | ||
variants.all { | ||
configureCollectViolationsTask(it.name, "lint-results-${it.name}") |
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.
me happy! 🐶
Fixes #66
Fixes #77
Problem
The lint setup didn't have filters around Android variants. In a big project with 10+ variants, the
evaluateViolations
task take too long. (around 20 mins)Solution
This PR make
lintOptions
variant aware.trait
to encapsulate Android variant awareness in Configurators.project.plugins.withId('com.android.application')
to wait for potential plugin addition. This will fix the timing issue described in Timing issue with lint configuration #77Nullable
variant param to task creation and change the report file path accordingly.Note: When filter is not provided, it will keep the old behavior. When filter is used, we may get duplicated results when the same problem is available in an intersection of the sourceSets of multiple variants. This problem is available in all tasks and fix will be introduced later.
Tests
Lots of tests added including the duplicate number behavior.
A test is also added to check if we really ignore problems when the variant is ignored.