test_install_vcs_git.py 13.5 KB
Newer Older
1
import pytest
2

P
Pradyun S. Gedam 已提交
3
from tests.lib import (
P
Pradyun Gedam 已提交
4
    _change_test_package_version, _create_test_package, pyversion,
P
Pradyun S. Gedam 已提交
5
)
6 7 8 9
from tests.lib.git_submodule_helpers import (
    _change_test_package_submodule, _create_test_package_with_submodule,
    _pull_in_submodule_changes_to_module,
)
10
from tests.lib.local_repos import local_checkout
11

12

13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
def _checkout_into_temp(url, temp_dir, egg=None):
    """
    Call local_checkout(), and return the resulting URL.

    Args:
      url: a package URL (e.g. a "git+https://" or "git+git://" URL).
      temp_dir: the pytest tmpdir value.
      egg: an optional project name to append to the URL as the egg fragment,
        prior to returning.
    """
    package_url = local_checkout(url, temp_dir.join("cache"))
    if egg is not None:
        package_url += '#egg={}'.format(egg)

    return package_url


30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
def _make_version_pkg_url(path, rev=None):
    """
    Return a "git+file://" URL to the version_pkg test package.

    Args:
      path: a tests.lib.path.Path object pointing to a Git repository
        containing the version_pkg package.
      rev: an optional revision to install like a branch name, tag, or SHA.
    """
    path = path.abspath.replace('\\', '/')
    url_rev = '' if rev is None else '@{}'.format(rev)
    url = 'git+file://{}{}#egg=version_pkg'.format(path, url_rev)

    return url


46
def _install_version_pkg(script, path, rev=None):
47 48 49 50 51 52
    """
    Install the version_pkg package, and return the version installed.

    Args:
      path: a tests.lib.path.Path object pointing to a Git repository
        containing the package.
53
      rev: an optional revision to install like a branch name or tag.
54
    """
55 56
    version_pkg_url = _make_version_pkg_url(path, rev=rev)
    script.pip('install', '-e', version_pkg_url)
57 58 59 60 61 62
    result = script.run('version_pkg')
    version = result.stdout.strip()

    return version


63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
def test_git_install_again_after_changes(script):
    """
    Test installing a repository a second time without specifying a revision,
    and after updates to the remote repository.

    This test also checks that no warning message like the following gets
    logged on the update: "Did not find branch or tag ..., assuming ref or
    revision."
    """
    version_pkg_path = _create_test_package(script)
    version = _install_version_pkg(script, version_pkg_path)
    assert version == '0.1'

    _change_test_package_version(script, version_pkg_path)
    version = _install_version_pkg(script, version_pkg_path)
    assert version == 'some different version'


81 82 83 84 85 86
def test_git_install_branch_again_after_branch_changes(script):
    """
    Test installing a branch again after the branch is updated in the remote
    repository.
    """
    version_pkg_path = _create_test_package(script)
87
    version = _install_version_pkg(script, version_pkg_path, rev='master')
88 89 90
    assert version == '0.1'

    _change_test_package_version(script, version_pkg_path)
91
    version = _install_version_pkg(script, version_pkg_path, rev='master')
92 93 94
    assert version == 'some different version'


95
@pytest.mark.network
96
def test_install_editable_from_git_with_https(script, tmpdir):
J
Jannis Leidel 已提交
97 98 99
    """
    Test cloning from Git with https.
    """
100 101 102
    url = 'git+https://github.com/pypa/pip-test-package.git'
    local_url = _checkout_into_temp(url, tmpdir, egg='pip-test-package')
    result = script.pip('install', '-e', local_url, expect_error=True)
103
    result.assert_installed('pip-test-package', with_files=['.git'])
J
Jannis Leidel 已提交
104

H
Hugo Lopes Tavares 已提交
105

106
@pytest.mark.network
107 108 109 110 111 112
def test_install_noneditable_git(script, tmpdir):
    """
    Test installing from a non-editable git URL with a given tag.
    """
    result = script.pip(
        'install',
M
Marcus Smith 已提交
113 114 115
        'git+https://github.com/pypa/pip-test-package.git'
        '@0.1.1#egg=pip-test-package'
    )
