Build transitive lint reports for apex modules

Build and export transitive lint report zips for apex modules.

Bug: 153485543
Test: m TARGET_BUILD_APPS=com.google.android.wifi lint-check dist
Change-Id: I5a1805440452301a7e2c4ca91482b989638b54fb
This commit is contained in:
Colin Cross 2020-07-21 20:31:17 -07:00
parent 9429c612ff
commit 08dca38eb0
8 changed files with 157 additions and 42 deletions

View File

@ -126,6 +126,26 @@ func (a *AndroidMkEntries) AddOptionalPath(name string, path OptionalPath) {
}
}
func (a *AndroidMkEntries) SetPaths(name string, paths Paths) {
if _, ok := a.EntryMap[name]; !ok {
a.entryOrder = append(a.entryOrder, name)
}
a.EntryMap[name] = paths.Strings()
}
func (a *AndroidMkEntries) SetOptionalPaths(name string, paths Paths) {
if len(paths) > 0 {
a.SetPaths(name, paths)
}
}
func (a *AndroidMkEntries) AddPaths(name string, paths Paths) {
if _, ok := a.EntryMap[name]; !ok {
a.entryOrder = append(a.entryOrder, name)
}
a.EntryMap[name] = append(a.EntryMap[name], paths.Strings()...)
}
func (a *AndroidMkEntries) SetBoolIfTrue(name string, flag bool) {
if flag {
if _, ok := a.EntryMap[name]; !ok {

View File

@ -353,6 +353,10 @@ func (a *apexBundle) androidMkForType() android.AndroidMkData {
if apexType == imageApex {
fmt.Fprintln(w, "ALL_MODULES.$(my_register_name).BUNDLE :=", a.bundleModuleFile.String())
}
if len(a.lintReports) > 0 {
fmt.Fprintln(w, "ALL_MODULES.$(my_register_name).LINT_REPORTS :=",
strings.Join(a.lintReports.Strings(), " "))
}
if a.installedFilesFile != nil {
goal := "checkbuild"

View File

@ -1154,6 +1154,7 @@ type apexFile struct {
hostRequiredModuleNames []string
jacocoReportClassesFile android.Path // only for javalibs and apps
lintDepSets java.LintDepSets // only for javalibs and apps
certificate java.Certificate // only for apps
overriddenPackageName string // only for apps
@ -1278,6 +1279,9 @@ type apexBundle struct {
// Struct holding the merged notice file paths in different formats
mergedNotices android.NoticeOutputs
// Optional list of lint report zip files for apexes that contain java or app modules
lintReports android.Paths
}
func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext,
@ -1666,9 +1670,16 @@ func apexFileForShBinary(ctx android.BaseModuleContext, sh *sh.ShBinary) apexFil
type javaDependency interface {
DexJarBuildPath() android.Path
JacocoReportClassesFile() android.Path
LintDepSets() java.LintDepSets
Stem() string
}
var _ javaDependency = (*java.Library)(nil)
var _ javaDependency = (*java.SdkLibrary)(nil)
var _ javaDependency = (*java.DexImport)(nil)
var _ javaDependency = (*java.SdkLibraryImport)(nil)
func apexFileForJavaLibrary(ctx android.BaseModuleContext, lib javaDependency, module android.Module) apexFile {
dirInApex := "javalib"
fileToCopy := lib.DexJarBuildPath()
@ -1676,6 +1687,7 @@ func apexFileForJavaLibrary(ctx android.BaseModuleContext, lib javaDependency, m
name := strings.TrimPrefix(module.Name(), "prebuilt_")
af := newApexFile(ctx, fileToCopy, name, dirInApex, javaSharedLib, module)
af.jacocoReportClassesFile = lib.JacocoReportClassesFile()
af.lintDepSets = lib.LintDepSets()
af.stem = lib.Stem() + ".jar"
return af
}
@ -2275,6 +2287,8 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx)
a.buildApexDependencyInfo(ctx)
a.buildLintReports(ctx)
}
// Enforce that Java deps of the apex are using stable SDKs to compile

View File

@ -815,3 +815,12 @@ func (a *apexBundle) buildApexDependencyInfo(ctx android.ModuleContext) {
},
})
}
func (a *apexBundle) buildLintReports(ctx android.ModuleContext) {
depSetsBuilder := java.NewLintDepSetBuilder()
for _, fi := range a.filesInfo {
depSetsBuilder.Transitive(fi.lintDepSets)
}
a.lintReports = java.BuildModuleLintReportZips(ctx, depSetsBuilder.Build())
}

View File

@ -132,9 +132,7 @@ func (library *Library) AndroidMkEntries() []android.AndroidMkEntries {
}
entries.SetString("LOCAL_MODULE_STEM", library.Stem())
entries.AddOptionalPath("LOCAL_SOONG_LINT_REPORTS", library.linter.outputs.transitiveHTMLZip)
entries.AddOptionalPath("LOCAL_SOONG_LINT_REPORTS", library.linter.outputs.transitiveTextZip)
entries.AddOptionalPath("LOCAL_SOONG_LINT_REPORTS", library.linter.outputs.transitiveXMLZip)
entries.SetOptionalPaths("LOCAL_SOONG_LINT_REPORTS", library.linter.reports)
},
},
}
@ -394,9 +392,7 @@ func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries {
entries.AddStrings("LOCAL_SOONG_BUILT_INSTALLED", extra.String()+":"+install)
}
entries.AddOptionalPath("LOCAL_SOONG_LINT_REPORTS", app.linter.outputs.transitiveHTMLZip)
entries.AddOptionalPath("LOCAL_SOONG_LINT_REPORTS", app.linter.outputs.transitiveTextZip)
entries.AddOptionalPath("LOCAL_SOONG_LINT_REPORTS", app.linter.outputs.transitiveXMLZip)
entries.SetOptionalPaths("LOCAL_SOONG_LINT_REPORTS", app.linter.reports)
},
},
ExtraFooters: []android.AndroidMkExtraFootersFunc{

View File

@ -1707,6 +1707,9 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
j.linter.compileSdkVersion = lintSDKVersionString(j.sdkVersion())
j.linter.javaLanguageLevel = flags.javaVersion.String()
j.linter.kotlinLanguageLevel = "1.3"
if j.ApexName() != "" && ctx.Config().UnbundledBuildApps() {
j.linter.buildModuleReportZip = true
}
j.linter.lint(ctx)
}
@ -2789,6 +2792,10 @@ func (a *DexImport) JacocoReportClassesFile() android.Path {
return nil
}
func (a *DexImport) LintDepSets() LintDepSets {
return LintDepSets{}
}
func (j *DexImport) IsInstallable() bool {
return true
}

