calkit-python 0.36.0__tar.gz → 0.37.1__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.
Files changed (308) hide show
  1. {calkit_python-0.36.0 → calkit_python-0.37.1}/PKG-INFO +1 -1
  2. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/cli/config.py +8 -1
  3. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/cli/main/core.py +175 -18
  4. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/cli/new.py +1 -3
  5. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/cli/update.py +1 -3
  6. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/core.py +6 -4
  7. calkit_python-0.36.0/calkit/dvc.py → calkit_python-0.37.1/calkit/dvc/core.py +47 -11
  8. calkit_python-0.37.1/calkit/dvc/zip.py +472 -0
  9. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/git.py +30 -2
  10. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/models/io.py +1 -1
  11. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/models/pipeline.py +5 -6
  12. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/pipeline.py +53 -24
  13. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/releases.py +15 -10
  14. calkit_python-0.37.1/calkit/templates/latex/__init__.py +1 -0
  15. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/cli/main/test_core.py +74 -0
  16. calkit_python-0.36.0/calkit/tests/test_dvc.py → calkit_python-0.37.1/calkit/tests/dvc/test_core.py +70 -1
  17. calkit_python-0.37.1/calkit/tests/dvc/test_zip.py +298 -0
  18. calkit_python-0.37.1/calkit/tests/models/__init__.py +0 -0
  19. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/test_core.py +19 -0
  20. calkit_python-0.37.1/calkit/tests/test_git.py +387 -0
  21. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/test_pipeline.py +11 -0
  22. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/test_releases.py +6 -6
  23. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/cli-reference.md +788 -751
  24. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/existing-project.md +6 -7
  25. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/version-control.md +51 -5
  26. {calkit_python-0.36.0 → calkit_python-0.37.1}/scripts/generate-cli-reference.py +174 -36
  27. calkit_python-0.36.0/calkit/tests/test_git.py +0 -199
  28. {calkit_python-0.36.0 → calkit_python-0.37.1}/.gitignore +0 -0
  29. {calkit_python-0.36.0 → calkit_python-0.37.1}/.pre-commit-config.yaml +0 -0
  30. {calkit_python-0.36.0 → calkit_python-0.37.1}/.prettierignore +0 -0
  31. {calkit_python-0.36.0 → calkit_python-0.37.1}/.python-version +0 -0
  32. {calkit_python-0.36.0 → calkit_python-0.37.1}/.vscode/launch.json +0 -0
  33. {calkit_python-0.36.0 → calkit_python-0.37.1}/.vscode/tasks.json +0 -0
  34. {calkit_python-0.36.0 → calkit_python-0.37.1}/.yarnrc.yml +0 -0
  35. {calkit_python-0.36.0 → calkit_python-0.37.1}/CITATION.cff +0 -0
  36. {calkit_python-0.36.0 → calkit_python-0.37.1}/CODE_OF_CONDUCT.md +0 -0
  37. {calkit_python-0.36.0 → calkit_python-0.37.1}/CONTRIBUTING.md +0 -0
  38. {calkit_python-0.36.0 → calkit_python-0.37.1}/LICENSE +0 -0
  39. {calkit_python-0.36.0 → calkit_python-0.37.1}/Makefile +0 -0
  40. {calkit_python-0.36.0 → calkit_python-0.37.1}/README.md +0 -0
  41. {calkit_python-0.36.0 → calkit_python-0.37.1}/babel.config.js +0 -0
  42. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/__init__.py +0 -0
  43. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/__main__.py +0 -0
  44. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/calc.py +0 -0
  45. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/check.py +0 -0
  46. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/cli/__init__.py +0 -0
  47. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/cli/check.py +0 -0
  48. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/cli/cloud.py +0 -0
  49. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/cli/core.py +0 -0
  50. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/cli/describe.py +0 -0
  51. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/cli/import_.py +0 -0
  52. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/cli/latex.py +0 -0
  53. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/cli/list.py +0 -0
  54. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/cli/main/__init__.py +0 -0
  55. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/cli/main/xr.py +0 -0
  56. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/cli/notebooks.py +0 -0
  57. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/cli/office.py +0 -0
  58. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/cli/overleaf.py +0 -0
  59. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/cli/slurm.py +0 -0
  60. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/cloud.py +0 -0
  61. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/conda.py +0 -0
  62. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/config.py +0 -0
  63. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/datasets.py +0 -0
  64. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/detect.py +0 -0
  65. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/docker.py +0 -0
  66. {calkit_python-0.36.0/calkit/templates → calkit_python-0.37.1/calkit/dvc}/__init__.py +0 -0
  67. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/environments.py +0 -0
  68. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/fs.py +0 -0
  69. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/github.py +0 -0
  70. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/gui.py +0 -0
  71. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/invenio.py +0 -0
  72. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/julia.py +0 -0
  73. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/jupyter.py +0 -0
  74. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/jupyterlab/__init__.py +0 -0
  75. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/jupyterlab/routes.py +0 -0
  76. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/labextension/package.json +0 -0
  77. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/labextension/schemas/calkit/package.json.orig +0 -0
  78. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/labextension/schemas/calkit/plugin.json +0 -0
  79. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/labextension/static/502.9a2c5772a15466e923ef.js +0 -0
  80. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/labextension/static/695.2c41003a452d43d2b358.js +0 -0
  81. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/labextension/static/867.a42a046aa5108f54f8fb.js +0 -0
  82. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/labextension/static/909.651be47ca47390b78a92.js +0 -0
  83. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/labextension/static/946.050af2abf7845cfbdbd2.js +0 -0
  84. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/labextension/static/946.050af2abf7845cfbdbd2.js.LICENSE.txt +0 -0
  85. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/labextension/static/b2f1c3efe70cb539d121.png +0 -0
  86. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/labextension/static/remoteEntry.c091821b3d7f2d287a67.js +0 -0
  87. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/labextension/static/style.js +0 -0
  88. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/labextension/static/third-party-licenses.json +0 -0
  89. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/licenses.py +0 -0
  90. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/magics.py +0 -0
  91. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/matlab.py +0 -0
  92. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/models/__init__.py +0 -0
  93. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/models/core.py +0 -0
  94. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/models/iteration.py +0 -0
  95. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/notebooks.py +0 -0
  96. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/office.py +0 -0
  97. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/ops.py +0 -0
  98. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/overleaf.py +0 -0
  99. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/server.py +0 -0
  100. {calkit_python-0.36.0/calkit/templates/latex → calkit_python-0.37.1/calkit/templates}/__init__.py +0 -0
  101. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/templates/core.py +0 -0
  102. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/templates/latex/article/paper.tex +0 -0
  103. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/templates/latex/core.py +0 -0
  104. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/templates/latex/jfm/jfm.bst +0 -0
  105. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/templates/latex/jfm/jfm.cls +0 -0
  106. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/templates/latex/jfm/lineno-FLM.sty +0 -0
  107. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/templates/latex/jfm/paper.tex +0 -0
  108. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/templates/latex/jfm/upmath.sty +0 -0
  109. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/__init__.py +0 -0
  110. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/cli/__init__.py +0 -0
  111. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/cli/main/__init__.py +0 -0
  112. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/cli/main/test_xr.py +0 -0
  113. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/cli/test_check.py +0 -0
  114. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/cli/test_config.py +0 -0
  115. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/cli/test_import.py +0 -0
  116. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/cli/test_latex.py +0 -0
  117. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/cli/test_list.py +0 -0
  118. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/cli/test_new.py +0 -0
  119. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/cli/test_notebooks.py +0 -0
  120. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/cli/test_overleaf.py +0 -0
  121. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/cli/test_update.py +0 -0
  122. {calkit_python-0.36.0/calkit/tests/jupyterlab → calkit_python-0.37.1/calkit/tests/dvc}/__init__.py +0 -0
  123. {calkit_python-0.36.0/calkit/tests/models → calkit_python-0.37.1/calkit/tests/jupyterlab}/__init__.py +0 -0
  124. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/jupyterlab/test_routes.py +0 -0
  125. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/models/test_iteration.py +0 -0
  126. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/models/test_pipeline.py +0 -0
  127. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/test_calc.py +0 -0
  128. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/test_check.py +0 -0
  129. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/test_conda.py +0 -0
  130. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/test_detect.py +0 -0
  131. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/test_docker.py +0 -0
  132. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/test_environments.py +0 -0
  133. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/test_fs.py +0 -0
  134. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/test_invenio.py +0 -0
  135. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/test_julia.py +0 -0
  136. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/test_jupyter.py +0 -0
  137. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/test_magics.py +0 -0
  138. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/test_matlab.py +0 -0
  139. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/test_notebooks.py +0 -0
  140. {calkit_python-0.36.0 → calkit_python-0.37.1}/calkit/tests/test_templates.py +0 -0
  141. {calkit_python-0.36.0 → calkit_python-0.37.1}/conftest.py +0 -0
  142. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/CNAME +0 -0
  143. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/apps.md +0 -0
  144. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/calculations.md +0 -0
  145. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/calkit-yaml.md +0 -0
  146. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/cloud-integration.md +0 -0
  147. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/datasets.md +0 -0
  148. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/dependencies.md +0 -0
  149. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/environments.md +0 -0
  150. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/examples.md +0 -0
  151. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/governance.md +0 -0
  152. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/help.md +0 -0
  153. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/img/c-to-the-k-white.svg +0 -0
  154. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/img/calkit-fragmentation-compendium.png +0 -0
  155. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/img/calkit-no-bg.png +0 -0
  156. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/img/connect-zenodo.png +0 -0
  157. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/img/jupyterlab/all-green.png +0 -0
  158. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/img/jupyterlab/collect-data-stale.png +0 -0
  159. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/img/jupyterlab/new-env.png +0 -0
  160. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/img/jupyterlab/new-notebook.png +0 -0
  161. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/img/jupyterlab/pipeline-badge.png +0 -0
  162. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/img/jupyterlab-params.png +0 -0
  163. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/img/plos-osi-code-2024-03.png +0 -0
  164. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/img/vscode-nb-params.png +0 -0
  165. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/index.md +0 -0
  166. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/installation.md +0 -0
  167. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/jupyterlab.md +0 -0
  168. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/local-server.md +0 -0
  169. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/notebooks.md +0 -0
  170. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/overleaf.md +0 -0
  171. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/pipeline/index.md +0 -0
  172. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/pipeline/manual-steps.md +0 -0
  173. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/pipeline/running-and-logging.md +0 -0
  174. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/pipeline/slurm.md +0 -0
  175. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/quickstart.md +0 -0
  176. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/references.md +0 -0
  177. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/releases.md +0 -0
  178. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/reproducibility.md +0 -0
  179. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/adding-latex-pub-docker.md +0 -0
  180. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/conda-envs.md +0 -0
  181. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/first-project.md +0 -0
  182. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/github-actions.md +0 -0
  183. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/actions-repo-secrets.png +0 -0
  184. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/latex-codespaces/building-codespace.png +0 -0
  185. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/latex-codespaces/codespaces-secrets-2.png +0 -0
  186. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/latex-codespaces/editor-split.png +0 -0
  187. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/latex-codespaces/go-to-linked-code.png +0 -0
  188. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/latex-codespaces/issue-from-selection.png +0 -0
  189. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/latex-codespaces/new-project.png +0 -0
  190. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/latex-codespaces/new-pub-2.png +0 -0
  191. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/latex-codespaces/new-token.png +0 -0
  192. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/latex-codespaces/paper.tex.png +0 -0
  193. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/latex-codespaces/project-home-3.png +0 -0
  194. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/latex-codespaces/push.png +0 -0
  195. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/latex-codespaces/stage.png +0 -0
  196. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/office/anakin-excel.jpg +0 -0
  197. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/office/chart-more-rows.png +0 -0
  198. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/office/create-project.png +0 -0
  199. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/office/elsevier-research-data-guidelines.png +0 -0
  200. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/office/excel-chart.png +0 -0
  201. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/office/excel-data.png +0 -0
  202. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/office/insert-link-to-file.png +0 -0
  203. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/office/needs-clone.png +0 -0
  204. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/office/new-stage.png +0 -0
  205. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/office/phd-comics-version-control.webp +0 -0
  206. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/office/pipeline-out-of-date.png +0 -0
  207. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/office/status-more-rows.png +0 -0
  208. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/office/uncommitted-changes.png +0 -0
  209. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/office/untracked-data.png +0 -0
  210. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/office/updated-publication.png +0 -0
  211. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/office/word-to-pdf-stage-2.png +0 -0
  212. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/office/workflow-page.png +0 -0
  213. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/openfoam/clone.png +0 -0
  214. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/openfoam/create-project.png +0 -0
  215. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/openfoam/datasets-page.png +0 -0
  216. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/openfoam/figure-on-website-updated.png +0 -0
  217. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/openfoam/figure-on-website.png +0 -0
  218. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/openfoam/new-token.png +0 -0
  219. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/openfoam/reclone.png +0 -0
  220. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/openfoam/status-after-import-dataset.png +0 -0
  221. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/quick-actions.png +0 -0
  222. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/img/run-proc.png +0 -0
  223. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/index.md +0 -0
  224. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/jupyterlab.md +0 -0
  225. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/latex-codespaces.md +0 -0
  226. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/matlab.md +0 -0
  227. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/notebook-pipeline.md +0 -0
  228. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/office.md +0 -0
  229. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/openfoam.md +0 -0
  230. {calkit_python-0.36.0 → calkit_python-0.37.1}/docs/tutorials/procedures.md +0 -0
  231. {calkit_python-0.36.0 → calkit_python-0.37.1}/install.json +0 -0
  232. {calkit_python-0.36.0 → calkit_python-0.37.1}/jest.config.js +0 -0
  233. {calkit_python-0.36.0 → calkit_python-0.37.1}/jupyter-config/server-config/calkit.json +0 -0
  234. {calkit_python-0.36.0 → calkit_python-0.37.1}/mkdocs.yml +0 -0
  235. {calkit_python-0.36.0 → calkit_python-0.37.1}/package.json +0 -0
  236. {calkit_python-0.36.0 → calkit_python-0.37.1}/pyproject.toml +0 -0
  237. {calkit_python-0.36.0 → calkit_python-0.37.1}/schema/plugin.json +0 -0
  238. {calkit_python-0.36.0 → calkit_python-0.37.1}/scripts/install.ps1 +0 -0
  239. {calkit_python-0.36.0 → calkit_python-0.37.1}/scripts/install.sh +0 -0
  240. {calkit_python-0.36.0 → calkit_python-0.37.1}/scripts/make-calk9.sh +0 -0
  241. {calkit_python-0.36.0 → calkit_python-0.37.1}/scripts/sync-docs.py +0 -0
  242. {calkit_python-0.36.0 → calkit_python-0.37.1}/src/__tests__/useQueries.spec.ts +0 -0
  243. {calkit_python-0.36.0 → calkit_python-0.37.1}/src/calkit-config.ts +0 -0
  244. {calkit_python-0.36.0 → calkit_python-0.37.1}/src/cell-output-marker.ts +0 -0
  245. {calkit_python-0.36.0 → calkit_python-0.37.1}/src/components/commit-dialog.tsx +0 -0
  246. {calkit_python-0.36.0 → calkit_python-0.37.1}/src/components/environment-editor.tsx +0 -0
  247. {calkit_python-0.36.0 → calkit_python-0.37.1}/src/components/notebook-registration.tsx +0 -0
  248. {calkit_python-0.36.0 → calkit_python-0.37.1}/src/components/notebook-toolbar.tsx +0 -0
  249. {calkit_python-0.36.0 → calkit_python-0.37.1}/src/components/pipeline-status-bar.tsx +0 -0
  250. {calkit_python-0.36.0 → calkit_python-0.37.1}/src/components/project-info-editor.tsx +0 -0
  251. {calkit_python-0.36.0 → calkit_python-0.37.1}/src/components/sidebar-settings.tsx +0 -0
  252. {calkit_python-0.36.0 → calkit_python-0.37.1}/src/components/sidebar.tsx +0 -0
  253. {calkit_python-0.36.0 → calkit_python-0.37.1}/src/components/stage-editor.tsx +0 -0
  254. {calkit_python-0.36.0 → calkit_python-0.37.1}/src/feature-flags.ts +0 -0
  255. {calkit_python-0.36.0 → calkit_python-0.37.1}/src/file-browser-menu.ts +0 -0
  256. {calkit_python-0.36.0 → calkit_python-0.37.1}/src/hooks/__tests__/useQueries.test.tsx +0 -0
  257. {calkit_python-0.36.0 → calkit_python-0.37.1}/src/hooks/useQueries.ts +0 -0
  258. {calkit_python-0.36.0 → calkit_python-0.37.1}/src/icons.ts +0 -0
  259. {calkit_python-0.36.0 → calkit_python-0.37.1}/src/index.ts +0 -0
  260. {calkit_python-0.36.0 → calkit_python-0.37.1}/src/io-tracker.ts +0 -0
  261. {calkit_python-0.36.0 → calkit_python-0.37.1}/src/pipeline-state.ts +0 -0
  262. {calkit_python-0.36.0 → calkit_python-0.37.1}/src/queryClient.ts +0 -0
  263. {calkit_python-0.36.0 → calkit_python-0.37.1}/src/request.ts +0 -0
  264. {calkit_python-0.36.0 → calkit_python-0.37.1}/src/shims-mainmenu.d.ts +0 -0
  265. {calkit_python-0.36.0 → calkit_python-0.37.1}/style/base.css +0 -0
  266. {calkit_python-0.36.0 → calkit_python-0.37.1}/style/cell-output-marker.css +0 -0
  267. {calkit_python-0.36.0 → calkit_python-0.37.1}/style/environment-editor.css +0 -0
  268. {calkit_python-0.36.0 → calkit_python-0.37.1}/style/environment-selector.css +0 -0
  269. {calkit_python-0.36.0 → calkit_python-0.37.1}/style/img/calkit-no-bg.png +0 -0
  270. {calkit_python-0.36.0 → calkit_python-0.37.1}/style/index.css +0 -0
  271. {calkit_python-0.36.0 → calkit_python-0.37.1}/style/index.js +0 -0
  272. {calkit_python-0.36.0 → calkit_python-0.37.1}/style/notebook-toolbar.css +0 -0
  273. {calkit_python-0.36.0 → calkit_python-0.37.1}/style/pipeline-status-bar.css +0 -0
  274. {calkit_python-0.36.0 → calkit_python-0.37.1}/style/sidebar.css +0 -0
  275. {calkit_python-0.36.0 → calkit_python-0.37.1}/test/dvc-md5-dir/osx-arm64.txt +0 -0
  276. {calkit_python-0.36.0 → calkit_python-0.37.1}/test/nb-julia.ipynb +0 -0
  277. {calkit_python-0.36.0 → calkit_python-0.37.1}/test/nb-params.ipynb +0 -0
  278. {calkit_python-0.36.0 → calkit_python-0.37.1}/test/nb-subdir.ipynb +0 -0
  279. {calkit_python-0.36.0 → calkit_python-0.37.1}/test/pipeline.ipynb +0 -0
  280. {calkit_python-0.36.0 → calkit_python-0.37.1}/test/script.py +0 -0
  281. {calkit_python-0.36.0 → calkit_python-0.37.1}/test/test-log.log +0 -0
  282. {calkit_python-0.36.0 → calkit_python-0.37.1}/tsconfig.json +0 -0
  283. {calkit_python-0.36.0 → calkit_python-0.37.1}/tsconfig.test.json +0 -0
  284. {calkit_python-0.36.0 → calkit_python-0.37.1}/ui-tests/.gitignore +0 -0
  285. {calkit_python-0.36.0 → calkit_python-0.37.1}/ui-tests/README.md +0 -0
  286. {calkit_python-0.36.0 → calkit_python-0.37.1}/ui-tests/jupyter_server_test_config.py +0 -0
  287. {calkit_python-0.36.0 → calkit_python-0.37.1}/ui-tests/package.json +0 -0
  288. {calkit_python-0.36.0 → calkit_python-0.37.1}/ui-tests/playwright.config.js +0 -0
  289. {calkit_python-0.36.0 → calkit_python-0.37.1}/ui-tests/tests/calkit.spec.ts +0 -0
  290. {calkit_python-0.36.0 → calkit_python-0.37.1}/ui-tests/yarn.lock +0 -0
  291. {calkit_python-0.36.0 → calkit_python-0.37.1}/uv.lock +0 -0
  292. {calkit_python-0.36.0 → calkit_python-0.37.1}/vscode-ext/.gitignore +0 -0
  293. {calkit_python-0.36.0 → calkit_python-0.37.1}/vscode-ext/.vscodeignore +0 -0
  294. {calkit_python-0.36.0 → calkit_python-0.37.1}/vscode-ext/CHANGELOG.md +0 -0
  295. {calkit_python-0.36.0 → calkit_python-0.37.1}/vscode-ext/LICENSE +0 -0
  296. {calkit_python-0.36.0 → calkit_python-0.37.1}/vscode-ext/README.md +0 -0
  297. {calkit_python-0.36.0 → calkit_python-0.37.1}/vscode-ext/images/calkit-no-bg.png +0 -0
  298. {calkit_python-0.36.0 → calkit_python-0.37.1}/vscode-ext/package-lock.json +0 -0
  299. {calkit_python-0.36.0 → calkit_python-0.37.1}/vscode-ext/package.json +0 -0
  300. {calkit_python-0.36.0 → calkit_python-0.37.1}/vscode-ext/scripts/set-proposed-api.js +0 -0
  301. {calkit_python-0.36.0 → calkit_python-0.37.1}/vscode-ext/src/environments.ts +0 -0
  302. {calkit_python-0.36.0 → calkit_python-0.37.1}/vscode-ext/src/extension.ts +0 -0
  303. {calkit_python-0.36.0 → calkit_python-0.37.1}/vscode-ext/src/notebooks.ts +0 -0
  304. {calkit_python-0.36.0 → calkit_python-0.37.1}/vscode-ext/src/test/environments.test.ts +0 -0
  305. {calkit_python-0.36.0 → calkit_python-0.37.1}/vscode-ext/src/test/notebooks.test.ts +0 -0
  306. {calkit_python-0.36.0 → calkit_python-0.37.1}/vscode-ext/src/types.ts +0 -0
  307. {calkit_python-0.36.0 → calkit_python-0.37.1}/vscode-ext/tsconfig.json +0 -0
  308. {calkit_python-0.36.0 → calkit_python-0.37.1}/yarn.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: calkit-python
