Esempio n. 1
0
    def from_metadata(cls, path):  # type: (Path) -> Optional[PackageInfo]
        """
        Helper method to parse package information from an unpacked metadata directory.

        :param path: The metadata directory to parse information from.
        """
        if path.suffix in {".dist-info", ".egg-info"}:
            directories = [path]
        else:
            directories = cls._find_dist_info(path=path)

        for directory in directories:
            try:
                if directory.suffix == ".egg-info":
                    dist = pkginfo.UnpackedSDist(directory.as_posix())
                elif directory.suffix == ".dist-info":
                    dist = pkginfo.Wheel(directory.as_posix())
                else:
                    continue
                break
            except ValueError:
                continue
        else:
            try:
                # handle PKG-INFO in unpacked sdist root
                dist = pkginfo.UnpackedSDist(path.as_posix())
            except ValueError:
                return

        info = cls._from_distribution(dist=dist)
        if info:
            return info
Esempio n. 2
0
    def _inspect_sdist_with_setup(self, sdist_dir):
        info = {"requires_python": None, "requires_dist": None}

        setup = sdist_dir / "setup.py"
        if not setup.exists():
            return info

        venv = Venv.create(NullIO())

        current_dir = os.getcwd()
        os.chdir(sdist_dir.as_posix())

        try:
            venv.run("python", "setup.py", "egg_info")

            egg_info = list(sdist_dir.glob("**/*.egg-info"))[0]

            meta = pkginfo.UnpackedSDist(str(egg_info))
            if meta.requires_python:
                info["requires_python"] = meta.requires_python

            if meta.requires_dist:
                info["requires_dist"] = list(meta.requires_dist)
            else:
                requires = egg_info / "requires.txt"
                if requires.exists():
                    with requires.open() as f:
                        info["requires_dist"] = parse_requires(f.read())
        except Exception:
            pass

        os.chdir(current_dir)

        return info
Esempio n. 3
0
def convert_distribution(context, pypi_name, zi_name, zi_version, feed,
                         old_feed, release_data,
                         release_url):  #TODO rm unused params
    # Add from old_feed if it already has it (distributions can be deleted, but not changed or reuploaded)
    implementations = old_feed.xpath('//implementation[@id={!r}]'.format(
        release_url['path']))
    if implementations:  #TODO test this, e.g. doe we have to add xpath(namespaces=nsmap)?
        context.feed_logger.info('Reusing from old feed')
        feed.append(implementations[0])
        return

    # Not in old feed, need to convert.
    with unpack_distribution(context, release_url) as distribution_directory:
        # Create <implementation>
        context.feed_logger.debug('Converting')
        egg_info_directory = next(distribution_directory.glob('*.egg-info'))
        package = pkginfo.UnpackedSDist(str(egg_info_directory))

        implementation = zi.implementation(
            id=release_url['path'],
            version=zi_version,
            released=release_url['upload_time'].strftime('%Y-%m-%d'),
            stability=stability(release_data['version']),
            langs=' '.join(_languages[classifier]
                           for classifier in package.classifiers
                           if classifier in _languages),
        )

        licenses = sorted(classifier for classifier in package.classifiers
                          if classifier.startswith('License ::'))
        if licenses:
            implementation.set('license', licenses[0])

        # Convert dependencies
        convert_dependencies(context, implementation, egg_info_directory)

        # Add to feed
        feed.getroot().append(implementation)
        print((etree.tostring(feed, pretty_print=True)).decode())
        assert False
Esempio n. 4
0
    def _inspect_sdist_with_setup(self, sdist_dir):
        info = {
            'requires_python': None,
            'requires_dist': None,
        }

        setup = sdist_dir / 'setup.py'
        if not setup.exists():
            return info

        venv = Venv.create(NullIO())

        current_dir = os.getcwd()
        os.chdir(sdist_dir.as_posix())

        try:
            venv.run('python', 'setup.py', 'egg_info')

            egg_info = list(sdist_dir.glob('**/*.egg-info'))[0]

            meta = pkginfo.UnpackedSDist(str(egg_info))
            if meta.requires_python:
                info['requires_python'] = meta.requires_python

            if meta.requires_dist:
                info['requires_dist'] = list(meta.requires_dist)
            else:
                requires = egg_info / 'requires.txt'
                if requires.exists():
                    with requires.open() as f:
                        info['requires_dist'] = parse_requires(f.read())
        except Exception:
            pass

        os.chdir(current_dir)

        return info
