calkit-python 0.41.3__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.3 → calkit_python-0.41.4}/PKG-INFO +1 -1
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/cli/check.py +1 -1
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/cli/main/core.py +6 -4
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/cli/new.py +3 -3
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/cli/scheduler.py +16 -7
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/detect.py +18 -11
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/dvc/core.py +70 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/dvc/zip.py +7 -2
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/environments.py +17 -9
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/git.py +4 -4
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/overleaf.py +4 -1
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/pipeline.py +16 -39
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/releases.py +2 -2
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/cli/main/test_core.py +25 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/cli/main/test_xr.py +5 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/cli/test_check.py +9 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/cli/test_latex.py +15 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/cli/test_new.py +5 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/cli/test_notebooks.py +9 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/cli/test_overleaf.py +5 -1
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/cli/test_scheduler.py +7 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/cli/test_update.py +5 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/dvc/test_core.py +88 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/test_conda.py +17 -2
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/test_git.py +14 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/test_install.py +13 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/.claude-plugin/marketplace.json +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/.gitignore +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/.pre-commit-config.yaml +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/.prettierignore +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/.python-version +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/.vscode/launch.json +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/.vscode/tasks.json +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/.yarnrc.yml +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/AGENTS.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/CITATION.cff +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/CODE_OF_CONDUCT.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/CONTRIBUTING.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/LICENSE +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/Makefile +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/README.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/agent-plugin/.claude-plugin/plugin.json +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/agent-plugin/skills/add-pipeline-stage/SKILL.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/agent-plugin/skills/conventions/SKILL.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/agent-plugin/skills/create-pipeline/SKILL.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/babel.config.js +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/__init__.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/__main__.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/calc.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/check.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/cli/__init__.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/cli/cloud.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/cli/config.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/cli/core.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/cli/describe.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/cli/dev.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/cli/import_.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/cli/latex.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/cli/list.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/cli/main/__init__.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/cli/main/xr.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/cli/notebooks.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/cli/office.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/cli/overleaf.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/cli/update.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/cloud.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/conda.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/config.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/core.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/datasets.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/dependencies.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/docker.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/dvc/__init__.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/fs.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/github.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/gui.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/install.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/invenio.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/julia.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/jupyter.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/jupyterlab/__init__.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/jupyterlab/routes.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/labextension/package.json +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/labextension/schemas/calkit/package.json.orig +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/labextension/schemas/calkit/plugin.json +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/labextension/static/502.9a2c5772a15466e923ef.js +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/labextension/static/695.2c41003a452d43d2b358.js +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/labextension/static/867.a42a046aa5108f54f8fb.js +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/labextension/static/909.e3f9cc3408834a7fdcc3.js +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/labextension/static/946.050af2abf7845cfbdbd2.js +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/labextension/static/946.050af2abf7845cfbdbd2.js.LICENSE.txt +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/labextension/static/b2f1c3efe70cb539d121.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/labextension/static/remoteEntry.65469af996e7a96aa983.js +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/labextension/static/style.js +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/labextension/static/third-party-licenses.json +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/licenses.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/magics.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/matlab.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/models/__init__.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/models/core.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/models/io.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/models/iteration.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/models/pipeline.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/notebooks.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/office.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/ops.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/server.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/templates/__init__.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/templates/core.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/templates/latex/__init__.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/templates/latex/article/paper.tex +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/templates/latex/core.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/templates/latex/jfm/jfm.bst +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/templates/latex/jfm/jfm.cls +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/templates/latex/jfm/lineno-FLM.sty +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/templates/latex/jfm/paper.tex +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/templates/latex/jfm/upmath.sty +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/__init__.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/cli/__init__.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/cli/main/__init__.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/cli/main/test_subprojects.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/cli/test_cloud.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/cli/test_config.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/cli/test_import.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/cli/test_list.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/dvc/__init__.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/dvc/test_zip.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/jupyterlab/__init__.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/jupyterlab/test_routes.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/models/__init__.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/models/test_iteration.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/models/test_pipeline.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/test_calc.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/test_check.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/test_cloud.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/test_core.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/test_dependencies.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/test_detect.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/test_docker.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/test_environments.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/test_fs.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/test_invenio.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/test_julia.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/test_jupyter.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/test_magics.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/test_matlab.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/test_notebooks.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/test_pipeline.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/test_releases.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/calkit/tests/test_templates.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/conftest.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/CNAME +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/ai-tools.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/apps.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/calculations.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/calkit-yaml.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/cli-reference.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/cloud-integration.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/datasets.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/dependencies.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/environments.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/examples.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/governance.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/help.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/hpc.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/img/c-to-the-k-white.svg +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/img/calkit-fragmentation-compendium.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/img/calkit-no-bg.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/img/connect-zenodo.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/img/jupyterlab/all-green.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/img/jupyterlab/collect-data-stale.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/img/jupyterlab/new-env.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/img/jupyterlab/new-notebook.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/img/jupyterlab/pipeline-badge.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/img/jupyterlab-params.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/img/plos-osi-code-2024-03.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/img/vscode-nb-params.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/index.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/installation.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/jupyterlab.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/local-server.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/notebooks.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/overleaf.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/pipeline/index.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/pipeline/manual-steps.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/pipeline/running-and-logging.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/quickstart.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/references.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/releases.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/reproducibility.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/subprojects.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/adding-latex-pub-docker.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/conda-envs.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/existing-project.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/first-project.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/github-actions.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/actions-repo-secrets.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/latex-codespaces/building-codespace.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/latex-codespaces/codespaces-secrets-2.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/latex-codespaces/editor-split.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/latex-codespaces/go-to-linked-code.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/latex-codespaces/issue-from-selection.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/latex-codespaces/new-project.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/latex-codespaces/new-pub-2.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/latex-codespaces/new-token.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/latex-codespaces/paper.tex.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/latex-codespaces/project-home-3.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/latex-codespaces/push.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/latex-codespaces/stage.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/office/anakin-excel.jpg +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/office/chart-more-rows.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/office/create-project.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/office/elsevier-research-data-guidelines.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/office/excel-chart.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/office/excel-data.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/office/insert-link-to-file.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/office/needs-clone.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/office/new-stage.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/office/phd-comics-version-control.webp +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/office/pipeline-out-of-date.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/office/status-more-rows.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/office/uncommitted-changes.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/office/untracked-data.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/office/updated-publication.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/office/word-to-pdf-stage-2.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/office/workflow-page.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/openfoam/clone.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/openfoam/create-project.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/openfoam/datasets-page.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/openfoam/figure-on-website-updated.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/openfoam/figure-on-website.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/openfoam/new-token.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/openfoam/reclone.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/openfoam/status-after-import-dataset.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/quick-actions.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/run-proc.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/vscode-slurm-notebook/create-calkit-env.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/vscode-slurm-notebook/create-inner-env.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/vscode-slurm-notebook/create-new-calkit-env.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/vscode-slurm-notebook/select-calkit-env.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/vscode-slurm-notebook/slurm-job-running.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/vscode-slurm-notebook/slurm-launch-options.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/img/vscode-slurm-notebook/starting-slurm-job.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/index.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/jupyterlab.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/latex-codespaces.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/matlab.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/notebook-pipeline.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/office.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/openfoam.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/procedures.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/tutorials/vscode-slurm-notebook.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/docs/version-control.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/flake.lock +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/flake.nix +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/install.json +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/jest.config.js +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/jupyter-config/server-config/calkit.json +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/mkdocs.yml +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/package.json +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/pyproject.toml +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/schema/plugin.json +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/scripts/generate-docs-references.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/scripts/install.ps1 +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/scripts/install.sh +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/scripts/make-calk9.sh +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/scripts/sync-docs.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/src/__tests__/useQueries.spec.ts +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/src/calkit-config.ts +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/src/cell-output-marker.ts +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/src/components/commit-dialog.tsx +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/src/components/environment-editor.tsx +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/src/components/notebook-registration.tsx +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/src/components/notebook-toolbar.tsx +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/src/components/pipeline-status-bar.tsx +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/src/components/project-info-editor.tsx +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/src/components/sidebar-settings.tsx +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/src/components/sidebar.tsx +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/src/components/stage-editor.tsx +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/src/feature-flags.ts +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/src/file-browser-menu.ts +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/src/hooks/__tests__/useQueries.test.tsx +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/src/hooks/useQueries.ts +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/src/icons.ts +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/src/index.ts +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/src/io-tracker.ts +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/src/pipeline-state.ts +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/src/queryClient.ts +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/src/request.ts +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/src/shims-mainmenu.d.ts +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/style/base.css +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/style/cell-output-marker.css +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/style/environment-editor.css +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/style/environment-selector.css +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/style/img/calkit-no-bg.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/style/index.css +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/style/index.js +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/style/notebook-toolbar.css +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/style/pipeline-status-bar.css +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/style/sidebar.css +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/test/dvc-md5-dir/osx-arm64.txt +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/test/nb-julia.ipynb +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/test/nb-params.ipynb +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/test/nb-subdir.ipynb +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/test/pipeline.ipynb +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/test/script.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/test/test-log.log +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/tsconfig.json +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/tsconfig.test.json +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/ui-tests/.gitignore +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/ui-tests/README.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/ui-tests/jupyter_server_test_config.py +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/ui-tests/package.json +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/ui-tests/playwright.config.js +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/ui-tests/tests/calkit.spec.ts +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/ui-tests/yarn.lock +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/uv.lock +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/vscode-ext/.gitignore +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/vscode-ext/.vscodeignore +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/vscode-ext/CHANGELOG.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/vscode-ext/LICENSE +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/vscode-ext/README.md +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/vscode-ext/images/calkit-no-bg.png +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/vscode-ext/package-lock.json +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/vscode-ext/package.json +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/vscode-ext/scripts/set-proposed-api.js +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/vscode-ext/src/environments.ts +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/vscode-ext/src/extension.ts +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/vscode-ext/src/notebooks.ts +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/vscode-ext/src/test/environments.test.ts +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/vscode-ext/src/test/kernel-selection.test.ts +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/vscode-ext/src/test/notebooks.test.ts +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/vscode-ext/src/types.ts +0 -0
- {calkit_python-0.41.3 → calkit_python-0.41.4}/vscode-ext/tsconfig.json +0 -0
- {calkit_python-0.41.3 → 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")
|
|
@@ -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
|
|
|
@@ -717,7 +723,7 @@ def make_env_name(path: str, all_env_names: list[str], kind: str) -> str:
|
|
|
717
723
|
str
|
|
718
724
|
A unique environment name.
|
|
719
725
|
"""
|
|
720
|
-
dirname =
|
|
726
|
+
dirname = Path(path).parent.name
|
|
721
727
|
# If this is the first env in the project, call it main
|
|
722
728
|
if not all_env_names:
|
|
723
729
|
return dirname or "main"
|
|
@@ -841,7 +847,7 @@ def env_from_name_or_path(
|
|
|
841
847
|
exists=True,
|
|
842
848
|
)
|
|
843
849
|
# Check if name_or_path is a file and detect environment type
|
|
844
|
-
env_path = name_or_path
|
|
850
|
+
env_path = _as_posix_path(name_or_path)
|
|
845
851
|
if os.path.isfile(env_path):
|
|
846
852
|
if env_path.endswith("requirements.txt"):
|
|
847
853
|
# TODO: Detect if uv is installed, and use a plain venv if not
|
|
@@ -851,9 +857,9 @@ def env_from_name_or_path(
|
|
|
851
857
|
"kind": "uv-venv",
|
|
852
858
|
"path": env_path,
|
|
853
859
|
"python": DEFAULT_PYTHON_VERSION,
|
|
854
|
-
"prefix":
|
|
855
|
-
|
|
856
|
-
),
|
|
860
|
+
"prefix": Path(env_path)
|
|
861
|
+
.parent.joinpath(".venv")
|
|
862
|
+
.as_posix(),
|
|
857
863
|
},
|
|
858
864
|
exists=False,
|
|
859
865
|
)
|
|
@@ -942,9 +948,10 @@ def env_from_name_and_or_path(
|
|
|
942
948
|
if ck_info is None:
|
|
943
949
|
ck_info = calkit.load_calkit_info()
|
|
944
950
|
envs = ck_info.get("environments", {})
|
|
951
|
+
path = _as_posix_path(path) if path else None
|
|
945
952
|
if name and name in envs:
|
|
946
953
|
env = envs[name]
|
|
947
|
-
if path and env.get("path") != path:
|
|
954
|
+
if path and _as_posix_path(env.get("path", "")) != path:
|
|
948
955
|
raise ValueError(
|
|
949
956
|
f"Environment '{name}' exists but has a different path "
|
|
950
957
|
f"('{env.get('path')}') than provided ('{path}')"
|
|
@@ -958,7 +965,7 @@ def env_from_name_and_or_path(
|
|
|
958
965
|
# Look for a sub-environment with the given name and path
|
|
959
966
|
for sub_name, sub_env in envs.items():
|
|
960
967
|
if (sub_name == sub_env_name) or (
|
|
961
|
-
path and sub_env.get("path") == path
|
|
968
|
+
path and _as_posix_path(sub_env.get("path", "")) == path
|
|
962
969
|
):
|
|
963
970
|
return EnvDetectResult(
|
|
964
971
|
name=sub_name,
|
|
@@ -995,12 +1002,13 @@ def env_from_notebook_path(
|
|
|
995
1002
|
"""
|
|
996
1003
|
if ck_info is None:
|
|
997
1004
|
ck_info = calkit.load_calkit_info()
|
|
1005
|
+
notebook_path = _as_posix_path(notebook_path)
|
|
998
1006
|
stages = ck_info.get("pipeline", {}).get("stages", {})
|
|
999
1007
|
envs = ck_info.get("environments", {})
|
|
1000
1008
|
for stage in stages.values():
|
|
1001
1009
|
if (
|
|
1002
1010
|
stage.get("kind") == "jupyter-notebook"
|
|
1003
|
-
and stage.get("notebook_path") == notebook_path
|
|
1011
|
+
and _as_posix_path(stage.get("notebook_path", "")) == notebook_path
|
|
1004
1012
|
):
|
|
1005
1013
|
env_name = stage.get("environment")
|
|
1006
1014
|
if env_name:
|
|
@@ -1008,7 +1016,7 @@ def env_from_notebook_path(
|
|
|
1008
1016
|
if env:
|
|
1009
1017
|
return EnvDetectResult(name=env_name, env=env, exists=True)
|
|
1010
1018
|
for nb in ck_info.get("notebooks", []):
|
|
1011
|
-
if nb.get("path") == notebook_path:
|
|
1019
|
+
if _as_posix_path(nb.get("path", "")) == notebook_path:
|
|
1012
1020
|
env_name = nb.get("environment")
|
|
1013
1021
|
if env_name:
|
|
1014
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
|
|
@@ -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
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"""Pipeline-related functionality."""
|
|
2
2
|
|
|
3
3
|
import itertools
|
|
4
|
-
import logging
|
|
5
4
|
import os
|
|
6
5
|
from collections.abc import Callable
|
|
7
6
|
from pathlib import Path
|
|
@@ -18,17 +17,6 @@ from calkit.models.pipeline import (
|
|
|
18
17
|
)
|
|
19
18
|
|
|
20
19
|
|
|
21
|
-
class _FrozenStageWarningFilter(logging.Filter):
|
|
22
|
-
"""Drop only DVC's "stage is frozen" status warning.
|
|
23
|
-
|
|
24
|
-
Frozen stages are intentionally hidden from Calkit status output, so this
|
|
25
|
-
warning is noise; all other ``dvc.repo.status`` diagnostics pass through.
|
|
26
|
-
"""
|
|
27
|
-
|
|
28
|
-
def filter(self, record: logging.LogRecord) -> bool:
|
|
29
|
-
return "is frozen. Its dependencies are" not in record.getMessage()
|
|
30
|
-
|
|
31
|
-
|
|
32
20
|
def _coerce_frozen(value: object) -> bool:
|
|
33
21
|
"""Interpret a raw ``frozen`` value the same way the Stage model would.
|
|
34
22
|
|
|
@@ -289,18 +277,15 @@ class StaleStage(BaseModel):
|
|
|
289
277
|
# parent-relative. Use normpath to collapse any "../" segments that
|
|
290
278
|
# arise from cross-subproject deps (e.g. sp + "../shared.txt").
|
|
291
279
|
if path_prefix:
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
]
|
|
300
|
-
modified_outputs = [
|
|
301
|
-
os.path.normpath(os.path.join(path_prefix, p))
|
|
302
|
-
for p in modified_outputs
|
|
303
|
-
]
|
|
280
|
+
|
|
281
|
+
def _prefix(p: str) -> str:
|
|
282
|
+
return Path(
|
|
283
|
+
os.path.normpath(os.path.join(path_prefix, p))
|
|
284
|
+
).as_posix()
|
|
285
|
+
|
|
286
|
+
modified_inputs = [_prefix(p) for p in modified_inputs]
|
|
287
|
+
output_paths = [_prefix(p) for p in output_paths]
|
|
288
|
+
modified_outputs = [_prefix(p) for p in modified_outputs]
|
|
304
289
|
configured_outputs = [str(path) for path in (configured_outputs or [])]
|
|
305
290
|
stale_outputs = []
|
|
306
291
|
if modified_inputs or modified_command:
|
|
@@ -641,19 +626,10 @@ def get_status(
|
|
|
641
626
|
return PipelineStatus.model_validate(result)
|
|
642
627
|
try:
|
|
643
628
|
dvc_repo = calkit.dvc.get_dvc_repo()
|
|
644
|
-
#
|
|
645
|
-
#
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
# A targeted filter is used (rather than raising the logger level)
|
|
649
|
-
# so unrelated DVC diagnostics are still emitted.
|
|
650
|
-
dvc_status_logger = logging.getLogger("dvc.repo.status")
|
|
651
|
-
frozen_filter = _FrozenStageWarningFilter()
|
|
652
|
-
dvc_status_logger.addFilter(frozen_filter)
|
|
653
|
-
try:
|
|
654
|
-
raw_status = dvc_repo.status(targets=targets)
|
|
655
|
-
finally:
|
|
656
|
-
dvc_status_logger.removeFilter(frozen_filter)
|
|
629
|
+
# calkit.dvc.core installs a filter on dvc.repo.status that drops
|
|
630
|
+
# the noisy frozen-stage warning, so the call here stays quiet.
|
|
631
|
+
raw_status = dvc_repo.status(targets=targets)
|
|
632
|
+
raw_status = calkit.dvc.status_as_posix(raw_status)
|
|
657
633
|
except Exception as e:
|
|
658
634
|
result["errors"].append(
|
|
659
635
|
"Failed to get pipeline status from DVC: "
|
|
@@ -690,6 +666,7 @@ def get_status(
|
|
|
690
666
|
try:
|
|
691
667
|
sp_dvc_repo = calkit.dvc.get_dvc_repo(sp)
|
|
692
668
|
sp_raw_status = sp_dvc_repo.status()
|
|
669
|
+
sp_raw_status = calkit.dvc.status_as_posix(sp_raw_status)
|
|
693
670
|
except Exception:
|
|
694
671
|
sp_raw_status = {}
|
|
695
672
|
if sp_raw_status:
|
|
@@ -808,7 +785,7 @@ def get_status(
|
|
|
808
785
|
)
|
|
809
786
|
# DVC reports subproject stage paths relative to the repo root
|
|
810
787
|
# (e.g., "sub1/out.txt"), but calkit.yaml stores them relative to
|
|
811
|
-
# the subproject dir ("out.txt").
|
|
788
|
+
# the subproject dir ("out.txt"). Prefix with the subproject path
|
|
812
789
|
# so configured_outputs matches DVC's reported paths.
|
|
813
790
|
raw_outputs = [
|
|
814
791
|
output.get("path", str(output))
|
|
@@ -1296,7 +1273,7 @@ def get_matrix_item_targets(
|
|
|
1296
1273
|
|
|
1297
1274
|
repo = calkit.dvc.get_dvc_repo(wdir)
|
|
1298
1275
|
prefix = stage_name + "@"
|
|
1299
|
-
items = [s for s in repo.index.stages if (s.name or "").startswith(prefix)]
|
|
1276
|
+
items = [s for s in repo.index.stages if (s.name or "").startswith(prefix)] # type: ignore
|
|
1300
1277
|
item_set = set(items)
|
|
1301
1278
|
upstreams: set = set()
|
|
1302
1279
|
for item in items:
|
|
@@ -164,7 +164,7 @@ def ls_files() -> list[str]:
|
|
|
164
164
|
for filename in files:
|
|
165
165
|
fpath = os.path.join(root, filename)
|
|
166
166
|
if os.path.isfile(fpath):
|
|
167
|
-
cache_files.append(fpath)
|
|
167
|
+
cache_files.append(Path(fpath).as_posix())
|
|
168
168
|
# Include files from unzipped dvc-zip workspace folders, which are
|
|
169
169
|
# ignored by both Git and DVC and would otherwise be missing from the
|
|
170
170
|
# release archive
|
|
@@ -185,7 +185,7 @@ def ls_files() -> list[str]:
|
|
|
185
185
|
abs_fpath = Path(root) / filename
|
|
186
186
|
if abs_fpath.is_file():
|
|
187
187
|
dvc_zip_files.append(
|
|
188
|
-
|
|
188
|
+
abs_fpath.relative_to(repo_root).as_posix()
|
|
189
189
|
)
|
|
190
190
|
elif abs_workspace.exists():
|
|
191
191
|
raise ValueError(
|