From c70f063873821da37543b2162ea1c712bc602df0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Mur=20Er=C5=BEen?= Date: Wed, 29 May 2024 18:47:12 +0200 Subject: [PATCH] edgedb-ls (#89) --- README.rst | 2 +- edgedbpkg/edgedb_ls/__init__.py | 310 ++++++++++++++++++ edgedbpkg/edgedb_ls/install.list | 1 + edgedbpkg/edgedb_ls/no_install.list | 18 + .../patches/pypkg-cffi__pkgconfig.patch | 22 ++ .../patches/pypkg-graphql-core__toml.patch | 22 ++ integration/linux/build/centos-7/Dockerfile | 2 +- integration/linux/build/centos-8/Dockerfile | 2 +- .../linux/build/debian-bookworm/Dockerfile | 2 +- .../linux/build/debian-bullseye/Dockerfile | 2 +- .../linux/build/debian-buster/Dockerfile | 2 +- integration/linux/build/fedora-29/Dockerfile | 2 +- .../linux/build/linux-aarch64/Dockerfile | 2 +- .../linux/build/linux-x86_64/Dockerfile | 2 +- .../linux/build/ubuntu-bionic/Dockerfile | 2 +- .../linux/build/ubuntu-focal/Dockerfile | 2 +- .../linux/build/ubuntu-hirsute/Dockerfile | 2 +- .../linux/build/ubuntu-jammy/Dockerfile | 2 +- .../test-systemd/debian-bookworm/Dockerfile | 2 +- 19 files changed, 387 insertions(+), 14 deletions(-) create mode 100644 edgedbpkg/edgedb_ls/__init__.py create mode 100644 edgedbpkg/edgedb_ls/install.list create mode 100644 edgedbpkg/edgedb_ls/no_install.list create mode 100644 edgedbpkg/edgedb_ls/patches/pypkg-cffi__pkgconfig.patch create mode 100644 edgedbpkg/edgedb_ls/patches/pypkg-graphql-core__toml.patch diff --git a/README.rst b/README.rst index 5f0aa728..2034f98c 100644 --- a/README.rst +++ b/README.rst @@ -55,7 +55,7 @@ takes the following optional arguments: virtualenv instead of pulling it from Github, this is useful for debugging or making changes to metapkg; * ``EXTRA_OPTIMIZATIONS``: build with extra optimizations enabled, this - significantly increases the build time, but results in sligtly faster + significantly increases the build time, but results in slightly faster binaries; * ``GET_SHELL``: when set to ``true``, start the shell instead of running the build. diff --git a/edgedbpkg/edgedb_ls/__init__.py b/edgedbpkg/edgedb_ls/__init__.py new file mode 100644 index 00000000..9033e09b --- /dev/null +++ b/edgedbpkg/edgedb_ls/__init__.py @@ -0,0 +1,310 @@ +from __future__ import annotations +from typing import TYPE_CHECKING + +import base64 +import os +import pathlib +import shlex +import textwrap + +from poetry.core.packages import dependency as poetry_dep + +from metapkg import packages +from metapkg import targets +from metapkg.packages import python + +from edgedbpkg import python as python_bundle +from edgedbpkg import pyentrypoint +from edgedbpkg import edgedb as edgedb_server + +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.13.0", + allows_prereleases=True, + ) +) + + +class EdgeDBLanguageServer(packages.BundledPythonPackage): + title = "EdgeDBLanguageServer" + name = packages.canonicalize_name("edgedb-ls") + description = "Language server for EdgeDB" + license_id = "Apache-2.0" + group = "Applications/Databases" + identifier = "com.edgedb.edgedb-ls" + url = "https://edgedb.com/" + + sources = [ + { + "url": "git+https://github.com/edgedb/edgedb.git", + "extras": { + "exclude_submodules": [ + # We obtain postgres from the fork repo directly, + # so there's no need to clone it as a submodule. + "postgres", + # TODO: make edgedb-server repo not build pgproto + # "edb/server/pgproto", + # TODO: make edgedb-server repo not build libpg_query + # "edb/pgsql/parser/libpg_query", + ], + "clone_depth": 0, + }, + }, + ] + + artifact_requirements = { + ">=5.0.dev1": [ + "python-edgedb (~= 3.12.0)", + ], + } + + artifact_build_requirements = [ + "pyentrypoint (>=1.0.0)", + ] + + bundle_deps = [ + python_bundle.Python(version="3.10.11"), + python_bundle.Python(version="3.11.8"), + python_bundle.Python(version="3.12.2"), + pyentrypoint.PyEntryPoint(version="1.0.0"), + ] + + @classmethod + def resolve( + cls, + io: cleo_io.IO, + *, + version: str | None = None, + revision: str | None = None, + is_release: bool = False, + target: targets.Target, + ) -> EdgeDBLanguageServer: + os.environ["EDGEDB_BUILD_OFFICIAL"] = "yes" + os.environ["EDGEDB_BUILD_TARGET"] = ( + base64.b32encode(target.triple.encode()) + .decode() + .rstrip("=") + .lower() + ) + if revision: + os.environ["EDGEDB_BUILD_DATE"] = revision + + prev: str | None + + try: + prev = os.environ["EDGEDB_BUILD_IS_RELEASE"] + except KeyError: + prev = None + + os.environ["EDGEDB_BUILD_IS_RELEASE"] = "1" if is_release else "" + os.environ["BUILD_EXT_MODE"] = "skip" + + try: + return ( + super() + .resolve( + io, + version=version, + revision=revision, + is_release=is_release, + target=target, + ) + .with_features(["language-server"]) + ) + finally: + if prev is None: + os.environ.pop("EDGEDB_BUILD_IS_RELEASE", None) + else: + os.environ["EDGEDB_BUILD_IS_RELEASE"] = prev + + os.environ.pop("BUILD_EXT_MODE", None) + + def parse_version_metadata( + self, + segments: tuple[str | int, ...], + ) -> dict[str, str]: + return {} + + @classmethod + def canonicalize_version( + cls, + io: cleo_io.IO, + version: poetry_version.Version, + *, + revision: str | None = None, + is_release: bool = False, + target: targets.Target, + ) -> poetry_version.Version: + if version.local: + if isinstance(version.local, tuple): + local = version.local + else: + local = (version.local,) + + for part in local: + if isinstance(part, str) and part.startswith("s"): + # new version format + build_signature = part[1:] + if version.is_devrelease(): + new_ver = version.without_local().replace( + pre=None, + local=(build_signature,), + ) + else: + new_ver = version.without_local().replace( + local=(build_signature,), + ) + + return new_ver + + return version + + @classmethod + def get_package_repository( + cls, target: targets.Target, io: cleo_io.IO + ) -> python.PyPiRepository: + repo = super().get_package_repository(target, io) + repo.register_package_impl("cryptography", edgedb_server.Cryptography) + repo.register_package_impl("cffi", edgedb_server.Cffi) + repo.register_package_impl("jwcrypto", edgedb_server.JWCrypto) + repo.register_package_impl("edgedb", edgedb_server.EdgeDBPython) + return repo + + @property + def base_slot(self) -> str: + if self.version.is_prerelease(): + pre = self.version.pre + assert pre is not None + pre_phase = packages.semver_pre_tag(self.version) + return f"{self.version.major}-{pre_phase}{pre.number}" + else: + return f"{self.version.major}" + + @property + def slot(self) -> str: + if ".s" in self.pretty_version: + # New version format + if self.version.is_devrelease(): + dev = self.version.dev + assert dev is not None + return f"{self.version.major}-{dev.phase}{dev.number}" + elif self.version.is_prerelease(): + pre = self.version.pre + assert pre is not None + pre_phase = packages.semver_pre_tag(self.version) + return f"{self.version.major}-{pre_phase}{pre.number}" + else: + return f"{self.version.major}" + else: + if self.version.text.find(".dev") == -1: + return self.base_slot + else: + return f"{self.base_slot}-dev" + + def version_includes_revision(self) -> bool: + return True + + def sh_get_build_wheel_env( + self, build: targets.Build, *, site_packages_var: str + ) -> dict[str, str]: + env = dict( + super().sh_get_build_wheel_env( + build, site_packages_var=site_packages_var + ) + ) + shared_dir = (build.get_install_path("data") / "data").relative_to("/") + temp_root = build.get_temp_root(relative_to="pkgsource") + src_python = build.sh_get_command( + "python", package=self, relative_to="pkgsource" + ) + + rel_datadir_script = ";".join( + ( + "import os.path", + "rp = os.path.relpath", + f"sp = rp('{site_packages_var}', start='{temp_root}')", + f"print(rp('{shared_dir}', start=os.path.join(sp, 'edb')))", + ) + ) + + data_dir = f'!"$("{src_python}" -c "{rel_datadir_script}")"' + + env["EDGEDB_BUILD_PACKAGE"] = "1" + env["EDGEDB_BUILD_PG_CONFIG"] = "" + env["EDGEDB_BUILD_RUNSTATEDIR"] = "" + env["EDGEDB_BUILD_SHARED_DIR"] = data_dir + env["_EDGEDB_BUILDMETA_SHARED_DATA_DIR"] = str( + build.get_build_dir(self, relative_to="pkgsource") / "share" + ) + + return env + + def get_build_script(self, build: targets.Build) -> str: + common_script = super().get_build_script(build) + + if build.channel == "stable" and not self.version.is_stable(): + raise AssertionError( + f"cannot build non-stable edgedb-ls=={self.version} " + f"for the stable channel" + ) + + return common_script + + def get_build_install_script(self, build: targets.Build) -> str: + script = super().get_build_install_script(build) + dest = build.get_install_dir(self, relative_to="pkgbuild") + + datadir = build.get_install_path("data") + script += textwrap.dedent( + f"""\ + mkdir -p "{dest}/{datadir}" + mkdir -p "{dest}/{datadir}/data/" + """ + ) + + bindir = build.get_install_path("bin").relative_to("/") + + ep_helper_pkg = build.get_package("pyentrypoint") + ep_helper = ( + build.get_temp_dir(ep_helper_pkg, relative_to="pkgbuild") + / "bin" + / "pyentrypoint" + ) + + script += textwrap.dedent( + f"""\ + for p in "{dest}/{bindir}"/*; do + if [ -f "$p" ]; then + mv "$p" "${{p}}.py" + chmod -x "${{p}}.py" + sed -i -e "/#!/d" "${{p}}.py" + cp "{ep_helper}" "$p" + fi + done + """ + ) + + return script + + def get_private_libraries(self, build: targets.Build) -> list[str]: + return ["libcrypto.*", "libssl.*"] + + def get_exposed_commands(self, build: targets.Build) -> list[pathlib.Path]: + bindir = build.get_install_path("bin") + + return [ + bindir / "edgedb-ls", + ] + + def get_conflict_packages( + self, + build: targets.Build, + root_version: str, + ) -> list[str]: + return ["edgedb-common"] diff --git a/edgedbpkg/edgedb_ls/install.list b/edgedbpkg/edgedb_ls/install.list new file mode 100644 index 00000000..4bdaaca6 --- /dev/null +++ b/edgedbpkg/edgedb_ls/install.list @@ -0,0 +1 @@ +{bindir}/edgedb-ls.py diff --git a/edgedbpkg/edgedb_ls/no_install.list b/edgedbpkg/edgedb_ls/no_install.list new file mode 100644 index 00000000..775ba7f9 --- /dev/null +++ b/edgedbpkg/edgedb_ls/no_install.list @@ -0,0 +1,18 @@ +{bindir}/edgedb +{bindir}/edgedb.py +{bindir}/edb +{bindir}/edb.py +{bindir}/edgedb-server +{bindir}/edgedb-server.py +{libdir}/**/edb/pgsql/parser +{libdir}/**/edb/pgsql/resolver +{libdir}/**/edb/pgsql/dbops +{libdir}/**/edb/server/dbview +{libdir}/**/edb/server/pgcon +{libdir}/**/edb/server/protocol +{libdir}/**/edb/server/pgproto +{libdir}/**/edb/graphql +{libdir}/**/edb/graphql-rewrite +{libdir}/**/edb/_graphql_rewrite.*.so +{libdir}/**/edb/testbase +{libdir}/**/edb/protocol diff --git a/edgedbpkg/edgedb_ls/patches/pypkg-cffi__pkgconfig.patch b/edgedbpkg/edgedb_ls/patches/pypkg-cffi__pkgconfig.patch new file mode 100644 index 00000000..53146f08 --- /dev/null +++ b/edgedbpkg/edgedb_ls/patches/pypkg-cffi__pkgconfig.patch @@ -0,0 +1,22 @@ +# HG changeset patch +# User Elvis Pranskevichus +# Date 1628975143 25200 +# Sat Aug 14 14:05:43 2021 -0700 +# Branch release-1.14 +# Node ID c05da61a029c4979464a48865c350bd8d0dd39f5 +# Parent 7a912c19190f62225217daf9e77b57f3eb225373 +Always use system's libffi on macOS + +diff -r 7a912c19190f -r c05da61a029c setup.py +--- a/setup.py Thu Jul 08 20:57:05 2021 -0700 ++++ b/setup.py Sat Aug 14 14:05:43 2021 -0700 +@@ -105,6 +105,9 @@ + return config.try_compile('#ifndef _MSC_VER\n#error "not MSVC"\n#endif') + + def use_pkg_config(): ++ if 'darwin' in sys.platform: ++ return ++ + if sys.platform == 'darwin' and os.path.exists('/usr/local/bin/brew'): + use_homebrew_for_libffi() + diff --git a/edgedbpkg/edgedb_ls/patches/pypkg-graphql-core__toml.patch b/edgedbpkg/edgedb_ls/patches/pypkg-graphql-core__toml.patch new file mode 100644 index 00000000..84b7dfcd --- /dev/null +++ b/edgedbpkg/edgedb_ls/patches/pypkg-graphql-core__toml.patch @@ -0,0 +1,22 @@ +From 0c0f180faea6703180ce5be7d9a429bfda841842 Mon Sep 17 00:00:00 2001 +From: Rui Chen +Date: Wed, 7 Sep 2022 10:14:32 -0400 +Subject: [PATCH] Remove newline in description (#180) + +--- + pyproject.toml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/pyproject.toml b/pyproject.toml +index 0e351d2d..37ae2df8 100644 +--- a/pyproject.toml ++++ b/pyproject.toml +@@ -2,7 +2,7 @@ + name = "graphql-core" + version = "3.1.7" + description = """ +-GraphQL-core is a Python port of GraphQL.js, ++GraphQL-core is a Python port of GraphQL.js,\ + the JavaScript reference implementation for GraphQL.""" + license = "MIT" + authors = [ diff --git a/integration/linux/build/centos-7/Dockerfile b/integration/linux/build/centos-7/Dockerfile index 09110838..a5ced9d1 100644 --- a/integration/linux/build/centos-7/Dockerfile +++ b/integration/linux/build/centos-7/Dockerfile @@ -34,7 +34,7 @@ RUN ulimit -n 1024 \ ENV GPG_KEY %%PLACEHOLDER%% -ENV PYTHON_VERSION 3.9.18 +ENV PYTHON_VERSION 3.9.19 ENV GIT_VERSION 2.20.1 ENV TAR_VERSION latest ENV RUSTUP_HOME /usr/local/rustup diff --git a/integration/linux/build/centos-8/Dockerfile b/integration/linux/build/centos-8/Dockerfile index bb27d468..bfb9a924 100644 --- a/integration/linux/build/centos-8/Dockerfile +++ b/integration/linux/build/centos-8/Dockerfile @@ -34,7 +34,7 @@ RUN ulimit -n 1024 \ ENV GPG_KEY %%PLACEHOLDER%% -ENV PYTHON_VERSION 3.9.18 +ENV PYTHON_VERSION 3.9.19 ENV GIT_VERSION 2.20.1 ENV TAR_VERSION latest ENV RUSTUP_HOME /usr/local/rustup diff --git a/integration/linux/build/debian-bookworm/Dockerfile b/integration/linux/build/debian-bookworm/Dockerfile index b04fd69f..7171f94f 100644 --- a/integration/linux/build/debian-bookworm/Dockerfile +++ b/integration/linux/build/debian-bookworm/Dockerfile @@ -21,7 +21,7 @@ RUN apt-get update \ zstd \ && rm -rf /var/lib/apt/lists/* -ENV PYTHON_VERSION 3.9.18 +ENV PYTHON_VERSION 3.9.19 ENV RUSTUP_HOME /usr/local/rustup ENV CARGO_HOME /usr/local/cargo ENV PATH /usr/local/cargo/bin:$PATH diff --git a/integration/linux/build/debian-bullseye/Dockerfile b/integration/linux/build/debian-bullseye/Dockerfile index a7024880..0e213653 100644 --- a/integration/linux/build/debian-bullseye/Dockerfile +++ b/integration/linux/build/debian-bullseye/Dockerfile @@ -21,7 +21,7 @@ RUN apt-get update \ zstd \ && rm -rf /var/lib/apt/lists/* -ENV PYTHON_VERSION 3.9.18 +ENV PYTHON_VERSION 3.9.19 ENV RUSTUP_HOME /usr/local/rustup ENV CARGO_HOME /usr/local/cargo ENV PATH /usr/local/cargo/bin:$PATH diff --git a/integration/linux/build/debian-buster/Dockerfile b/integration/linux/build/debian-buster/Dockerfile index afe02cfc..4ad9a1f4 100644 --- a/integration/linux/build/debian-buster/Dockerfile +++ b/integration/linux/build/debian-buster/Dockerfile @@ -21,7 +21,7 @@ RUN apt-get update \ zstd \ && rm -rf /var/lib/apt/lists/* -ENV PYTHON_VERSION 3.9.18 +ENV PYTHON_VERSION 3.9.19 ENV RUSTUP_HOME /usr/local/rustup ENV CARGO_HOME /usr/local/cargo ENV PATH /usr/local/cargo/bin:$PATH diff --git a/integration/linux/build/fedora-29/Dockerfile b/integration/linux/build/fedora-29/Dockerfile index e707a35d..87308e94 100644 --- a/integration/linux/build/fedora-29/Dockerfile +++ b/integration/linux/build/fedora-29/Dockerfile @@ -21,7 +21,7 @@ RUN yum install -y \ curl-devel xz-devel libffi-devel gettext glibc-langpack-en ENV GPG_KEY %%PLACEHOLDER%% -ENV PYTHON_VERSION 3.9.18 +ENV PYTHON_VERSION 3.9.19 ENV GIT_VERSION 2.20.1 ENV RUSTUP_HOME /usr/local/rustup ENV CARGO_HOME /usr/local/cargo diff --git a/integration/linux/build/linux-aarch64/Dockerfile b/integration/linux/build/linux-aarch64/Dockerfile index b980b5ff..1e172228 100644 --- a/integration/linux/build/linux-aarch64/Dockerfile +++ b/integration/linux/build/linux-aarch64/Dockerfile @@ -14,7 +14,7 @@ ENV LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:/usr/local/lib" ENV LANG C ENV GPG_KEY %%PLACEHOLDER%% -ENV PYTHON_VERSION 3.9.18 +ENV PYTHON_VERSION 3.9.19 ENV GIT_VERSION 2.33.1 ENV PATCHELF_VERSION 0.13 ENV TAR_VERSION latest diff --git a/integration/linux/build/linux-x86_64/Dockerfile b/integration/linux/build/linux-x86_64/Dockerfile index 806e4894..9acd88bf 100644 --- a/integration/linux/build/linux-x86_64/Dockerfile +++ b/integration/linux/build/linux-x86_64/Dockerfile @@ -14,7 +14,7 @@ ENV LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:/usr/local/lib" ENV LANG C ENV GPG_KEY %%PLACEHOLDER%% -ENV PYTHON_VERSION 3.9.18 +ENV PYTHON_VERSION 3.9.19 ENV GIT_VERSION 2.33.1 ENV PATCHELF_VERSION 0.13 ENV TAR_VERSION latest diff --git a/integration/linux/build/ubuntu-bionic/Dockerfile b/integration/linux/build/ubuntu-bionic/Dockerfile index 58c37851..354f9f9d 100644 --- a/integration/linux/build/ubuntu-bionic/Dockerfile +++ b/integration/linux/build/ubuntu-bionic/Dockerfile @@ -21,7 +21,7 @@ RUN apt-get update \ zstd \ && rm -rf /var/lib/apt/lists/* -ENV PYTHON_VERSION 3.9.18 +ENV PYTHON_VERSION 3.9.19 ENV RUSTUP_HOME /usr/local/rustup ENV CARGO_HOME /usr/local/cargo ENV PATH /usr/local/cargo/bin:$PATH diff --git a/integration/linux/build/ubuntu-focal/Dockerfile b/integration/linux/build/ubuntu-focal/Dockerfile index 74348944..4b139720 100644 --- a/integration/linux/build/ubuntu-focal/Dockerfile +++ b/integration/linux/build/ubuntu-focal/Dockerfile @@ -21,7 +21,7 @@ RUN apt-get update \ zstd \ && rm -rf /var/lib/apt/lists/* -ENV PYTHON_VERSION 3.9.18 +ENV PYTHON_VERSION 3.9.19 ENV RUSTUP_HOME /usr/local/rustup ENV CARGO_HOME /usr/local/cargo ENV PATH /usr/local/cargo/bin:$PATH diff --git a/integration/linux/build/ubuntu-hirsute/Dockerfile b/integration/linux/build/ubuntu-hirsute/Dockerfile index df1753f4..b9543ff3 100644 --- a/integration/linux/build/ubuntu-hirsute/Dockerfile +++ b/integration/linux/build/ubuntu-hirsute/Dockerfile @@ -21,7 +21,7 @@ RUN apt-get update \ zstd \ && rm -rf /var/lib/apt/lists/* -ENV PYTHON_VERSION 3.9.18 +ENV PYTHON_VERSION 3.9.19 ENV RUSTUP_HOME /usr/local/rustup ENV CARGO_HOME /usr/local/cargo ENV PATH /usr/local/cargo/bin:$PATH diff --git a/integration/linux/build/ubuntu-jammy/Dockerfile b/integration/linux/build/ubuntu-jammy/Dockerfile index a9f14595..6b882fab 100644 --- a/integration/linux/build/ubuntu-jammy/Dockerfile +++ b/integration/linux/build/ubuntu-jammy/Dockerfile @@ -21,7 +21,7 @@ RUN apt-get update \ zstd \ && rm -rf /var/lib/apt/lists/* -ENV PYTHON_VERSION 3.9.18 +ENV PYTHON_VERSION 3.9.19 ENV RUSTUP_HOME /usr/local/rustup ENV CARGO_HOME /usr/local/cargo ENV PATH /usr/local/cargo/bin:$PATH diff --git a/integration/linux/test-systemd/debian-bookworm/Dockerfile b/integration/linux/test-systemd/debian-bookworm/Dockerfile index 0ea4d3a0..40d1f141 100644 --- a/integration/linux/test-systemd/debian-bookworm/Dockerfile +++ b/integration/linux/test-systemd/debian-bookworm/Dockerfile @@ -4,7 +4,7 @@ # PLEASE DO NOT EDIT IT DIRECTLY. # -FROM debian:bullseye +FROM debian:bookworm ENV container docker