Esempio n. 5
0
    def search_for_vcs(self,
                       dependency):  # type: (VCSDependency) -> List[Package]
        """
        Search for the specifications that match the given VCS dependency.

        Basically, we clone the repository in a temporary directory
        and get the information we need by checking out the specified reference.
        """
        if dependency.vcs != "git":
            raise ValueError("Unsupported VCS dependency {}".format(
                dependency.vcs))

        tmp_dir = Path(
            mkdtemp(prefix="pypoetry-git-{}".format(dependency.name)))

        try:
            git = Git()
            git.clone(dependency.source, tmp_dir)
            git.checkout(dependency.reference, tmp_dir)
            revision = git.rev_parse(dependency.reference, tmp_dir).strip()

            if dependency.tag or dependency.rev:
                revision = dependency.reference

            pyproject = TomlFile(tmp_dir / "pyproject.toml")
            pyproject_content = None
            has_poetry = False
            if pyproject.exists():
                pyproject_content = pyproject.read()
                has_poetry = ("tool" in pyproject_content
                              and "poetry" in pyproject_content["tool"])

            if pyproject_content and has_poetry:
                # If a pyproject.toml file exists
                # We use it to get the information we need
                info = pyproject_content["tool"]["poetry"]

                name = info["name"]
                version = info["version"]
                package = Package(name, version, version)
                package.source_type = dependency.vcs
                package.source_url = dependency.source
                package.source_reference = dependency.reference
                for req_name, req_constraint in info["dependencies"].items():
                    if req_name == "python":
                        package.python_versions = req_constraint
                        continue

                    package.add_dependency(req_name, req_constraint)
            else:
                # We need to use setup.py here
                # to figure the information we need
                # We need to place ourselves in the proper
                # folder for it to work
                venv = Venv.create(self._io)

                current_dir = os.getcwd()
                os.chdir(tmp_dir.as_posix())

                try:
                    venv.run("python", "setup.py", "egg_info")

                    # Sometimes pathlib will fail on recursive
                    # symbolic links, so we need to workaround it
                    # and use the glob module instead.
                    # Note that this does not happen with pathlib2
                    # so it's safe to use it for Python < 3.4.
                    if PY35:
                        egg_info = next(
                            Path(p) for p in glob.glob(
                                os.path.join(str(tmp_dir), "**", "*.egg-info"),
                                recursive=True,
                            ))
                    else:
                        egg_info = next(tmp_dir.glob("**/*.egg-info"))

                    meta = pkginfo.UnpackedSDist(str(egg_info))

                    if meta.requires_dist:
                        reqs = list(meta.requires_dist)
                    else:
                        reqs = []
                        requires = egg_info / "requires.txt"
                        if requires.exists():
                            with requires.open() as f:
                                reqs = parse_requires(f.read())

                    package = Package(meta.name, meta.version)

                    for req in reqs:
                        dep = dependency_from_pep_508(req)
                        if dep.in_extras:
                            for extra in dep.in_extras:
                                if extra not in package.extras:
                                    package.extras[extra] = []

                                package.extras[extra].append(dep)

                        package.requires.append(dep)
                except Exception:
                    raise
                finally:
                    os.chdir(current_dir)

            package.source_type = "git"
            package.source_url = dependency.source
            package.source_reference = revision
        except Exception:
            raise
        finally:
            shutil.rmtree(tmp_dir.as_posix())

        if dependency.name != package.name:
            # For now, the dependency's name must match the actual package's name
            raise RuntimeError(
                "The dependency name for {} does not match the actual package's name: {}"
                .format(dependency.name, package.name))

        if dependency.extras:
            for extra in dependency.extras:
                if extra in package.extras:
                    for dep in package.extras[extra]:
                        dep.activate()

        return [package]
