Skip to content

Commit

Permalink
Add sem-ver tag support to git provider
Browse files Browse the repository at this point in the history
- use sem-ver constraints to provide a git package
- add tests for git provider using tags
  - test a tag dependency
  - test a missing tag dependency
  - test a sem-ver tag dependency
  • Loading branch information
Darren Weber committed Jun 21, 2019
1 parent ed8764d commit 882a5c1
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 5 deletions.
37 changes: 32 additions & 5 deletions poetry/puzzle/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from tempfile import mkdtemp
from typing import List

from poetry import semver
from poetry.packages import Dependency
from poetry.packages import DependencyPackage
from poetry.packages import DirectoryDependency
Expand Down Expand Up @@ -172,11 +173,38 @@ def search_for_vcs(self, dependency): # type: (VCSDependency) -> List[Package]
try:
git = Git()
git.clone(dependency.source, tmp_dir)
git.checkout(dependency.reference, tmp_dir)
revision = git.rev_parse(dependency.reference, tmp_dir).strip()
revision = None

if dependency.tag:
tags = git.tags(tmp_dir)
if dependency.tag in tags:
git.checkout(dependency.tag, tmp_dir)
revision = dependency.tag
elif semver.is_sem_ver_constraint(dependency.tag):
# find the latest matching sem-ver tag and update dependency.tag etc.
sem_ver_tags = git.sem_ver_tags(tmp_dir)
constraint = semver.parse_single_constraint(dependency.tag)
match = None
for tag in reversed(sem_ver_tags):
ver = semver.parse_single_constraint(tag)
if constraint.allows(ver):
match = str(ver)
break
if ver < constraint:
break
if match:
dependency = VCSDependency(
dependency.name,
dependency.vcs,
dependency.source,
tag=match,
)
git.checkout(dependency.tag, tmp_dir)
revision = dependency.tag

if dependency.tag or dependency.rev:
revision = dependency.reference
if revision is None:
git.checkout(dependency.reference, tmp_dir)
revision = git.rev_parse(dependency.reference, folder=tmp_dir).strip()

directory_dependency = DirectoryDependency(
dependency.name,
Expand All @@ -188,7 +216,6 @@ def search_for_vcs(self, dependency): # type: (VCSDependency) -> List[Package]
directory_dependency.extras.append(extra)

package = self.search_for_directory(directory_dependency)[0]

package.source_type = "git"
package.source_url = dependency.source
package.source_reference = revision
Expand Down
70 changes: 70 additions & 0 deletions tests/puzzle/test_provider.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
"""
Test Provider
-------------
Notes:
- git demo repo data is actually in:
- tests/fixtures/git/github.com/demo/demo
- the git demo project has a package version 0.1.2 defined in:
- tests/fixtures/git/github.com/demo/demo/setup.py
- git operation mocks are in:
- tests.conftest.git_mock
"""

import pytest

from poetry.io import NullIO
Expand Down Expand Up @@ -95,6 +108,63 @@ def test_search_for_vcs_read_setup(provider, mocker):
}


@pytest.mark.skipif(not PY35, reason="AST parsing does not work for Python <3.4")
def test_search_for_vcs_read_setup_with_single_tag(provider, mocker):
mocker.patch("poetry.utils.env.Env.get", return_value=MockEnv())

dependency = VCSDependency(
"demo", "git", "https://github.com/demo/demo.git", tag="0.1.2"
)
assert dependency.branch is None
assert dependency.rev is None
assert dependency.tag == "0.1.2"

packages = provider.search_for_vcs(dependency)
assert len(packages) == 1
package = packages[0]
assert package.name == "demo"
assert package.version.text == dependency.tag


@pytest.mark.skipif(not PY35, reason="AST parsing does not work for Python <3.4")
def test_search_for_vcs_read_setup_with_missing_tag(provider, mocker):
mocker.patch("poetry.utils.env.Env.get", return_value=MockEnv())

dependency = VCSDependency(
"demo", "git", "https://github.com/demo/demo.git", tag="0.20.0"
)
assert dependency.branch is None
assert dependency.rev is None
assert dependency.tag == "0.20.0"

packages = provider.search_for_vcs(dependency)
assert len(packages) == 1
package = packages[0]
assert package.name == "demo"
assert package.version.text != dependency.tag
assert package.version.text == "0.1.2" # defaults to latest available


@pytest.mark.skipif(not PY35, reason="AST parsing does not work for Python <3.4")
def test_search_for_vcs_read_setup_with_sem_ver_tag(provider, mocker):
mocker.patch("poetry.utils.env.Env.get", return_value=MockEnv())

dependency = VCSDependency(
"demo", "git", "https://github.com/demo/demo.git", tag="~0.1.0"
)
assert dependency.branch is None
assert dependency.rev is None
assert dependency.tag == "~0.1.0"

packages = provider.search_for_vcs(dependency)
assert len(packages) == 1
# package 0.1.2 is fixed in tests/fixtures/git/github.com/demo/demo/setup.py
package = packages[0]
assert package.name == "demo"
assert package.version.text != dependency.tag
assert package.version.text == "0.1.2"


@pytest.mark.skipif(not PY35, reason="AST parsing does not work for Python <3.4")
def test_search_for_vcs_read_setup_with_extras(provider, mocker):
mocker.patch("poetry.utils.env.Env.get", return_value=MockEnv())
Expand Down

0 comments on commit 882a5c1

Please sign in to comment.