calkit-python 0.35.7__tar.gz → 0.36.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {calkit_python-0.35.7 → calkit_python-0.36.0}/.gitignore +1 -1
- calkit_python-0.36.0/.vscode/launch.json +17 -0
- calkit_python-0.36.0/.vscode/tasks.json +15 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/PKG-INFO +1 -1
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/cli/main/core.py +83 -4
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/cli/new.py +153 -30
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/cli/notebooks.py +119 -13
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/cli/update.py +127 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/labextension/package.json +14 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/labextension/schemas/calkit/package.json.orig +14 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/cli/test_new.py +16 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/cli/test_notebooks.py +36 -0
- calkit_python-0.36.0/calkit/tests/cli/test_update.py +22 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/cli-reference.md +149 -41
- {calkit_python-0.35.7 → calkit_python-0.36.0}/package.json +14 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/pyproject.toml +1 -0
- calkit_python-0.36.0/vscode-ext/.gitignore +3 -0
- calkit_python-0.36.0/vscode-ext/.vscodeignore +5 -0
- calkit_python-0.36.0/vscode-ext/CHANGELOG.md +6 -0
- calkit_python-0.36.0/vscode-ext/LICENSE +19 -0
- calkit_python-0.36.0/vscode-ext/README.md +66 -0
- calkit_python-0.36.0/vscode-ext/images/calkit-no-bg.png +0 -0
- calkit_python-0.36.0/vscode-ext/package-lock.json +77 -0
- calkit_python-0.36.0/vscode-ext/package.json +138 -0
- calkit_python-0.36.0/vscode-ext/scripts/set-proposed-api.js +25 -0
- calkit_python-0.36.0/vscode-ext/src/environments.ts +224 -0
- calkit_python-0.36.0/vscode-ext/src/extension.ts +3510 -0
- calkit_python-0.36.0/vscode-ext/src/notebooks.ts +79 -0
- calkit_python-0.36.0/vscode-ext/src/test/environments.test.ts +130 -0
- calkit_python-0.36.0/vscode-ext/src/test/notebooks.test.ts +70 -0
- calkit_python-0.36.0/vscode-ext/src/types.ts +25 -0
- calkit_python-0.36.0/vscode-ext/tsconfig.json +14 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/.pre-commit-config.yaml +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/.prettierignore +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/.python-version +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/.yarnrc.yml +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/CITATION.cff +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/CODE_OF_CONDUCT.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/CONTRIBUTING.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/LICENSE +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/Makefile +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/README.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/babel.config.js +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/__init__.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/__main__.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/calc.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/check.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/cli/__init__.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/cli/check.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/cli/cloud.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/cli/config.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/cli/core.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/cli/describe.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/cli/import_.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/cli/latex.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/cli/list.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/cli/main/__init__.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/cli/main/xr.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/cli/office.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/cli/overleaf.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/cli/slurm.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/cloud.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/conda.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/config.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/core.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/datasets.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/detect.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/docker.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/dvc.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/environments.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/fs.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/git.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/github.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/gui.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/invenio.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/julia.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/jupyter.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/jupyterlab/__init__.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/jupyterlab/routes.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/labextension/schemas/calkit/plugin.json +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/labextension/static/502.9a2c5772a15466e923ef.js +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/labextension/static/695.2c41003a452d43d2b358.js +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/labextension/static/867.a42a046aa5108f54f8fb.js +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/labextension/static/909.651be47ca47390b78a92.js +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/labextension/static/946.050af2abf7845cfbdbd2.js +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/labextension/static/946.050af2abf7845cfbdbd2.js.LICENSE.txt +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/labextension/static/b2f1c3efe70cb539d121.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/labextension/static/remoteEntry.c091821b3d7f2d287a67.js +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/labextension/static/style.js +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/labextension/static/third-party-licenses.json +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/licenses.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/magics.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/matlab.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/models/__init__.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/models/core.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/models/io.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/models/iteration.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/models/pipeline.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/notebooks.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/office.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/ops.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/overleaf.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/pipeline.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/releases.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/server.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/templates/__init__.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/templates/core.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/templates/latex/__init__.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/templates/latex/article/paper.tex +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/templates/latex/core.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/templates/latex/jfm/jfm.bst +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/templates/latex/jfm/jfm.cls +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/templates/latex/jfm/lineno-FLM.sty +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/templates/latex/jfm/paper.tex +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/templates/latex/jfm/upmath.sty +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/__init__.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/cli/__init__.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/cli/main/__init__.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/cli/main/test_core.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/cli/main/test_xr.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/cli/test_check.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/cli/test_config.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/cli/test_import.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/cli/test_latex.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/cli/test_list.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/cli/test_overleaf.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/jupyterlab/__init__.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/jupyterlab/test_routes.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/models/__init__.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/models/test_iteration.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/models/test_pipeline.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/test_calc.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/test_check.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/test_conda.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/test_core.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/test_detect.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/test_docker.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/test_dvc.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/test_environments.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/test_fs.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/test_git.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/test_invenio.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/test_julia.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/test_jupyter.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/test_magics.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/test_matlab.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/test_notebooks.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/test_pipeline.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/test_releases.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/calkit/tests/test_templates.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/conftest.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/CNAME +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/apps.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/calculations.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/calkit-yaml.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/cloud-integration.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/datasets.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/dependencies.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/environments.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/examples.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/governance.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/help.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/img/c-to-the-k-white.svg +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/img/calkit-fragmentation-compendium.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/img/calkit-no-bg.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/img/connect-zenodo.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/img/jupyterlab/all-green.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/img/jupyterlab/collect-data-stale.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/img/jupyterlab/new-env.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/img/jupyterlab/new-notebook.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/img/jupyterlab/pipeline-badge.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/img/jupyterlab-params.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/img/plos-osi-code-2024-03.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/img/vscode-nb-params.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/index.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/installation.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/jupyterlab.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/local-server.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/notebooks.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/overleaf.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/pipeline/index.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/pipeline/manual-steps.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/pipeline/running-and-logging.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/pipeline/slurm.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/quickstart.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/references.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/releases.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/reproducibility.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/adding-latex-pub-docker.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/conda-envs.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/existing-project.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/first-project.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/github-actions.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/actions-repo-secrets.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/latex-codespaces/building-codespace.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/latex-codespaces/codespaces-secrets-2.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/latex-codespaces/editor-split.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/latex-codespaces/go-to-linked-code.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/latex-codespaces/issue-from-selection.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/latex-codespaces/new-project.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/latex-codespaces/new-pub-2.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/latex-codespaces/new-token.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/latex-codespaces/paper.tex.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/latex-codespaces/project-home-3.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/latex-codespaces/push.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/latex-codespaces/stage.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/office/anakin-excel.jpg +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/office/chart-more-rows.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/office/create-project.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/office/elsevier-research-data-guidelines.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/office/excel-chart.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/office/excel-data.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/office/insert-link-to-file.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/office/needs-clone.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/office/new-stage.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/office/phd-comics-version-control.webp +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/office/pipeline-out-of-date.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/office/status-more-rows.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/office/uncommitted-changes.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/office/untracked-data.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/office/updated-publication.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/office/word-to-pdf-stage-2.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/office/workflow-page.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/openfoam/clone.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/openfoam/create-project.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/openfoam/datasets-page.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/openfoam/figure-on-website-updated.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/openfoam/figure-on-website.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/openfoam/new-token.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/openfoam/reclone.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/openfoam/status-after-import-dataset.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/quick-actions.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/img/run-proc.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/index.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/jupyterlab.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/latex-codespaces.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/matlab.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/notebook-pipeline.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/office.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/openfoam.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/tutorials/procedures.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/docs/version-control.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/install.json +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/jest.config.js +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/jupyter-config/server-config/calkit.json +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/mkdocs.yml +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/schema/plugin.json +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/scripts/generate-cli-reference.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/scripts/install.ps1 +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/scripts/install.sh +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/scripts/make-calk9.sh +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/scripts/sync-docs.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/src/__tests__/useQueries.spec.ts +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/src/calkit-config.ts +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/src/cell-output-marker.ts +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/src/components/commit-dialog.tsx +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/src/components/environment-editor.tsx +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/src/components/notebook-registration.tsx +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/src/components/notebook-toolbar.tsx +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/src/components/pipeline-status-bar.tsx +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/src/components/project-info-editor.tsx +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/src/components/sidebar-settings.tsx +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/src/components/sidebar.tsx +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/src/components/stage-editor.tsx +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/src/feature-flags.ts +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/src/file-browser-menu.ts +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/src/hooks/__tests__/useQueries.test.tsx +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/src/hooks/useQueries.ts +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/src/icons.ts +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/src/index.ts +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/src/io-tracker.ts +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/src/pipeline-state.ts +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/src/queryClient.ts +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/src/request.ts +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/src/shims-mainmenu.d.ts +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/style/base.css +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/style/cell-output-marker.css +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/style/environment-editor.css +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/style/environment-selector.css +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/style/img/calkit-no-bg.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/style/index.css +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/style/index.js +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/style/notebook-toolbar.css +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/style/pipeline-status-bar.css +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/style/sidebar.css +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/test/dvc-md5-dir/osx-arm64.txt +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/test/nb-julia.ipynb +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/test/nb-params.ipynb +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/test/nb-subdir.ipynb +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/test/pipeline.ipynb +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/test/script.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/test/test-log.log +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/tsconfig.json +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/tsconfig.test.json +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/ui-tests/.gitignore +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/ui-tests/README.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/ui-tests/jupyter_server_test_config.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/ui-tests/package.json +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/ui-tests/playwright.config.js +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/ui-tests/tests/calkit.spec.ts +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/ui-tests/yarn.lock +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/uv.lock +0 -0
- {calkit_python-0.35.7 → calkit_python-0.36.0}/yarn.lock +0 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "0.2.0",
|
|
3
|
+
"configurations": [
|
|
4
|
+
{
|
|
5
|
+
"name": "Run Calkit VS Code Extension",
|
|
6
|
+
"type": "extensionHost",
|
|
7
|
+
"request": "launch",
|
|
8
|
+
"runtimeExecutable": "${execPath}",
|
|
9
|
+
"args": [
|
|
10
|
+
"--extensionDevelopmentPath=${workspaceFolder}/vscode-ext",
|
|
11
|
+
"--enable-proposed-api=calkit.calkit-vscode"
|
|
12
|
+
],
|
|
13
|
+
"outFiles": ["${workspaceFolder}/vscode-ext/out/**/*.js"],
|
|
14
|
+
"preLaunchTask": "npm: compile (vscode-ext)"
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "2.0.0",
|
|
3
|
+
"tasks": [
|
|
4
|
+
{
|
|
5
|
+
"type": "shell",
|
|
6
|
+
"command": "npm",
|
|
7
|
+
"args": ["run", "dev:compile"],
|
|
8
|
+
"options": {
|
|
9
|
+
"cwd": "${workspaceFolder}/vscode-ext"
|
|
10
|
+
},
|
|
11
|
+
"label": "npm: compile (vscode-ext)",
|
|
12
|
+
"problemMatcher": ["$tsc"]
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
}
|
|
@@ -249,6 +249,9 @@ def get_status(
|
|
|
249
249
|
),
|
|
250
250
|
),
|
|
251
251
|
] = None,
|
|
252
|
+
as_json: Annotated[
|
|
253
|
+
bool, typer.Option("--json", help="Output status as JSON.")
|
|
254
|
+
] = False,
|
|
252
255
|
):
|
|
253
256
|
"""View status (project, version control, and/or pipeline)."""
|
|
254
257
|
ck_info = calkit.load_calkit_info()
|
|
@@ -284,6 +287,78 @@ def get_status(
|
|
|
284
287
|
"Failed pipeline environment checks for: "
|
|
285
288
|
+ ", ".join(pipeline_status.failed_environment_checks)
|
|
286
289
|
)
|
|
290
|
+
if as_json:
|
|
291
|
+
status_dict = {}
|
|
292
|
+
if "project" in categories:
|
|
293
|
+
status = calkit.get_latest_project_status()
|
|
294
|
+
status_dict["project"] = (
|
|
295
|
+
None
|
|
296
|
+
if status is None
|
|
297
|
+
else {
|
|
298
|
+
"status": status.status,
|
|
299
|
+
"message": status.message,
|
|
300
|
+
"timestamp": status.timestamp.isoformat(),
|
|
301
|
+
}
|
|
302
|
+
)
|
|
303
|
+
if "git" in categories:
|
|
304
|
+
try:
|
|
305
|
+
repo = git.Repo()
|
|
306
|
+
changed_files = calkit.git.get_changed_files(repo=repo)
|
|
307
|
+
staged_files = calkit.git.get_staged_files(repo=repo)
|
|
308
|
+
untracked_files = calkit.git.get_untracked_files(repo=repo)
|
|
309
|
+
if targets:
|
|
310
|
+
target_prefixes = [
|
|
311
|
+
Path(target).as_posix().rstrip("/")
|
|
312
|
+
for target in targets
|
|
313
|
+
]
|
|
314
|
+
|
|
315
|
+
def _matches_target(path: str) -> bool:
|
|
316
|
+
path = Path(path).as_posix()
|
|
317
|
+
return any(
|
|
318
|
+
path == prefix or path.startswith(prefix + "/")
|
|
319
|
+
for prefix in target_prefixes
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
changed_files = [
|
|
323
|
+
path for path in changed_files if _matches_target(path)
|
|
324
|
+
]
|
|
325
|
+
staged_files = [
|
|
326
|
+
path for path in staged_files if _matches_target(path)
|
|
327
|
+
]
|
|
328
|
+
untracked_files = [
|
|
329
|
+
path
|
|
330
|
+
for path in untracked_files
|
|
331
|
+
if _matches_target(path)
|
|
332
|
+
]
|
|
333
|
+
status_dict["git"] = {
|
|
334
|
+
"branch": None
|
|
335
|
+
if repo.head.is_detached
|
|
336
|
+
else repo.active_branch.name,
|
|
337
|
+
"is_dirty": repo.is_dirty(untracked_files=True),
|
|
338
|
+
"changed_files": changed_files,
|
|
339
|
+
"staged_files": staged_files,
|
|
340
|
+
"untracked_files": untracked_files,
|
|
341
|
+
}
|
|
342
|
+
except InvalidGitRepositoryError:
|
|
343
|
+
status_dict["git"] = {"error": "Not a Git repository"}
|
|
344
|
+
if "dvc" in categories:
|
|
345
|
+
try:
|
|
346
|
+
dvc_repo = calkit.dvc.get_dvc_repo()
|
|
347
|
+
data_status = dvc_repo.data_status()
|
|
348
|
+
if isinstance(data_status, dict):
|
|
349
|
+
data_status.pop("git", None)
|
|
350
|
+
status_dict["dvc"] = data_status
|
|
351
|
+
except Exception as e:
|
|
352
|
+
status_dict["dvc"] = {"error": f"{e.__class__.__name__}: {e}"}
|
|
353
|
+
if "pipeline" in categories or "dvc" in categories:
|
|
354
|
+
if pipeline_status is None:
|
|
355
|
+
status_dict["pipeline"] = None
|
|
356
|
+
else:
|
|
357
|
+
status_dict["pipeline"] = pipeline_status.model_dump(
|
|
358
|
+
mode="json"
|
|
359
|
+
)
|
|
360
|
+
print(json.dumps(status_dict, indent=2, default=str))
|
|
361
|
+
return
|
|
287
362
|
if "project" in categories:
|
|
288
363
|
print_sep("Project")
|
|
289
364
|
# Print latest status
|
|
@@ -322,7 +397,11 @@ def get_status(
|
|
|
322
397
|
print_sep("Pipeline")
|
|
323
398
|
# Nicely format the results from pipeline status
|
|
324
399
|
if pipeline_status and pipeline_status.errors:
|
|
325
|
-
|
|
400
|
+
warn("Pipeline status unavailable due to errors.")
|
|
401
|
+
return
|
|
402
|
+
if pipeline_status and not pipeline_status.has_pipeline:
|
|
403
|
+
typer.echo("This project has no pipeline.")
|
|
404
|
+
return
|
|
326
405
|
elif pipeline_status and pipeline_status.is_stale:
|
|
327
406
|
for stage_name in pipeline_status.stale_stage_names:
|
|
328
407
|
stale_stage = pipeline_status.stale_stages.get(stage_name)
|
|
@@ -333,17 +412,17 @@ def get_status(
|
|
|
333
412
|
if stale_stage.stale_outputs:
|
|
334
413
|
typer.echo(" stale outputs:")
|
|
335
414
|
for output_path in stale_stage.stale_outputs:
|
|
336
|
-
typer.echo(f"
|
|
415
|
+
typer.echo(f" {output_path}")
|
|
337
416
|
# Show modified outputs from this stage
|
|
338
417
|
if stale_stage.modified_outputs:
|
|
339
418
|
typer.echo(" modified outputs:")
|
|
340
419
|
for output_path in stale_stage.modified_outputs:
|
|
341
|
-
typer.echo(f"
|
|
420
|
+
typer.echo(f" {output_path}")
|
|
342
421
|
# Show modified inputs making the stage stale
|
|
343
422
|
if stale_stage.modified_inputs:
|
|
344
423
|
typer.echo(" modified inputs:")
|
|
345
424
|
for input_path in stale_stage.modified_inputs:
|
|
346
|
-
typer.echo(f"
|
|
425
|
+
typer.echo(f" {input_path}")
|
|
347
426
|
elif pipeline_status:
|
|
348
427
|
typer.echo("Pipeline is up to date.")
|
|
349
428
|
|
|
@@ -1333,6 +1333,75 @@ def new_uv_env(
|
|
|
1333
1333
|
repo.git.commit(["-m", f"Add uv environment {name}"])
|
|
1334
1334
|
|
|
1335
1335
|
|
|
1336
|
+
@new_app.command("slurm-env")
|
|
1337
|
+
def new_slurm_env(
|
|
1338
|
+
name: Annotated[
|
|
1339
|
+
str, typer.Option("--name", "-n", help="Environment name.")
|
|
1340
|
+
],
|
|
1341
|
+
host: Annotated[
|
|
1342
|
+
str,
|
|
1343
|
+
typer.Option("--host", help="Host where SLURM commands should run."),
|
|
1344
|
+
] = "localhost",
|
|
1345
|
+
default_options: Annotated[
|
|
1346
|
+
list[str],
|
|
1347
|
+
typer.Option(
|
|
1348
|
+
"--default-option",
|
|
1349
|
+
help=(
|
|
1350
|
+
"Default sbatch/srun option string (for example --gpus=1). "
|
|
1351
|
+
"Repeat for multiple options."
|
|
1352
|
+
),
|
|
1353
|
+
),
|
|
1354
|
+
] = [],
|
|
1355
|
+
description: Annotated[
|
|
1356
|
+
str | None, typer.Option("--description", help="Description.")
|
|
1357
|
+
] = None,
|
|
1358
|
+
overwrite: Annotated[
|
|
1359
|
+
bool,
|
|
1360
|
+
typer.Option(
|
|
1361
|
+
"--overwrite",
|
|
1362
|
+
"-f",
|
|
1363
|
+
help="Overwrite any existing environment with this name.",
|
|
1364
|
+
),
|
|
1365
|
+
] = False,
|
|
1366
|
+
no_commit: Annotated[
|
|
1367
|
+
bool, typer.Option("--no-commit", help="Do not commit changes.")
|
|
1368
|
+
] = False,
|
|
1369
|
+
):
|
|
1370
|
+
"""Create a new SLURM environment."""
|
|
1371
|
+
host = host.strip()
|
|
1372
|
+
if not host:
|
|
1373
|
+
raise_error("Host is required")
|
|
1374
|
+
ck_info = calkit.load_calkit_info()
|
|
1375
|
+
envs = ck_info.get("environments", {})
|
|
1376
|
+
if isinstance(envs, list):
|
|
1377
|
+
typer.echo("Converting environments from list to dict")
|
|
1378
|
+
envs = {env.pop("name"): env for env in envs}
|
|
1379
|
+
if name in envs and not overwrite:
|
|
1380
|
+
raise_error(
|
|
1381
|
+
f"Environment with name {name} already exists "
|
|
1382
|
+
"(use -f to overwrite)"
|
|
1383
|
+
)
|
|
1384
|
+
normalized_default_options = [
|
|
1385
|
+
opt.strip() for opt in default_options if opt.strip()
|
|
1386
|
+
]
|
|
1387
|
+
env = {"kind": "slurm", "host": host}
|
|
1388
|
+
if normalized_default_options:
|
|
1389
|
+
env["default_options"] = normalized_default_options # type: ignore
|
|
1390
|
+
if description is not None:
|
|
1391
|
+
env["description"] = description
|
|
1392
|
+
envs[name] = env
|
|
1393
|
+
ck_info["environments"] = envs
|
|
1394
|
+
with open("calkit.yaml", "w") as f:
|
|
1395
|
+
ryaml.dump(ck_info, f)
|
|
1396
|
+
if not no_commit:
|
|
1397
|
+
repo = git.Repo()
|
|
1398
|
+
repo.git.add("calkit.yaml")
|
|
1399
|
+
if repo.git.diff(["--staged", "calkit.yaml"]):
|
|
1400
|
+
repo.git.commit(
|
|
1401
|
+
["calkit.yaml", "-m", f"Add SLURM environment {name}"]
|
|
1402
|
+
)
|
|
1403
|
+
|
|
1404
|
+
|
|
1336
1405
|
@new_app.command("uv-venv")
|
|
1337
1406
|
def new_uv_venv(
|
|
1338
1407
|
name: Annotated[
|
|
@@ -1615,21 +1684,29 @@ def new_pixi_env(
|
|
|
1615
1684
|
@new_app.command("julia-env")
|
|
1616
1685
|
def new_julia_env(
|
|
1617
1686
|
packages: Annotated[
|
|
1618
|
-
list[str],
|
|
1619
|
-
typer.Argument(
|
|
1620
|
-
|
|
1687
|
+
list[str] | None,
|
|
1688
|
+
typer.Argument(
|
|
1689
|
+
help="Optional packages to include in the environment."
|
|
1690
|
+
),
|
|
1691
|
+
] = None,
|
|
1621
1692
|
name: Annotated[
|
|
1622
1693
|
str, typer.Option("--name", "-n", help="Environment name.")
|
|
1623
|
-
],
|
|
1694
|
+
] = "main",
|
|
1624
1695
|
path: Annotated[
|
|
1625
|
-
str
|
|
1626
|
-
|
|
1696
|
+
str | None,
|
|
1697
|
+
typer.Option("--path", help="Path for Project.toml file."),
|
|
1698
|
+
] = None,
|
|
1627
1699
|
description: Annotated[
|
|
1628
1700
|
str | None, typer.Option("--description", help="Description.")
|
|
1629
1701
|
] = None,
|
|
1630
1702
|
julia_version: Annotated[
|
|
1631
|
-
str
|
|
1632
|
-
|
|
1703
|
+
str | None,
|
|
1704
|
+
typer.Option(
|
|
1705
|
+
"--julia",
|
|
1706
|
+
"-j",
|
|
1707
|
+
help="Julia version. Auto-detected if not supplied.",
|
|
1708
|
+
),
|
|
1709
|
+
] = None,
|
|
1633
1710
|
overwrite: Annotated[
|
|
1634
1711
|
bool,
|
|
1635
1712
|
typer.Option(
|
|
@@ -1641,8 +1718,17 @@ def new_julia_env(
|
|
|
1641
1718
|
no_commit: Annotated[
|
|
1642
1719
|
bool, typer.Option("--no-commit", help="Do not commit changes.")
|
|
1643
1720
|
] = False,
|
|
1721
|
+
no_check: Annotated[
|
|
1722
|
+
bool,
|
|
1723
|
+
typer.Option(
|
|
1724
|
+
"--no-check",
|
|
1725
|
+
help="Do not check environment is up-to-date after creation.",
|
|
1726
|
+
),
|
|
1727
|
+
] = False,
|
|
1644
1728
|
):
|
|
1645
|
-
"""Create a new Julia environment."""
|
|
1729
|
+
"""Create a new Julia environment or add an existing one to calkit.yaml."""
|
|
1730
|
+
if path is None:
|
|
1731
|
+
path = "Project.toml"
|
|
1646
1732
|
if not os.path.basename(path) == "Project.toml":
|
|
1647
1733
|
raise_error(
|
|
1648
1734
|
"Julia environment paths must point to a Project.toml file"
|
|
@@ -1665,27 +1751,57 @@ def new_julia_env(
|
|
|
1665
1751
|
f"Environment with name {name} already exists "
|
|
1666
1752
|
"(use -f to overwrite)"
|
|
1667
1753
|
)
|
|
1668
|
-
#
|
|
1754
|
+
# Detect Julia version if not supplied
|
|
1755
|
+
if julia_version is None:
|
|
1756
|
+
try:
|
|
1757
|
+
julia_version = calkit.julia.get_version()
|
|
1758
|
+
except ValueError as e:
|
|
1759
|
+
raise_error(
|
|
1760
|
+
f"Failed to detect Julia version: {e}. "
|
|
1761
|
+
"Use --julia to specify a version."
|
|
1762
|
+
)
|
|
1763
|
+
# Check for duplicate Julia environments with same path and version
|
|
1764
|
+
for env_name, env_config in envs.items():
|
|
1765
|
+
if (
|
|
1766
|
+
env_config.get("kind") == "julia"
|
|
1767
|
+
and env_config.get("path") == path
|
|
1768
|
+
and env_config.get("julia") == julia_version
|
|
1769
|
+
):
|
|
1770
|
+
raise_error(
|
|
1771
|
+
f"Julia environment '{env_name}' already exists with path "
|
|
1772
|
+
f"'{path}' and version '{julia_version}'; "
|
|
1773
|
+
f"Use a different path, version, or --overwrite to replace it"
|
|
1774
|
+
)
|
|
1669
1775
|
env_dir = os.path.dirname(path)
|
|
1670
1776
|
if env_dir:
|
|
1671
1777
|
os.makedirs(env_dir, exist_ok=True)
|
|
1672
1778
|
else:
|
|
1673
1779
|
env_dir = "."
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1780
|
+
project_exists = os.path.isfile(path)
|
|
1781
|
+
created_project_file = False
|
|
1782
|
+
# If packages are provided, initialize via Julia/Pkg.
|
|
1783
|
+
if packages:
|
|
1784
|
+
# First make sure the Julia version is installed
|
|
1785
|
+
cmd = ["juliaup", "add", julia_version]
|
|
1786
|
+
try:
|
|
1787
|
+
subprocess.run(cmd, check=True)
|
|
1788
|
+
except subprocess.CalledProcessError:
|
|
1789
|
+
raise_error(f"Failed to install Julia version {julia_version}")
|
|
1790
|
+
cmd = ["julia", f"+{julia_version}", f"--project={env_dir}", "-e"]
|
|
1791
|
+
install_cmd = f'using Pkg; Pkg.activate("{env_dir}");'
|
|
1792
|
+
for package in packages or []:
|
|
1793
|
+
install_cmd += f' Pkg.add("{package}");'
|
|
1794
|
+
cmd.append(install_cmd)
|
|
1795
|
+
try:
|
|
1796
|
+
subprocess.run(cmd, check=True)
|
|
1797
|
+
except subprocess.CalledProcessError:
|
|
1798
|
+
raise_error("Failed to create new Julia environment")
|
|
1799
|
+
elif not project_exists:
|
|
1800
|
+
# Allow creating a Julia environment scaffold without requiring Julia
|
|
1801
|
+
# tooling at creation time. IJulia or other packages can be added later.
|
|
1802
|
+
with open(path, "w") as f:
|
|
1803
|
+
f.write("[deps]\n")
|
|
1804
|
+
created_project_file = True
|
|
1689
1805
|
typer.echo("Adding environment to calkit.yaml")
|
|
1690
1806
|
env = dict(kind="julia", path=path, julia=julia_version)
|
|
1691
1807
|
if description is not None:
|
|
@@ -1694,11 +1810,18 @@ def new_julia_env(
|
|
|
1694
1810
|
ck_info["environments"] = envs
|
|
1695
1811
|
with open("calkit.yaml", "w") as f:
|
|
1696
1812
|
ryaml.dump(ck_info, f)
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1813
|
+
if not no_commit:
|
|
1814
|
+
repo.git.add("calkit.yaml")
|
|
1815
|
+
if packages or created_project_file:
|
|
1816
|
+
repo.git.add(path)
|
|
1817
|
+
if packages:
|
|
1818
|
+
repo.git.add(os.path.join(env_dir, "Manifest.toml"))
|
|
1819
|
+
if not no_check and packages:
|
|
1820
|
+
env_lock_fpath = check_environment(env_name=name)
|
|
1821
|
+
if env_lock_fpath is not None:
|
|
1822
|
+
repo.git.add(env_lock_fpath)
|
|
1823
|
+
if repo.git.diff("--staged"):
|
|
1824
|
+
repo.git.commit(["-m", f"Add Julia env {name}"])
|
|
1702
1825
|
|
|
1703
1826
|
|
|
1704
1827
|
@new_app.command("renv")
|
|
@@ -84,6 +84,39 @@ def _parse_params(params: list[str]) -> dict[str, Any]:
|
|
|
84
84
|
return parameters
|
|
85
85
|
|
|
86
86
|
|
|
87
|
+
def _check_ijulia_available(
|
|
88
|
+
julia_version: str,
|
|
89
|
+
env_dir: str,
|
|
90
|
+
) -> bool:
|
|
91
|
+
ijulia_check_cmd = [
|
|
92
|
+
"julia",
|
|
93
|
+
f"+{julia_version}",
|
|
94
|
+
"--project=" + env_dir,
|
|
95
|
+
"-e",
|
|
96
|
+
(
|
|
97
|
+
"import Pkg; "
|
|
98
|
+
"deps = Pkg.project().dependencies; "
|
|
99
|
+
'if !haskey(deps, "IJulia"); '
|
|
100
|
+
'println("IJulia is not in this Julia project environment."); '
|
|
101
|
+
"exit(3); "
|
|
102
|
+
"end"
|
|
103
|
+
),
|
|
104
|
+
]
|
|
105
|
+
try:
|
|
106
|
+
ijulia_check_cmd_checked = calkit.julia.check_version_in_command(
|
|
107
|
+
ijulia_check_cmd
|
|
108
|
+
)
|
|
109
|
+
except Exception as e:
|
|
110
|
+
raise_error(f"Failed to check Julia version: {e}")
|
|
111
|
+
return False
|
|
112
|
+
res = subprocess.run(
|
|
113
|
+
ijulia_check_cmd_checked,
|
|
114
|
+
capture_output=True,
|
|
115
|
+
text=True,
|
|
116
|
+
)
|
|
117
|
+
return res.returncode == 0
|
|
118
|
+
|
|
119
|
+
|
|
87
120
|
@notebooks_app.command("check-kernel")
|
|
88
121
|
def check_env_kernel(
|
|
89
122
|
env_name: Annotated[
|
|
@@ -115,10 +148,25 @@ def check_env_kernel(
|
|
|
115
148
|
verbose: Annotated[
|
|
116
149
|
bool, typer.Option("--verbose", "-v", help="Print verbose output.")
|
|
117
150
|
] = False,
|
|
151
|
+
json_output: Annotated[
|
|
152
|
+
bool,
|
|
153
|
+
typer.Option("--json", help="Output result as JSON."),
|
|
154
|
+
] = False,
|
|
155
|
+
auto_add_deps: Annotated[
|
|
156
|
+
bool,
|
|
157
|
+
typer.Option(
|
|
158
|
+
"--auto-add-deps",
|
|
159
|
+
help=(
|
|
160
|
+
"Automatically install missing kernel dependencies "
|
|
161
|
+
"(e.g., IJulia for Julia environments)."
|
|
162
|
+
),
|
|
163
|
+
),
|
|
164
|
+
] = False,
|
|
118
165
|
) -> tuple[str, str]:
|
|
119
166
|
"""Check that an environment has a registered Jupyter kernel."""
|
|
120
167
|
from calkit.cli.check import check_environment
|
|
121
168
|
from calkit.cli.main import run_in_env
|
|
169
|
+
from calkit.cli.update import update_environment
|
|
122
170
|
from calkit.environments import language_from_env
|
|
123
171
|
|
|
124
172
|
def get_env():
|
|
@@ -152,14 +200,24 @@ def check_env_kernel(
|
|
|
152
200
|
"--display-name",
|
|
153
201
|
display_name,
|
|
154
202
|
]
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
203
|
+
if json_output:
|
|
204
|
+
# For JSON output, run silently and don't show intermediate
|
|
205
|
+
# messages
|
|
206
|
+
res = run_in_env(
|
|
207
|
+
cmd=cmd,
|
|
208
|
+
env_name=env_name,
|
|
209
|
+
no_check=no_check,
|
|
210
|
+
verbose=False,
|
|
211
|
+
relaxed_check=True,
|
|
212
|
+
)
|
|
213
|
+
else:
|
|
214
|
+
res = run_in_env(
|
|
215
|
+
cmd=cmd,
|
|
216
|
+
env_name=env_name,
|
|
217
|
+
no_check=no_check,
|
|
218
|
+
verbose=verbose,
|
|
219
|
+
relaxed_check=True,
|
|
220
|
+
)
|
|
163
221
|
elif language == "r":
|
|
164
222
|
cmd = [
|
|
165
223
|
"Rscript",
|
|
@@ -176,7 +234,6 @@ def check_env_kernel(
|
|
|
176
234
|
verbose=verbose,
|
|
177
235
|
relaxed_check=True,
|
|
178
236
|
)
|
|
179
|
-
return kernel_name, display_name
|
|
180
237
|
elif language == "julia":
|
|
181
238
|
if not no_check:
|
|
182
239
|
check_environment(env_name=env_name, verbose=verbose)
|
|
@@ -193,6 +250,43 @@ def check_env_kernel(
|
|
|
193
250
|
if not env_dir:
|
|
194
251
|
env_dir = "."
|
|
195
252
|
env_dir_abs = os.path.abspath(env_dir)
|
|
253
|
+
# In reproducible Julia environments we disable global package loading,
|
|
254
|
+
# so IJulia must exist in the project environment itself.
|
|
255
|
+
ijulia_ok = _check_ijulia_available(
|
|
256
|
+
julia_version=julia_version,
|
|
257
|
+
env_dir=env_dir,
|
|
258
|
+
)
|
|
259
|
+
if not ijulia_ok:
|
|
260
|
+
should_install = auto_add_deps
|
|
261
|
+
if not should_install and sys.stdin.isatty() and not json_output:
|
|
262
|
+
should_install = typer.confirm(
|
|
263
|
+
(
|
|
264
|
+
"IJulia is not installed in this Julia environment. "
|
|
265
|
+
"Install now with "
|
|
266
|
+
f"'calkit update env --name {env_name} --add IJulia'?"
|
|
267
|
+
),
|
|
268
|
+
default=True,
|
|
269
|
+
)
|
|
270
|
+
if not should_install:
|
|
271
|
+
raise_error(
|
|
272
|
+
"IJulia is not installed in this Julia environment. "
|
|
273
|
+
"Install it and retry, or pass --auto-add-deps to "
|
|
274
|
+
"install automatically."
|
|
275
|
+
)
|
|
276
|
+
try:
|
|
277
|
+
update_environment(env_name=env_name, add_packages=["IJulia"])
|
|
278
|
+
except Exception as e:
|
|
279
|
+
raise_error(f"Failed to install IJulia: {e}")
|
|
280
|
+
ijulia_ok = _check_ijulia_available(
|
|
281
|
+
julia_version=julia_version,
|
|
282
|
+
env_dir=env_dir,
|
|
283
|
+
)
|
|
284
|
+
if not ijulia_ok:
|
|
285
|
+
raise_error(
|
|
286
|
+
"IJulia installation completed but the dependency check "
|
|
287
|
+
"still failed."
|
|
288
|
+
)
|
|
289
|
+
# Don't include version in display_name; IJulia appends it automatically
|
|
196
290
|
julia_cmd = (
|
|
197
291
|
"import IJulia;"
|
|
198
292
|
"kp=IJulia.installkernel("
|
|
@@ -218,13 +312,25 @@ def check_env_kernel(
|
|
|
218
312
|
raise_error(f"Failed to create kernel:\n{res.stdout}")
|
|
219
313
|
kernel_path = res.stdout.strip()
|
|
220
314
|
kernel_name = os.path.basename(kernel_path)
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
315
|
+
# Update display_name to include version for matching in VS Code
|
|
316
|
+
# The kernel name format is like: project_-env-X.Y or project_-env-X.Y.Z
|
|
317
|
+
# Extract version from kernel_name or use julia_version
|
|
318
|
+
display_name = f"{display_name} {julia_version}"
|
|
319
|
+
if not json_output:
|
|
320
|
+
typer.echo(
|
|
321
|
+
f"Registered IJulia kernel '{kernel_name}' at: {kernel_path}"
|
|
322
|
+
)
|
|
225
323
|
else:
|
|
226
324
|
raise_error(f"{language} not supported")
|
|
227
325
|
return "", "" # For typing analysis since raise_error exits
|
|
326
|
+
# Output result
|
|
327
|
+
if json_output:
|
|
328
|
+
result = {
|
|
329
|
+
"kernel_name": kernel_name,
|
|
330
|
+
"display_name": display_name,
|
|
331
|
+
}
|
|
332
|
+
typer.echo(json.dumps(result))
|
|
333
|
+
return kernel_name, display_name
|
|
228
334
|
|
|
229
335
|
|
|
230
336
|
@notebooks_app.command("exec", help="Alias for 'execute'.")
|