Esempio n. 6
0
    def search_for_vcs(self,
                       dependency):  # type: (VCSDependency) -> List[Package]
        """
        Search for the specifications that match the given VCS dependency.

        Basically, we clone the repository in a temporary directory
        and get the information we need by checking out the specified reference.
        """
        if dependency.vcs != 'git':
            raise ValueError('Unsupported VCS dependency {}'.format(
                dependency.vcs))

        tmp_dir = Path(
            mkdtemp(prefix='pypoetry-git-{}'.format(dependency.name)))

        try:
            git = Git()
            git.clone(dependency.source, tmp_dir)
            git.checkout(dependency.reference, tmp_dir)
            revision = git.rev_parse(dependency.reference, tmp_dir).strip()

            if dependency.tag or dependency.rev:
                revision = dependency.reference

            pyproject = TomlFile(tmp_dir / 'pyproject.toml')
            pyproject_content = None
            has_poetry = False
            if pyproject.exists():
                pyproject_content = pyproject.read(True)
                has_poetry = ('tool' in pyproject_content
                              and 'poetry' in pyproject_content['tool'])

            if pyproject_content and has_poetry:
                # If a pyproject.toml file exists
                # We use it to get the information we need
                info = pyproject_content['tool']['poetry']

                name = info['name']
                version = info['version']
                package = Package(name, version, version)
                package.source_type = dependency.vcs
                package.source_url = dependency.source
                package.source_reference = dependency.reference
                for req_name, req_constraint in info['dependencies'].items():
                    if req_name == 'python':
                        package.python_versions = req_constraint
                        continue

                    package.add_dependency(req_name, req_constraint)
            else:
                # We need to use setup.py here
                # to figure the information we need
                # We need to place ourselves in the proper
                # folder for it to work
                venv = Venv.create(self._io)

                current_dir = os.getcwd()
                os.chdir(tmp_dir.as_posix())

                try:
                    venv.run('python', 'setup.py', 'egg_info')

                    egg_info = list(tmp_dir.glob('*.egg-info'))[0]

                    meta = pkginfo.UnpackedSDist(str(egg_info))

                    if meta.requires_dist:
                        reqs = list(meta.requires_dist)
                    else:
                        reqs = []
                        requires = egg_info / 'requires.txt'
                        if requires.exists():
                            with requires.open() as f:
                                reqs = parse_requires(f.read())

                    package = Package(meta.name, meta.version)

                    for req in reqs:
                        package.requires.append(dependency_from_pep_508(req))
                except Exception:
                    raise
                finally:
                    os.chdir(current_dir)

            package.source_type = 'git'
            package.source_url = dependency.source
            package.source_reference = revision
        except Exception:
            raise
        finally:
            shutil.rmtree(tmp_dir.as_posix())

        return [package]
Esempio n. 7
0
import pkginfo

