mirror of
				https://github.com/pytorch/pytorch.git
				synced 2025-11-04 08:00:58 +08:00 
			
		
		
		
	Demo Run https://github.com/pytorch/pytorch/actions/runs/17259533323?pr=161565 <img width="1538" height="720" alt="image" src="https://github.com/user-attachments/assets/64f6d7b4-cac6-4c12-863c-b15514bb8810" /> Pull Request resolved: https://github.com/pytorch/pytorch/pull/161565 Approved by: https://github.com/huydhn
		
			
				
	
	
		
			140 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			140 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
"""
 | 
						|
General Utility helpers for CLI tasks.
 | 
						|
"""
 | 
						|
 | 
						|
import logging
 | 
						|
import os
 | 
						|
import shlex
 | 
						|
import subprocess
 | 
						|
import sys
 | 
						|
from contextlib import contextmanager
 | 
						|
from pathlib import Path
 | 
						|
from typing import Optional
 | 
						|
 | 
						|
 | 
						|
logger = logging.getLogger(__name__)
 | 
						|
 | 
						|
 | 
						|
def run_command(
 | 
						|
    cmd: str,
 | 
						|
    use_shell: bool = False,
 | 
						|
    log_cmd: bool = True,
 | 
						|
    cwd: Optional[str] = None,
 | 
						|
    env: Optional[dict] = None,
 | 
						|
    check: bool = True,
 | 
						|
) -> int:
 | 
						|
    """Run a command with optional shell execution."""
 | 
						|
    if use_shell:
 | 
						|
        args = cmd
 | 
						|
        log_prefix = "[shell]"
 | 
						|
        executable = "/bin/bash"
 | 
						|
    else:
 | 
						|
        args = shlex.split(cmd)
 | 
						|
        log_prefix = "[cmd]"
 | 
						|
        executable = None
 | 
						|
 | 
						|
    if log_cmd:
 | 
						|
        display_cmd = cmd if use_shell else " ".join(args)
 | 
						|
        logger.info("%s %s", log_prefix, display_cmd)
 | 
						|
 | 
						|
    run_env = {**os.environ, **(env or {})}
 | 
						|
 | 
						|
    proc = subprocess.run(
 | 
						|
        args,
 | 
						|
        shell=use_shell,
 | 
						|
        executable=executable,
 | 
						|
        stdout=sys.stdout,
 | 
						|
        stderr=sys.stderr,
 | 
						|
        cwd=cwd,
 | 
						|
        env=run_env,
 | 
						|
        check=False,
 | 
						|
    )
 | 
						|
 | 
						|
    if check and proc.returncode != 0:
 | 
						|
        logger.error(
 | 
						|
            "%s Command failed (exit %s): %s", log_prefix, proc.returncode, cmd
 | 
						|
        )
 | 
						|
        raise subprocess.CalledProcessError(
 | 
						|
            proc.returncode, args if not use_shell else cmd
 | 
						|
        )
 | 
						|
 | 
						|
    return proc.returncode
 | 
						|
 | 
						|
 | 
						|
def str2bool(value: Optional[str]) -> bool:
 | 
						|
    """Convert environment variables to boolean values."""
 | 
						|
    if not value:
 | 
						|
        return False
 | 
						|
    if not isinstance(value, str):
 | 
						|
        raise ValueError(
 | 
						|
            f"Expected a string value for boolean conversion, got {type(value)}"
 | 
						|
        )
 | 
						|
    value = value.strip().lower()
 | 
						|
 | 
						|
    true_value_set = {"1", "true", "t", "yes", "y", "on", "enable", "enabled", "found"}
 | 
						|
    false_value_set = {"0", "false", "f", "no", "n", "off", "disable"}
 | 
						|
 | 
						|
    if value in true_value_set:
 | 
						|
        return True
 | 
						|
    if value in false_value_set:
 | 
						|
        return False
 | 
						|
    raise ValueError(f"Invalid string value for boolean conversion: {value}")
 | 
						|
 | 
						|
 | 
						|
@contextmanager
 | 
						|
def temp_environ(updates: dict[str, str]):
 | 
						|
    """
 | 
						|
    Temporarily set environment variables and restore them after the block.
 | 
						|
    Args:
 | 
						|
        updates: Dict of environment variables to set.
 | 
						|
    """
 | 
						|
    missing = object()
 | 
						|
    old: dict[str, str | object] = {k: os.environ.get(k, missing) for k in updates}
 | 
						|
    try:
 | 
						|
        os.environ.update(updates)
 | 
						|
        yield
 | 
						|
    finally:
 | 
						|
        for k, v in old.items():
 | 
						|
            if v is missing:
 | 
						|
                os.environ.pop(k, None)
 | 
						|
            else:
 | 
						|
                os.environ[k] = v  # type: ignore[arg-type]
 | 
						|
 | 
						|
 | 
						|
@contextmanager
 | 
						|
def working_directory(path: str):
 | 
						|
    """
 | 
						|
    Temporarily change the working directory inside a context.
 | 
						|
    """
 | 
						|
    if not path:
 | 
						|
        # No-op context
 | 
						|
        yield
 | 
						|
        return
 | 
						|
    prev_cwd = os.getcwd()
 | 
						|
    try:
 | 
						|
        os.chdir(path)
 | 
						|
        yield
 | 
						|
    finally:
 | 
						|
        os.chdir(prev_cwd)
 | 
						|
 | 
						|
 | 
						|
def get_wheels(
 | 
						|
    output_dir: Path,
 | 
						|
    max_depth: Optional[int] = None,
 | 
						|
) -> list[str]:
 | 
						|
    """Return a list of wheels found in the given output directory."""
 | 
						|
    root = Path(output_dir)
 | 
						|
    if not root.exists():
 | 
						|
        return []
 | 
						|
    items = []
 | 
						|
    for dirpath, _, filenames in os.walk(root):
 | 
						|
        depth = Path(dirpath).relative_to(root).parts
 | 
						|
        if max_depth is not None and len(depth) > max_depth:
 | 
						|
            continue
 | 
						|
        for fname in sorted(filenames):
 | 
						|
            if fname.endswith(".whl"):
 | 
						|
                pkg = fname.split("-")[0]
 | 
						|
                relpath = str((Path(dirpath) / fname).relative_to(root))
 | 
						|
                items.append({"pkg": pkg, "relpath": relpath})
 | 
						|
    return items
 |