def __init__( self, version: str, pretty_version: str | None = None, *, source_version: str | None = None, requires: list[poetry_pkg.Package] | None = None, ) -> None: if self.title is None: raise RuntimeError( f"{type(self)!r} does not define the required " f"title attribute" ) super().__init__(self.name, version, pretty_version=pretty_version) if requires is not None: reqs = list(requires) else: reqs = [] reqs.extend(self.get_requirements()) if reqs: if "default" not in self._dependency_groups: self._dependency_groups[ "default" ] = poetry_depgroup.DependencyGroup("default") for req in reqs: self._dependency_groups["default"].add_dependency(req) self.build_requires = self.get_build_requirements() self.description = type(self).description # type: ignore if source_version is None: self.source_version = self.pretty_version else: self.source_version = source_version repository.bundle_repo.add_package(self) if self.aliases: for alias in self.aliases: pkg = DummyPackage(name=alias, version=self.version) pkg.add_dependency( poetry_dep.Dependency(self.name, self.version) ) repository.bundle_repo.add_package(pkg)
def get_build_requirements(self) -> list[poetry_dep.Dependency]: reqs = super().get_requirements() reqs.append(poetry_dep.Dependency("libffi", "*")) return reqs
def get_build_requirements(self) -> list[poetry_dep.Dependency]: reqs = super().get_requirements() reqs.append(poetry_dep.Dependency("openssl", ">=1.1.1")) return reqs
from metapkg import packages from metapkg import targets from metapkg.packages import python from edgedbpkg import postgresql from edgedbpkg import python as python_bundle from edgedbpkg import pyentrypoint if TYPE_CHECKING: from cleo.io import io as cleo_io from poetry.core.semver import version as poetry_version python.set_python_runtime_dependency( poetry_dep.Dependency( name="python-edgedb", constraint=">=3.10.0,<=3.11.0", allows_prereleases=True, )) class EdgeDB(packages.BundledPythonPackage): title = "EdgeDB" name = "edgedb-server" description = "Next generation object-relational database" license = "ASL 2.0" group = "Applications/Databases" identifier = "com.edgedb.edgedb-server" url = "https://edgedb.com/" sources = (
def handle(self) -> int: pkgname = self.argument("name") keepwork = self.option("keepwork") destination = self.option("dest") generic = self.option("generic") libc = self.option("libc") build_source = self.option("build-source") build_debug = self.option("build-debug") src_ref = self.option("source-ref") version = self.option("pkg-version") revision = self.option("pkg-revision") subdist = self.option("pkg-subdist") is_release = self.option("release") extra_opt = self.option("extra-optimizations") jobs = self.option("jobs") target = targets.detect_target(self.io, portable=generic, libc=libc) target.prepare() modname, _, clsname = pkgname.rpartition(":") mod = importlib.import_module(modname) pkgcls = getattr(mod, clsname) if src_ref: if "extras" not in pkgcls.sources[0]: pkgcls.sources[0]["extras"] = {} pkgcls.sources[0]["extras"]["version"] = src_ref root_pkg = pkgcls.resolve( self.io, version=version, revision=revision, is_release=is_release, target=target, ) sources = root_pkg.get_sources() if len(sources) != 1: self.error("Only single-source git packages are supported") return 1 source = sources[0] if not isinstance(source, af_sources.GitSource): self.error("Only single-source git packages are supported") return 1 root = project_package.ProjectPackage("__root__", "1") root.python_versions = af_python.python_dependency.pretty_constraint root.add_dependency( poetry_dep.Dependency(root_pkg.name, root_pkg.version)) af_repo.bundle_repo.add_package(root) target_capabilities = target.get_capabilities() extras = [f"capability-{c}" for c in target_capabilities] repo_pool = af_repo.Pool() repo_pool.add_repository(target.get_package_repository()) repo_pool.add_repository(af_repo.bundle_repo, secondary=True) item_repo = root_pkg.get_package_repository(target, io=self.io) if item_repo is not None: repo_pool.add_repository(item_repo, secondary=True) provider = af_repo.Provider(root, repo_pool, self.io, extras=extras) resolution = poetry_solver.resolve_version(root, provider) env = poetry_env.SystemEnv(pathlib.Path(sys.executable)) pkg_map = {} graph = {} for dep_package in resolution.packages: pkg_map[dep_package.name] = dep_package.package package = dep_package.package if env.is_valid_for_marker(dep_package.dependency.marker): deps = { req.name for req in package.requires if env.is_valid_for_marker(req.marker) } graph[package.name] = deps sorter = graphlib.TopologicalSorter(graph) packages = [pkg_map[pn] for pn in sorter.static_order()] # Build a separate package list for build deps. build_root = project_package.ProjectPackage("__build_root__", "1") build_root.python_versions = ( af_python.python_dependency.pretty_constraint) build_root.add_dependency( poetry_dep.Dependency(root_pkg.name, root_pkg.version)) build_root.build_requires = [] provider = af_repo.Provider(build_root, repo_pool, self.io, include_build_reqs=True) resolution = poetry_solver.resolve_version(build_root, provider) pkg_map = {} graph = {} for dep_package in resolution.packages: pkg_map[dep_package.name] = dep_package.package package = dep_package.package if env.is_valid_for_marker(dep_package.dependency.marker): reqs = set(package.requires) | set( getattr(package, "build_requires", [])) deps = { req.name for req in reqs if req.is_activated() and env.is_valid_for_marker(req.marker) } graph[package.name] = deps # Workaround cycles in build/runtime dependencies between # packages. This requires the depending package to explicitly # declare its cyclic runtime dependencies in get_cyclic_runtime_deps() # and then the cyclic dependency must take care to inject itself # into the dependent's context to build itself (e.g. by manipulating # PYTHONPATH at build time.) An example of such cycle is # flit-core -> tomli -> flit-core. cyclic_runtime_deps = collections.defaultdict(list) last_cycle = None current_cycle = None while True: sorter = graphlib.TopologicalSorter(graph) try: build_pkgs = [pkg_map[pn] for pn in sorter.static_order()] except graphlib.CycleError as e: cycle = e.args[1] if len(cycle) > 3 or cycle == last_cycle: raise dep = pkg_map[cycle[-1]] pkg_with_dep = pkg_map[cycle[-2]] if dep.name not in pkg_with_dep.get_cyclic_runtime_deps(): dep, pkg_with_dep = pkg_with_dep, dep if dep.name not in pkg_with_dep.get_cyclic_runtime_deps(): raise last_cycle = current_cycle current_cycle = cycle cyclic_runtime_deps[pkg_with_dep].append(dep) graph[pkg_with_dep.name].remove(dep.name) else: break for pkg_with_cr_deps, cr_deps in cyclic_runtime_deps.items(): for i, build_pkg in enumerate(build_pkgs): if build_pkg == pkg_with_cr_deps: build_pkgs[i + 1:i + 1] = cr_deps break if keepwork: workdir = tempfile.mkdtemp(prefix="metapkg.") else: tempdir = tempfile.TemporaryDirectory(prefix="metapkg.") workdir = tempdir.name os.chmod(workdir, 0o755) try: target.build( targets.BuildRequest( io=self.io, env=env, root_pkg=root_pkg, deps=packages, build_deps=build_pkgs, workdir=workdir, outputdir=destination, build_source=build_source, build_debug=build_debug, revision=revision or "1", subdist=subdist, extra_opt=extra_opt, jobs=jobs or 0, ), ) finally: if not keepwork: tempdir.cleanup() return 0
from poetry.core.semver import version as poetry_version from poetry.repositories import pypi_repository from metapkg import packages as mpkg from metapkg import tools from metapkg import targets from . import base from . import repository as af_repository from . import sources as af_sources from .utils import python_dependency_from_pep_508 if TYPE_CHECKING: from cleo.io import io as cleo_io python_dependency = poetry_dep.Dependency(name="python", constraint=">=3.7") wheel_dependency = poetry_dep.Dependency(name="pypkg-wheel", constraint="*") def set_python_runtime_dependency(dep: poetry_dep.Dependency) -> None: global python_dependency python_dependency = dep class PyPiRepository(pypi_repository.PyPiRepository): # type: ignore def __init__(self, io: cleo_io.IO) -> None: super().__init__() self._io = io self._pkg_impls: dict[str, type[PythonPackage]] = { "flit-core": FlitCore, "tomli": Tomli,