1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
|
#!/usr/bin/env python3
#
# Copyright (C) 2018 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.
#
"""This file generates project.xml and lint.xml files used to drive the Android Lint CLI tool."""
import argparse
from ninja_rsp import NinjaRspFileReader
def check_action(check_type):
"""
Returns an action that appends a tuple of check_type and the argument to the dest.
"""
class CheckAction(argparse.Action):
def __init__(self, option_strings, dest, nargs=None, **kwargs):
if nargs is not None:
raise ValueError("nargs must be None, was %s" % nargs)
super(CheckAction, self).__init__(option_strings, dest, **kwargs)
def __call__(self, parser, namespace, values, option_string=None):
checks = getattr(namespace, self.dest, [])
checks.append((check_type, values))
setattr(namespace, self.dest, checks)
return CheckAction
def parse_args():
"""Parse commandline arguments."""
def convert_arg_line_to_args(arg_line):
for arg in arg_line.split():
if arg.startswith('#'):
return
if not arg.strip():
continue
yield arg
parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
parser.convert_arg_line_to_args = convert_arg_line_to_args
parser.add_argument('--project_out', dest='project_out',
help='file to which the project.xml contents will be written.')
parser.add_argument('--config_out', dest='config_out',
help='file to which the lint.xml contents will be written.')
parser.add_argument('--name', dest='name',
help='name of the module.')
parser.add_argument('--srcs', dest='srcs', action='append', default=[],
help='file containing whitespace separated list of source files.')
parser.add_argument('--generated_srcs', dest='generated_srcs', action='append', default=[],
help='file containing whitespace separated list of generated source files.')
parser.add_argument('--resources', dest='resources', action='append', default=[],
help='file containing whitespace separated list of resource files.')
parser.add_argument('--classes', dest='classes', action='append', default=[],
help='file containing the module\'s classes.')
parser.add_argument('--classpath', dest='classpath', action='append', default=[],
help='file containing classes from dependencies.')
parser.add_argument('--extra_checks_jar', dest='extra_checks_jars', action='append', default=[],
help='file containing extra lint checks.')
parser.add_argument('--manifest', dest='manifest',
help='file containing the module\'s manifest.')
parser.add_argument('--merged_manifest', dest='merged_manifest',
help='file containing merged manifest for the module and its dependencies.')
parser.add_argument('--library', dest='library', action='store_true',
help='mark the module as a library.')
parser.add_argument('--test', dest='test', action='store_true',
help='mark the module as a test.')
parser.add_argument('--cache_dir', dest='cache_dir',
help='directory to use for cached file.')
parser.add_argument('--root_dir', dest='root_dir',
help='directory to use for root dir.')
group = parser.add_argument_group('check arguments', 'later arguments override earlier ones.')
group.add_argument('--fatal_check', dest='checks', action=check_action('fatal'), default=[],
help='treat a lint issue as a fatal error.')
group.add_argument('--error_check', dest='checks', action=check_action('error'), default=[],
help='treat a lint issue as an error.')
group.add_argument('--warning_check', dest='checks', action=check_action('warning'), default=[],
help='treat a lint issue as a warning.')
group.add_argument('--disable_check', dest='checks', action=check_action('ignore'), default=[],
help='disable a lint issue.')
return parser.parse_args()
def write_project_xml(f, args):
test_attr = "test='true' " if args.test else ""
f.write("<?xml version='1.0' encoding='utf-8'?>\n")
f.write("<project>\n")
if args.root_dir:
f.write(" <root dir='%s' />\n" % args.root_dir)
f.write(" <module name='%s' android='true' %sdesugar='full' >\n" % (args.name, "library='true' " if args.library else ""))
if args.manifest:
f.write(" <manifest file='%s' %s/>\n" % (args.manifest, test_attr))
if args.merged_manifest:
f.write(" <merged-manifest file='%s' %s/>\n" % (args.merged_manifest, test_attr))
for src_file in args.srcs:
for src in NinjaRspFileReader(src_file):
f.write(" <src file='%s' %s/>\n" % (src, test_attr))
for src_file in args.generated_srcs:
for src in NinjaRspFileReader(src_file):
f.write(" <src file='%s' generated='true' %s/>\n" % (src, test_attr))
for res_file in args.resources:
for res in NinjaRspFileReader(res_file):
f.write(" <resource file='%s' %s/>\n" % (res, test_attr))
for classes in args.classes:
f.write(" <classes jar='%s' />\n" % classes)
for classpath in args.classpath:
f.write(" <classpath jar='%s' />\n" % classpath)
for extra in args.extra_checks_jars:
f.write(" <lint-checks jar='%s' />\n" % extra)
f.write(" </module>\n")
if args.cache_dir:
f.write(" <cache dir='%s'/>\n" % args.cache_dir)
f.write("</project>\n")
def write_config_xml(f, args):
f.write("<?xml version='1.0' encoding='utf-8'?>\n")
f.write("<lint>\n")
for check in args.checks:
f.write(" <issue id='%s' severity='%s' />\n" % (check[1], check[0]))
f.write("</lint>\n")
def main():
"""Program entry point."""
args = parse_args()
if args.project_out:
with open(args.project_out, 'w') as f:
write_project_xml(f, args)
if args.config_out:
with open(args.config_out, 'w') as f:
write_config_xml(f, args)
if __name__ == '__main__':
main()
|