Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Android/tools/tools/lint_checks/fix/   (Android Betriebssystem Version 17©)  Datei vom 26.5.2026 mit Größe 9 kB image not shown  

Quelle  soong_lint_fix.py

  Sprache: Python
 

#  Copyright (C) 2022 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 argparse
import json
import functools
import os
import shutil
import subprocess
import sys
import zipfile

ANDROID_BUILD_TOP = os.environ.get("ANDROID_BUILD_TOP")
ANDROID_PRODUCT_OUT = os.environ.get("ANDROID_PRODUCT_OUT")
PRODUCT_OUT = ANDROID_PRODUCT_OUT.removeprefix(f"{ANDROID_BUILD_TOP}/")

SOONG_UI = "build/soong/soong_ui.bash"
PATH_PREFIX = "out/soong/.intermediates"
PATH_SUFFIX = "android_common/lint"
FIX_ZIP = "suggested-fixes.zip"
MODULE_JAVA_DEPS = "out/soong/module_bp_java_deps.json"


class SoongModule:
    """A Soong module to lint.

    The constructor takes the name of the module (for example,
    "framework-minus-apex"). find() must be called to extract the intermediate
    module path using aninja.
    """
    def __init__(self, name):
        self._name = name

    def find(self):
        """Finds the module path using aninja."""
        print(f"Finding module {self._name} with aninja...")
        try:
            cmd = ["aninja""-t""query", f"{self._name}-lint"]
            result = subprocess.run(
                cmd,
                capture_output=True,
                text=True,
                check=True,
                cwd=ANDROID_BUILD_TOP)

            output = result.stdout
            lines = output.splitlines()

            try:
                input_phony_index = next(
                    i for i, line in enumerate(lines)
                    if line.strip() == "input: phony")
            except StopIteration:
                raise Exception(
                    f"Could not find 'input: phony' in aninja output for {self._name}-lint\nOutput:\n{output}"
                )

            if input_phony_index + 1 >= len(lines):
                raise Exception(
                    f"No path found after 'input: phony' for {self._name}-lint")

            path_line = lines[input_phony_index + 1].strip()
            module_path = os.path.dirname(path_line)

            print(f"Found module {self._name} path: {module_path}.")
            self._path = module_path
        except FileNotFoundError:
            raise Exception(
                "`aninja` not found. Make sure you have run `m aninja` and it is in your PATH."
            )
        except subprocess.CalledProcessError as e:
            raise Exception(
                f"aninja failed for module {self._name}-lint:\n{e.stderr}")

    def find_java_deps(self, module_java_deps):
        """Finds the dependencies of a Java module in the loaded module_bp_java_deps.json.

        Returns:
            A list of module names.
        """
        if self._name not in module_java_deps:
            raise Exception(f"Module {self._name} not found!")

        return module_java_deps[self._name]["dependencies"]

    @property
    def name(self):
        return self._name

    @property
    def path(self):
        return self._path

    @property
    def lint_report(self):
        return f"{self._path}/lint-report.txt"

    @property
    def suggested_fixes(self):
        return f"{self._path}/{FIX_ZIP}"


