calkit-python 0.35.7__tar.gz → 0.37.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {calkit_python-0.35.7 → calkit_python-0.37.0}/.gitignore +1 -1
- calkit_python-0.37.0/.vscode/launch.json +17 -0
- calkit_python-0.37.0/.vscode/tasks.json +15 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/PKG-INFO +1 -1
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/cli/main/core.py +252 -16
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/cli/new.py +153 -30
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/cli/notebooks.py +119 -13
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/cli/update.py +127 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/core.py +6 -4
- calkit_python-0.37.0/calkit/dvc/zip.py +472 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/git.py +30 -2
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/labextension/package.json +14 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/labextension/schemas/calkit/package.json.orig +14 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/models/io.py +1 -1
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/models/pipeline.py +5 -6
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/pipeline.py +23 -6
- calkit_python-0.37.0/calkit/templates/latex/__init__.py +1 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/cli/main/test_core.py +74 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/cli/test_new.py +16 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/cli/test_notebooks.py +36 -0
- calkit_python-0.37.0/calkit/tests/cli/test_update.py +22 -0
- calkit_python-0.35.7/calkit/tests/test_dvc.py → calkit_python-0.37.0/calkit/tests/dvc/test_core.py +1 -1
- calkit_python-0.37.0/calkit/tests/dvc/test_zip.py +298 -0
- calkit_python-0.37.0/calkit/tests/models/__init__.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/test_core.py +19 -0
- calkit_python-0.37.0/calkit/tests/test_git.py +387 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/test_pipeline.py +11 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/cli-reference.md +192 -83
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/existing-project.md +6 -7
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/version-control.md +51 -5
- {calkit_python-0.35.7 → calkit_python-0.37.0}/package.json +14 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/pyproject.toml +1 -0
- calkit_python-0.37.0/vscode-ext/.gitignore +3 -0
- calkit_python-0.37.0/vscode-ext/.vscodeignore +5 -0
- calkit_python-0.37.0/vscode-ext/CHANGELOG.md +6 -0
- calkit_python-0.37.0/vscode-ext/LICENSE +19 -0
- calkit_python-0.37.0/vscode-ext/README.md +66 -0
- calkit_python-0.37.0/vscode-ext/images/calkit-no-bg.png +0 -0
- calkit_python-0.37.0/vscode-ext/package-lock.json +77 -0
- calkit_python-0.37.0/vscode-ext/package.json +138 -0
- calkit_python-0.37.0/vscode-ext/scripts/set-proposed-api.js +25 -0
- calkit_python-0.37.0/vscode-ext/src/environments.ts +224 -0
- calkit_python-0.37.0/vscode-ext/src/extension.ts +3510 -0
- calkit_python-0.37.0/vscode-ext/src/notebooks.ts +79 -0
- calkit_python-0.37.0/vscode-ext/src/test/environments.test.ts +130 -0
- calkit_python-0.37.0/vscode-ext/src/test/notebooks.test.ts +70 -0
- calkit_python-0.37.0/vscode-ext/src/types.ts +25 -0
- calkit_python-0.37.0/vscode-ext/tsconfig.json +14 -0
- calkit_python-0.35.7/calkit/tests/test_git.py +0 -199
- {calkit_python-0.35.7 → calkit_python-0.37.0}/.pre-commit-config.yaml +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/.prettierignore +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/.python-version +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/.yarnrc.yml +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/CITATION.cff +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/CODE_OF_CONDUCT.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/CONTRIBUTING.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/LICENSE +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/Makefile +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/README.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/babel.config.js +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/__init__.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/__main__.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/calc.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/check.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/cli/__init__.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/cli/check.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/cli/cloud.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/cli/config.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/cli/core.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/cli/describe.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/cli/import_.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/cli/latex.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/cli/list.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/cli/main/__init__.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/cli/main/xr.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/cli/office.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/cli/overleaf.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/cli/slurm.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/cloud.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/conda.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/config.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/datasets.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/detect.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/docker.py +0 -0
- {calkit_python-0.35.7/calkit/templates → calkit_python-0.37.0/calkit/dvc}/__init__.py +0 -0
- /calkit_python-0.35.7/calkit/dvc.py → /calkit_python-0.37.0/calkit/dvc/core.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/environments.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/fs.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/github.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/gui.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/invenio.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/julia.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/jupyter.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/jupyterlab/__init__.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/jupyterlab/routes.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/labextension/schemas/calkit/plugin.json +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/labextension/static/502.9a2c5772a15466e923ef.js +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/labextension/static/695.2c41003a452d43d2b358.js +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/labextension/static/867.a42a046aa5108f54f8fb.js +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/labextension/static/909.651be47ca47390b78a92.js +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/labextension/static/946.050af2abf7845cfbdbd2.js +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/labextension/static/946.050af2abf7845cfbdbd2.js.LICENSE.txt +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/labextension/static/b2f1c3efe70cb539d121.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/labextension/static/remoteEntry.c091821b3d7f2d287a67.js +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/labextension/static/style.js +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/labextension/static/third-party-licenses.json +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/licenses.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/magics.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/matlab.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/models/__init__.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/models/core.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/models/iteration.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/notebooks.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/office.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/ops.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/overleaf.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/releases.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/server.py +0 -0
- {calkit_python-0.35.7/calkit/templates/latex → calkit_python-0.37.0/calkit/templates}/__init__.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/templates/core.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/templates/latex/article/paper.tex +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/templates/latex/core.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/templates/latex/jfm/jfm.bst +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/templates/latex/jfm/jfm.cls +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/templates/latex/jfm/lineno-FLM.sty +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/templates/latex/jfm/paper.tex +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/templates/latex/jfm/upmath.sty +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/__init__.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/cli/__init__.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/cli/main/__init__.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/cli/main/test_xr.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/cli/test_check.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/cli/test_config.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/cli/test_import.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/cli/test_latex.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/cli/test_list.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/cli/test_overleaf.py +0 -0
- {calkit_python-0.35.7/calkit/tests/jupyterlab → calkit_python-0.37.0/calkit/tests/dvc}/__init__.py +0 -0
- {calkit_python-0.35.7/calkit/tests/models → calkit_python-0.37.0/calkit/tests/jupyterlab}/__init__.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/jupyterlab/test_routes.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/models/test_iteration.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/models/test_pipeline.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/test_calc.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/test_check.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/test_conda.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/test_detect.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/test_docker.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/test_environments.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/test_fs.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/test_invenio.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/test_julia.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/test_jupyter.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/test_magics.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/test_matlab.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/test_notebooks.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/test_releases.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/calkit/tests/test_templates.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/conftest.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/CNAME +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/apps.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/calculations.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/calkit-yaml.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/cloud-integration.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/datasets.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/dependencies.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/environments.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/examples.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/governance.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/help.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/img/c-to-the-k-white.svg +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/img/calkit-fragmentation-compendium.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/img/calkit-no-bg.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/img/connect-zenodo.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/img/jupyterlab/all-green.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/img/jupyterlab/collect-data-stale.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/img/jupyterlab/new-env.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/img/jupyterlab/new-notebook.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/img/jupyterlab/pipeline-badge.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/img/jupyterlab-params.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/img/plos-osi-code-2024-03.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/img/vscode-nb-params.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/index.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/installation.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/jupyterlab.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/local-server.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/notebooks.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/overleaf.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/pipeline/index.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/pipeline/manual-steps.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/pipeline/running-and-logging.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/pipeline/slurm.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/quickstart.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/references.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/releases.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/reproducibility.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/adding-latex-pub-docker.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/conda-envs.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/first-project.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/github-actions.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/actions-repo-secrets.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/latex-codespaces/building-codespace.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/latex-codespaces/codespaces-secrets-2.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/latex-codespaces/editor-split.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/latex-codespaces/go-to-linked-code.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/latex-codespaces/issue-from-selection.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/latex-codespaces/new-project.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/latex-codespaces/new-pub-2.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/latex-codespaces/new-token.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/latex-codespaces/paper.tex.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/latex-codespaces/project-home-3.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/latex-codespaces/push.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/latex-codespaces/stage.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/office/anakin-excel.jpg +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/office/chart-more-rows.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/office/create-project.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/office/elsevier-research-data-guidelines.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/office/excel-chart.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/office/excel-data.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/office/insert-link-to-file.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/office/needs-clone.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/office/new-stage.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/office/phd-comics-version-control.webp +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/office/pipeline-out-of-date.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/office/status-more-rows.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/office/uncommitted-changes.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/office/untracked-data.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/office/updated-publication.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/office/word-to-pdf-stage-2.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/office/workflow-page.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/openfoam/clone.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/openfoam/create-project.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/openfoam/datasets-page.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/openfoam/figure-on-website-updated.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/openfoam/figure-on-website.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/openfoam/new-token.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/openfoam/reclone.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/openfoam/status-after-import-dataset.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/quick-actions.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/img/run-proc.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/index.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/jupyterlab.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/latex-codespaces.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/matlab.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/notebook-pipeline.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/office.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/openfoam.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/docs/tutorials/procedures.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/install.json +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/jest.config.js +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/jupyter-config/server-config/calkit.json +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/mkdocs.yml +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/schema/plugin.json +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/scripts/generate-cli-reference.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/scripts/install.ps1 +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/scripts/install.sh +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/scripts/make-calk9.sh +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/scripts/sync-docs.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/src/__tests__/useQueries.spec.ts +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/src/calkit-config.ts +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/src/cell-output-marker.ts +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/src/components/commit-dialog.tsx +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/src/components/environment-editor.tsx +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/src/components/notebook-registration.tsx +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/src/components/notebook-toolbar.tsx +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/src/components/pipeline-status-bar.tsx +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/src/components/project-info-editor.tsx +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/src/components/sidebar-settings.tsx +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/src/components/sidebar.tsx +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/src/components/stage-editor.tsx +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/src/feature-flags.ts +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/src/file-browser-menu.ts +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/src/hooks/__tests__/useQueries.test.tsx +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/src/hooks/useQueries.ts +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/src/icons.ts +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/src/index.ts +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/src/io-tracker.ts +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/src/pipeline-state.ts +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/src/queryClient.ts +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/src/request.ts +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/src/shims-mainmenu.d.ts +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/style/base.css +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/style/cell-output-marker.css +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/style/environment-editor.css +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/style/environment-selector.css +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/style/img/calkit-no-bg.png +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/style/index.css +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/style/index.js +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/style/notebook-toolbar.css +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/style/pipeline-status-bar.css +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/style/sidebar.css +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/test/dvc-md5-dir/osx-arm64.txt +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/test/nb-julia.ipynb +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/test/nb-params.ipynb +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/test/nb-subdir.ipynb +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/test/pipeline.ipynb +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/test/script.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/test/test-log.log +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/tsconfig.json +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/tsconfig.test.json +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/ui-tests/.gitignore +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/ui-tests/README.md +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/ui-tests/jupyter_server_test_config.py +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/ui-tests/package.json +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/ui-tests/playwright.config.js +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/ui-tests/tests/calkit.spec.ts +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/ui-tests/yarn.lock +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/uv.lock +0 -0
- {calkit_python-0.35.7 → calkit_python-0.37.0}/yarn.lock +0 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "0.2.0",
|
|
3
|
+
"configurations": [
|
|
4
|
+
{
|
|
5
|
+
"name": "Run Calkit VS Code Extension",
|
|
6
|
+
"type": "extensionHost",
|
|
7
|
+
"request": "launch",
|
|
8
|
+
"runtimeExecutable": "${execPath}",
|
|
9
|
+
"args": [
|
|
10
|
+
"--extensionDevelopmentPath=${workspaceFolder}/vscode-ext",
|
|
11
|
+
"--enable-proposed-api=calkit.calkit-vscode"
|
|
12
|
+
],
|
|
13
|
+
"outFiles": ["${workspaceFolder}/vscode-ext/out/**/*.js"],
|
|
14
|
+
"preLaunchTask": "npm: compile (vscode-ext)"
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "2.0.0",
|
|
3
|
+
"tasks": [
|
|
4
|
+
{
|
|
5
|
+
"type": "shell",
|
|
6
|
+
"command": "npm",
|
|
7
|
+
"args": ["run", "dev:compile"],
|
|
8
|
+
"options": {
|
|
9
|
+
"cwd": "${workspaceFolder}/vscode-ext"
|
|
10
|
+
},
|
|
11
|
+
"label": "npm: compile (vscode-ext)",
|
|
12
|
+
"problemMatcher": ["$tsc"]
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
}
|
|
@@ -25,6 +25,7 @@ from git.exc import InvalidGitRepositoryError
|
|
|
25
25
|
from typing_extensions import Annotated, Optional
|
|
26
26
|
|
|
27
27
|
import calkit
|
|
28
|
+
import calkit.dvc.zip
|
|
28
29
|
import calkit.matlab
|
|
29
30
|
import calkit.pipeline
|
|
30
31
|
from calkit import (
|
|
@@ -225,6 +226,69 @@ def clone(
|
|
|
225
226
|
raise_error("Failed to pull from DVC remote(s)")
|
|
226
227
|
except Exception as e:
|
|
227
228
|
raise_error(f"Failed to pull from DVC remote(s): {e}")
|
|
229
|
+
calkit.dvc.zip.sync_all(direction="to-workspace")
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def _format_dvc_data_status(status: dict, zip_path_map: dict) -> str:
|
|
233
|
+
"""Format DVC data status, substituting zip paths with workspace paths."""
|
|
234
|
+
reverse_zip = {zip_p: ws for ws, zip_p in zip_path_map.items()}
|
|
235
|
+
color_map = {
|
|
236
|
+
"added": typer.colors.GREEN,
|
|
237
|
+
"modified": typer.colors.YELLOW,
|
|
238
|
+
"deleted": typer.colors.RED,
|
|
239
|
+
"renamed": typer.colors.CYAN,
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
def transform(path: str) -> str | None:
|
|
243
|
+
if path in reverse_zip:
|
|
244
|
+
return reverse_zip[path] + " (zipped)"
|
|
245
|
+
return path
|
|
246
|
+
|
|
247
|
+
def format_section(changes: dict, title: str) -> list[str]:
|
|
248
|
+
entries = []
|
|
249
|
+
for change_type, color in color_map.items():
|
|
250
|
+
for item in changes.get(change_type, []):
|
|
251
|
+
if isinstance(item, dict):
|
|
252
|
+
old = transform(item.get("old", ""))
|
|
253
|
+
new = transform(item.get("new", ""))
|
|
254
|
+
if old is not None and new is not None:
|
|
255
|
+
line = typer.style(
|
|
256
|
+
f" {change_type}: {old} -> {new}", fg=color
|
|
257
|
+
)
|
|
258
|
+
entries.append(line)
|
|
259
|
+
else:
|
|
260
|
+
display = transform(item)
|
|
261
|
+
if display is not None:
|
|
262
|
+
line = typer.style(
|
|
263
|
+
f" {change_type}: {display}", fg=color
|
|
264
|
+
)
|
|
265
|
+
entries.append(line)
|
|
266
|
+
if not entries:
|
|
267
|
+
return []
|
|
268
|
+
return [title] + entries
|
|
269
|
+
|
|
270
|
+
lines = []
|
|
271
|
+
lines += format_section(
|
|
272
|
+
status.get("committed", {}), "DVC committed changes:"
|
|
273
|
+
)
|
|
274
|
+
lines += format_section(
|
|
275
|
+
status.get("uncommitted", {}), "DVC uncommitted changes:"
|
|
276
|
+
)
|
|
277
|
+
not_in_cache = [transform(p) for p in status.get("not_in_cache", [])]
|
|
278
|
+
not_in_cache = [p for p in not_in_cache if p is not None]
|
|
279
|
+
if not_in_cache:
|
|
280
|
+
lines.append(typer.style("Files not in cache:", bold=True))
|
|
281
|
+
for p in not_in_cache:
|
|
282
|
+
lines.append(f" {p}")
|
|
283
|
+
not_in_remote = [transform(p) for p in status.get("not_in_remote", [])]
|
|
284
|
+
not_in_remote = [p for p in not_in_remote if p is not None]
|
|
285
|
+
if not_in_remote:
|
|
286
|
+
lines.append(typer.style("Files not in remote:", bold=True))
|
|
287
|
+
for p in not_in_remote:
|
|
288
|
+
lines.append(f" {p}")
|
|
289
|
+
if not lines:
|
|
290
|
+
return "No changes.\n"
|
|
291
|
+
return "\n".join(lines) + "\n"
|
|
228
292
|
|
|
229
293
|
|
|
230
294
|
@app.command(name="status")
|
|
@@ -249,6 +313,9 @@ def get_status(
|
|
|
249
313
|
),
|
|
250
314
|
),
|
|
251
315
|
] = None,
|
|
316
|
+
as_json: Annotated[
|
|
317
|
+
bool, typer.Option("--json", help="Output status as JSON.")
|
|
318
|
+
] = False,
|
|
252
319
|
):
|
|
253
320
|
"""View status (project, version control, and/or pipeline)."""
|
|
254
321
|
ck_info = calkit.load_calkit_info()
|
|
@@ -270,6 +337,9 @@ def get_status(
|
|
|
270
337
|
categories = valid_categories
|
|
271
338
|
pipeline_status = None
|
|
272
339
|
if "pipeline" in categories or "dvc" in categories:
|
|
340
|
+
# Sync zips so the zip files reflect current workspace state before
|
|
341
|
+
# reporting status
|
|
342
|
+
calkit.dvc.zip.sync_all(direction="to-zip")
|
|
273
343
|
pipeline_status = calkit.pipeline.get_status(
|
|
274
344
|
ck_info=ck_info,
|
|
275
345
|
targets=targets,
|
|
@@ -284,6 +354,78 @@ def get_status(
|
|
|
284
354
|
"Failed pipeline environment checks for: "
|
|
285
355
|
+ ", ".join(pipeline_status.failed_environment_checks)
|
|
286
356
|
)
|
|
357
|
+
if as_json:
|
|
358
|
+
status_dict = {}
|
|
359
|
+
if "project" in categories:
|
|
360
|
+
status = calkit.get_latest_project_status()
|
|
361
|
+
status_dict["project"] = (
|
|
362
|
+
None
|
|
363
|
+
if status is None
|
|
364
|
+
else {
|
|
365
|
+
"status": status.status,
|
|
366
|
+
"message": status.message,
|
|
367
|
+
"timestamp": status.timestamp.isoformat(),
|
|
368
|
+
}
|
|
369
|
+
)
|
|
370
|
+
if "git" in categories:
|
|
371
|
+
try:
|
|
372
|
+
repo = git.Repo()
|
|
373
|
+
changed_files = calkit.git.get_changed_files(repo=repo)
|
|
374
|
+
staged_files = calkit.git.get_staged_files(repo=repo)
|
|
375
|
+
untracked_files = calkit.git.get_untracked_files(repo=repo)
|
|
376
|
+
if targets:
|
|
377
|
+
target_prefixes = [
|
|
378
|
+
Path(target).as_posix().rstrip("/")
|
|
379
|
+
for target in targets
|
|
380
|
+
]
|
|
381
|
+
|
|
382
|
+
def _matches_target(path: str) -> bool:
|
|
383
|
+
path = Path(path).as_posix()
|
|
384
|
+
return any(
|
|
385
|
+
path == prefix or path.startswith(prefix + "/")
|
|
386
|
+
for prefix in target_prefixes
|
|
387
|
+
)
|
|
388
|
+
|
|
389
|
+
changed_files = [
|
|
390
|
+
path for path in changed_files if _matches_target(path)
|
|
391
|
+
]
|
|
392
|
+
staged_files = [
|
|
393
|
+
path for path in staged_files if _matches_target(path)
|
|
394
|
+
]
|
|
395
|
+
untracked_files = [
|
|
396
|
+
path
|
|
397
|
+
for path in untracked_files
|
|
398
|
+
if _matches_target(path)
|
|
399
|
+
]
|
|
400
|
+
status_dict["git"] = {
|
|
401
|
+
"branch": None
|
|
402
|
+
if repo.head.is_detached
|
|
403
|
+
else repo.active_branch.name,
|
|
404
|
+
"is_dirty": repo.is_dirty(untracked_files=True),
|
|
405
|
+
"changed_files": changed_files,
|
|
406
|
+
"staged_files": staged_files,
|
|
407
|
+
"untracked_files": untracked_files,
|
|
408
|
+
}
|
|
409
|
+
except InvalidGitRepositoryError:
|
|
410
|
+
status_dict["git"] = {"error": "Not a Git repository"}
|
|
411
|
+
if "dvc" in categories:
|
|
412
|
+
try:
|
|
413
|
+
dvc_repo = calkit.dvc.get_dvc_repo()
|
|
414
|
+
data_status = dvc_repo.data_status()
|
|
415
|
+
if isinstance(data_status, dict):
|
|
416
|
+
data_status.pop("git", None)
|
|
417
|
+
status_dict["dvc"] = data_status
|
|
418
|
+
except Exception as e:
|
|
419
|
+
status_dict["dvc"] = {"error": f"{e.__class__.__name__}: {e}"}
|
|
420
|
+
if "pipeline" in categories or "dvc" in categories:
|
|
421
|
+
if pipeline_status is None:
|
|
422
|
+
status_dict["pipeline"] = None
|
|
423
|
+
else:
|
|
424
|
+
status_dict["pipeline"] = pipeline_status.model_dump(
|
|
425
|
+
mode="json"
|
|
426
|
+
)
|
|
427
|
+
print(json.dumps(status_dict, indent=2, default=str))
|
|
428
|
+
return
|
|
287
429
|
if "project" in categories:
|
|
288
430
|
print_sep("Project")
|
|
289
431
|
# Print latest status
|
|
@@ -313,37 +455,49 @@ def get_status(
|
|
|
313
455
|
typer.echo()
|
|
314
456
|
if "dvc" in categories:
|
|
315
457
|
print_sep("DVC")
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
458
|
+
try:
|
|
459
|
+
get_dvc_repo()
|
|
460
|
+
except Exception:
|
|
461
|
+
typer.echo("This is not a DVC repository.\n")
|
|
462
|
+
else:
|
|
463
|
+
zip_path_map = calkit.dvc.zip.get_zip_path_map()
|
|
464
|
+
dvc_repo = get_dvc_repo()
|
|
465
|
+
raw = dict(dvc_repo.data_status())
|
|
466
|
+
raw.pop("git", None)
|
|
467
|
+
typer.echo(_format_dvc_data_status(raw, zip_path_map))
|
|
321
468
|
if "pipeline" in categories or "dvc" in categories:
|
|
322
469
|
print_sep("Pipeline")
|
|
323
470
|
# Nicely format the results from pipeline status
|
|
324
471
|
if pipeline_status and pipeline_status.errors:
|
|
325
|
-
|
|
472
|
+
warn("Pipeline status unavailable due to errors.")
|
|
473
|
+
return
|
|
474
|
+
if pipeline_status and not pipeline_status.has_pipeline:
|
|
475
|
+
typer.echo("This project has no pipeline.")
|
|
476
|
+
return
|
|
326
477
|
elif pipeline_status and pipeline_status.is_stale:
|
|
478
|
+
typer.echo("Stale stages:")
|
|
327
479
|
for stage_name in pipeline_status.stale_stage_names:
|
|
328
480
|
stale_stage = pipeline_status.stale_stages.get(stage_name)
|
|
329
481
|
if stale_stage is None:
|
|
330
482
|
continue
|
|
331
|
-
typer.echo(f"{typer.style(stage_name, fg='yellow')}:")
|
|
483
|
+
typer.echo(f" {typer.style(stage_name, fg='yellow')}:")
|
|
484
|
+
if stale_stage.modified_command:
|
|
485
|
+
typer.echo(" modified command")
|
|
332
486
|
# Show stale outputs for this stage
|
|
333
487
|
if stale_stage.stale_outputs:
|
|
334
|
-
typer.echo("
|
|
488
|
+
typer.echo(" stale outputs:")
|
|
335
489
|
for output_path in stale_stage.stale_outputs:
|
|
336
|
-
typer.echo(f"
|
|
490
|
+
typer.echo(f" {output_path}")
|
|
337
491
|
# Show modified outputs from this stage
|
|
338
492
|
if stale_stage.modified_outputs:
|
|
339
|
-
typer.echo("
|
|
493
|
+
typer.echo(" modified outputs:")
|
|
340
494
|
for output_path in stale_stage.modified_outputs:
|
|
341
|
-
typer.echo(f"
|
|
495
|
+
typer.echo(f" {output_path}")
|
|
342
496
|
# Show modified inputs making the stage stale
|
|
343
497
|
if stale_stage.modified_inputs:
|
|
344
|
-
typer.echo("
|
|
498
|
+
typer.echo(" modified inputs:")
|
|
345
499
|
for input_path in stale_stage.modified_inputs:
|
|
346
|
-
typer.echo(f"
|
|
500
|
+
typer.echo(f" {input_path}")
|
|
347
501
|
elif pipeline_status:
|
|
348
502
|
typer.echo("Pipeline is up to date.")
|
|
349
503
|
|
|
@@ -395,7 +549,9 @@ def add(
|
|
|
395
549
|
to: Annotated[
|
|
396
550
|
str | None,
|
|
397
551
|
typer.Option(
|
|
398
|
-
"--to",
|
|
552
|
+
"--to",
|
|
553
|
+
"-t",
|
|
554
|
+
help="System with which to add (git, dvc, or dvc-zip).",
|
|
399
555
|
),
|
|
400
556
|
] = None,
|
|
401
557
|
):
|
|
@@ -421,7 +577,7 @@ def add(
|
|
|
421
577
|
raise_error(
|
|
422
578
|
"Cannot auto-generate commit message for more than one path"
|
|
423
579
|
)
|
|
424
|
-
if to is not None and to not in ["git", "dvc"]:
|
|
580
|
+
if to is not None and to not in ["git", "dvc", "dvc-zip"]:
|
|
425
581
|
raise_error(f"Invalid option for 'to': {to}")
|
|
426
582
|
try:
|
|
427
583
|
repo = git.Repo()
|
|
@@ -464,6 +620,10 @@ def add(
|
|
|
464
620
|
subprocess.call(["git", "add"] + paths)
|
|
465
621
|
elif to == "dvc":
|
|
466
622
|
run_dvc_command(["add"] + paths)
|
|
623
|
+
elif to == "dvc-zip":
|
|
624
|
+
for path in paths:
|
|
625
|
+
typer.echo(f"Adding {path} as a DVC zip")
|
|
626
|
+
calkit.dvc.zip.add(path)
|
|
467
627
|
else:
|
|
468
628
|
raise_error(f"Invalid option for 'to': {to}")
|
|
469
629
|
else:
|
|
@@ -512,7 +672,14 @@ def add(
|
|
|
512
672
|
d.a_path for d in repo.index.diff(None) if d.a_path is not None
|
|
513
673
|
]:
|
|
514
674
|
paths.append(changed_file)
|
|
675
|
+
zip_path_map = calkit.dvc.zip.get_zip_path_map()
|
|
515
676
|
for path in paths:
|
|
677
|
+
# Check if this path is already registered as a zip
|
|
678
|
+
posix_path = Path(path).as_posix()
|
|
679
|
+
if posix_path in zip_path_map:
|
|
680
|
+
typer.echo(f"Adding {path} via DVC zip")
|
|
681
|
+
calkit.dvc.zip.add(path)
|
|
682
|
+
continue
|
|
516
683
|
# Detect if this file should be tracked with Git or DVC
|
|
517
684
|
# First see if it's in Git
|
|
518
685
|
if repo.git.ls_files(path):
|
|
@@ -528,6 +695,12 @@ def add(
|
|
|
528
695
|
elif os.path.splitext(path)[-1] in DVC_EXTENSIONS:
|
|
529
696
|
typer.echo(f"Adding {path} to DVC per its extension")
|
|
530
697
|
run_dvc_command(["add", path])
|
|
698
|
+
elif calkit.dvc.zip.is_zip_candidate(path):
|
|
699
|
+
typer.echo(
|
|
700
|
+
f"Adding {path} as a DVC zip "
|
|
701
|
+
"(large directory of small files)"
|
|
702
|
+
)
|
|
703
|
+
calkit.dvc.zip.add(path)
|
|
531
704
|
elif calkit.get_size(path) > DVC_SIZE_THRESH_BYTES:
|
|
532
705
|
typer.echo(
|
|
533
706
|
f"Adding {path} to DVC since it's greater than 1 MB"
|
|
@@ -763,6 +936,7 @@ def pull(
|
|
|
763
936
|
result = run_dvc_command(["pull"] + dvc_args)
|
|
764
937
|
if result != 0:
|
|
765
938
|
raise_error("DVC pull failed")
|
|
939
|
+
calkit.dvc.zip.sync_all(direction="to-workspace")
|
|
766
940
|
|
|
767
941
|
|
|
768
942
|
@app.command(name="push")
|
|
@@ -1098,6 +1272,7 @@ def run(
|
|
|
1098
1272
|
import dvc.ui
|
|
1099
1273
|
from dvc.cli import main as dvc_cli_main
|
|
1100
1274
|
|
|
1275
|
+
import calkit.dvc.zip
|
|
1101
1276
|
import calkit.environments
|
|
1102
1277
|
import calkit.pipeline
|
|
1103
1278
|
from calkit.cli.overleaf import sync as overleaf_sync
|
|
@@ -1297,10 +1472,38 @@ def run(
|
|
|
1297
1472
|
dvc.ui.ui.write = lambda *args, **kwargs: None
|
|
1298
1473
|
res = dvc_cli_main(["repro"] + args)
|
|
1299
1474
|
failed = res != 0
|
|
1300
|
-
# Parse log to get timing
|
|
1475
|
+
# Parse log to get timing and which stages ran
|
|
1301
1476
|
with open(log_fpath, "r") as f:
|
|
1302
1477
|
log_content = f.read()
|
|
1303
1478
|
stage_run_info = _stage_run_info_from_log_content(log_content)
|
|
1479
|
+
# Zip dvc-zip outputs for stages that actually ran
|
|
1480
|
+
if stage_run_info:
|
|
1481
|
+
from calkit.models.io import PathOutput
|
|
1482
|
+
from calkit.models.pipeline import Pipeline
|
|
1483
|
+
|
|
1484
|
+
ck_info = calkit.load_calkit_info()
|
|
1485
|
+
pipeline_cfg = ck_info.get("pipeline", {})
|
|
1486
|
+
if pipeline_cfg:
|
|
1487
|
+
try:
|
|
1488
|
+
ck_pipeline = Pipeline.model_validate(pipeline_cfg)
|
|
1489
|
+
zip_input_paths = []
|
|
1490
|
+
for stage_name in stage_run_info:
|
|
1491
|
+
stage = ck_pipeline.stages.get(stage_name)
|
|
1492
|
+
if stage is None:
|
|
1493
|
+
continue
|
|
1494
|
+
for out in stage.outputs:
|
|
1495
|
+
if (
|
|
1496
|
+
isinstance(out, PathOutput)
|
|
1497
|
+
and out.storage == "dvc-zip"
|
|
1498
|
+
):
|
|
1499
|
+
zip_input_paths.append(out.path)
|
|
1500
|
+
if zip_input_paths:
|
|
1501
|
+
calkit.dvc.zip.sync_some(
|
|
1502
|
+
zip_input_paths, direction="to-zip"
|
|
1503
|
+
)
|
|
1504
|
+
except Exception:
|
|
1505
|
+
# Fall back to syncing all zips if pipeline parsing fails
|
|
1506
|
+
calkit.dvc.zip.sync_all(direction="to-zip")
|
|
1304
1507
|
# Close logger file handler to prevent permissions issues if deleting
|
|
1305
1508
|
dvc.log.logger.removeHandler(file_handler)
|
|
1306
1509
|
file_handler.close()
|
|
@@ -2166,6 +2369,39 @@ def switch_branch(name: Annotated[str, typer.Argument(help="Branch name.")]):
|
|
|
2166
2369
|
else:
|
|
2167
2370
|
cmd = [name]
|
|
2168
2371
|
repo.git.checkout(cmd)
|
|
2372
|
+
# After switching branches, DVC-tracked zips may have changed; check out
|
|
2373
|
+
# the new branch's DVC data and unzip to the workspace
|
|
2374
|
+
run_dvc_command(["checkout"])
|
|
2375
|
+
calkit.dvc.zip.sync_all(direction="to-workspace")
|
|
2376
|
+
|
|
2377
|
+
|
|
2378
|
+
@app.command(name="stash")
|
|
2379
|
+
def stash(
|
|
2380
|
+
pop: Annotated[
|
|
2381
|
+
bool, typer.Option("--pop", help="Pop the most recent stash.")
|
|
2382
|
+
] = False,
|
|
2383
|
+
):
|
|
2384
|
+
"""Stash or restore workspace changes including dvc-zip tracked dirs.
|
|
2385
|
+
|
|
2386
|
+
Without --pop: zips any modified workspace dirs into the DVC cache, then
|
|
2387
|
+
git-stashes (saving the updated .dvc files), checks out the committed DVC
|
|
2388
|
+
state, and unzips it to the workspace.
|
|
2389
|
+
|
|
2390
|
+
With --pop: pops the git stash (restoring the saved .dvc files), checks
|
|
2391
|
+
out the stashed DVC state, and unzips it to the workspace.
|
|
2392
|
+
"""
|
|
2393
|
+
if pop:
|
|
2394
|
+
subprocess.check_call(["git", "stash", "pop"])
|
|
2395
|
+
run_dvc_command(["checkout"])
|
|
2396
|
+
calkit.dvc.zip.sync_all(direction="to-workspace")
|
|
2397
|
+
else:
|
|
2398
|
+
# Zip any modified workspace dirs so their current state is in the DVC
|
|
2399
|
+
# cache (the updated .dvc file will be captured by git stash)
|
|
2400
|
+
calkit.dvc.zip.sync_all(direction="to-zip")
|
|
2401
|
+
subprocess.check_call(["git", "stash"])
|
|
2402
|
+
# Restore the committed zip versions and unzip them
|
|
2403
|
+
run_dvc_command(["checkout"])
|
|
2404
|
+
calkit.dvc.zip.sync_all(direction="to-workspace")
|
|
2169
2405
|
|
|
2170
2406
|
|
|
2171
2407
|
@app.command(
|
|
@@ -1333,6 +1333,75 @@ def new_uv_env(
|
|
|
1333
1333
|
repo.git.commit(["-m", f"Add uv environment {name}"])
|
|
1334
1334
|
|
|
1335
1335
|
|
|
1336
|
+
@new_app.command("slurm-env")
|
|
1337
|
+
def new_slurm_env(
|
|
1338
|
+
name: Annotated[
|
|
1339
|
+
str, typer.Option("--name", "-n", help="Environment name.")
|
|
1340
|
+
],
|
|
1341
|
+
host: Annotated[
|
|
1342
|
+
str,
|
|
1343
|
+
typer.Option("--host", help="Host where SLURM commands should run."),
|
|
1344
|
+
] = "localhost",
|
|
1345
|
+
default_options: Annotated[
|
|
1346
|
+
list[str],
|
|
1347
|
+
typer.Option(
|
|
1348
|
+
"--default-option",
|
|
1349
|
+
help=(
|
|
1350
|
+
"Default sbatch/srun option string (for example --gpus=1). "
|
|
1351
|
+
"Repeat for multiple options."
|
|
1352
|
+
),
|
|
1353
|
+
),
|
|
1354
|
+
] = [],
|
|
1355
|
+
description: Annotated[
|
|
1356
|
+
str | None, typer.Option("--description", help="Description.")
|
|
1357
|
+
] = None,
|
|
1358
|
+
overwrite: Annotated[
|
|
1359
|
+
bool,
|
|
1360
|
+
typer.Option(
|
|
1361
|
+
"--overwrite",
|
|
1362
|
+
"-f",
|
|
1363
|
+
help="Overwrite any existing environment with this name.",
|
|
1364
|
+
),
|
|
1365
|
+
] = False,
|
|
1366
|
+
no_commit: Annotated[
|
|
1367
|
+
bool, typer.Option("--no-commit", help="Do not commit changes.")
|
|
1368
|
+
] = False,
|
|
1369
|
+
):
|
|
1370
|
+
"""Create a new SLURM environment."""
|
|
1371
|
+
host = host.strip()
|
|
1372
|
+
if not host:
|
|
1373
|
+
raise_error("Host is required")
|
|
1374
|
+
ck_info = calkit.load_calkit_info()
|
|
1375
|
+
envs = ck_info.get("environments", {})
|
|
1376
|
+
if isinstance(envs, list):
|
|
1377
|
+
typer.echo("Converting environments from list to dict")
|
|
1378
|
+
envs = {env.pop("name"): env for env in envs}
|
|
1379
|
+
if name in envs and not overwrite:
|
|
1380
|
+
raise_error(
|
|
1381
|
+
f"Environment with name {name} already exists "
|
|
1382
|
+
"(use -f to overwrite)"
|
|
1383
|
+
)
|
|
1384
|
+
normalized_default_options = [
|
|
1385
|
+
opt.strip() for opt in default_options if opt.strip()
|
|
1386
|
+
]
|
|
1387
|
+
env = {"kind": "slurm", "host": host}
|
|
1388
|
+
if normalized_default_options:
|
|
1389
|
+
env["default_options"] = normalized_default_options # type: ignore
|
|
1390
|
+
if description is not None:
|
|
1391
|
+
env["description"] = description
|
|
1392
|
+
envs[name] = env
|
|
1393
|
+
ck_info["environments"] = envs
|
|
1394
|
+
with open("calkit.yaml", "w") as f:
|
|
1395
|
+
ryaml.dump(ck_info, f)
|
|
1396
|
+
if not no_commit:
|
|
1397
|
+
repo = git.Repo()
|
|
1398
|
+
repo.git.add("calkit.yaml")
|
|
1399
|
+
if repo.git.diff(["--staged", "calkit.yaml"]):
|
|
1400
|
+
repo.git.commit(
|
|
1401
|
+
["calkit.yaml", "-m", f"Add SLURM environment {name}"]
|
|
1402
|
+
)
|
|
1403
|
+
|
|
1404
|
+
|
|
1336
1405
|
@new_app.command("uv-venv")
|
|
1337
1406
|
def new_uv_venv(
|
|
1338
1407
|
name: Annotated[
|
|
@@ -1615,21 +1684,29 @@ def new_pixi_env(
|
|
|
1615
1684
|
@new_app.command("julia-env")
|
|
1616
1685
|
def new_julia_env(
|
|
1617
1686
|
packages: Annotated[
|
|
1618
|
-
list[str],
|
|
1619
|
-
typer.Argument(
|
|
1620
|
-
|
|
1687
|
+
list[str] | None,
|
|
1688
|
+
typer.Argument(
|
|
1689
|
+
help="Optional packages to include in the environment."
|
|
1690
|
+
),
|
|
1691
|
+
] = None,
|
|
1621
1692
|
name: Annotated[
|
|
1622
1693
|
str, typer.Option("--name", "-n", help="Environment name.")
|
|
1623
|
-
],
|
|
1694
|
+
] = "main",
|
|
1624
1695
|
path: Annotated[
|
|
1625
|
-
str
|
|
1626
|
-
|
|
1696
|
+
str | None,
|
|
1697
|
+
typer.Option("--path", help="Path for Project.toml file."),
|
|
1698
|
+
] = None,
|
|
1627
1699
|
description: Annotated[
|
|
1628
1700
|
str | None, typer.Option("--description", help="Description.")
|
|
1629
1701
|
] = None,
|
|
1630
1702
|
julia_version: Annotated[
|
|
1631
|
-
str
|
|
1632
|
-
|
|
1703
|
+
str | None,
|
|
1704
|
+
typer.Option(
|
|
1705
|
+
"--julia",
|
|
1706
|
+
"-j",
|
|
1707
|
+
help="Julia version. Auto-detected if not supplied.",
|
|
1708
|
+
),
|
|
1709
|
+
] = None,
|
|
1633
1710
|
overwrite: Annotated[
|
|
1634
1711
|
bool,
|
|
1635
1712
|
typer.Option(
|
|
@@ -1641,8 +1718,17 @@ def new_julia_env(
|
|
|
1641
1718
|
no_commit: Annotated[
|
|
1642
1719
|
bool, typer.Option("--no-commit", help="Do not commit changes.")
|
|
1643
1720
|
] = False,
|
|
1721
|
+
no_check: Annotated[
|
|
1722
|
+
bool,
|
|
1723
|
+
typer.Option(
|
|
1724
|
+
"--no-check",
|
|
1725
|
+
help="Do not check environment is up-to-date after creation.",
|
|
1726
|
+
),
|
|
1727
|
+
] = False,
|
|
1644
1728
|
):
|
|
1645
|
-
"""Create a new Julia environment."""
|
|
1729
|
+
"""Create a new Julia environment or add an existing one to calkit.yaml."""
|
|
1730
|
+
if path is None:
|
|
1731
|
+
path = "Project.toml"
|
|
1646
1732
|
if not os.path.basename(path) == "Project.toml":
|
|
1647
1733
|
raise_error(
|
|
1648
1734
|
"Julia environment paths must point to a Project.toml file"
|
|
@@ -1665,27 +1751,57 @@ def new_julia_env(
|
|
|
1665
1751
|
f"Environment with name {name} already exists "
|
|
1666
1752
|
"(use -f to overwrite)"
|
|
1667
1753
|
)
|
|
1668
|
-
#
|
|
1754
|
+
# Detect Julia version if not supplied
|
|
1755
|
+
if julia_version is None:
|
|
1756
|
+
try:
|
|
1757
|
+
julia_version = calkit.julia.get_version()
|
|
1758
|
+
except ValueError as e:
|
|
1759
|
+
raise_error(
|
|
1760
|
+
f"Failed to detect Julia version: {e}. "
|
|
1761
|
+
"Use --julia to specify a version."
|
|
1762
|
+
)
|
|
1763
|
+
# Check for duplicate Julia environments with same path and version
|
|
1764
|
+
for env_name, env_config in envs.items():
|
|
1765
|
+
if (
|
|
1766
|
+
env_config.get("kind") == "julia"
|
|
1767
|
+
and env_config.get("path") == path
|
|
1768
|
+
and env_config.get("julia") == julia_version
|
|
1769
|
+
):
|
|
1770
|
+
raise_error(
|
|
1771
|
+
f"Julia environment '{env_name}' already exists with path "
|
|
1772
|
+
f"'{path}' and version '{julia_version}'; "
|
|
1773
|
+
f"Use a different path, version, or --overwrite to replace it"
|
|
1774
|
+
)
|
|
1669
1775
|
env_dir = os.path.dirname(path)
|
|
1670
1776
|
if env_dir:
|
|
1671
1777
|
os.makedirs(env_dir, exist_ok=True)
|
|
1672
1778
|
else:
|
|
1673
1779
|
env_dir = "."
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1780
|
+
project_exists = os.path.isfile(path)
|
|
1781
|
+
created_project_file = False
|
|
1782
|
+
# If packages are provided, initialize via Julia/Pkg.
|
|
1783
|
+
if packages:
|
|
1784
|
+
# First make sure the Julia version is installed
|
|
1785
|
+
cmd = ["juliaup", "add", julia_version]
|
|
1786
|
+
try:
|
|
1787
|
+
subprocess.run(cmd, check=True)
|
|
1788
|
+
except subprocess.CalledProcessError:
|
|
1789
|
+
raise_error(f"Failed to install Julia version {julia_version}")
|
|
1790
|
+
cmd = ["julia", f"+{julia_version}", f"--project={env_dir}", "-e"]
|
|
1791
|
+
install_cmd = f'using Pkg; Pkg.activate("{env_dir}");'
|
|
1792
|
+
for package in packages or []:
|
|
1793
|
+
install_cmd += f' Pkg.add("{package}");'
|
|
1794
|
+
cmd.append(install_cmd)
|
|
1795
|
+
try:
|
|
1796
|
+
subprocess.run(cmd, check=True)
|
|
1797
|
+
except subprocess.CalledProcessError:
|
|
1798
|
+
raise_error("Failed to create new Julia environment")
|
|
1799
|
+
elif not project_exists:
|
|
1800
|
+
# Allow creating a Julia environment scaffold without requiring Julia
|
|
1801
|
+
# tooling at creation time. IJulia or other packages can be added later.
|
|
1802
|
+
with open(path, "w") as f:
|
|
1803
|
+
f.write("[deps]\n")
|
|
1804
|
+
created_project_file = True
|
|
1689
1805
|
typer.echo("Adding environment to calkit.yaml")
|
|
1690
1806
|
env = dict(kind="julia", path=path, julia=julia_version)
|
|
1691
1807
|
if description is not None:
|
|
@@ -1694,11 +1810,18 @@ def new_julia_env(
|
|
|
1694
1810
|
ck_info["environments"] = envs
|
|
1695
1811
|
with open("calkit.yaml", "w") as f:
|
|
1696
1812
|
ryaml.dump(ck_info, f)
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1813
|
+
if not no_commit:
|
|
1814
|
+
repo.git.add("calkit.yaml")
|
|
1815
|
+
if packages or created_project_file:
|
|
1816
|
+
repo.git.add(path)
|
|
1817
|
+
if packages:
|
|
1818
|
+
repo.git.add(os.path.join(env_dir, "Manifest.toml"))
|
|
1819
|
+
if not no_check and packages:
|
|
1820
|
+
env_lock_fpath = check_environment(env_name=name)
|
|
1821
|
+
if env_lock_fpath is not None:
|
|
1822
|
+
repo.git.add(env_lock_fpath)
|
|
1823
|
+
if repo.git.diff("--staged"):
|
|
1824
|
+
repo.git.commit(["-m", f"Add Julia env {name}"])
|
|
1702
1825
|
|
|
1703
1826
|
|
|
1704
1827
|
@new_app.command("renv")
|