116
    egg_info_folder = (
M
Marcus Smith 已提交
117 118 119 120 121 122
        script.site_packages /
        'pip_test_package-0.1.1-py%s.egg-info' % pyversion
    )
    result.assert_installed('piptestpackage',
                            without_egg_link=True,
                            editable=False)
123 124 125
    assert egg_info_folder in result.files_created, str(result)


126
@pytest.mark.network
127
def test_git_with_sha1_revisions(script):
H
Hugo Lopes Tavares 已提交
128 129 130
    """
    Git backend should be able to install from SHA1 revisions
    """
D
Donald Stufft 已提交
131 132
    version_pkg_path = _create_test_package(script)
    _change_test_package_version(script, version_pkg_path)
133 134 135 136
    sha1 = script.run(
        'git', 'rev-parse', 'HEAD~1',
        cwd=version_pkg_path,
    ).stdout.strip()
137 138
    version_pkg_url = _make_version_pkg_url(version_pkg_path, rev=sha1)
    script.pip('install', '-e', version_pkg_url, expect_stderr=True)
D
Donald Stufft 已提交
139
    version = script.run('version_pkg')
140 141 142 143 144 145 146 147 148 149 150 151 152 153
    assert '0.1' in version.stdout, version.stdout


@pytest.mark.network
def test_git_with_short_sha1_revisions(script):
    """
    Git backend should be able to install from SHA1 revisions
    """
    version_pkg_path = _create_test_package(script)
    _change_test_package_version(script, version_pkg_path)
    sha1 = script.run(
        'git', 'rev-parse', 'HEAD~1',
        cwd=version_pkg_path,
    ).stdout.strip()[:7]
154 155
    version_pkg_url = _make_version_pkg_url(version_pkg_path, rev=sha1)
    script.pip('install', '-e', version_pkg_url, expect_stderr=True)
156
    version = script.run('version_pkg')
H
Hugo Lopes Tavares 已提交
157 158
    assert '0.1' in version.stdout, version.stdout

159

160
@pytest.mark.network
161
def test_git_with_branch_name_as_revision(script):
162 163 164
    """
    Git backend should be able to install from branch names
    """
D
Donald Stufft 已提交
165
    version_pkg_path = _create_test_package(script)
166
    branch = 'test_branch'
167
    script.run(
168
        'git', 'checkout', '-b', branch,
169 170 171
        expect_stderr=True,
        cwd=version_pkg_path,
    )
D
Donald Stufft 已提交
172
    _change_test_package_version(script, version_pkg_path)
173 174
    version_pkg_url = _make_version_pkg_url(version_pkg_path, rev=branch)
    script.pip('install', '-e', version_pkg_url)
D
Donald Stufft 已提交
175
    version = script.run('version_pkg')
176 177
    assert 'some different version' in version.stdout

178

179
@pytest.mark.network
180
def test_git_with_tag_name_as_revision(script):
181 182 183
    """
    Git backend should be able to install from tag names
    """
D
Donald Stufft 已提交
184
    version_pkg_path = _create_test_package(script)
185 186 187 188 189
    script.run(
        'git', 'tag', 'test_tag',
        expect_stderr=True,
        cwd=version_pkg_path,
    )
D
Donald Stufft 已提交
190
    _change_test_package_version(script, version_pkg_path)
191 192
    version_pkg_url = _make_version_pkg_url(version_pkg_path, rev='test_tag')
    script.pip('install', '-e', version_pkg_url)
D
Donald Stufft 已提交
193
    version = script.run('version_pkg')
194 195
    assert '0.1' in version.stdout

196

C
Chris Jerdonek 已提交
197
def _add_ref(script, path, ref):
198
    """
C
Chris Jerdonek 已提交
199
    Add a new ref to a repository at the given path.
200
    """
C
Chris Jerdonek 已提交
201 202 203 204 205 206 207 208 209 210 211
    script.run('git', 'update-ref', ref, 'HEAD', expect_stderr=True, cwd=path)


