Skip to content

Commit

Permalink
edgedb-ls (#89)
Browse files Browse the repository at this point in the history
  • Loading branch information
aljazerzen authored May 29, 2024
1 parent 68288f2 commit c70f063
Show file tree
Hide file tree
Showing 19 changed files with 387 additions and 14 deletions.
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
310 changes: 310 additions & 0 deletions edgedbpkg/edgedb_ls/__init__.py
Original file line number Diff line number Diff line change
@@ -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"]
1 change: 1 addition & 0 deletions edgedbpkg/edgedb_ls/install.list
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{bindir}/edgedb-ls.py
18 changes: 18 additions & 0 deletions edgedbpkg/edgedb_ls/no_install.list
Original file line number Diff line number Diff line change
@@ -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
22 changes: 22 additions & 0 deletions edgedbpkg/edgedb_ls/patches/pypkg-cffi__pkgconfig.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# HG changeset patch
# User Elvis Pranskevichus <[email protected]>
# 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()

22 changes: 22 additions & 0 deletions edgedbpkg/edgedb_ls/patches/pypkg-graphql-core__toml.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
From 0c0f180faea6703180ce5be7d9a429bfda841842 Mon Sep 17 00:00:00 2001
From: Rui Chen <[email protected]>
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 = [
2 changes: 1 addition & 1 deletion integration/linux/build/centos-7/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit c70f063

Please sign in to comment.