View File

@ -69,28 +69,78 @@ type linter struct {
outputs lintOutputs
properties LintProperties
reports android.Paths
buildModuleReportZip bool
}
type lintOutputs struct {
html android.ModuleOutPath
text android.ModuleOutPath
xml android.ModuleOutPath
html android.Path
text android.Path
xml android.Path
transitiveHTML *android.DepSet
transitiveText *android.DepSet
transitiveXML *android.DepSet
transitiveHTMLZip android.OptionalPath
transitiveTextZip android.OptionalPath
transitiveXMLZip android.OptionalPath
depSets LintDepSets
}
type lintOutputIntf interface {
type lintOutputsIntf interface {
lintOutputs() *lintOutputs
}
var _ lintOutputIntf = (*linter)(nil)
type lintDepSetsIntf interface {
LintDepSets() LintDepSets
}
type LintDepSets struct {
HTML, Text, XML *android.DepSet
}
type LintDepSetsBuilder struct {
HTML, Text, XML *android.DepSetBuilder
}
func NewLintDepSetBuilder() LintDepSetsBuilder {
return LintDepSetsBuilder{
HTML: android.NewDepSetBuilder(android.POSTORDER),
Text: android.NewDepSetBuilder(android.POSTORDER),
XML: android.NewDepSetBuilder(android.POSTORDER),
}
}
func (l LintDepSetsBuilder) Direct(html, text, xml android.Path) LintDepSetsBuilder {
l.HTML.Direct(html)
l.Text.Direct(text)
l.XML.Direct(xml)
return l
}
func (l LintDepSetsBuilder) Transitive(depSets LintDepSets) LintDepSetsBuilder {
if depSets.HTML != nil {
l.HTML.Transitive(depSets.HTML)
}
if depSets.Text != nil {
l.Text.Transitive(depSets.Text)
}
if depSets.XML != nil {
l.XML.Transitive(depSets.XML)
}
return l
}
func (l LintDepSetsBuilder) Build() LintDepSets {
return LintDepSets{
HTML: l.HTML.Build(),
Text: l.Text.Build(),
XML: l.XML.Build(),
}
}
func (l *linter) LintDepSets() LintDepSets {
return l.outputs.depSets
}
var _ lintDepSetsIntf = (*linter)(nil)
var _ lintOutputsIntf = (*linter)(nil)
func (l *linter) lintOutputs() *lintOutputs {
return &l.outputs
@ -247,16 +297,11 @@ func (l *linter) lint(ctx android.ModuleContext) {
text := android.PathForModuleOut(ctx, "lint-report.txt")
xml := android.PathForModuleOut(ctx, "lint-report.xml")
htmlDeps := android.NewDepSetBuilder(android.POSTORDER).Direct(html)
textDeps := android.NewDepSetBuilder(android.POSTORDER).Direct(text)
xmlDeps := android.NewDepSetBuilder(android.POSTORDER).Direct(xml)
depSetsBuilder := NewLintDepSetBuilder().Direct(html, text, xml)
ctx.VisitDirectDepsWithTag(staticLibTag, func(dep android.Module) {
if depLint, ok := dep.(lintOutputIntf); ok {
depLintOutputs := depLint.lintOutputs()
htmlDeps.Transitive(depLintOutputs.transitiveHTML)
textDeps.Transitive(depLintOutputs.transitiveText)
xmlDeps.Transitive(depLintOutputs.transitiveXML)
if depLint, ok := dep.(lintDepSetsIntf); ok {
depSetsBuilder.Transitive(depLint.LintDepSets())
}
})
@ -309,26 +354,35 @@ func (l *linter) lint(ctx android.ModuleContext) {
text: text,
xml: xml,
transitiveHTML: htmlDeps.Build(),
transitiveText: textDeps.Build(),
transitiveXML: xmlDeps.Build(),
depSets: depSetsBuilder.Build(),
}
if l.buildModuleReportZip {
htmlZip := android.PathForModuleOut(ctx, "lint-report-html.zip")
l.outputs.transitiveHTMLZip = android.OptionalPathForPath(htmlZip)
lintZip(ctx, l.outputs.transitiveHTML.ToSortedList(), htmlZip)
textZip := android.PathForModuleOut(ctx, "lint-report-text.zip")
l.outputs.transitiveTextZip = android.OptionalPathForPath(textZip)
lintZip(ctx, l.outputs.transitiveText.ToSortedList(), textZip)
xmlZip := android.PathForModuleOut(ctx, "lint-report-xml.zip")
l.outputs.transitiveXMLZip = android.OptionalPathForPath(xmlZip)
lintZip(ctx, l.outputs.transitiveXML.ToSortedList(), xmlZip)
l.reports = BuildModuleLintReportZips(ctx, l.LintDepSets())
}
}
func BuildModuleLintReportZips(ctx android.ModuleContext, depSets LintDepSets) android.Paths {
htmlList := depSets.HTML.ToSortedList()
textList := depSets.Text.ToSortedList()
xmlList := depSets.XML.ToSortedList()
if len(htmlList) == 0 && len(textList) == 0 && len(xmlList) == 0 {
return nil
}
htmlZip := android.PathForModuleOut(ctx, "lint-report-html.zip")
lintZip(ctx, htmlList, htmlZip)
textZip := android.PathForModuleOut(ctx, "lint-report-text.zip")
lintZip(ctx, textList, textZip)
xmlZip := android.PathForModuleOut(ctx, "lint-report-xml.zip")
lintZip(ctx, xmlList, xmlZip)
return android.Paths{htmlZip, textZip, xmlZip}
}
type lintSingleton struct {
htmlZip android.WritablePath
textZip android.WritablePath
@ -403,7 +457,7 @@ func (l *lintSingleton) generateLintReportZips(ctx android.SingletonContext) {
return
}
if l, ok := m.(lintOutputIntf); ok {
if l, ok := m.(lintOutputsIntf); ok {
outputs = append(outputs, l.lintOutputs())
}
})
@ -414,7 +468,9 @@ func (l *lintSingleton) generateLintReportZips(ctx android.SingletonContext) {
var paths android.Paths
for _, output := range outputs {
paths = append(paths, get(output))
if p := get(output); p != nil {
paths = append(paths, p)
}
}
lintZip(ctx, paths, outputPath)

View File

@ -1995,6 +1995,15 @@ func (module *SdkLibraryImport) JacocoReportClassesFile() android.Path {
}
}
// to satisfy apex.javaDependency interface
func (module *SdkLibraryImport) LintDepSets() LintDepSets {
if module.implLibraryModule == nil {
return LintDepSets{}
} else {
return module.implLibraryModule.LintDepSets()
}
}
// to satisfy apex.javaDependency interface
func (module *SdkLibraryImport) Stem() string {
return module.BaseModuleName()