diff --git a/git_cl.py b/git_cl.py index 912a519631..797cbc6722 100755 --- a/git_cl.py +++ b/git_cl.py @@ -22,6 +22,7 @@ import multiprocessing import optparse import os import re +import shutil import stat import sys import textwrap @@ -187,7 +188,7 @@ def confirm_or_exit(prefix='', action='confirm'): """Asks user to press enter to continue or press Ctrl+C to abort.""" if not prefix or prefix.endswith('\n'): mid = 'Press' - elif prefix.endswith('.'): + elif prefix.endswith('.') or prefix.endswith('?'): mid = ' Press' elif prefix.endswith(' '): mid = 'press' @@ -3442,6 +3443,70 @@ def GetRietveldCodereviewSettingsInteractively(): 'run-post-upload-hook', False) +def _ensure_default_gitcookies_path(configured_path, default_path): + assert configured_path + if configured_path == default_path: + print('git is already configured to use your .gitcookies from %s' % + configured_path) + return + + print('WARNING: you have configured custom path to .gitcookies: %s\n' + 'Gerrit and other depot_tools expect .gitcookies at %s\n' % + (configured_path, default_path)) + + if not os.path.exists(configured_path): + print('However, your configured .gitcookies file is missing.') + confirm_or_exit('Reconfigure git to use default .gitcookies?', + action='reconfigure') + RunGit(['config', '--global', 'http.cookiefile', default_path]) + return + + if os.path.exists(default_path): + print('WARNING: default .gitcookies file already exists %s' % default_path) + DieWithError('Please delete %s manually and re-run git cl creds-check' % + default_path) + + confirm_or_exit('Move existing .gitcookies to default location?', + action='move') + shutil.move(configured_path, default_path) + RunGit(['config', '--global', 'http.cookiefile', default_path]) + print('Moved and reconfigured git to use .gitcookies from %s' % default_path) + + +def _configure_gitcookies_path(gitcookies_path): + netrc_path = gerrit_util.CookiesAuthenticator.get_netrc_path() + if os.path.exists(netrc_path): + print('You seem to be using outdated .netrc for git credentials: %s' % + netrc_path) + print('This tool will guide you through setting up recommended ' + '.gitcookies store for git credentials.\n' + '\n' + 'IMPORTANT: If something goes wrong and you decide to go back, do:\n' + ' git config --global --unset http.cookiefile\n' + ' mv %s %s.backup\n\n' % (gitcookies_path, gitcookies_path)) + confirm_or_exit(action='setup .gitcookies') + RunGit(['config', '--global', 'http.cookiefile', gitcookies_path]) + print('Configured git to use .gitcookies from %s' % gitcookies_path) + + +def CMDcreds_check(parser, args): + """Checks credentials and suggests changes.""" + _, _ = parser.parse_args(args) + + if gerrit_util.GceAuthenticator.is_gce(): + DieWithError('this command is not designed for GCE, are you on a bot?') + + gitcookies_path = gerrit_util.CookiesAuthenticator.get_gitcookies_path() + configured_gitcookies_path = RunGitSilent( + ['config', '--global', 'http.cookiefile']).strip() + if configured_gitcookies_path: + _ensure_default_gitcookies_path(configured_gitcookies_path, gitcookies_path) + else: + _configure_gitcookies_path(gitcookies_path) + # TODO(tandrii): finish this. + return 0 + + @subcommand.usage('[repo root containing codereview.settings]') def CMDconfig(parser, args): """Edits configuration for this tree.""" diff --git a/tests/git_cl_test.py b/tests/git_cl_test.py index dbcb26af4b..d112f0bd42 100755 --- a/tests/git_cl_test.py +++ b/tests/git_cl_test.py @@ -2933,6 +2933,56 @@ class TestGitCl(TestCase): self.assertEqual(cl.GetDescription(), 'desc1') # cache hit. self.assertEqual(cl.GetDescription(force=True), 'desc2') + def _common_creds_check_mocks(self): + def exists_mock(path): + dirname = os.path.dirname(path) + if dirname == os.path.expanduser('~'): + dirname = '~' + base = os.path.basename(path) + if base in ('.netrc', '.gitcookies'): + return self._mocked_call('os.path.exists', '%s/%s' % (dirname, base)) + # git cl also checks for existence other files not relevant to this test. + return None + self.mock(os.path, 'exists', exists_mock) + self.mock(sys, 'stdout', StringIO.StringIO()) + + def test_creds_check_gitcookies_not_configured(self): + self._common_creds_check_mocks() + self.calls = [ + ((['git', 'config', '--global', 'http.cookiefile'],), CERR1), + (('os.path.exists', '~/.netrc'), True), + (('ask_for_data', 'Press Enter to setup .gitcookies, ' + 'or Ctrl+C to abort'), ''), + ((['git', 'config', '--global', 'http.cookiefile', + os.path.expanduser('~/.gitcookies')], ), ''), + ] + self.assertEqual(0, git_cl.main(['creds-check'])) + self.assertRegexpMatches( + sys.stdout.getvalue(), + '^You seem to be using outdated .netrc for git credentials:') + self.assertRegexpMatches( + sys.stdout.getvalue(), + '\nConfigured git to use .gitcookies from') + + def test_creds_check_gitcookies_configured_custom_broken(self): + self._common_creds_check_mocks() + self.calls = [ + ((['git', 'config', '--global', 'http.cookiefile'],), + '/custom/.gitcookies'), + (('os.path.exists', '/custom/.gitcookies'), False), + (('ask_for_data', 'Reconfigure git to use default .gitcookies? ' + 'Press Enter to reconfigure, or Ctrl+C to abort'), ''), + ((['git', 'config', '--global', 'http.cookiefile', + os.path.expanduser('~/.gitcookies')], ), ''), + ] + self.assertEqual(0, git_cl.main(['creds-check'])) + self.assertRegexpMatches( + sys.stdout.getvalue(), + 'WARNING: you have configured custom path to .gitcookies: ') + self.assertRegexpMatches( + sys.stdout.getvalue(), + 'However, your configured .gitcookies file is missing.') + if __name__ == '__main__': logging.basicConfig( level=logging.DEBUG if '-v' in sys.argv else logging.ERROR)