def test_git_install_ref(script):
    """
    The Git backend should be able to install a ref with the first install.
    """
    package_path = _create_test_package(script)
    _add_ref(script, package_path, 'refs/foo/bar')
    _change_test_package_version(script, package_path)

212 213
    version_pkg_url = _make_version_pkg_url(package_path, rev='refs/foo/bar')
    script.pip('install', '-e', version_pkg_url, expect_stderr=True)
C
Chris Jerdonek 已提交
214 215 216 217 218 219 220 221 222 223 224 225 226
    version = script.run('version_pkg')
    assert '0.1' in version.stdout


def test_git_install_then_install_ref(script):
    """
    The Git backend should be able to install a ref after a package has
    already been installed.
    """
    package_path = _create_test_package(script)
    _add_ref(script, package_path, 'refs/foo/bar')
    _change_test_package_version(script, package_path)

227 228
    version_pkg_url = _make_version_pkg_url(package_path)
    script.pip('install', '-e', version_pkg_url, expect_stderr=True)
C
Chris Jerdonek 已提交
229 230 231 232
    version = script.run('version_pkg')
    assert 'some different version' in version.stdout

    # Now install the ref.
233 234
    version_pkg_url = _make_version_pkg_url(package_path, rev='refs/foo/bar')
    script.pip('install', '-e', version_pkg_url, expect_stderr=True)
235 236 237 238
    version = script.run('version_pkg')
    assert '0.1' in version.stdout


239
@pytest.mark.network
240
def test_git_with_tag_name_and_update(script, tmpdir):
241 242 243
    """
    Test cloning a git repository and updating to a different version.
    """
244 245 246
    url = 'git+https://github.com/pypa/pip-test-package.git'
    local_url = _checkout_into_temp(url, tmpdir, egg='pip-test-package')
    result = script.pip('install', '-e', local_url, expect_error=True)
247
    result.assert_installed('pip-test-package', with_files=['.git'])
248 249 250

    new_local_url = _checkout_into_temp(url, tmpdir)
    new_local_url += '@0.1.2#egg=pip-test-package'
251
    result = script.pip(
252
        'install', '--global-option=--version', '-e', new_local_url,
253 254
        expect_error=True,
    )
255
    assert '0.1.2' in result.stdout
256

257

258
@pytest.mark.network
259
def test_git_branch_should_not_be_changed(script, tmpdir):
260 261 262 263
    """
    Editable installations should not change branch
    related to issue #32 and #161
    """
264 265 266
    url = 'git+https://github.com/pypa/pip-test-package.git'
    local_url = _checkout_into_temp(url, tmpdir, egg='pip-test-package')
    script.pip('install', '-e', local_url, expect_error=True)
D
Donald Stufft 已提交
267
    source_dir = script.venv_path / 'src' / 'pip-test-package'
D
Donald Stufft 已提交
268
    result = script.run('git', 'branch', cwd=source_dir)
C
Carl Meyer 已提交
269
    assert '* master' in result.stdout, result.stdout
270

271

272
@pytest.mark.network
273
def test_git_with_non_editable_unpacking(script, tmpdir):
274 275 276
    """
    Test cloning a git repository from a non-editable URL with a given tag.
    """
277 278 279 280 281
    url = (
        'git+https://github.com/pypa/pip-test-package.git@0.1.2'
        '#egg=pip-test-package'
    )
    local_url = _checkout_into_temp(url, tmpdir)
282
    result = script.pip(
283
        'install', '--global-option=--version', local_url, expect_error=True,
284
    )
285
    assert '0.1.2' in result.stdout
286

287

288
@pytest.mark.network
289
def test_git_with_editable_where_egg_contains_dev_string(script, tmpdir):
290
    """
291 292
    Test cloning a git repository from an editable url which contains "dev"
    string
293
    """
294 295 296
    url = 'git+git://github.com/dcramer/django-devserver.git'
    local_url = _checkout_into_temp(url, tmpdir, egg='django-devserver')
    result = script.pip('install', '-e', local_url)
297 298
    result.assert_installed('django-devserver', with_files=['.git'])

299

