mirror of
https://gerrit.googlesource.com/git-repo
synced 2024-12-21 07:16:21 +00:00
Extract env building into a testable helper.
Previously env dict building was untested and mixed with other mutative actions. Extract the dict building into a dedicated function and author tests to ensure the functionality is working as expected. BUG: b/255376186 BUG: https://crbug.com/gerrit/16247 Change-Id: I0c88e53eb285c5c3fb27f8e6b3a903aedb8e02a8 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/351874 Reviewed-by: LaMont Jones <lamontjones@google.com> Tested-by: Sam Saccone <samccone@google.com>
This commit is contained in:
parent
d3cadf1856
commit
d686365449
@ -16,6 +16,7 @@ import functools
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import subprocess
|
import subprocess
|
||||||
|
from typing import Any, Optional
|
||||||
|
|
||||||
from error import GitError
|
from error import GitError
|
||||||
from git_refs import HEAD
|
from git_refs import HEAD
|
||||||
@ -157,23 +158,19 @@ def git_require(min_version, fail=False, msg=''):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
class GitCommand(object):
|
def _build_env(
|
||||||
"""Wrapper around a single git invocation."""
|
_kwargs_only=(),
|
||||||
|
bare: Optional[bool] = False,
|
||||||
|
disable_editor: Optional[bool] = False,
|
||||||
|
ssh_proxy: Optional[Any] = None,
|
||||||
|
gitdir: Optional[str] = None,
|
||||||
|
objdir: Optional[str] = None
|
||||||
|
):
|
||||||
|
"""Constucts an env dict for command execution."""
|
||||||
|
|
||||||
def __init__(self,
|
assert _kwargs_only == (), '_build_env only accepts keyword arguments.'
|
||||||
project,
|
|
||||||
cmdv,
|
env = GitCommand._GetBasicEnv()
|
||||||
bare=False,
|
|
||||||
input=None,
|
|
||||||
capture_stdout=False,
|
|
||||||
capture_stderr=False,
|
|
||||||
merge_output=False,
|
|
||||||
disable_editor=False,
|
|
||||||
ssh_proxy=None,
|
|
||||||
cwd=None,
|
|
||||||
gitdir=None,
|
|
||||||
objdir=None):
|
|
||||||
env = self._GetBasicEnv()
|
|
||||||
|
|
||||||
if disable_editor:
|
if disable_editor:
|
||||||
env['GIT_EDITOR'] = ':'
|
env['GIT_EDITOR'] = ':'
|
||||||
@ -192,11 +189,45 @@ class GitCommand(object):
|
|||||||
'file:git:http:https:ssh:persistent-http:persistent-https:sso:rpc')
|
'file:git:http:https:ssh:persistent-http:persistent-https:sso:rpc')
|
||||||
env['GIT_HTTP_USER_AGENT'] = user_agent.git
|
env['GIT_HTTP_USER_AGENT'] = user_agent.git
|
||||||
|
|
||||||
|
if objdir:
|
||||||
|
# Set to the place we want to save the objects.
|
||||||
|
env['GIT_OBJECT_DIRECTORY'] = objdir
|
||||||
|
|
||||||
|
alt_objects = os.path.join(gitdir, 'objects') if gitdir else None
|
||||||
|
if (alt_objects and
|
||||||
|
os.path.realpath(alt_objects) != os.path.realpath(objdir)):
|
||||||
|
# Allow git to search the original place in case of local or unique refs
|
||||||
|
# that git will attempt to resolve even if we aren't fetching them.
|
||||||
|
env['GIT_ALTERNATE_OBJECT_DIRECTORIES'] = alt_objects
|
||||||
|
if bare and gitdir is not None:
|
||||||
|
env[GIT_DIR] = gitdir
|
||||||
|
|
||||||
|
return env
|
||||||
|
|
||||||
|
|
||||||
|
class GitCommand(object):
|
||||||
|
"""Wrapper around a single git invocation."""
|
||||||
|
|
||||||
|
def __init__(self,
|
||||||
|
project,
|
||||||
|
cmdv,
|
||||||
|
bare=False,
|
||||||
|
input=None,
|
||||||
|
capture_stdout=False,
|
||||||
|
capture_stderr=False,
|
||||||
|
merge_output=False,
|
||||||
|
disable_editor=False,
|
||||||
|
ssh_proxy=None,
|
||||||
|
cwd=None,
|
||||||
|
gitdir=None,
|
||||||
|
objdir=None):
|
||||||
|
|
||||||
if project:
|
if project:
|
||||||
if not cwd:
|
if not cwd:
|
||||||
cwd = project.worktree
|
cwd = project.worktree
|
||||||
if not gitdir:
|
if not gitdir:
|
||||||
gitdir = project.gitdir
|
gitdir = project.gitdir
|
||||||
|
|
||||||
# Git on Windows wants its paths only using / for reliability.
|
# Git on Windows wants its paths only using / for reliability.
|
||||||
if platform_utils.isWindows():
|
if platform_utils.isWindows():
|
||||||
if objdir:
|
if objdir:
|
||||||
@ -204,20 +235,16 @@ class GitCommand(object):
|
|||||||
if gitdir:
|
if gitdir:
|
||||||
gitdir = gitdir.replace('\\', '/')
|
gitdir = gitdir.replace('\\', '/')
|
||||||
|
|
||||||
if objdir:
|
env = _build_env(
|
||||||
# Set to the place we want to save the objects.
|
disable_editor=disable_editor,
|
||||||
env['GIT_OBJECT_DIRECTORY'] = objdir
|
ssh_proxy=ssh_proxy,
|
||||||
|
objdir=objdir,
|
||||||
alt_objects = os.path.join(gitdir, 'objects') if gitdir else None
|
gitdir=gitdir,
|
||||||
if alt_objects and os.path.realpath(alt_objects) != os.path.realpath(objdir):
|
bare=bare,
|
||||||
# Allow git to search the original place in case of local or unique refs
|
)
|
||||||
# that git will attempt to resolve even if we aren't fetching them.
|
|
||||||
env['GIT_ALTERNATE_OBJECT_DIRECTORIES'] = alt_objects
|
|
||||||
|
|
||||||
command = [GIT]
|
command = [GIT]
|
||||||
if bare:
|
if bare:
|
||||||
if gitdir:
|
|
||||||
env[GIT_DIR] = gitdir
|
|
||||||
cwd = None
|
cwd = None
|
||||||
command.append(cmdv[0])
|
command.append(cmdv[0])
|
||||||
# Need to use the --progress flag for fetch/clone so output will be
|
# Need to use the --progress flag for fetch/clone so output will be
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
"""Unittests for the git_command.py module."""
|
"""Unittests for the git_command.py module."""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
import os
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -26,6 +27,38 @@ import git_command
|
|||||||
import wrapper
|
import wrapper
|
||||||
|
|
||||||
|
|
||||||
|
class GitCommandTest(unittest.TestCase):
|
||||||
|
"""Tests the GitCommand class (via git_command.git)."""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
|
||||||
|
def realpath_mock(val):
|
||||||
|
return val
|
||||||
|
|
||||||
|
mock.patch.object(os.path, 'realpath', side_effect=realpath_mock).start()
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
mock.patch.stopall()
|
||||||
|
|
||||||
|
def test_alternative_setting_when_matching(self):
|
||||||
|
r = git_command._build_env(
|
||||||
|
objdir = 'zap/objects',
|
||||||
|
gitdir = 'zap'
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertIsNone(r.get('GIT_ALTERNATE_OBJECT_DIRECTORIES'))
|
||||||
|
self.assertEqual(r.get('GIT_OBJECT_DIRECTORY'), 'zap/objects')
|
||||||
|
|
||||||
|
def test_alternative_setting_when_different(self):
|
||||||
|
r = git_command._build_env(
|
||||||
|
objdir = 'wow/objects',
|
||||||
|
gitdir = 'zap'
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(r.get('GIT_ALTERNATE_OBJECT_DIRECTORIES'), 'zap/objects')
|
||||||
|
self.assertEqual(r.get('GIT_OBJECT_DIRECTORY'), 'wow/objects')
|
||||||
|
|
||||||
|
|
||||||
class GitCallUnitTest(unittest.TestCase):
|
class GitCallUnitTest(unittest.TestCase):
|
||||||
"""Tests the _GitCall class (via git_command.git)."""
|
"""Tests the _GitCall class (via git_command.git)."""
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user