From 23462587a716fb1ace46fecf46efa55ebbf76d54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Eustace?= Date: Fri, 23 Jul 2021 15:45:03 +0200 Subject: [PATCH 1/5] Do not assume a defaut branch for VCS dependencies --- poetry/core/packages/vcs_dependency.py | 13 +++++-------- tests/masonry/builders/test_sdist.py | 2 +- tests/packages/test_vcs_dependency.py | 14 +++++++++----- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/poetry/core/packages/vcs_dependency.py b/poetry/core/packages/vcs_dependency.py index 145bd6b0c..e51cec20f 100644 --- a/poetry/core/packages/vcs_dependency.py +++ b/poetry/core/packages/vcs_dependency.py @@ -33,10 +33,6 @@ def __init__( self._vcs = vcs self._source = source - if not any([branch, tag, rev]): - # If nothing has been specified, we assume master - branch = "master" - self._branch = branch self._tag = tag self._rev = rev @@ -108,11 +104,12 @@ def base_pep_508_name(self) -> str: requirement += "[{}]".format(",".join(self.extras)) if parsed_url.protocol is not None: - requirement += " @ {}+{}@{}".format(self._vcs, self._source, self.reference) + requirement += " @ {}+{}".format(self._vcs, self._source) else: - requirement += " @ {}+ssh://{}@{}".format( - self._vcs, parsed_url.format(), self.reference - ) + requirement += " @ {}+ssh://{}".format(self._vcs, parsed_url.format()) + + if self.reference: + requirement += f"@{self.reference}" return requirement diff --git a/tests/masonry/builders/test_sdist.py b/tests/masonry/builders/test_sdist.py index 2b058d275..ae299595a 100644 --- a/tests/masonry/builders/test_sdist.py +++ b/tests/masonry/builders/test_sdist.py @@ -56,7 +56,7 @@ def test_convert_dependencies(): "A>=1.0,<2.0", "B>=1.0,<1.1", "C==1.2.3", - "D @ git+https://github.com/sdispater/d.git@master", + "D @ git+https://github.com/sdispater/d.git", "E>=1.0,<2.0", "F>=1.0,<2.0,!=1.3", ] diff --git a/tests/packages/test_vcs_dependency.py b/tests/packages/test_vcs_dependency.py index 5e97769fd..be8534e7d 100644 --- a/tests/packages/test_vcs_dependency.py +++ b/tests/packages/test_vcs_dependency.py @@ -8,7 +8,7 @@ def test_to_pep_508(): "poetry", "git", "https://github.com/python-poetry/poetry.git" ) - expected = "poetry @ git+https://github.com/python-poetry/poetry.git@master" + expected = "poetry @ git+https://github.com/python-poetry/poetry.git" assert expected == dependency.to_pep_508() @@ -16,7 +16,7 @@ def test_to_pep_508(): def test_to_pep_508_ssh(): dependency = VCSDependency("poetry", "git", "git@github.com:sdispater/poetry.git") - expected = "poetry @ git+ssh://git@github.com/sdispater/poetry.git@master" + expected = "poetry @ git+ssh://git@github.com/sdispater/poetry.git" assert expected == dependency.to_pep_508() @@ -26,7 +26,7 @@ def test_to_pep_508_with_extras(): "poetry", "git", "https://github.com/python-poetry/poetry.git", extras=["foo"] ) - expected = "poetry[foo] @ git+https://github.com/python-poetry/poetry.git@master" + expected = "poetry[foo] @ git+https://github.com/python-poetry/poetry.git" assert expected == dependency.to_pep_508() @@ -37,7 +37,9 @@ def test_to_pep_508_in_extras(): ) dependency.in_extras.append("foo") - expected = 'poetry @ git+https://github.com/python-poetry/poetry.git@master ; extra == "foo"' + expected = ( + 'poetry @ git+https://github.com/python-poetry/poetry.git ; extra == "foo"' + ) assert expected == dependency.to_pep_508() dependency = VCSDependency( @@ -45,7 +47,9 @@ def test_to_pep_508_in_extras(): ) dependency.in_extras.append("foo") - expected = 'poetry[bar] @ git+https://github.com/python-poetry/poetry.git@master ; extra == "foo"' + expected = ( + 'poetry[bar] @ git+https://github.com/python-poetry/poetry.git ; extra == "foo"' + ) assert expected == dependency.to_pep_508() From 3854e17994b5929051bdbea7f01fd0b83c92363a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Eustace?= Date: Fri, 23 Jul 2021 15:54:33 +0200 Subject: [PATCH 2/5] Prefer resolved references for comparison --- poetry/core/packages/specification.py | 12 ++++++++++++ tests/packages/test_vcs_dependency.py | 19 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/poetry/core/packages/specification.py b/poetry/core/packages/specification.py index 3137f7f51..8e7ba6239 100644 --- a/poetry/core/packages/specification.py +++ b/poetry/core/packages/specification.py @@ -76,6 +76,18 @@ def is_same_package_as(self, other: "PackageSpecification") -> bool: if self._source_url != other.source_url: return False + # We check the resolved reference first: + # if they match we assume equality regardless + # of their source reference. + # This is important when comparing a resolved branch VCS + # dependency to a direct commit reference VCS dependency + if ( + self._source_resolved_reference + and other.source_resolved_reference + and self._source_resolved_reference == other.source_resolved_reference + ): + return True + if self._source_reference or other.source_reference: # special handling for packages with references if not self._source_reference or not other.source_reference: diff --git a/tests/packages/test_vcs_dependency.py b/tests/packages/test_vcs_dependency.py index be8534e7d..e7c759759 100644 --- a/tests/packages/test_vcs_dependency.py +++ b/tests/packages/test_vcs_dependency.py @@ -86,3 +86,22 @@ def test_vcs_dependency_can_have_resolved_reference_specified(): assert dependency.branch == "develop" assert dependency.source_reference == "develop" assert dependency.source_resolved_reference == "123456" + + +def test_vcs_dependencies_are_equal_if_resolved_references_match(): + dependency1 = VCSDependency( + "poetry", + "git", + "https://github.com/python-poetry/poetry.git", + branch="develop", + resolved_rev="123456", + ) + dependency2 = VCSDependency( + "poetry", + "git", + "https://github.com/python-poetry/poetry.git", + rev="123", + resolved_rev="123456", + ) + + assert dependency1 == dependency2 From 3144f1fb2feeb754bd69966dd7ee80028022c128 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Eustace?= Date: Fri, 23 Jul 2021 18:37:41 +0200 Subject: [PATCH 3/5] Add support for subdirectories for VCS dependencies Co-authored-by: finswimmer <2164565+finswimmer@users.noreply.github.com> --- poetry/core/factory.py | 1 + poetry/core/json/schemas/poetry-schema.json | 4 + poetry/core/packages/dependency.py | 9 +- poetry/core/packages/vcs_dependency.py | 9 ++ poetry/core/vcs/git.py | 53 +++++++-- tests/packages/test_main.py | 13 +++ tests/vcs/test_vcs.py | 122 +++++++++++++++++--- 7 files changed, 184 insertions(+), 27 deletions(-) diff --git a/poetry/core/factory.py b/poetry/core/factory.py index d3becd29e..7dbc8ff2d 100644 --- a/poetry/core/factory.py +++ b/poetry/core/factory.py @@ -274,6 +274,7 @@ def create_dependency( branch=constraint.get("branch", None), tag=constraint.get("tag", None), rev=constraint.get("rev", None), + directory=constraint.get("subdirectory", None), groups=groups, optional=optional, develop=constraint.get("develop", False), diff --git a/poetry/core/json/schemas/poetry-schema.json b/poetry/core/json/schemas/poetry-schema.json index b1493503a..708e000f8 100644 --- a/poetry/core/json/schemas/poetry-schema.json +++ b/poetry/core/json/schemas/poetry-schema.json @@ -373,6 +373,10 @@ "type": "string", "description": "The revision to checkout." }, + "subdirectory": { + "type": "string", + "description": "The relative path to the directory where the package is located." + }, "python": { "type": "string", "description": "The python versions for which the dependency should be installed." diff --git a/poetry/core/packages/dependency.py b/poetry/core/packages/dependency.py index 9c0d729a4..9e495a27d 100644 --- a/poetry/core/packages/dependency.py +++ b/poetry/core/packages/dependency.py @@ -435,7 +435,7 @@ def create_from_pep_508( from .vcs_dependency import VCSDependency # Removing comments - parts = name.split("#", 1) + parts = name.split(" #", 1) name = parts[0].strip() if len(parts) > 1: rest = parts[1] @@ -497,7 +497,12 @@ def create_from_pep_508( if link.scheme.startswith("git+"): url = ParsedUrl.parse(link.url) dep = VCSDependency( - name, "git", url.url, rev=url.rev, extras=req.extras + name, + "git", + url.url, + rev=url.rev, + directory=url.subdirectory, + extras=req.extras, ) elif link.scheme == "git": dep = VCSDependency( diff --git a/poetry/core/packages/vcs_dependency.py b/poetry/core/packages/vcs_dependency.py index e51cec20f..db96fe726 100644 --- a/poetry/core/packages/vcs_dependency.py +++ b/poetry/core/packages/vcs_dependency.py @@ -25,6 +25,7 @@ def __init__( tag: Optional[str] = None, rev: Optional[str] = None, resolved_rev: Optional[str] = None, + directory: Optional[str] = None, groups: Optional[List[str]] = None, optional: bool = False, develop: bool = False, @@ -36,6 +37,7 @@ def __init__( self._branch = branch self._tag = tag self._rev = rev + self._directory = directory self._develop = develop super(VCSDependency, self).__init__( @@ -71,6 +73,10 @@ def tag(self) -> Optional[str]: def rev(self) -> Optional[str]: return self._rev + @property + def directory(self) -> Optional[str]: + return self._directory + @property def develop(self) -> bool: return self._develop @@ -111,6 +117,9 @@ def base_pep_508_name(self) -> str: if self.reference: requirement += f"@{self.reference}" + if self._directory: + requirement += f"#subdirectory{self._directory}" + return requirement def is_vcs(self) -> bool: diff --git a/poetry/core/vcs/git.py b/poetry/core/vcs/git.py index 1633ad090..3c923538d 100644 --- a/poetry/core/vcs/git.py +++ b/poetry/core/vcs/git.py @@ -14,7 +14,8 @@ "port": r"\d+", "path": r"[\w~.\-/\\]+", "name": r"[\w~.\-]+", - "rev": r"[^@#]+", + "rev": r"[^@#]+?", + "subdir": r"[\w\-/\\]+", } PATTERNS = [ @@ -26,7 +27,13 @@ r"(:(?P{port}))?" r"(?P[:/\\]({path}[/\\])?" r"((?P{name}?)(\.git|[/\\])?)?)" - r"([@#](?P{rev}))?" + r"(?:" + r"#egg=?.+" + r"|" + r"#(?:egg=.+?&subdirectory=|subdirectory=)(?P{subdir})" + r"|" + r"[@#](?P{rev})(?:[&#](?:egg=.+?|(?:egg=.+?&subdirectory=|subdirectory=)(?P{subdir})))?" + r")?" r"$".format( user=pattern_formats["user"], resource=pattern_formats["resource"], @@ -34,6 +41,7 @@ path=pattern_formats["path"], name=pattern_formats["name"], rev=pattern_formats["rev"], + subdir=pattern_formats["subdir"], ) ), re.compile( @@ -44,7 +52,13 @@ r"(:(?P{port}))?" r"(?P({path})" r"(?P{name})(\.git|/)?)" - r"([@#](?P{rev}))?" + r"(?:" + r"#egg=?.+" + r"|" + r"#(?:egg=.+?&subdirectory=|subdirectory=)(?P{subdir})" + r"|" + r"[@#](?P{rev})(?:[&#](?:egg=.+?|(?:egg=.+?&subdirectory=|subdirectory=)(?P{subdir})))?" + r")?" r"$".format( protocol=pattern_formats["protocol"], user=pattern_formats["user"], @@ -53,6 +67,7 @@ path=pattern_formats["path"], name=pattern_formats["name"], rev=pattern_formats["rev"], + subdir=pattern_formats["subdir"], ) ), re.compile( @@ -61,7 +76,13 @@ r"(:(?P{port}))?" r"(?P([:/]{path}/)" r"(?P{name})(\.git|/)?)" - r"([@#](?P{rev}))?" + r"(?:" + r"#egg=.+?" + r"|" + r"#(?:egg=.+?&subdirectory=|subdirectory=)(?P{subdir})" + r"|" + r"[@#](?P{rev})(?:[&#](?:egg=.+?&subdirectory=|subdirectory=)(?P{subdir}))?" + r")?" r"$".format( user=pattern_formats["user"], resource=pattern_formats["resource"], @@ -69,6 +90,7 @@ path=pattern_formats["path"], name=pattern_formats["name"], rev=pattern_formats["rev"], + subdir=pattern_formats["subdir"], ) ), re.compile( @@ -77,13 +99,20 @@ r"[:/]{{1,2}}" r"(?P({path})" r"(?P{name})(\.git|/)?)" - r"([@#](?P{rev}))?" + r"(?:" + r"#egg=?.+" + r"|" + r"#(?:egg=.+?&subdirectory=|subdirectory=)(?P{subdir})" + r"|" + r"[@#](?P{rev})(?:[&#](?:egg=.+?|(?:egg=.+?&subdirectory=|subdirectory=)(?P{subdir})))?" + r")?" r"$".format( user=pattern_formats["user"], resource=pattern_formats["resource"], path=pattern_formats["path"], name=pattern_formats["name"], rev=pattern_formats["rev"], + subdir=pattern_formats["subdir"], ) ), ] @@ -99,6 +128,7 @@ def __init__( port: Optional[str], name: Optional[str], rev: Optional[str], + subdirectory: Optional[str] = None, ): self.protocol = protocol self.resource = resource @@ -107,6 +137,7 @@ def __init__( self.port = port self.name = name self.rev = rev + self.subdirectory = subdirectory @classmethod def parse(cls, url: str) -> "ParsedUrl": @@ -122,6 +153,7 @@ def parse(cls, url: str) -> "ParsedUrl": groups.get("port"), groups.get("name"), groups.get("rev"), + groups.get("rev_subdirectory") or groups.get("subdirectory"), ) raise ValueError('Invalid git url "{}"'.format(url)) @@ -143,7 +175,7 @@ def __str__(self) -> str: return self.format() -GitUrl = namedtuple("GitUrl", ["url", "revision"]) +GitUrl = namedtuple("GitUrl", ["url", "revision", "subdirectory"]) class GitConfig: @@ -183,6 +215,11 @@ def normalize_url(cls, url: str) -> GitUrl: if parsed.rev: formatted = re.sub(r"[#@]{}$".format(parsed.rev), "", formatted) + if parsed.subdirectory: + formatted = re.sub( + r"[#&]subdirectory={}$".format(parsed.subdirectory), "", formatted + ) + altered = parsed.format() != formatted if altered: @@ -197,7 +234,9 @@ def normalize_url(cls, url: str) -> GitUrl: else: normalized = parsed.format() - return GitUrl(re.sub(r"#[^#]*$", "", normalized), parsed.rev) + return GitUrl( + re.sub(r"#[^#]*$", "", normalized), parsed.rev, parsed.subdirectory + ) @property def config(self) -> GitConfig: diff --git a/tests/packages/test_main.py b/tests/packages/test_main.py index b8c1eed9c..c25158c54 100644 --- a/tests/packages/test_main.py +++ b/tests/packages/test_main.py @@ -184,6 +184,19 @@ def test_dependency_from_pep_508_with_git_url(): assert "1.2" == dep.reference +def test_dependency_from_pep_508_with_git_url_and_subdirectory(): + name = "django-utils @ git+ssh://git@corp-gitlab.com/corp-utils.git@1.2#subdirectory=package-dir" + + dep = Dependency.create_from_pep_508(name) + + assert "django-utils" == dep.name + assert dep.is_vcs() + assert "git" == dep.vcs + assert "ssh://git@corp-gitlab.com/corp-utils.git" == dep.source + assert "1.2" == dep.reference + assert "package-dir" == dep.directory + + def test_dependency_from_pep_508_with_git_url_and_comment_and_extra(): name = ( "poetry @ git+https://github.com/python-poetry/poetry.git@b;ar;#egg=poetry" diff --git a/tests/vcs/test_vcs.py b/tests/vcs/test_vcs.py index ebd518cc7..52cf32d68 100644 --- a/tests/vcs/test_vcs.py +++ b/tests/vcs/test_vcs.py @@ -10,73 +10,82 @@ [ ( "git+ssh://user@hostname:project.git#commit", - GitUrl("user@hostname:project.git", "commit"), + GitUrl("user@hostname:project.git", "commit", None), ), ( "git+http://user@hostname/project/blah.git@commit", - GitUrl("http://user@hostname/project/blah.git", "commit"), + GitUrl("http://user@hostname/project/blah.git", "commit", None), ), ( "git+https://user@hostname/project/blah.git", - GitUrl("https://user@hostname/project/blah.git", None), + GitUrl("https://user@hostname/project/blah.git", None, None), ), ( "git+https://user@hostname/project~_-.foo/blah~_-.bar.git", - GitUrl("https://user@hostname/project~_-.foo/blah~_-.bar.git", None), + GitUrl("https://user@hostname/project~_-.foo/blah~_-.bar.git", None, None), ), ( "git+https://user@hostname:project/blah.git", - GitUrl("https://user@hostname/project/blah.git", None), + GitUrl("https://user@hostname/project/blah.git", None, None), ), ( "git+ssh://git@github.com:sdispater/poetry.git#v1.0.27", - GitUrl("git@github.com:sdispater/poetry.git", "v1.0.27"), + GitUrl("git@github.com:sdispater/poetry.git", "v1.0.27", None), ), ( "git+ssh://git@github.com:/sdispater/poetry.git", - GitUrl("git@github.com:/sdispater/poetry.git", None), + GitUrl("git@github.com:/sdispater/poetry.git", None, None), ), ( "git+ssh://git@github.com:org/repo", - GitUrl("git@github.com:org/repo", None), + GitUrl("git@github.com:org/repo", None, None), ), ( "git+ssh://git@github.com/org/repo", - GitUrl("ssh://git@github.com/org/repo", None), + GitUrl("ssh://git@github.com/org/repo", None, None), ), - ("git+ssh://foo:22/some/path", GitUrl("ssh://foo:22/some/path", None)), - ("git@github.com:org/repo", GitUrl("git@github.com:org/repo", None)), + ("git+ssh://foo:22/some/path", GitUrl("ssh://foo:22/some/path", None, None)), + ("git@github.com:org/repo", GitUrl("git@github.com:org/repo", None, None)), ( "git+https://github.com/sdispater/pendulum", - GitUrl("https://github.com/sdispater/pendulum", None), + GitUrl("https://github.com/sdispater/pendulum", None, None), ), ( "git+https://github.com/sdispater/pendulum#7a018f2d075b03a73409e8356f9b29c9ad4ea2c5", GitUrl( "https://github.com/sdispater/pendulum", "7a018f2d075b03a73409e8356f9b29c9ad4ea2c5", + None, ), ), ( "git+ssh://git@git.example.com:b/b.git#v1.0.0", - GitUrl("git@git.example.com:b/b.git", "v1.0.0"), + GitUrl("git@git.example.com:b/b.git", "v1.0.0", None), ), ( "git+ssh://git@github.com:sdispater/pendulum.git#foo/bar", - GitUrl("git@github.com:sdispater/pendulum.git", "foo/bar"), + GitUrl("git@github.com:sdispater/pendulum.git", "foo/bar", None), ), - ("git+file:///foo/bar.git", GitUrl("file:///foo/bar.git", None)), + ("git+file:///foo/bar.git", GitUrl("file:///foo/bar.git", None, None)), ( "git+file://C:\\Users\\hello\\testing.git#zkat/windows-files", - GitUrl("file://C:\\Users\\hello\\testing.git", "zkat/windows-files"), + GitUrl("file://C:\\Users\\hello\\testing.git", "zkat/windows-files", None), ), ( "git+https://git.example.com/sdispater/project/my_repo.git", - GitUrl("https://git.example.com/sdispater/project/my_repo.git", None), + GitUrl("https://git.example.com/sdispater/project/my_repo.git", None, None), ), ( "git+ssh://git@git.example.com:sdispater/project/my_repo.git", - GitUrl("git@git.example.com:sdispater/project/my_repo.git", None), + GitUrl("git@git.example.com:sdispater/project/my_repo.git", None, None), + ), + ( + "git+https://github.com/demo/pyproject-demo-subdirectory.git#subdirectory=project", + GitUrl( + "https://github.com/demo/pyproject-demo-subdirectory.git", + None, + "project", + ), ), ], ) @@ -135,6 +144,18 @@ def test_normalize_url(url, normalized): "v1.0.27", ), ), + ( + "git+ssh://git@github.com:sdispater/poetry.git#egg=name", + ParsedUrl( + "ssh", + "github.com", + ":sdispater/poetry.git", + "git", + None, + "poetry", + None, + ), + ), ( "git+ssh://git@github.com:/sdispater/poetry.git", ParsedUrl( @@ -243,6 +264,71 @@ def test_normalize_url(url, normalized): None, ), ), + ( + "git+ssh://git@git.example.com:sdispater/project/my_repo.git#subdirectory=project-dir", + ParsedUrl( + "ssh", + "git.example.com", + ":sdispater/project/my_repo.git", + "git", + None, + "my_repo", + None, + "project-dir", + ), + ), + ( + "git+ssh://git@git.example.com:sdispater/project/my_repo.git#commit&subdirectory=project-dir", + ParsedUrl( + "ssh", + "git.example.com", + ":sdispater/project/my_repo.git", + "git", + None, + "my_repo", + "commit", + "project-dir", + ), + ), + ( + "git+ssh://git@git.example.com:sdispater/project/my_repo.git@commit#subdirectory=project-dir", + ParsedUrl( + "ssh", + "git.example.com", + ":sdispater/project/my_repo.git", + "git", + None, + "my_repo", + "commit", + "project-dir", + ), + ), + ( + "git+ssh://git@git.example.com:sdispater/project/my_repo.git@commit&subdirectory=project_dir", + ParsedUrl( + "ssh", + "git.example.com", + ":sdispater/project/my_repo.git", + "git", + None, + "my_repo", + "commit", + "project_dir", + ), + ), + ( + "git+ssh://git@git.example.com:sdispater/project/my_repo.git@commit#egg=package&subdirectory=project_dir", + ParsedUrl( + "ssh", + "git.example.com", + ":sdispater/project/my_repo.git", + "git", + None, + "my_repo", + "commit", + "project_dir", + ), + ), ], ) def test_parse_url(url, parsed): From 2b7673e1200b8b8f50fe243d17f8a6b5157ce449 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Eustace?= Date: Fri, 20 Aug 2021 11:20:59 +0200 Subject: [PATCH 4/5] Add the source subdirectory at the specification level --- poetry/core/packages/dependency.py | 2 ++ poetry/core/packages/package.py | 3 +++ poetry/core/packages/specification.py | 6 ++++++ poetry/core/packages/vcs_dependency.py | 2 ++ tests/packages/test_package.py | 26 ++++++++++++++++++++++++++ 5 files changed, 39 insertions(+) diff --git a/poetry/core/packages/dependency.py b/poetry/core/packages/dependency.py index 9e495a27d..0ea6d127b 100644 --- a/poetry/core/packages/dependency.py +++ b/poetry/core/packages/dependency.py @@ -41,6 +41,7 @@ def __init__( source_url: Optional[str] = None, source_reference: Optional[str] = None, source_resolved_reference: Optional[str] = None, + source_subdirectory: Optional[str] = None, ): from poetry.core.version.markers import AnyMarker @@ -50,6 +51,7 @@ def __init__( source_url=source_url, source_reference=source_reference, source_resolved_reference=source_resolved_reference, + source_subdirectory=source_subdirectory, features=extras, ) diff --git a/poetry/core/packages/package.py b/poetry/core/packages/package.py index ff2851360..2c8e8a031 100644 --- a/poetry/core/packages/package.py +++ b/poetry/core/packages/package.py @@ -51,6 +51,7 @@ def __init__( source_url: Optional[str] = None, source_reference: Optional[str] = None, source_resolved_reference: Optional[str] = None, + source_subdirectory: Optional[str] = None, features: Optional[List[str]] = None, develop: bool = False, ) -> None: @@ -66,6 +67,7 @@ def __init__( source_url=source_url, source_reference=source_reference, source_resolved_reference=source_resolved_reference, + source_subdirectory=source_subdirectory, features=features, ) @@ -468,6 +470,7 @@ def to_dependency( self.source_url, rev=self.source_reference, resolved_rev=self.source_resolved_reference, + directory=self.source_subdirectory, groups=list(self._dependency_groups.keys()), optional=self.optional, develop=self.develop, diff --git a/poetry/core/packages/specification.py b/poetry/core/packages/specification.py index 8e7ba6239..08e6e2c44 100644 --- a/poetry/core/packages/specification.py +++ b/poetry/core/packages/specification.py @@ -11,6 +11,7 @@ def __init__( source_url: Optional[str] = None, source_reference: Optional[str] = None, source_resolved_reference: Optional[str] = None, + source_subdirectory: Optional[str] = None, features: Optional[List[str]] = None, ): from poetry.core.utils.helpers import canonicalize_name @@ -21,6 +22,7 @@ def __init__( self._source_url = source_url self._source_reference = source_reference self._source_resolved_reference = source_resolved_reference + self._source_subdirectory = source_subdirectory if not features: features = [] @@ -60,6 +62,10 @@ def source_reference(self) -> Optional[str]: def source_resolved_reference(self) -> Optional[str]: return self._source_resolved_reference + @property + def source_subdirectory(self) -> Optional[str]: + return self._source_subdirectory + @property def features(self) -> FrozenSet[str]: return self._features diff --git a/poetry/core/packages/vcs_dependency.py b/poetry/core/packages/vcs_dependency.py index db96fe726..51b8da4d6 100644 --- a/poetry/core/packages/vcs_dependency.py +++ b/poetry/core/packages/vcs_dependency.py @@ -50,6 +50,7 @@ def __init__( source_url=self._source, source_reference=branch or tag or rev, source_resolved_reference=resolved_rev, + source_subdirectory=directory, extras=extras, ) @@ -137,6 +138,7 @@ def with_constraint(self, constraint: "BaseConstraint") -> "VCSDependency": tag=self._tag, rev=self._rev, resolved_rev=self._source_resolved_reference, + directory=self.directory, optional=self.is_optional(), groups=list(self._groups), develop=self._develop, diff --git a/tests/packages/test_package.py b/tests/packages/test_package.py index 799255d2b..6e9f971d9 100644 --- a/tests/packages/test_package.py +++ b/tests/packages/test_package.py @@ -301,6 +301,32 @@ def test_to_dependency_for_url(): assert "https://example.com/path.tar.gz" == dep.source_url +def test_to_dependency_for_vcs(): + package = Package( + "foo", + "1.2.3", + source_type="git", + source_url="https://github.com/foo/foo.git", + source_reference="master", + source_resolved_reference="123456", + source_subdirectory="baz", + features=["baz", "bar"], + ) + dep = package.to_dependency() + + assert "foo" == dep.name + assert package.version == dep.constraint + assert frozenset({"bar", "baz"}) == dep.features + assert dep.is_vcs() + assert "git" == dep.source_type + assert "https://github.com/foo/foo.git" == dep.source + assert "master" == dep.reference + assert "master" == dep.source_reference + assert "123456" == dep.source_resolved_reference + assert "baz" == dep.directory + assert "baz" == dep.source_subdirectory + + def test_package_clone(f): # TODO(nic): this test is not future-proof, in that any attributes added # to the Package object and not filled out in this test setup might From 9e223ad7bd9c237ffdf80780ae4aa7c7dc3dac62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Eustace?= Date: Fri, 20 Aug 2021 16:13:46 +0200 Subject: [PATCH 5/5] Add a convenience method to retrieve the current git branch Co-authored-by: grimmer0125 <5940941+grimmer0125@users.noreply.github.com> --- poetry/core/vcs/git.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/poetry/core/vcs/git.py b/poetry/core/vcs/git.py index 3c923538d..220b5018c 100644 --- a/poetry/core/vcs/git.py +++ b/poetry/core/vcs/git.py @@ -267,14 +267,6 @@ def rev_parse(self, rev: str, folder: Optional[Path] = None) -> str: if folder is None and self._work_dir: folder = self._work_dir - if folder: - args += [ - "--git-dir", - (folder / ".git").as_posix(), - "--work-tree", - folder.as_posix(), - ] - # We need "^0" (an alternative to "^{commit}") to ensure that the # commit SHA of the commit the tag points to is returned, even in # the case of annotated tags. @@ -285,7 +277,15 @@ def rev_parse(self, rev: str, folder: Optional[Path] = None) -> str: # they should not be escaped. args += ["rev-parse", rev + "^0"] - return self.run(*args) + return self.run(*args, folder=folder) + + def get_current_branch(self, folder: Optional[Path] = None) -> str: + if folder is None and self._work_dir: + folder = self._work_dir + + output = self.run("symbolic-ref", "--short", "HEAD", folder=folder) + + return output.strip() def get_ignored_files(self, folder: Optional[Path] = None) -> list: args = []