calkit-python 0.41.13__tar.gz → 0.41.15__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.41.13 → calkit_python-0.41.15}/AGENTS.md +3 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/PKG-INFO +1 -1
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/cli/check.py +5 -2
- calkit_python-0.41.15/calkit/cli/delete.py +33 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/cli/list.py +56 -1
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/cli/main/core.py +38 -6
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/cli/new.py +98 -1
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/cli/notebooks.py +17 -10
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/cli/scheduler.py +20 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/cli/update.py +1 -1
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/core.py +7 -3
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/detect.py +103 -2
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/dvc/core.py +133 -57
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/julia.py +29 -2
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/models/core.py +58 -5
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/notebooks.py +1 -3
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/pipeline.py +57 -8
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/cli/main/test_core.py +103 -45
- calkit_python-0.41.15/calkit/tests/cli/main/test_lock.py +274 -0
- calkit_python-0.41.15/calkit/tests/cli/test_delete.py +23 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/cli/test_list.py +46 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/cli/test_new.py +48 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/cli/test_scheduler.py +4 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/dvc/test_core.py +17 -36
- calkit_python-0.41.15/calkit/tests/models/test_core.py +25 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/test_core.py +15 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/test_detect.py +67 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/test_julia.py +46 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/test_pipeline.py +49 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/cli-reference.md +160 -14
- calkit_python-0.41.15/vscode-ext/README.md +148 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/vscode-ext/package.json +200 -2
- {calkit_python-0.41.13 → calkit_python-0.41.15}/vscode-ext/src/extension.ts +962 -528
- calkit_python-0.41.15/vscode-ext/src/figures/core.ts +93 -0
- calkit_python-0.41.15/vscode-ext/src/figures/view.ts +474 -0
- calkit_python-0.41.15/vscode-ext/src/pipeline/core.ts +81 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/vscode-ext/src/sidebar.ts +478 -146
- calkit_python-0.41.15/vscode-ext/src/test/figures.test.ts +96 -0
- calkit_python-0.41.15/vscode-ext/src/test/pipeline.test.ts +61 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/vscode-ext/src/types.ts +43 -0
- calkit_python-0.41.13/vscode-ext/README.md +0 -66
- {calkit_python-0.41.13 → calkit_python-0.41.15}/.claude-plugin/marketplace.json +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/.gitattributes +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/.gitignore +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/.pre-commit-config.yaml +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/.prettierignore +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/.python-version +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/.vscode/launch.json +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/.vscode/tasks.json +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/.yarnrc.yml +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/CITATION.cff +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/CODE_OF_CONDUCT.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/CONTRIBUTING.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/LICENSE +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/Makefile +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/README.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/agent-plugin/.claude-plugin/plugin.json +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/agent-plugin/skills/add-pipeline-stage/SKILL.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/agent-plugin/skills/conventions/SKILL.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/agent-plugin/skills/create-pipeline/SKILL.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/babel.config.js +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/__init__.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/__main__.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/calc.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/check.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/cli/__init__.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/cli/cloud.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/cli/config.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/cli/core.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/cli/describe.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/cli/dev.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/cli/import_.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/cli/latex.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/cli/main/__init__.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/cli/main/xr.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/cli/office.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/cli/overleaf.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/cloud.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/conda.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/config.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/datasets.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/dependencies.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/docker.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/dvc/__init__.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/dvc/zip.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/environments.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/fs.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/git.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/github.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/gui.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/install.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/invenio.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/jupyter.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/jupyterlab/__init__.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/jupyterlab/routes.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/labextension/package.json +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/labextension/schemas/calkit/package.json.orig +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/labextension/schemas/calkit/plugin.json +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/labextension/static/502.9a2c5772a15466e923ef.js +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/labextension/static/695.2c41003a452d43d2b358.js +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/labextension/static/867.a42a046aa5108f54f8fb.js +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/labextension/static/909.e3f9cc3408834a7fdcc3.js +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/labextension/static/946.050af2abf7845cfbdbd2.js +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/labextension/static/946.050af2abf7845cfbdbd2.js.LICENSE.txt +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/labextension/static/b2f1c3efe70cb539d121.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/labextension/static/remoteEntry.65469af996e7a96aa983.js +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/labextension/static/style.js +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/labextension/static/third-party-licenses.json +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/licenses.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/magics.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/matlab.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/models/__init__.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/models/io.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/models/iteration.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/models/pipeline.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/office.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/ops.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/overleaf.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/releases.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/server.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/templates/__init__.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/templates/core.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/templates/latex/__init__.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/templates/latex/article/paper.tex +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/templates/latex/core.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/templates/latex/jfm/jfm.bst +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/templates/latex/jfm/jfm.cls +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/templates/latex/jfm/lineno-FLM.sty +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/templates/latex/jfm/paper.tex +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/templates/latex/jfm/upmath.sty +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/__init__.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/cli/__init__.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/cli/main/__init__.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/cli/main/test_subprojects.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/cli/main/test_xr.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/cli/test_check.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/cli/test_cloud.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/cli/test_config.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/cli/test_import.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/cli/test_latex.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/cli/test_notebooks.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/cli/test_overleaf.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/cli/test_update.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/dvc/__init__.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/dvc/test_zip.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/jupyterlab/__init__.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/jupyterlab/test_routes.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/models/__init__.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/models/test_iteration.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/models/test_pipeline.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/test_calc.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/test_check.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/test_cloud.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/test_conda.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/test_dependencies.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/test_docker.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/test_environments.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/test_fs.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/test_git.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/test_install.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/test_invenio.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/test_jupyter.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/test_licenses.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/test_magics.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/test_matlab.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/test_notebooks.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/test_releases.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/calkit/tests/test_templates.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/conftest.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/CNAME +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/ai-tools.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/apps.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/calculations.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/calkit-yaml.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/cloud-integration.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/datasets.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/dependencies.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/environments.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/examples.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/governance.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/help.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/hpc.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/img/c-to-the-k-white.svg +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/img/calkit-fragmentation-compendium.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/img/calkit-no-bg.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/img/connect-zenodo.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/img/jupyterlab/all-green.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/img/jupyterlab/collect-data-stale.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/img/jupyterlab/new-env.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/img/jupyterlab/new-notebook.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/img/jupyterlab/pipeline-badge.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/img/jupyterlab-params.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/img/plos-osi-code-2024-03.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/img/vscode-nb-params.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/index.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/installation.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/jupyterlab.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/local-server.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/notebooks.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/overleaf.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/pipeline/index.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/pipeline/manual-steps.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/pipeline/running-and-logging.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/quickstart.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/references.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/releases.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/reproducibility.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/subprojects.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/adding-latex-pub-docker.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/ai-agents.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/conda-envs.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/existing-project.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/first-project.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/github-actions.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/actions-repo-secrets.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/latex-codespaces/building-codespace.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/latex-codespaces/codespaces-secrets-2.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/latex-codespaces/editor-split.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/latex-codespaces/go-to-linked-code.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/latex-codespaces/issue-from-selection.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/latex-codespaces/new-project.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/latex-codespaces/new-pub-2.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/latex-codespaces/new-token.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/latex-codespaces/paper.tex.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/latex-codespaces/project-home-3.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/latex-codespaces/push.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/latex-codespaces/stage.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/office/anakin-excel.jpg +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/office/chart-more-rows.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/office/create-project.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/office/elsevier-research-data-guidelines.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/office/excel-chart.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/office/excel-data.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/office/insert-link-to-file.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/office/needs-clone.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/office/new-stage.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/office/phd-comics-version-control.webp +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/office/pipeline-out-of-date.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/office/status-more-rows.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/office/uncommitted-changes.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/office/untracked-data.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/office/updated-publication.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/office/word-to-pdf-stage-2.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/office/workflow-page.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/openfoam/clone.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/openfoam/create-project.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/openfoam/datasets-page.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/openfoam/figure-on-website-updated.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/openfoam/figure-on-website.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/openfoam/new-token.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/openfoam/reclone.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/openfoam/status-after-import-dataset.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/quick-actions.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/run-proc.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/vscode-slurm-notebook/create-calkit-env.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/vscode-slurm-notebook/create-inner-env.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/vscode-slurm-notebook/create-new-calkit-env.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/vscode-slurm-notebook/select-calkit-env.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/vscode-slurm-notebook/slurm-job-running.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/vscode-slurm-notebook/slurm-launch-options.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/img/vscode-slurm-notebook/starting-slurm-job.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/index.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/jupyterlab.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/latex-codespaces.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/matlab.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/notebook-pipeline.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/office.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/openfoam.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/procedures.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/tutorials/vscode-slurm-notebook.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/docs/version-control.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/flake.lock +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/flake.nix +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/install.json +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/jest.config.js +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/jupyter-config/server-config/calkit.json +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/mkdocs.yml +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/package.json +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/pyproject.toml +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/schema/plugin.json +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/scripts/generate-docs-references.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/scripts/install.ps1 +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/scripts/install.sh +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/scripts/make-calk9.sh +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/scripts/sync-docs.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/src/__tests__/useQueries.spec.ts +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/src/calkit-config.ts +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/src/cell-output-marker.ts +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/src/components/commit-dialog.tsx +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/src/components/environment-editor.tsx +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/src/components/notebook-registration.tsx +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/src/components/notebook-toolbar.tsx +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/src/components/pipeline-status-bar.tsx +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/src/components/project-info-editor.tsx +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/src/components/sidebar-settings.tsx +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/src/components/sidebar.tsx +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/src/components/stage-editor.tsx +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/src/feature-flags.ts +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/src/file-browser-menu.ts +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/src/hooks/__tests__/useQueries.test.tsx +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/src/hooks/useQueries.ts +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/src/icons.ts +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/src/index.ts +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/src/io-tracker.ts +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/src/pipeline-state.ts +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/src/queryClient.ts +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/src/request.ts +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/src/shims-mainmenu.d.ts +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/style/base.css +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/style/cell-output-marker.css +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/style/environment-editor.css +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/style/environment-selector.css +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/style/img/calkit-no-bg.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/style/index.css +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/style/index.js +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/style/notebook-toolbar.css +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/style/pipeline-status-bar.css +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/style/sidebar.css +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/test/dvc-md5-dir/osx-arm64.txt +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/test/nb-julia.ipynb +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/test/nb-params.ipynb +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/test/nb-subdir.ipynb +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/test/pipeline.ipynb +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/test/script.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/test/test-log.log +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/tsconfig.json +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/tsconfig.test.json +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/ui-tests/.gitignore +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/ui-tests/README.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/ui-tests/jupyter_server_test_config.py +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/ui-tests/package.json +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/ui-tests/playwright.config.js +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/ui-tests/tests/calkit.spec.ts +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/ui-tests/yarn.lock +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/uv.lock +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/vscode-ext/.gitignore +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/vscode-ext/.vscodeignore +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/vscode-ext/CHANGELOG.md +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/vscode-ext/LICENSE +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/vscode-ext/images/calkit-icon.svg +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/vscode-ext/images/calkit-no-bg.png +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/vscode-ext/package-lock.json +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/vscode-ext/scripts/set-proposed-api.js +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/vscode-ext/src/environments.ts +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/vscode-ext/src/notebooks.ts +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/vscode-ext/src/test/environments.test.ts +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/vscode-ext/src/test/kernel-selection.test.ts +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/vscode-ext/src/test/notebooks.test.ts +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/vscode-ext/tsconfig.json +0 -0
- {calkit_python-0.41.13 → calkit_python-0.41.15}/yarn.lock +0 -0
|
@@ -43,3 +43,6 @@ The only exception here is if splitting up a function makes it easier to
|
|
|
43
43
|
write meaningful unit tests.
|
|
44
44
|
If a function is only used inside one other function, nest it inside the
|
|
45
45
|
caller at the top.
|
|
46
|
+
|
|
47
|
+
No spaces on either side of en or em dashes used for ranges or pauses in prose,
|
|
48
|
+
respectively.
|
|
@@ -180,7 +180,8 @@ def _check_julia_env(
|
|
|
180
180
|
try:
|
|
181
181
|
subprocess.check_call(
|
|
182
182
|
cmd,
|
|
183
|
-
env=os.environ.copy()
|
|
183
|
+
env=os.environ.copy()
|
|
184
|
+
| {"JULIA_LOAD_PATH": calkit.julia.load_path()},
|
|
184
185
|
)
|
|
185
186
|
except subprocess.CalledProcessError:
|
|
186
187
|
calkit.environments.save_cache(
|
|
@@ -206,7 +207,9 @@ def _check_julia_env(
|
|
|
206
207
|
cmd = calkit.julia.ensure_startup_file_disabled_in_command(cmd)
|
|
207
208
|
try:
|
|
208
209
|
subprocess.check_call(
|
|
209
|
-
cmd,
|
|
210
|
+
cmd,
|
|
211
|
+
env=os.environ.copy()
|
|
212
|
+
| {"JULIA_LOAD_PATH": calkit.julia.load_path()},
|
|
210
213
|
)
|
|
211
214
|
except subprocess.CalledProcessError:
|
|
212
215
|
calkit.environments.save_cache(
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""CLI for deleting objects."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import typer
|
|
6
|
+
|
|
7
|
+
import calkit
|
|
8
|
+
from calkit.cli import AliasGroup, raise_error
|
|
9
|
+
from calkit.core import ryaml
|
|
10
|
+
|
|
11
|
+
delete_app = typer.Typer(cls=AliasGroup, no_args_is_help=True)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@delete_app.command(name="question")
|
|
15
|
+
def delete_question(
|
|
16
|
+
index: int = typer.Argument(
|
|
17
|
+
...,
|
|
18
|
+
help="1-based index of the question to remove (see `calkit list questions`).",
|
|
19
|
+
),
|
|
20
|
+
):
|
|
21
|
+
"""Remove a question by its 1-based index."""
|
|
22
|
+
ck_info = calkit.load_calkit_info()
|
|
23
|
+
questions = ck_info.get("questions", []) or []
|
|
24
|
+
if index < 1 or index > len(questions):
|
|
25
|
+
raise_error(
|
|
26
|
+
f"Invalid question index {index}; "
|
|
27
|
+
f"there are {len(questions)} question(s)."
|
|
28
|
+
)
|
|
29
|
+
removed = questions.pop(index - 1)
|
|
30
|
+
ck_info["questions"] = questions
|
|
31
|
+
with open("calkit.yaml", "w") as f:
|
|
32
|
+
ryaml.dump(ck_info, f)
|
|
33
|
+
typer.echo(f"Removed question: {removed}")
|
|
@@ -55,7 +55,7 @@ def _list_objects(
|
|
|
55
55
|
|
|
56
56
|
|
|
57
57
|
def _list_artifacts(
|
|
58
|
-
kind: Literal["figures", "datasets"],
|
|
58
|
+
kind: Literal["figures", "datasets", "results", "presentations"],
|
|
59
59
|
json_output: bool,
|
|
60
60
|
declared_only: bool,
|
|
61
61
|
):
|
|
@@ -134,6 +134,61 @@ def list_datasets(
|
|
|
134
134
|
_list_artifacts("datasets", json_output, declared_only)
|
|
135
135
|
|
|
136
136
|
|
|
137
|
+
@list_app.command(name="results")
|
|
138
|
+
def list_results(
|
|
139
|
+
json_output: Annotated[
|
|
140
|
+
bool, typer.Option("--json", help="Output result as JSON.")
|
|
141
|
+
] = False,
|
|
142
|
+
declared_only: Annotated[
|
|
143
|
+
bool,
|
|
144
|
+
typer.Option(
|
|
145
|
+
"--declared-only",
|
|
146
|
+
help=(
|
|
147
|
+
"Only list results declared in calkit.yaml; "
|
|
148
|
+
"skip auto-detection."
|
|
149
|
+
),
|
|
150
|
+
),
|
|
151
|
+
] = False,
|
|
152
|
+
):
|
|
153
|
+
"""List results in the project."""
|
|
154
|
+
_list_artifacts("results", json_output, declared_only)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
@list_app.command(name="presentations|pres")
|
|
158
|
+
def list_presentations(
|
|
159
|
+
json_output: Annotated[
|
|
160
|
+
bool, typer.Option("--json", help="Output result as JSON.")
|
|
161
|
+
] = False,
|
|
162
|
+
declared_only: Annotated[
|
|
163
|
+
bool,
|
|
164
|
+
typer.Option(
|
|
165
|
+
"--declared-only",
|
|
166
|
+
help=(
|
|
167
|
+
"Only list presentations declared in calkit.yaml; "
|
|
168
|
+
"skip auto-detection."
|
|
169
|
+
),
|
|
170
|
+
),
|
|
171
|
+
] = False,
|
|
172
|
+
):
|
|
173
|
+
"""List presentations in the project."""
|
|
174
|
+
_list_artifacts("presentations", json_output, declared_only)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
@list_app.command(name="questions")
|
|
178
|
+
def list_questions(
|
|
179
|
+
json_output: Annotated[
|
|
180
|
+
bool, typer.Option("--json", help="Output result as JSON.")
|
|
181
|
+
] = False,
|
|
182
|
+
):
|
|
183
|
+
"""List the project's questions (1-indexed)."""
|
|
184
|
+
questions = calkit.load_calkit_info().get("questions", []) or []
|
|
185
|
+
if json_output:
|
|
186
|
+
typer.echo(json.dumps(questions))
|
|
187
|
+
return
|
|
188
|
+
for n, question in enumerate(questions, start=1):
|
|
189
|
+
typer.echo(f"{n}. {question}")
|
|
190
|
+
|
|
191
|
+
|
|
137
192
|
@list_app.command(name="publications|pubs")
|
|
138
193
|
def list_publications():
|
|
139
194
|
"""List publications in the project."""
|
|
@@ -48,6 +48,7 @@ from calkit.cli.check import (
|
|
|
48
48
|
)
|
|
49
49
|
from calkit.cli.cloud import cloud_app
|
|
50
50
|
from calkit.cli.config import config_app
|
|
51
|
+
from calkit.cli.delete import delete_app
|
|
51
52
|
from calkit.cli.describe import describe_app
|
|
52
53
|
from calkit.cli.dev import dev_app
|
|
53
54
|
from calkit.cli.import_ import import_app
|
|
@@ -69,6 +70,7 @@ app = typer.Typer(
|
|
|
69
70
|
)
|
|
70
71
|
app.add_typer(config_app, name="config", help="Configure Calkit.")
|
|
71
72
|
app.add_typer(new_app, name="new|create", help="Create a new Calkit object.")
|
|
73
|
+
app.add_typer(delete_app, name="delete|rm", help="Delete a Calkit object.")
|
|
72
74
|
app.add_typer(
|
|
73
75
|
notebooks_app, name="notebooks|nb", help="Work with Jupyter notebooks."
|
|
74
76
|
)
|
|
@@ -579,6 +581,18 @@ def get_status(
|
|
|
579
581
|
if pipeline_status and not pipeline_status.has_pipeline:
|
|
580
582
|
typer.echo("This project has no pipeline.")
|
|
581
583
|
return
|
|
584
|
+
# A failed environment check makes get_status bail out before computing
|
|
585
|
+
# staleness, leaving stale_stages empty. Don't let that masquerade as an
|
|
586
|
+
# up-to-date pipeline---say plainly that the status is unknown.
|
|
587
|
+
elif pipeline_status and pipeline_status.failed_environment_checks:
|
|
588
|
+
# The failing environments were already named in the warning emitted
|
|
589
|
+
# right after computing pipeline_status, so keep this explanatory
|
|
590
|
+
# only rather than repeating the list.
|
|
591
|
+
typer.echo(
|
|
592
|
+
"Pipeline status unavailable until the failed environment "
|
|
593
|
+
"checks above are resolved."
|
|
594
|
+
)
|
|
595
|
+
return
|
|
582
596
|
elif pipeline_status and pipeline_status.is_stale:
|
|
583
597
|
typer.echo("Stale stages:")
|
|
584
598
|
for stage_name in pipeline_status.stale_stage_names:
|
|
@@ -1172,7 +1186,10 @@ def pull(
|
|
|
1172
1186
|
and "-R" not in dvc_args
|
|
1173
1187
|
):
|
|
1174
1188
|
dvc_args.append("--recursive")
|
|
1175
|
-
result = calkit.dvc.run_dvc_command(
|
|
1189
|
+
result = calkit.dvc.run_dvc_command(
|
|
1190
|
+
["pull"] + dvc_args,
|
|
1191
|
+
lock_timeout=calkit.dvc.DEFAULT_RUN_LOCK_TIMEOUT,
|
|
1192
|
+
)
|
|
1176
1193
|
if result != 0:
|
|
1177
1194
|
raise_error("DVC pull failed")
|
|
1178
1195
|
calkit.dvc.zip.sync_all(direction="to-workspace")
|
|
@@ -1187,7 +1204,9 @@ def pull(
|
|
|
1187
1204
|
continue
|
|
1188
1205
|
typer.echo(f"DVC pulling subproject: {sp_path}")
|
|
1189
1206
|
sp_result = calkit.dvc.run_dvc_command(
|
|
1190
|
-
["pull"] + dvc_args,
|
|
1207
|
+
["pull"] + dvc_args,
|
|
1208
|
+
cwd=sp_path,
|
|
1209
|
+
lock_timeout=calkit.dvc.DEFAULT_RUN_LOCK_TIMEOUT,
|
|
1191
1210
|
)
|
|
1192
1211
|
if sp_result != 0:
|
|
1193
1212
|
raise_error(f"DVC pull failed for subproject: {sp_path}")
|
|
@@ -1225,7 +1244,8 @@ def push(
|
|
|
1225
1244
|
if remotes:
|
|
1226
1245
|
typer.echo("Pushing to DVC remote")
|
|
1227
1246
|
result = calkit.dvc.run_dvc_command(
|
|
1228
|
-
["push"] + dvc_args,
|
|
1247
|
+
["push"] + dvc_args,
|
|
1248
|
+
lock_timeout=calkit.dvc.DEFAULT_RUN_LOCK_TIMEOUT,
|
|
1229
1249
|
)
|
|
1230
1250
|
if result != 0:
|
|
1231
1251
|
raise_error("DVC push failed")
|
|
@@ -2035,7 +2055,10 @@ def run(
|
|
|
2035
2055
|
original_dir = os.getcwd()
|
|
2036
2056
|
try:
|
|
2037
2057
|
os.chdir(sp_path)
|
|
2038
|
-
|
|
2058
|
+
with calkit.dvc.dvc_lock_timeout(
|
|
2059
|
+
calkit.dvc.DEFAULT_RUN_LOCK_TIMEOUT
|
|
2060
|
+
):
|
|
2061
|
+
sp_res = dvc_cli_main(["repro"] + sp_args)
|
|
2039
2062
|
finally:
|
|
2040
2063
|
os.chdir(original_dir)
|
|
2041
2064
|
if sp_res != 0:
|
|
@@ -2104,7 +2127,15 @@ def run(
|
|
|
2104
2127
|
if force:
|
|
2105
2128
|
os.environ["CALKIT_FORCE"] = "1"
|
|
2106
2129
|
try:
|
|
2107
|
-
|
|
2130
|
+
# Wait generously for the repo lock instead of failing after DVC's 3s
|
|
2131
|
+
# default. Brief contention is common and benign: a background
|
|
2132
|
+
# `calkit status` poller (e.g. the VS Code extension), a stage whose
|
|
2133
|
+
# command is itself `calkit run`, or DVC's own per-stage re-lock (DVC
|
|
2134
|
+
# releases the repo lock while a stage command runs and re-acquires it
|
|
2135
|
+
# the instant it finishes) can all hold it momentarily. Without this,
|
|
2136
|
+
# such a collision aborts the whole run with "Unable to acquire lock".
|
|
2137
|
+
with calkit.dvc.dvc_lock_timeout(calkit.dvc.DEFAULT_RUN_LOCK_TIMEOUT):
|
|
2138
|
+
res = dvc_cli_main(["repro"] + args)
|
|
2108
2139
|
finally:
|
|
2109
2140
|
os.environ.pop("CALKIT_FORCE", None)
|
|
2110
2141
|
failed = failed or res != 0
|
|
@@ -2567,7 +2598,8 @@ def run_in_env(
|
|
|
2567
2598
|
subprocess.check_call(
|
|
2568
2599
|
julia_cmd,
|
|
2569
2600
|
cwd=wdir,
|
|
2570
|
-
env=os.environ.copy()
|
|
2601
|
+
env=os.environ.copy()
|
|
2602
|
+
| {"JULIA_LOAD_PATH": calkit.julia.load_path()},
|
|
2571
2603
|
)
|
|
2572
2604
|
except subprocess.CalledProcessError:
|
|
2573
2605
|
raise_error("Failed to run in julia environment")
|
|
@@ -9,6 +9,7 @@ import shutil
|
|
|
9
9
|
import subprocess
|
|
10
10
|
import time
|
|
11
11
|
from enum import Enum
|
|
12
|
+
from typing import Literal
|
|
12
13
|
|
|
13
14
|
import typer
|
|
14
15
|
from typing_extensions import Annotated
|
|
@@ -591,6 +592,102 @@ def new_figure(
|
|
|
591
592
|
repo.git.commit(["-m", f"Add figure {path}"])
|
|
592
593
|
|
|
593
594
|
|
|
595
|
+
def _new_simple_artifact(
|
|
596
|
+
kind: Literal["results", "presentations"],
|
|
597
|
+
path: str,
|
|
598
|
+
title: str,
|
|
599
|
+
description: str | None,
|
|
600
|
+
stage_name: str | None,
|
|
601
|
+
no_commit: bool,
|
|
602
|
+
overwrite: bool,
|
|
603
|
+
) -> None:
|
|
604
|
+
"""Declare a simple artifact (path/title/description/stage) in calkit.yaml."""
|
|
605
|
+
singular = kind.rstrip("s")
|
|
606
|
+
ck_info = calkit.load_calkit_info()
|
|
607
|
+
objects = ck_info.get(kind, [])
|
|
608
|
+
paths = [o.get("path") for o in objects]
|
|
609
|
+
if not overwrite and path in paths:
|
|
610
|
+
raise_error(f"{singular.capitalize()} at path {path} already exists")
|
|
611
|
+
if overwrite and path in paths:
|
|
612
|
+
objects = [o for o in objects if o.get("path") != path]
|
|
613
|
+
obj = dict(path=path, title=title)
|
|
614
|
+
if description is not None:
|
|
615
|
+
obj["description"] = description
|
|
616
|
+
if stage_name is not None:
|
|
617
|
+
obj["stage"] = stage_name
|
|
618
|
+
objects.append(obj)
|
|
619
|
+
ck_info[kind] = objects
|
|
620
|
+
with open("calkit.yaml", "w") as f:
|
|
621
|
+
ryaml.dump(ck_info, f)
|
|
622
|
+
if not no_commit:
|
|
623
|
+
repo = calkit.git.get_repo()
|
|
624
|
+
repo.git.add("calkit.yaml")
|
|
625
|
+
if repo.git.diff("--staged"):
|
|
626
|
+
repo.git.commit(["-m", f"Add {singular} {path}"])
|
|
627
|
+
|
|
628
|
+
|
|
629
|
+
@new_app.command(name="result")
|
|
630
|
+
def new_result(
|
|
631
|
+
path: str,
|
|
632
|
+
title: Annotated[str, typer.Option("--title")],
|
|
633
|
+
description: Annotated[str | None, typer.Option("--description")] = None,
|
|
634
|
+
stage_name: Annotated[
|
|
635
|
+
str | None,
|
|
636
|
+
typer.Option(
|
|
637
|
+
"--stage",
|
|
638
|
+
help="Name of the pipeline stage that generates this result.",
|
|
639
|
+
),
|
|
640
|
+
] = None,
|
|
641
|
+
no_commit: Annotated[bool, typer.Option("--no-commit")] = False,
|
|
642
|
+
overwrite: Annotated[
|
|
643
|
+
bool,
|
|
644
|
+
typer.Option(
|
|
645
|
+
"--overwrite",
|
|
646
|
+
"-f",
|
|
647
|
+
help="Overwrite existing result if one exists.",
|
|
648
|
+
),
|
|
649
|
+
] = False,
|
|
650
|
+
):
|
|
651
|
+
"""Declare a new result."""
|
|
652
|
+
_new_simple_artifact(
|
|
653
|
+
"results", path, title, description, stage_name, no_commit, overwrite
|
|
654
|
+
)
|
|
655
|
+
|
|
656
|
+
|
|
657
|
+
@new_app.command(name="presentation|pres")
|
|
658
|
+
def new_presentation(
|
|
659
|
+
path: str,
|
|
660
|
+
title: Annotated[str, typer.Option("--title")],
|
|
661
|
+
description: Annotated[str | None, typer.Option("--description")] = None,
|
|
662
|
+
stage_name: Annotated[
|
|
663
|
+
str | None,
|
|
664
|
+
typer.Option(
|
|
665
|
+
"--stage",
|
|
666
|
+
help="Name of the pipeline stage that generates this presentation.",
|
|
667
|
+
),
|
|
668
|
+
] = None,
|
|
669
|
+
no_commit: Annotated[bool, typer.Option("--no-commit")] = False,
|
|
670
|
+
overwrite: Annotated[
|
|
671
|
+
bool,
|
|
672
|
+
typer.Option(
|
|
673
|
+
"--overwrite",
|
|
674
|
+
"-f",
|
|
675
|
+
help="Overwrite existing presentation if one exists.",
|
|
676
|
+
),
|
|
677
|
+
] = False,
|
|
678
|
+
):
|
|
679
|
+
"""Declare a new presentation."""
|
|
680
|
+
_new_simple_artifact(
|
|
681
|
+
"presentations",
|
|
682
|
+
path,
|
|
683
|
+
title,
|
|
684
|
+
description,
|
|
685
|
+
stage_name,
|
|
686
|
+
no_commit,
|
|
687
|
+
overwrite,
|
|
688
|
+
)
|
|
689
|
+
|
|
690
|
+
|
|
594
691
|
@new_app.command("question")
|
|
595
692
|
def new_question(
|
|
596
693
|
question: str,
|
|
@@ -2011,7 +2108,7 @@ def new_julia_env(
|
|
|
2011
2108
|
except subprocess.CalledProcessError:
|
|
2012
2109
|
raise_error(f"Failed to install Julia version {julia_version}")
|
|
2013
2110
|
cmd = ["julia", f"+{julia_version}", f"--project={env_dir}", "-e"]
|
|
2014
|
-
install_cmd = f'using Pkg; Pkg.activate("{env_dir}");'
|
|
2111
|
+
install_cmd = f'using Pkg; Pkg.activate("{calkit.julia.escape_string(env_dir)}");'
|
|
2015
2112
|
for package in packages or []:
|
|
2016
2113
|
install_cmd += f' Pkg.add("{package}");'
|
|
2017
2114
|
cmd.append(install_cmd)
|
|
@@ -310,14 +310,18 @@ def check_env_kernel(
|
|
|
310
310
|
"still failed."
|
|
311
311
|
)
|
|
312
312
|
# Don't include version in display_name; IJulia appends it automatically
|
|
313
|
+
# Escape interpolated values for the Julia string literals---notably the
|
|
314
|
+
# Windows project path, whose backslashes are otherwise read as invalid
|
|
315
|
+
# unicode escapes.
|
|
316
|
+
esc = calkit.julia.escape_string
|
|
313
317
|
julia_cmd = (
|
|
314
318
|
"import IJulia;"
|
|
315
319
|
"kp=IJulia.installkernel("
|
|
316
|
-
f'"{kernel_name}",'
|
|
317
|
-
f'"--project={env_dir_abs}",'
|
|
320
|
+
f'"{esc(kernel_name)}",'
|
|
321
|
+
f'"--project={esc(env_dir_abs)}",'
|
|
318
322
|
'"--startup-file=no",'
|
|
319
|
-
f'displayname="{display_name}",'
|
|
320
|
-
'env=Dict("JULIA_LOAD_PATH" => "
|
|
323
|
+
f'displayname="{esc(display_name)}",'
|
|
324
|
+
f'env=Dict("JULIA_LOAD_PATH" => "{esc(calkit.julia.load_path())}")'
|
|
321
325
|
");"
|
|
322
326
|
"println(kp);"
|
|
323
327
|
)
|
|
@@ -474,8 +478,7 @@ def execute_notebook(
|
|
|
474
478
|
# Create this environment and write it to file
|
|
475
479
|
envs[res.name] = res.env
|
|
476
480
|
ck_info["environments"] = envs
|
|
477
|
-
|
|
478
|
-
calkit.ryaml.dump(ck_info, f)
|
|
481
|
+
calkit.save_calkit_info(ck_info)
|
|
479
482
|
# Detect language from environment
|
|
480
483
|
if language is None:
|
|
481
484
|
detected_language = language_from_notebook(path)
|
|
@@ -501,16 +504,20 @@ def execute_notebook(
|
|
|
501
504
|
raise ValueError(
|
|
502
505
|
"Language must be one of 'python', 'matlab', 'julia', or 'r'"
|
|
503
506
|
)
|
|
504
|
-
# Try to set kernelspec metadata so execution uses the expected kernel
|
|
507
|
+
# Try to set kernelspec metadata so execution uses the expected kernel.
|
|
508
|
+
# Always read/write as UTF-8: notebooks routinely contain non-ASCII (e.g.,
|
|
509
|
+
# Greek letters such as "ν" in code), and on Windows the default open()
|
|
510
|
+
# encoding is cp1252, which mangles UTF-8 content into mojibake ("ν" ->
|
|
511
|
+
# "ν") and breaks execution.
|
|
505
512
|
try:
|
|
506
|
-
with open(path, "r") as f:
|
|
513
|
+
with open(path, "r", encoding="utf-8") as f:
|
|
507
514
|
nb_json = json.load(f)
|
|
508
515
|
metadata = nb_json.setdefault("metadata", {})
|
|
509
516
|
kernelspec = metadata.setdefault("kernelspec", {})
|
|
510
517
|
kernelspec["name"] = kernel_name
|
|
511
518
|
kernelspec["display_name"] = display_name
|
|
512
|
-
kernelspec
|
|
513
|
-
with open(path, "w") as f:
|
|
519
|
+
kernelspec["language"] = language.lower()
|
|
520
|
+
with open(path, "w", encoding="utf-8") as f:
|
|
514
521
|
json.dump(nb_json, f, indent=1)
|
|
515
522
|
except Exception as e:
|
|
516
523
|
if verbose:
|
|
@@ -77,6 +77,23 @@ def _record_job(name: str, info: dict) -> None:
|
|
|
77
77
|
jobs[name] = info
|
|
78
78
|
|
|
79
79
|
|
|
80
|
+
def _delete_job(name: str) -> None:
|
|
81
|
+
"""Remove a job record from the database.
|
|
82
|
+
|
|
83
|
+
Used when a job is canceled (e.g. the user hits Ctrl+C while waiting for
|
|
84
|
+
it). Without this the record would linger, and the next ``calkit run``
|
|
85
|
+
would find the job gone from the queue with no exit status and wrongly
|
|
86
|
+
treat it as successful instead of resubmitting it.
|
|
87
|
+
"""
|
|
88
|
+
if not os.path.isfile(JOBS_DB_PATH):
|
|
89
|
+
return
|
|
90
|
+
with SqliteDict(
|
|
91
|
+
JOBS_DB_PATH, autocommit=True, timeout=JOBS_DB_TIMEOUT
|
|
92
|
+
) as jobs:
|
|
93
|
+
if name in jobs:
|
|
94
|
+
del jobs[name]
|
|
95
|
+
|
|
96
|
+
|
|
80
97
|
def _mock_enabled() -> bool:
|
|
81
98
|
"""Whether scheduler commands should run jobs locally.
|
|
82
99
|
|
|
@@ -390,6 +407,9 @@ def _wait_until_done(kind: str, job_id: str, name: str) -> int | None:
|
|
|
390
407
|
ok, stderr = _cancel(kind, job_id)
|
|
391
408
|
if not ok:
|
|
392
409
|
typer.echo(f"Failed to cancel job '{name}' ({job_id}): {stderr}")
|
|
410
|
+
# Drop the record so the next run resubmits this job instead of
|
|
411
|
+
# mistaking the canceled job (which has no exit status) for a success.
|
|
412
|
+
_delete_job(name)
|
|
393
413
|
raise typer.Exit(130)
|
|
394
414
|
|
|
395
415
|
|
|
@@ -746,7 +746,7 @@ def update_julia_env(
|
|
|
746
746
|
env_dir = os.path.dirname(spec_path) or "."
|
|
747
747
|
julia_version = env.get("julia")
|
|
748
748
|
julia_bin = ["julia", f"+{julia_version}"] if julia_version else ["julia"]
|
|
749
|
-
cmds = [f'Pkg.activate("{env_dir}")']
|
|
749
|
+
cmds = [f'Pkg.activate("{calkit.julia.escape_string(env_dir)}")']
|
|
750
750
|
if add:
|
|
751
751
|
pkg_list = "[" + ", ".join(f'"{p}"' for p in add) + "]"
|
|
752
752
|
cmds.append(f"Pkg.add({pkg_list})")
|
|
@@ -144,7 +144,9 @@ def load_calkit_info(
|
|
|
144
144
|
if wdir is not None:
|
|
145
145
|
fpath = os.path.join(wdir, fpath)
|
|
146
146
|
if os.path.isfile(fpath):
|
|
147
|
-
|
|
147
|
+
# Always read as UTF-8; on Windows the default open() encoding is
|
|
148
|
+
# cp1252, which mangles non-ASCII content (e.g., Greek letters).
|
|
149
|
+
with open(fpath, encoding="utf-8") as f:
|
|
148
150
|
info = ryaml.load(f)
|
|
149
151
|
if info is None:
|
|
150
152
|
info = {}
|
|
@@ -166,7 +168,7 @@ def load_calkit_info(
|
|
|
166
168
|
if wdir is not None:
|
|
167
169
|
include_fpath = os.path.join(wdir, include_fpath)
|
|
168
170
|
if os.path.isfile(include_fpath):
|
|
169
|
-
with open(include_fpath) as f:
|
|
171
|
+
with open(include_fpath, encoding="utf-8") as f:
|
|
170
172
|
include_data = ryaml.load(f)
|
|
171
173
|
info[kind][obj_name] |= include_data
|
|
172
174
|
return info
|
|
@@ -180,7 +182,9 @@ def save_calkit_info(
|
|
|
180
182
|
fpath = "calkit.yaml"
|
|
181
183
|
if wdir is not None:
|
|
182
184
|
fpath = os.path.join(wdir, fpath)
|
|
183
|
-
|
|
185
|
+
# Always write as UTF-8; on Windows the default open() encoding is cp1252,
|
|
186
|
+
# which mangles non-ASCII content (e.g., Greek letters) into mojibake.
|
|
187
|
+
with open(fpath, "w", encoding="utf-8") as f:
|
|
184
188
|
ryaml.dump(info, f)
|
|
185
189
|
|
|
186
190
|
|
|
@@ -1837,6 +1837,31 @@ DATASET_EXTENSIONS = {
|
|
|
1837
1837
|
".ndjson",
|
|
1838
1838
|
}
|
|
1839
1839
|
DATA_DIRS = {"data", "datasets", "dataset"}
|
|
1840
|
+
RESULT_DIRS = {"results", "result"}
|
|
1841
|
+
RESULT_EXTENSIONS = {
|
|
1842
|
+
".json",
|
|
1843
|
+
".csv",
|
|
1844
|
+
".tsv",
|
|
1845
|
+
".yaml",
|
|
1846
|
+
".yml",
|
|
1847
|
+
".parquet",
|
|
1848
|
+
".h5",
|
|
1849
|
+
".hdf5",
|
|
1850
|
+
".txt",
|
|
1851
|
+
".html",
|
|
1852
|
+
}
|
|
1853
|
+
PRESENTATION_DIRS = {"presentations", "presentation", "slides", "talks"}
|
|
1854
|
+
PRESENTATION_EXTENSIONS = {".pdf", ".pptx", ".key"}
|
|
1855
|
+
# Files that look like a presentation regardless of which directory they live in.
|
|
1856
|
+
PRESENTATION_NAMES = {
|
|
1857
|
+
"slides.pdf",
|
|
1858
|
+
"slides.pptx",
|
|
1859
|
+
"slides.key",
|
|
1860
|
+
"presentation.pdf",
|
|
1861
|
+
"presentation.pptx",
|
|
1862
|
+
"presentation.key",
|
|
1863
|
+
"talk.pdf",
|
|
1864
|
+
}
|
|
1840
1865
|
|
|
1841
1866
|
|
|
1842
1867
|
def _ancestor_dir_names(rel_path: str) -> set[str]:
|
|
@@ -1871,6 +1896,37 @@ def is_dataset_path(rel_path: str) -> bool:
|
|
|
1871
1896
|
)
|
|
1872
1897
|
|
|
1873
1898
|
|
|
1899
|
+
def is_result_path(rel_path: str) -> bool:
|
|
1900
|
+
"""Whether a repo-relative path looks like an auto-detectable result.
|
|
1901
|
+
|
|
1902
|
+
A result is a data-like file (JSON, CSV, etc.) under a ``results``-style
|
|
1903
|
+
directory. Anything already detected as a figure or dataset is excluded.
|
|
1904
|
+
"""
|
|
1905
|
+
return (
|
|
1906
|
+
_path_ext(rel_path) in RESULT_EXTENSIONS
|
|
1907
|
+
and bool(_ancestor_dir_names(rel_path) & RESULT_DIRS)
|
|
1908
|
+
and not is_figure_path(rel_path)
|
|
1909
|
+
and not is_dataset_path(rel_path)
|
|
1910
|
+
)
|
|
1911
|
+
|
|
1912
|
+
|
|
1913
|
+
def is_presentation_path(rel_path: str) -> bool:
|
|
1914
|
+
"""Whether a repo-relative path looks like an auto-detectable presentation.
|
|
1915
|
+
|
|
1916
|
+
Either a slide-deck file (PDF/PPTX/KEY) under a ``slides``/``presentations``
|
|
1917
|
+
directory, or a file with a presentation-like name (e.g. ``slides.pdf``,
|
|
1918
|
+
``presentation.pdf``) anywhere. Figures are excluded.
|
|
1919
|
+
"""
|
|
1920
|
+
if is_figure_path(rel_path):
|
|
1921
|
+
return False
|
|
1922
|
+
name = rel_path.rsplit("/", 1)[-1].lower()
|
|
1923
|
+
if name in PRESENTATION_NAMES:
|
|
1924
|
+
return True
|
|
1925
|
+
return _path_ext(rel_path) in PRESENTATION_EXTENSIONS and bool(
|
|
1926
|
+
_ancestor_dir_names(rel_path) & PRESENTATION_DIRS
|
|
1927
|
+
)
|
|
1928
|
+
|
|
1929
|
+
|
|
1874
1930
|
def _is_hidden_path(rel_path: str) -> bool:
|
|
1875
1931
|
return any(part.startswith(".") for part in rel_path.split("/"))
|
|
1876
1932
|
|
|
@@ -1949,6 +2005,44 @@ def detect_datasets(
|
|
|
1949
2005
|
return _collapse_dataset_folders(sorted(files))
|
|
1950
2006
|
|
|
1951
2007
|
|
|
2008
|
+
def detect_results(
|
|
2009
|
+
candidate_paths: list[str],
|
|
2010
|
+
reserved_paths: list[str] | tuple[str, ...] = (),
|
|
2011
|
+
) -> list[str]:
|
|
2012
|
+
"""Auto-detected result paths among ``candidate_paths``.
|
|
2013
|
+
|
|
2014
|
+
Paths under a dot-directory or under one of ``reserved_paths`` (declared
|
|
2015
|
+
artifacts) are skipped.
|
|
2016
|
+
"""
|
|
2017
|
+
reserved = list(reserved_paths)
|
|
2018
|
+
return sorted(
|
|
2019
|
+
{
|
|
2020
|
+
p
|
|
2021
|
+
for p in candidate_paths
|
|
2022
|
+
if not _is_hidden_path(p)
|
|
2023
|
+
and not _is_under_any_dir(p, reserved)
|
|
2024
|
+
and is_result_path(p)
|
|
2025
|
+
}
|
|
2026
|
+
)
|
|
2027
|
+
|
|
2028
|
+
|
|
2029
|
+
def detect_presentations(
|
|
2030
|
+
candidate_paths: list[str],
|
|
2031
|
+
reserved_paths: list[str] | tuple[str, ...] = (),
|
|
2032
|
+
) -> list[str]:
|
|
2033
|
+
"""Auto-detected presentation paths among ``candidate_paths``."""
|
|
2034
|
+
reserved = list(reserved_paths)
|
|
2035
|
+
return sorted(
|
|
2036
|
+
{
|
|
2037
|
+
p
|
|
2038
|
+
for p in candidate_paths
|
|
2039
|
+
if not _is_hidden_path(p)
|
|
2040
|
+
and not _is_under_any_dir(p, reserved)
|
|
2041
|
+
and is_presentation_path(p)
|
|
2042
|
+
}
|
|
2043
|
+
)
|
|
2044
|
+
|
|
2045
|
+
|
|
1952
2046
|
def list_repo_files(wdir: str | None = None) -> list[str]:
|
|
1953
2047
|
"""Repo-relative paths of files Git does not ignore.
|
|
1954
2048
|
|
|
@@ -2014,7 +2108,7 @@ def _reserved_artifact_paths(
|
|
|
2014
2108
|
if ck_info is None:
|
|
2015
2109
|
ck_info = calkit.load_calkit_info(wdir=wdir)
|
|
2016
2110
|
paths: list[str] = []
|
|
2017
|
-
for kind in ("figures", "datasets"):
|
|
2111
|
+
for kind in ("figures", "datasets", "results", "presentations"):
|
|
2018
2112
|
for obj in ck_info.get(kind, []) or []:
|
|
2019
2113
|
if isinstance(obj, dict) and isinstance(obj.get("path"), str):
|
|
2020
2114
|
paths.append(obj["path"])
|
|
@@ -2044,4 +2138,11 @@ def detect_project_artifacts(
|
|
|
2044
2138
|
datasets = detect_datasets(
|
|
2045
2139
|
candidates, reserved_paths=reserved, figure_paths=figures
|
|
2046
2140
|
)
|
|
2047
|
-
|
|
2141
|
+
results = detect_results(candidates, reserved_paths=reserved)
|
|
2142
|
+
presentations = detect_presentations(candidates, reserved_paths=reserved)
|
|
2143
|
+
return {
|
|
2144
|
+
"figures": figures,
|
|
2145
|
+
"datasets": datasets,
|
|
2146
|
+
"results": results,
|
|
2147
|
+
"presentations": presentations,
|
|
2148
|
+
}
|