def install_git(self, package: Package) -> None: from poetry.core.packages.package import Package from poetry.core.vcs.git import Git src_dir = self._env.path / "src" / package.name if src_dir.exists(): safe_rmtree(str(src_dir)) src_dir.parent.mkdir(exist_ok=True) git = Git() git.clone(package.source_url, src_dir) reference = package.source_resolved_reference if not reference: reference = package.source_reference git.checkout(reference, src_dir) # Now we just need to install from the source directory pkg = Package(package.name, package.version) pkg._source_type = "directory" pkg._source_url = str(src_dir) pkg.develop = package.develop self.install_directory(pkg)
def test_requirement_git_develop_false(installer: PipInstaller, package_git: Package): package_git.develop = False result = installer.requirement(package_git) expected = "[email protected]:demo/demo.git@master#egg=demo" assert expected == result
def test_requirement_git_develop_true(installer: PipInstaller, package_git: Package): package_git.develop = True result = installer.requirement(package_git) expected = ["-e", "[email protected]:demo/demo.git@master#egg=demo"] assert result == expected
def test_execute_executes_a_batch_of_operations(config, pool, io, tmp_dir, mock_file_downloads, env): config = Config() config.merge({"cache-dir": tmp_dir}) executor = Executor(env, pool, config, io) file_package = Package( "demo", "0.1.0", source_type="file", source_url=Path(__file__).parent.parent.joinpath( "fixtures/distributions/demo-0.1.0-py2.py3-none-any.whl").resolve( ).as_posix(), ) directory_package = Package( "simple-project", "1.2.3", source_type="directory", source_url=Path(__file__).parent.parent.joinpath( "fixtures/simple_project").resolve().as_posix(), ) directory_package.develop = True git_package = Package( "demo", "0.1.0", source_type="git", source_reference="master", source_url="https://github.com/demo/demo.git", ) return_code = executor.execute([ Install(Package("pytest", "3.5.2")), Uninstall(Package("attrs", "17.4.0")), Update(Package("requests", "2.18.3"), Package("requests", "2.18.4")), Uninstall(Package("clikit", "0.2.3")).skip("Not currently installed"), Install(file_package), Install(directory_package), Install(git_package), ]) expected = """ Package operations: 4 installs, 1 update, 1 removal • Installing pytest (3.5.2) • Removing attrs (17.4.0) • Updating requests (2.18.3 -> 2.18.4) • Installing demo (0.1.0 {}) • Installing simple-project (1.2.3 {}) • Installing demo (0.1.0 master) """.format(file_package.source_url, directory_package.source_url) expected = set(expected.splitlines()) output = set(io.fetch_output().splitlines()) assert expected == output assert 6 == len(env.executed) assert 0 == return_code
def install_git(self, package: Package) -> None: from poetry.core.packages.package import Package from poetry.vcs.git import Git source = Git.clone( url=package.source_url, source_root=self._env.path / "src", revision=package.source_resolved_reference or package.source_reference, ) # Now we just need to install from the source directory pkg = Package(package.name, package.version) pkg._source_type = "directory" pkg._source_url = str(source.path) pkg.develop = package.develop self.install_directory(pkg)
def test_uninstall_git_package_nspkg_pth_cleanup(mocker, tmp_venv, pool): # this test scenario requires a real installation using the pip installer installer = PipInstaller(tmp_venv, NullIO(), pool) # use a namepspace package package = Package("namespace-package-one", "1.0.0") package.source_type = "git" package.source_url = "https://github.com/demo/namespace-package-one.git" package.source_reference = "master" package.develop = True # we do this here because the virtual env might not be usable if failure case is triggered pth_file_candidate = tmp_venv.site_packages / "{}-nspkg.pth".format( package.name) # in order to reproduce the scenario where the git source is removed prior to proper # clean up of nspkg.pth file, we need to make sure the fixture is copied and not # symlinked into the git src directory def copy_only(source, dest): if dest.exists(): dest.unlink() if source.is_dir(): shutil.copytree(str(source), str(dest)) else: shutil.copyfile(str(source), str(dest)) mocker.patch("tests.helpers.copy_or_symlink", new=copy_only) # install package and then remove it installer.install(package) installer.remove(package) assert not Path(pth_file_candidate).exists() # any command in the virtual environment should trigger the error message output = tmp_venv.run("python", "-m", "site") assert "Error processing line 1 of {}".format( pth_file_candidate) not in output
def locked_repository( self, with_dev_reqs: bool = False) -> poetry.repositories.Repository: """ Searches and returns a repository of locked packages. """ from poetry.factory import Factory if not self.is_locked(): return poetry.repositories.Repository() lock_data = self.lock_data packages = poetry.repositories.Repository() if with_dev_reqs: locked_packages = lock_data["package"] else: locked_packages = [ p for p in lock_data["package"] if p["category"] == "main" ] if not locked_packages: return packages for info in locked_packages: source = info.get("source", {}) source_type = source.get("type") url = source.get("url") if source_type in ["directory", "file"]: url = self._lock.path.parent.joinpath(url).resolve().as_posix() package = Package( info["name"], info["version"], info["version"], source_type=source_type, source_url=url, source_reference=source.get("reference"), source_resolved_reference=source.get("resolved_reference"), ) package.description = info.get("description", "") package.category = info.get("category", "main") package.groups = info.get("groups", ["default"]) package.optional = info["optional"] if "hashes" in lock_data["metadata"]: # Old lock so we create dummy files from the hashes package.files = [{ "name": h, "hash": h } for h in lock_data["metadata"]["hashes"][info["name"]]] else: package.files = lock_data["metadata"]["files"][info["name"]] package.python_versions = info["python-versions"] extras = info.get("extras", {}) if extras: for name, deps in extras.items(): package.extras[name] = [] for dep in deps: try: dependency = Dependency.create_from_pep_508(dep) except InvalidRequirement: # handle lock files with invalid PEP 508 m = re.match( r"^(.+?)(?:\[(.+?)])?(?:\s+\((.+)\))?$", dep) dep_name = m.group(1) extras = m.group(2) or "" constraint = m.group(3) or "*" dependency = Dependency(dep_name, constraint, extras=extras.split(",")) package.extras[name].append(dependency) if "marker" in info: package.marker = parse_marker(info["marker"]) else: # Compatibility for old locks if "requirements" in info: dep = Dependency("foo", "0.0.0") for name, value in info["requirements"].items(): if name == "python": dep.python_versions = value elif name == "platform": dep.platform = value split_dep = dep.to_pep_508(False).split(";") if len(split_dep) > 1: package.marker = parse_marker(split_dep[1].strip()) for dep_name, constraint in info.get("dependencies", {}).items(): root_dir = self._lock.path.parent if package.source_type == "directory": # root dir should be the source of the package relative to the lock path root_dir = Path(package.source_url) if isinstance(constraint, list): for c in constraint: package.add_dependency( Factory.create_dependency(dep_name, c, root_dir=root_dir)) continue package.add_dependency( Factory.create_dependency(dep_name, constraint, root_dir=root_dir)) if "develop" in info: package.develop = info["develop"] packages.add_package(package) return packages
def locked_repository(self, with_dev_reqs=False ): # type: (bool) -> poetry.repositories.Repository """ Searches and returns a repository of locked packages. """ if not self.is_locked(): return poetry.repositories.Repository() lock_data = self.lock_data packages = poetry.repositories.Repository() if with_dev_reqs: locked_packages = lock_data["package"] else: locked_packages = [ p for p in lock_data["package"] if p["category"] == "main" ] if not locked_packages: return packages for info in locked_packages: package = Package(info["name"], info["version"], info["version"]) package.description = info.get("description", "") package.category = info["category"] package.optional = info["optional"] if "hashes" in lock_data["metadata"]: # Old lock so we create dummy files from the hashes package.files = [{ "name": h, "hash": h } for h in lock_data["metadata"]["hashes"][info["name"]]] else: package.files = lock_data["metadata"]["files"][info["name"]] package.python_versions = info["python-versions"] extras = info.get("extras", {}) if extras: for name, deps in extras.items(): package.extras[name] = [] for dep in deps: m = re.match(r"^(.+?)(?:\s+\((.+)\))?$", dep) dep_name = m.group(1) constraint = m.group(2) or "*" package.extras[name].append( Dependency(dep_name, constraint)) if "marker" in info: package.marker = parse_marker(info["marker"]) else: # Compatibility for old locks if "requirements" in info: dep = Dependency("foo", "0.0.0") for name, value in info["requirements"].items(): if name == "python": dep.python_versions = value elif name == "platform": dep.platform = value split_dep = dep.to_pep_508(False).split(";") if len(split_dep) > 1: package.marker = parse_marker(split_dep[1].strip()) for dep_name, constraint in info.get("dependencies", {}).items(): if isinstance(constraint, list): for c in constraint: package.add_dependency(dep_name, c) continue package.add_dependency(dep_name, constraint) if "develop" in info: package.develop = info["develop"] if "source" in info: package.source_type = info["source"].get("type", "") package.source_url = info["source"]["url"] package.source_reference = info["source"]["reference"] packages.add_package(package) return packages