diff options
43 files changed, 148 insertions, 12 deletions
@@ -84,6 +84,7 @@ def _Color(fg=None, bg=None, attr=None): | |||
84 | code = '' | 84 | code = '' |
85 | return code | 85 | return code |
86 | 86 | ||
87 | |||
87 | DEFAULT = None | 88 | DEFAULT = None |
88 | 89 | ||
89 | 90 | ||
@@ -236,6 +236,7 @@ class InteractiveCommand(Command): | |||
236 | """Command which requires user interaction on the tty and | 236 | """Command which requires user interaction on the tty and |
237 | must not run within a pager, even if the user asks to. | 237 | must not run within a pager, even if the user asks to. |
238 | """ | 238 | """ |
239 | |||
239 | def WantPager(self, _opt): | 240 | def WantPager(self, _opt): |
240 | return False | 241 | return False |
241 | 242 | ||
@@ -244,6 +245,7 @@ class PagedCommand(Command): | |||
244 | """Command which defaults to output in a pager, as its | 245 | """Command which defaults to output in a pager, as its |
245 | display tends to be larger than one screen full. | 246 | display tends to be larger than one screen full. |
246 | """ | 247 | """ |
248 | |||
247 | def WantPager(self, _opt): | 249 | def WantPager(self, _opt): |
248 | return True | 250 | return True |
249 | 251 | ||
@@ -24,6 +24,7 @@ import tempfile | |||
24 | from error import EditorError | 24 | from error import EditorError |
25 | import platform_utils | 25 | import platform_utils |
26 | 26 | ||
27 | |||
27 | class Editor(object): | 28 | class Editor(object): |
28 | """Manages the user's preferred text editor.""" | 29 | """Manages the user's preferred text editor.""" |
29 | 30 | ||
@@ -14,21 +14,26 @@ | |||
14 | # See the License for the specific language governing permissions and | 14 | # See the License for the specific language governing permissions and |
15 | # limitations under the License. | 15 | # limitations under the License. |
16 | 16 | ||
17 | |||
17 | class ManifestParseError(Exception): | 18 | class ManifestParseError(Exception): |
18 | """Failed to parse the manifest file. | 19 | """Failed to parse the manifest file. |
19 | """ | 20 | """ |
20 | 21 | ||
22 | |||
21 | class ManifestInvalidRevisionError(Exception): | 23 | class ManifestInvalidRevisionError(Exception): |
22 | """The revision value in a project is incorrect. | 24 | """The revision value in a project is incorrect. |
23 | """ | 25 | """ |
24 | 26 | ||
27 | |||
25 | class ManifestInvalidPathError(Exception): | 28 | class ManifestInvalidPathError(Exception): |
26 | """A path used in <copyfile> or <linkfile> is incorrect. | 29 | """A path used in <copyfile> or <linkfile> is incorrect. |
27 | """ | 30 | """ |
28 | 31 | ||
32 | |||
29 | class NoManifestException(Exception): | 33 | class NoManifestException(Exception): |
30 | """The required manifest does not exist. | 34 | """The required manifest does not exist. |
31 | """ | 35 | """ |
36 | |||
32 | def __init__(self, path, reason): | 37 | def __init__(self, path, reason): |
33 | super(NoManifestException, self).__init__() | 38 | super(NoManifestException, self).__init__() |
34 | self.path = path | 39 | self.path = path |
@@ -37,9 +42,11 @@ class NoManifestException(Exception): | |||
37 | def __str__(self): | 42 | def __str__(self): |
38 | return self.reason | 43 | return self.reason |
39 | 44 | ||
45 | |||
40 | class EditorError(Exception): | 46 | class EditorError(Exception): |
41 | """Unspecified error from the user's text editor. | 47 | """Unspecified error from the user's text editor. |
42 | """ | 48 | """ |
49 | |||
43 | def __init__(self, reason): | 50 | def __init__(self, reason): |
44 | super(EditorError, self).__init__() | 51 | super(EditorError, self).__init__() |
45 | self.reason = reason | 52 | self.reason = reason |
@@ -47,9 +54,11 @@ class EditorError(Exception): | |||
47 | def __str__(self): | 54 | def __str__(self): |
48 | return self.reason | 55 | return self.reason |
49 | 56 | ||
57 | |||
50 | class GitError(Exception): | 58 | class GitError(Exception): |
51 | """Unspecified internal error from git. | 59 | """Unspecified internal error from git. |
52 | """ | 60 | """ |
61 | |||
53 | def __init__(self, command): | 62 | def __init__(self, command): |
54 | super(GitError, self).__init__() | 63 | super(GitError, self).__init__() |
55 | self.command = command | 64 | self.command = command |
@@ -57,9 +66,11 @@ class GitError(Exception): | |||
57 | def __str__(self): | 66 | def __str__(self): |
58 | return self.command | 67 | return self.command |
59 | 68 | ||
69 | |||
60 | class UploadError(Exception): | 70 | class UploadError(Exception): |
61 | """A bundle upload to Gerrit did not succeed. | 71 | """A bundle upload to Gerrit did not succeed. |
62 | """ | 72 | """ |
73 | |||
63 | def __init__(self, reason): | 74 | def __init__(self, reason): |
64 | super(UploadError, self).__init__() | 75 | super(UploadError, self).__init__() |
65 | self.reason = reason | 76 | self.reason = reason |
@@ -67,9 +78,11 @@ class UploadError(Exception): | |||
67 | def __str__(self): | 78 | def __str__(self): |
68 | return self.reason | 79 | return self.reason |
69 | 80 | ||
81 | |||
70 | class DownloadError(Exception): | 82 | class DownloadError(Exception): |
71 | """Cannot download a repository. | 83 | """Cannot download a repository. |
72 | """ | 84 | """ |
85 | |||
73 | def __init__(self, reason): | 86 | def __init__(self, reason): |
74 | super(DownloadError, self).__init__() | 87 | super(DownloadError, self).__init__() |
75 | self.reason = reason | 88 | self.reason = reason |
@@ -77,9 +90,11 @@ class DownloadError(Exception): | |||
77 | def __str__(self): | 90 | def __str__(self): |
78 | return self.reason | 91 | return self.reason |
79 | 92 | ||
93 | |||
80 | class NoSuchProjectError(Exception): | 94 | class NoSuchProjectError(Exception): |
81 | """A specified project does not exist in the work tree. | 95 | """A specified project does not exist in the work tree. |
82 | """ | 96 | """ |
97 | |||
83 | def __init__(self, name=None): | 98 | def __init__(self, name=None): |
84 | super(NoSuchProjectError, self).__init__() | 99 | super(NoSuchProjectError, self).__init__() |
85 | self.name = name | 100 | self.name = name |
@@ -93,6 +108,7 @@ class NoSuchProjectError(Exception): | |||
93 | class InvalidProjectGroupsError(Exception): | 108 | class InvalidProjectGroupsError(Exception): |
94 | """A specified project is not suitable for the specified groups | 109 | """A specified project is not suitable for the specified groups |
95 | """ | 110 | """ |
111 | |||
96 | def __init__(self, name=None): | 112 | def __init__(self, name=None): |
97 | super(InvalidProjectGroupsError, self).__init__() | 113 | super(InvalidProjectGroupsError, self).__init__() |
98 | self.name = name | 114 | self.name = name |
@@ -102,15 +118,18 @@ class InvalidProjectGroupsError(Exception): | |||
102 | return 'in current directory' | 118 | return 'in current directory' |
103 | return self.name | 119 | return self.name |
104 | 120 | ||
121 | |||
105 | class RepoChangedException(Exception): | 122 | class RepoChangedException(Exception): |
106 | """Thrown if 'repo sync' results in repo updating its internal | 123 | """Thrown if 'repo sync' results in repo updating its internal |
107 | repo or manifest repositories. In this special case we must | 124 | repo or manifest repositories. In this special case we must |
108 | use exec to re-execute repo with the new code and manifest. | 125 | use exec to re-execute repo with the new code and manifest. |
109 | """ | 126 | """ |
127 | |||
110 | def __init__(self, extra_args=None): | 128 | def __init__(self, extra_args=None): |
111 | super(RepoChangedException, self).__init__() | 129 | super(RepoChangedException, self).__init__() |
112 | self.extra_args = extra_args or [] | 130 | self.extra_args = extra_args or [] |
113 | 131 | ||
132 | |||
114 | class HookError(Exception): | 133 | class HookError(Exception): |
115 | """Thrown if a 'repo-hook' could not be run. | 134 | """Thrown if a 'repo-hook' could not be run. |
116 | 135 | ||
diff --git a/event_log.py b/event_log.py index 45800a59..5dd9db66 100644 --- a/event_log.py +++ b/event_log.py | |||
@@ -23,6 +23,7 @@ TASK_COMMAND = 'command' | |||
23 | TASK_SYNC_NETWORK = 'sync-network' | 23 | TASK_SYNC_NETWORK = 'sync-network' |
24 | TASK_SYNC_LOCAL = 'sync-local' | 24 | TASK_SYNC_LOCAL = 'sync-local' |
25 | 25 | ||
26 | |||
26 | class EventLog(object): | 27 | class EventLog(object): |
27 | """Event log that records events that occurred during a repo invocation. | 28 | """Event log that records events that occurred during a repo invocation. |
28 | 29 | ||
@@ -165,6 +166,7 @@ class EventLog(object): | |||
165 | # An integer id that is unique across this invocation of the program. | 166 | # An integer id that is unique across this invocation of the program. |
166 | _EVENT_ID = multiprocessing.Value('i', 1) | 167 | _EVENT_ID = multiprocessing.Value('i', 1) |
167 | 168 | ||
169 | |||
168 | def _NextEventId(): | 170 | def _NextEventId(): |
169 | """Helper function for grabbing the next unique id. | 171 | """Helper function for grabbing the next unique id. |
170 | 172 | ||
diff --git a/git_command.py b/git_command.py index df39ec09..c7e94fd0 100644 --- a/git_command.py +++ b/git_command.py | |||
@@ -48,6 +48,7 @@ _ssh_proxy_path = None | |||
48 | _ssh_sock_path = None | 48 | _ssh_sock_path = None |
49 | _ssh_clients = [] | 49 | _ssh_clients = [] |
50 | 50 | ||
51 | |||
51 | def ssh_sock(create=True): | 52 | def ssh_sock(create=True): |
52 | global _ssh_sock_path | 53 | global _ssh_sock_path |
53 | if _ssh_sock_path is None: | 54 | if _ssh_sock_path is None: |
@@ -61,6 +62,7 @@ def ssh_sock(create=True): | |||
61 | 'master-%r@%h:%p') | 62 | 'master-%r@%h:%p') |
62 | return _ssh_sock_path | 63 | return _ssh_sock_path |
63 | 64 | ||
65 | |||
64 | def _ssh_proxy(): | 66 | def _ssh_proxy(): |
65 | global _ssh_proxy_path | 67 | global _ssh_proxy_path |
66 | if _ssh_proxy_path is None: | 68 | if _ssh_proxy_path is None: |
@@ -69,15 +71,18 @@ def _ssh_proxy(): | |||
69 | 'git_ssh') | 71 | 'git_ssh') |
70 | return _ssh_proxy_path | 72 | return _ssh_proxy_path |
71 | 73 | ||
74 | |||
72 | def _add_ssh_client(p): | 75 | def _add_ssh_client(p): |
73 | _ssh_clients.append(p) | 76 | _ssh_clients.append(p) |
74 | 77 | ||
78 | |||
75 | def _remove_ssh_client(p): | 79 | def _remove_ssh_client(p): |
76 | try: | 80 | try: |
77 | _ssh_clients.remove(p) | 81 | _ssh_clients.remove(p) |
78 | except ValueError: | 82 | except ValueError: |
79 | pass | 83 | pass |
80 | 84 | ||
85 | |||
81 | def terminate_ssh_clients(): | 86 | def terminate_ssh_clients(): |
82 | global _ssh_clients | 87 | global _ssh_clients |
83 | for p in _ssh_clients: | 88 | for p in _ssh_clients: |
@@ -88,8 +93,10 @@ def terminate_ssh_clients(): | |||
88 | pass | 93 | pass |
89 | _ssh_clients = [] | 94 | _ssh_clients = [] |
90 | 95 | ||
96 | |||
91 | _git_version = None | 97 | _git_version = None |
92 | 98 | ||
99 | |||
93 | class _GitCall(object): | 100 | class _GitCall(object): |
94 | def version_tuple(self): | 101 | def version_tuple(self): |
95 | global _git_version | 102 | global _git_version |
@@ -102,11 +109,14 @@ class _GitCall(object): | |||
102 | 109 | ||
103 | def __getattr__(self, name): | 110 | def __getattr__(self, name): |
104 | name = name.replace('_', '-') | 111 | name = name.replace('_', '-') |
112 | |||
105 | def fun(*cmdv): | 113 | def fun(*cmdv): |
106 | command = [name] | 114 | command = [name] |
107 | command.extend(cmdv) | 115 | command.extend(cmdv) |
108 | return GitCommand(None, command).Wait() == 0 | 116 | return GitCommand(None, command).Wait() == 0 |
109 | return fun | 117 | return fun |
118 | |||
119 | |||
110 | git = _GitCall() | 120 | git = _GitCall() |
111 | 121 | ||
112 | 122 | ||
@@ -187,8 +197,10 @@ class UserAgent(object): | |||
187 | 197 | ||
188 | return self._git_ua | 198 | return self._git_ua |
189 | 199 | ||
200 | |||
190 | user_agent = UserAgent() | 201 | user_agent = UserAgent() |
191 | 202 | ||
203 | |||
192 | def git_require(min_version, fail=False, msg=''): | 204 | def git_require(min_version, fail=False, msg=''): |
193 | git_version = git.version_tuple() | 205 | git_version = git.version_tuple() |
194 | if min_version <= git_version: | 206 | if min_version <= git_version: |
@@ -201,9 +213,11 @@ def git_require(min_version, fail=False, msg=''): | |||
201 | sys.exit(1) | 213 | sys.exit(1) |
202 | return False | 214 | return False |
203 | 215 | ||
216 | |||
204 | def _setenv(env, name, value): | 217 | def _setenv(env, name, value): |
205 | env[name] = value.encode() | 218 | env[name] = value.encode() |
206 | 219 | ||
220 | |||
207 | class GitCommand(object): | 221 | class GitCommand(object): |
208 | def __init__(self, | 222 | def __init__(self, |
209 | project, | 223 | project, |
diff --git a/git_config.py b/git_config.py index 13fbda24..5fb61d21 100644 --- a/git_config.py +++ b/git_config.py | |||
@@ -59,18 +59,23 @@ ID_RE = re.compile(r'^[0-9a-f]{40}$') | |||
59 | 59 | ||
60 | REVIEW_CACHE = dict() | 60 | REVIEW_CACHE = dict() |
61 | 61 | ||
62 | |||
62 | def IsChange(rev): | 63 | def IsChange(rev): |
63 | return rev.startswith(R_CHANGES) | 64 | return rev.startswith(R_CHANGES) |
64 | 65 | ||
66 | |||
65 | def IsId(rev): | 67 | def IsId(rev): |
66 | return ID_RE.match(rev) | 68 | return ID_RE.match(rev) |
67 | 69 | ||
70 | |||
68 | def IsTag(rev): | 71 | def IsTag(rev): |
69 | return rev.startswith(R_TAGS) | 72 | return rev.startswith(R_TAGS) |
70 | 73 | ||
74 | |||
71 | def IsImmutable(rev): | 75 | def IsImmutable(rev): |
72 | return IsChange(rev) or IsId(rev) or IsTag(rev) | 76 | return IsChange(rev) or IsId(rev) or IsTag(rev) |
73 | 77 | ||
78 | |||
74 | def _key(name): | 79 | def _key(name): |
75 | parts = name.split('.') | 80 | parts = name.split('.') |
76 | if len(parts) < 2: | 81 | if len(parts) < 2: |
@@ -79,6 +84,7 @@ def _key(name): | |||
79 | parts[-1] = parts[-1].lower() | 84 | parts[-1] = parts[-1].lower() |
80 | return '.'.join(parts) | 85 | return '.'.join(parts) |
81 | 86 | ||
87 | |||
82 | class GitConfig(object): | 88 | class GitConfig(object): |
83 | _ForUser = None | 89 | _ForUser = None |
84 | 90 | ||
@@ -392,6 +398,7 @@ _master_keys = set() | |||
392 | _ssh_master = True | 398 | _ssh_master = True |
393 | _master_keys_lock = None | 399 | _master_keys_lock = None |
394 | 400 | ||
401 | |||
395 | def init_ssh(): | 402 | def init_ssh(): |
396 | """Should be called once at the start of repo to init ssh master handling. | 403 | """Should be called once at the start of repo to init ssh master handling. |
397 | 404 | ||
@@ -401,6 +408,7 @@ def init_ssh(): | |||
401 | assert _master_keys_lock is None, "Should only call init_ssh once" | 408 | assert _master_keys_lock is None, "Should only call init_ssh once" |
402 | _master_keys_lock = _threading.Lock() | 409 | _master_keys_lock = _threading.Lock() |
403 | 410 | ||
411 | |||
404 | def _open_ssh(host, port=None): | 412 | def _open_ssh(host, port=None): |
405 | global _ssh_master | 413 | global _ssh_master |
406 | 414 | ||
@@ -479,6 +487,7 @@ def _open_ssh(host, port=None): | |||
479 | finally: | 487 | finally: |
480 | _master_keys_lock.release() | 488 | _master_keys_lock.release() |
481 | 489 | ||
490 | |||
482 | def close_ssh(): | 491 | def close_ssh(): |
483 | global _master_keys_lock | 492 | global _master_keys_lock |
484 | 493 | ||
@@ -503,15 +512,18 @@ def close_ssh(): | |||
503 | # We're done with the lock, so we can delete it. | 512 | # We're done with the lock, so we can delete it. |
504 | _master_keys_lock = None | 513 | _master_keys_lock = None |
505 | 514 | ||
515 | |||
506 | URI_SCP = re.compile(r'^([^@:]*@?[^:/]{1,}):') | 516 | URI_SCP = re.compile(r'^([^@:]*@?[^:/]{1,}):') |
507 | URI_ALL = re.compile(r'^([a-z][a-z+-]*)://([^@/]*@?[^/]*)/') | 517 | URI_ALL = re.compile(r'^([a-z][a-z+-]*)://([^@/]*@?[^/]*)/') |
508 | 518 | ||
519 | |||
509 | def GetSchemeFromUrl(url): | 520 | def GetSchemeFromUrl(url): |
510 | m = URI_ALL.match(url) | 521 | m = URI_ALL.match(url) |
511 | if m: | 522 | if m: |
512 | return m.group(1) | 523 | return m.group(1) |
513 | return None | 524 | return None |
514 | 525 | ||
526 | |||
515 | @contextlib.contextmanager | 527 | @contextlib.contextmanager |
516 | def GetUrlCookieFile(url, quiet): | 528 | def GetUrlCookieFile(url, quiet): |
517 | if url.startswith('persistent-'): | 529 | if url.startswith('persistent-'): |
@@ -552,6 +564,7 @@ def GetUrlCookieFile(url, quiet): | |||
552 | cookiefile = os.path.expanduser(cookiefile) | 564 | cookiefile = os.path.expanduser(cookiefile) |
553 | yield cookiefile, None | 565 | yield cookiefile, None |
554 | 566 | ||
567 | |||
555 | def _preconnect(url): | 568 | def _preconnect(url): |
556 | m = URI_ALL.match(url) | 569 | m = URI_ALL.match(url) |
557 | if m: | 570 | if m: |
@@ -572,9 +585,11 @@ def _preconnect(url): | |||
572 | 585 | ||
573 | return False | 586 | return False |
574 | 587 | ||
588 | |||
575 | class Remote(object): | 589 | class Remote(object): |
576 | """Configuration options related to a remote. | 590 | """Configuration options related to a remote. |
577 | """ | 591 | """ |
592 | |||
578 | def __init__(self, config, name): | 593 | def __init__(self, config, name): |
579 | self._config = config | 594 | self._config = config |
580 | self.name = name | 595 | self.name = name |
@@ -735,6 +750,7 @@ class Remote(object): | |||
735 | class Branch(object): | 750 | class Branch(object): |
736 | """Configuration options related to a single branch. | 751 | """Configuration options related to a single branch. |
737 | """ | 752 | """ |
753 | |||
738 | def __init__(self, config, name): | 754 | def __init__(self, config, name): |
739 | self._config = config | 755 | self._config = config |
740 | self.name = name | 756 | self.name = name |
diff --git a/gitc_utils.py b/gitc_utils.py index 45920b07..11284e20 100644 --- a/gitc_utils.py +++ b/gitc_utils.py | |||
@@ -29,12 +29,15 @@ from error import ManifestParseError | |||
29 | 29 | ||
30 | NUM_BATCH_RETRIEVE_REVISIONID = 32 | 30 | NUM_BATCH_RETRIEVE_REVISIONID = 32 |
31 | 31 | ||
32 | |||
32 | def get_gitc_manifest_dir(): | 33 | def get_gitc_manifest_dir(): |
33 | return wrapper.Wrapper().get_gitc_manifest_dir() | 34 | return wrapper.Wrapper().get_gitc_manifest_dir() |
34 | 35 | ||
36 | |||
35 | def parse_clientdir(gitc_fs_path): | 37 | def parse_clientdir(gitc_fs_path): |
36 | return wrapper.Wrapper().gitc_parse_clientdir(gitc_fs_path) | 38 | return wrapper.Wrapper().gitc_parse_clientdir(gitc_fs_path) |
37 | 39 | ||
40 | |||
38 | def _set_project_revisions(projects): | 41 | def _set_project_revisions(projects): |
39 | """Sets the revisionExpr for a list of projects. | 42 | """Sets the revisionExpr for a list of projects. |
40 | 43 | ||
@@ -63,6 +66,7 @@ def _set_project_revisions(projects): | |||
63 | (proj.remote.url, proj.revisionExpr)) | 66 | (proj.remote.url, proj.revisionExpr)) |
64 | proj.revisionExpr = revisionExpr | 67 | proj.revisionExpr = revisionExpr |
65 | 68 | ||
69 | |||
66 | def _manifest_groups(manifest): | 70 | def _manifest_groups(manifest): |
67 | """Returns the manifest group string that should be synced | 71 | """Returns the manifest group string that should be synced |
68 | 72 | ||
@@ -77,6 +81,7 @@ def _manifest_groups(manifest): | |||
77 | groups = 'default,platform-' + platform.system().lower() | 81 | groups = 'default,platform-' + platform.system().lower() |
78 | return groups | 82 | return groups |
79 | 83 | ||
84 | |||
80 | def generate_gitc_manifest(gitc_manifest, manifest, paths=None): | 85 | def generate_gitc_manifest(gitc_manifest, manifest, paths=None): |
81 | """Generate a manifest for shafsd to use for this GITC client. | 86 | """Generate a manifest for shafsd to use for this GITC client. |
82 | 87 | ||
@@ -140,6 +145,7 @@ def generate_gitc_manifest(gitc_manifest, manifest, paths=None): | |||
140 | # Save the manifest. | 145 | # Save the manifest. |
141 | save_manifest(manifest) | 146 | save_manifest(manifest) |
142 | 147 | ||
148 | |||
143 | def save_manifest(manifest, client_dir=None): | 149 | def save_manifest(manifest, client_dir=None): |
144 | """Save the manifest file in the client_dir. | 150 | """Save the manifest file in the client_dir. |
145 | 151 | ||
@@ -101,6 +101,7 @@ global_options.add_option('--event-log', | |||
101 | dest='event_log', action='store', | 101 | dest='event_log', action='store', |
102 | help='filename of event log to append timeline to') | 102 | help='filename of event log to append timeline to') |
103 | 103 | ||
104 | |||
104 | class _Repo(object): | 105 | class _Repo(object): |
105 | def __init__(self, repodir): | 106 | def __init__(self, repodir): |
106 | self.repodir = repodir | 107 | self.repodir = repodir |
@@ -300,11 +301,13 @@ repo: error: | |||
300 | cp %s %s | 301 | cp %s %s |
301 | """ % (exp_str, WrapperPath(), repo_path), file=sys.stderr) | 302 | """ % (exp_str, WrapperPath(), repo_path), file=sys.stderr) |
302 | 303 | ||
304 | |||
303 | def _CheckRepoDir(repo_dir): | 305 | def _CheckRepoDir(repo_dir): |
304 | if not repo_dir: | 306 | if not repo_dir: |
305 | print('no --repo-dir argument', file=sys.stderr) | 307 | print('no --repo-dir argument', file=sys.stderr) |
306 | sys.exit(1) | 308 | sys.exit(1) |
307 | 309 | ||
310 | |||
308 | def _PruneOptions(argv, opt): | 311 | def _PruneOptions(argv, opt): |
309 | i = 0 | 312 | i = 0 |
310 | while i < len(argv): | 313 | while i < len(argv): |
@@ -320,6 +323,7 @@ def _PruneOptions(argv, opt): | |||
320 | continue | 323 | continue |
321 | i += 1 | 324 | i += 1 |
322 | 325 | ||
326 | |||
323 | class _UserAgentHandler(urllib.request.BaseHandler): | 327 | class _UserAgentHandler(urllib.request.BaseHandler): |
324 | def http_request(self, req): | 328 | def http_request(self, req): |
325 | req.add_header('User-Agent', user_agent.repo) | 329 | req.add_header('User-Agent', user_agent.repo) |
@@ -329,6 +333,7 @@ class _UserAgentHandler(urllib.request.BaseHandler): | |||
329 | req.add_header('User-Agent', user_agent.repo) | 333 | req.add_header('User-Agent', user_agent.repo) |
330 | return req | 334 | return req |
331 | 335 | ||
336 | |||
332 | def _AddPasswordFromUserInput(handler, msg, req): | 337 | def _AddPasswordFromUserInput(handler, msg, req): |
333 | # If repo could not find auth info from netrc, try to get it from user input | 338 | # If repo could not find auth info from netrc, try to get it from user input |
334 | url = req.get_full_url() | 339 | url = req.get_full_url() |
@@ -342,6 +347,7 @@ def _AddPasswordFromUserInput(handler, msg, req): | |||
342 | return | 347 | return |
343 | handler.passwd.add_password(None, url, user, password) | 348 | handler.passwd.add_password(None, url, user, password) |
344 | 349 | ||
350 | |||
345 | class _BasicAuthHandler(urllib.request.HTTPBasicAuthHandler): | 351 | class _BasicAuthHandler(urllib.request.HTTPBasicAuthHandler): |
346 | def http_error_401(self, req, fp, code, msg, headers): | 352 | def http_error_401(self, req, fp, code, msg, headers): |
347 | _AddPasswordFromUserInput(self, msg, req) | 353 | _AddPasswordFromUserInput(self, msg, req) |
@@ -351,6 +357,7 @@ class _BasicAuthHandler(urllib.request.HTTPBasicAuthHandler): | |||
351 | def http_error_auth_reqed(self, authreq, host, req, headers): | 357 | def http_error_auth_reqed(self, authreq, host, req, headers): |
352 | try: | 358 | try: |
353 | old_add_header = req.add_header | 359 | old_add_header = req.add_header |
360 | |||
354 | def _add_header(name, val): | 361 | def _add_header(name, val): |
355 | val = val.replace('\n', '') | 362 | val = val.replace('\n', '') |
356 | old_add_header(name, val) | 363 | old_add_header(name, val) |
@@ -365,6 +372,7 @@ class _BasicAuthHandler(urllib.request.HTTPBasicAuthHandler): | |||
365 | self.retried = 0 | 372 | self.retried = 0 |
366 | raise | 373 | raise |
367 | 374 | ||
375 | |||
368 | class _DigestAuthHandler(urllib.request.HTTPDigestAuthHandler): | 376 | class _DigestAuthHandler(urllib.request.HTTPDigestAuthHandler): |
369 | def http_error_401(self, req, fp, code, msg, headers): | 377 | def http_error_401(self, req, fp, code, msg, headers): |
370 | _AddPasswordFromUserInput(self, msg, req) | 378 | _AddPasswordFromUserInput(self, msg, req) |
@@ -374,6 +382,7 @@ class _DigestAuthHandler(urllib.request.HTTPDigestAuthHandler): | |||
374 | def http_error_auth_reqed(self, auth_header, host, req, headers): | 382 | def http_error_auth_reqed(self, auth_header, host, req, headers): |
375 | try: | 383 | try: |
376 | old_add_header = req.add_header | 384 | old_add_header = req.add_header |
385 | |||
377 | def _add_header(name, val): | 386 | def _add_header(name, val): |
378 | val = val.replace('\n', '') | 387 | val = val.replace('\n', '') |
379 | old_add_header(name, val) | 388 | old_add_header(name, val) |
@@ -388,6 +397,7 @@ class _DigestAuthHandler(urllib.request.HTTPDigestAuthHandler): | |||
388 | self.retried = 0 | 397 | self.retried = 0 |
389 | raise | 398 | raise |
390 | 399 | ||
400 | |||
391 | class _KerberosAuthHandler(urllib.request.BaseHandler): | 401 | class _KerberosAuthHandler(urllib.request.BaseHandler): |
392 | def __init__(self): | 402 | def __init__(self): |
393 | self.retried = 0 | 403 | self.retried = 0 |
@@ -468,6 +478,7 @@ class _KerberosAuthHandler(urllib.request.BaseHandler): | |||
468 | kerberos.authGSSClientClean(self.context) | 478 | kerberos.authGSSClientClean(self.context) |
469 | self.context = None | 479 | self.context = None |
470 | 480 | ||
481 | |||
471 | def init_http(): | 482 | def init_http(): |
472 | handlers = [_UserAgentHandler()] | 483 | handlers = [_UserAgentHandler()] |
473 | 484 | ||
@@ -495,6 +506,7 @@ def init_http(): | |||
495 | handlers.append(urllib.request.HTTPSHandler(debuglevel=1)) | 506 | handlers.append(urllib.request.HTTPSHandler(debuglevel=1)) |
496 | urllib.request.install_opener(urllib.request.build_opener(*handlers)) | 507 | urllib.request.install_opener(urllib.request.build_opener(*handlers)) |
497 | 508 | ||
509 | |||
498 | def _Main(argv): | 510 | def _Main(argv): |
499 | result = 0 | 511 | result = 0 |
500 | 512 | ||
@@ -551,5 +563,6 @@ def _Main(argv): | |||
551 | TerminatePager() | 563 | TerminatePager() |
552 | sys.exit(result) | 564 | sys.exit(result) |
553 | 565 | ||
566 | |||
554 | if __name__ == '__main__': | 567 | if __name__ == '__main__': |
555 | _Main(sys.argv[1:]) | 568 | _Main(sys.argv[1:]) |
diff --git a/manifest_xml.py b/manifest_xml.py index fd0e4f12..7f38d8c3 100644 --- a/manifest_xml.py +++ b/manifest_xml.py | |||
@@ -56,6 +56,7 @@ urllib.parse.uses_netloc.extend([ | |||
56 | 'sso', | 56 | 'sso', |
57 | 'rpc']) | 57 | 'rpc']) |
58 | 58 | ||
59 | |||
59 | class _Default(object): | 60 | class _Default(object): |
60 | """Project defaults within the manifest.""" | 61 | """Project defaults within the manifest.""" |
61 | 62 | ||
@@ -74,6 +75,7 @@ class _Default(object): | |||
74 | def __ne__(self, other): | 75 | def __ne__(self, other): |
75 | return self.__dict__ != other.__dict__ | 76 | return self.__dict__ != other.__dict__ |
76 | 77 | ||
78 | |||
77 | class _XmlRemote(object): | 79 | class _XmlRemote(object): |
78 | def __init__(self, | 80 | def __init__(self, |
79 | name, | 81 | name, |
@@ -127,6 +129,7 @@ class _XmlRemote(object): | |||
127 | orig_name=self.name, | 129 | orig_name=self.name, |
128 | fetchUrl=self.fetchUrl) | 130 | fetchUrl=self.fetchUrl) |
129 | 131 | ||
132 | |||
130 | class XmlManifest(object): | 133 | class XmlManifest(object): |
131 | """manages the repo configuration file""" | 134 | """manages the repo configuration file""" |
132 | 135 | ||
@@ -655,7 +658,6 @@ class XmlManifest(object): | |||
655 | if self._repo_hooks_project and (self._repo_hooks_project.name == name): | 658 | if self._repo_hooks_project and (self._repo_hooks_project.name == name): |
656 | self._repo_hooks_project = None | 659 | self._repo_hooks_project = None |
657 | 660 | ||
658 | |||
659 | def _AddMetaProjectMirror(self, m): | 661 | def _AddMetaProjectMirror(self, m): |
660 | name = None | 662 | name = None |
661 | m_url = m.GetRemote(m.remote.name).url | 663 | m_url = m.GetRemote(m.remote.name).url |
@@ -27,6 +27,7 @@ pager_process = None | |||
27 | old_stdout = None | 27 | old_stdout = None |
28 | old_stderr = None | 28 | old_stderr = None |
29 | 29 | ||
30 | |||
30 | def RunPager(globalConfig): | 31 | def RunPager(globalConfig): |
31 | if not os.isatty(0) or not os.isatty(1): | 32 | if not os.isatty(0) or not os.isatty(1): |
32 | return | 33 | return |
@@ -39,6 +40,7 @@ def RunPager(globalConfig): | |||
39 | else: | 40 | else: |
40 | _ForkPager(pager) | 41 | _ForkPager(pager) |
41 | 42 | ||
43 | |||
42 | def TerminatePager(): | 44 | def TerminatePager(): |
43 | global pager_process, old_stdout, old_stderr | 45 | global pager_process, old_stdout, old_stderr |
44 | if pager_process: | 46 | if pager_process: |
@@ -52,6 +54,7 @@ def TerminatePager(): | |||
52 | sys.stdout = old_stdout | 54 | sys.stdout = old_stdout |
53 | sys.stderr = old_stderr | 55 | sys.stderr = old_stderr |
54 | 56 | ||
57 | |||
55 | def _PipePager(pager): | 58 | def _PipePager(pager): |
56 | global pager_process, old_stdout, old_stderr | 59 | global pager_process, old_stdout, old_stderr |
57 | assert pager_process is None, "Only one active pager process at a time" | 60 | assert pager_process is None, "Only one active pager process at a time" |
@@ -62,6 +65,7 @@ def _PipePager(pager): | |||
62 | sys.stdout = pager_process.stdin | 65 | sys.stdout = pager_process.stdin |
63 | sys.stderr = pager_process.stdin | 66 | sys.stderr = pager_process.stdin |
64 | 67 | ||
68 | |||
65 | def _ForkPager(pager): | 69 | def _ForkPager(pager): |
66 | global active | 70 | global active |
67 | # This process turns into the pager; a child it forks will | 71 | # This process turns into the pager; a child it forks will |
@@ -88,6 +92,7 @@ def _ForkPager(pager): | |||
88 | print("fatal: cannot start pager '%s'" % pager, file=sys.stderr) | 92 | print("fatal: cannot start pager '%s'" % pager, file=sys.stderr) |
89 | sys.exit(255) | 93 | sys.exit(255) |
90 | 94 | ||
95 | |||
91 | def _SelectPager(globalConfig): | 96 | def _SelectPager(globalConfig): |
92 | try: | 97 | try: |
93 | return os.environ['GIT_PAGER'] | 98 | return os.environ['GIT_PAGER'] |
@@ -105,6 +110,7 @@ def _SelectPager(globalConfig): | |||
105 | 110 | ||
106 | return 'less' | 111 | return 'less' |
107 | 112 | ||
113 | |||
108 | def _BecomePager(pager): | 114 | def _BecomePager(pager): |
109 | # Delaying execution of the pager until we have output | 115 | # Delaying execution of the pager until we have output |
110 | # ready works around a long-standing bug in popularly | 116 | # ready works around a long-standing bug in popularly |
diff --git a/platform_utils.py b/platform_utils.py index 06ef9b18..490ba208 100644 --- a/platform_utils.py +++ b/platform_utils.py | |||
@@ -92,6 +92,7 @@ class _FileDescriptorStreamsNonBlocking(FileDescriptorStreams): | |||
92 | """ | 92 | """ |
93 | class Stream(object): | 93 | class Stream(object): |
94 | """ Encapsulates a file descriptor """ | 94 | """ Encapsulates a file descriptor """ |
95 | |||
95 | def __init__(self, fd, dest, std_name): | 96 | def __init__(self, fd, dest, std_name): |
96 | self.fd = fd | 97 | self.fd = fd |
97 | self.dest = dest | 98 | self.dest = dest |
@@ -125,6 +126,7 @@ class _FileDescriptorStreamsThreads(FileDescriptorStreams): | |||
125 | non blocking I/O. This implementation requires creating threads issuing | 126 | non blocking I/O. This implementation requires creating threads issuing |
126 | blocking read operations on file descriptors. | 127 | blocking read operations on file descriptors. |
127 | """ | 128 | """ |
129 | |||
128 | def __init__(self): | 130 | def __init__(self): |
129 | super(_FileDescriptorStreamsThreads, self).__init__() | 131 | super(_FileDescriptorStreamsThreads, self).__init__() |
130 | # The queue is shared accross all threads so we can simulate the | 132 | # The queue is shared accross all threads so we can simulate the |
@@ -144,12 +146,14 @@ class _FileDescriptorStreamsThreads(FileDescriptorStreams): | |||
144 | 146 | ||
145 | class QueueItem(object): | 147 | class QueueItem(object): |
146 | """ Item put in the shared queue """ | 148 | """ Item put in the shared queue """ |
149 | |||
147 | def __init__(self, stream, data): | 150 | def __init__(self, stream, data): |
148 | self.stream = stream | 151 | self.stream = stream |
149 | self.data = data | 152 | self.data = data |
150 | 153 | ||
151 | class Stream(object): | 154 | class Stream(object): |
152 | """ Encapsulates a file descriptor """ | 155 | """ Encapsulates a file descriptor """ |
156 | |||
153 | def __init__(self, fd, dest, std_name, queue): | 157 | def __init__(self, fd, dest, std_name, queue): |
154 | self.fd = fd | 158 | self.fd = fd |
155 | self.dest = dest | 159 | self.dest = dest |
diff --git a/progress.py b/progress.py index 8a643db2..ff627980 100644 --- a/progress.py +++ b/progress.py | |||
@@ -26,6 +26,7 @@ _NOT_TTY = not os.isatty(2) | |||
26 | # column 0. | 26 | # column 0. |
27 | CSI_ERASE_LINE = '\x1b[2K' | 27 | CSI_ERASE_LINE = '\x1b[2K' |
28 | 28 | ||
29 | |||
29 | class Progress(object): | 30 | class Progress(object): |
30 | def __init__(self, title, total=0, units='', print_newline=False, | 31 | def __init__(self, title, total=0, units='', print_newline=False, |
31 | always_print_percentage=False): | 32 | always_print_percentage=False): |
@@ -85,6 +85,7 @@ def not_rev(r): | |||
85 | def sq(r): | 85 | def sq(r): |
86 | return "'" + r.replace("'", "'\''") + "'" | 86 | return "'" + r.replace("'", "'\''") + "'" |
87 | 87 | ||
88 | |||
88 | _project_hook_list = None | 89 | _project_hook_list = None |
89 | 90 | ||
90 | 91 | ||
@@ -1256,9 +1257,7 @@ class Project(object): | |||
1256 | print(line[:-1]) | 1257 | print(line[:-1]) |
1257 | return p.Wait() == 0 | 1258 | return p.Wait() == 0 |
1258 | 1259 | ||
1259 | |||
1260 | # Publish / Upload ## | 1260 | # Publish / Upload ## |
1261 | |||
1262 | def WasPublished(self, branch, all_refs=None): | 1261 | def WasPublished(self, branch, all_refs=None): |
1263 | """Was the branch published (uploaded) for code review? | 1262 | """Was the branch published (uploaded) for code review? |
1264 | If so, returns the SHA-1 hash of the last published | 1263 | If so, returns the SHA-1 hash of the last published |
@@ -1410,9 +1409,7 @@ class Project(object): | |||
1410 | R_HEADS + branch.name, | 1409 | R_HEADS + branch.name, |
1411 | message=msg) | 1410 | message=msg) |
1412 | 1411 | ||
1413 | |||
1414 | # Sync ## | 1412 | # Sync ## |
1415 | |||
1416 | def _ExtractArchive(self, tarpath, path=None): | 1413 | def _ExtractArchive(self, tarpath, path=None): |
1417 | """Extract the given tar on its current location | 1414 | """Extract the given tar on its current location |
1418 | 1415 | ||
@@ -1819,9 +1816,7 @@ class Project(object): | |||
1819 | patch_id, | 1816 | patch_id, |
1820 | self.bare_git.rev_parse('FETCH_HEAD')) | 1817 | self.bare_git.rev_parse('FETCH_HEAD')) |
1821 | 1818 | ||
1822 | |||
1823 | # Branch Management ## | 1819 | # Branch Management ## |
1824 | |||
1825 | def GetHeadPath(self): | 1820 | def GetHeadPath(self): |
1826 | """Return the full path to the HEAD ref.""" | 1821 | """Return the full path to the HEAD ref.""" |
1827 | dotgit = os.path.join(self.worktree, '.git') | 1822 | dotgit = os.path.join(self.worktree, '.git') |
@@ -2019,9 +2014,7 @@ class Project(object): | |||
2019 | kept.append(ReviewableBranch(self, branch, base)) | 2014 | kept.append(ReviewableBranch(self, branch, base)) |
2020 | return kept | 2015 | return kept |
2021 | 2016 | ||
2022 | |||
2023 | # Submodule Management ## | 2017 | # Submodule Management ## |
2024 | |||
2025 | def GetRegisteredSubprojects(self): | 2018 | def GetRegisteredSubprojects(self): |
2026 | result = [] | 2019 | result = [] |
2027 | 2020 | ||
@@ -2172,7 +2165,6 @@ class Project(object): | |||
2172 | result.extend(subproject.GetDerivedSubprojects()) | 2165 | result.extend(subproject.GetDerivedSubprojects()) |
2173 | return result | 2166 | return result |
2174 | 2167 | ||
2175 | |||
2176 | # Direct Git Commands ## | 2168 | # Direct Git Commands ## |
2177 | def _CheckForImmutableRevision(self): | 2169 | def _CheckForImmutableRevision(self): |
2178 | try: | 2170 | try: |
diff --git a/pyversion.py b/pyversion.py index f6082408..8dbf909b 100644 --- a/pyversion.py +++ b/pyversion.py | |||
@@ -16,5 +16,6 @@ | |||
16 | 16 | ||
17 | import sys | 17 | import sys |
18 | 18 | ||
19 | |||
19 | def is_python3(): | 20 | def is_python3(): |
20 | return sys.version_info[0] == 3 | 21 | return sys.version_info[0] == 3 |
diff --git a/repo_trace.py b/repo_trace.py index f5bc76d4..cd571f4c 100644 --- a/repo_trace.py +++ b/repo_trace.py | |||
@@ -28,13 +28,16 @@ REPO_TRACE = 'REPO_TRACE' | |||
28 | 28 | ||
29 | _TRACE = os.environ.get(REPO_TRACE) == '1' | 29 | _TRACE = os.environ.get(REPO_TRACE) == '1' |
30 | 30 | ||
31 | |||
31 | def IsTrace(): | 32 | def IsTrace(): |
32 | return _TRACE | 33 | return _TRACE |
33 | 34 | ||
35 | |||
34 | def SetTrace(): | 36 | def SetTrace(): |
35 | global _TRACE | 37 | global _TRACE |
36 | _TRACE = True | 38 | _TRACE = True |
37 | 39 | ||
40 | |||
38 | def Trace(fmt, *args): | 41 | def Trace(fmt, *args): |
39 | if IsTrace(): | 42 | if IsTrace(): |
40 | print(fmt % args, file=sys.stderr) | 43 | print(fmt % args, file=sys.stderr) |
diff --git a/subcmds/abandon.py b/subcmds/abandon.py index 9a645c0a..f3478129 100644 --- a/subcmds/abandon.py +++ b/subcmds/abandon.py | |||
@@ -21,6 +21,7 @@ from collections import defaultdict | |||
21 | from git_command import git | 21 | from git_command import git |
22 | from progress import Progress | 22 | from progress import Progress |
23 | 23 | ||
24 | |||
24 | class Abandon(Command): | 25 | class Abandon(Command): |
25 | common = True | 26 | common = True |
26 | helpSummary = "Permanently abandon a development branch" | 27 | helpSummary = "Permanently abandon a development branch" |
@@ -32,6 +33,7 @@ deleting it (and all its history) from your local repository. | |||
32 | 33 | ||
33 | It is equivalent to "git branch -D <branchname>". | 34 | It is equivalent to "git branch -D <branchname>". |
34 | """ | 35 | """ |
36 | |||
35 | def _Options(self, p): | 37 | def _Options(self, p): |
36 | p.add_option('--all', | 38 | p.add_option('--all', |
37 | dest='all', action='store_true', | 39 | dest='all', action='store_true', |
diff --git a/subcmds/branches.py b/subcmds/branches.py index b4894ec8..9709f7f0 100644 --- a/subcmds/branches.py +++ b/subcmds/branches.py | |||
@@ -19,6 +19,7 @@ import sys | |||
19 | from color import Coloring | 19 | from color import Coloring |
20 | from command import Command | 20 | from command import Command |
21 | 21 | ||
22 | |||
22 | class BranchColoring(Coloring): | 23 | class BranchColoring(Coloring): |
23 | def __init__(self, config): | 24 | def __init__(self, config): |
24 | Coloring.__init__(self, config, 'branch') | 25 | Coloring.__init__(self, config, 'branch') |
@@ -26,6 +27,7 @@ class BranchColoring(Coloring): | |||
26 | self.local = self.printer('local') | 27 | self.local = self.printer('local') |
27 | self.notinproject = self.printer('notinproject', fg='red') | 28 | self.notinproject = self.printer('notinproject', fg='red') |
28 | 29 | ||
30 | |||
29 | class BranchInfo(object): | 31 | class BranchInfo(object): |
30 | def __init__(self, name): | 32 | def __init__(self, name): |
31 | self.name = name | 33 | self.name = name |
diff --git a/subcmds/checkout.py b/subcmds/checkout.py index c8a09a8e..efa31d26 100644 --- a/subcmds/checkout.py +++ b/subcmds/checkout.py | |||
@@ -19,6 +19,7 @@ import sys | |||
19 | from command import Command | 19 | from command import Command |
20 | from progress import Progress | 20 | from progress import Progress |
21 | 21 | ||
22 | |||
22 | class Checkout(Command): | 23 | class Checkout(Command): |
23 | common = True | 24 | common = True |
24 | helpSummary = "Checkout a branch for development" | 25 | helpSummary = "Checkout a branch for development" |
diff --git a/subcmds/cherry_pick.py b/subcmds/cherry_pick.py index 8d81be33..3ad82109 100644 --- a/subcmds/cherry_pick.py +++ b/subcmds/cherry_pick.py | |||
@@ -22,6 +22,7 @@ from git_command import GitCommand | |||
22 | 22 | ||
23 | CHANGE_ID_RE = re.compile(r'^\s*Change-Id: I([0-9a-f]{40})\s*$') | 23 | CHANGE_ID_RE = re.compile(r'^\s*Change-Id: I([0-9a-f]{40})\s*$') |
24 | 24 | ||
25 | |||
25 | class CherryPick(Command): | 26 | class CherryPick(Command): |
26 | common = True | 27 | common = True |
27 | helpSummary = "Cherry-pick a change." | 28 | helpSummary = "Cherry-pick a change." |
diff --git a/subcmds/diff.py b/subcmds/diff.py index fa41e70e..406baa28 100644 --- a/subcmds/diff.py +++ b/subcmds/diff.py | |||
@@ -16,6 +16,7 @@ | |||
16 | 16 | ||
17 | from command import PagedCommand | 17 | from command import PagedCommand |
18 | 18 | ||
19 | |||
19 | class Diff(PagedCommand): | 20 | class Diff(PagedCommand): |
20 | common = True | 21 | common = True |
21 | helpSummary = "Show changes between commit and working tree" | 22 | helpSummary = "Show changes between commit and working tree" |
diff --git a/subcmds/diffmanifests.py b/subcmds/diffmanifests.py index 9bdb5e14..77f99df2 100644 --- a/subcmds/diffmanifests.py +++ b/subcmds/diffmanifests.py | |||
@@ -18,10 +18,12 @@ from color import Coloring | |||
18 | from command import PagedCommand | 18 | from command import PagedCommand |
19 | from manifest_xml import XmlManifest | 19 | from manifest_xml import XmlManifest |
20 | 20 | ||
21 | |||
21 | class _Coloring(Coloring): | 22 | class _Coloring(Coloring): |
22 | def __init__(self, config): | 23 | def __init__(self, config): |
23 | Coloring.__init__(self, config, "status") | 24 | Coloring.__init__(self, config, "status") |
24 | 25 | ||
26 | |||
25 | class Diffmanifests(PagedCommand): | 27 | class Diffmanifests(PagedCommand): |
26 | """ A command to see logs in projects represented by manifests | 28 | """ A command to see logs in projects represented by manifests |
27 | 29 | ||
diff --git a/subcmds/download.py b/subcmds/download.py index fbd302aa..87d0ce04 100644 --- a/subcmds/download.py +++ b/subcmds/download.py | |||
@@ -23,6 +23,7 @@ from error import GitError | |||
23 | 23 | ||
24 | CHANGE_RE = re.compile(r'^([1-9][0-9]*)(?:[/\.-]([1-9][0-9]*))?$') | 24 | CHANGE_RE = re.compile(r'^([1-9][0-9]*)(?:[/\.-]([1-9][0-9]*))?$') |
25 | 25 | ||
26 | |||
26 | class Download(Command): | 27 | class Download(Command): |
27 | common = True | 28 | common = True |
28 | helpSummary = "Download and checkout a change" | 29 | helpSummary = "Download and checkout a change" |
diff --git a/subcmds/forall.py b/subcmds/forall.py index 5d2be91f..dbf26f0b 100644 --- a/subcmds/forall.py +++ b/subcmds/forall.py | |||
@@ -277,6 +277,7 @@ without iterating through the remaining projects. | |||
277 | return | 277 | return |
278 | yield [mirror, opt, cmd, shell, cnt, config, project] | 278 | yield [mirror, opt, cmd, shell, cnt, config, project] |
279 | 279 | ||
280 | |||
280 | class WorkerKeyboardInterrupt(Exception): | 281 | class WorkerKeyboardInterrupt(Exception): |
281 | """ Keyboard interrupt exception for worker processes. """ | 282 | """ Keyboard interrupt exception for worker processes. """ |
282 | pass | 283 | pass |
@@ -285,6 +286,7 @@ class WorkerKeyboardInterrupt(Exception): | |||
285 | def InitWorker(): | 286 | def InitWorker(): |
286 | signal.signal(signal.SIGINT, signal.SIG_IGN) | 287 | signal.signal(signal.SIGINT, signal.SIG_IGN) |
287 | 288 | ||
289 | |||
288 | def DoWorkWrapper(args): | 290 | def DoWorkWrapper(args): |
289 | """ A wrapper around the DoWork() method. | 291 | """ A wrapper around the DoWork() method. |
290 | 292 | ||
@@ -303,6 +305,7 @@ def DoWorkWrapper(args): | |||
303 | 305 | ||
304 | def DoWork(project, mirror, opt, cmd, shell, cnt, config): | 306 | def DoWork(project, mirror, opt, cmd, shell, cnt, config): |
305 | env = os.environ.copy() | 307 | env = os.environ.copy() |
308 | |||
306 | def setenv(name, val): | 309 | def setenv(name, val): |
307 | if val is None: | 310 | if val is None: |
308 | val = '' | 311 | val = '' |
diff --git a/subcmds/gitc_delete.py b/subcmds/gitc_delete.py index e5214b8e..1011276f 100644 --- a/subcmds/gitc_delete.py +++ b/subcmds/gitc_delete.py | |||
@@ -24,6 +24,7 @@ from pyversion import is_python3 | |||
24 | if not is_python3(): | 24 | if not is_python3(): |
25 | input = raw_input | 25 | input = raw_input |
26 | 26 | ||
27 | |||
27 | class GitcDelete(Command, GitcClientCommand): | 28 | class GitcDelete(Command, GitcClientCommand): |
28 | common = True | 29 | common = True |
29 | visible_everywhere = False | 30 | visible_everywhere = False |
diff --git a/subcmds/grep.py b/subcmds/grep.py index 4dd85d57..13069286 100644 --- a/subcmds/grep.py +++ b/subcmds/grep.py | |||
@@ -23,12 +23,14 @@ from command import PagedCommand | |||
23 | from error import GitError | 23 | from error import GitError |
24 | from git_command import git_require, GitCommand | 24 | from git_command import git_require, GitCommand |
25 | 25 | ||
26 | |||
26 | class GrepColoring(Coloring): | 27 | class GrepColoring(Coloring): |
27 | def __init__(self, config): | 28 | def __init__(self, config): |
28 | Coloring.__init__(self, config, 'grep') | 29 | Coloring.__init__(self, config, 'grep') |
29 | self.project = self.printer('project', attr='bold') | 30 | self.project = self.printer('project', attr='bold') |
30 | self.fail = self.printer('fail', fg='red') | 31 | self.fail = self.printer('fail', fg='red') |
31 | 32 | ||
33 | |||
32 | class Grep(PagedCommand): | 34 | class Grep(PagedCommand): |
33 | common = True | 35 | common = True |
34 | helpSummary = "Print lines matching a pattern" | 36 | helpSummary = "Print lines matching a pattern" |
@@ -156,7 +158,6 @@ contain a line that matches both expressions: | |||
156 | action='callback', callback=carry, | 158 | action='callback', callback=carry, |
157 | help='Show only file names not containing matching lines') | 159 | help='Show only file names not containing matching lines') |
158 | 160 | ||
159 | |||
160 | def Execute(self, opt, args): | 161 | def Execute(self, opt, args): |
161 | out = GrepColoring(self.manifest.manifestProject.config) | 162 | out = GrepColoring(self.manifest.manifestProject.config) |
162 | 163 | ||
diff --git a/subcmds/help.py b/subcmds/help.py index 93b9a86d..36b3a7ae 100644 --- a/subcmds/help.py +++ b/subcmds/help.py | |||
@@ -23,6 +23,7 @@ from color import Coloring | |||
23 | from command import PagedCommand, MirrorSafeCommand, GitcAvailableCommand, GitcClientCommand | 23 | from command import PagedCommand, MirrorSafeCommand, GitcAvailableCommand, GitcClientCommand |
24 | import gitc_utils | 24 | import gitc_utils |
25 | 25 | ||
26 | |||
26 | class Help(PagedCommand, MirrorSafeCommand): | 27 | class Help(PagedCommand, MirrorSafeCommand): |
27 | common = False | 28 | common = False |
28 | helpSummary = "Display detailed help on a command" | 29 | helpSummary = "Display detailed help on a command" |
diff --git a/subcmds/info.py b/subcmds/info.py index 96fa6a4c..76f5d1d6 100644 --- a/subcmds/info.py +++ b/subcmds/info.py | |||
@@ -18,10 +18,12 @@ from command import PagedCommand | |||
18 | from color import Coloring | 18 | from color import Coloring |
19 | from git_refs import R_M | 19 | from git_refs import R_M |
20 | 20 | ||
21 | |||
21 | class _Coloring(Coloring): | 22 | class _Coloring(Coloring): |
22 | def __init__(self, config): | 23 | def __init__(self, config): |
23 | Coloring.__init__(self, config, "status") | 24 | Coloring.__init__(self, config, "status") |
24 | 25 | ||
26 | |||
25 | class Info(PagedCommand): | 27 | class Info(PagedCommand): |
26 | common = True | 28 | common = True |
27 | helpSummary = "Get info on the manifest branch, current branch or unmerged branches" | 29 | helpSummary = "Get info on the manifest branch, current branch or unmerged branches" |
@@ -41,7 +43,6 @@ class Info(PagedCommand): | |||
41 | dest="local", action="store_true", | 43 | dest="local", action="store_true", |
42 | help="Disable all remote operations") | 44 | help="Disable all remote operations") |
43 | 45 | ||
44 | |||
45 | def Execute(self, opt, args): | 46 | def Execute(self, opt, args): |
46 | self.out = _Coloring(self.manifest.globalConfig) | 47 | self.out = _Coloring(self.manifest.globalConfig) |
47 | self.heading = self.out.printer('heading', attr='bold') | 48 | self.heading = self.out.printer('heading', attr='bold') |
diff --git a/subcmds/init.py b/subcmds/init.py index 7181b86f..dde97286 100644 --- a/subcmds/init.py +++ b/subcmds/init.py | |||
@@ -37,6 +37,7 @@ from git_config import GitConfig | |||
37 | from git_command import git_require, MIN_GIT_VERSION_SOFT, MIN_GIT_VERSION_HARD | 37 | from git_command import git_require, MIN_GIT_VERSION_SOFT, MIN_GIT_VERSION_HARD |
38 | import platform_utils | 38 | import platform_utils |
39 | 39 | ||
40 | |||
40 | class Init(InteractiveCommand, MirrorSafeCommand): | 41 | class Init(InteractiveCommand, MirrorSafeCommand): |
41 | common = True | 42 | common = True |
42 | helpSummary = "Initialize repo in the current directory" | 43 | helpSummary = "Initialize repo in the current directory" |
diff --git a/subcmds/list.py b/subcmds/list.py index 1cd971ef..13cae5ff 100644 --- a/subcmds/list.py +++ b/subcmds/list.py | |||
@@ -18,6 +18,7 @@ from __future__ import print_function | |||
18 | 18 | ||
19 | from command import Command, MirrorSafeCommand | 19 | from command import Command, MirrorSafeCommand |
20 | 20 | ||
21 | |||
21 | class List(Command, MirrorSafeCommand): | 22 | class List(Command, MirrorSafeCommand): |
22 | common = True | 23 | common = True |
23 | helpSummary = "List projects and their associated directories" | 24 | helpSummary = "List projects and their associated directories" |
diff --git a/subcmds/manifest.py b/subcmds/manifest.py index 6bb01045..072c9ff7 100644 --- a/subcmds/manifest.py +++ b/subcmds/manifest.py | |||
@@ -20,6 +20,7 @@ import sys | |||
20 | 20 | ||
21 | from command import PagedCommand | 21 | from command import PagedCommand |
22 | 22 | ||
23 | |||
23 | class Manifest(PagedCommand): | 24 | class Manifest(PagedCommand): |
24 | common = False | 25 | common = False |
25 | helpSummary = "Manifest inspection utility" | 26 | helpSummary = "Manifest inspection utility" |
diff --git a/subcmds/prune.py b/subcmds/prune.py index ff2fba1d..e90ff213 100644 --- a/subcmds/prune.py +++ b/subcmds/prune.py | |||
@@ -18,6 +18,7 @@ from __future__ import print_function | |||
18 | from color import Coloring | 18 | from color import Coloring |
19 | from command import PagedCommand | 19 | from command import PagedCommand |
20 | 20 | ||
21 | |||
21 | class Prune(PagedCommand): | 22 | class Prune(PagedCommand): |
22 | common = True | 23 | common = True |
23 | helpSummary = "Prune (delete) already merged topics" | 24 | helpSummary = "Prune (delete) already merged topics" |
diff --git a/subcmds/selfupdate.py b/subcmds/selfupdate.py index b157e2f1..4817a862 100644 --- a/subcmds/selfupdate.py +++ b/subcmds/selfupdate.py | |||
@@ -22,6 +22,7 @@ from command import Command, MirrorSafeCommand | |||
22 | from subcmds.sync import _PostRepoUpgrade | 22 | from subcmds.sync import _PostRepoUpgrade |
23 | from subcmds.sync import _PostRepoFetch | 23 | from subcmds.sync import _PostRepoFetch |
24 | 24 | ||
25 | |||
25 | class Selfupdate(Command, MirrorSafeCommand): | 26 | class Selfupdate(Command, MirrorSafeCommand): |
26 | common = False | 27 | common = False |
27 | helpSummary = "Update repo to the latest version" | 28 | helpSummary = "Update repo to the latest version" |
diff --git a/subcmds/smartsync.py b/subcmds/smartsync.py index 675b9834..6037e5a3 100644 --- a/subcmds/smartsync.py +++ b/subcmds/smartsync.py | |||
@@ -16,6 +16,7 @@ | |||
16 | 16 | ||
17 | from subcmds.sync import Sync | 17 | from subcmds.sync import Sync |
18 | 18 | ||
19 | |||
19 | class Smartsync(Sync): | 20 | class Smartsync(Sync): |
20 | common = True | 21 | common = True |
21 | helpSummary = "Update working tree to the latest known good revision" | 22 | helpSummary = "Update working tree to the latest known good revision" |
diff --git a/subcmds/stage.py b/subcmds/stage.py index aeb49513..4dce5ce5 100644 --- a/subcmds/stage.py +++ b/subcmds/stage.py | |||
@@ -21,6 +21,7 @@ from color import Coloring | |||
21 | from command import InteractiveCommand | 21 | from command import InteractiveCommand |
22 | from git_command import GitCommand | 22 | from git_command import GitCommand |
23 | 23 | ||
24 | |||
24 | class _ProjectList(Coloring): | 25 | class _ProjectList(Coloring): |
25 | def __init__(self, gc): | 26 | def __init__(self, gc): |
26 | Coloring.__init__(self, gc, 'interactive') | 27 | Coloring.__init__(self, gc, 'interactive') |
@@ -28,6 +29,7 @@ class _ProjectList(Coloring): | |||
28 | self.header = self.printer('header', attr='bold') | 29 | self.header = self.printer('header', attr='bold') |
29 | self.help = self.printer('help', fg='red', attr='bold') | 30 | self.help = self.printer('help', fg='red', attr='bold') |
30 | 31 | ||
32 | |||
31 | class Stage(InteractiveCommand): | 33 | class Stage(InteractiveCommand): |
32 | common = True | 34 | common = True |
33 | helpSummary = "Stage file(s) for commit" | 35 | helpSummary = "Stage file(s) for commit" |
@@ -105,6 +107,7 @@ The '%prog' command stages files to prepare the next commit. | |||
105 | continue | 107 | continue |
106 | print('Bye.') | 108 | print('Bye.') |
107 | 109 | ||
110 | |||
108 | def _AddI(project): | 111 | def _AddI(project): |
109 | p = GitCommand(project, ['add', '--interactive'], bare=False) | 112 | p = GitCommand(project, ['add', '--interactive'], bare=False) |
110 | p.Wait() | 113 | p.Wait() |
diff --git a/subcmds/start.py b/subcmds/start.py index f98f790a..adc6d293 100644 --- a/subcmds/start.py +++ b/subcmds/start.py | |||
@@ -25,6 +25,7 @@ import gitc_utils | |||
25 | from progress import Progress | 25 | from progress import Progress |
26 | from project import SyncBuffer | 26 | from project import SyncBuffer |
27 | 27 | ||
28 | |||
28 | class Start(Command): | 29 | class Start(Command): |
29 | common = True | 30 | common = True |
30 | helpSummary = "Start a new branch for development" | 31 | helpSummary = "Start a new branch for development" |
diff --git a/subcmds/status.py b/subcmds/status.py index a04ba922..b594bd89 100644 --- a/subcmds/status.py +++ b/subcmds/status.py | |||
@@ -31,6 +31,7 @@ import os | |||
31 | from color import Coloring | 31 | from color import Coloring |
32 | import platform_utils | 32 | import platform_utils |
33 | 33 | ||
34 | |||
34 | class Status(PagedCommand): | 35 | class Status(PagedCommand): |
35 | common = True | 36 | common = True |
36 | helpSummary = "Show the working tree status" | 37 | helpSummary = "Show the working tree status" |
diff --git a/subcmds/sync.py b/subcmds/sync.py index 1ea102c0..c433ce6f 100644 --- a/subcmds/sync.py +++ b/subcmds/sync.py | |||
@@ -53,6 +53,7 @@ except ImportError: | |||
53 | 53 | ||
54 | try: | 54 | try: |
55 | import resource | 55 | import resource |
56 | |||
56 | def _rlimit_nofile(): | 57 | def _rlimit_nofile(): |
57 | return resource.getrlimit(resource.RLIMIT_NOFILE) | 58 | return resource.getrlimit(resource.RLIMIT_NOFILE) |
58 | except ImportError: | 59 | except ImportError: |
@@ -81,13 +82,16 @@ from manifest_xml import GitcManifest | |||
81 | 82 | ||
82 | _ONE_DAY_S = 24 * 60 * 60 | 83 | _ONE_DAY_S = 24 * 60 * 60 |
83 | 84 | ||
85 | |||
84 | class _FetchError(Exception): | 86 | class _FetchError(Exception): |
85 | """Internal error thrown in _FetchHelper() when we don't want stack trace.""" | 87 | """Internal error thrown in _FetchHelper() when we don't want stack trace.""" |
86 | pass | 88 | pass |
87 | 89 | ||
90 | |||
88 | class _CheckoutError(Exception): | 91 | class _CheckoutError(Exception): |
89 | """Internal error thrown in _CheckoutOne() when we don't want stack trace.""" | 92 | """Internal error thrown in _CheckoutOne() when we don't want stack trace.""" |
90 | 93 | ||
94 | |||
91 | class Sync(Command, MirrorSafeCommand): | 95 | class Sync(Command, MirrorSafeCommand): |
92 | jobs = 1 | 96 | jobs = 1 |
93 | common = True | 97 | common = True |
@@ -1044,6 +1048,7 @@ later is required to fix a server side protocol bug. | |||
1044 | file=sys.stderr) | 1048 | file=sys.stderr) |
1045 | sys.exit(1) | 1049 | sys.exit(1) |
1046 | 1050 | ||
1051 | |||
1047 | def _PostRepoUpgrade(manifest, quiet=False): | 1052 | def _PostRepoUpgrade(manifest, quiet=False): |
1048 | wrapper = Wrapper() | 1053 | wrapper = Wrapper() |
1049 | if wrapper.NeedSetupGnuPG(): | 1054 | if wrapper.NeedSetupGnuPG(): |
@@ -1052,6 +1057,7 @@ def _PostRepoUpgrade(manifest, quiet=False): | |||
1052 | if project.Exists: | 1057 | if project.Exists: |
1053 | project.PostRepoUpgrade() | 1058 | project.PostRepoUpgrade() |
1054 | 1059 | ||
1060 | |||
1055 | def _PostRepoFetch(rp, no_repo_verify=False, verbose=False): | 1061 | def _PostRepoFetch(rp, no_repo_verify=False, verbose=False): |
1056 | if rp.HasChanges: | 1062 | if rp.HasChanges: |
1057 | print('info: A new version of repo is available', file=sys.stderr) | 1063 | print('info: A new version of repo is available', file=sys.stderr) |
@@ -1070,6 +1076,7 @@ def _PostRepoFetch(rp, no_repo_verify=False, verbose=False): | |||
1070 | print('repo version %s is current' % rp.work_git.describe(HEAD), | 1076 | print('repo version %s is current' % rp.work_git.describe(HEAD), |
1071 | file=sys.stderr) | 1077 | file=sys.stderr) |
1072 | 1078 | ||
1079 | |||
1073 | def _VerifyTag(project): | 1080 | def _VerifyTag(project): |
1074 | gpg_dir = os.path.expanduser('~/.repoconfig/gnupg') | 1081 | gpg_dir = os.path.expanduser('~/.repoconfig/gnupg') |
1075 | if not os.path.exists(gpg_dir): | 1082 | if not os.path.exists(gpg_dir): |
@@ -1174,6 +1181,8 @@ class _FetchTimes(object): | |||
1174 | # and supporting persistent-http[s]. It cannot change hosts from | 1181 | # and supporting persistent-http[s]. It cannot change hosts from |
1175 | # request to request like the normal transport, the real url | 1182 | # request to request like the normal transport, the real url |
1176 | # is passed during initialization. | 1183 | # is passed during initialization. |
1184 | |||
1185 | |||
1177 | class PersistentTransport(xmlrpc.client.Transport): | 1186 | class PersistentTransport(xmlrpc.client.Transport): |
1178 | def __init__(self, orig_host): | 1187 | def __init__(self, orig_host): |
1179 | self.orig_host = orig_host | 1188 | self.orig_host = orig_host |
diff --git a/subcmds/upload.py b/subcmds/upload.py index 180496fc..bc373b3e 100644 --- a/subcmds/upload.py +++ b/subcmds/upload.py | |||
@@ -33,6 +33,7 @@ else: | |||
33 | 33 | ||
34 | UNUSUAL_COMMIT_THRESHOLD = 5 | 34 | UNUSUAL_COMMIT_THRESHOLD = 5 |
35 | 35 | ||
36 | |||
36 | def _ConfirmManyUploads(multiple_branches=False): | 37 | def _ConfirmManyUploads(multiple_branches=False): |
37 | if multiple_branches: | 38 | if multiple_branches: |
38 | print('ATTENTION: One or more branches has an unusually high number ' | 39 | print('ATTENTION: One or more branches has an unusually high number ' |
@@ -44,17 +45,20 @@ def _ConfirmManyUploads(multiple_branches=False): | |||
44 | answer = input("If you are sure you intend to do this, type 'yes': ").strip() | 45 | answer = input("If you are sure you intend to do this, type 'yes': ").strip() |
45 | return answer == "yes" | 46 | return answer == "yes" |
46 | 47 | ||
48 | |||
47 | def _die(fmt, *args): | 49 | def _die(fmt, *args): |
48 | msg = fmt % args | 50 | msg = fmt % args |
49 | print('error: %s' % msg, file=sys.stderr) | 51 | print('error: %s' % msg, file=sys.stderr) |
50 | sys.exit(1) | 52 | sys.exit(1) |
51 | 53 | ||
54 | |||
52 | def _SplitEmails(values): | 55 | def _SplitEmails(values): |
53 | result = [] | 56 | result = [] |
54 | for value in values: | 57 | for value in values: |
55 | result.extend([s.strip() for s in value.split(',')]) | 58 | result.extend([s.strip() for s in value.split(',')]) |
56 | return result | 59 | return result |
57 | 60 | ||
61 | |||
58 | class Upload(InteractiveCommand): | 62 | class Upload(InteractiveCommand): |
59 | common = True | 63 | common = True |
60 | helpSummary = "Upload changes for code review" | 64 | helpSummary = "Upload changes for code review" |
diff --git a/subcmds/version.py b/subcmds/version.py index 761172b7..92316549 100644 --- a/subcmds/version.py +++ b/subcmds/version.py | |||
@@ -20,6 +20,7 @@ from command import Command, MirrorSafeCommand | |||
20 | from git_command import git, RepoSourceVersion, user_agent | 20 | from git_command import git, RepoSourceVersion, user_agent |
21 | from git_refs import HEAD | 21 | from git_refs import HEAD |
22 | 22 | ||
23 | |||
23 | class Version(Command, MirrorSafeCommand): | 24 | class Version(Command, MirrorSafeCommand): |
24 | wrapper_version = None | 25 | wrapper_version = None |
25 | wrapper_path = None | 26 | wrapper_path = None |
diff --git a/tests/test_git_config.py b/tests/test_git_config.py index b735f27f..6aa6b381 100644 --- a/tests/test_git_config.py +++ b/tests/test_git_config.py | |||
@@ -23,14 +23,17 @@ import unittest | |||
23 | 23 | ||
24 | import git_config | 24 | import git_config |
25 | 25 | ||
26 | |||
26 | def fixture(*paths): | 27 | def fixture(*paths): |
27 | """Return a path relative to test/fixtures. | 28 | """Return a path relative to test/fixtures. |
28 | """ | 29 | """ |
29 | return os.path.join(os.path.dirname(__file__), 'fixtures', *paths) | 30 | return os.path.join(os.path.dirname(__file__), 'fixtures', *paths) |
30 | 31 | ||
32 | |||
31 | class GitConfigUnitTest(unittest.TestCase): | 33 | class GitConfigUnitTest(unittest.TestCase): |
32 | """Tests the GitConfig class. | 34 | """Tests the GitConfig class. |
33 | """ | 35 | """ |
36 | |||
34 | def setUp(self): | 37 | def setUp(self): |
35 | """Create a GitConfig object using the test.gitconfig fixture. | 38 | """Create a GitConfig object using the test.gitconfig fixture. |
36 | """ | 39 | """ |
@@ -68,5 +71,6 @@ class GitConfigUnitTest(unittest.TestCase): | |||
68 | val = config.GetString('empty') | 71 | val = config.GetString('empty') |
69 | self.assertEqual(val, None) | 72 | self.assertEqual(val, None) |
70 | 73 | ||
74 | |||
71 | if __name__ == '__main__': | 75 | if __name__ == '__main__': |
72 | unittest.main() | 76 | unittest.main() |
diff --git a/tests/test_wrapper.py b/tests/test_wrapper.py index 8ef8d48d..38def512 100644 --- a/tests/test_wrapper.py +++ b/tests/test_wrapper.py | |||
@@ -23,14 +23,17 @@ import unittest | |||
23 | 23 | ||
24 | import wrapper | 24 | import wrapper |
25 | 25 | ||
26 | |||
26 | def fixture(*paths): | 27 | def fixture(*paths): |
27 | """Return a path relative to tests/fixtures. | 28 | """Return a path relative to tests/fixtures. |
28 | """ | 29 | """ |
29 | return os.path.join(os.path.dirname(__file__), 'fixtures', *paths) | 30 | return os.path.join(os.path.dirname(__file__), 'fixtures', *paths) |
30 | 31 | ||
32 | |||
31 | class RepoWrapperUnitTest(unittest.TestCase): | 33 | class RepoWrapperUnitTest(unittest.TestCase): |
32 | """Tests helper functions in the repo wrapper | 34 | """Tests helper functions in the repo wrapper |
33 | """ | 35 | """ |
36 | |||
34 | def setUp(self): | 37 | def setUp(self): |
35 | """Load the wrapper module every time | 38 | """Load the wrapper module every time |
36 | """ | 39 | """ |
@@ -76,5 +79,6 @@ class RepoWrapperUnitTest(unittest.TestCase): | |||
76 | self.assertEqual(self.wrapper.gitc_parse_clientdir('/gitc/manifest-rw/'), None) | 79 | self.assertEqual(self.wrapper.gitc_parse_clientdir('/gitc/manifest-rw/'), None) |
77 | self.assertEqual(self.wrapper.gitc_parse_clientdir('/test/usr/local/google/gitc/'), None) | 80 | self.assertEqual(self.wrapper.gitc_parse_clientdir('/test/usr/local/google/gitc/'), None) |
78 | 81 | ||
82 | |||
79 | if __name__ == '__main__': | 83 | if __name__ == '__main__': |
80 | unittest.main() | 84 | unittest.main() |
@@ -27,7 +27,10 @@ import os | |||
27 | def WrapperPath(): | 27 | def WrapperPath(): |
28 | return os.path.join(os.path.dirname(__file__), 'repo') | 28 | return os.path.join(os.path.dirname(__file__), 'repo') |
29 | 29 | ||
30 | |||
30 | _wrapper_module = None | 31 | _wrapper_module = None |
32 | |||
33 | |||
31 | def Wrapper(): | 34 | def Wrapper(): |
32 | global _wrapper_module | 35 | global _wrapper_module |
33 | if not _wrapper_module: | 36 | if not _wrapper_module: |