calkit-python 0.41.2__tar.gz → 0.41.4__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.4/.gitattributes +1 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/PKG-INFO +1 -1
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/cli/check.py +1 -1
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/cli/main/core.py +20 -5
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/cli/new.py +3 -3
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/cli/scheduler.py +16 -7
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/detect.py +18 -11
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/dvc/core.py +70 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/dvc/zip.py +7 -2
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/environments.py +23 -9
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/git.py +4 -4
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/jupyterlab/routes.py +6 -3
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/overleaf.py +4 -1
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/pipeline.py +78 -44
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/releases.py +2 -2
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/server.py +3 -5
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/cli/main/test_core.py +25 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/cli/main/test_xr.py +5 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/cli/test_check.py +9 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/cli/test_latex.py +15 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/cli/test_new.py +5 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/cli/test_notebooks.py +9 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/cli/test_overleaf.py +5 -1
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/cli/test_scheduler.py +7 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/cli/test_update.py +5 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/dvc/test_core.py +88 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/test_conda.py +17 -2
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/test_environments.py +34 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/test_git.py +14 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/test_install.py +13 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/test_pipeline.py +92 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/.claude-plugin/marketplace.json +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/.gitignore +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/.pre-commit-config.yaml +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/.prettierignore +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/.python-version +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/.vscode/launch.json +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/.vscode/tasks.json +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/.yarnrc.yml +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/AGENTS.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/CITATION.cff +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/CODE_OF_CONDUCT.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/CONTRIBUTING.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/LICENSE +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/Makefile +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/README.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/agent-plugin/.claude-plugin/plugin.json +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/agent-plugin/skills/add-pipeline-stage/SKILL.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/agent-plugin/skills/conventions/SKILL.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/agent-plugin/skills/create-pipeline/SKILL.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/babel.config.js +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/__init__.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/__main__.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/calc.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/check.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/cli/__init__.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/cli/cloud.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/cli/config.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/cli/core.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/cli/describe.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/cli/dev.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/cli/import_.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/cli/latex.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/cli/list.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/cli/main/__init__.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/cli/main/xr.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/cli/notebooks.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/cli/office.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/cli/overleaf.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/cli/update.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/cloud.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/conda.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/config.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/core.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/datasets.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/dependencies.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/docker.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/dvc/__init__.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/fs.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/github.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/gui.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/install.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/invenio.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/julia.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/jupyter.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/jupyterlab/__init__.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/labextension/package.json +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/labextension/schemas/calkit/package.json.orig +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/labextension/schemas/calkit/plugin.json +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/labextension/static/502.9a2c5772a15466e923ef.js +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/labextension/static/695.2c41003a452d43d2b358.js +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/labextension/static/867.a42a046aa5108f54f8fb.js +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/labextension/static/909.e3f9cc3408834a7fdcc3.js +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/labextension/static/946.050af2abf7845cfbdbd2.js +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/labextension/static/946.050af2abf7845cfbdbd2.js.LICENSE.txt +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/labextension/static/b2f1c3efe70cb539d121.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/labextension/static/remoteEntry.65469af996e7a96aa983.js +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/labextension/static/style.js +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/labextension/static/third-party-licenses.json +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/licenses.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/magics.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/matlab.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/models/__init__.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/models/core.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/models/io.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/models/iteration.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/models/pipeline.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/notebooks.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/office.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/ops.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/templates/__init__.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/templates/core.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/templates/latex/__init__.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/templates/latex/article/paper.tex +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/templates/latex/core.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/templates/latex/jfm/jfm.bst +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/templates/latex/jfm/jfm.cls +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/templates/latex/jfm/lineno-FLM.sty +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/templates/latex/jfm/paper.tex +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/templates/latex/jfm/upmath.sty +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/__init__.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/cli/__init__.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/cli/main/__init__.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/cli/main/test_subprojects.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/cli/test_cloud.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/cli/test_config.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/cli/test_import.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/cli/test_list.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/dvc/__init__.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/dvc/test_zip.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/jupyterlab/__init__.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/jupyterlab/test_routes.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/models/__init__.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/models/test_iteration.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/models/test_pipeline.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/test_calc.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/test_check.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/test_cloud.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/test_core.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/test_dependencies.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/test_detect.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/test_docker.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/test_fs.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/test_invenio.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/test_julia.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/test_jupyter.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/test_magics.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/test_matlab.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/test_notebooks.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/test_releases.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/calkit/tests/test_templates.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/conftest.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/CNAME +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/ai-tools.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/apps.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/calculations.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/calkit-yaml.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/cli-reference.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/cloud-integration.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/datasets.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/dependencies.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/environments.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/examples.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/governance.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/help.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/hpc.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/img/c-to-the-k-white.svg +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/img/calkit-fragmentation-compendium.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/img/calkit-no-bg.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/img/connect-zenodo.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/img/jupyterlab/all-green.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/img/jupyterlab/collect-data-stale.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/img/jupyterlab/new-env.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/img/jupyterlab/new-notebook.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/img/jupyterlab/pipeline-badge.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/img/jupyterlab-params.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/img/plos-osi-code-2024-03.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/img/vscode-nb-params.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/index.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/installation.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/jupyterlab.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/local-server.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/notebooks.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/overleaf.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/pipeline/index.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/pipeline/manual-steps.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/pipeline/running-and-logging.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/quickstart.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/references.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/releases.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/reproducibility.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/subprojects.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/adding-latex-pub-docker.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/conda-envs.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/existing-project.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/first-project.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/github-actions.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/actions-repo-secrets.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/latex-codespaces/building-codespace.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/latex-codespaces/codespaces-secrets-2.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/latex-codespaces/editor-split.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/latex-codespaces/go-to-linked-code.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/latex-codespaces/issue-from-selection.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/latex-codespaces/new-project.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/latex-codespaces/new-pub-2.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/latex-codespaces/new-token.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/latex-codespaces/paper.tex.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/latex-codespaces/project-home-3.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/latex-codespaces/push.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/latex-codespaces/stage.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/office/anakin-excel.jpg +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/office/chart-more-rows.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/office/create-project.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/office/elsevier-research-data-guidelines.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/office/excel-chart.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/office/excel-data.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/office/insert-link-to-file.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/office/needs-clone.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/office/new-stage.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/office/phd-comics-version-control.webp +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/office/pipeline-out-of-date.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/office/status-more-rows.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/office/uncommitted-changes.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/office/untracked-data.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/office/updated-publication.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/office/word-to-pdf-stage-2.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/office/workflow-page.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/openfoam/clone.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/openfoam/create-project.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/openfoam/datasets-page.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/openfoam/figure-on-website-updated.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/openfoam/figure-on-website.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/openfoam/new-token.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/openfoam/reclone.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/openfoam/status-after-import-dataset.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/quick-actions.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/run-proc.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/vscode-slurm-notebook/create-calkit-env.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/vscode-slurm-notebook/create-inner-env.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/vscode-slurm-notebook/create-new-calkit-env.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/vscode-slurm-notebook/select-calkit-env.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/vscode-slurm-notebook/slurm-job-running.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/vscode-slurm-notebook/slurm-launch-options.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/img/vscode-slurm-notebook/starting-slurm-job.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/index.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/jupyterlab.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/latex-codespaces.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/matlab.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/notebook-pipeline.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/office.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/openfoam.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/procedures.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/tutorials/vscode-slurm-notebook.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/docs/version-control.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/flake.lock +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/flake.nix +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/install.json +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/jest.config.js +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/jupyter-config/server-config/calkit.json +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/mkdocs.yml +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/package.json +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/pyproject.toml +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/schema/plugin.json +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/scripts/generate-docs-references.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/scripts/install.ps1 +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/scripts/install.sh +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/scripts/make-calk9.sh +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/scripts/sync-docs.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/src/__tests__/useQueries.spec.ts +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/src/calkit-config.ts +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/src/cell-output-marker.ts +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/src/components/commit-dialog.tsx +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/src/components/environment-editor.tsx +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/src/components/notebook-registration.tsx +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/src/components/notebook-toolbar.tsx +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/src/components/pipeline-status-bar.tsx +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/src/components/project-info-editor.tsx +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/src/components/sidebar-settings.tsx +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/src/components/sidebar.tsx +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/src/components/stage-editor.tsx +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/src/feature-flags.ts +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/src/file-browser-menu.ts +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/src/hooks/__tests__/useQueries.test.tsx +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/src/hooks/useQueries.ts +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/src/icons.ts +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/src/index.ts +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/src/io-tracker.ts +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/src/pipeline-state.ts +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/src/queryClient.ts +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/src/request.ts +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/src/shims-mainmenu.d.ts +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/style/base.css +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/style/cell-output-marker.css +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/style/environment-editor.css +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/style/environment-selector.css +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/style/img/calkit-no-bg.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/style/index.css +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/style/index.js +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/style/notebook-toolbar.css +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/style/pipeline-status-bar.css +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/style/sidebar.css +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/test/dvc-md5-dir/osx-arm64.txt +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/test/nb-julia.ipynb +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/test/nb-params.ipynb +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/test/nb-subdir.ipynb +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/test/pipeline.ipynb +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/test/script.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/test/test-log.log +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/tsconfig.json +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/tsconfig.test.json +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/ui-tests/.gitignore +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/ui-tests/README.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/ui-tests/jupyter_server_test_config.py +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/ui-tests/package.json +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/ui-tests/playwright.config.js +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/ui-tests/tests/calkit.spec.ts +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/ui-tests/yarn.lock +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/uv.lock +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/vscode-ext/.gitignore +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/vscode-ext/.vscodeignore +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/vscode-ext/CHANGELOG.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/vscode-ext/LICENSE +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/vscode-ext/README.md +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/vscode-ext/images/calkit-no-bg.png +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/vscode-ext/package-lock.json +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/vscode-ext/package.json +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/vscode-ext/scripts/set-proposed-api.js +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/vscode-ext/src/environments.ts +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/vscode-ext/src/extension.ts +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/vscode-ext/src/notebooks.ts +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/vscode-ext/src/test/environments.test.ts +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/vscode-ext/src/test/kernel-selection.test.ts +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/vscode-ext/src/test/notebooks.test.ts +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/vscode-ext/src/types.ts +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/vscode-ext/tsconfig.json +0 -0
- {calkit_python-0.41.2 → calkit_python-0.41.4}/yarn.lock +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
test/dvc-md5-dir/** text eol=lf
|
|
@@ -502,10 +502,11 @@ def get_status(
|
|
|
502
502
|
if "dvc" in categories:
|
|
503
503
|
try:
|
|
504
504
|
dvc_repo = calkit.dvc.get_dvc_repo()
|
|
505
|
-
data_status = dvc_repo.data_status()
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
505
|
+
data_status = dict(dvc_repo.data_status())
|
|
506
|
+
data_status.pop("git", None)
|
|
507
|
+
status_dict["dvc"] = calkit.dvc.data_status_as_posix(
|
|
508
|
+
data_status
|
|
509
|
+
)
|
|
509
510
|
except Exception as e:
|
|
510
511
|
status_dict["dvc"] = {"error": f"{e.__class__.__name__}: {e}"}
|
|
511
512
|
if "pipeline" in categories or "dvc" in categories:
|
|
@@ -557,6 +558,7 @@ def get_status(
|
|
|
557
558
|
dvc_repo = calkit.dvc.get_dvc_repo()
|
|
558
559
|
raw = dict(dvc_repo.data_status())
|
|
559
560
|
raw.pop("git", None)
|
|
561
|
+
raw = calkit.dvc.data_status_as_posix(raw)
|
|
560
562
|
typer.echo(_format_dvc_data_status(raw, zip_path_map))
|
|
561
563
|
if "pipeline" in categories or "dvc" in categories:
|
|
562
564
|
print_sep("Pipeline")
|
|
@@ -579,6 +581,8 @@ def get_status(
|
|
|
579
581
|
if stale_stage is None:
|
|
580
582
|
continue
|
|
581
583
|
typer.echo(f" {typer.style(stage_name, fg='yellow')}:")
|
|
584
|
+
if stale_stage.always_run:
|
|
585
|
+
typer.echo(" always runs")
|
|
582
586
|
if stale_stage.modified_command:
|
|
583
587
|
typer.echo(" modified command")
|
|
584
588
|
# Show stale outputs for this stage
|
|
@@ -596,8 +600,16 @@ def get_status(
|
|
|
596
600
|
typer.echo(" modified inputs:")
|
|
597
601
|
for input_path in stale_stage.modified_inputs:
|
|
598
602
|
typer.echo(f" {input_path}")
|
|
603
|
+
if pipeline_status.always_run_stage_names:
|
|
604
|
+
typer.echo("Always-run stages:")
|
|
605
|
+
for stage_name in pipeline_status.always_run_stage_names:
|
|
606
|
+
typer.echo(f" {typer.style(stage_name, fg='cyan')}")
|
|
599
607
|
elif pipeline_status:
|
|
600
608
|
typer.echo("Pipeline is up to date.")
|
|
609
|
+
if pipeline_status.always_run_stage_names:
|
|
610
|
+
typer.echo("Always-run stages:")
|
|
611
|
+
for stage_name in pipeline_status.always_run_stage_names:
|
|
612
|
+
typer.echo(f" {typer.style(stage_name, fg='cyan')}")
|
|
601
613
|
|
|
602
614
|
|
|
603
615
|
@app.command(name="diff")
|
|
@@ -2421,7 +2433,10 @@ def run_in_env(
|
|
|
2421
2433
|
elif env["kind"] == "pixi":
|
|
2422
2434
|
env_cmd = []
|
|
2423
2435
|
if "name" in env:
|
|
2424
|
-
env_cmd
|
|
2436
|
+
env_cmd += ["--environment", env["name"]]
|
|
2437
|
+
env_path = env.get("path")
|
|
2438
|
+
if env_path and os.path.dirname(env_path):
|
|
2439
|
+
env_cmd += ["--manifest-path", os.path.abspath(env_path)]
|
|
2425
2440
|
cmd = ["pixi", "run"] + env_cmd + cmd
|
|
2426
2441
|
if verbose:
|
|
2427
2442
|
typer.echo(f"Running command: {cmd}")
|
|
@@ -1152,10 +1152,10 @@ def new_publication(
|
|
|
1152
1152
|
deps += stage.get("outs", [])
|
|
1153
1153
|
# Create publication object
|
|
1154
1154
|
if template_type == "latex":
|
|
1155
|
-
pub_fpath =
|
|
1155
|
+
pub_fpath = pathlib.Path(
|
|
1156
1156
|
path,
|
|
1157
1157
|
template_obj.target.removesuffix(".tex") + ".pdf", # type: ignore
|
|
1158
|
-
)
|
|
1158
|
+
).as_posix()
|
|
1159
1159
|
else:
|
|
1160
1160
|
pub_fpath = path
|
|
1161
1161
|
if not overwrite and pub_fpath in pub_paths:
|
|
@@ -1190,7 +1190,7 @@ def new_publication(
|
|
|
1190
1190
|
stage = LatexStage(
|
|
1191
1191
|
kind="latex",
|
|
1192
1192
|
environment=env_name,
|
|
1193
|
-
target_path=
|
|
1193
|
+
target_path=pathlib.Path(path, template_obj.target).as_posix(), # type: ignore
|
|
1194
1194
|
outputs=[pub_fpath],
|
|
1195
1195
|
).model_dump()
|
|
1196
1196
|
if "pipeline" not in ck_info:
|
|
@@ -92,9 +92,9 @@ def _mock_enabled() -> bool:
|
|
|
92
92
|
|
|
93
93
|
|
|
94
94
|
def _require_posix_mock() -> None:
|
|
95
|
-
# The mock backend uses bash
|
|
96
|
-
if
|
|
97
|
-
raise_error("CALKIT_MOCK_SCHEDULER
|
|
95
|
+
# The mock backend uses bash; if that is missing, the mock cannot run.
|
|
96
|
+
if shutil.which("bash") is None:
|
|
97
|
+
raise_error("CALKIT_MOCK_SCHEDULER requires bash on PATH")
|
|
98
98
|
|
|
99
99
|
|
|
100
100
|
def _ensure_mock_dir() -> None:
|
|
@@ -177,13 +177,19 @@ def _mock_submit(job_id: str, job_command: str, log_path: str) -> int:
|
|
|
177
177
|
env = dict(os.environ)
|
|
178
178
|
env.setdefault("PBS_O_WORKDIR", os.getcwd())
|
|
179
179
|
with open(log_path, "w") as log_file:
|
|
180
|
-
|
|
181
|
-
["bash", "-c", wrapped],
|
|
180
|
+
popen_kwargs = dict(
|
|
182
181
|
stdout=log_file,
|
|
183
182
|
stderr=subprocess.STDOUT,
|
|
184
|
-
start_new_session=True,
|
|
185
183
|
env=env,
|
|
186
184
|
)
|
|
185
|
+
if os.name == "posix":
|
|
186
|
+
popen_kwargs["start_new_session"] = True
|
|
187
|
+
elif hasattr(subprocess, "CREATE_NEW_PROCESS_GROUP"):
|
|
188
|
+
popen_kwargs["creationflags"] = subprocess.CREATE_NEW_PROCESS_GROUP
|
|
189
|
+
proc = subprocess.Popen(
|
|
190
|
+
["bash", "-c", wrapped],
|
|
191
|
+
**popen_kwargs,
|
|
192
|
+
)
|
|
187
193
|
return proc.pid
|
|
188
194
|
|
|
189
195
|
|
|
@@ -192,7 +198,10 @@ def _mock_cancel(job_id: str) -> tuple[bool, str]:
|
|
|
192
198
|
pid = _mock_pid(job_id)
|
|
193
199
|
if pid is not None:
|
|
194
200
|
try:
|
|
195
|
-
os.
|
|
201
|
+
if os.name == "posix":
|
|
202
|
+
os.killpg(os.getpgid(pid), signal.SIGTERM)
|
|
203
|
+
else:
|
|
204
|
+
os.kill(pid, signal.SIGTERM)
|
|
196
205
|
except (ProcessLookupError, PermissionError):
|
|
197
206
|
pass
|
|
198
207
|
# Drop a sentinel so later liveness checks report the job as finished.
|
|
@@ -10,6 +10,7 @@ import os
|
|
|
10
10
|
import re
|
|
11
11
|
import shlex
|
|
12
12
|
import sys
|
|
13
|
+
from pathlib import Path
|
|
13
14
|
from typing import Literal
|
|
14
15
|
|
|
15
16
|
NotebookLanguage = Literal["python", "julia", "r"]
|
|
@@ -114,7 +115,7 @@ def detect_julia_script_io(
|
|
|
114
115
|
if not os.path.isabs(match):
|
|
115
116
|
full_path = os.path.join(script_dir, match)
|
|
116
117
|
if os.path.exists(full_path):
|
|
117
|
-
inputs.append(os.path.relpath(full_path))
|
|
118
|
+
inputs.append(Path(os.path.relpath(full_path)).as_posix())
|
|
118
119
|
elif _is_valid_project_path(match):
|
|
119
120
|
inputs.append(match)
|
|
120
121
|
read_patterns = [
|
|
@@ -421,26 +422,29 @@ def detect_latex_io(tex_path: str) -> dict[str, list[str]]:
|
|
|
421
422
|
for pattern, pattern_type in patterns:
|
|
422
423
|
matches = re.findall(pattern, content)
|
|
423
424
|
for match in matches:
|
|
425
|
+
|
|
426
|
+
def _resolve(name: str) -> str:
|
|
427
|
+
return Path(
|
|
428
|
+
os.path.normpath(os.path.join(tex_dir, name))
|
|
429
|
+
).as_posix()
|
|
430
|
+
|
|
424
431
|
if pattern_type == "bib":
|
|
425
432
|
files = [f.strip() for f in match.split(",")]
|
|
426
433
|
for f in files:
|
|
427
434
|
if not f.endswith(".bib"):
|
|
428
435
|
f += ".bib"
|
|
429
436
|
# Resolve relative to the document directory
|
|
430
|
-
|
|
431
|
-
inputs.append(resolved)
|
|
437
|
+
inputs.append(_resolve(f))
|
|
432
438
|
elif pattern_type == "tex":
|
|
433
439
|
filename = match
|
|
434
440
|
if not filename.endswith(".tex"):
|
|
435
441
|
filename += ".tex"
|
|
436
442
|
# Resolve relative to the document directory
|
|
437
|
-
|
|
438
|
-
inputs.append(resolved)
|
|
443
|
+
inputs.append(_resolve(filename))
|
|
439
444
|
else:
|
|
440
445
|
# Include graphics or other files
|
|
441
446
|
# Resolve relative to the document directory
|
|
442
|
-
|
|
443
|
-
inputs.append(resolved)
|
|
447
|
+
inputs.append(_resolve(match))
|
|
444
448
|
# Filter and deduplicate inputs
|
|
445
449
|
inputs = [p for p in inputs if _is_valid_project_path(p)]
|
|
446
450
|
inputs = list(dict.fromkeys(inputs))
|
|
@@ -774,6 +778,9 @@ def _detect_python_code_io(
|
|
|
774
778
|
except ValueError:
|
|
775
779
|
# If paths are on different drives (Windows), use normalized path
|
|
776
780
|
rel_path = full_path
|
|
781
|
+
# Always emit posix separators so downstream comparisons are stable
|
|
782
|
+
# across platforms.
|
|
783
|
+
rel_path = Path(rel_path).as_posix()
|
|
777
784
|
# Strip leading ../ for paths outside project root
|
|
778
785
|
while rel_path.startswith("../"):
|
|
779
786
|
rel_path = rel_path[3:]
|
|
@@ -938,7 +945,7 @@ def _detect_julia_code_io(
|
|
|
938
945
|
if not os.path.isabs(match):
|
|
939
946
|
full_path = os.path.join(script_dir, match)
|
|
940
947
|
if os.path.exists(full_path):
|
|
941
|
-
inputs.append(os.path.relpath(full_path))
|
|
948
|
+
inputs.append(Path(os.path.relpath(full_path)).as_posix())
|
|
942
949
|
elif _is_valid_project_path(match):
|
|
943
950
|
inputs.append(match)
|
|
944
951
|
read_patterns = [
|
|
@@ -978,12 +985,12 @@ def _resolve_python_import(
|
|
|
978
985
|
if os.path.exists(file_path) and _is_valid_project_path(
|
|
979
986
|
os.path.relpath(file_path)
|
|
980
987
|
):
|
|
981
|
-
return os.path.relpath(file_path)
|
|
988
|
+
return Path(os.path.relpath(file_path)).as_posix()
|
|
982
989
|
init_path = os.path.join(search_dir, module_path, "__init__.py")
|
|
983
990
|
if os.path.exists(init_path) and _is_valid_project_path(
|
|
984
991
|
os.path.relpath(init_path)
|
|
985
992
|
):
|
|
986
|
-
return os.path.relpath(init_path)
|
|
993
|
+
return Path(os.path.relpath(init_path)).as_posix()
|
|
987
994
|
return None
|
|
988
995
|
|
|
989
996
|
|
|
@@ -1018,7 +1025,7 @@ def _detect_r_code_io(
|
|
|
1018
1025
|
if not os.path.isabs(match):
|
|
1019
1026
|
full_path = os.path.join(script_dir, match)
|
|
1020
1027
|
if os.path.exists(full_path):
|
|
1021
|
-
inputs.append(os.path.relpath(full_path))
|
|
1028
|
+
inputs.append(Path(os.path.relpath(full_path)).as_posix())
|
|
1022
1029
|
elif _is_valid_project_path(match):
|
|
1023
1030
|
inputs.append(match)
|
|
1024
1031
|
# Read patterns that capture variables, file.path() expressions, or literals
|
|
@@ -26,6 +26,24 @@ logger.setLevel(logging.INFO)
|
|
|
26
26
|
USE_CK_REMOTE_BY_DEFAULT = True
|
|
27
27
|
|
|
28
28
|
|
|
29
|
+
class _FrozenStageWarningFilter(logging.Filter):
|
|
30
|
+
"""Drop DVC's "stage is frozen" warnings.
|
|
31
|
+
|
|
32
|
+
DVC emits these for every frozen stage on every ``status``/``repro`` call
|
|
33
|
+
("... not going to be shown in the status output." and "... not going to
|
|
34
|
+
be reproduced."). Frozen stages are pinned by design, so the warnings are
|
|
35
|
+
noise — the substring shared by both variants is matched here.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
def filter(self, record: logging.LogRecord) -> bool:
|
|
39
|
+
return "is frozen. Its dependencies are" not in record.getMessage()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
_frozen_stage_warning_filter = _FrozenStageWarningFilter()
|
|
43
|
+
for _name in ("dvc.repo.reproduce", "dvc.repo.status"):
|
|
44
|
+
logging.getLogger(_name).addFilter(_frozen_stage_warning_filter)
|
|
45
|
+
|
|
46
|
+
|
|
29
47
|
class CalkitDVCFileSystem(ObjectFileSystem):
|
|
30
48
|
"""DVC-facing filesystem wrapper for the ``ck://`` scheme."""
|
|
31
49
|
|
|
@@ -614,3 +632,55 @@ def hash_path(path: str) -> dict:
|
|
|
614
632
|
return hash_file(path)
|
|
615
633
|
else:
|
|
616
634
|
raise ValueError(f"Path does not exist: {path}")
|
|
635
|
+
|
|
636
|
+
|
|
637
|
+
def _path_item_as_posix(item):
|
|
638
|
+
# Renamed entries are dicts like {"old": ..., "new": ...}.
|
|
639
|
+
if isinstance(item, dict):
|
|
640
|
+
return {k: Path(v).as_posix() for k, v in item.items()}
|
|
641
|
+
return Path(item).as_posix()
|
|
642
|
+
|
|
643
|
+
|
|
644
|
+
def data_status_as_posix(data_status: dict) -> dict:
|
|
645
|
+
"""Convert all paths in DVC data status to posix format.
|
|
646
|
+
|
|
647
|
+
We skip the ``git`` entry since Git already formats as posix.
|
|
648
|
+
"""
|
|
649
|
+
data_status_fmt = {}
|
|
650
|
+
for cat, obj in data_status.items():
|
|
651
|
+
if cat == "git":
|
|
652
|
+
data_status_fmt[cat] = obj
|
|
653
|
+
elif isinstance(obj, list):
|
|
654
|
+
data_status_fmt[cat] = [_path_item_as_posix(p) for p in obj]
|
|
655
|
+
elif isinstance(obj, dict):
|
|
656
|
+
obj_fmt = {}
|
|
657
|
+
for cat2, obj_i in obj.items():
|
|
658
|
+
obj_fmt[cat2] = [_path_item_as_posix(p) for p in obj_i]
|
|
659
|
+
data_status_fmt[cat] = obj_fmt
|
|
660
|
+
else:
|
|
661
|
+
data_status_fmt[cat] = obj
|
|
662
|
+
return data_status_fmt
|
|
663
|
+
|
|
664
|
+
|
|
665
|
+
def status_as_posix(status: dict) -> dict:
|
|
666
|
+
"""Convert all paths in repo status to posix format."""
|
|
667
|
+
status_fmt = {}
|
|
668
|
+
for stage_name, st_list in status.items():
|
|
669
|
+
st_list_fmt = []
|
|
670
|
+
for st_dict in st_list:
|
|
671
|
+
if isinstance(st_dict, str):
|
|
672
|
+
st_list_fmt.append(st_dict)
|
|
673
|
+
continue
|
|
674
|
+
st_dict_fmt = {}
|
|
675
|
+
for st_cat, path_st_dict in st_dict.items():
|
|
676
|
+
if not isinstance(path_st_dict, dict):
|
|
677
|
+
# e.g. {"changed command": "python src/new-script.py"}
|
|
678
|
+
st_dict_fmt[st_cat] = path_st_dict
|
|
679
|
+
continue
|
|
680
|
+
path_st_dict_fmt = {}
|
|
681
|
+
for p, st in path_st_dict.items():
|
|
682
|
+
path_st_dict_fmt[Path(p).as_posix()] = st
|
|
683
|
+
st_dict_fmt[st_cat] = path_st_dict_fmt
|
|
684
|
+
st_list_fmt.append(st_dict_fmt)
|
|
685
|
+
status_fmt[stage_name] = st_list_fmt
|
|
686
|
+
return status_fmt
|
|
@@ -113,7 +113,7 @@ class SyncRecord(BaseModel):
|
|
|
113
113
|
|
|
114
114
|
def make_zip_path(workspace_path: str) -> str:
|
|
115
115
|
"""Make a zip path for a given workspace path."""
|
|
116
|
-
return
|
|
116
|
+
return Path(ZIPS_DIR, "files", f"{workspace_path}.zip").as_posix()
|
|
117
117
|
|
|
118
118
|
|
|
119
119
|
def _path_map_path(wdir: str | None = None) -> str:
|
|
@@ -272,6 +272,7 @@ def get_sync_record(
|
|
|
272
272
|
) -> SyncRecord | None:
|
|
273
273
|
"""Get a sync record for a given workspace path."""
|
|
274
274
|
_check_local_dir(wdir)
|
|
275
|
+
workspace_path = Path(workspace_path).as_posix()
|
|
275
276
|
with SqliteDict(_sync_records_path(wdir)) as db:
|
|
276
277
|
raw = db.get(workspace_path)
|
|
277
278
|
if raw is not None:
|
|
@@ -283,13 +284,14 @@ def write_sync_record(record: SyncRecord, wdir: str | None = None):
|
|
|
283
284
|
"""Write a sync record."""
|
|
284
285
|
_check_local_dir(wdir)
|
|
285
286
|
with SqliteDict(_sync_records_path(wdir)) as db:
|
|
286
|
-
db[record.workspace_path] = record.model_dump()
|
|
287
|
+
db[Path(record.workspace_path).as_posix()] = record.model_dump()
|
|
287
288
|
db.commit()
|
|
288
289
|
|
|
289
290
|
|
|
290
291
|
def delete_sync_record(workspace_path: str, wdir: str | None = None):
|
|
291
292
|
"""Delete a sync record."""
|
|
292
293
|
_check_local_dir(wdir)
|
|
294
|
+
workspace_path = Path(workspace_path).as_posix()
|
|
293
295
|
with SqliteDict(_sync_records_path(wdir)) as db:
|
|
294
296
|
if workspace_path in db:
|
|
295
297
|
del db[workspace_path]
|
|
@@ -466,6 +468,9 @@ def sync_one(
|
|
|
466
468
|
workspace_path = os.path.join(wdir, workspace_path)
|
|
467
469
|
if zip_path is not None:
|
|
468
470
|
zip_path = os.path.join(wdir, zip_path)
|
|
471
|
+
workspace_path = Path(workspace_path).as_posix()
|
|
472
|
+
if zip_path is not None:
|
|
473
|
+
zip_path = Path(zip_path).as_posix()
|
|
469
474
|
return _sync_one(workspace_path, zip_path, direction, wdir=wdir)
|
|
470
475
|
|
|
471
476
|
|
|
@@ -38,6 +38,12 @@ CONDA_VENV_ARCHS = [
|
|
|
38
38
|
]
|
|
39
39
|
ENV_CHECK_CACHE_TTL_SECONDS = 3600
|
|
40
40
|
KINDS_NO_CHECK = ["_system", "ssh"]
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _as_posix_path(path: str) -> str:
|
|
44
|
+
return Path(path).as_posix()
|
|
45
|
+
|
|
46
|
+
|
|
41
47
|
COMPOSITE_ENV_SEP = ":"
|
|
42
48
|
VALID_OUTER_ENV_KINDS = ["slurm", "pbs"]
|
|
43
49
|
|
|
@@ -314,6 +320,12 @@ def get_env_lock_fpath(
|
|
|
314
320
|
lock_fpath = os.path.join(env_dir, "uv.lock")
|
|
315
321
|
else:
|
|
316
322
|
lock_fpath = "uv.lock"
|
|
323
|
+
elif env_kind == "pixi":
|
|
324
|
+
env_dir = os.path.dirname(env.get("path") or "")
|
|
325
|
+
if env_dir:
|
|
326
|
+
lock_fpath = os.path.join(env_dir, "pixi.lock")
|
|
327
|
+
else:
|
|
328
|
+
lock_fpath = "pixi.lock"
|
|
317
329
|
elif env_kind in ["venv", "uv-venv"]:
|
|
318
330
|
if legacy:
|
|
319
331
|
lock_fpath += ".txt"
|
|
@@ -711,7 +723,7 @@ def make_env_name(path: str, all_env_names: list[str], kind: str) -> str:
|
|
|
711
723
|
str
|
|
712
724
|
A unique environment name.
|
|
713
725
|
"""
|
|
714
|
-
dirname =
|
|
726
|
+
dirname = Path(path).parent.name
|
|
715
727
|
# If this is the first env in the project, call it main
|
|
716
728
|
if not all_env_names:
|
|
717
729
|
return dirname or "main"
|
|
@@ -835,7 +847,7 @@ def env_from_name_or_path(
|
|
|
835
847
|
exists=True,
|
|
836
848
|
)
|
|
837
849
|
# Check if name_or_path is a file and detect environment type
|
|
838
|
-
env_path = name_or_path
|
|
850
|
+
env_path = _as_posix_path(name_or_path)
|
|
839
851
|
if os.path.isfile(env_path):
|
|
840
852
|
if env_path.endswith("requirements.txt"):
|
|
841
853
|
# TODO: Detect if uv is installed, and use a plain venv if not
|
|
@@ -845,9 +857,9 @@ def env_from_name_or_path(
|
|
|
845
857
|
"kind": "uv-venv",
|
|
846
858
|
"path": env_path,
|
|
847
859
|
"python": DEFAULT_PYTHON_VERSION,
|
|
848
|
-
"prefix":
|
|
849
|
-
|
|
850
|
-
),
|
|
860
|
+
"prefix": Path(env_path)
|
|
861
|
+
.parent.joinpath(".venv")
|
|
862
|
+
.as_posix(),
|
|
851
863
|
},
|
|
852
864
|
exists=False,
|
|
853
865
|
)
|
|
@@ -936,9 +948,10 @@ def env_from_name_and_or_path(
|
|
|
936
948
|
if ck_info is None:
|
|
937
949
|
ck_info = calkit.load_calkit_info()
|
|
938
950
|
envs = ck_info.get("environments", {})
|
|
951
|
+
path = _as_posix_path(path) if path else None
|
|
939
952
|
if name and name in envs:
|
|
940
953
|
env = envs[name]
|
|
941
|
-
if path and env.get("path") != path:
|
|
954
|
+
if path and _as_posix_path(env.get("path", "")) != path:
|
|
942
955
|
raise ValueError(
|
|
943
956
|
f"Environment '{name}' exists but has a different path "
|
|
944
957
|
f"('{env.get('path')}') than provided ('{path}')"
|
|
@@ -952,7 +965,7 @@ def env_from_name_and_or_path(
|
|
|
952
965
|
# Look for a sub-environment with the given name and path
|
|
953
966
|
for sub_name, sub_env in envs.items():
|
|
954
967
|
if (sub_name == sub_env_name) or (
|
|
955
|
-
path and sub_env.get("path") == path
|
|
968
|
+
path and _as_posix_path(sub_env.get("path", "")) == path
|
|
956
969
|
):
|
|
957
970
|
return EnvDetectResult(
|
|
958
971
|
name=sub_name,
|
|
@@ -989,12 +1002,13 @@ def env_from_notebook_path(
|
|
|
989
1002
|
"""
|
|
990
1003
|
if ck_info is None:
|
|
991
1004
|
ck_info = calkit.load_calkit_info()
|
|
1005
|
+
notebook_path = _as_posix_path(notebook_path)
|
|
992
1006
|
stages = ck_info.get("pipeline", {}).get("stages", {})
|
|
993
1007
|
envs = ck_info.get("environments", {})
|
|
994
1008
|
for stage in stages.values():
|
|
995
1009
|
if (
|
|
996
1010
|
stage.get("kind") == "jupyter-notebook"
|
|
997
|
-
and stage.get("notebook_path") == notebook_path
|
|
1011
|
+
and _as_posix_path(stage.get("notebook_path", "")) == notebook_path
|
|
998
1012
|
):
|
|
999
1013
|
env_name = stage.get("environment")
|
|
1000
1014
|
if env_name:
|
|
@@ -1002,7 +1016,7 @@ def env_from_notebook_path(
|
|
|
1002
1016
|
if env:
|
|
1003
1017
|
return EnvDetectResult(name=env_name, env=env, exists=True)
|
|
1004
1018
|
for nb in ck_info.get("notebooks", []):
|
|
1005
|
-
if nb.get("path") == notebook_path:
|
|
1019
|
+
if _as_posix_path(nb.get("path", "")) == notebook_path:
|
|
1006
1020
|
env_name = nb.get("environment")
|
|
1007
1021
|
if env_name:
|
|
1008
1022
|
env = envs.get(env_name)
|
|
@@ -157,7 +157,7 @@ def ensure_path_is_ignored(
|
|
|
157
157
|
if os.path.isfile(gitignore_path):
|
|
158
158
|
with open(gitignore_path) as f:
|
|
159
159
|
gitignore_txt = f.read()
|
|
160
|
-
lines = gitignore_txt.splitlines()
|
|
160
|
+
lines = [line for line in gitignore_txt.splitlines() if line]
|
|
161
161
|
if target_path in lines:
|
|
162
162
|
# The direct rule exists; also remove any stale negation that
|
|
163
163
|
# follows it, otherwise the negation wins and the path stays
|
|
@@ -169,7 +169,7 @@ def ensure_path_is_ignored(
|
|
|
169
169
|
for n in stale:
|
|
170
170
|
lines.remove(n)
|
|
171
171
|
with open(gitignore_path, "w") as f:
|
|
172
|
-
f.write(
|
|
172
|
+
f.write("\n".join(lines))
|
|
173
173
|
return True
|
|
174
174
|
# Remove any stale negations for this path so the ignore rule takes
|
|
175
175
|
# effect cleanly without accumulating contradictory entries.
|
|
@@ -180,7 +180,7 @@ def ensure_path_is_ignored(
|
|
|
180
180
|
lines.remove(n)
|
|
181
181
|
lines.append(target_path)
|
|
182
182
|
with open(gitignore_path, "w") as f:
|
|
183
|
-
f.write(
|
|
183
|
+
f.write("\n".join(lines))
|
|
184
184
|
return True
|
|
185
185
|
with open(gitignore_path, "a") as f:
|
|
186
186
|
if (
|
|
@@ -329,7 +329,7 @@ def ensure_path_is_not_ignored(
|
|
|
329
329
|
lines.remove(no_ignore_line)
|
|
330
330
|
lines.append(no_ignore_line)
|
|
331
331
|
with open(gitignore_path, "w") as f:
|
|
332
|
-
f.write(
|
|
332
|
+
f.write("\n".join(lines))
|
|
333
333
|
# If the path is still ignored after updating this gitignore file (e.g.,
|
|
334
334
|
# because a subdirectory .gitignore also contains a matching rule), fix
|
|
335
335
|
# that file as well. Depth-limit guards against pathological gitignore
|
|
@@ -903,11 +903,14 @@ class PipelineStatusRouteHandler(APIHandler):
|
|
|
903
903
|
pipeline_status = {
|
|
904
904
|
k.split("dvc.yaml:")[-1]: v
|
|
905
905
|
for k, v in raw_status.items()
|
|
906
|
-
if
|
|
907
|
-
and not k.endswith(".dvc")
|
|
906
|
+
if not k.endswith(".dvc")
|
|
908
907
|
and k.split("dvc.yaml:")[-1].split("@")[0] not in frozen_stages
|
|
909
908
|
}
|
|
910
|
-
|
|
909
|
+
# Always-run-only stages are surfaced in pipeline_status but do
|
|
910
|
+
# not count toward is_outdated, matching the CLI's is_stale logic.
|
|
911
|
+
is_outdated = any(
|
|
912
|
+
v != ["always changed"] for v in pipeline_status.values()
|
|
913
|
+
)
|
|
911
914
|
self.finish(
|
|
912
915
|
json.dumps(
|
|
913
916
|
{
|
|
@@ -4,6 +4,7 @@ import json
|
|
|
4
4
|
import os
|
|
5
5
|
import shutil
|
|
6
6
|
import subprocess
|
|
7
|
+
import tempfile
|
|
7
8
|
import warnings
|
|
8
9
|
from copy import deepcopy
|
|
9
10
|
from functools import cached_property
|
|
@@ -23,7 +24,9 @@ def get_git_remote_url(project_id: str, token: str) -> str:
|
|
|
23
24
|
If running against a test environment, this will use a local directory.
|
|
24
25
|
"""
|
|
25
26
|
if calkit.config.get_env() == "test":
|
|
26
|
-
return
|
|
27
|
+
return (
|
|
28
|
+
Path(tempfile.gettempdir()) / "overleaf" / project_id
|
|
29
|
+
).as_posix()
|
|
27
30
|
return f"https://git:{token}@git.overleaf.com/{project_id}"
|
|
28
31
|
|
|
29
32
|
|