summaryrefslogtreecommitdiffstats
path: root/noxfile.py
diff options
context:
space:
mode:
Diffstat (limited to 'noxfile.py')
-rw-r--r--noxfile.py257
1 files changed, 257 insertions, 0 deletions
diff --git a/noxfile.py b/noxfile.py
new file mode 100644
index 0000000..88cf122
--- /dev/null
+++ b/noxfile.py
@@ -0,0 +1,257 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+import json
+import os
+import pathlib
+import urllib.request as url_lib
+
+import nox
+
+
+def _install_requirements(session: nox.Session):
+ session.install(
+ "-r",
+ "./packages/python/requirements.txt",
+ "-r",
+ "./requirements.txt",
+ )
+ session.run("pip", "list")
+
+
+@nox.session()
+def tests(session: nox.Session):
+ """Run tests for generator and generated code in all languages."""
+ _install_requirements(session)
+
+ session.log("Running test data generator.")
+ session.run("python", "-m", "generator", "--plugin", "testdata")
+
+ session.log("Running tests: generator and generated Python code.")
+ session.run("pytest", "./tests")
+
+
+@nox.session()
+def lint(session: nox.Session):
+ """Linting for generator and generated code in all languages."""
+ _install_requirements(session)
+
+ session.log("Linting: generator and generated Python code.")
+ session.install("isort", "black", "mypy")
+ session.run("isort", "--profile", "black", "--check", ".")
+ session.run("black", "--check", ".")
+ session.run("mypy", "--strict", "--no-incremental", "./packages/python/lsprotocol")
+
+ session.log("Linting: generated Rust code.")
+ with session.chdir("./packages/rust/lsprotocol"):
+ session.run("cargo", "fmt", "--check", external=True)
+
+
+@nox.session()
+def format(session: nox.Session):
+ """Format generator and lsprotocol package for PyPI."""
+ _format_code(session)
+
+
+def _format_code(session: nox.Session):
+ session.install("isort", "black")
+
+ session.run("isort", "--profile", "black", "noxfile.py")
+ session.run("black", "noxfile.py")
+
+ session.run("isort", "--profile", "black", "generator")
+ session.run("black", "generator")
+
+ session.run("isort", "--profile", "black", "tests/generator")
+ session.run("black", "tests/generator")
+
+ session.run("isort", "--profile", "black", "tests/python")
+ session.run("black", "tests/python")
+
+ # this is for the lsprotocol package only
+ python_package_path = os.fspath(pathlib.Path("./packages/python/lsprotocol"))
+ session.run("isort", "--profile", "black", python_package_path)
+ session.run("black", python_package_path)
+
+
+@nox.session()
+def build(session: nox.Session):
+ """Build lsprotocol (python) package for PyPI."""
+ session.install("flit")
+ with session.chdir("./packages/python"):
+ session.run("flit", "build")
+
+
+def _get_content(uri) -> str:
+ with url_lib.urlopen(uri) as response:
+ content = response.read()
+ if isinstance(content, str):
+ return content
+ else:
+ return content.decode("utf-8")
+
+
+MODEL_SCHEMA = "https://raw.githubusercontent.com/microsoft/vscode-languageserver-node/main/protocol/metaModel.schema.json"
+MODEL = "https://raw.githubusercontent.com/microsoft/vscode-languageserver-node/main/protocol/metaModel.json"
+
+
+def _download_models(session: nox.Session):
+ session.log("Downloading LSP model schema.")
+ model_schema_text: str = _get_content(MODEL_SCHEMA)
+ session.log("Downloading LSP model.")
+ model_text: str = _get_content(MODEL)
+
+ schema_path = pathlib.Path(__file__).parent / "generator" / "lsp.schema.json"
+ model_path = schema_path.parent / "lsp.json"
+
+ schema_path.write_text(
+ json.dumps(json.loads(model_schema_text), indent=4, ensure_ascii=False) + "\n",
+ encoding="utf-8",
+ )
+ model_path.write_text(
+ json.dumps(json.loads(model_text), indent=4, ensure_ascii=False) + "\n",
+ encoding="utf-8",
+ )
+
+
+@nox.session()
+def build_lsp(session: nox.Session):
+ """Generate lsprotocol for all languages."""
+ generate_python(session)
+ generate_dotnet(session)
+ generate_rust(session)
+
+
+@nox.session()
+def update_lsp(session: nox.Session):
+ """Update the LSP model and generate the lsprotocol for all languages."""
+ update_packages(session)
+ _download_models(session)
+ build_lsp(session)
+
+
+@nox.session()
+def update_packages(session: nox.Session):
+ """Update dependencies of generator and lsprotocol."""
+ session.install("wheel", "pip-tools")
+
+ session.run(
+ "pip-compile",
+ "--generate-hashes",
+ "--resolver=backtracking",
+ "--upgrade",
+ "./packages/python/requirements.in",
+ )
+ session.run(
+ "pip-compile",
+ "--generate-hashes",
+ "--resolver=backtracking",
+ "--upgrade",
+ "./requirements.in",
+ )
+
+
+@nox.session()
+def create_plugin(session: nox.Session):
+ """Create a new plugin."""
+ name = input("Enter the name of the plugin: ")
+
+ plugin_root = pathlib.Path(__file__).parent / "generator" / "plugins" / name
+ plugin_root.mkdir(parents=True, exist_ok=True)
+
+ init_text = "\n".join(
+ [
+ "# Copyright (c) Microsoft Corporation. All rights reserved.",
+ "# Licensed under the MIT License.",
+ "",
+ f"from .{name}_utils import generate_from_spec as generate",
+ "",
+ ]
+ )
+ plugin_root.joinpath("__init__.py").write_text(init_text, encoding="utf-8")
+
+ utils_text = "\n".join(
+ [
+ "# Copyright (c) Microsoft Corporation. All rights reserved.",
+ "# Licensed under the MIT License.",
+ "",
+ "import pathlib",
+ "from typing import List, Dict",
+ "",
+ "import generator.model as model",
+ "",
+ "",
+ 'PACKAGE_DIR_NAME = "lsprotocol"',
+ "",
+ "",
+ "def generate_from_spec(spec: model.LSPModel, output_dir: str) -> None:",
+ ' """Generate the code for the given spec."""',
+ " # key is the relative path to the file, value is the content",
+ " code: Dict[str, str] = generate_package_code(spec)",
+ " for file_name in code:",
+ " pathlib.Path(output_dir, PACKAGE_DIR_NAME, file_name).write_text(",
+ ' code[file_name], encoding="utf-8"',
+ " )",
+ "",
+ "def generate_package_code(spec: model.LSPModel) -> List[str]:",
+ " return {",
+ ' "src/lib.rs": "code for lib.rs",',
+ " }",
+ "",
+ ]
+ )
+
+ plugin_root.joinpath(f"{name}_utils.py").write_text(utils_text, encoding="utf-8")
+
+ package_root = pathlib.Path(__file__).parent / "packages" / name / "lsprotocol"
+ package_root.mkdir(parents=True, exist_ok=True)
+ package_root.joinpath("README.md").write_text(
+ f"# your generated code and other package files go under this directory.",
+ encoding="utf-8",
+ )
+
+ tests_root = pathlib.Path(__file__).parent / "tests" / name
+ tests_root.mkdir(parents=True, exist_ok=True)
+ tests_root.joinpath("README.md").write_text(
+ f"# your tests go under this directory.", encoding="utf-8"
+ )
+
+ launch_json_path = pathlib.Path(__file__).parent / ".vscode" / "launch.json"
+ launch_json = json.loads(launch_json_path.read_text(encoding="utf-8"))
+
+ for i in launch_json["inputs"]:
+ if i["id"] == "plugin":
+ i["options"].append(name)
+
+ launch_json_path.write_text(json.dumps(launch_json, indent=4), encoding="utf-8")
+
+ session.log(f"Created plugin {name}.")
+
+
+@nox.session()
+def generate_dotnet(session: nox.Session):
+ """Update the dotnet code."""
+ _install_requirements(session)
+
+ session.run("python", "-m", "generator", "--plugin", "dotnet")
+ with session.chdir("./packages/dotnet/lsprotocol"):
+ session.run("dotnet", "format", external=True)
+ session.run("dotnet", "build", external=True)
+
+
+@nox.session()
+def generate_python(session: nox.Session):
+ """Update the python code."""
+ _install_requirements(session)
+
+ session.run("python", "-m", "generator", "--plugin", "python")
+ _format_code(session)
+
+
+@nox.session()
+def generate_rust(session: nox.Session):
+ """Update the rust code."""
+ _install_requirements(session)
+
+ session.run("python", "-m", "generator", "--plugin", "rust")
+ with session.chdir("./packages/rust/lsprotocol"):
+ session.run("cargo", "fmt", external=True)