diff options
Diffstat (limited to 'noxfile.py')
-rw-r--r-- | noxfile.py | 257 |
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) |