diff options
-rw-r--r-- | git/cmd.py | 6 | ||||
-rw-r--r-- | git/remote.py | 4 | ||||
-rw-r--r-- | git/repo/base.py | 2 | ||||
-rw-r--r-- | git/test/lib/helper.py | 92 | ||||
-rw-r--r-- | git/test/test_base.py | 11 | ||||
-rw-r--r-- | git/test/test_docs.py | 2 | ||||
-rw-r--r-- | git/test/test_remote.py | 19 | ||||
-rw-r--r-- | git/test/test_repo.py | 12 | ||||
-rw-r--r-- | git/test/test_submodule.py | 2 |
9 files changed, 81 insertions, 69 deletions
@@ -186,14 +186,18 @@ class Git(LazyMixin): # Override this value using `Git.USE_SHELL = True` USE_SHELL = False - class AutoInterrupt(object): + @classmethod + def polish_url(cls, url): + return url.replace("\\\\", "\\").replace("\\", "/") + class AutoInterrupt(object): """Kill/Interrupt the stored process instance once this instance goes out of scope. It is used to prevent processes piling up in case iterators stop reading. Besides all attributes are wired through to the contained process object. The wait method was overridden to perform automatic status code checking and possibly raise.""" + __slots__ = ("proc", "args") def __init__(self, proc, args): diff --git a/git/remote.py b/git/remote.py index a7d3fe7e..8a46b2c5 100644 --- a/git/remote.py +++ b/git/remote.py @@ -29,7 +29,7 @@ from git.util import ( join_path, finalize_process ) -from git.cmd import handle_process_output +from git.cmd import handle_process_output, Git from gitdb.util import join from git.compat import (defenc, force_text, is_win) import logging @@ -570,7 +570,7 @@ class Remote(LazyMixin, Iterable): :raise GitCommandError: in case an origin with that name already exists""" scmd = 'add' kwargs['insert_kwargs_after'] = scmd - repo.git.remote(scmd, name, url, **kwargs) + repo.git.remote(scmd, name, Git.polish_url(url), **kwargs) return cls(repo, name) # add is an alias diff --git a/git/repo/base.py b/git/repo/base.py index 4e9549ee..c5cdce7c 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -897,7 +897,7 @@ class Repo(object): repo = cls(path, odbt=odbt) if repo.remotes: with repo.remotes[0].config_writer as writer: - writer.set_value('url', repo.remotes[0].url.replace("\\\\", "\\").replace("\\", "/")) + writer.set_value('url', Git.polish_url(repo.remotes[0].url)) # END handle remote repo return repo diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index 092068b9..3d6c3735 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -5,26 +5,28 @@ # the BSD License: http://www.opensource.org/licenses/bsd-license.php from __future__ import print_function -import os -from unittest import TestCase -import time -import tempfile +from functools import wraps import io import logging +import os +import tempfile +import textwrap +import time +from unittest import TestCase -from functools import wraps - -from git.util import rmtree from git.compat import string_types, is_win -import textwrap +from git.util import rmtree, HIDE_WINDOWS_KNOWN_ERRORS + +import os.path as osp + -osp = os.path.dirname +ospd = osp.dirname -GIT_REPO = os.environ.get("GIT_PYTHON_TEST_GIT_REPO_BASE", osp(osp(osp(osp(__file__))))) -GIT_DAEMON_PORT = os.environ.get("GIT_PYTHON_TEST_GIT_DAEMON_PORT", "9418") +GIT_REPO = os.environ.get("GIT_PYTHON_TEST_GIT_REPO_BASE", ospd(ospd(ospd(ospd(__file__))))) +GIT_DAEMON_PORT = os.environ.get("GIT_PYTHON_TEST_GIT_DAEMON_PORT", "19418") __all__ = ( - 'fixture_path', 'fixture', 'absolute_project_path', 'StringProcessAdapter', + 'fixture_path', 'fixture', 'StringProcessAdapter', 'with_rw_directory', 'with_rw_repo', 'with_rw_and_rw_remote_repo', 'TestBase', 'TestCase', 'GIT_REPO', 'GIT_DAEMON_PORT' ) @@ -35,18 +37,13 @@ log = logging.getLogger('git.util') def fixture_path(name): - test_dir = osp(osp(__file__)) - return os.path.join(test_dir, "fixtures", name) + return osp.join(ospd(ospd(__file__)), 'fixtures', name) def fixture(name): with open(fixture_path(name), 'rb') as fd: return fd.read() - -def absolute_project_path(): - return os.path.abspath(os.path.join(osp(__file__), "..", "..")) - #} END routines #{ Adapters @@ -165,26 +162,31 @@ def with_rw_repo(working_tree_ref, bare=False): return argument_passer -def launch_git_daemon(temp_dir, ip, port): +def launch_git_daemon(base_path, ip, port): from git import Git if is_win: ## On MINGW-git, daemon exists in .\Git\mingw64\libexec\git-core\, # but if invoked as 'git daemon', it detaches from parent `git` cmd, # and then CANNOT DIE! # So, invoke it as a single command. - ## Cygwin-git has no daemon. + ## Cygwin-git has no daemon. But it can use MINGW's. # - daemon_cmd = ['git-daemon', temp_dir, + daemon_cmd = ['git-daemon', '--enable=receive-pack', '--listen=%s' % ip, - '--port=%s' % port] + '--port=%s' % port, + '--base-path=%s' % base_path, + base_path] gd = Git().execute(daemon_cmd, as_process=True) else: - gd = Git().daemon(temp_dir, + gd = Git().daemon(base_path, enable='receive-pack', listen=ip, port=port, + base_path=base_path, as_process=True) + # yes, I know ... fortunately, this is always going to work if sleep time is just large enough + time.sleep(0.5) return gd @@ -212,7 +214,8 @@ def with_rw_and_rw_remote_repo(working_tree_ref): See working dir info in with_rw_repo :note: We attempt to launch our own invocation of git-daemon, which will be shutdown at the end of the test. """ - from git import Remote, GitCommandError + from git import Git, Remote, GitCommandError + assert isinstance(working_tree_ref, string_types), "Decorator requires ref name for working tree checkout" def argument_passer(func): @@ -240,23 +243,36 @@ def with_rw_and_rw_remote_repo(working_tree_ref): pass crw.set(section, "receivepack", True) - # initialize the remote - first do it as local remote and pull, then - # we change the url to point to the daemon. The daemon should be started - # by the user, not by us + # Initialize the remote - first do it as local remote and pull, then + # we change the url to point to the daemon. d_remote = Remote.create(rw_repo, "daemon_origin", remote_repo_dir) d_remote.fetch() - remote_repo_url = "git://localhost:%s%s" % (GIT_DAEMON_PORT, remote_repo_dir) + base_path, rel_repo_dir = osp.split(remote_repo_dir) + + remote_repo_url = "git://localhost:%s/%s" % (GIT_DAEMON_PORT, rel_repo_dir) with d_remote.config_writer as cw: cw.set('url', remote_repo_url) - temp_dir = osp(_mktemp()) - gd = launch_git_daemon(temp_dir, '127.0.0.1', GIT_DAEMON_PORT) try: - # yes, I know ... fortunately, this is always going to work if sleep time is just large enough - time.sleep(0.5) - # end - + gd = launch_git_daemon(Git.polish_url(base_path), '127.0.0.1', GIT_DAEMON_PORT) + except Exception as ex: + if is_win: + msg = textwrap.dedent(""" + The `git-daemon.exe` must be in PATH. + For MINGW, look into .\Git\mingw64\libexec\git-core\), but problems with paths might appear. + CYGWIN has no daemon, but if one exists, it gets along fine (has also paths problems) + Anyhow, alternatively try starting `git-daemon` manually:""") + else: + msg = "Please try starting `git-daemon` manually:" + msg += textwrap.dedent(""" + git daemon --enable=receive-pack --base-path=%s %s + You can also run the daemon on a different port by passing --port=<port>" + and setting the environment variable GIT_PYTHON_TEST_GIT_DAEMON_PORT to <port> + """ % (base_path, base_path)) + raise AssertionError(ex, msg) + # END make assertion + else: # try to list remotes to diagnoes whether the server is up try: rw_repo.git.ls_remote(d_remote) @@ -283,9 +299,9 @@ def with_rw_and_rw_remote_repo(working_tree_ref): git daemon --enable=receive-pack '%s' You can also run the daemon on a different port by passing --port=<port>" and setting the environment variable GIT_PYTHON_TEST_GIT_DAEMON_PORT to <port> - """ % temp_dir) + """ % base_path) from unittest import SkipTest - raise SkipTest(msg) if is_win else AssertionError(msg) + raise SkipTest(msg) if HIDE_WINDOWS_KNOWN_ERRORS else AssertionError(e, msg) # END make assertion # END catch ls remote error @@ -354,7 +370,7 @@ class TestBase(TestCase): def _small_repo_url(self): """:return" a path to a small, clonable repository""" - return os.path.join(self.rorepo.working_tree_dir, 'git/ext/gitdb/gitdb/ext/smmap') + return osp.join(self.rorepo.working_tree_dir, 'git/ext/gitdb/gitdb/ext/smmap') @classmethod def setUpClass(cls): @@ -378,7 +394,7 @@ class TestBase(TestCase): with the given data. Returns absolute path to created file. """ repo = repo or self.rorepo - abs_path = os.path.join(repo.working_tree_dir, rela_path) + abs_path = osp.join(repo.working_tree_dir, rela_path) with open(abs_path, "w") as fp: fp.write(data) return abs_path diff --git a/git/test/test_base.py b/git/test/test_base.py index 2956f3d4..a4382d3e 100644 --- a/git/test/test_base.py +++ b/git/test/test_base.py @@ -110,17 +110,6 @@ class TestBase(TestBase): assert not rw_repo.config_reader("repository").getboolean("core", "bare") assert os.path.isdir(os.path.join(rw_repo.working_tree_dir, 'lib')) - # @skipIf(HIDE_WINDOWS_KNOWN_ERRORS, """ - # FIXME: helper.wrapper fails with: - # PermissionError: [WinError 5] Access is denied: - # 'C:\\Users\\appveyor\\AppData\\Local\\Temp\\1\\test_work_tree_unsupportedryfa60di\\ - # master_repo\\.git\\objects\\pack\\pack-bc9e0787aef9f69e1591ef38ea0a6f566ec66fe3.idx' - # AND - # FIXME: git-daemon failing with: - # git.exc.GitCommandError: Cmd('git') failed due to: exit code(128) - # cmdline: git ls-remote daemon_origin - # stderr: 'fatal: bad config line 15 in file .git/config' - # """) @with_rw_and_rw_remote_repo('0.1.6') def test_with_rw_remote_and_rw_repo(self, rw_repo, rw_remote_repo): assert not rw_repo.config_reader("repository").getboolean("core", "bare") diff --git a/git/test/test_docs.py b/git/test/test_docs.py index e2bfcb21..f3c75f79 100644 --- a/git/test/test_docs.py +++ b/git/test/test_docs.py @@ -16,7 +16,7 @@ class Tutorials(TestBase): import gc gc.collect() - # @skipIf(HIDE_WINDOWS_KNOWN_ERRORS, + # @skipIf(HIDE_WINDOWS_KNOWN_ERRORS, ## ACTUALLY skipped by `git.submodule.base#L869`. # "FIXME: helper.wrapper fails with: PermissionError: [WinError 5] Access is denied: " # "'C:\\Users\\appveyor\\AppData\\Local\\Temp\\1\\test_work_tree_unsupportedryfa60di\\master_repo\\.git\\objects\\pack\\pack-bc9e0787aef9f69e1591ef38ea0a6f566ec66fe3.idx") # noqa E501 @with_rw_directory diff --git a/git/test/test_remote.py b/git/test/test_remote.py index e0b00e0c..8382d7fa 100644 --- a/git/test/test_remote.py +++ b/git/test/test_remote.py @@ -28,8 +28,11 @@ from git import ( from git.util import IterableList, rmtree from git.compat import string_types import tempfile -import os +import os.path as osp import random +from unittest.case import skipIf +from git.util import HIDE_WINDOWS_KNOWN_ERRORS +from git.cmd import Git # assure we have repeatable results random.seed(0) @@ -105,7 +108,7 @@ class TestRemote(TestBase): gc.collect() def _print_fetchhead(self, repo): - with open(os.path.join(repo.git_dir, "FETCH_HEAD")): + with open(osp.join(repo.git_dir, "FETCH_HEAD")): pass def _do_test_fetch_result(self, results, remote): @@ -156,7 +159,7 @@ class TestRemote(TestBase): # Create a file with a random name and random data and commit it to repo. # Return the commited absolute file path index = repo.index - new_file = self._make_file(os.path.basename(tempfile.mktemp()), str(random.random()), repo) + new_file = self._make_file(osp.basename(tempfile.mktemp()), str(random.random()), repo) index.add([new_file]) index.commit("Committing %s" % new_file) return new_file @@ -263,7 +266,8 @@ class TestRemote(TestBase): # must clone with a local path for the repo implementation not to freak out # as it wants local paths only ( which I can understand ) other_repo = remote_repo.clone(other_repo_dir, shared=False) - remote_repo_url = "git://localhost:%s%s" % (GIT_DAEMON_PORT, remote_repo.git_dir) + remote_repo_url = osp.basename(remote_repo.git_dir) # git-daemon runs with appropriate `--base-path`. + remote_repo_url = Git.polish_url("git://localhost:%s/%s" % (GIT_DAEMON_PORT, remote_repo_url)) # put origin to git-url other_origin = other_repo.remotes.origin @@ -384,12 +388,7 @@ class TestRemote(TestBase): TagReference.delete(rw_repo, new_tag, other_tag) remote.push(":%s" % other_tag.path) - # @skipIf(HIDE_WINDOWS_KNOWN_ERRORS, """ - # FIXME: git-daemon failing with: - # git.exc.GitCommandError: Cmd('git') failed due to: exit code(128) - # cmdline: git ls-remote daemon_origin - # stderr: 'fatal: bad config line 15 in file .git/config' - # """) + @skipIf(HIDE_WINDOWS_KNOWN_ERRORS, "FIXME: Freezes!") @with_rw_and_rw_remote_repo('0.1.6') def test_base(self, rw_repo, remote_repo): num_remotes = 0 diff --git a/git/test/test_repo.py b/git/test/test_repo.py index 2c0847e1..a0a6a5b0 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -472,12 +472,16 @@ class TestRepo(TestBase): head = self.rorepo.create_head("new_head", "HEAD~1") self.rorepo.delete_head(head) - tag = self.rorepo.create_tag("new_tag", "HEAD~2") - self.rorepo.delete_tag(tag) + try: + tag = self.rorepo.create_tag("new_tag", "HEAD~2") + finally: + self.rorepo.delete_tag(tag) with self.rorepo.config_writer(): pass - remote = self.rorepo.create_remote("new_remote", "git@server:repo.git") - self.rorepo.delete_remote(remote) + try: + remote = self.rorepo.create_remote("new_remote", "git@server:repo.git") + finally: + self.rorepo.delete_remote(remote) def test_comparison_and_hash(self): # this is only a preliminary test, more testing done in test_index diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index e935017f..902a96b5 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -418,7 +418,7 @@ class TestSubmodule(TestBase): # Error if there is no submodule file here self.failUnlessRaises(IOError, Submodule._config_parser, rwrepo, rwrepo.commit(self.k_no_subm_tag), True) - # @skipIf(HIDE_WINDOWS_KNOWN_ERRORS, + # @skipIf(HIDE_WINDOWS_KNOWN_ERRORS, ## ACTUALLY skipped by `git.submodule.base#L869`. # "FIXME: fails with: PermissionError: [WinError 32] The process cannot access the file because" # "it is being used by another process: " # "'C:\\Users\\ankostis\\AppData\\Local\\Temp\\tmp95c3z83bnon_bare_test_base_rw\\git\\ext\\gitdb\\gitdb\\ext\\smmap'") # noqa E501 |