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
|
#!/usr/bin/env python3
##===----------------------------------------------------------------------===##
##
## This source file is part of the Swift open source project
##
## Copyright (c) 2014-2025 Apple Inc. and the Swift project authors
## Licensed under Apache License v2.0 with Runtime Library Exception
##
## See http://swift.org/LICENSE.txt for license information
## See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
##
##===----------------------------------------------------------------------===##
import contextlib
import enum
import errno
import logging
import os
import pathlib
import subprocess
import typing as t
@contextlib.contextmanager
def change_directory(directory: pathlib.Path) -> t.Iterator[pathlib.Path]:
current_directory = pathlib.Path.cwd()
logging.info("Current directory is %s", current_directory)
logging.info("Changing directory to: %s", directory)
os.chdir(directory)
try:
yield directory
finally:
logging.debug("Chaning directory back to %s", current_directory)
os.chdir(current_directory)
class Configuration(str, enum.Enum):
DEBUG = "debug"
RELEASE = "release"
def __str__(self) -> str:
return self.value
def symlink_force(source, destination):
try:
os.symlink(source, destination)
except OSError as e:
if e.errno == errno.EEXIST:
os.remove(destination)
os.symlink(source, destination)
def mkdir_p(path):
"""Create the given directory, if it does not exist."""
try:
os.makedirs(path)
except OSError as e:
# Ignore EEXIST, which may occur during a race condition.
if e.errno != errno.EEXIST:
raise
def call(cmd, cwd=None, verbose=False):
"""Calls a subprocess."""
cwd = cwd or pathlib.Path.cwd()
logging.info("executing command >>> %r with cwd %s", " ".join([str(c) for c in cmd]), cwd)
try:
subprocess.check_call(cmd, cwd=cwd)
except subprocess.CalledProcessError as cpe:
logging.debug("executing command >>> %r with cwd %s", " ".join([str(c) for c in cmd]), cwd)
logging.error(
"\n".join([
"Process failure with return code %d: %s",
"[---- START stdout ----]",
"%s",
"[---- END stdout ----]",
"[---- START stderr ----]",
"%s",
"[---- END stderr ----]",
"[---- START OUTPUT ----]",
"%s",
"[---- END OUTPUT ----]",
]),
cpe.returncode,
str(cpe),
cpe.stdout,
cpe.stderr,
cpe.output,
)
raise cpe
def call_output(cmd, cwd=None, stderr=False, verbose=False):
"""Calls a subprocess for its return data."""
stderr = subprocess.STDOUT if stderr else False
cwd = cwd or pathlib.Path.cwd()
logging.info("executing command >>> %r with cwd %s", " ".join([str(c) for c in cmd]), cwd)
try:
return subprocess.check_output(
cmd,
cwd=cwd,
stderr=stderr,
universal_newlines=True,
).strip()
except subprocess.CalledProcessError as cpe:
logging.debug("executing command >>> %r with cwd %s", " ".join([str(c) for c in cmd]), cwd)
logging.error(
"\n".join([
"Process failure with return code %d: %s",
"[---- START stdout ----]",
"%s",
"[---- END stdout ----]",
"[---- START stderr ----]",
"%s",
"[---- END stderr ----]",
"[---- START OUTPUT ----]",
"%s",
"[---- END OUTPUT ----]",
]),
cpe.returncode,
str(cpe),
cpe.stdout,
cpe.stderr,
cpe.output,
)
raise cpe
|