mypackage = pkginfo.UnpackedSDist('PyPRT.egg-info')
print(mypackage.version)
Esempio n. 8
0
    def __init__(
            self,
            path,  # type: Path
            category="main",  # type: str
            optional=False,  # type: bool
            base=None,  # type: Path
            develop=False,  # type: bool
    ):
        from . import dependency_from_pep_508
        from .package import Package

        self._path = path
        self._base = base
        self._full_path = path
        self._develop = develop

        if self._base and not self._path.is_absolute():
            self._full_path = self._base / self._path

        if not self._full_path.exists():
            raise ValueError("Directory {} does not exist".format(self._path))

        if self._full_path.is_file():
            raise ValueError("{} is a file, expected a directory".format(
                self._path))

        # Checking content to dertermine actions
        setup = self._full_path / "setup.py"
        pyproject = TomlFile(self._full_path / "pyproject.toml")
        has_poetry = False
        if pyproject.exists():
            pyproject_content = pyproject.read()
            has_poetry = ("tool" in pyproject_content
                          and "poetry" in pyproject_content["tool"])

        if not setup.exists() and not has_poetry:
            raise ValueError(
                "Directory {} does not seem to be a Python package".format(
                    self._full_path))

        if has_poetry:
            from poetry.masonry.builders import SdistBuilder
            from poetry.poetry import Poetry

            poetry = Poetry.create(self._full_path)
            builder = SdistBuilder(poetry, NullVenv(), NullIO())

            with setup.open("w") as f:
                f.write(decode(builder.build_setup()))

            package = poetry.package
            self._package = Package(package.pretty_name, package.version)
            self._package.requires += package.requires
            self._package.dev_requires += package.dev_requires
            self._package.extras = package.extras
            self._package.python_versions = package.python_versions
            self._package.platform = package.platform
        else:
            # Execute egg_info
            current_dir = os.getcwd()
            os.chdir(str(self._full_path))

            try:
                cwd = base
                venv = Venv.create(NullIO(), cwd=cwd)
                venv.run("python", "setup.py", "egg_info")
            finally:
                os.chdir(current_dir)

            egg_info = list(self._full_path.glob("*.egg-info"))[0]

            meta = pkginfo.UnpackedSDist(str(egg_info))

            if meta.requires_dist:
                reqs = list(meta.requires_dist)
            else:
                reqs = []
                requires = egg_info / "requires.txt"
                if requires.exists():
                    with requires.open() as f:
                        reqs = parse_requires(f.read())

            package = Package(meta.name, meta.version)
            package.description = meta.summary

            for req in reqs:
                package.requires.append(dependency_from_pep_508(req))

            if meta.requires_python:
                package.python_versions = meta.requires_python

            if meta.platforms:
                platforms = [
                    p for p in meta.platforms if p.lower() != "unknown"
                ]
                if platforms:
                    package.platform = " || ".join(platforms)

            self._package = package

        self._package.source_type = "directory"
        self._package.source_url = self._path.as_posix()

        super(DirectoryDependency, self).__init__(
            self._package.name,
            self._package.version,
            category=category,
            optional=optional,
            allows_prereleases=True,
        )
Esempio n. 9
0
    def get_package_from_directory(
            cls,
            directory,
            name=None):  # type: (Path, Optional[str]) -> Package
        supports_poetry = False
        pyproject = directory.joinpath("pyproject.toml")
        if pyproject.exists():
            pyproject = TomlFile(pyproject)
            pyproject_content = pyproject.read()
            supports_poetry = ("tool" in pyproject_content
                               and "poetry" in pyproject_content["tool"])

        if supports_poetry:
            poetry = Factory().create_poetry(directory)

            pkg = poetry.package
            package = Package(pkg.name, pkg.version)

            for dep in pkg.requires:
                if not dep.is_optional():
                    package.requires.append(dep)

            for extra, deps in pkg.extras.items():
                if extra not in package.extras:
                    package.extras[extra] = []

                for dep in deps:
                    package.extras[extra].append(dep)

            package.python_versions = pkg.python_versions
        else:
            # Execute egg_info
            current_dir = os.getcwd()
            os.chdir(str(directory))

            try:
                cwd = directory
                venv = EnvManager().get(cwd)
                venv.run("python", "setup.py", "egg_info")
            except EnvCommandError:
                result = SetupReader.read_from_directory(directory)
                if not result["name"]:
                    # The name could not be determined
                    # We use the dependency name
                    result["name"] = name

                if not result["version"]:
                    # The version could not be determined
                    # so we raise an error since it is mandatory
                    raise RuntimeError(
                        "Unable to retrieve the package version for {}".format(
                            directory))

                package_name = result["name"]
                package_version = result["version"]
                python_requires = result["python_requires"]
                if python_requires is None:
                    python_requires = "*"

                package_summary = ""

                requires = ""
                for dep in result["install_requires"]:
                    requires += dep + "\n"

                if result["extras_require"]:
                    requires += "\n"

                for extra_name, deps in result["extras_require"].items():
                    requires += "[{}]\n".format(extra_name)

                    for dep in deps:
                        requires += dep + "\n"

                    requires += "\n"

                reqs = parse_requires(requires)
            else:
                os.chdir(current_dir)
                # Sometimes pathlib will fail on recursive
                # symbolic links, so we need to workaround it
                # and use the glob module instead.
                # Note that this does not happen with pathlib2
                # so it's safe to use it for Python < 3.4.
                if PY35:
                    egg_info = next(
                        Path(p) for p in glob.glob(
                            os.path.join(str(directory), "**", "*.egg-info"),
                            recursive=True,
                        ))
                else:
                    egg_info = next(directory.glob("**/*.egg-info"))

                meta = pkginfo.UnpackedSDist(str(egg_info))
                package_name = meta.name
                package_version = meta.version
                package_summary = meta.summary
                python_requires = meta.requires_python

                if meta.requires_dist:
                    reqs = list(meta.requires_dist)
                else:
                    reqs = []
                    requires = egg_info / "requires.txt"
                    if requires.exists():
                        with requires.open(encoding="utf-8") as f:
                            reqs = parse_requires(f.read())
            finally:
                os.chdir(current_dir)

            package = Package(package_name, package_version)
            package.description = package_summary

            for req in reqs:
                dep = dependency_from_pep_508(req)
                if dep.in_extras:
                    for extra in dep.in_extras:
                        if extra not in package.extras:
                            package.extras[extra] = []

                        package.extras[extra].append(dep)

                if not dep.is_optional():
                    package.requires.append(dep)

            if python_requires:
                package.python_versions = python_requires

        if name and name != package.name:
            # For now, the dependency's name must match the actual package's name
            raise RuntimeError(
                "The dependency name for {} does not match the actual package's name: {}"
                .format(name, package.name))

        package.source_type = "directory"
        package.source_url = directory.as_posix()

        return package
