Commit 58e3676c by Sébastien Eustace

Improve installation of directory and git dependencies

parent 179c4d2a
...@@ -23,6 +23,16 @@ class PipInstaller(BaseInstaller): ...@@ -23,6 +23,16 @@ class PipInstaller(BaseInstaller):
self._io = io self._io = io
def install(self, package, update=False): def install(self, package, update=False):
if package.source_type == "directory":
self.install_directory(package, update=update)
return
if package.source_type == "git":
self.install_git(package)
return
args = ["install", "--no-deps"] args = ["install", "--no-deps"]
if package.source_type == "legacy" and package.source_url: if package.source_type == "legacy" and package.source_url:
...@@ -129,3 +139,72 @@ class PipInstaller(BaseInstaller): ...@@ -129,3 +139,72 @@ class PipInstaller(BaseInstaller):
os.close(fd) os.close(fd)
return name return name
def install_directory(self, package, update=False):
from poetry.io import NullIO
from poetry.masonry.builder import SdistBuilder
from poetry.poetry import Poetry
from poetry.utils._compat import decode
from poetry.utils.env import NullEnv
from poetry.utils.toml_file import TomlFile
if package.root_dir:
req = os.path.join(package.root_dir, package.source_url)
else:
req = os.path.realpath(package.source_url)
args = ["install", "--no-deps", "-U"]
pyproject = TomlFile(os.path.join(req, "pyproject.toml"))
has_poetry = False
if pyproject.exists():
pyproject_content = pyproject.read()
has_poetry = (
"tool" in pyproject_content and "poetry" in pyproject_content["tool"]
)
has_build_system = "build-system" in pyproject_content
setup = os.path.join(req, "setup.py")
has_setup = os.path.exists(setup)
if not has_setup and has_poetry and (package.develop or not has_build_system):
# We actually need to rely on creating a temporary setup.py
# file since pip, as of this comment, does not support
# build-system for editable packages
# We also need it for non-PEP-517 packages
builder = SdistBuilder(Poetry.create(pyproject.parent), NullEnv(), NullIO())
with open(setup, "w") as f:
f.write(decode(builder.build_setup()))
if package.develop:
args.append("-e")
args.append(req)
try:
return self.run(*args)
finally:
if not has_setup and os.path.exists(setup):
os.remove(setup)
def install_git(self, package):
from poetry.packages import Package
from poetry.utils._compat import Path
from poetry.utils.helpers import temporary_directory
from poetry.vcs import Git
with temporary_directory() as tmp_dir:
tmp_dir = Path(tmp_dir)
git = Git()
git.clone(package.source_url, tmp_dir)
git.checkout(package.source_reference, tmp_dir)
# Now we just need to install from the temporary directory
pkg = Package(package.name, package.version)
pkg.source_type = "directory"
pkg.source_url = str(tmp_dir)
pkg.develop = False
self.install_directory(pkg)
...@@ -9,7 +9,6 @@ from poetry.utils._compat import Path ...@@ -9,7 +9,6 @@ from poetry.utils._compat import Path
from poetry.utils._compat import decode from poetry.utils._compat import decode
from poetry.utils.helpers import parse_requires from poetry.utils.helpers import parse_requires
from poetry.utils.toml_file import TomlFile from poetry.utils.toml_file import TomlFile
from poetry.utils.env import NullEnv
from poetry.utils.env import Env from poetry.utils.env import Env
from .dependency import Dependency from .dependency import Dependency
...@@ -27,7 +26,7 @@ class DirectoryDependency(Dependency): ...@@ -27,7 +26,7 @@ class DirectoryDependency(Dependency):
category="main", # type: str category="main", # type: str
optional=False, # type: bool optional=False, # type: bool
base=None, # type: Path base=None, # type: Path
develop=False, # type: bool develop=True, # type: bool
): ):
from . import dependency_from_pep_508 from . import dependency_from_pep_508
from .package import Package from .package import Package
...@@ -36,6 +35,7 @@ class DirectoryDependency(Dependency): ...@@ -36,6 +35,7 @@ class DirectoryDependency(Dependency):
self._base = base self._base = base
self._full_path = path self._full_path = path
self._develop = develop self._develop = develop
self._supports_poetry = False
if self._base and not self._path.is_absolute(): if self._base and not self._path.is_absolute():
self._full_path = self._base / self._path self._full_path = self._base / self._path
...@@ -49,29 +49,23 @@ class DirectoryDependency(Dependency): ...@@ -49,29 +49,23 @@ class DirectoryDependency(Dependency):
# Checking content to dertermine actions # Checking content to dertermine actions
setup = self._full_path / "setup.py" setup = self._full_path / "setup.py"
pyproject = TomlFile(self._full_path / "pyproject.toml") pyproject = TomlFile(self._full_path / "pyproject.toml")
has_poetry = False
if pyproject.exists(): if pyproject.exists():
pyproject_content = pyproject.read() pyproject_content = pyproject.read()
has_poetry = ( self._supports_poetry = (
"tool" in pyproject_content and "poetry" in pyproject_content["tool"] "tool" in pyproject_content and "poetry" in pyproject_content["tool"]
) )
if not setup.exists() and not has_poetry: if not setup.exists() and not self._supports_poetry:
raise ValueError( raise ValueError(
"Directory {} does not seem to be a Python package".format( "Directory {} does not seem to be a Python package".format(
self._full_path self._full_path
) )
) )
if has_poetry: if self._supports_poetry:
from poetry.masonry.builders import SdistBuilder
from poetry.poetry import Poetry from poetry.poetry import Poetry
poetry = Poetry.create(self._full_path) poetry = Poetry.create(self._full_path)
builder = SdistBuilder(poetry, NullEnv(), NullIO())
with setup.open("w") as f:
f.write(decode(builder.build_setup()))
package = poetry.package package = poetry.package
self._package = Package(package.pretty_name, package.version) self._package = Package(package.pretty_name, package.version)
...@@ -148,5 +142,8 @@ class DirectoryDependency(Dependency): ...@@ -148,5 +142,8 @@ class DirectoryDependency(Dependency):
def develop(self): def develop(self):
return self._develop return self._develop
def supports_poetry(self):
return self._supports_poetry
def is_directory(self): def is_directory(self):
return True return True
...@@ -75,7 +75,7 @@ class Package(object): ...@@ -75,7 +75,7 @@ class Package(object):
self.root_dir = None self.root_dir = None
self.develop = False self.develop = True
@property @property
def name(self): def name(self):
...@@ -106,6 +106,9 @@ class Package(object): ...@@ -106,6 +106,9 @@ class Package(object):
@property @property
def full_pretty_version(self): def full_pretty_version(self):
if self.source_type in ["file", "directory"]:
return "{} {}".format(self._pretty_version, self.source_url)
if self.source_type not in ["hg", "git"]: if self.source_type not in ["hg", "git"]:
return self._pretty_version return self._pretty_version
...@@ -266,7 +269,7 @@ class Package(object): ...@@ -266,7 +269,7 @@ class Package(object):
category=category, category=category,
optional=optional, optional=optional,
base=self.root_dir, base=self.root_dir,
develop=constraint.get("develop", False), develop=constraint.get("develop", True),
) )
else: else:
version = constraint["version"] version = constraint["version"]
......
...@@ -197,7 +197,7 @@ Package operations: 2 installs, 0 updates, 0 removals ...@@ -197,7 +197,7 @@ Package operations: 2 installs, 0 updates, 0 removals
Writing lock file Writing lock file
- Installing pendulum (1.4.4) - Installing pendulum (1.4.4)
- Installing demo (0.1.0) - Installing demo (0.1.0 ../distributions/demo-0.1.0-py2.py3-none-any.whl)
""" """
assert tester.get_display(True) == expected assert tester.get_display(True) == expected
...@@ -237,7 +237,7 @@ Package operations: 2 installs, 0 updates, 0 removals ...@@ -237,7 +237,7 @@ Package operations: 2 installs, 0 updates, 0 removals
Writing lock file Writing lock file
- Installing pendulum (1.4.4) - Installing pendulum (1.4.4)
- Installing demo (0.1.0) - Installing demo (0.1.0 ../distributions/demo-0.1.0.tar.gz)
""" """
assert tester.get_display(True) == expected assert tester.get_display(True) == expected
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment