diff --git a/README.md b/README.md index 3f365bc04..52a4ed768 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ Open it searching for "Show diagnostics panel" in JupyterLab commands palette or Either: -- JupyterLab >=2,<3.0.0a0 +- JupyterLab >=2.1.0,<3.0.0a0 And: @@ -99,9 +99,9 @@ Use of a python `virtualenv` or a conda env is also recommended. 1. install JupyterLab ```bash - conda install -c conda-forge 'jupyterlab>=2,<2.1.0a0' + conda install -c conda-forge 'jupyterlab>=2.1,<3.0.0a0' # or - pip install 'jupyterlab>=2,<2.1.0a0' + pip install 'jupyterlab>=2.1,<3.0.0a0' ``` 1. install the server extension: diff --git a/binder/environment.yml b/binder/environment.yml index ad84ddb87..c119e143c 100644 --- a/binder/environment.yml +++ b/binder/environment.yml @@ -7,7 +7,7 @@ channels: dependencies: # runtime dependencies - python >=3.7,<3.8.0a0 - - jupyterlab >=2,<3.0.0a0 + - jupyterlab >=2.1.0,<3.0.0a0 - notebook >=4.3.1 # build dependencies - nodejs >=10,<14 diff --git a/ci/job.test.yml b/ci/job.test.yml index e12289aaf..ad26b6f61 100644 --- a/ci/job.test.yml +++ b/ci/job.test.yml @@ -12,15 +12,15 @@ parameters: pythons: - name: ThreeSix spec: '=3.6' - lab: '>=2,<3.0.0a0' + lab: '>=2.1.0,<3.0.0a0' nodejs: '>=10,<11.0.0.a0' - name: ThreeSeven spec: '=3.7' - lab: '>=2,<3.0.0a0' + lab: '>=2.1.0,<3.0.0a0' nodejs: '>=12,<13.0.0a0' - name: ThreeEight spec: '=3.8' - lab: '>=2,<3.0.0a0' + lab: '>=2.1.0,<3.0.0a0' nodejs: '>=13,<14.0.0a0' js_cov_packages: - jupyterlab-go-to-definition diff --git a/docs/Installation.ipynb b/docs/Installation.ipynb index 7cc44e48d..0ed33e253 100644 --- a/docs/Installation.ipynb +++ b/docs/Installation.ipynb @@ -1,5 +1,25 @@ { "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hide_input": true + }, + "outputs": [], + "source": [ + "from markdown import markdown\n", + "import sys\n", + "sys.path.insert(0, '..')\n", + "from versions import (\n", + " JUPYTER_LSP_VERSION,\n", + " JUPYTERLAB_LSP_VERSION,\n", + " JUPYTERLAB_NEXT_MAJOR_VERSION,\n", + " JUPYTERLAB_VERSION,\n", + " REQUIRED_JUPYTERLAB\n", + ")" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -8,9 +28,14 @@ ] }, { - "cell_type": "markdown", - "metadata": {}, + "cell_type": "code", + "execution_count": null, + "metadata": { + "hide_input": true + }, + "outputs": [], "source": [ + "%%markdown\n", "### Please Read This First\n", "\n", "Delivering LSP features to your JupyterLab **requires** three pieces:\n", @@ -28,7 +53,7 @@ "- runs in your browser, as an extension to JupyterLab\n", "- to install it, you need:\n", " - `nodejs >8`\n", - " - `jupyterlab >=1.1,<2`\n", + " - `jupyterlab {REQUIRED_JUPYTERLAB}`\n", "\n", "#### Language Servers\n", "\n", @@ -49,17 +74,22 @@ ] }, { - "cell_type": "markdown", - "metadata": {}, + "cell_type": "code", + "execution_count": null, + "metadata": { + "hide_input": true + }, + "outputs": [], "source": [ + "%%markdown\n", "#### conda (minimal python)\n", "\n", "```bash\n", - "conda create -c conda-forge -n lsp 'python >=3.7,<3.8' 'jupyterlab=1.2' 'nodejs>8' python-language-server\n", + "conda create -c conda-forge -n lsp 'python >=3.7,<3.8' 'jupyterlab={JUPYTERLAB_VERSION}' 'nodejs>8' python-language-server\n", "# Also consider: r-languageserver [*]\n", "source activate lsp\n", - "python -m pip install 'jupyter-lsp=0.8.0' --no-deps\n", - "jupyter labextension install '@krassowski/jupyterlab-lsp@1.0.0'\n", + "python -m pip install 'jupyter-lsp={JUPYTER_LSP_VERSION}' --no-deps\n", + "jupyter labextension install '@krassowski/jupyterlab-lsp@{JUPYTERLAB_LSP_VERSION}'\n", "```\n", "\n", "Then run\n", @@ -84,9 +114,14 @@ ] }, { - "cell_type": "markdown", - "metadata": {}, + "cell_type": "code", + "execution_count": null, + "metadata": { + "hide_input": true + }, + "outputs": [], "source": [ + "%%markdown\n", "##### `Dockerfile`\n", "\n", "```dockerfile\n", @@ -95,12 +130,12 @@ "\n", "RUN conda install --quiet --yes --freeze-installed \\\n", " 'python-language-server' \\\n", - " 'jupyterlab=2' \\\n", + " 'jupyterlab=2.1' \\\n", " 'r-languageserver' \\\n", " && python3 -m pip install --no-cache-dir --no-deps \\\n", - " 'jupyter-lsp=0.8.0' \\\n", + " 'jupyter-lsp={JUPYTER_LSP_VERSION}' \\\n", " && jupyter labextension install --no-build \\\n", - " '@krassowski/jupyterlab-lsp@1.0.0' \\\n", + " '@krassowski/jupyterlab-lsp@{JUPYTERLAB_LSP_VERSION}' \\\n", " && jupyter lab build --dev-build=False --minimize=True \\\n", " && conda clean --all -f -y \\\n", " && rm -rf \\\n", @@ -202,14 +237,19 @@ ] }, { - "cell_type": "markdown", - "metadata": {}, + "cell_type": "code", + "execution_count": null, + "metadata": { + "hide_input": true + }, + "outputs": [], "source": [ + "%%markdown\n", "#### Install Jupyter[Lab] LSP\n", "\n", "```bash\n", - "pip install jupyter-lsp=0.8.0\n", - "jupyter labextension install @krassowski/jupyterlab-lsp@1.0.0\n", + "pip install jupyter-lsp={JUPYTER_LSP_VERSION}\n", + "jupyter labextension install @krassowski/jupyterlab-lsp@{JUPYTERLAB_LSP_VERSION}\n", "```" ] }, @@ -245,7 +285,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.6" + "version": "3.7.5" } }, "nbformat": 4, diff --git a/docs/Releasing.ipynb b/docs/Releasing.ipynb index 7af47677a..0f21cc4fd 100644 --- a/docs/Releasing.ipynb +++ b/docs/Releasing.ipynb @@ -25,7 +25,7 @@ "- TODO: create a `release.py` script\n", " [#88](https://github.com/krassowski/jupyterlab-lsp/issues/88)\n", "\n", - "The PyPI version must be updated in the following places:\n", + "The PyPI version (jupyter-lsp) must be updated in the following places:\n", "\n", "- `py_src/jupyter_lsp/_version.py` (canonical)\n", "- `azure-pipelines.yml`\n", @@ -33,17 +33,25 @@ "\n", "The npm version of `jupyterlab-lsp` must be updated in the following places:\n", "\n", - "- `packages/jupyterlab-lsp/package.json` (canonical)\n", + "- `packages/jupyterlab-lsp/package.json` > `version` (canonical)\n", "- `azure-pipelines.yml`\n", "- `packages/metapackage/package.json`\n", "- `CHANGELOG.md`\n", "\n", "The npm version of `lsp-ws-connection` must be updated in the following places:\n", "\n", - "- `packages/lsp-ws-connection/package.json` (canonical)\n", + "- `packages/lsp-ws-connection/package.json` > `version` (canonical)\n", "- `packages/jupyterlab-lsp/package.json`\n", "- `CHANGELOG.md`\n", "\n", + "The JupyterLab version (if a newer is supported or required) needs to be updated\n", + "in:\n", + "\n", + "- `packages/jupyterlab-lsp/package.json` > `devDependencies` >\n", + " `@jupyterlab/application` (canonical)\n", + "- `binder/environment.yml`\n", + "- `README.md`\n", + "\n", "### Releasing:\n", "\n", "```bash\n", @@ -74,7 +82,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.0" + "version": "3.7.5" } }, "nbformat": 4, diff --git a/docs/__init__.py b/docs/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/docs/markdown.py b/docs/markdown.py new file mode 100644 index 000000000..a07650075 --- /dev/null +++ b/docs/markdown.py @@ -0,0 +1,13 @@ +from IPython.core.magic import needs_local_scope, register_cell_magic +from IPython.display import Markdown + + +@register_cell_magic +@needs_local_scope +def markdown(line, cell, local_ns): + """Cell interpreted as Markdown but with variable substitution support. + + Variables from global environment will be substituted using the standard + Python format mechanism which uses single curly braces (e.g. {variable}) + """ + return Markdown(cell.format(**local_ns)) diff --git a/packages/jupyterlab-lsp/package.json b/packages/jupyterlab-lsp/package.json index 98f78757d..1faac034f 100644 --- a/packages/jupyterlab-lsp/package.json +++ b/packages/jupyterlab-lsp/package.json @@ -42,7 +42,7 @@ }, "devDependencies": { "@babel/preset-env": "^7.4.3", - "@jupyterlab/application": "~2.0.0", + "@jupyterlab/application": "~2.1.0", "@jupyterlab/apputils": "~2.0.0", "@jupyterlab/cells": "~2.0.0", "@jupyterlab/codeeditor": "~2.0.0", @@ -77,7 +77,7 @@ "typescript": "~3.9.5" }, "peerDependencies": { - "@jupyterlab/application": "~2.0.0", + "@jupyterlab/application": "~2.1.0", "@jupyterlab/apputils": "~2.0.0", "@jupyterlab/cells": "~2.0.0", "@jupyterlab/codeeditor": "~2.0.0", diff --git a/requirements/lab.txt b/requirements/lab.txt index 4f1a8a976..f977c4b5a 100644 --- a/requirements/lab.txt +++ b/requirements/lab.txt @@ -1,3 +1,3 @@ # the version of jupyterlab -r ./prod.txt -jupyterlab >=2,<3.0.0a0 +jupyterlab >=2.1.0,<3.0.0a0 diff --git a/scripts/integrity.py b/scripts/integrity.py index 899f67f46..62cd9bb7e 100644 --- a/scripts/integrity.py +++ b/scripts/integrity.py @@ -6,13 +6,14 @@ import json import pathlib -import re import sys import tempfile from importlib.util import find_spec import jsonschema +import nbformat import pytest +from nbconvert.preprocessors import ExecutePreprocessor try: import ruamel.yaml as yaml @@ -20,6 +21,17 @@ import ruamel_yaml as yaml ROOT = pathlib.Path.cwd() + +sys.path.insert(0, str(ROOT)) + +if True: + # a workaround for isort 4.0 limitations + # see https://github.com/timothycrosley/isort/issues/468 + from versions import ( # noqa + REQUIRED_JUPYTERLAB as LAB_SPEC, + JUPYTER_LSP_VERSION as PY_VERSION, + ) + REQS = ROOT / "requirements" BINDER = ROOT / "binder" @@ -27,14 +39,6 @@ MAIN_README = ROOT / "README.md" CHANGELOG = ROOT / "CHANGELOG.md" -# dependencies -ENV = yaml.safe_load((BINDER / "environment.yml").read_text()) -LAB_SPEC = [ - d.split(" ", 1)[1] - for d in ENV["dependencies"] - if isinstance(d, str) and d.startswith("jupyterlab ") -][0] - # TS stuff NPM_NS = "@krassowski" PACKAGES = { @@ -55,8 +59,7 @@ # py stuff PY_NAME = "jupyter-lsp" -_VERSION_PY = ROOT / "py_src" / "jupyter_lsp" / "_version.py" -PY_VERSION = re.findall(r'= "(.*)"$', (_VERSION_PY).read_text())[0] + # CI stuff PIPE_FILE = ROOT / "azure-pipelines.yml" @@ -87,9 +90,16 @@ def the_meta_package(): @pytest.fixture(scope="module") def the_installation_notebook(): - """ loads up the installation notebook + """ executes and loads up the installation notebook """ - return (DOCS / "Installation.ipynb").read_text() + with open(DOCS / "Installation.ipynb") as f: + installation_nb = nbformat.read(f, as_version=4) + executor = ExecutePreprocessor(timeout=600) + + # modifies notebook in-place + executor.preprocess(installation_nb, {"metadata": {"path": DOCS}}) + + return nbformat.writes(installation_nb) @pytest.mark.parametrize( @@ -138,7 +148,16 @@ def test_ts_package_integrity(name, info, the_meta_package): @pytest.mark.parametrize( - "path", map(str, [REQS / "lab.txt", CI / "job.test.yml", MAIN_README]) + "path", + map( + str, + [ + REQS / "lab.txt", + CI / "job.test.yml", + MAIN_README, + BINDER / "environment.yml", + ], + ), ) def test_jlab_versions(path): """ is the version of jupyterlab consistent? diff --git a/versions.py b/versions.py new file mode 100644 index 000000000..9db8b1d86 --- /dev/null +++ b/versions.py @@ -0,0 +1,22 @@ +import json +from pathlib import Path +from re import findall + +ROOT = Path(__file__).resolve().parent + + +_VERSION_PY = ROOT / "py_src" / "jupyter_lsp" / "_version.py" +JUPYTER_LSP_VERSION = findall(r'= "(.*)"$', (_VERSION_PY).read_text())[0] + +with open(ROOT / "packages/jupyterlab-lsp/package.json") as f: + jupyterlab_lsp_package = json.load(f) + +JUPYTERLAB_LSP_VERSION = jupyterlab_lsp_package['version'] +JUPYTERLAB_VERSION = ( + jupyterlab_lsp_package + ['devDependencies'] + ['@jupyterlab/application'] + .lstrip('~^') +) +JUPYTERLAB_NEXT_MAJOR_VERSION = int(JUPYTERLAB_VERSION.split('.')[0]) + 1 +REQUIRED_JUPYTERLAB = f'>={JUPYTERLAB_VERSION},<{JUPYTERLAB_NEXT_MAJOR_VERSION}.0.0a0'