OLD | NEW |
---|---|
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright 2014 The Chromium Authors. All rights reserved. | 2 # Copyright 2014 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 # TODO(hinoka): Use logging. | |
7 | |
6 import codecs | 8 import codecs |
7 import copy | 9 import copy |
8 import cStringIO | 10 import cStringIO |
9 import ctypes | 11 import ctypes |
10 import json | 12 import json |
11 import optparse | 13 import optparse |
12 import os | 14 import os |
13 import pprint | 15 import pprint |
14 import re | 16 import re |
15 import shutil | 17 import shutil |
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
499 finally: | 501 finally: |
500 os.remove(gclient_output_file) | 502 os.remove(gclient_output_file) |
501 | 503 |
502 | 504 |
503 def gclient_runhooks(gyp_envs): | 505 def gclient_runhooks(gyp_envs): |
504 gclient_bin = 'gclient.bat' if sys.platform.startswith('win') else 'gclient' | 506 gclient_bin = 'gclient.bat' if sys.platform.startswith('win') else 'gclient' |
505 env = dict([env_var.split('=', 1) for env_var in gyp_envs]) | 507 env = dict([env_var.split('=', 1) for env_var in gyp_envs]) |
506 call(gclient_bin, 'runhooks', env=env) | 508 call(gclient_bin, 'runhooks', env=env) |
507 | 509 |
508 | 510 |
509 def create_less_than_or_equal_regex(number): | |
510 """ Return a regular expression to test whether an integer less than or equal | |
511 to 'number' is present in a given string. | |
512 """ | |
513 | |
514 # In three parts, build a regular expression that match any numbers smaller | |
515 # than 'number'. | |
516 # For example, 78656 would give a regular expression that looks like: | |
517 # Part 1 | |
518 # (78356| # 78356 | |
519 # Part 2 | |
520 # 7835[0-5]| # 78350-78355 | |
521 # 783[0-4][0-9]| # 78300-78349 | |
522 # 78[0-2][0-9]{2}| # 78000-78299 | |
523 # 7[0-7][0-9]{3}| # 70000-77999 | |
524 # [0-6][0-9]{4}| # 10000-69999 | |
525 # Part 3 | |
526 # [0-9]{1,4} # 0-9999 | |
527 | |
528 # Part 1: Create an array with all the regexes, as described above. | |
529 # Prepopulate it with the number itself. | |
530 number = str(number) | |
531 expressions = [number] | |
532 | |
533 # Convert the number to a list, so we can translate digits in it to | |
534 # expressions. | |
535 num_list = list(number) | |
536 num_len = len(num_list) | |
537 | |
538 # Part 2: Go through all the digits in the number, starting from the end. | |
539 # Each iteration appends a line to 'expressions'. | |
540 for index in range (num_len - 1, -1, -1): | |
541 # Convert this digit back to an integer. | |
542 digit = int(num_list[index]) | |
543 | |
544 # Part 2.1: No processing if this digit is a zero. | |
545 if digit == 0: | |
546 continue | |
547 | |
548 # Part 2.2: We switch the current digit X by a range "[0-(X-1)]". | |
549 if digit == 1: | |
550 num_list[index] = '0' | |
551 else: | |
552 num_list[index] = '[0-%d]' % (digit - 1) | |
553 | |
554 # Part 2.3: We set all following digits to be "[0-9]". | |
555 # Since we just decrementented a digit in a most important position, all | |
556 # following digits don't matter. The possible numbers will always be smaller | |
557 # than before we decremented. | |
558 if (index + 1) < num_len: | |
559 if (num_len - (index + 1)) == 1: | |
560 num_list[index + 1] = '[0-9]' | |
561 else: | |
562 num_list[index + 1] = '[0-9]{%s}' % (num_len - (index + 1)) | |
563 | |
564 # Part 2.4: Add this new sub-expression to the list. | |
565 expressions.append(''.join(num_list[:min(index+2, num_len)])) | |
566 | |
567 # Part 3: We add all the full ranges to match all numbers that are at least | |
568 # one order of magnitude smaller than the original numbers. | |
569 if num_len == 2: | |
570 expressions.append('[0-9]') | |
571 elif num_len > 2: | |
572 expressions.append('[0-9]{1,%s}' % (num_len - 1)) | |
573 | |
574 # All done. We now have our final regular expression. | |
575 regex = '(%s)' % ('|'.join(expressions)) | |
576 return regex | |
577 | |
578 | |
579 def get_svn_rev(git_hash, dir_name): | 511 def get_svn_rev(git_hash, dir_name): |
580 pattern = r'^\s*git-svn-id: [^ ]*@(\d+) ' | 512 pattern = r'^\s*git-svn-id: [^ ]*@(\d+) ' |
581 lkcr_pattern = r'^\s*LK[CG]R w/ DEPS up to revision (\d+)' | |
582 log = git('log', '-1', git_hash, cwd=dir_name) | 513 log = git('log', '-1', git_hash, cwd=dir_name) |
583 match = re.search(pattern, log, re.M) | 514 match = re.search(pattern, log, re.M) |
584 if not match: | 515 if not match: |
585 # This might be a patched checkout, try the parent commit. | 516 return None |
586 log = git('log', '-1', '%s^' % git_hash, cwd=dir_name) | |
587 match = re.search(pattern, log, re.M) | |
588 if not match: | |
589 # Might be patched on top of LKCR, which has a special message. | |
590 match = re.search(lkcr_pattern, log, re.M) | |
591 if not match: | |
592 return None | |
593 return int(match.group(1)) | 517 return int(match.group(1)) |
594 | 518 |
595 | 519 |
596 def get_git_hash(revision, dir_name): | 520 def get_git_hash(revision, sln_dir): |
597 match = "^git-svn-id: [^ ]*@%s " % create_less_than_or_equal_regex(revision) | 521 """We want to search for the SVN revision on the git-svn branch. |
598 cmd = ['log', '-E', '--grep', match, '--format=%H', '--max-count=1'] | 522 |
599 results = git(*cmd, cwd=dir_name).strip().splitlines() | 523 Note that git will search backwards from origin/master. |
600 if results: | 524 """ |
601 return results[0] | 525 match = "^git-svn-id: [^ ]*@%s " % revision |
602 raise Exception('We can\'t resolve svn revision %s into a git hash' % | 526 cmd = ['log', '-E', '--grep', match, '--format=%H', '--max-count=1', |
603 revision) | 527 'origin/master'] |
528 result = git(*cmd, cwd=sln_dir).strip() | |
529 if result: | |
530 return result | |
531 raise SVNRevisionNotFound('We can\'t resolve svn r%s into a git hash in %s' % | |
532 (revision, sln_dir)) | |
604 | 533 |
605 | 534 |
606 def get_revision_mapping(root, addl_rev_map): | 535 def get_revision_mapping(root, addl_rev_map): |
607 result = {} | 536 result = {} |
608 if root in GOT_REVISION_MAPPINGS: | 537 if root in GOT_REVISION_MAPPINGS: |
609 result.update(GOT_REVISION_MAPPINGS[root]) | 538 result.update(GOT_REVISION_MAPPINGS[root]) |
610 if addl_rev_map: | 539 if addl_rev_map: |
611 result.update(json.loads(addl_rev_map)) | 540 result.update(json.loads(addl_rev_map)) |
612 return result | 541 return result |
613 | 542 |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
743 raise ctypes.WinError() | 672 raise ctypes.WinError() |
744 return (total.value, free.value) | 673 return (total.value, free.value) |
745 | 674 |
746 else: | 675 else: |
747 st = os.statvfs(cwd) | 676 st = os.statvfs(cwd) |
748 free = st.f_bavail * st.f_frsize | 677 free = st.f_bavail * st.f_frsize |
749 total = st.f_blocks * st.f_frsize | 678 total = st.f_blocks * st.f_frsize |
750 return (total, free) | 679 return (total, free) |
751 | 680 |
752 | 681 |
753 def git_checkout(solutions, revision, shallow): | 682 def get_revision(folder_name, git_url, revisions): |
683 normalized_name = folder_name.strip('/') | |
684 if normalized_name in revisions: | |
685 return revisions[normalized_name] | |
686 if git_url in revisions: | |
687 return revisions[git_url] | |
688 return None | |
689 | |
690 | |
691 def force_revision(folder_name, revision): | |
692 if revision and revision.lower() != 'head': | |
iannucci
2014/05/10 01:07:18
nit, I would upper() since 'HEAD' is more greppabl
Ryan Tseng
2014/05/10 01:11:36
Done.
| |
693 if revision and revision.isdigit() and len(revision) < 40: | |
694 # rev_num is really a svn revision number, convert it into a git hash. | |
695 git_ref = get_git_hash(int(revision), folder_name) | |
696 else: | |
697 # rev_num is actually a git hash or ref, we can just use it. | |
698 git_ref = revision | |
699 git('checkout', git_ref, cwd=folder_name) | |
700 else: | |
701 # Revision is None or 'HEAD', we want ToT. | |
702 git('checkout', 'origin/master', cwd=folder_name) | |
703 | |
704 | |
705 def git_checkout(solutions, revisions, shallow): | |
754 build_dir = os.getcwd() | 706 build_dir = os.getcwd() |
755 # Before we do anything, break all git_cache locks. | 707 # Before we do anything, break all git_cache locks. |
756 if path.isdir(CACHE_DIR): | 708 if path.isdir(CACHE_DIR): |
757 git('cache', 'unlock', '-vv', '--force', '--all', '--cache-dir', CACHE_DIR) | 709 git('cache', 'unlock', '-vv', '--force', '--all', '--cache-dir', CACHE_DIR) |
758 for item in os.listdir(CACHE_DIR): | 710 for item in os.listdir(CACHE_DIR): |
759 filename = os.path.join(CACHE_DIR, item) | 711 filename = os.path.join(CACHE_DIR, item) |
760 if item.endswith('.lock'): | 712 if item.endswith('.lock'): |
761 raise Exception('%s exists after cache unlock' % filename) | 713 raise Exception('%s exists after cache unlock' % filename) |
762 # Revision only applies to the first solution. | |
763 first_solution = True | 714 first_solution = True |
764 for sln in solutions: | 715 for sln in solutions: |
765 # This is so we can loop back and try again if we need to wait for the | 716 # This is so we can loop back and try again if we need to wait for the |
766 # git mirrors to update from SVN. | 717 # git mirrors to update from SVN. |
767 done = False | 718 done = False |
768 tries_left = 60 | 719 tries_left = 60 |
769 while not done: | 720 while not done: |
770 done = True | 721 done = True |
771 name = sln['name'] | 722 name = sln['name'] |
772 url = sln['url'] | 723 url = sln['url'] |
(...skipping 21 matching lines...) Expand all Loading... | |
794 # Lets wipe the checkout and try again. | 745 # Lets wipe the checkout and try again. |
795 chromium_utils.RemoveDirectory(sln_dir) | 746 chromium_utils.RemoveDirectory(sln_dir) |
796 git(*clone_cmd) | 747 git(*clone_cmd) |
797 git('checkout', '--force', 'origin/master', cwd=sln_dir) | 748 git('checkout', '--force', 'origin/master', cwd=sln_dir) |
798 git('reset', '--hard', cwd=sln_dir) | 749 git('reset', '--hard', cwd=sln_dir) |
799 else: | 750 else: |
800 raise | 751 raise |
801 | 752 |
802 git('clean', '-df', cwd=sln_dir) | 753 git('clean', '-df', cwd=sln_dir) |
803 git('fetch', 'origin', cwd=sln_dir) | 754 git('fetch', 'origin', cwd=sln_dir) |
804 # TODO(hinoka): We probably have to make use of revision mapping. | |
805 if first_solution and revision and revision.lower() != 'head': | |
806 if revision and revision.isdigit() and len(revision) < 40: | |
807 # rev_num is really a svn revision number, convert it into a git hash. | |
808 git_ref = get_git_hash(int(revision), name) | |
809 # Lets make sure our checkout has the correct revision number. | |
810 got_revision = get_svn_rev(git_ref, sln_dir) | |
811 if not got_revision or int(got_revision) != int(revision): | |
812 tries_left -= 1 | |
813 if tries_left > 0: | |
814 # If we don't have the correct revision, wait and try again. | |
815 print 'We want revision %s, but got revision %s.' % ( | |
816 revision, got_revision) | |
817 print 'The svn to git replicator is probably falling behind.' | |
818 print 'waiting 5 seconds and trying again...' | |
819 time.sleep(5) | |
820 done = False | |
821 continue | |
822 raise SVNRevisionNotFound | |
823 else: | |
824 # rev_num is actually a git hash or ref, we can just use it. | |
825 git_ref = revision | |
826 git('checkout', git_ref, cwd=sln_dir) | |
827 else: | |
828 git('checkout', 'origin/master', cwd=sln_dir) | |
829 if first_solution: | |
830 git_ref = git('log', '--format=%H', '--max-count=1', | |
831 cwd=sln_dir).strip() | |
832 | 755 |
756 revision = get_revision(name, url, revisions) or 'HEAD' | |
757 try: | |
758 force_revision(sln_dir, revision) | |
759 except SVNRevisionNotFound: | |
760 tries_left -= 1 | |
761 if tries_left > 0: | |
762 # If we don't have the correct revision, wait and try again. | |
763 print 'We can\'t find revision %s.' % revision | |
764 print 'The svn to git replicator is probably falling behind.' | |
765 print 'waiting 5 seconds and trying again...' | |
766 time.sleep(5) | |
767 done = False | |
768 continue | |
769 raise | |
770 | |
771 if first_solution: | |
772 git_ref = git('log', '--format=%H', '--max-count=1', | |
773 cwd=sln_dir).strip() | |
833 first_solution = False | 774 first_solution = False |
834 return git_ref | 775 return git_ref |
835 | 776 |
836 | 777 |
837 def _download(url): | 778 def _download(url): |
838 """Fetch url and return content, with retries for flake.""" | 779 """Fetch url and return content, with retries for flake.""" |
839 for attempt in xrange(RETRIES): | 780 for attempt in xrange(RETRIES): |
840 try: | 781 try: |
841 return urllib2.urlopen(url).read() | 782 return urllib2.urlopen(url).read() |
842 except Exception: | 783 except Exception: |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
901 for dir_name, property_name in got_revision_mapping.iteritems(): | 842 for dir_name, property_name in got_revision_mapping.iteritems(): |
902 if dir_name not in solutions_output: | 843 if dir_name not in solutions_output: |
903 continue | 844 continue |
904 solution_output = solutions_output[dir_name] | 845 solution_output = solutions_output[dir_name] |
905 if solution_output.get('scm') is None: | 846 if solution_output.get('scm') is None: |
906 # This is an ignored DEPS, so the output got_revision should be 'None'. | 847 # This is an ignored DEPS, so the output got_revision should be 'None'. |
907 git_revision = revision = None | 848 git_revision = revision = None |
908 else: | 849 else: |
909 # Since we are using .DEPS.git, everything had better be git. | 850 # Since we are using .DEPS.git, everything had better be git. |
910 assert solution_output.get('scm') == 'git' | 851 assert solution_output.get('scm') == 'git' |
911 git_revision = get_real_git_hash(solution_output['revision'], dir_name) | 852 git_revision = git('rev-parse', 'HEAD', cwd=dir_name).strip() |
912 if use_svn_revs: | 853 if use_svn_revs: |
913 revision = get_svn_rev(git_revision, dir_name) | 854 revision = get_svn_rev(git_revision, dir_name) |
914 if not revision: | 855 if not revision: |
915 revision = git_revision | 856 revision = git_revision |
916 else: | 857 else: |
917 revision = git_revision | 858 revision = git_revision |
918 | 859 |
919 properties[property_name] = revision | 860 properties[property_name] = revision |
920 if revision != git_revision: | 861 if revision != git_revision: |
921 properties['%s_git' % property_name] = git_revision | 862 properties['%s_git' % property_name] = git_revision |
922 | 863 |
923 return properties | 864 return properties |
924 | 865 |
925 | 866 |
926 def emit_json(out_file, did_run, gclient_output=None, **kwargs): | 867 def emit_json(out_file, did_run, gclient_output=None, **kwargs): |
927 """Write run information into a JSON file.""" | 868 """Write run information into a JSON file.""" |
928 output = {} | 869 output = {} |
929 output.update(gclient_output if gclient_output else {}) | 870 output.update(gclient_output if gclient_output else {}) |
930 output.update({'did_run': did_run}) | 871 output.update({'did_run': did_run}) |
931 output.update(kwargs) | 872 output.update(kwargs) |
932 with open(out_file, 'wb') as f: | 873 with open(out_file, 'wb') as f: |
933 f.write(json.dumps(output)) | 874 f.write(json.dumps(output)) |
934 | 875 |
935 | 876 |
936 def ensure_checkout(solutions, revision, first_sln, target_os, target_os_only, | 877 def ensure_deps_revisions(deps_url_mapping, solutions, revisions): |
878 """Ensure correct DEPS revisions, ignores solutions.""" | |
879 for deps_name, deps_data in sorted(deps_url_mapping.items()): | |
880 if deps_name.strip('/') in solutions: | |
881 # This has already been forced to the correct solution by git_checkout(). | |
882 continue | |
883 revision = get_revision(deps_name, deps_data.get('url', None), revisions) | |
884 if not revision: | |
885 continue | |
886 # TODO(hinoka): Catch SVNRevisionNotFound error maybe? | |
887 force_revision(deps_name, revision) | |
888 | |
889 | |
890 def ensure_checkout(solutions, revisions, first_sln, target_os, target_os_only, | |
937 root, issue, patchset, patch_url, rietveld_server, | 891 root, issue, patchset, patch_url, rietveld_server, |
938 revision_mapping, buildspec_name, gyp_env, shallow): | 892 revision_mapping, buildspec_name, gyp_env, shallow): |
939 # Get a checkout of each solution, without DEPS or hooks. | 893 # Get a checkout of each solution, without DEPS or hooks. |
940 # Calling git directly because there is no way to run Gclient without | 894 # Calling git directly because there is no way to run Gclient without |
941 # invoking DEPS. | 895 # invoking DEPS. |
942 print 'Fetching Git checkout' | 896 print 'Fetching Git checkout' |
943 git_ref = git_checkout(solutions, revision, shallow) | 897 git_ref = git_checkout(solutions, revisions, shallow) |
944 | 898 |
945 # If either patch_url or issue is passed in, then we need to apply a patch. | 899 # If either patch_url or issue is passed in, then we need to apply a patch. |
946 if patch_url: | 900 if patch_url: |
947 # patch_url takes precidence since its only passed in on gcl try/git try. | 901 # patch_url takes precidence since its only passed in on gcl try/git try. |
948 apply_issue_svn(root, patch_url) | 902 apply_issue_svn(root, patch_url) |
949 elif issue: | 903 elif issue: |
950 apply_issue_rietveld(issue, patchset, root, rietveld_server, | 904 apply_issue_rietveld(issue, patchset, root, rietveld_server, |
951 revision_mapping, git_ref) | 905 revision_mapping, git_ref) |
952 | 906 |
953 if buildspec_name: | 907 if buildspec_name: |
954 buildspecs2git(root, buildspec_name) | 908 buildspecs2git(root, buildspec_name) |
955 elif first_sln == root: | 909 elif first_sln == root: |
956 # Run deps2git if there is a DEPS commit after the last .DEPS.git commit. | 910 # Run deps2git if there is a DEPS commit after the last .DEPS.git commit. |
957 # We only need to ensure deps2git if the root is not overridden, since | 911 # We only need to ensure deps2git if the root is not overridden, since |
958 # if the root is overridden, it means we are working with a sub repository | 912 # if the root is overridden, it means we are working with a sub repository |
959 # patch, which means its impossible for it to touch DEPS. | 913 # patch, which means its impossible for it to touch DEPS. |
960 ensure_deps2git(root, shallow) | 914 ensure_deps2git(root, shallow) |
961 | 915 |
962 # Ensure our build/ directory is set up with the correct .gclient file. | 916 # Ensure our build/ directory is set up with the correct .gclient file. |
963 gclient_configure(solutions, target_os, target_os_only) | 917 gclient_configure(solutions, target_os, target_os_only) |
964 | 918 |
965 # Let gclient do the DEPS syncing. | 919 # Let gclient do the DEPS syncing. |
966 gclient_output = gclient_sync(buildspec_name) | 920 gclient_output = gclient_sync(buildspec_name) |
967 if buildspec_name: | 921 if buildspec_name: |
968 # Run gclient runhooks if we're on an official builder. | 922 # Run gclient runhooks if we're on an official builder. |
969 # TODO(hinoka): Remove this when the official builders run their own | 923 # TODO(hinoka): Remove this when the official builders run their own |
970 # runhooks step. | 924 # runhooks step. |
971 gclient_runhooks(gyp_env) | 925 gclient_runhooks(gyp_env) |
926 | |
927 # Finally, ensure that all DEPS are pinned to the correct revision. | |
928 dir_names = [sln['name'] for sln in solutions] | |
929 ensure_deps_revisions(gclient_output.get('solutions', {}), | |
930 dir_names, revisions) | |
972 return gclient_output | 931 return gclient_output |
973 | 932 |
974 | 933 |
975 class UploadTelemetryThread(threading.Thread): | 934 class UploadTelemetryThread(threading.Thread): |
976 def __init__(self, prefix, master, builder, slave, kwargs): | 935 def __init__(self, prefix, master, builder, slave, kwargs): |
977 super(UploadTelemetryThread, self).__init__() | 936 super(UploadTelemetryThread, self).__init__() |
978 self.master = master | 937 self.master = master |
979 self.builder = builder | 938 self.builder = builder |
980 self.slave = slave | 939 self.slave = slave |
981 self.prefix = prefix | 940 self.prefix = prefix |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1015 stdin_data=json.dumps(data)) | 974 stdin_data=json.dumps(data)) |
1016 | 975 |
1017 | 976 |
1018 def upload_telemetry(prefix, master, builder, slave, **kwargs): | 977 def upload_telemetry(prefix, master, builder, slave, **kwargs): |
1019 thr = UploadTelemetryThread(prefix, master, builder, slave, kwargs) | 978 thr = UploadTelemetryThread(prefix, master, builder, slave, kwargs) |
1020 thr.daemon = True | 979 thr.daemon = True |
1021 thr.start() | 980 thr.start() |
1022 return thr | 981 return thr |
1023 | 982 |
1024 | 983 |
984 def parse_revisions(revisions, root): | |
985 """Turn a list of revision specs into a nice dictionary. | |
986 | |
987 We will always return a dict with {root: something}. By default if root | |
988 is unspecified, or if revisions is [], then revision will be assigned 'HEAD' | |
989 """ | |
990 results = {root.strip('/'): 'HEAD'} | |
991 for revision in revisions: | |
992 split_revision = revision.split('@') | |
993 if len(split_revision) == 1: | |
994 # This is just a plain revision, set it as the revision for root. | |
995 results[root] = split_revision[0] | |
996 elif len(split_revision) == 2: | |
997 # This is an alt_root@revision argument. | |
998 current_root, current_rev = split_revision | |
999 | |
1000 # We want to normalize svn/git urls into .git urls. | |
1001 parsed_root = urlparse.urlparse(current_root) | |
1002 if parsed_root.scheme == 'svn': | |
1003 if parsed_root.path in RECOGNIZED_PATHS: | |
1004 normalized_root = RECOGNIZED_PATHS[parsed_root.path] | |
1005 else: | |
1006 print 'WARNING: SVN path %s not recognized, ignoring' % current_root | |
1007 continue | |
1008 elif parsed_root.scheme in ['http', 'https']: | |
1009 normalized_root = 'https://%s/%s' % (parsed_root.netloc, | |
1010 parsed_root.path) | |
1011 if not normalized_root.endswith('.git'): | |
1012 normalized_root = '%s.git' % normalized_root | |
1013 elif parsed_root.scheme: | |
1014 print 'WARNING: Unrecognized scheme %s, ignoring' % parsed_root.scheme | |
1015 continue | |
1016 else: | |
1017 # This is probably a local path. | |
1018 normalized_root = current_root.strip('/') | |
1019 | |
1020 results[normalized_root] = current_rev | |
1021 else: | |
1022 print ('WARNING: %r is not recognized as a valid revision specification,' | |
1023 'skipping' % revision) | |
1024 return results | |
1025 | |
1026 | |
1025 def parse_args(): | 1027 def parse_args(): |
1026 parse = optparse.OptionParser() | 1028 parse = optparse.OptionParser() |
1027 | 1029 |
1028 parse.add_option('--issue', help='Issue number to patch from.') | 1030 parse.add_option('--issue', help='Issue number to patch from.') |
1029 parse.add_option('--patchset', | 1031 parse.add_option('--patchset', |
1030 help='Patchset from issue to patch from, if applicable.') | 1032 help='Patchset from issue to patch from, if applicable.') |
1031 parse.add_option('--patch_url', help='Optional URL to SVN patch.') | 1033 parse.add_option('--patch_url', help='Optional URL to SVN patch.') |
1032 parse.add_option('--root', help='Repository root.') | 1034 parse.add_option('--root', help='Repository root.') |
1033 parse.add_option('--rietveld_server', | 1035 parse.add_option('--rietveld_server', |
1034 default='codereview.chromium.org', | 1036 default='codereview.chromium.org', |
1035 help='Rietveld server.') | 1037 help='Rietveld server.') |
1036 parse.add_option('--specs', help='Gcilent spec.') | 1038 parse.add_option('--specs', help='Gcilent spec.') |
1037 parse.add_option('--master', help='Master name.') | 1039 parse.add_option('--master', help='Master name.') |
1038 parse.add_option('-f', '--force', action='store_true', | 1040 parse.add_option('-f', '--force', action='store_true', |
1039 help='Bypass check to see if we want to be run. ' | 1041 help='Bypass check to see if we want to be run. ' |
1040 'Should ONLY be used locally.') | 1042 'Should ONLY be used locally.') |
1041 parse.add_option('--revision_mapping') | 1043 parse.add_option('--revision_mapping') |
1042 parse.add_option('--revision-mapping') # Backwards compatability. | 1044 parse.add_option('--revision-mapping') # Backwards compatability. |
1043 # TODO(hinoka): Support root@revision format. | 1045 parse.add_option('--revision', action='append', default=[], |
1044 parse.add_option('--revision', | |
1045 help='Revision to check out. Can be an SVN revision number, ' | 1046 help='Revision to check out. Can be an SVN revision number, ' |
1046 'git hash, or any form of git ref.') | 1047 'git hash, or any form of git ref. Can prepend ' |
1048 'root@<rev> to specify which repository, where root ' | |
1049 'is either a filesystem path, git https url, or ' | |
1050 'svn url. To specify Tip of Tree, set rev to HEAD.') | |
1047 parse.add_option('--slave_name', default=socket.getfqdn().split('.')[0], | 1051 parse.add_option('--slave_name', default=socket.getfqdn().split('.')[0], |
1048 help='Hostname of the current machine, ' | 1052 help='Hostname of the current machine, ' |
1049 'used for determining whether or not to activate.') | 1053 'used for determining whether or not to activate.') |
1050 parse.add_option('--builder_name', help='Name of the builder, ' | 1054 parse.add_option('--builder_name', help='Name of the builder, ' |
1051 'used for determining whether or not to activate.') | 1055 'used for determining whether or not to activate.') |
1052 parse.add_option('--build_dir', default=os.getcwd()) | 1056 parse.add_option('--build_dir', default=os.getcwd()) |
1053 parse.add_option('--flag_file', default=path.join(os.getcwd(), | 1057 parse.add_option('--flag_file', default=path.join(os.getcwd(), |
1054 'update.flag')) | 1058 'update.flag')) |
1055 parse.add_option('--shallow', action='store_true', | 1059 parse.add_option('--shallow', action='store_true', |
1056 help='Use shallow clones for cache repositories.') | 1060 help='Use shallow clones for cache repositories.') |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1142 print '@@@STEP_TEXT@%s@@@' % step_text | 1146 print '@@@STEP_TEXT@%s@@@' % step_text |
1143 if not options.shallow: | 1147 if not options.shallow: |
1144 options.shallow = total_disk_space < SHALLOW_CLONE_THRESHOLD | 1148 options.shallow = total_disk_space < SHALLOW_CLONE_THRESHOLD |
1145 | 1149 |
1146 # By default, the root should be the name of the first solution, but | 1150 # By default, the root should be the name of the first solution, but |
1147 # also make it overridable. The root is where patches are applied on top of. | 1151 # also make it overridable. The root is where patches are applied on top of. |
1148 options.root = options.root or dir_names[0] | 1152 options.root = options.root or dir_names[0] |
1149 # The first solution is where the primary DEPS file resides. | 1153 # The first solution is where the primary DEPS file resides. |
1150 first_sln = dir_names[0] | 1154 first_sln = dir_names[0] |
1151 | 1155 |
1156 # Split all the revision specifications into a nice dict. | |
1157 print 'Revisions: %s' % options.revision | |
1158 revisions = parse_revisions(options.revision, options.root) | |
1159 # This is meant to be just an alias to the revision of the main solution. | |
1160 root_revision = revisions[options.root] | |
1161 print 'Fetching Git checkout at %s@%s' % (options.root, root_revision) | |
1162 | |
1152 try: | 1163 try: |
1153 checkout_parameters = dict( | 1164 checkout_parameters = dict( |
1154 # First, pass in the base of what we want to check out. | 1165 # First, pass in the base of what we want to check out. |
1155 solutions=git_solutions, | 1166 solutions=git_solutions, |
1156 revision=options.revision, | 1167 revisions=revisions, |
1157 first_sln=first_sln, | 1168 first_sln=first_sln, |
1158 | 1169 |
1159 # Also, target os variables for gclient. | 1170 # Also, target os variables for gclient. |
1160 target_os=specs.get('target_os', []), | 1171 target_os=specs.get('target_os', []), |
1161 target_os_only=specs.get('target_os_only', False), | 1172 target_os_only=specs.get('target_os_only', False), |
1162 | 1173 |
1163 # Then, pass in information about how to patch on top of the checkout. | 1174 # Then, pass in information about how to patch on top of the checkout. |
1164 root=options.root, | 1175 root=options.root, |
1165 issue=options.issue, | 1176 issue=options.issue, |
1166 patchset=options.patchset, | 1177 patchset=options.patchset, |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1212 specs=options.specs) | 1223 specs=options.specs) |
1213 all_threads.append(thr) | 1224 all_threads.append(thr) |
1214 | 1225 |
1215 # Sort of wait for all telemetry threads to finish. | 1226 # Sort of wait for all telemetry threads to finish. |
1216 for thr in all_threads: | 1227 for thr in all_threads: |
1217 thr.join(5) | 1228 thr.join(5) |
1218 | 1229 |
1219 | 1230 |
1220 if __name__ == '__main__': | 1231 if __name__ == '__main__': |
1221 sys.exit(main()) | 1232 sys.exit(main()) |
OLD | NEW |