Skip to content

Commit 76a3900

Browse files
committed
Merge pull request #2836 from ddunbar/eliminate-SwiftBuildSupport-subprocess-functions
[build-script] Eliminate swift build support subprocess functions
2 parents 974fe58 + ad1540f commit 76a3900

File tree

8 files changed

+105
-82
lines changed

8 files changed

+105
-82
lines changed

utils/SwiftBuildSupport.py

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818
import configparser as ConfigParser
1919

2020
import os
21-
import platform
22-
import subprocess
2321
import sys
2422

2523
sys.path.append(os.path.join(os.path.dirname(__file__), 'swift_build_support'))
@@ -70,44 +68,6 @@ def _get_default_source_root():
7068
"SWIFT_BUILD_ROOT", os.path.join(SWIFT_SOURCE_ROOT, "build"))
7169

7270

73-
def check_call(args, print_command=False, verbose=False, disable_sleep=False):
74-
if disable_sleep:
75-
if platform.system() == 'Darwin':
76-
# Don't mutate the caller's copy of the arguments.
77-
args = list(args)
78-
args.insert(0, "caffeinate")
79-
80-
if print_command:
81-
print(os.getcwd() + "$ " + shell.quote_command(args))
82-
sys.stdout.flush()
83-
try:
84-
return subprocess.check_call(args)
85-
except subprocess.CalledProcessError as e:
86-
diagnostics.fatal(
87-
"command terminated with a non-zero exit status " +
88-
str(e.returncode) + ", aborting")
89-
except OSError as e:
90-
diagnostics.fatal(
91-
"could not execute '" + shell.quote_command(args) +
92-
"': " + e.strerror)
93-
94-
95-
def check_output(args, print_command=False, verbose=False):
96-
if print_command:
97-
print(os.getcwd() + "$ " + shell.quote_command(args))
98-
sys.stdout.flush()
99-
try:
100-
return subprocess.check_output(args)
101-
except subprocess.CalledProcessError as e:
102-
diagnostics.fatal(
103-
"command terminated with a non-zero exit status " +
104-
str(e.returncode) + ", aborting")
105-
except OSError as e:
106-
diagnostics.fatal(
107-
"could not execute '" + shell.quote_command(args) +
108-
"': " + e.strerror)
109-
110-
11171
def _load_preset_files_impl(preset_file_names, substitutions={}):
11272
config = ConfigParser.SafeConfigParser(substitutions, allow_no_value=True)
11373
if config.read(preset_file_names) == []:

utils/build-script

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ from SwiftBuildSupport import (
2828
HOME,
2929
SWIFT_BUILD_ROOT,
3030
SWIFT_SOURCE_ROOT,
31-
check_call,
3231
get_all_preset_names,
3332
get_preset_options,
3433
) # noqa (E402 module level import not at top of file)
@@ -51,6 +50,21 @@ from swift_build_support.workspace import Workspace # noqa(E402)
5150
from swift_build_support.workspace import compute_build_subdir # noqa(E402)
5251

5352

53+
def call_without_sleeping(command, dry_run=False):
54+
"""
55+
Execute a command during which system sleep is disabled.
56+
57+
By default, this ignores the state of the `shell.dry_run` flag.
58+
"""
59+
60+
# Disable system sleep, if possible.
61+
if platform.system() == 'Darwin':
62+
# Don't mutate the caller's copy of the arguments.
63+
command = ["caffeinate"] + list(command)
64+
65+
shell.call(command, dry_run=dry_run, print_command=False)
66+
67+
5468
# Main entry point for the preset mode.
5569
def main_preset():
5670
parser = argparse.ArgumentParser(
@@ -124,7 +138,7 @@ def main_preset():
124138
"using preset '" + args.preset + "', which expands to \n\n" +
125139
shell.quote_command(build_script_args) + "\n")
126140

127-
check_call(build_script_args, disable_sleep=True)
141+
call_without_sleeping(build_script_args)
128142

129143
return 0
130144