3
- Version: 0.36.0
3
+ Version: 0.37.1
4
4
  Summary: Reproducibility simplified.
5
5
  Project-URL: Homepage, https://calkit.org
6
6
  Project-URL: Issues, https://github.com/calkit/calkit/issues
@@ -70,6 +70,13 @@ def unset_config_value(key: str):
70
70
  @config_app.command(name="setup-remote", help="Alias for 'remote'.")
71
71
  @config_app.command(name="remote")
72
72
  def setup_remote(
73
+ ck: Annotated[
74
+ bool,
75
+ typer.Option(
76
+ "--ck",
77
+ help="Use a ck:// URL for the 'calkit' DVC remote.",
78
+ ),
79
+ ] = False,
73
80
  no_commit: Annotated[
74
81
  bool,
75
82
  typer.Option(
@@ -81,7 +88,7 @@ def setup_remote(
81
88
  the local config.
82
89
  """
83
90
  try:
84
- configure_remote()
91
+ configure_remote(use_ck=ck)
85
92
  set_remote_auth()
86
93
  except subprocess.CalledProcessError:
87
94
  if not os.path.isfile(".dvc/config"):
@@ -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")
@@ -273,6 +337,9 @@ def get_status(
273
337
  categories = valid_categories
274
338
  pipeline_status = None
275
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")
276
343
  pipeline_status = calkit.pipeline.get_status(
277
344
  ck_info=ck_info,
278
345
  targets=targets,
@@ -280,8 +347,6 @@ def get_status(
280
347
  clean_notebooks=True,
281
348
  compile_to_dvc=True,
282
349
  )
283
- for error in pipeline_status.errors:
284
- warn(error)
285
350
  if pipeline_status.failed_environment_checks:
286
351
  warn(
287
352
  "Failed pipeline environment checks for: "
@@ -388,41 +453,51 @@ def get_status(
388
453
  typer.echo()
389
454
  if "dvc" in categories:
390
455
  print_sep("DVC")
391
- dvc_data_cmd = ["data", "status"]
392
- if targets:
393
- dvc_data_cmd += targets
394
- run_dvc_command(dvc_data_cmd)
395
- typer.echo()
456
+ try:
457
+ get_dvc_repo()
458
+ except Exception:
459
+ typer.echo("This is not a DVC repository.\n")
460
+ else:
461
+ zip_path_map = calkit.dvc.zip.get_zip_path_map()
462
+ dvc_repo = get_dvc_repo()
463
+ raw = dict(dvc_repo.data_status())
464
+ raw.pop("git", None)
465
+ typer.echo(_format_dvc_data_status(raw, zip_path_map))
396
466
  if "pipeline" in categories or "dvc" in categories:
397
467
  print_sep("Pipeline")
398
468
  # Nicely format the results from pipeline status
399
469
  if pipeline_status and pipeline_status.errors:
400
- warn("Pipeline status unavailable due to errors.")
470
+ warn("Pipeline status unavailable due to errors:")
471
+ for error in pipeline_status.errors:
472
+ warn(error)
401
473
  return
402
474
  if pipeline_status and not pipeline_status.has_pipeline:
403
475
  typer.echo("This project has no pipeline.")
404
476
  return
405
477
  elif pipeline_status and pipeline_status.is_stale:
478
+ typer.echo("Stale stages:")
406
479
  for stage_name in pipeline_status.stale_stage_names:
407
480
  stale_stage = pipeline_status.stale_stages.get(stage_name)
408
481
  if stale_stage is None:
409
482
  continue
410
- 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")
411
486
  # Show stale outputs for this stage
412
487
  if stale_stage.stale_outputs:
413
- typer.echo(" stale outputs:")
488
+ typer.echo(" stale outputs:")
414
489
  for output_path in stale_stage.stale_outputs:
415
- typer.echo(f" {output_path}")
490
+ typer.echo(f" {output_path}")
416
491
  # Show modified outputs from this stage
417
492
  if stale_stage.modified_outputs:
418
- typer.echo(" modified outputs:")
493
+ typer.echo(" modified outputs:")
419
494
  for output_path in stale_stage.modified_outputs:
420
- typer.echo(f" {output_path}")
495
+ typer.echo(f" {output_path}")
421
496
  # Show modified inputs making the stage stale
422
497
  if stale_stage.modified_inputs:
423
- typer.echo(" modified inputs:")
498
+ typer.echo(" modified inputs:")
424
499
  for input_path in stale_stage.modified_inputs:
425
- typer.echo(f" {input_path}")
500
+ typer.echo(f" {input_path}")
426
501
  elif pipeline_status:
427
502
  typer.echo("Pipeline is up to date.")
428
503
 
@@ -474,7 +549,9 @@ def add(
474
549
  to: Annotated[
475
550
  str | None,
476
551
  typer.Option(
477
- "--to", "-t", help="System with which to add (git or dvc)."
552
+ "--to",
553
+ "-t",
554
+ help="System with which to add (git, dvc, or dvc-zip).",
478
555
  ),
479
556
  ] = None,
480
557
  ):
@@ -500,7 +577,7 @@ def add(
500
577
  raise_error(
501
578
  "Cannot auto-generate commit message for more than one path"
502
579
  )
503
- 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"]:
504
581
  raise_error(f"Invalid option for 'to': {to}")
505
582
  try:
506
583
  repo = git.Repo()
@@ -543,6 +620,10 @@ def add(
543
620
  subprocess.call(["git", "add"] + paths)
544
621
  elif to == "dvc":
545
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)
546
627
  else:
547
628
  raise_error(f"Invalid option for 'to': {to}")
548
629
  else:
@@ -591,7 +672,14 @@ def add(
591
672
  d.a_path for d in repo.index.diff(None) if d.a_path is not None
592
673
  ]:
593
674
  paths.append(changed_file)
675
+ zip_path_map = calkit.dvc.zip.get_zip_path_map()
594
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
595
683
  # Detect if this file should be tracked with Git or DVC
596
684
  # First see if it's in Git
597
685
  if repo.git.ls_files(path):
@@ -607,6 +695,12 @@ def add(
607
695
  elif os.path.splitext(path)[-1] in DVC_EXTENSIONS:
608
696
  typer.echo(f"Adding {path} to DVC per its extension")
609
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)
610
704
  elif calkit.get_size(path) > DVC_SIZE_THRESH_BYTES:
611
705
  typer.echo(
612
706
  f"Adding {path} to DVC since it's greater than 1 MB"
@@ -842,6 +936,7 @@ def pull(
842
936
  result = run_dvc_command(["pull"] + dvc_args)
843
937
  if result != 0:
844
938
  raise_error("DVC pull failed")
939
+ calkit.dvc.zip.sync_all(direction="to-workspace")
845
940
 
846
941
 
847
942
  @app.command(name="push")
@@ -1177,6 +1272,7 @@ def run(
1177
1272
  import dvc.ui
1178
1273
  from dvc.cli import main as dvc_cli_main
1179
1274
 
1275
+ import calkit.dvc.zip
1180
1276
  import calkit.environments
1181
1277
  import calkit.pipeline
1182
1278
  from calkit.cli.overleaf import sync as overleaf_sync
@@ -1376,10 +1472,38 @@ def run(
1376
1472
  dvc.ui.ui.write = lambda *args, **kwargs: None
1377
1473
  res = dvc_cli_main(["repro"] + args)
1378
1474
  failed = res != 0
1379
- # Parse log to get timing
1475
+ # Parse log to get timing and which stages ran
1380
1476
  with open(log_fpath, "r") as f:
1381
1477
  log_content = f.read()
1382
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")
1383
1507
  # Close logger file handler to prevent permissions issues if deleting
1384
1508
  dvc.log.logger.removeHandler(file_handler)
1385
1509
  file_handler.close()
@@ -2245,6 +2369,39 @@ def switch_branch(name: Annotated[str, typer.Argument(help="Branch name.")]):
2245
2369
  else:
2246
2370
  cmd = [name]
2247
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")
2248
2405
 
2249
2406
 
2250
2407
  @app.command(
@@ -7,7 +7,6 @@ import os
7
7
  import pathlib
8
8
  import shutil
9
9
  import subprocess
10
- import zipfile
11
10
  from enum import Enum
12
11
 
13
12
  import dotenv
@@ -2686,8 +2685,7 @@ def new_release(
2686
2685
  zip_path = release_files_dir + "/archive.zip"
2687
2686
  all_paths = calkit.releases.ls_files()
2688
2687
  typer.echo(f"Adding files to {zip_path}")
2689
- with zipfile.ZipFile(zip_path, "w") as zipf:
2690
- calkit.releases.add_paths_to_zip(zipf, all_paths)
2688
+ calkit.releases.zip_paths(zip_path, all_paths)
2691
2689
  typer.echo("Checking extracted project release archive")
2692
2690
  try:
2693
2691
  calkit.releases.check_project_release_archive(
@@ -4,7 +4,6 @@ from __future__ import annotations
4
4
 
5
5
  import json
6
6
  import os
7
- import zipfile
8
7
  from datetime import datetime
9
8
 
10
9
  import git
@@ -266,8 +265,7 @@ def update_release(
266
265
  zip_path = release_files_dir + "/archive.zip"
267
266
  all_paths = calkit.releases.ls_files()
268
267
  typer.echo(f"Adding files to {zip_path}")
269
- with zipfile.ZipFile(zip_path, "w") as zipf:
270
- calkit.releases.add_paths_to_zip(zipf, all_paths)
268
+ calkit.releases.zip_paths(zip_path, all_paths)
271
269
  typer.echo("Checking project release archive")
272
270
  try:
273
271
  calkit.releases.check_project_release_archive(zip_path)
@@ -647,10 +647,12 @@ def get_system_info() -> dict:
647
647
  def get_md5(path: str, exclude_files: list[str] | None = None) -> str:
648
648
  if os.path.isdir(path):
649
649
  return checksumdir.dirhash(path, excluded_files=exclude_files)
650
- else:
651
- with open(path) as f:
652
- content = f.read()
653
- return hashlib.md5(content.encode()).hexdigest()
650
+ hasher = hashlib.md5()
651
+ with open(path, "rb") as f:
652
+ # Read the file in chunks to avoid memory issues with large files
653
+ for chunk in iter(lambda: f.read(4096), b""):
654
+ hasher.update(chunk)
655
+ return hasher.hexdigest()
654
656
 
655
657
 
656
658
  def set_env_vars(ck_info: dict, cli: bool = True) -> None:
@@ -11,6 +11,7 @@ from typing import Any
11
11
 
12
12
  import dvc.repo
13
13
  import git
14
+ from configobj import ConfigObj
14
15
  from dvc.utils.objects import cached_property
15
16
  from dvc_objects.fs.base import ObjectFileSystem
16
17
  from fsspec import Callback
@@ -251,10 +252,10 @@ def run_dvc_command(argv: list[str], cwd: str | None = None) -> int:
251
252
  return run_dvc_cli(argv)
252
253
 
253
254
 
254
- def configure_remote(wdir: str | None = None) -> str:
255
+ def configure_remote(wdir: str | None = None, use_ck: bool = False) -> str:
255
256
  """Configure a DVC remote for the current project.
256
257
 
257
- TODO: Use the ck:// scheme.
258
+ TODO: Use the ck:// scheme by default once it's deemed stable.
258
259
  """
259
260
  try:
260
261
  project_name = calkit.detect_project_name(wdir=wdir)
@@ -275,8 +276,12 @@ def configure_remote(wdir: str | None = None) -> str:
275
276
  if not url.endswith(".git"):
276
277
  url += ".git"
277
278
  repo.git.remote(["add", "origin", url])
278
- base_url = calkit.cloud.get_base_url()
279
- remote_url = f"{base_url}/projects/{project_name}/dvc"
279
+ if use_ck:
280
+ clear_remote_local_http_auth(wdir=wdir)
281
+ remote_url = f"ck://{project_name}"
282
+ else:
283
+ base_url = calkit.cloud.get_base_url()
284
+ remote_url = f"{base_url}/projects/{project_name}/dvc"
280
285
  remote_name = get_app_name()
281
286
  result = run_dvc_command(
282
287
  ["remote", "add", "-d", "-f", remote_name, remote_url],
@@ -284,17 +289,47 @@ def configure_remote(wdir: str | None = None) -> str:
284
289
  )
285
290
  if result != 0:
286
291
  raise RuntimeError(f"Failed to add DVC remote {remote_name}")
287
- result = run_dvc_command(
288
- ["remote", "modify", remote_name, "auth", "custom"],
289
- cwd=wdir,
290
- )
291
- if result != 0:
292
- raise RuntimeError(
293
- f"Failed to configure auth for DVC remote {remote_name}"
292
+ if not use_ck:
293
+ result = run_dvc_command(
294
+ ["remote", "modify", remote_name, "auth", "custom"],
295
+ cwd=wdir,
294
296
  )
297
+ if result != 0:
298
+ raise RuntimeError(
299
+ f"Failed to configure auth for DVC remote {remote_name}"
300
+ )
295
301
  return remote_name
296
302
 
297
303
 
304
+ def clear_remote_local_http_auth(
305
+ remote_name: str | None = None, wdir: str | None = None
306
+ ) -> None:
307
+ """Remove HTTP-specific local auth settings for a DVC remote.
308
+
309
+ This clears values written to ``.dvc/config.local`` by HTTP auth setup.
310
+ """
311
+ if remote_name is None:
312
+ remote_name = get_app_name()
313
+ config_local = Path(wdir or ".") / ".dvc" / "config.local"
314
+ if not config_local.is_file():
315
+ return
316
+ cfg = ConfigObj(str(config_local), encoding="utf-8")
317
+ section_name = f'remote "{remote_name}"'
318
+ remote = cfg.get(section_name)
319
+ if not isinstance(remote, dict):
320
+ return
321
+ changed = False
322
+ for option in ("custom_auth_header", "password", "auth"):
323
+ if option in remote:
324
+ remote.pop(option)
325
+ changed = True
326
+ if not changed:
327
+ return
328
+ if not remote:
329
+ cfg.pop(section_name, None)
330
+ cfg.write()
331
+
332
+
298
333
  def set_remote_auth(
299
334
  remote_name: str | None = None,
300
335
  always_auth: bool = False,
@@ -312,6 +347,7 @@ def set_remote_auth(
312
347
  remotes = get_remotes(wdir=wdir)
313
348
  remote_url = remotes.get(remote_name, "")
314
349
  if remote_url.startswith("ck://"):
350
+ clear_remote_local_http_auth(remote_name=remote_name, wdir=wdir)
315
351
  logger.info(
316
352
  f"Remote {remote_name} uses ck:// scheme; skipping HTTP auth setup"
317
353
  )