Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0959d41b authored by Thiébaud Weksteen's avatar Thiébaud Weksteen Committed by Gerrit Code Review
Browse files

Merge changes I08f5aa3e,I7876e44c,I4e90a045 into main

* changes:
  Support multiple modules for lint_fix
  Add utility lint for metrics on @EnforcePermission
  Move AidlImplementationDetector from global to common
parents 9a792ca2 5c149e2d
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -27,3 +27,30 @@ java_library_host {
    libs: ["lint_api"],
    kotlincflags: ["-Xjvm-default=all"],
}

java_defaults {
    name: "AndroidLintCheckerTestDefaults",
    srcs: ["checks/src/test/java/**/*.kt"],
    static_libs: [
        "junit",
        "lint",
        "lint_tests",
    ],
    test_options: {
        unit_test: true,
        tradefed_options: [
            {
                // lint bundles in some classes that were built with older versions
                // of libraries, and no longer load. Since tradefed tries to load
                // all classes in the jar to look for tests, it crashes loading them.
                // Exclude these classes from tradefed's search.
                name: "exclude-paths",
                value: "org/apache",
            },
            {
                name: "exclude-paths",
                value: "META-INF",
            },
        ],
    },
}
+0 −0

File moved.

+0 −0

File moved.

+66 −37
Original line number Diff line number Diff line
@@ -29,6 +29,39 @@ PATH_PREFIX = "out/soong/.intermediates"
PATH_SUFFIX = "android_common/lint"
FIX_ZIP = "suggested-fixes.zip"


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 from Soong's module-info.json
    """
    def __init__(self, name):
        self._name = name

    def find(self, module_info):
        """Finds the module in the loaded module_info.json."""
        if self._name not in module_info:
            raise Exception(f"Module {self._name} not found!")

        partial_path = module_info[self._name]["path"][0]
        print(f"Found module {partial_path}/{self._name}.")
        self._path = f"{PATH_PREFIX}/{partial_path}/{self._name}/{PATH_SUFFIX}"

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

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

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


class SoongLintFix:
    """
    This class creates a command line tool that will
@@ -53,16 +86,14 @@ class SoongLintFix:
        self._parser = _setup_parser()
        self._args = None
        self._kwargs = None
        self._path = None
        self._target = None

        self._modules = []

    def run(self, additional_setup=None, custom_fix=None):
    def run(self):
        """
        Run the script
        """
        self._setup()
        self._find_module()
        self._find_modules()
        self._lint()

        if not self._args.no_fix:
@@ -87,8 +118,6 @@ class SoongLintFix:

        os.chdir(ANDROID_BUILD_TOP)


    def _find_module(self):
        print("Refreshing soong modules...")
        try:
            os.mkdir(ANDROID_PRODUCT_OUT)
@@ -97,36 +126,35 @@ class SoongLintFix:
        subprocess.call(f"{SOONG_UI} --make-mode {PRODUCT_OUT}/module-info.json", **self._kwargs)
        print("done.")


    def _find_modules(self):
        with open(f"{ANDROID_PRODUCT_OUT}/module-info.json") as f:
            module_info = json.load(f)

        if self._args.module not in module_info:
            sys.exit(f"Module {self._args.module} not found!")

        module_path = module_info[self._args.module]["path"][0]
        print(f"Found module {module_path}/{self._args.module}.")

        self._path = f"{PATH_PREFIX}/{module_path}/{self._args.module}/{PATH_SUFFIX}"
        self._target = f"{self._path}/lint-report.txt"

        for module_name in self._args.modules:
            module = SoongModule(module_name)
            module.find(module_info)
            self._modules.append(module)

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

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


    def _fix(self):
        print("Copying suggested fixes to the tree...")
        with zipfile.ZipFile(f"{self._path}/{FIX_ZIP}") as zip:
        for module in self._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
@@ -134,10 +162,10 @@ class SoongLintFix:
                        shutil.copyfileobj(src, dst)
            print("done.")


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


@@ -151,7 +179,8 @@ def _setup_parser():
        **Gotcha**: You must have run `source build/envsetup.sh` and `lunch` first.
        """, formatter_class=argparse.RawTextHelpFormatter)

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

Loading