@@ -14,8 +14,10 @@ from __future__ import print_function
14
14
import argparse
15
15
import json
16
16
import os
17
+ import re
17
18
import sys
18
19
20
+
19
21
from functools import reduce
20
22
21
23
sys .path .append (os .path .dirname (__file__ ))
@@ -32,7 +34,8 @@ sys.path.append(os.path.join(SCRIPT_DIR, 'swift_build_support'))
32
34
from swift_build_support import shell # noqa (E402)
33
35
34
36
35
- def update_single_repository (repo_path , branch , reset_to_remote , should_clean ):
37
+ def update_single_repository (repo_path , branch , reset_to_remote , should_clean ,
38
+ cross_repos_pr ):
36
39
if not os .path .isdir (repo_path ):
37
40
return
38
41
@@ -43,12 +46,12 @@ def update_single_repository(repo_path, branch, reset_to_remote, should_clean):
43
46
if should_clean :
44
47
shell .call (['git' , 'clean' , '-fdx' ],
45
48
echo = True )
46
- shell .call (['git' , 'submodule' , 'foreach' , '--recursive' , 'git' , 'clean' , '-fdx' ],
47
- echo = True )
48
- shell .call (['git' , 'submodule' , 'foreach' , '--recursive' , 'git' , 'reset' , '--hard' , 'HEAD' ],
49
- echo = True )
49
+ shell .call (['git' , 'submodule' , 'foreach' , '--recursive' , 'git' ,
50
+ 'clean' , '-fdx' ], echo = True )
51
+ shell .call (['git' , 'submodule' , 'foreach' , '--recursive' , 'git' ,
52
+ 'reset' , '--hard' , 'HEAD' ], echo = True )
50
53
status = shell .call (['git' , 'reset' , '--hard' , 'HEAD' ],
51
- echo = True )
54
+ echo = True )
52
55
if status :
53
56
print ("Please, commit your changes." )
54
57
print (status )
@@ -73,17 +76,19 @@ def update_single_repository(repo_path, branch, reset_to_remote, should_clean):
73
76
# Prior to Git 2.6, this is the way to do a "git pull
74
77
# --rebase" that respects rebase.autostash. See
75
78
# http://stackoverflow.com/a/30209750/125349
76
- shell .call (["git" , "rebase" , "FETCH_HEAD" ], echo = True )
79
+ if not cross_repos_pr :
80
+ shell .call (["git" , "rebase" , "FETCH_HEAD" ], echo = True )
77
81
shell .call (["git" , "submodule" , "update" , "--recursive" ],
78
82
echo = True )
79
83
80
84
81
- def update_all_repositories (args , config , scheme_name ):
85
+ def update_all_repositories (args , config , scheme_name , cross_repos_pr ):
82
86
repo_branch = scheme_name
83
87
for repo_name in config ['repos' ].keys ():
84
88
if repo_name in args .skip_repository_list :
85
89
print ("--- Skipping '" + repo_name + "' ---" )
86
90
continue
91
+ repo_path = os .path .join (SWIFT_SOURCE_ROOT , repo_name )
87
92
if scheme_name :
88
93
# This loop is only correct, since we know that each alias set has
89
94
# unique contents. This is checked by verify config. Thus the first
@@ -93,12 +98,22 @@ def update_all_repositories(args, config, scheme_name):
93
98
if scheme_name not in v ['aliases' ]:
94
99
continue
95
100
repo_branch = v ['repos' ][repo_name ]
101
+ remote_repo_id = config ['repos' ][repo_name ]['remote' ]['id' ]
102
+ if remote_repo_id in cross_repos_pr :
103
+ pr_id = cross_repos_pr [remote_repo_id ]
104
+ repo_branch = "ci_pr_{0}" .format (pr_id )
105
+ with shell .pushd (repo_path , dry_run = False , echo = False ):
106
+ shell .capture (["git" , "branch" , "-D" , repo_branch ],
107
+ echo = True , allow_non_zero_exit = True )
108
+ shell .call (["git" , "fetch" , "origin" ,
109
+ "pull/{0}/merge:{1}"
110
+ .format (pr_id , repo_branch )], echo = True )
96
111
break
97
-
98
- update_single_repository (os .path .join (SWIFT_SOURCE_ROOT , repo_name ),
112
+ update_single_repository (repo_path ,
99
113
repo_branch ,
100
114
args .reset_to_remote ,
101
- args .clean )
115
+ args .clean ,
116
+ cross_repos_pr )
102
117
103
118
104
119
def obtain_additional_swift_sources (
@@ -217,17 +232,30 @@ By default, updates your checkouts of Swift, SourceKit, LLDB, and SwiftPM.""")
217
232
"--config" ,
218
233
default = os .path .join (SCRIPT_DIR , "update-checkout-config.json" ),
219
234
help = "Configuration file to use" )
235
+ parser .add_argument (
236
+ "--github-comment" ,
237
+ help = """Check out related pull requests referenced in the given
238
+ free-form GitHub-style comment.""" ,
239
+ metavar = 'GITHUB-COMMENT' ,
240
+ dest = 'github_comment' )
220
241
args = parser .parse_args ()
221
242
222
243
clone = args .clone
223
244
clone_with_ssh = args .clone_with_ssh
224
245
skip_history = args .skip_history
225
246
scheme = args .scheme
247
+ github_comment = args .github_comment
226
248
227
249
with open (args .config ) as f :
228
250
config = json .load (f )
229
251
validate_config (config )
230
252
253
+ cross_repos_pr = {}
254
+ if github_comment :
255
+ repos_with_pr = re .findall (r'apple/[-a-zA-Z0-9_]+#\d+' , github_comment )
256
+ print ("Found related pull requests:" , str (repos_with_pr ))
257
+ cross_repos_pr = dict (pr .split ('#' ) for pr in repos_with_pr )
258
+
231
259
if clone or clone_with_ssh :
232
260
# If branch is None, default to using the default branch alias
233
261
# specified by our configuration file.
@@ -238,7 +266,7 @@ By default, updates your checkouts of Swift, SourceKit, LLDB, and SwiftPM.""")
238
266
config , clone_with_ssh , scheme , skip_history ,
239
267
args .skip_repository_list )
240
268
241
- update_all_repositories (args , config , scheme )
269
+ update_all_repositories (args , config , scheme , cross_repos_pr )
242
270
243
271
return 0
244
272
0 commit comments