diff options
-rw-r--r-- | git_command.py | 3 | ||||
-rw-r--r-- | git_config.py | 14 | ||||
-rw-r--r-- | git_superproject.py | 81 | ||||
-rw-r--r-- | subcmds/sync.py | 11 |
4 files changed, 98 insertions, 11 deletions
diff --git a/git_command.py b/git_command.py index 04953f38..95db91f2 100644 --- a/git_command.py +++ b/git_command.py | |||
@@ -75,7 +75,8 @@ def RepoSourceVersion(): | |||
75 | proj = os.path.dirname(os.path.abspath(__file__)) | 75 | proj = os.path.dirname(os.path.abspath(__file__)) |
76 | env[GIT_DIR] = os.path.join(proj, '.git') | 76 | env[GIT_DIR] = os.path.join(proj, '.git') |
77 | result = subprocess.run([GIT, 'describe', HEAD], stdout=subprocess.PIPE, | 77 | result = subprocess.run([GIT, 'describe', HEAD], stdout=subprocess.PIPE, |
78 | encoding='utf-8', env=env, check=False) | 78 | stderr=subprocess.DEVNULL, encoding='utf-8', |
79 | env=env, check=False) | ||
79 | if result.returncode == 0: | 80 | if result.returncode == 0: |
80 | ver = result.stdout.strip() | 81 | ver = result.stdout.strip() |
81 | if ver.startswith('v'): | 82 | if ver.startswith('v'): |
diff --git a/git_config.py b/git_config.py index 978f6a59..3eaf201c 100644 --- a/git_config.py +++ b/git_config.py | |||
@@ -65,6 +65,15 @@ class GitConfig(object): | |||
65 | 65 | ||
66 | _USER_CONFIG = '~/.gitconfig' | 66 | _USER_CONFIG = '~/.gitconfig' |
67 | 67 | ||
68 | _ForSystem = None | ||
69 | _SYSTEM_CONFIG = '/etc/gitconfig' | ||
70 | |||
71 | @classmethod | ||
72 | def ForSystem(cls): | ||
73 | if cls._ForSystem is None: | ||
74 | cls._ForSystem = cls(configfile=cls._SYSTEM_CONFIG) | ||
75 | return cls._ForSystem | ||
76 | |||
68 | @classmethod | 77 | @classmethod |
69 | def ForUser(cls): | 78 | def ForUser(cls): |
70 | if cls._ForUser is None: | 79 | if cls._ForUser is None: |
@@ -356,7 +365,10 @@ class GitConfig(object): | |||
356 | return c | 365 | return c |
357 | 366 | ||
358 | def _do(self, *args): | 367 | def _do(self, *args): |
359 | command = ['config', '--file', self.file, '--includes'] | 368 | if self.file == self._SYSTEM_CONFIG: |
369 | command = ['config', '--system', '--includes'] | ||
370 | else: | ||
371 | command = ['config', '--file', self.file, '--includes'] | ||
360 | command.extend(args) | 372 | command.extend(args) |
361 | 373 | ||
362 | p = GitCommand(None, | 374 | p = GitCommand(None, |
diff --git a/git_superproject.py b/git_superproject.py index 0c477060..2a47847a 100644 --- a/git_superproject.py +++ b/git_superproject.py | |||
@@ -23,11 +23,14 @@ Examples: | |||
23 | """ | 23 | """ |
24 | 24 | ||
25 | import hashlib | 25 | import hashlib |
26 | import functools | ||
26 | import os | 27 | import os |
27 | import sys | 28 | import sys |
29 | import time | ||
28 | from typing import NamedTuple | 30 | from typing import NamedTuple |
29 | 31 | ||
30 | from git_command import git_require, GitCommand | 32 | from git_command import git_require, GitCommand |
33 | from git_config import RepoConfig | ||
31 | from git_refs import R_HEADS | 34 | from git_refs import R_HEADS |
32 | from manifest_xml import LOCAL_MANIFEST_GROUP_PREFIX | 35 | from manifest_xml import LOCAL_MANIFEST_GROUP_PREFIX |
33 | 36 | ||
@@ -343,3 +346,81 @@ class Superproject(object): | |||
343 | 346 | ||
344 | manifest_path = self._WriteManfiestFile() | 347 | manifest_path = self._WriteManfiestFile() |
345 | return UpdateProjectsResult(manifest_path, False) | 348 | return UpdateProjectsResult(manifest_path, False) |
349 | |||
350 | |||
351 | @functools.lru_cache(maxsize=None) | ||
352 | def _UseSuperprojectFromConfiguration(): | ||
353 | """Returns the user choice of whether to use superproject.""" | ||
354 | user_cfg = RepoConfig.ForUser() | ||
355 | system_cfg = RepoConfig.ForSystem() | ||
356 | time_now = int(time.time()) | ||
357 | |||
358 | user_value = user_cfg.GetBoolean('repo.superprojectChoice') | ||
359 | if user_value is not None: | ||
360 | user_expiration = user_cfg.GetInt('repo.superprojectChoiceExpire') | ||
361 | if user_expiration is not None and (user_expiration <= 0 or user_expiration >= time_now): | ||
362 | # TODO(b/190688390) - Remove prompt when we are comfortable with the new | ||
363 | # default value. | ||
364 | print(('You are currently enrolled in Git submodules experiment ' | ||
365 | '(go/android-submodules-quickstart). Use --no-use-superproject ' | ||
366 | 'to override.\n'), file=sys.stderr) | ||
367 | return user_value | ||
368 | |||
369 | # We don't have an unexpired choice, ask for one. | ||
370 | system_value = system_cfg.GetBoolean('repo.superprojectChoice') | ||
371 | if system_value: | ||
372 | # The system configuration is proposing that we should enable the | ||
373 | # use of superproject. Present this to user for confirmation if we | ||
374 | # are on a TTY, or, when we are not on a TTY, accept the system | ||
375 | # default for this time only. | ||
376 | # | ||
377 | # TODO(b/190688390) - Remove prompt when we are comfortable with the new | ||
378 | # default value. | ||
379 | prompt = ('Repo can now use Git submodules (go/android-submodules-quickstart) ' | ||
380 | 'instead of manifests to represent the state of the Android ' | ||
381 | 'superproject, which results in faster syncs and better atomicity.\n\n') | ||
382 | if sys.stdout.isatty(): | ||
383 | prompt += 'Would you like to opt in for two weeks (y/N)? ' | ||
384 | response = input(prompt).lower() | ||
385 | time_choiceexpire = time_now + (86400 * 14) | ||
386 | if response in ('y', 'yes'): | ||
387 | userchoice = True | ||
388 | elif response in ('a', 'always'): | ||
389 | userchoice = True | ||
390 | time_choiceexpire = 0 | ||
391 | elif response == 'never': | ||
392 | userchoice = False | ||
393 | time_choiceexpire = 0 | ||
394 | elif response in ('n', 'no'): | ||
395 | userchoice = False | ||
396 | else: | ||
397 | # Unrecognized user response, assume the intention was no, but | ||
398 | # only for 2 hours instead of 2 weeks to balance between not | ||
399 | # being overly pushy while still retain the opportunity to | ||
400 | # enroll. | ||
401 | userchoice = False | ||
402 | time_choiceexpire = time_now + 7200 | ||
403 | |||
404 | user_cfg.SetString('repo.superprojectChoiceExpire', str(time_choiceexpire)) | ||
405 | user_cfg.SetBoolean('repo.superprojectChoice', userchoice) | ||
406 | |||
407 | return userchoice | ||
408 | else: | ||
409 | print('Accepting once since we are not on a TTY', file=sys.stderr) | ||
410 | return True | ||
411 | |||
412 | # For all other cases, we would not use superproject by default. | ||
413 | return False | ||
414 | |||
415 | |||
416 | def UseSuperproject(opt, manifest): | ||
417 | """Returns a boolean if use-superproject option is enabled.""" | ||
418 | |||
419 | if opt.use_superproject is not None: | ||
420 | return opt.use_superproject | ||
421 | else: | ||
422 | client_value = manifest.manifestProject.config.GetBoolean('repo.superproject') | ||
423 | if client_value is not None: | ||
424 | return client_value | ||
425 | else: | ||
426 | return _UseSuperprojectFromConfiguration() | ||
diff --git a/subcmds/sync.py b/subcmds/sync.py index 8d89cf72..8defc932 100644 --- a/subcmds/sync.py +++ b/subcmds/sync.py | |||
@@ -278,16 +278,9 @@ later is required to fix a server side protocol bug. | |||
278 | branch = branch[len(R_HEADS):] | 278 | branch = branch[len(R_HEADS):] |
279 | return branch | 279 | return branch |
280 | 280 | ||
281 | def _UseSuperproject(self, opt): | ||
282 | """Returns True if use-superproject option is enabled""" | ||
283 | if opt.use_superproject is not None: | ||
284 | return opt.use_superproject | ||
285 | else: | ||
286 | return self.manifest.manifestProject.config.GetBoolean('repo.superproject') | ||
287 | |||
288 | def _GetCurrentBranchOnly(self, opt): | 281 | def _GetCurrentBranchOnly(self, opt): |
289 | """Returns True if current-branch or use-superproject options are enabled.""" | 282 | """Returns True if current-branch or use-superproject options are enabled.""" |
290 | return opt.current_branch_only or self._UseSuperproject(opt) | 283 | return opt.current_branch_only or git_superproject.UseSuperproject(opt, self.manifest) |
291 | 284 | ||
292 | def _UpdateProjectsRevisionId(self, opt, args, load_local_manifests): | 285 | def _UpdateProjectsRevisionId(self, opt, args, load_local_manifests): |
293 | """Update revisionId of every project with the SHA from superproject. | 286 | """Update revisionId of every project with the SHA from superproject. |
@@ -964,7 +957,7 @@ later is required to fix a server side protocol bug. | |||
964 | self._UpdateManifestProject(opt, mp, manifest_name) | 957 | self._UpdateManifestProject(opt, mp, manifest_name) |
965 | 958 | ||
966 | load_local_manifests = not self.manifest.HasLocalManifests | 959 | load_local_manifests = not self.manifest.HasLocalManifests |
967 | if self._UseSuperproject(opt): | 960 | if git_superproject.UseSuperproject(opt, self.manifest): |
968 | new_manifest_name = self._UpdateProjectsRevisionId(opt, args, load_local_manifests) | 961 | new_manifest_name = self._UpdateProjectsRevisionId(opt, args, load_local_manifests) |
969 | if not new_manifest_name: | 962 | if not new_manifest_name: |
970 | manifest_name = new_manifest_name | 963 | manifest_name = new_manifest_name |