@@ -1435,8 +1449,7 @@ details of the setups of other systems or automated environments.""")
14351449
if args.dry_run:
14361450
build_script_impl_args += ["--dry-run"]
14371451

1438-
check_call([build_script_impl] + build_script_impl_args,
1439-
disable_sleep=True)
1452+
call_without_sleeping([build_script_impl] + build_script_impl_args)
14401453

14411454
if args.symbols_package:
14421455
print('--- Creating symbols package ---')

utils/profdata_merge/process.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,16 @@
1919
from multiprocessing import Process
2020

2121

22-
# hack to import SwiftBuildSupport and swift_build_support
23-
parent_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..')
24-
sys.path.append(parent_dir)
25-
support_dir = os.path.join(parent_dir, 'swift_build_support')
26-
sys.path.append(support_dir)
22+
# Allow importing swift_build_support.
23+
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..',
24+
'swift_build_support'))
25+
from swift_build_support import shell # noqa (E402)
2726
from swift_build_support.toolchain import host_toolchain # noqa (E402)
28-
from SwiftBuildSupport import check_output, check_call # noqa (E402)
2927

3028
toolchain = host_toolchain()
3129
LLVM_PROFDATA_PATH = toolchain.llvm_profdata
32-
_profdata_help = check_output([LLVM_PROFDATA_PATH, 'merge', '-help'])
30+
_profdata_help = shell.capture([LLVM_PROFDATA_PATH, 'merge', '-help'],
31+
print_command=False)
3332
LLVM_PROFDATA_SUPPORTS_SPARSE = 'sparse' in _profdata_help
3433

3534

@@ -65,7 +64,7 @@ def merge_file_buffer(self):
6564
llvm_cmd.append("-sparse")
6665
llvm_cmd += cleaned_files
6766
self.report(llvm_cmd)
68-
ret = check_call(llvm_cmd)
67+
ret = shell.call(llvm_cmd, print_command=False)
6968
if ret != 0:
7069
self.report("llvm profdata command failed -- Exited with code %d"
7170
% ret, level=logging.ERROR)

utils/recursive-lipo

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@ import filecmp
77
import os
88
import os.path
99
import shutil
10+
import sys
1011

11-
from SwiftBuildSupport import check_call
12+
sys.path.append(os.path.join(os.path.dirname(__file__), 'swift_build_support'))
13+
14+
from swift_build_support import shell # noqa (E402)
1215

1316

1417
def merge_file_lists(src_root_dirs, skip_files, skip_subpaths):
@@ -89,8 +92,8 @@ def merge_lipo_files(src_root_dirs, file_list, copy_verbatim_subpaths,
8992
print("-- Running lipo %s to %s" % (file_paths, dest_path))
9093
else:
9194
print("-- Running lipo %s" % dest_path)
92-
check_call(lipo_cmd + ["-output", dest_path] + file_paths,
93-
print_command=verbose, verbose=verbose)
95+
shell.call(lipo_cmd + ["-output", dest_path] + file_paths,
96+
print_command=verbose)
9497
else:
9598
# Multiple instances are different, and they're not executable.
9699
print(

utils/swift_build_support/swift_build_support/shell.py

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,17 @@ def _print_command(dry_run, command, env=None, prompt="+ "):
5959
file.flush()
6060

6161

62-
def call(command, stderr=None, env=None, dry_run=None):
62+
def call(command, stderr=None, env=None, dry_run=None, print_command=True):
63+
"""
64+
call(command, ...) -> str
65+
66+
Execute the given command.
67+
68+
This function will raise an exception on any command failure.
69+
"""
6370
dry_run = _coerce_dry_run(dry_run)
64-
_print_command(dry_run, command, env=env)
71+
if dry_run or print_command:
72+
_print_command(dry_run, command, env=env)
6573
if dry_run:
6674
return
6775
_env = None
@@ -80,40 +88,74 @@ def call(command, stderr=None, env=None, dry_run=None):
8088
"': " + e.strerror)
8189

8290

91+
def capture(command, stderr=None, env=None, dry_run=None, print_command=True):
92+
"""
93+
capture(command, ...) -> str
94+
95+
Execute the given command and return the standard output.
96+
97+
This function will raise an exception on any command failure.
98+
"""
99+
dry_run = _coerce_dry_run(dry_run)
100+
if dry_run or print_command:
101+
_print_command(dry_run, command, env=env)
102+
if dry_run:
103+
return
104+
_env = None
105+
if env is not None:
106+
_env = dict(os.environ)
107+
_env.update(env)
108+
try:
109+
return subprocess.check_output(command, env=_env, stderr=stderr)
110+
except subprocess.CalledProcessError as e:
111+
diagnostics.fatal(
112+
"command terminated with a non-zero exit status " +
113+
str(e.returncode) + ", aborting")
114+
except OSError as e:
115+
diagnostics.fatal(
116+
"could not execute '" + quote_command(command) +
117+
"': " + e.strerror)
118+
119+
83120
@contextmanager
84-
def pushd(path, dry_run=None):
121+
def pushd(path, dry_run=None, print_command=True):
85122
dry_run = _coerce_dry_run(dry_run)
86123
old_dir = os.getcwd()
87-
_print_command(dry_run, ["pushd", path])
124+
if dry_run or print_command:
125+
_print_command(dry_run, ["pushd", path])
88126
if not dry_run:
89127
os.chdir(path)
90128
yield
91-
_print_command(dry_run, ["popd"])
129+
if dry_run or print_command:
130+
_print_command(dry_run, ["popd"])
92131
if not dry_run:
93132
os.chdir(old_dir)
94133

95134

96-
def makedirs(path, dry_run=None):
135+
def makedirs(path, dry_run=None, print_command=True):
97136
dry_run = _coerce_dry_run(dry_run)
98-
_print_command(dry_run, ['mkdir', '-p', path])
137+
if dry_run or print_command:
138+
_print_command(dry_run, ['mkdir', '-p', path])
99139
if dry_run:
100140
return
101141
if not os.path.isdir(path):
102142
os.makedirs(path)
103143

104144

105-
def rmtree(path, dry_run=None):
145+
def rmtree(path, dry_run=None, print_command=True):
106146
dry_run = _coerce_dry_run(dry_run)
107-
_print_command(dry_run, ['rm', '-rf', path])
147+
if dry_run or print_command:
148+
_print_command(dry_run, ['rm', '-rf', path])
108149
if dry_run:
109150
return
110151
if os.path.exists(path):
111152
shutil.rmtree(path)
112153

113154

114-
def copytree(src, dest, dry_run=None):
155+
def copytree(src, dest, dry_run=None, print_command=True):
115156
dry_run = _coerce_dry_run(dry_run)
116-
_print_command(dry_run, ['cp', '-r', src, dest])
157+
if dry_run or print_command:
158+
_print_command(dry_run, ['cp', '-r', src, dest])
117159
if dry_run:
118160
return
119161
shutil.copytree(src, dest)

utils/swift_build_support/tests/test_shell.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ def test_call(self):
6363
+ cp {foo_file} {bar_file}
6464
'''.format(foo_file=foo_file, bar_file=bar_file))
6565

66+
def test_capture(self):
67+
self.assertEqual(shell.capture(["echo", "hi"]), "hi\n")
68+
69+
with self.assertRaises(SystemExit):
70+
shell.capture(["false"])
71+
6672
def test_rmtree(self):
6773
shell.dry_run = False
6874
path = os.path.join(self.tmpdir, 'foo', 'bar')

utils/swift_build_support/tests/test_tar.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
import os
1212
import platform
13-
import subprocess
1413
import sys
1514
import tempfile
1615
import unittest

utils/update-checkout

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ sys.path.append(os.path.dirname(__file__))
1919

2020
from SwiftBuildSupport import (
2121
SWIFT_SOURCE_ROOT,
22-
check_call,
23-
check_output,
2422
) # noqa (E402 module level import not at top of file)
2523

2624
sys.path.append(os.path.join(os.path.dirname(__file__), 'swift_build_support'))
@@ -94,21 +92,23 @@ def update_working_copy(repo_path, branch):
9492
return
9593

9694
print("--- Updating '" + repo_path + "' ---")
97-
with shell.pushd(repo_path, dry_run=False):
95+
with shell.pushd(repo_path, dry_run=False, print_command=False):
9896
if branch:
99-
status = check_output(['git', 'status', '--porcelain'])
97+
status = shell.capture(['git', 'status', '--porcelain'],
98+
print_command=False)
10099
if status:
101100
print("Please, commit your changes.")
102101
print(status)
103102
exit(1)
104-
check_call(['git', 'checkout', branch])
103+
shell.call(['git', 'checkout', branch], print_command=False)
105104

106105
# Prior to Git 2.6, this is the way to do a "git pull
107106
# --rebase" that respects rebase.autostash. See
108107
# http://stackoverflow.com/a/30209750/125349
109-
check_call(["git", "fetch"])
110-
check_call(["git", "rebase", "FETCH_HEAD"])
111-
check_call(["git", "submodule", "update", "--recursive"])
108+
shell.call(["git", "fetch"], print_command=False)
109+
shell.call(["git", "rebase", "FETCH_HEAD"], print_command=False)
110+
shell.call(["git", "submodule", "update", "--recursive"],
111+
print_command=False)
112112

113113

114114
def obtain_additional_swift_sources(
@@ -117,19 +117,20 @@ def obtain_additional_swift_sources(
117117
if dir_name in skip_repositories:
118118
print("--- Skipping '" + dir_name + "' ---")
119119
continue
120-
with shell.pushd(SWIFT_SOURCE_ROOT, dry_run=False):
120+
with shell.pushd(SWIFT_SOURCE_ROOT, dry_run=False,
121+
print_command=False):
121122
if not os.path.isdir(os.path.join(dir_name, ".git")):
122123
print("--- Cloning '" + dir_name + "' ---")
123124
if with_ssh is True:
124125
remote = "[email protected]:" + repo + '.git'
125126
else:
126127
remote = "https://github.com/" + repo + '.git'
127128
if skip_history:
128-
check_call(['git', 'clone', '--recursive', '--depth', '1',
129-
remote, dir_name])
129+
shell.call(['git', 'clone', '--recursive', '--depth', '1',
130+
remote, dir_name], print_command=False)
130131
else:
131-
check_call(['git', 'clone', '--recursive', remote,
132-
dir_name])
132+
shell.call(['git', 'clone', '--recursive', remote,
133+
dir_name], print_command=False)
133134
if branch:
134135
if branch == "master" or branch == "stable":
135136
repo_branch = MASTER_BRANCHES[dir_name]
@@ -142,9 +143,9 @@ def obtain_additional_swift_sources(
142143
repo_branch = branch
143144
src_path = SWIFT_SOURCE_ROOT + "/" + dir_name + "/" + \
144145
".git"
145-
check_call(['git', '--git-dir', src_path, '--work-tree',
146+
shell.call(['git', '--git-dir', src_path, '--work-tree',
146147
os.path.join(SWIFT_SOURCE_ROOT, dir_name),
147-
'checkout', repo_branch])
148+
'checkout', repo_branch], print_command=False)
148149

149150

150151
def main():

0 commit comments

Comments
 (0)