|
|
@@ -22,6 +22,7 @@ import tempfile
|
|
|
from signal import SIGTERM
|
|
|
|
|
|
from error import GitError
|
|
|
+from git_refs import HEAD
|
|
|
import platform_utils
|
|
|
from repo_trace import REPO_TRACE, IsTrace, Trace
|
|
|
from wrapper import Wrapper
|
|
|
@@ -99,50 +100,72 @@ class _GitCall(object):
|
|
|
git = _GitCall()
|
|
|
|
|
|
|
|
|
-_user_agent = None
|
|
|
+def RepoSourceVersion():
|
|
|
+ """Return the version of the repo.git tree."""
|
|
|
+ ver = getattr(RepoSourceVersion, 'version', None)
|
|
|
|
|
|
-def RepoUserAgent():
|
|
|
- """Return a User-Agent string suitable for HTTP-like services.
|
|
|
+ # We avoid GitCommand so we don't run into circular deps -- GitCommand needs
|
|
|
+ # to initialize version info we provide.
|
|
|
+ if ver is None:
|
|
|
+ env = GitCommand._GetBasicEnv()
|
|
|
|
|
|
- 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:]
|
|
|
+ proj = os.path.dirname(os.path.abspath(__file__))
|
|
|
+ env[GIT_DIR] = os.path.join(proj, '.git')
|
|
|
+
|
|
|
+ p = subprocess.Popen([GIT, 'describe', HEAD], stdout=subprocess.PIPE,
|
|
|
+ env=env)
|
|
|
+ if p.wait() == 0:
|
|
|
+ ver = p.stdout.read().strip().decode('utf-8')
|
|
|
+ if ver.startswith('v'):
|
|
|
+ ver = ver[1:]
|
|
|
else:
|
|
|
- repo_version = 'unknown'
|
|
|
+ ver = 'unknown'
|
|
|
+ setattr(RepoSourceVersion, 'version', ver)
|
|
|
|
|
|
- _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 ver
|
|
|
|
|
|
- return _user_agent
|
|
|
|
|
|
+class UserAgent(object):
|
|
|
+ """Mange User-Agent settings when talking to external services
|
|
|
+
|
|
|
+ We follow the style as documented here:
|
|
|
+ https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent
|
|
|
+ """
|
|
|
+
|
|
|
+ _os = None
|
|
|
+ _repo_ua = None
|
|
|
+
|
|
|
+ @property
|
|
|
+ def os(self):
|
|
|
+ """The operating system name."""
|
|
|
+ if self._os is None:
|
|
|
+ os_name = sys.platform
|
|
|
+ if os_name.lower().startswith('linux'):
|
|
|
+ os_name = 'Linux'
|
|
|
+ elif os_name == 'win32':
|
|
|
+ os_name = 'Win32'
|
|
|
+ elif os_name == 'cygwin':
|
|
|
+ os_name = 'Cygwin'
|
|
|
+ elif os_name == 'darwin':
|
|
|
+ os_name = 'Darwin'
|
|
|
+ self._os = os_name
|
|
|
+
|
|
|
+ return self._os
|
|
|
+
|
|
|
+ @property
|
|
|
+ def repo(self):
|
|
|
+ """The UA when connecting directly from repo."""
|
|
|
+ if self._repo_ua is None:
|
|
|
+ py_version = sys.version_info
|
|
|
+ self._repo_ua = 'git-repo/%s (%s) git/%s Python/%d.%d.%d' % (
|
|
|
+ RepoSourceVersion(),
|
|
|
+ self.os,
|
|
|
+ git.version_tuple().full,
|
|
|
+ py_version.major, py_version.minor, py_version.micro)
|
|
|
+
|
|
|
+ return self._repo_ua
|
|
|
+
|
|
|
+user_agent = UserAgent()
|
|
|
|
|
|
def git_require(min_version, fail=False, msg=''):
|
|
|
git_version = git.version_tuple()
|
|
|
@@ -171,17 +194,7 @@ class GitCommand(object):
|
|
|
ssh_proxy = False,
|
|
|
cwd = None,
|
|
|
gitdir = None):
|
|
|
- env = os.environ.copy()
|
|
|
-
|
|
|
- for key in [REPO_TRACE,
|
|
|
- GIT_DIR,
|
|
|
- 'GIT_ALTERNATE_OBJECT_DIRECTORIES',
|
|
|
- 'GIT_OBJECT_DIRECTORY',
|
|
|
- 'GIT_WORK_TREE',
|
|
|
- 'GIT_GRAFT_FILE',
|
|
|
- 'GIT_INDEX_FILE']:
|
|
|
- if key in env:
|
|
|
- del env[key]
|
|
|
+ env = self._GetBasicEnv()
|
|
|
|
|
|
# If we are not capturing std* then need to print it.
|
|
|
self.tee = {'stdout': not capture_stdout, 'stderr': not capture_stderr}
|
|
|
@@ -273,6 +286,23 @@ class GitCommand(object):
|
|
|
self.process = p
|
|
|
self.stdin = p.stdin
|
|
|
|
|
|
+ @staticmethod
|
|
|
+ def _GetBasicEnv():
|
|
|
+ """Return a basic env for running git under.
|
|
|
+
|
|
|
+ This is guaranteed to be side-effect free.
|
|
|
+ """
|
|
|
+ env = os.environ.copy()
|
|
|
+ for key in (REPO_TRACE,
|
|
|
+ GIT_DIR,
|
|
|
+ 'GIT_ALTERNATE_OBJECT_DIRECTORIES',
|
|
|
+ 'GIT_OBJECT_DIRECTORY',
|
|
|
+ 'GIT_WORK_TREE',
|
|
|
+ 'GIT_GRAFT_FILE',
|
|
|
+ 'GIT_INDEX_FILE'):
|
|
|
+ env.pop(key, None)
|
|
|
+ return env
|
|
|
+
|
|
|
def Wait(self):
|
|
|
try:
|
|
|
p = self.process
|