6
6
import shutil
7
7
import subprocess
8
8
import sys
9
- from typing import Dict , List , Optional
9
+ from typing import Dict , List
10
10
11
11
# -----------------------------------------------------------------------------
12
12
# General utilities
@@ -24,23 +24,45 @@ def escapeCmdArg(arg: str) -> str:
24
24
return arg
25
25
26
26
27
- def check_call (cmd : List [str ], env : Optional [Dict [str , str ]], cwd : Optional [str ] = None , verbose : bool = False ):
27
+ def print_cmd (cmd : List [str ], additional_env : Dict [str , str ]) -> None :
28
+ env_str = " " .join ([f"{ key } ={ escapeCmdArg (str (value ))} " for (key , value ) in additional_env .items ()])
29
+ command_str = " " .join ([escapeCmdArg (str (arg )) for arg in cmd ])
30
+ print (f"{ env_str } { command_str } " )
31
+
32
+
33
+ def env_with_additional_env (additional_env : Dict [str , str ]) -> Dict [str , str ]:
34
+ env = dict (os .environ )
35
+ for (key , value ) in additional_env .items ():
36
+ env [key ] = str (value )
37
+ return env
38
+
39
+
40
+ def check_call (cmd : List [str ], additional_env : Dict [str , str ] = {}, verbose : bool = False ) -> None :
41
+ if verbose :
42
+ print_cmd (cmd = cmd , additional_env = additional_env )
43
+
44
+ subprocess .check_call (cmd , env = env_with_additional_env (additional_env ), stderr = subprocess .STDOUT )
45
+
46
+
47
+ def check_output (cmd : List [str ], additional_env : Dict [str , str ] = {}, capture_stderr : bool = True , verbose : bool = False ) -> str :
28
48
if verbose :
29
- print (" " .join ([escapeCmdArg (arg ) for arg in cmd ]))
30
- return subprocess .check_call (cmd , cwd = cwd , env = env , stderr = subprocess .STDOUT )
49
+ print_cmd (cmd = cmd , additional_env = additional_env )
50
+ if capture_stderr :
51
+ stderr = subprocess .STDOUT
52
+ else :
53
+ stderr = subprocess .DEVNULL
54
+ return subprocess .check_output (cmd , env = env_with_additional_env (additional_env ), stderr = stderr , encoding = 'utf-8' )
31
55
32
56
# -----------------------------------------------------------------------------
33
57
# SwiftPM wrappers
34
58
35
59
36
- def swiftpm_bin_path (swift_exec : str , swiftpm_args : List [str ], env : Optional [ Dict [str , str ] ], verbose : bool = False ) -> str :
60
+ def swiftpm_bin_path (swift_exec : str , swiftpm_args : List [str ], additional_env : Dict [str , str ], verbose : bool = False ) -> str :
37
61
"""
38
62
Return the path of the directory that contains the binaries produced by this package.
39
63
"""
40
64
cmd = [swift_exec , 'build' , '--show-bin-path' ] + swiftpm_args
41
- if verbose :
42
- print (" " .join ([escapeCmdArg (arg ) for arg in cmd ]))
43
- return subprocess .check_output (cmd , env = env , universal_newlines = True ).strip ()
65
+ return check_output (cmd , additional_env = additional_env , capture_stderr = False , verbose = verbose ).strip ()
44
66
45
67
# -----------------------------------------------------------------------------
46
68
# Build indexstore-db
@@ -52,10 +74,13 @@ def get_swiftpm_options(args: argparse.Namespace) -> List[str]:
52
74
"""
53
75
swiftpm_args = [
54
76
'--package-path' , args .package_path ,
55
- '--build -path' , args .build_path ,
77
+ '--scratch -path' , args .build_path ,
56
78
'--configuration' , args .configuration ,
57
79
]
58
80
81
+ if args .multiroot_data_file :
82
+ swiftpm_args += ['--multiroot-data-file' , args .multiroot_data_file ]
83
+
59
84
if args .verbose :
60
85
swiftpm_args += ['--verbose' ]
61
86
@@ -82,9 +107,11 @@ def get_swiftpm_environment_variables(args: argparse.Namespace) -> Dict[str, str
82
107
'swift test' invocation.
83
108
"""
84
109
85
- env = dict (os .environ )
86
- # Set the toolchain used in tests at runtime
87
- env ['INDEXSTOREDB_TOOLCHAIN_BIN_PATH' ] = args .toolchain
110
+ env = {
111
+ # Set the toolchain used in tests at runtime
112
+ 'INDEXSTOREDB_TOOLCHAIN_BIN_PATH' : args .toolchain ,
113
+ 'SWIFTCI_USE_LOCAL_DEPS' : '1' ,
114
+ }
88
115
89
116
if args .ninja_bin :
90
117
env ['NINJA_BIN' ] = args .ninja_bin
@@ -106,36 +133,32 @@ def build(swift_exec: str, args: argparse.Namespace) -> None:
106
133
Build one product in the package
107
134
"""
108
135
swiftpm_args = get_swiftpm_options (args )
109
- env = get_swiftpm_environment_variables (args )
110
- cmd = [swift_exec , 'build' ] + swiftpm_args
111
- check_call (cmd , env = env , verbose = args .verbose )
136
+ additional_env = get_swiftpm_environment_variables (args )
137
+ cmd = [swift_exec , 'build' , '--product' , 'IndexStoreDBPackageTests' ] + swiftpm_args
138
+ check_call (cmd , additional_env = additional_env , verbose = args .verbose )
112
139
113
140
114
141
def run_tests (swift_exec : str , args : argparse .Namespace ) -> None :
115
142
"""
116
143
Run all tests in the indexstore-db package
117
144
"""
118
145
swiftpm_args = get_swiftpm_options (args )
119
- env = get_swiftpm_environment_variables (args )
146
+ additional_env = get_swiftpm_environment_variables (args )
120
147
121
- bin_path = swiftpm_bin_path (swift_exec = swift_exec , swiftpm_args = swiftpm_args , env = env , verbose = args .verbose )
148
+ bin_path = swiftpm_bin_path (swift_exec = swift_exec , swiftpm_args = swiftpm_args , additional_env = additional_env , verbose = args .verbose )
122
149
tests = os .path .join (bin_path , 'isdb-tests' )
123
150
print ('Cleaning ' + tests )
124
151
shutil .rmtree (tests , ignore_errors = True )
125
152
126
153
cmd = [swift_exec , 'test' , '--parallel' , '--test-product' , 'IndexStoreDBPackageTests' ] + swiftpm_args
127
- check_call (cmd , env = env , verbose = args .verbose )
154
+ check_call (cmd , additional_env = additional_env , verbose = args .verbose )
128
155
129
156
130
157
def handle_invocation (swift_exec : str , args : argparse .Namespace ) -> None :
131
158
"""
132
159
Depending on the action in 'args', build the package or run tests.
133
160
"""
134
161
if args .action == 'build' :
135
- # Workaround for incremental build bug in swiftpm.
136
- print ('Cleaning ' + args .build_path )
137
- shutil .rmtree (args .build_path , ignore_errors = True )
138
-
139
162
build (swift_exec , args )
140
163
elif args .action == 'test' :
141
164
run_tests (swift_exec , args )
@@ -156,7 +179,8 @@ def add_common_args(parser):
156
179
parser .add_argument ('--sanitize' , action = 'append' , help = 'build using the given sanitizer(s) (address|thread|undefined)' )
157
180
parser .add_argument ('--sanitize-all' , action = 'store_true' , help = 'build using every available sanitizer in sub-directories of build path' )
158
181
parser .add_argument ('--verbose' , '-v' , action = 'store_true' , help = 'enable verbose output' )
159
-
182
+ parser .add_argument ('--multiroot-data-file' , help = 'path to an Xcode workspace to create a unified build of all of Swift\' s SwiftPM projects' )
183
+
160
184
parser = argparse .ArgumentParser (description = 'Build along with the Swift build-script.' )
161
185
162
186
if sys .version_info >= (3 , 7 , 0 ):
0 commit comments