class SoongLintWrapper:
    """
    This class wraps the necessary calls to Soong and/or shell commands to lint
    platform modules and apply suggested fixes if desired.

    It breaks up these operations into a few methods that are available to
    sub-classes (see SoongLintFix for an example).
    """
    def __init__(self, check=None, lint_module=None):
        self._check = check
        self._lint_module = lint_module
        self._kwargs = None

    def _setup(self):
        env = os.environ.copy()
        if self._check:
            env["ANDROID_LINT_CHECK"] = self._check
        if self._lint_module:
            env["ANDROID_LINT_CHECK_EXTRA_MODULES"] = self._lint_module

        self._kwargs = {
            "env": env,
            "executable""/bin/bash",
            "shell"True,
        }

        os.chdir(ANDROID_BUILD_TOP)

    def _find_module(self, module_name):
        """Returns a SoongModule from a module name.

        Ensures that the module is known to Soong.
        """
        module = SoongModule(module_name)
        module.find()
        return module

    def _find_modules(self, module_names):
        modules = []
        for module_name in module_names:
            modules.append(self._find_module(module_name))
        return modules

    @functools.cached_property
    def _module_java_deps(self):
        """Returns the JSON content of module_bp_java_deps.json."""
        print("Refreshing Soong Java deps...")
        subprocess.call(f"{SOONG_UI} --make-mode {MODULE_JAVA_DEPS}", **self._kwargs)
        print("done.")

        with open(f"{MODULE_JAVA_DEPS}"as f:
            return json.load(f)

    def _find_module_java_deps(self, module):
        """Returns a list a dependencies for a module.

        Args:
            module: A SoongModule.

        Returns:
            A list of SoongModule.
        """
        deps = []
        dep_names = module.find_java_deps(self._module_java_deps)
        for dep_name in dep_names:
            dep = SoongModule(dep_name)
            dep.find()
            deps.append(dep)
        return deps

    def _lint(self, modules):
        print("Cleaning up any old lint results...")
        for module in modules:
            try:
                os.remove(f"{module.lint_report}")
                os.remove(f"{module.suggested_fixes}")
            except FileNotFoundError:
                pass
        print("done.")

        target = " ".join([ module.lint_report for module in modules ])
        print(f"Generating {target}")
        subprocess.call(f"{SOONG_UI} --make-mode {target}", **self._kwargs)
        print("done.")

    def _fix(self, modules):
        for module in modules:
            print(f"Copying suggested fixes for {module.name} to the tree...")
            with zipfile.ZipFile(f"{module.suggested_fixes}"as zip:
                for name in zip.namelist():
                    if name.startswith("out"or not name.endswith(".java"):
                        continue
                    with zip.open(name) as src, open(f"{ANDROID_BUILD_TOP}/{name}""wb"as dst:
                        shutil.copyfileobj(src, dst)
            print("done.")

    def _print(self, modules):
        for module in modules:
            print(f"### lint-report.txt {module.name} ###", end="\n\n")
            with open(module.lint_report, "r"as f:
                print(f.read())


class SoongLintFix(SoongLintWrapper):
    """
    Basic usage:
    ```
    from soong_lint_fix import SoongLintFix

    opts = SoongLintFixOptions()
    opts.parse_args()
    SoongLintFix(opts).run()
    ```
    """
    def __init__(self, opts):
        super().__init__(check=opts.check, lint_module=opts.lint_module)
        self._opts = opts

    def run(self):
        self._setup()
        modules = self._find_modules(self._opts.modules)
        self._lint(modules)

        if not self._opts.no_fix:
            self._fix(modules)

        if self._opts.print:
            self._print(modules)


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:
        1. Set up the environment, etc.
        2. Run lint on the specified target.
        3. Copy the modified files, from soong's intermediate directory, back into the tree.

        **Gotcha**: You must have run `source build/envsetup.sh` and `lunch` first.
        """, formatter_class=argparse.RawTextHelpFormatter)

    parser.add_argument('modules',
                        nargs='+',
                        help='The soong build module to run '
                             '(e.g. framework-minus-apex or services.core.unboosted)')

    parser.add_argument('--check',
                        help='Which lint to run. Passed to the ANDROID_LINT_CHECK environment variable.')

    parser.add_argument('--lint-module',
                            help='Specific lint module to run. Passed to the ANDROID_LINT_CHECK_EXTRA_MODULES environment variable.')

    parser.add_argument('--no-fix', action='store_true',
                        help='Just build and run the lint, do NOT apply the fixes.')

    parser.add_argument('--print', action='store_true',
                        help='Print the contents of the generated lint-report.txt at the end.')

    return parser

if __name__ == "__main__":
    opts = SoongLintFixOptions()
    opts.parse_args()
    SoongLintFix(opts).run()

Messung V0.5 in Prozent
C=88 H=88 G=87

¤ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet am  2026-06-27) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.