Loading tools/lint/fix/soong_lint_fix.py +36 −21 Original line number Diff line number Diff line Loading @@ -64,27 +64,27 @@ class SoongModule: class SoongLintFix: """ This class creates a command line tool that will apply lint fixes to the platform via the necessary combination of soong and shell commands. This class creates a command line tool that will apply lint fixes to the platform via the necessary combination of soong and shell commands. It breaks up these operations into a few "private" methods that are intentionally exposed so experimental code can tweak behavior. It breaks up these operations into a few "private" methods that are intentionally exposed so experimental code can tweak behavior. The entry point, `run`, will apply lint fixes using the intermediate `suggested-fixes` directory that soong creates during its invocation of lint. The entry point, `run`, will apply lint fixes using the intermediate `suggested-fixes` directory that soong creates during its invocation of lint. Basic usage: ``` from soong_lint_fix import SoongLintFix SoongLintFix().run() opts = SoongLintFixOptions() opts.parse_args(sys.argv) SoongLintFix(opts).run() ``` """ def __init__(self): self._parser = _setup_parser() self._args = None def __init__(self, opts): self._opts = opts self._kwargs = None self._modules = [] Loading @@ -96,19 +96,18 @@ class SoongLintFix: self._find_modules() self._lint() if not self._args.no_fix: if not self._opts.no_fix: self._fix() if self._args.print: if self._opts.print: self._print() def _setup(self): self._args = self._parser.parse_args() env = os.environ.copy() if self._args.check: env["ANDROID_LINT_CHECK"] = self._args.check if self._args.lint_module: env["ANDROID_LINT_CHECK_EXTRA_MODULES"] = self._args.lint_module if self._opts.check: env["ANDROID_LINT_CHECK"] = self._opts.check if self._opts.lint_module: env["ANDROID_LINT_CHECK_EXTRA_MODULES"] = self._opts.lint_module self._kwargs = { "env": env, Loading @@ -131,7 +130,7 @@ class SoongLintFix: with open(f"{ANDROID_PRODUCT_OUT}/module-info.json") as f: module_info = json.load(f) for module_name in self._args.modules: for module_name in self._opts.modules: module = SoongModule(module_name) module.find(module_info) self._modules.append(module) Loading Loading @@ -169,6 +168,20 @@ class SoongLintFix: print(f.read()) class SoongLintFixOptions: """Options for SoongLintFix""" def __init__(self): self.modules = [] self.check = None self.lint_module = None self.no_fix = False self.print = False def parse_args(self, args=None): _setup_parser().parse_args(args, self) def _setup_parser(): parser = argparse.ArgumentParser(description=""" This is a python script that applies lint fixes to the platform: Loading Loading @@ -199,4 +212,6 @@ def _setup_parser(): return parser if __name__ == "__main__": SoongLintFix().run() opts = SoongLintFixOptions() opts.parse_args(sys.argv) SoongLintFix(opts).run() tools/lint/utils/Android.bp +6 −0 Original line number Diff line number Diff line Loading @@ -43,3 +43,9 @@ java_test_host { "AndroidUtilsLintChecker", ], } python_binary_host { name: "enforce_permission_counter", srcs: ["enforce_permission_counter.py"], libs: ["soong_lint_fix"], } tools/lint/utils/enforce_permission_counter.py 0 → 100644 +82 −0 Original line number Diff line number Diff line # Copyright (C) 2023 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. import re import soong_lint_fix # Libraries that constitute system_server. # It is non-trivial to keep in sync with services/Android.bp as some # module are post-processed (e.g, services.core). TARGETS = [ "services.core.unboosted", "services.accessibility", "services.appprediction", "services.appwidget", "services.autofill", "services.backup", "services.companion", "services.contentcapture", "services.contentsuggestions", "services.coverage", "services.devicepolicy", "services.midi", "services.musicsearch", "services.net", "services.people", "services.print", "services.profcollect", "services.restrictions", "services.searchui", "services.smartspace", "services.systemcaptions", "services.translation", "services.texttospeech", "services.usage", "services.usb", "services.voiceinteraction", "services.wallpapereffectsgeneration", "services.wifi", ] class EnforcePermissionMigratedCounter: """Wrapper around lint_fix to count the number of AIDL methods annotated.""" def run(self): opts = soong_lint_fix.SoongLintFixOptions() opts.check = "AnnotatedAidlCounter" opts.lint_module = "AndroidUtilsLintChecker" opts.no_fix = True opts.modules = TARGETS self.linter = soong_lint_fix.SoongLintFix(opts) self.linter.run() self.parse_lint_reports() def parse_lint_reports(self): counts = { "unannotated": 0, "enforced": 0, "notRequired": 0 } for module in self.linter._modules: with open(module.lint_report, "r") as f: content = f.read() keys = dict(re.findall(r'(\w+)=(\d+)', content)) for key in keys: counts[key] += int(keys[key]) print(counts) total = sum(counts.values()) annotated_percent = (1 - (counts["unannotated"] / total)) * 100 print("Annotated methods = %.2f%%" % (annotated_percent)) if __name__ == "__main__": EnforcePermissionMigratedCounter().run() Loading
tools/lint/fix/soong_lint_fix.py +36 −21 Original line number Diff line number Diff line Loading @@ -64,27 +64,27 @@ class SoongModule: class SoongLintFix: """ This class creates a command line tool that will apply lint fixes to the platform via the necessary combination of soong and shell commands. This class creates a command line tool that will apply lint fixes to the platform via the necessary combination of soong and shell commands. It breaks up these operations into a few "private" methods that are intentionally exposed so experimental code can tweak behavior. It breaks up these operations into a few "private" methods that are intentionally exposed so experimental code can tweak behavior. The entry point, `run`, will apply lint fixes using the intermediate `suggested-fixes` directory that soong creates during its invocation of lint. The entry point, `run`, will apply lint fixes using the intermediate `suggested-fixes` directory that soong creates during its invocation of lint. Basic usage: ``` from soong_lint_fix import SoongLintFix SoongLintFix().run() opts = SoongLintFixOptions() opts.parse_args(sys.argv) SoongLintFix(opts).run() ``` """ def __init__(self): self._parser = _setup_parser() self._args = None def __init__(self, opts): self._opts = opts self._kwargs = None self._modules = [] Loading @@ -96,19 +96,18 @@ class SoongLintFix: self._find_modules() self._lint() if not self._args.no_fix: if not self._opts.no_fix: self._fix() if self._args.print: if self._opts.print: self._print() def _setup(self): self._args = self._parser.parse_args() env = os.environ.copy() if self._args.check: env["ANDROID_LINT_CHECK"] = self._args.check if self._args.lint_module: env["ANDROID_LINT_CHECK_EXTRA_MODULES"] = self._args.lint_module if self._opts.check: env["ANDROID_LINT_CHECK"] = self._opts.check if self._opts.lint_module: env["ANDROID_LINT_CHECK_EXTRA_MODULES"] = self._opts.lint_module self._kwargs = { "env": env, Loading @@ -131,7 +130,7 @@ class SoongLintFix: with open(f"{ANDROID_PRODUCT_OUT}/module-info.json") as f: module_info = json.load(f) for module_name in self._args.modules: for module_name in self._opts.modules: module = SoongModule(module_name) module.find(module_info) self._modules.append(module) Loading Loading @@ -169,6 +168,20 @@ class SoongLintFix: print(f.read()) class SoongLintFixOptions: """Options for SoongLintFix""" def __init__(self): self.modules = [] self.check = None self.lint_module = None self.no_fix = False self.print = False def parse_args(self, args=None): _setup_parser().parse_args(args, self) def _setup_parser(): parser = argparse.ArgumentParser(description=""" This is a python script that applies lint fixes to the platform: Loading Loading @@ -199,4 +212,6 @@ def _setup_parser(): return parser if __name__ == "__main__": SoongLintFix().run() opts = SoongLintFixOptions() opts.parse_args(sys.argv) SoongLintFix(opts).run()
tools/lint/utils/Android.bp +6 −0 Original line number Diff line number Diff line Loading @@ -43,3 +43,9 @@ java_test_host { "AndroidUtilsLintChecker", ], } python_binary_host { name: "enforce_permission_counter", srcs: ["enforce_permission_counter.py"], libs: ["soong_lint_fix"], }
tools/lint/utils/enforce_permission_counter.py 0 → 100644 +82 −0 Original line number Diff line number Diff line # Copyright (C) 2023 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. import re import soong_lint_fix # Libraries that constitute system_server. # It is non-trivial to keep in sync with services/Android.bp as some # module are post-processed (e.g, services.core). TARGETS = [ "services.core.unboosted", "services.accessibility", "services.appprediction", "services.appwidget", "services.autofill", "services.backup", "services.companion", "services.contentcapture", "services.contentsuggestions", "services.coverage", "services.devicepolicy", "services.midi", "services.musicsearch", "services.net", "services.people", "services.print", "services.profcollect", "services.restrictions", "services.searchui", "services.smartspace", "services.systemcaptions", "services.translation", "services.texttospeech", "services.usage", "services.usb", "services.voiceinteraction", "services.wallpapereffectsgeneration", "services.wifi", ] class EnforcePermissionMigratedCounter: """Wrapper around lint_fix to count the number of AIDL methods annotated.""" def run(self): opts = soong_lint_fix.SoongLintFixOptions() opts.check = "AnnotatedAidlCounter" opts.lint_module = "AndroidUtilsLintChecker" opts.no_fix = True opts.modules = TARGETS self.linter = soong_lint_fix.SoongLintFix(opts) self.linter.run() self.parse_lint_reports() def parse_lint_reports(self): counts = { "unannotated": 0, "enforced": 0, "notRequired": 0 } for module in self.linter._modules: with open(module.lint_report, "r") as f: content = f.read() keys = dict(re.findall(r'(\w+)=(\d+)', content)) for key in keys: counts[key] += int(keys[key]) print(counts) total = sum(counts.values()) annotated_percent = (1 - (counts["unannotated"] / total)) * 100 print("Annotated methods = %.2f%%" % (annotated_percent)) if __name__ == "__main__": EnforcePermissionMigratedCounter().run()