Esempio n. 10
0
    def search_for_directory(
            self, dependency):  # type: (DirectoryDependency) -> List[Package]
        if dependency.supports_poetry():
            from poetry.poetry import Poetry

            poetry = Poetry.create(dependency.full_path)

            pkg = poetry.package
            package = Package(pkg.name, pkg.version)

            for dep in pkg.requires:
                if not dep.is_optional():
                    package.requires.append(dep)

            for extra, deps in pkg.extras.items():
                if extra not in package.extras:
                    package.extras[extra] = []

                for dep in deps:
                    package.extras[extra].append(dep)

            package.python_versions = pkg.python_versions
        else:
            # Execute egg_info
            current_dir = os.getcwd()
            os.chdir(str(dependency.full_path))

            try:
                cwd = dependency.full_path
                venv = Env.get(NullIO(), cwd=cwd)
                venv.run("python", "setup.py", "egg_info")
            except EnvCommandError:
                result = SetupReader.read_from_directory(dependency.full_path)
                if not result["name"]:
                    # The name could not be determined
                    # We use the dependency name
                    result["name"] = dependency.name

                if not result["version"]:
                    # The version could not be determined
                    # so we raise an error since it is mandatory
                    raise RuntimeError(
                        "Unable to retrieve the package version for {}".format(
                            dependency.path))

                package_name = result["name"]
                package_version = result["version"]
                python_requires = result["python_requires"]
                if python_requires is None:
                    python_requires = "*"

                package_summary = ""

                requires = ""
                for dep in result["install_requires"]:
                    requires += dep + "\n"

                if result["extras_require"]:
                    requires += "\n"

                for extra_name, deps in result["extras_require"].items():
                    requires += "[{}]\n".format(extra_name)

                    for dep in deps:
                        requires += dep + "\n"

                    requires += "\n"

                reqs = parse_requires(requires)
            else:
                os.chdir(current_dir)
                # Sometimes pathlib will fail on recursive
                # symbolic links, so we need to workaround it
                # and use the glob module instead.
                # Note that this does not happen with pathlib2
                # so it's safe to use it for Python < 3.4.
                if PY35:
                    egg_info = next(
                        Path(p) for p in glob.glob(
                            os.path.join(str(dependency.full_path), "**",
                                         "*.egg-info"),
                            recursive=True,
                        ))
                else:
                    egg_info = next(dependency.full_path.glob("**/*.egg-info"))

                meta = pkginfo.UnpackedSDist(str(egg_info))
                package_name = meta.name
                package_version = meta.version
                package_summary = meta.summary
                python_requires = meta.requires_python

                if meta.requires_dist:
                    reqs = list(meta.requires_dist)
                else:
                    reqs = []
                    requires = egg_info / "requires.txt"
                    if requires.exists():
                        with requires.open() as f:
                            reqs = parse_requires(f.read())
            finally:
                os.chdir(current_dir)

            package = Package(package_name, package_version)

            if dependency.name != package.name:
                # For now, the dependency's name must match the actual package's name
                raise RuntimeError(
                    "The dependency name for {} does not match the actual package's name: {}"
                    .format(dependency.name, package.name))

            package.description = package_summary

            for req in reqs:
                dep = dependency_from_pep_508(req)
                if dep.in_extras:
                    for extra in dep.in_extras:
                        if extra not in package.extras:
                            package.extras[extra] = []

                        package.extras[extra].append(dep)

                if not dep.is_optional():
                    package.requires.append(dep)

            if python_requires:
                package.python_versions = python_requires

        package.source_type = "directory"
        package.source_url = dependency.path.as_posix()

        for extra in dependency.extras:
            if extra in package.extras:
                for dep in package.extras[extra]:
                    dep.activate()

                package.requires += package.extras[extra]

        return [package]
