OLD | NEW |
1 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """SCM-specific utility classes.""" | 5 """SCM-specific utility classes.""" |
6 | 6 |
7 import cStringIO | 7 import cStringIO |
8 import glob | 8 import glob |
9 import logging | 9 import logging |
10 import os | 10 import os |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 subprocess2.check_call( | 79 subprocess2.check_call( |
80 ['git', 'rev-parse', '--show-cdup'], | 80 ['git', 'rev-parse', '--show-cdup'], |
81 stdout=subprocess2.VOID, | 81 stdout=subprocess2.VOID, |
82 stderr=subprocess2.VOID, | 82 stderr=subprocess2.VOID, |
83 cwd=root) | 83 cwd=root) |
84 return 'git' | 84 return 'git' |
85 except (OSError, subprocess2.CalledProcessError): | 85 except (OSError, subprocess2.CalledProcessError): |
86 return None | 86 return None |
87 | 87 |
88 | 88 |
| 89 def only_int(val): |
| 90 if val.isdigit(): |
| 91 return int(val) |
| 92 else: |
| 93 return 0 |
| 94 |
| 95 |
89 class GIT(object): | 96 class GIT(object): |
| 97 current_version = None |
| 98 |
90 @staticmethod | 99 @staticmethod |
91 def Capture(args, **kwargs): | 100 def Capture(args, **kwargs): |
92 return subprocess2.check_output( | 101 return subprocess2.check_output( |
93 ['git'] + args, stderr=subprocess2.PIPE, **kwargs) | 102 ['git'] + args, stderr=subprocess2.PIPE, **kwargs) |
94 | 103 |
95 @staticmethod | 104 @staticmethod |
96 def CaptureStatus(files, upstream_branch=None): | 105 def CaptureStatus(files, upstream_branch=None): |
97 """Returns git status. | 106 """Returns git status. |
98 | 107 |
99 @files can be a string (one file) or a list of files. | 108 @files can be a string (one file) or a list of files. |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 short_sha = GIT.Capture(['rev-parse', '--short=4', 'HEAD'], cwd=cwd).strip() | 372 short_sha = GIT.Capture(['rev-parse', '--short=4', 'HEAD'], cwd=cwd).strip() |
364 return "%s#%s" % (GIT.GetBranch(cwd), short_sha) | 373 return "%s#%s" % (GIT.GetBranch(cwd), short_sha) |
365 | 374 |
366 @staticmethod | 375 @staticmethod |
367 def GetCheckoutRoot(cwd): | 376 def GetCheckoutRoot(cwd): |
368 """Returns the top level directory of a git checkout as an absolute path. | 377 """Returns the top level directory of a git checkout as an absolute path. |
369 """ | 378 """ |
370 root = GIT.Capture(['rev-parse', '--show-cdup'], cwd=cwd).strip() | 379 root = GIT.Capture(['rev-parse', '--show-cdup'], cwd=cwd).strip() |
371 return os.path.abspath(os.path.join(cwd, root)) | 380 return os.path.abspath(os.path.join(cwd, root)) |
372 | 381 |
373 @staticmethod | 382 @classmethod |
374 def AssertVersion(min_version): | 383 def AssertVersion(cls, min_version): |
375 """Asserts git's version is at least min_version.""" | 384 """Asserts git's version is at least min_version.""" |
376 def only_int(val): | 385 if cls.current_version is None: |
377 if val.isdigit(): | 386 cls.current_version = cls.Capture(['--version']).split()[-1] |
378 return int(val) | 387 current_version_list = map(only_int, cls.current_version.split('.')) |
379 else: | |
380 return 0 | |
381 current_version = GIT.Capture(['--version']).split()[-1] | |
382 current_version_list = map(only_int, current_version.split('.')) | |
383 for min_ver in map(int, min_version.split('.')): | 388 for min_ver in map(int, min_version.split('.')): |
384 ver = current_version_list.pop(0) | 389 ver = current_version_list.pop(0) |
385 if ver < min_ver: | 390 if ver < min_ver: |
386 return (False, current_version) | 391 return (False, cls.current_version) |
387 elif ver > min_ver: | 392 elif ver > min_ver: |
388 return (True, current_version) | 393 return (True, cls.current_version) |
389 return (True, current_version) | 394 return (True, cls.current_version) |
390 | 395 |
391 | 396 |
392 class SVN(object): | 397 class SVN(object): |
393 current_version = None | 398 current_version = None |
394 | 399 |
395 @staticmethod | 400 @staticmethod |
396 def Capture(args, **kwargs): | 401 def Capture(args, **kwargs): |
397 """Always redirect stderr. | 402 """Always redirect stderr. |
398 | 403 |
399 Throws an exception if non-0 is returned. | 404 Throws an exception if non-0 is returned. |
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
917 info = SVN.CaptureInfo(parent) | 922 info = SVN.CaptureInfo(parent) |
918 if (info['Repository Root'] != cur_dir_repo_root or | 923 if (info['Repository Root'] != cur_dir_repo_root or |
919 info['URL'] != os.path.dirname(url)): | 924 info['URL'] != os.path.dirname(url)): |
920 break | 925 break |
921 url = info['URL'] | 926 url = info['URL'] |
922 except subprocess2.CalledProcessError: | 927 except subprocess2.CalledProcessError: |
923 break | 928 break |
924 directory = parent | 929 directory = parent |
925 return GetCasedPath(directory) | 930 return GetCasedPath(directory) |
926 | 931 |
927 @staticmethod | 932 @classmethod |
928 def AssertVersion(min_version): | 933 def AssertVersion(cls, min_version): |
929 """Asserts svn's version is at least min_version.""" | 934 """Asserts svn's version is at least min_version.""" |
930 def only_int(val): | 935 if cls.current_version is None: |
931 if val.isdigit(): | 936 cls.current_version = cls.Capture(['--version']).split()[2] |
932 return int(val) | 937 current_version_list = map(only_int, cls.current_version.split('.')) |
933 else: | |
934 return 0 | |
935 if not SVN.current_version: | |
936 SVN.current_version = SVN.Capture(['--version']).split()[2] | |
937 current_version_list = map(only_int, SVN.current_version.split('.')) | |
938 for min_ver in map(int, min_version.split('.')): | 938 for min_ver in map(int, min_version.split('.')): |
939 ver = current_version_list.pop(0) | 939 ver = current_version_list.pop(0) |
940 if ver < min_ver: | 940 if ver < min_ver: |
941 return (False, SVN.current_version) | 941 return (False, cls.current_version) |
942 elif ver > min_ver: | 942 elif ver > min_ver: |
943 return (True, SVN.current_version) | 943 return (True, cls.current_version) |
944 return (True, SVN.current_version) | 944 return (True, cls.current_version) |
945 | 945 |
946 @staticmethod | 946 @staticmethod |
947 def Revert(repo_root, callback=None, ignore_externals=False): | 947 def Revert(repo_root, callback=None, ignore_externals=False): |
948 """Reverts all svn modifications in repo_root, including properties. | 948 """Reverts all svn modifications in repo_root, including properties. |
949 | 949 |
950 Deletes any modified files or directory. | 950 Deletes any modified files or directory. |
951 | 951 |
952 A "svn update --revision BASE" call is required after to revive deleted | 952 A "svn update --revision BASE" call is required after to revive deleted |
953 files. | 953 files. |
954 """ | 954 """ |
(...skipping 29 matching lines...) Expand all Loading... |
984 if (file_status[0][0] in ('D', 'A', '!') or | 984 if (file_status[0][0] in ('D', 'A', '!') or |
985 not file_status[0][1:].isspace()): | 985 not file_status[0][1:].isspace()): |
986 # Added, deleted file requires manual intervention and require calling | 986 # Added, deleted file requires manual intervention and require calling |
987 # revert, like for properties. | 987 # revert, like for properties. |
988 try: | 988 try: |
989 SVN.Capture(['revert', file_status[1]], cwd=repo_root) | 989 SVN.Capture(['revert', file_status[1]], cwd=repo_root) |
990 except subprocess2.CalledProcessError: | 990 except subprocess2.CalledProcessError: |
991 if not os.path.exists(file_path): | 991 if not os.path.exists(file_path): |
992 continue | 992 continue |
993 raise | 993 raise |
OLD | NEW |