@@ -182,6 +182,27 @@ def emsdk_path():
182182else :
183183 EMSDK_SET_ENV = os .path .join (emsdk_path (), 'emsdk_set_env.bat' )
184184
185+
186+ # Parses https://github.com/emscripten-core/emscripten/tree/d6aced8 to a pair (https://github.com/emscripten-core/emscripten, d6aced8)
187+ def parse_github_url_and_refspec (url ):
188+ if not url :
189+ return ('' , '' )
190+
191+ if url .endswith (('/tree/' , '/tree' , '/commit/' , '/commit' )):
192+ raise Exception ('Malformed git URL and refspec ' + url + '!' )
193+
194+ if '/tree/' in url :
195+ if url .endswith ('/' ):
196+ raise Exception ('Malformed git URL and refspec ' + url + '!' )
197+ return url .split ('/tree/' )
198+ elif '/commit/' in url :
199+ if url .endswith ('/' ):
200+ raise Exception ('Malformed git URL and refspec ' + url + '!' )
201+ return url .split ('/commit/' )
202+ else :
203+ return (url , 'main' ) # Assume the default branch is main in the absence of a refspec
204+
205+
185206ARCHIVE_SUFFIXES = ('zip' , '.tar' , '.gz' , '.xz' , '.tbz2' , '.bz2' )
186207
187208
@@ -498,11 +519,11 @@ def num_files_in_directory(path):
498519 return len ([name for name in os .listdir (path ) if os .path .exists (os .path .join (path , name ))])
499520
500521
501- def run (cmd , cwd = None ):
522+ def run (cmd , cwd = None , quiet = False ):
502523 debug_print ('run(cmd=' + str (cmd ) + ', cwd=' + str (cwd ) + ')' )
503524 process = subprocess .Popen (cmd , cwd = cwd , env = os .environ .copy ())
504525 process .communicate ()
505- if process .returncode != 0 :
526+ if process .returncode != 0 and not quiet :
506527 errlog (str (cmd ) + ' failed with error code ' + str (process .returncode ) + '!' )
507528 return process .returncode
508529
@@ -792,33 +813,37 @@ def git_clone(url, dstpath):
792813 git_clone_args = []
793814 if GIT_CLONE_SHALLOW :
794815 git_clone_args += ['--depth' , '1' ]
816+ print ('Cloning from ' + url + '...' )
795817 return run ([GIT (), 'clone' ] + git_clone_args + [url , dstpath ]) == 0
796818
797819
798- def git_checkout_and_pull (repo_path , branch ):
799- debug_print ('git_checkout_and_pull(repo_path=' + repo_path + ', branch=' + branch + ')' )
820+ def git_checkout_and_pull (repo_path , branch_or_tag ):
821+ debug_print ('git_checkout_and_pull(repo_path=' + repo_path + ', branch/tag =' + branch_or_tag + ')' )
800822 ret = run ([GIT (), 'fetch' , '--quiet' , 'origin' ], repo_path )
801823 if ret != 0 :
802824 return False
803825 try :
804- print ("Fetching latest changes to the branch '" + branch + "' for '" + repo_path + "'..." )
826+ print ("Fetching latest changes to the branch/tag '" + branch_or_tag + "' for '" + repo_path + "'..." )
805827 ret = run ([GIT (), 'fetch' , '--quiet' , 'origin' ], repo_path )
806828 if ret != 0 :
807829 return False
808- # run([GIT, 'checkout', '-b', branch, '--track', 'origin/'+branch], repo_path)
809830 # this line assumes that the user has not gone and manually messed with the
810831 # repo and added new remotes to ambiguate the checkout.
811- ret = run ([GIT (), 'checkout' , '--quiet' , branch ], repo_path )
832+ ret = run ([GIT (), 'checkout' , '--quiet' , branch_or_tag ], repo_path )
812833 if ret != 0 :
813834 return False
814- # this line assumes that the user has not gone and made local changes to the repo
815- ret = run ([GIT (), 'merge' , '--ff-only' , 'origin/' + branch ], repo_path )
835+ # Test if branch_or_tag is a branch, or if it is a tag that needs to be updated
836+ target_is_tag = run ([GIT (), 'symbolic-ref' , '-q' , 'HEAD' ], repo_path , quiet = True )
837+ if not target_is_tag :
838+ # update branch to latest (not needed for tags)
839+ # this line assumes that the user has not gone and made local changes to the repo
840+ ret = run ([GIT (), 'merge' , '--ff-only' , 'origin/' + branch_or_tag ], repo_path )
816841 if ret != 0 :
817842 return False
818843 except :
819844 errlog ('git operation failed!' )
820845 return False
821- print ("Successfully updated and checked out branch '" + branch + "' on repository '" + repo_path + "'" )
846+ print ("Successfully updated and checked out branch/tag '" + branch_or_tag + "' on repository '" + repo_path + "'" )
822847 print ("Current repository version: " + git_repo_version (repo_path ))
823848 return True
824849
@@ -1684,7 +1709,9 @@ def __init__(self, data):
16841709 setattr (self , key , value )
16851710
16861711 # Cache the name ID of this Tool (these are read very often)
1687- self .name = self .id + '-' + self .version
1712+ self .name = self .id
1713+ if self .version :
1714+ self .name += '-' + self .version
16881715 if hasattr (self , 'bitness' ):
16891716 self .name += '-' + str (self .bitness ) + 'bit'
16901717
@@ -2873,6 +2900,10 @@ def main(args):
28732900 in the environment where the build is invoked.
28742901 See README.md for details.
28752902
2903+ --override-repository: Specifies the git URL to use for a given Tool. E.g.
2904+ --override-repository emscripten-main@https://github.com/<fork>/emscripten/tree/<refspec>
2905+
2906+
28762907 emsdk uninstall <tool/sdk> - Removes the given tool or SDK from disk.''' )
28772908
28782909 if WINDOWS :
@@ -2920,6 +2951,13 @@ def extract_bool_arg(name):
29202951 return True
29212952 return False
29222953
2954+ def extract_string_arg (name ):
2955+ for i in range (len (args )):
2956+ if args [i ] == name :
2957+ value = args [i + 1 ]
2958+ del args [i :i + 2 ]
2959+ return value
2960+
29232961 arg_old = extract_bool_arg ('--old' )
29242962 arg_uses = extract_bool_arg ('--uses' )
29252963 arg_permanent = extract_bool_arg ('--permanent' )
@@ -2949,6 +2987,20 @@ def extract_bool_arg(name):
29492987 load_dot_emscripten ()
29502988 load_sdk_manifest ()
29512989
2990+ # Apply any overrides to git branch names to clone from.
2991+ forked_url = extract_string_arg ('--override-repository' )
2992+ while forked_url :
2993+ tool_name , url_and_refspec = forked_url .split ('@' )
2994+ t = find_tool (tool_name )
2995+ if not t :
2996+ errlog ('Failed to find tool ' + tool_name + '!' )
2997+ return False
2998+ else :
2999+ t .url , t .git_branch = parse_github_url_and_refspec (url_and_refspec )
3000+ debug_print ('Reading git repository URL "' + t .url + '" and git branch "' + t .git_branch + '" for Tool "' + tool_name + '".' )
3001+
3002+ forked_url = extract_string_arg ('--override-repository' )
3003+
29523004 # Process global args
29533005 for i in range (len (args )):
29543006 if args [i ].startswith ('--generator=' ):
0 commit comments