300
@pytest.mark.network
301
def test_git_with_non_editable_where_egg_contains_dev_string(script, tmpdir):
302
    """
303 304
    Test cloning a git repository from a non-editable url which contains "dev"
    string
305
    """
306 307 308
    url = 'git+git://github.com/dcramer/django-devserver.git'
    local_url = _checkout_into_temp(url, tmpdir, egg='django-devserver')
    result = script.pip('install', local_url)
D
Donald Stufft 已提交
309
    devserver_folder = script.site_packages / 'devserver'
310
    assert devserver_folder in result.files_created, str(result)
311 312


313
@pytest.mark.network
314
def test_git_with_ambiguous_revs(script):
315 316 317
    """
    Test git with two "names" (tag/branch) pointing to the same commit
    """
D
Donald Stufft 已提交
318
    version_pkg_path = _create_test_package(script)
319
    version_pkg_url = _make_version_pkg_url(version_pkg_path, rev='0.1')
D
Donald Stufft 已提交
320
    script.run('git', 'tag', '0.1', cwd=version_pkg_path)
321
    result = script.pip('install', '-e', version_pkg_url)
322 323 324 325
    assert 'Could not find a tag or branch' not in result.stdout
    # it is 'version-pkg' instead of 'version_pkg' because
    # egg-link name is version-pkg.egg-link because it is a single .py module
    result.assert_installed('version-pkg', with_files=['.git'])
R
test  
Rory McCann 已提交
326

327

328
@pytest.mark.network
329
def test_git_works_with_editable_non_origin_repo(script):
330 331
    # set up, create a git repo and install it as editable from a local
    # directory path
D
Donald Stufft 已提交
332 333
    version_pkg_path = _create_test_package(script)
    script.pip('install', '-e', version_pkg_path.abspath)
R
test  
Rory McCann 已提交
334

335 336
    # 'freeze'ing this should not fall over, but should result in stderr output
    # warning
D
Donald Stufft 已提交
337
    result = script.pip('freeze', expect_stderr=True)
338 339 340
    assert "Error when trying to get requirement" in result.stderr
    assert "Could not determine repository location" in result.stdout
    assert "version-pkg==0.1" in result.stdout
341 342 343 344 345 346 347 348 349 350 351 352 353


@pytest.mark.network
def test_reinstalling_works_with_editible_non_master_branch(script):
    """
    Reinstalling an editable installation should not assume that the "master"
    branch exists. See https://github.com/pypa/pip/issues/4448.
    """
    version_pkg_path = _create_test_package(script)

    # Switch the default branch to something other than 'master'
    script.run('git', 'branch', '-m', 'foobar', cwd=version_pkg_path)

354 355
    version_pkg_url = _make_version_pkg_url(version_pkg_path)
    script.pip('install', '-e', version_pkg_url)
356 357 358 359
    version = script.run('version_pkg')
    assert '0.1' in version.stdout

    _change_test_package_version(script, version_pkg_path)
360
    script.pip('install', '-e', version_pkg_url)
361 362
    version = script.run('version_pkg')
    assert 'some different version' in version.stdout
363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395


# TODO(pnasrat) fix all helpers to do right things with paths on windows.
@pytest.mark.skipif("sys.platform == 'win32'")
@pytest.mark.network
def test_check_submodule_addition(script):
    """
    Submodules are pulled in on install and updated on upgrade.
    """
    module_path, submodule_path = _create_test_package_with_submodule(script)

    install_result = script.pip(
        'install', '-e', 'git+' + module_path + '#egg=version_pkg'
    )
    assert (
        script.venv / 'src/version-pkg/testpkg/static/testfile'
        in install_result.files_created
    )

    _change_test_package_submodule(script, submodule_path)
    _pull_in_submodule_changes_to_module(script, module_path)

    # expect error because git may write to stderr
    update_result = script.pip(
        'install', '-e', 'git+' + module_path + '#egg=version_pkg',
        '--upgrade',
        expect_error=True,
    )

    assert (
        script.venv / 'src/version-pkg/testpkg/static/testfile2'
        in update_result.files_created
    )