Browse Source

Merge "get_remote_url(): honor any "url.<base>.insteadOf" config setting"

tags/1.0.0
Jenkins 4 years ago
parent
commit
80f7cd2c0a
2 changed files with 64 additions and 0 deletions
  1. 52
    0
      git_review/cmd.py
  2. 12
    0
      git_review/tests/test_git_review.py

+ 52
- 0
git_review/cmd.py View File

@@ -62,6 +62,7 @@ _branch_name = None
62 62
 _has_color = None
63 63
 _use_color = None
64 64
 _orig_head = None
65
+_rewrites = None
65 66
 
66 67
 
67 68
 class colors:
@@ -385,9 +386,60 @@ def add_remote(scheme, hostname, port, project, remote):
385 386
         print()
386 387
 
387 388
 
389
+def populate_rewrites():
390
+    """Populate the global _rewrites map based on the output of "git-config".
391
+    """
392
+
393
+    cmd = ['git', 'config', '--list']
394
+    out = run_command_exc(CommandFailed, *cmd).strip()
395
+
396
+    global _rewrites
397
+    _rewrites = {}
398
+
399
+    for entry in out.splitlines():
400
+        key, _, value = entry.partition('=')
401
+        key = key.lower()
402
+
403
+        if key.startswith('url.') and key.endswith('.insteadof'):
404
+            rewrite = key[4:-10]
405
+            if rewrite:
406
+                _rewrites[value] = rewrite
407
+
408
+
409
+def alias_url(url):
410
+    """Expand a remote URL. Use the global map _rewrites to replace the
411
+    longest match with its equivalent.
412
+    """
413
+
414
+    if _rewrites is None:
415
+        populate_rewrites()
416
+
417
+    longest = None
418
+    for alias in _rewrites:
419
+        if (url.startswith(alias)
420
+                and (longest is None or len(longest) < len(alias))):
421
+            longest = alias
422
+
423
+    if longest:
424
+        url = url.replace(longest, _rewrites[longest])
425
+    return url
426
+
427
+
388 428
 def get_remote_url(remote):
429
+    """Retrieve the remote URL. Read the configuration to expand the URL of a
430
+    remote repository taking into account any "url.<base>.insteadOf" config
431
+    setting.
432
+
433
+    TODO: Replace current code with "git ls-remote --get-url" when the
434
+    continuous builders will support it. It requires the use of Git v1.7.5
435
+    or above. Beware that option "--get-url" of "git-ls-remote" is
436
+    supported since v1.7.5 (see https://github.com/git/git/commit/45781ad) but
437
+    was not properly documented until v1.7.12.2.
438
+    """
439
+
389 440
     url = git_config_get_value('remote.%s' % remote, 'url', '')
390 441
     push_url = git_config_get_value('remote.%s' % remote, 'pushurl', url)
442
+    push_url = alias_url(push_url)
391 443
     if VERBOSE:
392 444
         print("Found origin Push URL:", push_url)
393 445
     return push_url

+ 12
- 0
git_review/tests/test_git_review.py View File

@@ -331,6 +331,18 @@ class GitReviewTestCase(tests.BaseGitReviewTestCase):
331 331
         remote = self._run_git('remote').strip()
332 332
         self.assertEqual('remote-file', remote)
333 333
 
334
+    def test_config_instead_of_honored(self):
335
+        self._run_git('remote', 'add', 'alias', 'test_project_url')
336
+
337
+        exc = self.assertRaises(Exception, self._run_git_review,
338
+                                '-l', '-r', 'alias')
339
+        self.assertIn("'test_project_url' does not appear to be a git "
340
+                      "repository", exc.args[0])
341
+
342
+        self._run_git('config', '--add', 'url.%s.insteadof' % self.project_uri,
343
+                      'test_project_url')
344
+        self._run_git_review('-l', '-r', 'alias')
345
+
334 346
 
335 347
 class HttpGitReviewTestCase(tests.HttpMixin, GitReviewTestCase):
336 348
     """Class for the git-review tests over HTTP(S)."""

Loading…
Cancel
Save