diff --git a/python/servo/command_base.py b/python/servo/command_base.py index abd193eda49..aef26511546 100644 --- a/python/servo/command_base.py +++ b/python/servo/command_base.py @@ -10,11 +10,10 @@ from __future__ import annotations import contextlib -from enum import Enum -from typing import Any, Dict, List, Optional import functools import gzip import itertools +import json import locale import os import re @@ -24,24 +23,23 @@ import sys import tarfile import urllib import zipfile - from dataclasses import dataclass +from enum import Enum from errno import ENOENT as NO_SUCH_FILE_OR_DIRECTORY from glob import glob from os import path from subprocess import PIPE +from typing import Any, Dict, List, Optional from xml.etree.ElementTree import XML import toml - from mach.decorators import CommandArgument, CommandArgumentGroup from mach.registrar import Registrar -from servo.platform.build_target import BuildTarget, AndroidTarget, OpenHarmonyTarget -from servo.util import download_file, get_default_cache_dir - import servo.platform import servo.util as util +from servo.platform.build_target import AndroidTarget, BuildTarget, OpenHarmonyTarget +from servo.util import download_file, get_default_cache_dir NIGHTLY_REPOSITORY_URL = "https://servo-builds2.s3.amazonaws.com/" ASAN_LEAK_SUPPRESSION_FILE = "support/suppressed_leaks_for_asan.txt" @@ -784,6 +782,7 @@ class CommandBase(object): with_debug_assertions=False, with_frame_pointer=False, use_crown=False, + dump_output=False, target_override: Optional[str] = None, **_kwargs, ): @@ -855,6 +854,28 @@ class CommandBase(object): # but uv venv on Windows only provides a `python`, not `python3`. env["PYTHON3"] = "python" + os.makedirs("./temp", exist_ok=True) + + if dump_output: + try: + output = subprocess.check_output(["cargo", command] + args + cargo_args, env=env) + + output_str = output.decode("utf-8").strip() + json_array = [json.loads(line) for line in output_str.splitlines()] + + with open("./temp/out.json", "w", encoding="utf-8") as file: + json.dump(json_array, file, indent=2) + + return 0 + except subprocess.CalledProcessError as e: + output_str = e.output.decode("utf-8").strip() + json_array = [json.loads(line) for line in output_str.splitlines()] + + with open("./temp/out.json", "w", encoding="utf-8") as file: + json.dump(json_array, file, indent=2) + + return e.returncode + return call(["cargo", command] + args + cargo_args, env=env, verbose=verbose) def android_adb_path(self, env): @@ -927,7 +948,7 @@ class CommandBase(object): if auto: if os.path.getmtime(src_clobber) > os.path.getmtime(target_clobber): - print("Automatically clobbering target directory: {}".format(target_dir)) + prstdoutint("Automatically clobbering target directory: {}".format(target_dir)) try: Registrar.dispatch("clean", context=self.context, verbose=True) diff --git a/python/servo/devenv_commands.py b/python/servo/devenv_commands.py index 2ccba1ee64d..b2c0f80efa1 100644 --- a/python/servo/devenv_commands.py +++ b/python/servo/devenv_commands.py @@ -7,20 +7,20 @@ # option. This file may not be copied, modified, or distributed # except according to those terms. -from os import path, listdir, getcwd - +import json import signal import subprocess import sys import tempfile +from os import getcwd, listdir, path from mach.decorators import ( + Command, CommandArgument, CommandProvider, - Command, ) -from servo.command_base import CommandBase, cd, call +from servo.command_base import CommandBase, call, cd @CommandProvider @@ -108,8 +108,9 @@ class MachCommands(CommandBase): @Command("clippy", description='Run "cargo clippy"', category="devenv") @CommandArgument("params", default=None, nargs="...", help="Command-line arguments to be passed through to clippy") + @CommandArgument("--report", "-r", default=False, action="store_true", help="Put the lint result on the file") @CommandBase.common_command_arguments(build_configuration=True, build_type=False) - def cargo_clippy(self, params, **kwargs): + def cargo_clippy(self, params, report=False, **kwargs): if not params: params = [] @@ -117,6 +118,25 @@ class MachCommands(CommandBase): self.ensure_clobbered() env = self.build_env() env["RUSTC"] = "rustc" + + if "--message-format=json" in params and report: + retcode = self.run_cargo_build_like_command("clippy", params, env=env, dump_output=True, **kwargs) + + with open("temp/out.json", "r", encoding="utf-8") as file: + data = json.load(file) + condition = ["help", "note", "warning", "failure"] + + filtered_data = [ + item + for item in data + if item["reason"] != "compiler-message" + or item["message"]["code"] is not None + or item["message"]["level"] in condition + ] + + with open("temp/clippy.json", "w", encoding="utf-8") as file: + json.dump(filtered_data, file, indent=2) + return retcode return self.run_cargo_build_like_command("clippy", params, env=env, **kwargs) @Command("grep", description="`git grep` for selected directories.", category="devenv")