Esempio n. 11
0
    def __init__(
            self,
            path,  # type: Path
            category="main",  # type: str
            optional=False,  # type: bool
            base=None,  # type: Path
            develop=True,  # type: bool
    ):
        from . import dependency_from_pep_508
        from .package import Package

        self._path = path
        self._base = base
        self._full_path = path
        self._develop = develop
        self._supports_poetry = False

        if self._base and not self._path.is_absolute():
            self._full_path = self._base / self._path

        if not self._full_path.exists():
            raise ValueError("Directory {} does not exist".format(self._path))

        if self._full_path.is_file():
            raise ValueError("{} is a file, expected a directory".format(
                self._path))

        # Checking content to dertermine actions
        setup = self._full_path / "setup.py"
        pyproject = TomlFile(self._full_path / "pyproject.toml")
        if pyproject.exists():
            pyproject_content = pyproject.read()
            self._supports_poetry = ("tool" in pyproject_content
                                     and "poetry" in pyproject_content["tool"])

        if not setup.exists() and not self._supports_poetry:
            raise ValueError(
                "Directory {} does not seem to be a Python package".format(
                    self._full_path))

        if self._supports_poetry:
            from poetry.poetry import Poetry

            poetry = Poetry.create(self._full_path)

            package = poetry.package
            self._package = Package(package.pretty_name, package.version)
            self._package.requires += package.requires
            self._package.dev_requires += package.dev_requires
            self._package.extras = package.extras
            self._package.python_versions = package.python_versions
        else:
            # Execute egg_info
            current_dir = os.getcwd()
            os.chdir(str(self._full_path))

            try:
                cwd = base
                venv = Env.get(NullIO(), cwd=cwd)
                venv.run("python", "setup.py", "egg_info")
            except EnvCommandError:
                result = SetupReader.read_from_directory(self._full_path)
                if not result["name"]:
                    # The name could not be determined
                    # so we raise an error since it is mandatory
                    raise RuntimeError(
                        "Unable to retrieve the package name for {}".format(
                            path))

                if not result["version"]:
                    # The version could not be determined
                    # so we raise an error since it is mandatory
                    raise RuntimeError(
                        "Unable to retrieve the package version for {}".format(
                            path))

                package_name = result["name"]
                package_version = result["version"]
                python_requires = result["python_requires"]
                if python_requires is None:
                    python_requires = "*"

                package_summary = ""

                requires = ""
                for dep in result["install_requires"]:
                    requires += dep + "\n"

                if result["extras_require"]:
                    requires += "\n"

                for extra_name, deps in result["extras_require"].items():
                    requires += "[{}]\n".format(extra_name)

                    for dep in deps:
                        requires += dep + "\n"

                    requires += "\n"

                reqs = parse_requires(requires)
            else:
                os.chdir(current_dir)
                # Sometimes pathlib will fail on recursive
                # symbolic links, so we need to workaround it
                # and use the glob module instead.
                # Note that this does not happen with pathlib2
                # so it's safe to use it for Python < 3.4.
                if PY35:
                    egg_info = next(
                        Path(p) for p in glob.glob(
                            os.path.join(str(self._full_path), "**",
                                         "*.egg-info"),
                            recursive=True,
                        ))
                else:
                    egg_info = next(self._full_path.glob("**/*.egg-info"))

                meta = pkginfo.UnpackedSDist(str(egg_info))
                package_name = meta.name
                package_version = meta.version
                package_summary = meta.summary
                python_requires = meta.requires_python

                if meta.requires_dist:
                    reqs = list(meta.requires_dist)
                else:
                    reqs = []
                    requires = egg_info / "requires.txt"
                    if requires.exists():
                        with requires.open() as f:
                            reqs = parse_requires(f.read())
            finally:
                os.chdir(current_dir)

            package = Package(package_name, package_version)
            package.description = package_summary

            for req in reqs:
                package.requires.append(dependency_from_pep_508(req))

            if python_requires:
                package.python_versions = python_requires

            self._package = package

        self._package.source_type = "directory"
        self._package.source_url = self._path.as_posix()

        super(DirectoryDependency, self).__init__(
            self._package.name,
            self._package.version,
            category=category,
            optional=optional,
            allows_prereleases=True,
        )
