style: apply black via pre-commit run -a
This commit is contained in:
committed by
Henry Schreiner
parent
9cbed6a9be
commit
178aaea6c7
@@ -23,13 +23,16 @@ class DockerContainer:
|
||||
the command is relayed to the remote shell, and the results are streamed
|
||||
back to cibuildwheel.
|
||||
'''
|
||||
|
||||
UTILITY_PYTHON = '/opt/python/cp38-cp38/bin/python'
|
||||
|
||||
process: PopenBytes
|
||||
bash_stdin: IO[bytes]
|
||||
bash_stdout: IO[bytes]
|
||||
|
||||
def __init__(self, docker_image: str, simulate_32_bit: bool = False, cwd: Optional[PathOrStr] = None):
|
||||
def __init__(
|
||||
self, docker_image: str, simulate_32_bit: bool = False, cwd: Optional[PathOrStr] = None
|
||||
):
|
||||
if not docker_image:
|
||||
raise ValueError("Must have a non-empty docker image to run.")
|
||||
|
||||
@@ -44,21 +47,24 @@ class DockerContainer:
|
||||
shell_args = ['linux32', '/bin/bash'] if self.simulate_32_bit else ['/bin/bash']
|
||||
subprocess.run(
|
||||
[
|
||||
'docker', 'create',
|
||||
'docker',
|
||||
'create',
|
||||
'--env=CIBUILDWHEEL',
|
||||
f'--name={self.name}',
|
||||
'--interactive',
|
||||
'--volume=/:/host', # ignored on CircleCI
|
||||
*cwd_args,
|
||||
self.docker_image,
|
||||
*shell_args
|
||||
*shell_args,
|
||||
],
|
||||
check=True,
|
||||
)
|
||||
self.process = subprocess.Popen(
|
||||
[
|
||||
'docker', 'start',
|
||||
'--attach', '--interactive',
|
||||
'docker',
|
||||
'start',
|
||||
'--attach',
|
||||
'--interactive',
|
||||
self.name,
|
||||
],
|
||||
stdin=subprocess.PIPE,
|
||||
@@ -75,10 +81,11 @@ class DockerContainer:
|
||||
return self
|
||||
|
||||
def __exit__(
|
||||
self,
|
||||
exc_type: Optional[Type[BaseException]],
|
||||
exc_val: Optional[BaseException],
|
||||
exc_tb: Optional[TracebackType]) -> None:
|
||||
self,
|
||||
exc_type: Optional[Type[BaseException]],
|
||||
exc_val: Optional[BaseException],
|
||||
exc_tb: Optional[TracebackType],
|
||||
) -> None:
|
||||
|
||||
self.bash_stdin.close()
|
||||
self.process.terminate()
|
||||
@@ -101,12 +108,14 @@ class DockerContainer:
|
||||
f'tar cf - . | docker exec -i {self.name} tar -xC {shell_quote(to_path)} -f -',
|
||||
shell=True,
|
||||
check=True,
|
||||
cwd=from_path)
|
||||
cwd=from_path,
|
||||
)
|
||||
else:
|
||||
subprocess.run(
|
||||
f'cat {shell_quote(from_path)} | docker exec -i {self.name} sh -c "cat > {shell_quote(to_path)}"',
|
||||
shell=True,
|
||||
check=True)
|
||||
check=True,
|
||||
)
|
||||
|
||||
def copy_out(self, from_path: PurePath, to_path: Path) -> None:
|
||||
# note: we assume from_path is a dir
|
||||
@@ -116,30 +125,39 @@ class DockerContainer:
|
||||
f'docker exec -i {self.name} tar -cC {shell_quote(from_path)} -f - . | tar -xf -',
|
||||
shell=True,
|
||||
check=True,
|
||||
cwd=to_path
|
||||
cwd=to_path,
|
||||
)
|
||||
|
||||
def glob(self, path: PurePath, pattern: str) -> List[PurePath]:
|
||||
glob_pattern = os.path.join(str(path), pattern)
|
||||
|
||||
path_strs = json.loads(self.call([
|
||||
self.UTILITY_PYTHON,
|
||||
'-c',
|
||||
f'import sys, json, glob; json.dump(glob.glob({glob_pattern!r}), sys.stdout)'
|
||||
], capture_output=True))
|
||||
path_strs = json.loads(
|
||||
self.call(
|
||||
[
|
||||
self.UTILITY_PYTHON,
|
||||
'-c',
|
||||
f'import sys, json, glob; json.dump(glob.glob({glob_pattern!r}), sys.stdout)',
|
||||
],
|
||||
capture_output=True,
|
||||
)
|
||||
)
|
||||
|
||||
return [PurePath(p) for p in path_strs]
|
||||
|
||||
def call(
|
||||
self,
|
||||
args: Sequence[PathOrStr],
|
||||
env: Optional[Dict[str, str]] = None,
|
||||
capture_output: bool = False,
|
||||
cwd: Optional[PathOrStr] = None) -> str:
|
||||
self,
|
||||
args: Sequence[PathOrStr],
|
||||
env: Optional[Dict[str, str]] = None,
|
||||
capture_output: bool = False,
|
||||
cwd: Optional[PathOrStr] = None,
|
||||
) -> str:
|
||||
|
||||
chdir = f'cd {cwd}' if cwd else ''
|
||||
env_assignments = ' '.join(f'{shlex.quote(k)}={shlex.quote(v)}'
|
||||
for k, v in env.items()) if env is not None else ''
|
||||
env_assignments = (
|
||||
' '.join(f'{shlex.quote(k)}={shlex.quote(v)}' for k, v in env.items())
|
||||
if env is not None
|
||||
else ''
|
||||
)
|
||||
command = ' '.join(shlex.quote(str(a)) for a in args)
|
||||
end_of_message = str(uuid.uuid4())
|
||||
|
||||
@@ -153,12 +171,18 @@ class DockerContainer:
|
||||
# Finally, the remote shell is told to write a footer - this will show
|
||||
# up in the output so we know when to stop reading, and will include
|
||||
# the returncode of `command`.
|
||||
self.bash_stdin.write(bytes(f'''(
|
||||
self.bash_stdin.write(
|
||||
bytes(
|
||||
f'''(
|
||||
{chdir}
|
||||
env {env_assignments} {command}
|
||||
printf "%04d%s\n" $? {end_of_message}
|
||||
)
|
||||
''', encoding='utf8', errors='surrogateescape'))
|
||||
''',
|
||||
encoding='utf8',
|
||||
errors='surrogateescape',
|
||||
)
|
||||
)
|
||||
self.bash_stdin.flush()
|
||||
|
||||
if capture_output:
|
||||
@@ -178,7 +202,7 @@ class DockerContainer:
|
||||
- 4 # 4 returncode decimals
|
||||
)
|
||||
# fmt: on
|
||||
returncode_str = line[footer_offset:footer_offset+4]
|
||||
returncode_str = line[footer_offset : footer_offset + 4]
|
||||
returncode = int(returncode_str)
|
||||
# add the last line to output, without the footer
|
||||
output_io.write(line[0:footer_offset])
|
||||
@@ -197,11 +221,16 @@ class DockerContainer:
|
||||
return output
|
||||
|
||||
def get_environment(self) -> Dict[str, str]:
|
||||
env = json.loads(self.call([
|
||||
self.UTILITY_PYTHON,
|
||||
'-c',
|
||||
'import sys, json, os; json.dump(os.environ.copy(), sys.stdout)'
|
||||
], capture_output=True))
|
||||
env = json.loads(
|
||||
self.call(
|
||||
[
|
||||
self.UTILITY_PYTHON,
|
||||
'-c',
|
||||
'import sys, json, os; json.dump(os.environ.copy(), sys.stdout)',
|
||||
],
|
||||
capture_output=True,
|
||||
)
|
||||
)
|
||||
return cast(Dict[str, str], env)
|
||||
|
||||
def environment_executor(self, command: List[str], environment: Dict[str, str]) -> str:
|
||||
|
||||
Reference in New Issue
Block a user