File: pylint.py

package info (click to toggle)
python-azure 20251014%2Bgit-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 766,472 kB
  • sloc: python: 6,314,744; ansic: 804; javascript: 287; makefile: 198; sh: 198; xml: 109
file content (155 lines) | stat: -rw-r--r-- 5,835 bytes parent folder | download
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
152
153
154
155
import argparse
import os
import sys

from typing import Optional, List
import subprocess
from subprocess import CalledProcessError, check_call

from .Check import Check
from ci_tools.functions import install_into_venv, get_pip_command
from ci_tools.scenario.generation import create_package_and_install
from ci_tools.variables import discover_repo_root, in_ci, set_envvar_defaults
from ci_tools.environment_exclusions import is_check_enabled
from ci_tools.logging import logger, run_logged

REPO_ROOT = discover_repo_root()
PYLINT_VERSION = "3.2.7"
PYGITHUB_VERSION = "1.59.0"


class pylint(Check):
    def __init__(self) -> None:
        super().__init__()

    def register(
        self, subparsers: "argparse._SubParsersAction", parent_parsers: Optional[List[argparse.ArgumentParser]] = None
    ) -> None:
        """Register the pylint check. The pylint check installs pylint and runs pylint against the target package."""
        parents = parent_parsers or []
        p = subparsers.add_parser("pylint", parents=parents, help="Run the pylint check")
        p.set_defaults(func=self.run)

        p.add_argument(
            "--next",
            default=False,
            help="Next version of pylint is being tested.",
            required=False,
        )

    def run(self, args: argparse.Namespace) -> int:
        """Run the pylint check command."""
        logger.info("Running pylint check...")

        set_envvar_defaults()
        targeted = self.get_targeted_directories(args)

        results: List[int] = []

        for parsed in targeted:
            package_dir = parsed.folder
            package_name = parsed.name
            executable, staging_directory = self.get_executable(args.isolate, args.command, sys.executable, package_dir)
            logger.info(f"Processing {package_name} for pylint check")
            pip_cmd = get_pip_command(executable)

            # install dependencies
            self.install_dev_reqs(executable, args, package_dir)
            try:
                install_into_venv(
                    executable,
                    [
                        "azure-pylint-guidelines-checker==0.5.6",
                        "--index-url=https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-python/pypi/simple/",
                    ],
                    package_dir,
                )
            except CalledProcessError as e:
                logger.error(f"Failed to install dependencies: {e}")
                return e.returncode

            create_package_and_install(
                distribution_directory=staging_directory,
                target_setup=package_dir,
                skip_install=False,
                cache_dir=None,
                work_dir=staging_directory,
                force_create=False,
                package_type="sdist",
                pre_download_disabled=False,
                python_executable=executable,
            )

            # install pylint
            try:
                if args.next:
                    # use latest version of pylint
                    install_into_venv(executable, ["pylint", f"PyGithub=={PYGITHUB_VERSION}"], package_dir)
                else:
                    install_into_venv(executable, [f"pylint=={PYLINT_VERSION}"], package_dir)
            except CalledProcessError as e:
                logger.error(f"Failed to install pylint: {e}")
                return e.returncode

            # debug a pip freeze result
            cmd = pip_cmd + ["freeze"]
            freeze_result = subprocess.run(
                cmd, cwd=package_dir, check=False, text=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT
            )
            logger.debug(f"Running pip freeze with {cmd}")
            logger.debug(freeze_result.stdout)

            top_level_module = parsed.namespace.split(".")[0]

            if in_ci():
                if not is_check_enabled(package_dir, "pylint"):
                    logger.info(f"Package {package_name} opts-out of pylint check.")
                    continue

            rcFileLocation = (
                os.path.join(REPO_ROOT, "eng/pylintrc") if args.next else os.path.join(REPO_ROOT, "pylintrc")
            )

            try:
                logger.info(
                    [
                        executable,
                        "-m",
                        "pylint",
                        "--rcfile={}".format(rcFileLocation),
                        "--output-format=parseable",
                        os.path.join(package_dir, top_level_module),
                    ]
                )

                results.append(
                    check_call(
                        [
                            executable,
                            "-m",
                            "pylint",
                            "--rcfile={}".format(rcFileLocation),
                            "--output-format=parseable",
                            os.path.join(package_dir, top_level_module),
                        ]
                    )
                )
            except CalledProcessError as e:
                logger.error(
                    "{} exited with linting error {}. Please see this link for more information https://aka.ms/azsdk/python/pylint-guide".format(
                        package_name, e.returncode
                    )
                )
                if args.next and in_ci():
                    from gh_tools.vnext_issue_creator import create_vnext_issue

                    create_vnext_issue(package_dir, "pylint")

                results.append(e.returncode)

            if args.next and in_ci():
                from gh_tools.vnext_issue_creator import close_vnext_issue

                close_vnext_issue(package_name, "pylint")

        return max(results) if results else 0