From af495fd703332cdeed04c5d250af2649645455d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix-Antoine=20Fortin?= Date: Tue, 28 Mar 2023 15:01:27 -0400 Subject: [PATCH 1/4] Make setup.py install labextension --- .gitignore | 1 + jupyterlab/package.json | 32 +++++++--- jupyterlab/tsconfig.json | 4 +- pyproject.toml | 4 ++ setup.py | 133 +++++++++++++++++++++++++++++++-------- 5 files changed, 138 insertions(+), 36 deletions(-) create mode 100644 pyproject.toml diff --git a/.gitignore b/.gitignore index e8bad80..841bd0b 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ jupyterlmod.egg-info/ *.lock *env*/ package-lock.json +jupyterlmod/labextension diff --git a/jupyterlab/package.json b/jupyterlab/package.json index 8b2caa6..a17ab32 100644 --- a/jupyterlab/package.json +++ b/jupyterlab/package.json @@ -12,7 +12,8 @@ "url": "https://github.com/cmd-ntrf/jupyter-lmod/issues" }, "license": "MIT", - "author": "etienned", + "author": "Félix-Antoine Fortin ", + "contributors": ["Étienne Dubeau", "Guillaume Moutier", "Alex Domingo"], "files": [ "lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}", "style/*.css" @@ -25,10 +26,24 @@ "url": "https://github.com/cmd-ntrf/jupyter-lmod.git" }, "scripts": { - "build": "tsc", - "clean": "rimraf lib", - "watch": "tsc -w", - "prepare": "npm run clean && npm run build" + "build": "jlpm run build:lib && jlpm run build:labextension:dev", + "build:prod": "jlpm run build:lib && jlpm run build:labextension", + "build:labextension": "jupyter labextension build .", + "build:labextension:dev": "jupyter labextension build --development True .", + "build:lib": "tsc", + "clean": "jlpm run clean:lib", + "clean:lib": "rimraf lib tsconfig.tsbuildinfo", + "clean:labextension": "rimraf jupyterlab-lmod/labextension", + "clean:all": "jlpm run clean:lib && jlpm run clean:labextension", + "eslint": "eslint . --ext .ts,.tsx --fix", + "eslint:check": "eslint . --ext .ts,.tsx", + "eslint:check:junit": "eslint . --ext .ts,.tsx --format junit --output-file linting.xml", + "install:extension": "jupyter labextension develop --overwrite .", + "prepare": "jlpm run clean && jlpm run build:prod", + "watch": "run-p watch:src watch:labextension", + "watch:src": "tsc -w", + "watch:labextension": "jupyter labextension watch ." + }, "dependencies": { "@jupyterlab/application": "^2.0.0 || ^3.0.0", @@ -37,9 +52,12 @@ }, "devDependencies": { "rimraf": "~3.0.2", - "typescript": "~4.1.3" + "typescript": "~4.1.3", + "@jupyterlab/builder": "^3.6.1" }, "jupyterlab": { - "extension": true + "extension": true, + "schemaDir": "schema", + "outputDir": "../jupyterlmod/labextension" } } diff --git a/jupyterlab/tsconfig.json b/jupyterlab/tsconfig.json index 1834133..f1f676f 100644 --- a/jupyterlab/tsconfig.json +++ b/jupyterlab/tsconfig.json @@ -1,13 +1,13 @@ { "compilerOptions": { - "lib": ["es2017", "dom"], + "lib": ["es2018", "dom"], "module": "commonjs", "esModuleInterop" : true, "moduleResolution": "node", "noEmitOnError": true, "noUnusedLocals": true, "outDir": "./lib", - "target": "es2017", + "target": "es2018", "strict": true, "strictNullChecks": false, "noImplicitAny": false, diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..7f33979 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,4 @@ +[build-system] +requires = ["jupyter_packaging~=0.7.9", "jupyterlab~=3.0", "setuptools>=40.8.0", "wheel"] +build-backend = "setuptools.build_meta" + diff --git a/setup.py b/setup.py index 6ce8f78..8860dcf 100644 --- a/setup.py +++ b/setup.py @@ -1,43 +1,122 @@ #!/usr/bin/env python # coding: utf-8 + +"""jupyterlmod setup""" + +import json from glob import glob -from setuptools import setup +from pathlib import Path + +from jupyter_packaging import ( + create_cmdclass, + install_npm, + ensure_targets, + combine_commands, + skip_if_exists, +) +import setuptools + +HERE = Path(__file__).parent.resolve() + +# The name of the project +name = "jupyterlmod" + +lab_path = HERE / name / "labextension" + +# Representative files that should exist after a successful build +jstargets = [ + str(lab_path / "package.json"), +] + +package_data_spec = { + name: ["*"], +} + +labext_name = "@cmd-ntrf/jupyterlab-lmod" + +data_files_spec = [ + ("share/jupyter/labextensions/%s" % labext_name, str(lab_path), "**"), + ("share/jupyter/labextensions/%s" % labext_name, str(HERE), "install.json"), + ( + "etc/jupyter/jupyter_notebook_config.d", + "jupyterlmod/etc", + "jupyterlmod_serverextension.json" + ), + ( + "etc/jupyter/jupyter_server_config.d", + "jupyterlmod/etc", + "jupyterlmod_jupyterserverextension.json" + ), + ( + "etc/jupyter/nbconfig/tree.d", + "jupyterlmod/etc", + "jupyterlmod_nbextension.json", + ) +] + +cmdclass = create_cmdclass( + "jsdeps", package_data_spec=package_data_spec, data_files_spec=data_files_spec +) + +js_command = combine_commands( + install_npm(HERE / "jupyterlab", build_cmd="build:prod", npm=["jlpm"]), + ensure_targets(jstargets), +) + +is_repo = (HERE / ".git").exists() +if is_repo: + cmdclass["jsdeps"] = js_command +else: + cmdclass["jsdeps"] = skip_if_exists(jstargets, js_command) + +long_description = (HERE / "README.md").read_text() + +# Get the package info from package.json +pkg_json = json.loads((HERE / "jupyterlab" / "package.json").read_bytes()) + +settings_path = "./config/settings/*.json" + setup_args = dict( - name = 'jupyterlmod', - packages = ['jupyterlmod', 'lmod'], - version = "3.1.0", - description = "jupyterlmod: notebook server extension to interact with Lmod system", - long_description = "Jupyter interactive notebook server extension that allows user to select software modules to load with Lmod before launching kernels.", - author = "Félix-Antoine Fortin", - author_email = "felix-antoine.fortin@calculquebec.ca", - url = "http://www.calculquebec.ca", - license = "MIT", - platforms = "Linux, Mac OS X", - keywords = ['Interactive', 'Interpreter', 'Shell', 'Web', 'Lmod'], - classifiers = [ - 'Intended Audience :: Developers', - 'Intended Audience :: System Administrators', - 'Intended Audience :: Science/Research', - 'License :: OSI Approved :: MIT License', - 'Programming Language :: Python', - 'Programming Language :: Python :: 3', - ], - install_requires = [ + name=name, + version=pkg_json["version"], + url=pkg_json["homepage"], + author=pkg_json["author"], + description=pkg_json["description"], + license=pkg_json["license"], + long_description=long_description, + long_description_content_type="text/markdown", + cmdclass=cmdclass, + packages=setuptools.find_packages(), + install_requires=[ 'jupyter-core', 'jupyter-server' ], data_files=[ - ('share/jupyter/nbextensions/jupyterlmod', glob('jupyterlmod/static/*')), + ('share/jupyter/nbextensions/jupyterlmod ', glob('jupyterlmod/static/*')), ('etc/jupyter/jupyter_notebook_config.d', ['jupyterlmod/etc/jupyterlmod_serverextension.json']), ("etc/jupyter/jupyter_server_config.d", ['jupyterlmod/etc/jupyterlmod_jupyterserverextension.json']), ('etc/jupyter/nbconfig/tree.d', ['jupyterlmod/etc/jupyterlmod_nbextension.json']) ], - zip_safe=False + zip_safe=False, + include_package_data=True, + python_requires=">=3.6", + platforms="Linux, Mac OS X, Windows", + keywords=["Jupyter", "JupyterLab", "JupyterLab3", "Modules", "Tmod"], + classifiers=[ + "License :: OSI Approved :: BSD License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Framework :: Jupyter", + ], ) -def main(): - setup(**setup_args) -if __name__ == '__main__': - main() +if __name__ == "__main__": + setuptools.setup(**setup_args) + From 42d400cb5e516d3dc570cdeb6a557510a0d149d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix-Antoine=20Fortin?= Date: Tue, 28 Mar 2023 16:18:52 -0400 Subject: [PATCH 2/4] Migrate to hatch --- .github/workflows/main.yml | 9 ++- README.md | 30 +++++++-- jupyterlab/package.json | 18 ++++-- pyproject.toml | 100 +++++++++++++++++++++++++++++- setup.py | 123 +------------------------------------ 5 files changed, 141 insertions(+), 139 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0c36fed..f27ff08 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -21,11 +21,14 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install setuptools wheel twine - - name: Build and publish + pip install wheel twine + - name: Build dist + run: | + pyproject-build + cd dist && sha256sum * | tee SHA256SUMS + - name: Publish env: TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} run: | - python setup.py sdist bdist_wheel twine upload dist/* diff --git a/README.md b/README.md index e588c07..f16d6ec 100644 --- a/README.md +++ b/README.md @@ -24,12 +24,6 @@ proxy server launchers to JupyterLab UI when modules with matching names are loa pip install jupyterlmod ``` -### jupyterlab - -``` -jupyter labextension install jupyterlab-lmod -``` - ### Disable jupyter-server-proxy notebook and lab extensions To avoid having items in the launcher that cannot be launched because the binaries location are not in PATH, @@ -63,3 +57,27 @@ c.Lmod.launcher_pins = ['Desktop', 'RStudio'] ![Jupyter notebook demo](https://i.imgur.com/pK1Q5gG.gif) ![JupyterLab demo](https://i.imgur.com/1HDH7iN.gif) + + +## develop + +### requirements + +- pip >= 23 +- [build](https://pypi.org/project/build/) +- nodejs >= 18.x + +### build + +- wheel and tarball: + ```shell + pyproject-build + ``` +- labextension + ```shell + cd jupyterlab + npm install + npm run build + # To install extension in jupyterlab in develop mode: + npm run install:extension + ``` diff --git a/jupyterlab/package.json b/jupyterlab/package.json index a17ab32..035cde6 100644 --- a/jupyterlab/package.json +++ b/jupyterlab/package.json @@ -1,7 +1,7 @@ { - "name": "jupyterlab-lmod", - "version": "1.1.0", - "description": "Lmod JupyterLab extension.", + "name": "@cmd-ntrf/jupyterlab-lmod", + "version": "4.0.0", + "description": "Lmod JupyterLab extension", "keywords": [ "jupyter", "jupyterlab", @@ -12,8 +12,15 @@ "url": "https://github.com/cmd-ntrf/jupyter-lmod/issues" }, "license": "MIT", - "author": "Félix-Antoine Fortin ", - "contributors": ["Étienne Dubeau", "Guillaume Moutier", "Alex Domingo"], + "author": { + "name": "Felix-Antoine Fortin", + "email": "felix@calculquebec.ca" + }, + "contributors": [ + { "name": "Étienne Dubeau" }, + { "name": "Guillaume Moutier" }, + { "name": "Alex Domingo" } + ], "files": [ "lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}", "style/*.css" @@ -43,7 +50,6 @@ "watch": "run-p watch:src watch:labextension", "watch:src": "tsc -w", "watch:labextension": "jupyter labextension watch ." - }, "dependencies": { "@jupyterlab/application": "^2.0.0 || ^3.0.0", diff --git a/pyproject.toml b/pyproject.toml index 7f33979..d2c111b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,4 +1,100 @@ [build-system] -requires = ["jupyter_packaging~=0.7.9", "jupyterlab~=3.0", "setuptools>=40.8.0", "wheel"] -build-backend = "setuptools.build_meta" +requires = [ + "hatch-jupyter-builder >=0.5", + "hatch-nodejs-version", + "hatchling >=1.4.0", + "jupyterlab >=3.4.7,<4.0.0", +] +build-backend = "hatchling.build" +[project] +name = "jupyterlmod" +dynamic = [ + "authors", + "description", + "keywords", + "urls", + "version", +] +readme = "README.md" +license = { file = "LICENSE" } +requires-python = ">=3.6" +classifiers = [ + "Framework :: Jupyter", + "License :: OSI Approved :: BSD License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", +] +dependencies = [ + "jupyter-core", + "jupyter-server", +] + +[tool.hatch.metadata.hooks.nodejs] +path = "jupyterlab/package.json" +fields = ["description", "authors", "urls"] + +[tool.hatch.build] +artifacts = [ + "jupyterlmod.egg-info/", + "jupyterlmod/labextension", +] + +[tool.hatch.build.targets.wheel] +packages = ["jupyterlmod", "lmod"] + +[tool.hatch.build.targets.wheel.shared-data] +"jupyterlmod/static" = "share/jupyter/nbextensions/jupyterlmod" +"jupyterlmod/etc/jupyterlmod_serverextension.json" = "etc/jupyter/jupyter_notebook_config.d/jupyterlmod_serverextension.json" +"jupyterlmod/etc/jupyterlmod_jupyterserverextension.json" = "etc/jupyter/jupyter_server_config.d/jupyterlmod_jupyterserverextension.json" +"jupyterlmod/etc/jupyterlmod_nbextension.json" = "etc/jupyter/nbconfig/tree.d/jupyterlmod_nbextension.json" +"jupyterlmod/labextension" = "share/jupyter/labextensions/@cmd-ntrf/jupyterlab-lmod" +"./install.json" = "share/jupyter/labextensions/@cmd-ntrf/jupyterlab-lmod/install.json" + +[tool.hatch.version] +source = "nodejs" +path = "jupyterlab/package.json" + +[tool.hatch.build.targets.sdist] +exclude = [ + ".github", +] + +[tool.hatch.build.hooks.jupyter-builder] +ensured-targets = [ + "jupyterlmod/labextension/package.json", +] +dependencies = [ + "hatch-jupyter-builder>=0.8.2", +] +build-function = "hatch_jupyter_builder.npm_builder" + +[tool.hatch.build.hooks.jupyter-builder.build-kwargs] +path = "jupyterlab" +build_cmd = "build:prod" +npm = [ + "jlpm", +] + +[tool.tbump] +field = [ + { name = "channel", default = "" }, + { name = "release", default = "" }, +] + +[tool.tbump.version] +current = "4.0.0" +regex = "(?P\\d+)\\.(?P\\d+)\\.(?P\\d+)((?Pa|b|rc|.dev)(?P\\d+))?" + +[tool.tbump.git] +message_template = "Bump to {new_version}" +tag_template = "v{new_version}" + +[[tool.tbump.file]] +src = "pyproject.toml" +version_template = "version = \"{major}.{minor}.{patch}{channel}{release}\"" diff --git a/setup.py b/setup.py index 8860dcf..8e125ed 100644 --- a/setup.py +++ b/setup.py @@ -1,122 +1 @@ -#!/usr/bin/env python -# coding: utf-8 - -"""jupyterlmod setup""" - -import json -from glob import glob -from pathlib import Path - -from jupyter_packaging import ( - create_cmdclass, - install_npm, - ensure_targets, - combine_commands, - skip_if_exists, -) -import setuptools - -HERE = Path(__file__).parent.resolve() - -# The name of the project -name = "jupyterlmod" - -lab_path = HERE / name / "labextension" - -# Representative files that should exist after a successful build -jstargets = [ - str(lab_path / "package.json"), -] - -package_data_spec = { - name: ["*"], -} - -labext_name = "@cmd-ntrf/jupyterlab-lmod" - -data_files_spec = [ - ("share/jupyter/labextensions/%s" % labext_name, str(lab_path), "**"), - ("share/jupyter/labextensions/%s" % labext_name, str(HERE), "install.json"), - ( - "etc/jupyter/jupyter_notebook_config.d", - "jupyterlmod/etc", - "jupyterlmod_serverextension.json" - ), - ( - "etc/jupyter/jupyter_server_config.d", - "jupyterlmod/etc", - "jupyterlmod_jupyterserverextension.json" - ), - ( - "etc/jupyter/nbconfig/tree.d", - "jupyterlmod/etc", - "jupyterlmod_nbextension.json", - ) -] - -cmdclass = create_cmdclass( - "jsdeps", package_data_spec=package_data_spec, data_files_spec=data_files_spec -) - -js_command = combine_commands( - install_npm(HERE / "jupyterlab", build_cmd="build:prod", npm=["jlpm"]), - ensure_targets(jstargets), -) - -is_repo = (HERE / ".git").exists() -if is_repo: - cmdclass["jsdeps"] = js_command -else: - cmdclass["jsdeps"] = skip_if_exists(jstargets, js_command) - -long_description = (HERE / "README.md").read_text() - -# Get the package info from package.json -pkg_json = json.loads((HERE / "jupyterlab" / "package.json").read_bytes()) - -settings_path = "./config/settings/*.json" - - -setup_args = dict( - name=name, - version=pkg_json["version"], - url=pkg_json["homepage"], - author=pkg_json["author"], - description=pkg_json["description"], - license=pkg_json["license"], - long_description=long_description, - long_description_content_type="text/markdown", - cmdclass=cmdclass, - packages=setuptools.find_packages(), - install_requires=[ - 'jupyter-core', - 'jupyter-server' - ], - data_files=[ - ('share/jupyter/nbextensions/jupyterlmod ', glob('jupyterlmod/static/*')), - ('etc/jupyter/jupyter_notebook_config.d', ['jupyterlmod/etc/jupyterlmod_serverextension.json']), - ("etc/jupyter/jupyter_server_config.d", ['jupyterlmod/etc/jupyterlmod_jupyterserverextension.json']), - ('etc/jupyter/nbconfig/tree.d', ['jupyterlmod/etc/jupyterlmod_nbextension.json']) - ], - zip_safe=False, - include_package_data=True, - python_requires=">=3.6", - platforms="Linux, Mac OS X, Windows", - keywords=["Jupyter", "JupyterLab", "JupyterLab3", "Modules", "Tmod"], - classifiers=[ - "License :: OSI Approved :: BSD License", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Framework :: Jupyter", - ], -) - - -if __name__ == "__main__": - setuptools.setup(**setup_args) - +# this file intentionally left blank for legacy tools to find \ No newline at end of file From 52be7dc7fada22daebba061851eab57e9bcca26c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix-Antoine=20Fortin?= Date: Wed, 29 Mar 2023 11:24:26 -0400 Subject: [PATCH 3/4] Rename jupyterlab folder to labextension --- {jupyterlab => labextension}/.gitignore | 0 {jupyterlab => labextension}/package.json | 4 ++-- {jupyterlab => labextension}/src/index.ts | 0 {jupyterlab => labextension}/style/index.css | 0 {jupyterlab => labextension}/tsconfig.json | 0 pyproject.toml | 6 +++--- 6 files changed, 5 insertions(+), 5 deletions(-) rename {jupyterlab => labextension}/.gitignore (100%) rename {jupyterlab => labextension}/package.json (96%) rename {jupyterlab => labextension}/src/index.ts (100%) rename {jupyterlab => labextension}/style/index.css (100%) rename {jupyterlab => labextension}/tsconfig.json (100%) diff --git a/jupyterlab/.gitignore b/labextension/.gitignore similarity index 100% rename from jupyterlab/.gitignore rename to labextension/.gitignore diff --git a/jupyterlab/package.json b/labextension/package.json similarity index 96% rename from jupyterlab/package.json rename to labextension/package.json index 035cde6..6e58f4e 100644 --- a/jupyterlab/package.json +++ b/labextension/package.json @@ -25,8 +25,8 @@ "lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}", "style/*.css" ], - "main": "lib/jupyterlab/src/index.js", - "types": "lib/jupyterlab/src/index.d.ts", + "main": "lib/labextension/src/index.js", + "types": "lib/labextension/src/index.d.ts", "style": "style/index.css", "repository": { "type": "git", diff --git a/jupyterlab/src/index.ts b/labextension/src/index.ts similarity index 100% rename from jupyterlab/src/index.ts rename to labextension/src/index.ts diff --git a/jupyterlab/style/index.css b/labextension/style/index.css similarity index 100% rename from jupyterlab/style/index.css rename to labextension/style/index.css diff --git a/jupyterlab/tsconfig.json b/labextension/tsconfig.json similarity index 100% rename from jupyterlab/tsconfig.json rename to labextension/tsconfig.json diff --git a/pyproject.toml b/pyproject.toml index d2c111b..b133605 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,7 +36,7 @@ dependencies = [ ] [tool.hatch.metadata.hooks.nodejs] -path = "jupyterlab/package.json" +path = "labextension/package.json" fields = ["description", "authors", "urls"] [tool.hatch.build] @@ -58,7 +58,7 @@ packages = ["jupyterlmod", "lmod"] [tool.hatch.version] source = "nodejs" -path = "jupyterlab/package.json" +path = "labextension/package.json" [tool.hatch.build.targets.sdist] exclude = [ @@ -75,7 +75,7 @@ dependencies = [ build-function = "hatch_jupyter_builder.npm_builder" [tool.hatch.build.hooks.jupyter-builder.build-kwargs] -path = "jupyterlab" +path = "labextension" build_cmd = "build:prod" npm = [ "jlpm", From e27e47ccc51c0bc55935f79930e7392e683be7df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix-Antoine=20Fortin?= Date: Wed, 29 Mar 2023 12:32:23 -0400 Subject: [PATCH 4/4] Add build to the list of python packages in github workflow --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f27ff08..f40d814 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -21,7 +21,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install wheel twine + pip install build wheel twine - name: Build dist run: | pyproject-build