move UserAgent to git_command for wider user

We can't import the main module, so move the UserAgent helper out of
it and into the git_command module so it can be used in more places.

Bug: https://crbug.com/gerrit/11144
Change-Id: I8093c8a20bd1dc7d612d0e2a85180341817c0d86
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/231057
Tested-by: Mike Frysinger <vapier@google.com>
Reviewed-by: David Pursehouse <dpursehouse@collab.net>
diff --git a/git_command.py b/git_command.py
index 6742303..32dcde0 100644
--- a/git_command.py
+++ b/git_command.py
@@ -98,6 +98,52 @@
     return fun
 git = _GitCall()
 
+
+_user_agent = None
+
+def RepoUserAgent():
+  """Return a User-Agent string suitable for HTTP-like services.
+
+  We follow the style as documented here:
+  https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent
+  """
+  global _user_agent
+
+  if _user_agent is None:
+    py_version = sys.version_info
+
+    os_name = sys.platform
+    if os_name == 'linux2':
+      os_name = 'Linux'
+    elif os_name == 'win32':
+      os_name = 'Win32'
+    elif os_name == 'cygwin':
+      os_name = 'Cygwin'
+    elif os_name == 'darwin':
+      os_name = 'Darwin'
+
+    p = GitCommand(
+        None, ['describe', 'HEAD'],
+        cwd=os.path.dirname(__file__),
+        capture_stdout=True)
+    if p.Wait() == 0:
+      repo_version = p.stdout
+      if repo_version and repo_version[-1] == '\n':
+        repo_version = repo_version[0:-1]
+      if repo_version and repo_version[0] == 'v':
+        repo_version = repo_version[1:]
+    else:
+      repo_version = 'unknown'
+
+    _user_agent = 'git-repo/%s (%s) git/%s Python/%d.%d.%d' % (
+        repo_version,
+        os_name,
+        git.version_tuple().full,
+        py_version.major, py_version.minor, py_version.micro)
+
+  return _user_agent
+
+
 def git_require(min_version, fail=False, msg=''):
   git_version = git.version_tuple()
   if min_version <= git_version:
diff --git a/main.py b/main.py
index 2ab79b5..0b19aeb 100755
--- a/main.py
+++ b/main.py
@@ -46,7 +46,7 @@
 from color import SetDefaultColoring
 import event_log
 from repo_trace import SetTrace
-from git_command import git, GitCommand
+from git_command import git, GitCommand, RepoUserAgent
 from git_config import init_ssh, close_ssh
 from command import InteractiveCommand
 from command import MirrorSafeCommand
@@ -244,10 +244,6 @@
     return result
 
 
-def _MyRepoPath():
-  return os.path.dirname(__file__)
-
-
 def _CheckWrapperVersion(ver, repo_path):
   if not repo_path:
     repo_path = '~/bin/repo'
@@ -299,51 +295,13 @@
       continue
     i += 1
 
-_user_agent = None
-
-def _UserAgent():
-  global _user_agent
-
-  if _user_agent is None:
-    py_version = sys.version_info
-
-    os_name = sys.platform
-    if os_name == 'linux2':
-      os_name = 'Linux'
-    elif os_name == 'win32':
-      os_name = 'Win32'
-    elif os_name == 'cygwin':
-      os_name = 'Cygwin'
-    elif os_name == 'darwin':
-      os_name = 'Darwin'
-
-    p = GitCommand(
-      None, ['describe', 'HEAD'],
-      cwd = _MyRepoPath(),
-      capture_stdout = True)
-    if p.Wait() == 0:
-      repo_version = p.stdout
-      if len(repo_version) > 0 and repo_version[-1] == '\n':
-        repo_version = repo_version[0:-1]
-      if len(repo_version) > 0 and repo_version[0] == 'v':
-        repo_version = repo_version[1:]
-    else:
-      repo_version = 'unknown'
-
-    _user_agent = 'git-repo/%s (%s) git/%s Python/%d.%d.%d' % (
-      repo_version,
-      os_name,
-      git.version_tuple().full,
-      py_version[0], py_version[1], py_version[2])
-  return _user_agent
-
 class _UserAgentHandler(urllib.request.BaseHandler):
   def http_request(self, req):
-    req.add_header('User-Agent', _UserAgent())
+    req.add_header('User-Agent', RepoUserAgent())
     return req
 
   def https_request(self, req):
-    req.add_header('User-Agent', _UserAgent())
+    req.add_header('User-Agent', RepoUserAgent())
     return req
 
 def _AddPasswordFromUserInput(handler, msg, req):
diff --git a/tests/test_git_command.py b/tests/test_git_command.py
index 928eb40..4d65d3c 100644
--- a/tests/test_git_command.py
+++ b/tests/test_git_command.py
@@ -18,6 +18,7 @@
 
 from __future__ import print_function
 
+import re
 import unittest
 
 import git_command
@@ -47,3 +48,15 @@
     self.assertLess(ver, (9999, 9999, 9999))
 
     self.assertNotEqual('', ver.full)
+
+
+class RepoUserAgentUnitTest(unittest.TestCase):
+  """Tests the RepoUserAgent function."""
+
+  def test_smoke(self):
+    """Make sure it returns something useful."""
+    ua = git_command.RepoUserAgent()
+    # We can't dive too deep because of OS/tool differences, but we can check
+    # the general form.
+    m = re.match(r'^git-repo/[^ ]+ ([^ ]+) git/[^ ]+ Python/[0-9.]+', ua)
+    self.assertIsNotNone(m)