-
Notifications
You must be signed in to change notification settings - Fork 27
[PT-511] Configure lint via SAP extension #51
[PT-511] Configure lint via SAP extension #51
Conversation
…o maven in this test
This reverts commit 6a1a943.
@@ -15,11 +13,6 @@ import static com.novoda.test.LogsSubject.assertThat | |||
@RunWith(Parameterized.class) | |||
class DetektIntegrationTest { | |||
|
|||
@ClassRule |
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.
Just some boy scouting, we're not using the artifact in this test.
@@ -63,11 +63,6 @@ ${formatExtension(project)} | |||
.join('\n\t\t') | |||
} | |||
|
|||
@Override |
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 what was the reasons for this? Can we kill it? All tests are still passing...
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.
the reason for this was to temporary disable lint as the default configuration breaks the build on error. I would have expected the other integration tests to fail if these lines are removed, mmm
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. Have 1 confusion and small comments.
@@ -63,11 +63,6 @@ ${formatExtension(project)} | |||
.join('\n\t\t') | |||
} | |||
|
|||
@Override | |||
List<String> defaultArguments() { | |||
['-x', 'lint'] + super.defaultArguments() |
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 CollectLintViolationsTask createCollectViolationsTask(Violations violations) { | ||
def outputFolder = new File(project.projectDir, 'build/reports') |
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.
We shouldn't hardcode build/reports
, android team may change the location. I wonder if the lint
task has output?
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, I agree. Also the user can change the location.
return | ||
} | ||
|
||
project.extensions.findByName('android').lintOptions(config) |
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 if you like more groovy magic but I believe this can be replaced by
project.android.lintOptions(config)
static LintConfigurator create(Project project, | ||
NamedDomainObjectContainer<Violations> violationsContainer, | ||
Task evaluateViolations) { | ||
Violations violations = violationsContainer.maybeCreate('Lint') |
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 confused by this maybeCreate('Lint')
This means that the container is supposed to have a named closure called Lint
but I couldn't find another usage. Not in the tests for example.
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 am also confused since I don't fully understand what's going in here. Tbh I just copy pasted it from the other configurators. From what I understand we pass the same Violations
to each Configurator
. But I don't understand how this relates to it.
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.
Maybe @mr-archano can enlighten us around 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.
We just hold all the violations in the plugin extension to keep the output of each tool output in memory before the final evaluation (see StaticAnalysisExtension.allViolations
).
Each tool is now responsible of creating the Violations
entry in the container, that is then passed to the evaluateViolations
task.
As already mentioned IRL couple of times this is a pretty lame way of collecting all the info, and I already logged an issue to get rid of this in the next future: #43
} | ||
|
||
private CollectLintViolationsTask createCollectViolationsTask(Violations violations) { | ||
def outputFolder = new File(project.projectDir, 'build/reports') |
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 follow-up it would be good to resolve this path dynamically. Otherwise this will break in case the user configures another 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.
we should fix this now, as we shouldn't hardcode anything that can be configured. The only constraint we actually have is that we need to get this information after lint is configured, in order to read the correct path to the xml report. We have two ways of doing this as I see it: we get it from lintOptions
or from the lint
task.
If we assume that the user will configure lint through our plugin - effectively done at L36 - then we should be able to read the value from the lint extension right afterwards, 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.
Also keep in mind that lint
is run for all variants. Maybe we should have includeVariants
here too. But in any case, should we also support multiple outputs?
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 this PR is towards a feature branch. Not on develop. So I think we can just merge it without this? with a follow-up soon?
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 just checked that, but the output path of lintOptions
is null in case the user hasn't configured it. So we need to find another way. I agree with @tasomaniac to follow up on this as part of this ticket.
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.
We agreed on for now to check whether the output path of lintOptions
is configured or to fall back to the hardcoded one.
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 done
@Override | ||
void execute() { | ||
project.extensions.findByType(StaticAnalysisExtension).ext."lintOptions" = { Closure config -> | ||
|
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: extra whiteline
|
||
private CollectLintViolationsTask createCollectViolationsTask(Violations violations) { | ||
def outputFolder = new File(project.projectDir, 'build/reports') | ||
project.tasks.create("collectLintViolations", CollectLintViolationsTask) { collectViolations -> |
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: use single quotes for "collectLintViolations"
for consistency
Project project = ProjectBuilder.builder().build() | ||
def task = project.task('collectLintViolationsTask', type: CollectLintViolationsTask) | ||
|
||
Violations violations = new Violations("Android Lint") |
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: use single quotes for "Android Lint"
for consistency
public class Warning { | ||
|
||
public Warning() { | ||
// assertions are ignored at runtime |
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 the plugin can't deal with Lint warnings, but only with errors? Not really clear to 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.
Nope, using assertions in code results in a Warning
for lint. This is just a fixture that can be used for tests when provoking a lint warning.
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 I'm blind and I hadn't seen the path. My bad, sorry :)
testProject.withToolsConfig(lintConfiguration()) | ||
} | ||
|
||
private static GString lintConfiguration() { |
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 not a constant or inlined as a string?
return | ||
} | ||
|
||
project.android.lintOptions(config) |
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 seems to be missing the bit where we avoid lint to break the build (we want to be in charge of when doing that). I believe we should force abortOnError false
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.
Having a look at the whole options here: https://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.LintOptions.html
I think we can also add xmlReport true
to make sure that xml report is enabled.
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.
Same for the htmlReport I'd say
} | ||
|
||
private CollectLintViolationsTask createCollectViolationsTask(Violations violations) { | ||
def outputFolder = new File(project.projectDir, 'build/reports') |
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.
we should fix this now, as we shouldn't hardcode anything that can be configured. The only constraint we actually have is that we need to get this information after lint is configured, in order to read the correct path to the xml report. We have two ways of doing this as I see it: we get it from lintOptions
or from the lint
task.
If we assume that the user will configure lint through our plugin - effectively done at L36 - then we should be able to read the value from the lint extension right afterwards, right?
@@ -63,11 +63,6 @@ ${formatExtension(project)} | |||
.join('\n\t\t') | |||
} | |||
|
|||
@Override |
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.
the reason for this was to temporary disable lint as the default configuration breaks the build on error. I would have expected the other integration tests to fail if these lines are removed, mmm
5744c3b
to
ff98b70
Compare
collectViolations.violations = violations | ||
} | ||
} | ||
|
||
private File xmlOutputFile() { |
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.
sorry to be a PITA, but this could be a getter getXmlOutputFile()
, so you can use it simply at L58 as xmlOutputFile
property
project.android.lintOptions.xmlOutput ?: new File(defaultOutputFolder(), 'lint-results.xml') | ||
} | ||
|
||
private File defaultOutputFolder() { |
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.
same here
} | ||
|
||
private File defaultOutputFolder() { | ||
new File(project.projectDir, 'build/reports') |
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.
you should never add build/
, but rather use project.buildDir
. this will become then:
new File(project.buildDir, 'reports')
PT-511
Description
Scope of this PR is to add basic support for Android Lint to the SAP plugin.
This targets a feature branch.
Considerations
Added
CollectLintViolationsTask
which parseslint-result.xml
and appends errors and warnings to the violationsAdded
LintConfigurator
which applies thelintConfig
closure to Lint and orchestrates the tasksTests
CollectLintViolationsTask
to verify we parse thelint-result.xml
correctlyLintIntegrationTest
which verifies warnings and errors are considered for the thresholdsPaired with @lgvalle on parts of it