Repository: servo/servo
File: python/servo/devenv_commands.py (Python)

Code before:
import shlex
from subprocess import CompletedProcess
from typing import Any

from mach.decorators import (
    Command,
    CommandArgument,
    CommandProvider,
)
from tidy.linting_report import GitHubAnnotationManager

from servo.command_base import CommandBase, call


@CommandProvider
class MachCommands(CommandBase):
    @Command(
        "env",
        description="Print or use the build environment. Useful for running custom commands in the build environment",
        category="devenv",
    )
    @CommandArgument(
        "--export",
        default=False,
        action="store_true",
        help="Print (POSIX) shell export statements for variables changed by build_env()",
    )
    @CommandArgument("command", default=None, nargs="...", help="Command to execute in the build environment")
    @CommandBase.common_command_arguments(build_configuration=True, build_type=False)
    def env_command(self, command: list[str] | None, export: bool = False, **_kwargs: Any) -> int:
        # We want to avoid noise on stdout with `--export`.
        if command:
            self.ensure_bootstrapped()
        env = self.build_env()

        if command is not None and export:
            # There is no technical reason for this, it just would be wierd user experience.
            # If you have a usecase for this, feel free to open a PR and remove this check.
            print("--export and command cannot be used together.")
            return 1

        if export:
            for key in sorted(env):
                value = env[key]
                # The build_env command also reads environment variables from the env it copies,
                # so we can't build a "clean" env and need to filter here instead.
                if os.environ.get(key) != value:
                    print(f"export {key}={shlex.quote(value)}")
            return 0

        if command is not None:

Review comment (suggestion):
```suggestion
        help="Print (POSIX) shell export statements for custom environment variables set by mach when building Servo",
```
Better not to expose the internal method names in the help string.

Code after:
import shlex
from subprocess import CompletedProcess
from typing import Any

from mach.decorators import (
    Command,
    CommandArgument,
    CommandProvider,
)
from tidy.linting_report import GitHubAnnotationManager

from servo.command_base import CommandBase, call


@CommandProvider
class MachCommands(CommandBase):
    @Command(
        "print-env",
        description="Print (POSIX) shell export statements for environment variables set by mach when building servo",
        category="devenv",
    )
    @CommandBase.common_command_arguments(build_configuration=True, build_type=False)
    def print_env(self, **_kwargs: Any) -> int:
        env = self.build_env()
        for key in sorted(env):
            value = env[key]
            # The build_env command also reads environment variables from the env it copies,
            # so we can't build a "clean" env and need to filter here instead.
            if os.environ.get(key) != value:
                print(f"export {key}={shlex.quote(value)}")
        return 0

    @Command(
        "exec",
        description="Execute a command in the build environment",
        category="devenv",
    )
    @CommandArgument(
        "command",
        nargs=argparse.REMAINDER,
        help="Command to execute in the build environment. \
            Use `--` to delimit the start of the command, \
            if arguments to the command are falsely interpreted as mach arguments",
    )
    @CommandBase.common_command_arguments(build_configuration=True, build_type=False)
    def exec_command(self, command: list[str], **_kwargs: Any) -> int:
        if not command:
            print("No command provided. Pass a command to execute.")
            return 1

        self.ensure_bootstrapped()