Esempio n. 12
0
    def __init__(
            self,
            path,  # type: Path
            category='main',  # type: str
            optional=False,  # type: bool
            base=None,  # type: Path
            develop=False  # type: bool
    ):
        from . import dependency_from_pep_508

        self._path = path
        self._base = base
        self._full_path = path
        self._develop = develop

        if self._base and not self._path.is_absolute():
            self._full_path = self._base / self._path

        if not self._full_path.exists():
            raise ValueError('Directory {} does not exist'.format(self._path))

        if self._full_path.is_file():
            raise ValueError('{} is a file, expected a directory'.format(
                self._path))

        # Checking content to dertermine actions
        setup = self._full_path / 'setup.py'
        pyproject = TomlFile(self._full_path / 'pyproject.toml')
        has_poetry = False
        if pyproject.exists():
            pyproject_content = pyproject.read(True)
            has_poetry = ('tool' in pyproject_content
                          and 'poetry' in pyproject_content['tool'])

        if not setup.exists() and not has_poetry:
            raise ValueError(
                'Directory {} does not seem to be a Python package'.format(
                    self._full_path))

        if has_poetry:
            from poetry.masonry.builders import SdistBuilder
            from poetry.poetry import Poetry

            poetry = Poetry.create(self._full_path)
            builder = SdistBuilder(poetry, NullVenv(), NullIO())

            with setup.open('w') as f:
                f.write(decode(builder.build_setup()))

            self._package = poetry.package
        else:
            from poetry.packages import Package
            # Execute egg_info
            current_dir = os.getcwd()
            os.chdir(str(self._full_path))

            try:
                cwd = base
                venv = Venv.create(NullIO(), cwd=cwd)
                venv.run('python', 'setup.py', 'egg_info')
            finally:
                os.chdir(current_dir)

            egg_info = list(self._full_path.glob('*.egg-info'))[0]

            meta = pkginfo.UnpackedSDist(str(egg_info))

            if meta.requires_dist:
                reqs = list(meta.requires_dist)
            else:
                reqs = []
                requires = egg_info / 'requires.txt'
                if requires.exists():
                    with requires.open() as f:
                        reqs = parse_requires(f.read())

            package = Package(meta.name, meta.version)
            package.description = meta.summary

            for req in reqs:
                package.requires.append(dependency_from_pep_508(req))

            if meta.requires_python:
                package.python_versions = meta.requires_python

            if meta.platforms:
                platforms = [
                    p for p in meta.platforms if p.lower() != 'unknown'
                ]
                if platforms:
                    package.platform = ' || '.join(platforms)

            self._package = package

        self._package.source_type = 'directory'
        self._package.source_reference = str(self._path)

        super(DirectoryDependency, self).__init__(self._package.name,
                                                  self._package.version,
                                                  category=category,
                                                  optional=optional,
                                                  allows_prereleases=True)