Merge changes Ibdeb2e5a,I520a5af4,I0db32bec,Id3ab0f3b

* changes:
  Add lint_project_xml_test.py
  Rename lint-project-xml.py to remove dashes.
  Lint baseline file check in lint-project-xml
  Extract getBaselineFilepath method.
This commit is contained in:
Jaewoong Jung 2021-04-20 22:59:38 +00:00 committed by Gerrit Code Review
commit cbb3825d86
4 changed files with 108 additions and 15 deletions

View File

@ -200,7 +200,7 @@ func (l *linter) writeLintProjectXML(ctx android.ModuleContext, rule *android.Ru
srcJarList := zipSyncCmd(ctx, rule, srcJarDir, l.srcJars) srcJarList := zipSyncCmd(ctx, rule, srcJarDir, l.srcJars)
cmd := rule.Command(). cmd := rule.Command().
BuiltTool("lint-project-xml"). BuiltTool("lint_project_xml").
FlagWithOutput("--project_out ", projectXMLPath). FlagWithOutput("--project_out ", projectXMLPath).
FlagWithOutput("--config_out ", configXMLPath). FlagWithOutput("--config_out ", configXMLPath).
FlagWithArg("--name ", ctx.ModuleName()) FlagWithArg("--name ", ctx.ModuleName())
@ -279,6 +279,19 @@ func (l *linter) generateManifest(ctx android.ModuleContext, rule *android.RuleB
return manifestPath return manifestPath
} }
func (l *linter) getBaselineFilepath(ctx android.ModuleContext) android.OptionalPath {
var lintBaseline android.OptionalPath
if lintFilename := proptools.StringDefault(l.properties.Lint.Baseline_filename, "lint-baseline.xml"); lintFilename != "" {
if String(l.properties.Lint.Baseline_filename) != "" {
// if manually specified, we require the file to exist
lintBaseline = android.OptionalPathForPath(android.PathForModuleSrc(ctx, lintFilename))
} else {
lintBaseline = android.ExistentPathForSource(ctx, ctx.ModuleDir(), lintFilename)
}
}
return lintBaseline
}
func (l *linter) lint(ctx android.ModuleContext) { func (l *linter) lint(ctx android.ModuleContext) {
if !l.enabled() { if !l.enabled() {
return return
@ -381,18 +394,10 @@ func (l *linter) lint(ctx android.ModuleContext) {
cmd.FlagWithArg("--check ", checkOnly) cmd.FlagWithArg("--check ", checkOnly)
} }
if lintFilename := proptools.StringDefault(l.properties.Lint.Baseline_filename, "lint-baseline.xml"); lintFilename != "" { lintBaseline := l.getBaselineFilepath(ctx)
var lintBaseline android.OptionalPath
if String(l.properties.Lint.Baseline_filename) != "" {
// if manually specified, we require the file to exist
lintBaseline = android.OptionalPathForPath(android.PathForModuleSrc(ctx, lintFilename))
} else {
lintBaseline = android.ExistentPathForSource(ctx, ctx.ModuleDir(), lintFilename)
}
if lintBaseline.Valid() { if lintBaseline.Valid() {
cmd.FlagWithInput("--baseline ", lintBaseline.Path()) cmd.FlagWithInput("--baseline ", lintBaseline.Path())
} }
}
cmd.Text("|| (").Text("if [ -e").Input(text).Text("]; then cat").Input(text).Text("; fi; exit 7)") cmd.Text("|| (").Text("if [ -e").Input(text).Text("]; then cat").Input(text).Text("; fi; exit 7)")

View File

@ -219,14 +219,25 @@ python_library_host {
} }
python_binary_host { python_binary_host {
name: "lint-project-xml", name: "lint_project_xml",
main: "lint-project-xml.py", main: "lint_project_xml.py",
srcs: [ srcs: [
"lint-project-xml.py", "lint_project_xml.py",
], ],
libs: ["ninja_rsp"], libs: ["ninja_rsp"],
} }
python_test_host {
name: "lint_project_xml_test",
main: "lint_project_xml_test.py",
srcs: [
"lint_project_xml_test.py",
"lint_project_xml.py",
],
libs: ["ninja_rsp"],
test_suites: ["general-tests"],
}
python_binary_host { python_binary_host {
name: "gen-kotlin-build-file.py", name: "gen-kotlin-build-file.py",
main: "gen-kotlin-build-file.py", main: "gen-kotlin-build-file.py",

View File

@ -18,6 +18,7 @@
"""This file generates project.xml and lint.xml files used to drive the Android Lint CLI tool.""" """This file generates project.xml and lint.xml files used to drive the Android Lint CLI tool."""
import argparse import argparse
from xml.dom import minidom
from ninja_rsp import NinjaRspFileReader from ninja_rsp import NinjaRspFileReader
@ -73,6 +74,8 @@ def parse_args():
help='file containing the module\'s manifest.') help='file containing the module\'s manifest.')
parser.add_argument('--merged_manifest', dest='merged_manifest', parser.add_argument('--merged_manifest', dest='merged_manifest',
help='file containing merged manifest for the module and its dependencies.') help='file containing merged manifest for the module and its dependencies.')
parser.add_argument('--baseline', dest='baseline_path',
help='file containing baseline lint issues.')
parser.add_argument('--library', dest='library', action='store_true', parser.add_argument('--library', dest='library', action='store_true',
help='mark the module as a library.') help='mark the module as a library.')
parser.add_argument('--test', dest='test', action='store_true', parser.add_argument('--test', dest='test', action='store_true',
@ -90,6 +93,8 @@ def parse_args():
help='treat a lint issue as a warning.') help='treat a lint issue as a warning.')
group.add_argument('--disable_check', dest='checks', action=check_action('ignore'), default=[], group.add_argument('--disable_check', dest='checks', action=check_action('ignore'), default=[],
help='disable a lint issue.') help='disable a lint issue.')
group.add_argument('--disallowed_issues', dest='disallowed_issues', default=[],
help='lint issues disallowed in the baseline file')
return parser.parse_args() return parser.parse_args()
@ -134,10 +139,30 @@ def write_config_xml(f, args):
f.write("</lint>\n") f.write("</lint>\n")
def check_baseline_for_disallowed_issues(baseline, forced_checks):
issues_element = baseline.documentElement
if issues_element.tagName != 'issues':
raise RuntimeError('expected issues tag at root')
issues = issues_element.getElementsByTagName('issue')
disallwed = set()
for issue in issues:
id = issue.getAttribute('id')
if id in forced_checks:
disallwed.add(id)
return disallwed
def main(): def main():
"""Program entry point.""" """Program entry point."""
args = parse_args() args = parse_args()
if args.baseline_path:
baseline = minidom.parse(args.baseline_path)
diallowed_issues = check_baseline_for_disallowed_issues(baseline, args.disallowed_issues)
if bool(diallowed_issues):
raise RuntimeError('disallowed issues %s found in lint baseline file %s for module %s'
% (diallowed_issues, args.baseline_path, args.name))
if args.project_out: if args.project_out:
with open(args.project_out, 'w') as f: with open(args.project_out, 'w') as f:
write_project_xml(f, args) write_project_xml(f, args)

View File

@ -0,0 +1,52 @@
#!/usr/bin/env python3
#
# Copyright (C) 2021 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""Unit tests for lint_project_xml.py."""
import unittest
from xml.dom import minidom
import lint_project_xml
class CheckBaselineForDisallowedIssuesTest(unittest.TestCase):
"""Unit tests for check_baseline_for_disallowed_issues function."""
baseline_xml = minidom.parseString(
'<?xml version="1.0" encoding="utf-8"?>\n'
'<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">\n'
' <issue id="foo" message="foo is evil" errorLine1="foo()">\n'
' <location file="a/b/c.java" line="3" column="10"/>\n'
' </issue>\n'
' <issue id="bar" message="bar is known to be evil" errorLine1="bar()">\n'
' <location file="a/b/c.java" line="5" column="12"/>\n'
' </issue>\n'
' <issue id="baz" message="baz may be evil" errorLine1="a = baz()">\n'
' <location file="a/b/c.java" line="10" column="10"/>\n'
' </issue>\n'
' <issue id="foo" message="foo is evil" errorLine1="b = foo()">\n'
' <location file="a/d/e.java" line="100" column="4"/>\n'
' </issue>\n'
'</issues>\n')
def test_check_baseline_for_disallowed_issues(self):
disallowed_issues = lint_project_xml.check_baseline_for_disallowed_issues(self.baseline_xml, ["foo", "bar", "qux"])
self.assertEqual({"foo", "bar"}, disallowed_issues)
if __name__ == '__main__':
unittest.main(verbosity=2)