calkit-python 0.38.2__tar.gz → 0.38.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (329) hide show
  1. {calkit_python-0.38.2 → calkit_python-0.38.4}/.pre-commit-config.yaml +1 -0
  2. {calkit_python-0.38.2 → calkit_python-0.38.4}/AGENTS.md +3 -0
  3. {calkit_python-0.38.2 → calkit_python-0.38.4}/PKG-INFO +10 -5
  4. {calkit_python-0.38.2 → calkit_python-0.38.4}/README.md +5 -0
  5. calkit_python-0.38.4/calkit/__init__.py +83 -0
  6. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/check.py +3 -2
  7. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/cli/check.py +17 -13
  8. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/cli/cloud.py +2 -1
  9. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/cli/config.py +17 -4
  10. calkit_python-0.38.4/calkit/cli/core.py +85 -0
  11. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/cli/import_.py +15 -7
  12. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/cli/list.py +35 -9
  13. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/cli/main/core.py +237 -106
  14. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/cli/main/xr.py +3 -2
  15. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/cli/new.py +138 -18
  16. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/cli/office.py +2 -1
  17. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/cli/overleaf.py +6 -1
  18. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/cli/update.py +15 -3
  19. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/cloud.py +4 -0
  20. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/core.py +32 -22
  21. calkit_python-0.38.4/calkit/dvc/__init__.py +14 -0
  22. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/models/pipeline.py +6 -4
  23. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/notebooks.py +13 -6
  24. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/pipeline.py +47 -4
  25. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/cli/main/test_core.py +119 -0
  26. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/cli/test_check.py +32 -0
  27. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/cli/test_list.py +20 -0
  28. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/cli/test_new.py +114 -0
  29. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/test_cloud.py +11 -0
  30. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/cli-reference.md +293 -272
  31. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/quickstart.md +5 -0
  32. {calkit_python-0.38.2 → calkit_python-0.38.4}/pyproject.toml +10 -4
  33. {calkit_python-0.38.2 → calkit_python-0.38.4}/scripts/generate-docs-references.py +11 -2
  34. {calkit_python-0.38.2 → calkit_python-0.38.4}/scripts/install.ps1 +3 -0
  35. {calkit_python-0.38.2 → calkit_python-0.38.4}/scripts/install.sh +7 -0
  36. {calkit_python-0.38.2 → calkit_python-0.38.4}/uv.lock +60 -54
  37. {calkit_python-0.38.2 → calkit_python-0.38.4}/vscode-ext/package.json +1 -1
  38. calkit_python-0.38.2/calkit/__init__.py +0 -53
  39. calkit_python-0.38.2/calkit/cli/core.py +0 -37
  40. calkit_python-0.38.2/calkit/templates/latex/__init__.py +0 -1
  41. {calkit_python-0.38.2 → calkit_python-0.38.4}/.claude-plugin/marketplace.json +0 -0
  42. {calkit_python-0.38.2 → calkit_python-0.38.4}/.gitignore +0 -0
  43. {calkit_python-0.38.2 → calkit_python-0.38.4}/.prettierignore +0 -0
  44. {calkit_python-0.38.2 → calkit_python-0.38.4}/.python-version +0 -0
  45. {calkit_python-0.38.2 → calkit_python-0.38.4}/.vscode/launch.json +0 -0
  46. {calkit_python-0.38.2 → calkit_python-0.38.4}/.vscode/tasks.json +0 -0
  47. {calkit_python-0.38.2 → calkit_python-0.38.4}/.yarnrc.yml +0 -0
  48. {calkit_python-0.38.2 → calkit_python-0.38.4}/CITATION.cff +0 -0
  49. {calkit_python-0.38.2 → calkit_python-0.38.4}/CODE_OF_CONDUCT.md +0 -0
  50. {calkit_python-0.38.2 → calkit_python-0.38.4}/CONTRIBUTING.md +0 -0
  51. {calkit_python-0.38.2 → calkit_python-0.38.4}/LICENSE +0 -0
  52. {calkit_python-0.38.2 → calkit_python-0.38.4}/Makefile +0 -0
  53. {calkit_python-0.38.2 → calkit_python-0.38.4}/agent-plugin/.claude-plugin/plugin.json +0 -0
  54. {calkit_python-0.38.2 → calkit_python-0.38.4}/agent-plugin/skills/add-pipeline-stage/SKILL.md +0 -0
  55. {calkit_python-0.38.2 → calkit_python-0.38.4}/agent-plugin/skills/conventions/SKILL.md +0 -0
  56. {calkit_python-0.38.2 → calkit_python-0.38.4}/agent-plugin/skills/create-pipeline/SKILL.md +0 -0
  57. {calkit_python-0.38.2 → calkit_python-0.38.4}/babel.config.js +0 -0
  58. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/__main__.py +0 -0
  59. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/calc.py +0 -0
  60. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/cli/__init__.py +0 -0
  61. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/cli/describe.py +0 -0
  62. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/cli/dev.py +0 -0
  63. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/cli/latex.py +0 -0
  64. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/cli/main/__init__.py +0 -0
  65. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/cli/notebooks.py +0 -0
  66. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/cli/slurm.py +0 -0
  67. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/conda.py +0 -0
  68. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/config.py +0 -0
  69. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/datasets.py +0 -0
  70. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/detect.py +0 -0
  71. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/docker.py +0 -0
  72. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/dvc/core.py +0 -0
  73. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/dvc/zip.py +0 -0
  74. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/environments.py +0 -0
  75. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/fs.py +0 -0
  76. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/git.py +0 -0
  77. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/github.py +0 -0
  78. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/gui.py +0 -0
  79. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/invenio.py +0 -0
  80. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/julia.py +0 -0
  81. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/jupyter.py +0 -0
  82. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/jupyterlab/__init__.py +0 -0
  83. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/jupyterlab/routes.py +0 -0
  84. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/labextension/package.json +0 -0
  85. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/labextension/schemas/calkit/package.json.orig +0 -0
  86. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/labextension/schemas/calkit/plugin.json +0 -0
  87. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/labextension/static/502.9a2c5772a15466e923ef.js +0 -0
  88. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/labextension/static/695.2c41003a452d43d2b358.js +0 -0
  89. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/labextension/static/867.a42a046aa5108f54f8fb.js +0 -0
  90. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/labextension/static/909.e3f9cc3408834a7fdcc3.js +0 -0
  91. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/labextension/static/946.050af2abf7845cfbdbd2.js +0 -0
  92. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/labextension/static/946.050af2abf7845cfbdbd2.js.LICENSE.txt +0 -0
  93. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/labextension/static/b2f1c3efe70cb539d121.png +0 -0
  94. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/labextension/static/remoteEntry.65469af996e7a96aa983.js +0 -0
  95. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/labextension/static/style.js +0 -0
  96. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/labextension/static/third-party-licenses.json +0 -0
  97. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/licenses.py +0 -0
  98. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/magics.py +0 -0
  99. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/matlab.py +0 -0
  100. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/models/__init__.py +0 -0
  101. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/models/core.py +0 -0
  102. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/models/io.py +0 -0
  103. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/models/iteration.py +0 -0
  104. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/office.py +0 -0
  105. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/ops.py +0 -0
  106. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/overleaf.py +0 -0
  107. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/releases.py +0 -0
  108. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/server.py +0 -0
  109. {calkit_python-0.38.2/calkit/dvc → calkit_python-0.38.4/calkit/templates}/__init__.py +0 -0
  110. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/templates/core.py +0 -0
  111. {calkit_python-0.38.2/calkit/templates → calkit_python-0.38.4/calkit/templates/latex}/__init__.py +0 -0
  112. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/templates/latex/article/paper.tex +0 -0
  113. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/templates/latex/core.py +0 -0
  114. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/templates/latex/jfm/jfm.bst +0 -0
  115. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/templates/latex/jfm/jfm.cls +0 -0
  116. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/templates/latex/jfm/lineno-FLM.sty +0 -0
  117. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/templates/latex/jfm/paper.tex +0 -0
  118. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/templates/latex/jfm/upmath.sty +0 -0
  119. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/__init__.py +0 -0
  120. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/cli/__init__.py +0 -0
  121. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/cli/main/__init__.py +0 -0
  122. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/cli/main/test_xr.py +0 -0
  123. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/cli/test_cloud.py +0 -0
  124. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/cli/test_config.py +0 -0
  125. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/cli/test_import.py +0 -0
  126. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/cli/test_latex.py +0 -0
  127. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/cli/test_notebooks.py +0 -0
  128. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/cli/test_overleaf.py +0 -0
  129. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/cli/test_update.py +0 -0
  130. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/dvc/__init__.py +0 -0
  131. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/dvc/test_core.py +0 -0
  132. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/dvc/test_zip.py +0 -0
  133. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/jupyterlab/__init__.py +0 -0
  134. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/jupyterlab/test_routes.py +0 -0
  135. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/models/__init__.py +0 -0
  136. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/models/test_iteration.py +0 -0
  137. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/models/test_pipeline.py +0 -0
  138. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/test_calc.py +0 -0
  139. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/test_check.py +0 -0
  140. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/test_conda.py +0 -0
  141. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/test_core.py +0 -0
  142. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/test_detect.py +0 -0
  143. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/test_docker.py +0 -0
  144. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/test_environments.py +0 -0
  145. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/test_fs.py +0 -0
  146. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/test_git.py +0 -0
  147. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/test_invenio.py +0 -0
  148. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/test_julia.py +0 -0
  149. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/test_jupyter.py +0 -0
  150. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/test_magics.py +0 -0
  151. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/test_matlab.py +0 -0
  152. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/test_notebooks.py +0 -0
  153. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/test_pipeline.py +0 -0
  154. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/test_releases.py +0 -0
  155. {calkit_python-0.38.2 → calkit_python-0.38.4}/calkit/tests/test_templates.py +0 -0
  156. {calkit_python-0.38.2 → calkit_python-0.38.4}/conftest.py +0 -0
  157. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/CNAME +0 -0
  158. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/ai-tools.md +0 -0
  159. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/apps.md +0 -0
  160. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/calculations.md +0 -0
  161. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/calkit-yaml.md +0 -0
  162. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/cloud-integration.md +0 -0
  163. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/datasets.md +0 -0
  164. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/dependencies.md +0 -0
  165. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/environments.md +0 -0
  166. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/examples.md +0 -0
  167. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/governance.md +0 -0
  168. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/help.md +0 -0
  169. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/img/c-to-the-k-white.svg +0 -0
  170. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/img/calkit-fragmentation-compendium.png +0 -0
  171. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/img/calkit-no-bg.png +0 -0
  172. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/img/connect-zenodo.png +0 -0
  173. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/img/jupyterlab/all-green.png +0 -0
  174. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/img/jupyterlab/collect-data-stale.png +0 -0
  175. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/img/jupyterlab/new-env.png +0 -0
  176. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/img/jupyterlab/new-notebook.png +0 -0
  177. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/img/jupyterlab/pipeline-badge.png +0 -0
  178. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/img/jupyterlab-params.png +0 -0
  179. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/img/plos-osi-code-2024-03.png +0 -0
  180. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/img/vscode-nb-params.png +0 -0
  181. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/index.md +0 -0
  182. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/installation.md +0 -0
  183. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/jupyterlab.md +0 -0
  184. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/local-server.md +0 -0
  185. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/notebooks.md +0 -0
  186. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/overleaf.md +0 -0
  187. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/pipeline/index.md +0 -0
  188. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/pipeline/manual-steps.md +0 -0
  189. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/pipeline/running-and-logging.md +0 -0
  190. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/pipeline/slurm.md +0 -0
  191. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/references.md +0 -0
  192. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/releases.md +0 -0
  193. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/reproducibility.md +0 -0
  194. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/adding-latex-pub-docker.md +0 -0
  195. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/conda-envs.md +0 -0
  196. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/existing-project.md +0 -0
  197. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/first-project.md +0 -0
  198. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/github-actions.md +0 -0
  199. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/actions-repo-secrets.png +0 -0
  200. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/latex-codespaces/building-codespace.png +0 -0
  201. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/latex-codespaces/codespaces-secrets-2.png +0 -0
  202. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/latex-codespaces/editor-split.png +0 -0
  203. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/latex-codespaces/go-to-linked-code.png +0 -0
  204. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/latex-codespaces/issue-from-selection.png +0 -0
  205. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/latex-codespaces/new-project.png +0 -0
  206. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/latex-codespaces/new-pub-2.png +0 -0
  207. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/latex-codespaces/new-token.png +0 -0
  208. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/latex-codespaces/paper.tex.png +0 -0
  209. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/latex-codespaces/project-home-3.png +0 -0
  210. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/latex-codespaces/push.png +0 -0
  211. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/latex-codespaces/stage.png +0 -0
  212. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/office/anakin-excel.jpg +0 -0
  213. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/office/chart-more-rows.png +0 -0
  214. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/office/create-project.png +0 -0
  215. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/office/elsevier-research-data-guidelines.png +0 -0
  216. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/office/excel-chart.png +0 -0
  217. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/office/excel-data.png +0 -0
  218. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/office/insert-link-to-file.png +0 -0
  219. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/office/needs-clone.png +0 -0
  220. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/office/new-stage.png +0 -0
  221. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/office/phd-comics-version-control.webp +0 -0
  222. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/office/pipeline-out-of-date.png +0 -0
  223. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/office/status-more-rows.png +0 -0
  224. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/office/uncommitted-changes.png +0 -0
  225. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/office/untracked-data.png +0 -0
  226. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/office/updated-publication.png +0 -0
  227. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/office/word-to-pdf-stage-2.png +0 -0
  228. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/office/workflow-page.png +0 -0
  229. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/openfoam/clone.png +0 -0
  230. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/openfoam/create-project.png +0 -0
  231. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/openfoam/datasets-page.png +0 -0
  232. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/openfoam/figure-on-website-updated.png +0 -0
  233. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/openfoam/figure-on-website.png +0 -0
  234. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/openfoam/new-token.png +0 -0
  235. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/openfoam/reclone.png +0 -0
  236. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/openfoam/status-after-import-dataset.png +0 -0
  237. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/quick-actions.png +0 -0
  238. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/run-proc.png +0 -0
  239. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/vscode-slurm-notebook/create-calkit-env.png +0 -0
  240. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/vscode-slurm-notebook/create-inner-env.png +0 -0
  241. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/vscode-slurm-notebook/create-new-calkit-env.png +0 -0
  242. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/vscode-slurm-notebook/select-calkit-env.png +0 -0
  243. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/vscode-slurm-notebook/slurm-job-running.png +0 -0
  244. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/vscode-slurm-notebook/slurm-launch-options.png +0 -0
  245. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/img/vscode-slurm-notebook/starting-slurm-job.png +0 -0
  246. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/index.md +0 -0
  247. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/jupyterlab.md +0 -0
  248. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/latex-codespaces.md +0 -0
  249. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/matlab.md +0 -0
  250. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/notebook-pipeline.md +0 -0
  251. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/office.md +0 -0
  252. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/openfoam.md +0 -0
  253. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/procedures.md +0 -0
  254. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/tutorials/vscode-slurm-notebook.md +0 -0
  255. {calkit_python-0.38.2 → calkit_python-0.38.4}/docs/version-control.md +0 -0
  256. {calkit_python-0.38.2 → calkit_python-0.38.4}/install.json +0 -0
  257. {calkit_python-0.38.2 → calkit_python-0.38.4}/jest.config.js +0 -0
  258. {calkit_python-0.38.2 → calkit_python-0.38.4}/jupyter-config/server-config/calkit.json +0 -0
  259. {calkit_python-0.38.2 → calkit_python-0.38.4}/mkdocs.yml +0 -0
  260. {calkit_python-0.38.2 → calkit_python-0.38.4}/package.json +0 -0
  261. {calkit_python-0.38.2 → calkit_python-0.38.4}/schema/plugin.json +0 -0
  262. {calkit_python-0.38.2 → calkit_python-0.38.4}/scripts/make-calk9.sh +0 -0
  263. {calkit_python-0.38.2 → calkit_python-0.38.4}/scripts/sync-docs.py +0 -0
  264. {calkit_python-0.38.2 → calkit_python-0.38.4}/src/__tests__/useQueries.spec.ts +0 -0
  265. {calkit_python-0.38.2 → calkit_python-0.38.4}/src/calkit-config.ts +0 -0
  266. {calkit_python-0.38.2 → calkit_python-0.38.4}/src/cell-output-marker.ts +0 -0
  267. {calkit_python-0.38.2 → calkit_python-0.38.4}/src/components/commit-dialog.tsx +0 -0
  268. {calkit_python-0.38.2 → calkit_python-0.38.4}/src/components/environment-editor.tsx +0 -0
  269. {calkit_python-0.38.2 → calkit_python-0.38.4}/src/components/notebook-registration.tsx +0 -0
  270. {calkit_python-0.38.2 → calkit_python-0.38.4}/src/components/notebook-toolbar.tsx +0 -0
  271. {calkit_python-0.38.2 → calkit_python-0.38.4}/src/components/pipeline-status-bar.tsx +0 -0
  272. {calkit_python-0.38.2 → calkit_python-0.38.4}/src/components/project-info-editor.tsx +0 -0
  273. {calkit_python-0.38.2 → calkit_python-0.38.4}/src/components/sidebar-settings.tsx +0 -0
  274. {calkit_python-0.38.2 → calkit_python-0.38.4}/src/components/sidebar.tsx +0 -0
  275. {calkit_python-0.38.2 → calkit_python-0.38.4}/src/components/stage-editor.tsx +0 -0
  276. {calkit_python-0.38.2 → calkit_python-0.38.4}/src/feature-flags.ts +0 -0
  277. {calkit_python-0.38.2 → calkit_python-0.38.4}/src/file-browser-menu.ts +0 -0
  278. {calkit_python-0.38.2 → calkit_python-0.38.4}/src/hooks/__tests__/useQueries.test.tsx +0 -0
  279. {calkit_python-0.38.2 → calkit_python-0.38.4}/src/hooks/useQueries.ts +0 -0
  280. {calkit_python-0.38.2 → calkit_python-0.38.4}/src/icons.ts +0 -0
  281. {calkit_python-0.38.2 → calkit_python-0.38.4}/src/index.ts +0 -0
  282. {calkit_python-0.38.2 → calkit_python-0.38.4}/src/io-tracker.ts +0 -0
  283. {calkit_python-0.38.2 → calkit_python-0.38.4}/src/pipeline-state.ts +0 -0
  284. {calkit_python-0.38.2 → calkit_python-0.38.4}/src/queryClient.ts +0 -0
  285. {calkit_python-0.38.2 → calkit_python-0.38.4}/src/request.ts +0 -0
  286. {calkit_python-0.38.2 → calkit_python-0.38.4}/src/shims-mainmenu.d.ts +0 -0
  287. {calkit_python-0.38.2 → calkit_python-0.38.4}/style/base.css +0 -0
  288. {calkit_python-0.38.2 → calkit_python-0.38.4}/style/cell-output-marker.css +0 -0
  289. {calkit_python-0.38.2 → calkit_python-0.38.4}/style/environment-editor.css +0 -0
  290. {calkit_python-0.38.2 → calkit_python-0.38.4}/style/environment-selector.css +0 -0
  291. {calkit_python-0.38.2 → calkit_python-0.38.4}/style/img/calkit-no-bg.png +0 -0
  292. {calkit_python-0.38.2 → calkit_python-0.38.4}/style/index.css +0 -0
  293. {calkit_python-0.38.2 → calkit_python-0.38.4}/style/index.js +0 -0
  294. {calkit_python-0.38.2 → calkit_python-0.38.4}/style/notebook-toolbar.css +0 -0
  295. {calkit_python-0.38.2 → calkit_python-0.38.4}/style/pipeline-status-bar.css +0 -0
  296. {calkit_python-0.38.2 → calkit_python-0.38.4}/style/sidebar.css +0 -0
  297. {calkit_python-0.38.2 → calkit_python-0.38.4}/test/dvc-md5-dir/osx-arm64.txt +0 -0
  298. {calkit_python-0.38.2 → calkit_python-0.38.4}/test/nb-julia.ipynb +0 -0
  299. {calkit_python-0.38.2 → calkit_python-0.38.4}/test/nb-params.ipynb +0 -0
  300. {calkit_python-0.38.2 → calkit_python-0.38.4}/test/nb-subdir.ipynb +0 -0
  301. {calkit_python-0.38.2 → calkit_python-0.38.4}/test/pipeline.ipynb +0 -0
  302. {calkit_python-0.38.2 → calkit_python-0.38.4}/test/script.py +0 -0
  303. {calkit_python-0.38.2 → calkit_python-0.38.4}/test/test-log.log +0 -0
  304. {calkit_python-0.38.2 → calkit_python-0.38.4}/tsconfig.json +0 -0
  305. {calkit_python-0.38.2 → calkit_python-0.38.4}/tsconfig.test.json +0 -0
  306. {calkit_python-0.38.2 → calkit_python-0.38.4}/ui-tests/.gitignore +0 -0
  307. {calkit_python-0.38.2 → calkit_python-0.38.4}/ui-tests/README.md +0 -0
  308. {calkit_python-0.38.2 → calkit_python-0.38.4}/ui-tests/jupyter_server_test_config.py +0 -0
  309. {calkit_python-0.38.2 → calkit_python-0.38.4}/ui-tests/package.json +0 -0
  310. {calkit_python-0.38.2 → calkit_python-0.38.4}/ui-tests/playwright.config.js +0 -0
  311. {calkit_python-0.38.2 → calkit_python-0.38.4}/ui-tests/tests/calkit.spec.ts +0 -0
  312. {calkit_python-0.38.2 → calkit_python-0.38.4}/ui-tests/yarn.lock +0 -0
  313. {calkit_python-0.38.2 → calkit_python-0.38.4}/vscode-ext/.gitignore +0 -0
  314. {calkit_python-0.38.2 → calkit_python-0.38.4}/vscode-ext/.vscodeignore +0 -0
  315. {calkit_python-0.38.2 → calkit_python-0.38.4}/vscode-ext/CHANGELOG.md +0 -0
  316. {calkit_python-0.38.2 → calkit_python-0.38.4}/vscode-ext/LICENSE +0 -0
  317. {calkit_python-0.38.2 → calkit_python-0.38.4}/vscode-ext/README.md +0 -0
  318. {calkit_python-0.38.2 → calkit_python-0.38.4}/vscode-ext/images/calkit-no-bg.png +0 -0
  319. {calkit_python-0.38.2 → calkit_python-0.38.4}/vscode-ext/package-lock.json +0 -0
  320. {calkit_python-0.38.2 → calkit_python-0.38.4}/vscode-ext/scripts/set-proposed-api.js +0 -0
  321. {calkit_python-0.38.2 → calkit_python-0.38.4}/vscode-ext/src/environments.ts +0 -0
  322. {calkit_python-0.38.2 → calkit_python-0.38.4}/vscode-ext/src/extension.ts +0 -0
  323. {calkit_python-0.38.2 → calkit_python-0.38.4}/vscode-ext/src/notebooks.ts +0 -0
  324. {calkit_python-0.38.2 → calkit_python-0.38.4}/vscode-ext/src/test/environments.test.ts +0 -0
  325. {calkit_python-0.38.2 → calkit_python-0.38.4}/vscode-ext/src/test/kernel-selection.test.ts +0 -0
  326. {calkit_python-0.38.2 → calkit_python-0.38.4}/vscode-ext/src/test/notebooks.test.ts +0 -0
  327. {calkit_python-0.38.2 → calkit_python-0.38.4}/vscode-ext/src/types.ts +0 -0
  328. {calkit_python-0.38.2 → calkit_python-0.38.4}/vscode-ext/tsconfig.json +0 -0
  329. {calkit_python-0.38.2 → calkit_python-0.38.4}/yarn.lock +0 -0
@@ -4,6 +4,7 @@ repos:
4
4
  hooks:
5
5
  - id: check-case-conflict
6
6
  - id: check-merge-conflict
7
+ exclude: ^docs/overleaf\.md$
7
8
  - id: end-of-file-fixer
8
9
  - id: trailing-whitespace
9
10
  - id: check-yaml
@@ -18,3 +18,6 @@ Wrap prose at natural breakpoints in phrases or punctuation to keep max
18
18
  line length below 80 characters.
19
19
 
20
20
  Agents should never make commits to Git.
21
+
22
+ Prefer tests that include multiple scenarios to comprehensively test
23
+ a feature in one function over many different test functions.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: calkit-python
3
- Version: 0.38.2
3
+ Version: 0.38.4
4
4
  Summary: Reproducibility simplified.
5
5
  Project-URL: Homepage, https://calkit.org
6
6
  Project-URL: Issues, https://github.com/calkit/calkit/issues
@@ -26,9 +26,9 @@ Requires-Dist: arithmeval
26
26
  Requires-Dist: bibtexparser
27
27
  Requires-Dist: checksumdir
28
28
  Requires-Dist: docx2pdf
29
- Requires-Dist: dvc==3.66.1
29
+ Requires-Dist: dvc==3.67.1
30
30
  Requires-Dist: fastapi
31
- Requires-Dist: fsspec>=2026.2.0
31
+ Requires-Dist: fsspec>=2026.4.0
32
32
  Requires-Dist: gitpython
33
33
  Requires-Dist: json2latex>=0.0.3
34
34
  Requires-Dist: jupyterlab>=4.4.5
@@ -45,10 +45,10 @@ Requires-Dist: python-dotenv>=1
45
45
  Requires-Dist: pywin32; platform_system == 'Windows'
46
46
  Requires-Dist: requests
47
47
  Requires-Dist: sqlitedict>=2.1.0
48
- Requires-Dist: texsoup>=0.3.1
48
+ Requires-Dist: texsoup>=0.3.3
49
49
  Requires-Dist: toml>=0.10.2
50
50
  Requires-Dist: tqdm>=4.67.1
51
- Requires-Dist: typer==0.24.1
51
+ Requires-Dist: typer==0.25.1
52
52
  Requires-Dist: uvicorn
53
53
  Provides-Extra: data
54
54
  Requires-Dist: pandas>=2.2.3; extra == 'data'
@@ -209,6 +209,11 @@ all scientific or analytical computing projects.
209
209
 
210
210
  <!-- INCLUDE: docs/quickstart.md +1 -->
211
211
 
212
+ <!-- prettier-ignore -->
213
+ !!! note
214
+ `ck` is an abbreviated alias for the `calkit` executable.
215
+ All `calkit` commands can be run as `ck` instead, e.g., `ck save -am "..."`.
216
+
212
217
  ### From an existing project
213
218
 
214
219
  If you want to use Calkit with an existing project,
@@ -150,6 +150,11 @@ all scientific or analytical computing projects.
150
150
 
151
151
  <!-- INCLUDE: docs/quickstart.md +1 -->
152
152
 
153
+ <!-- prettier-ignore -->
154
+ !!! note
155
+ `ck` is an abbreviated alias for the `calkit` executable.
156
+ All `calkit` commands can be run as `ck` instead, e.g., `ck save -am "..."`.
157
+
153
158
  ### From an existing project
154
159
 
155
160
  If you want to use Calkit with an existing project,
@@ -0,0 +1,83 @@
1
+ from importlib.metadata import version as _version
2
+
3
+ __version__ = _version("calkit-python")
4
+
5
+ from .core import * # noqa: F403, I001
6
+
7
+ # Lazy-load submodules to speed up imports
8
+ _SUBMODULES = {
9
+ "git",
10
+ "dvc",
11
+ "cloud",
12
+ "fs",
13
+ "jupyter",
14
+ "config",
15
+ "models",
16
+ "office",
17
+ "templates",
18
+ "conda",
19
+ "calc",
20
+ "check",
21
+ "github",
22
+ "invenio",
23
+ "releases",
24
+ "licenses",
25
+ "overleaf",
26
+ "julia",
27
+ "notebooks",
28
+ "environments",
29
+ "pipeline",
30
+ "matlab",
31
+ "datasets",
32
+ "detect",
33
+ "docker",
34
+ "gui",
35
+ "magics",
36
+ "ops",
37
+ "server",
38
+ }
39
+
40
+
41
+ def __getattr__(name: str):
42
+ if name in _SUBMODULES:
43
+ import importlib
44
+
45
+ mod = importlib.import_module(f"calkit.{name}")
46
+ globals()[name] = mod
47
+ return mod
48
+ if name == "declare_notebook":
49
+ from .notebooks import declare_notebook
50
+
51
+ globals()["declare_notebook"] = declare_notebook
52
+ return declare_notebook
53
+ raise AttributeError(f"module 'calkit' has no attribute {name!r}")
54
+
55
+
56
+ def _jupyter_labextension_paths():
57
+ return [{"src": "labextension", "dest": "calkit"}]
58
+
59
+
60
+ def _jupyter_server_extension_points():
61
+ return [{"module": "calkit"}]
62
+
63
+
64
+ def _load_jupyter_server_extension(server_app):
65
+ """Registers the API handler to receive HTTP requests from the frontend
66
+ extension.
67
+
68
+ Parameters
69
+ ----------
70
+ server_app: jupyterlab.labapp.LabApp
71
+ JupyterLab application instance
72
+ """
73
+ import os
74
+
75
+ from .jupyterlab.routes import setup_route_handlers
76
+
77
+ # Change to root_dir so all handlers work in the correct directory context
78
+ root_dir = server_app.root_dir
79
+ os.chdir(root_dir)
80
+ server_app.log.info(f"Changed working directory to {root_dir}")
81
+ setup_route_handlers(server_app.web_app)
82
+ name = "calkit"
83
+ server_app.log.info(f"Registered {name} server extension")
@@ -3,8 +3,6 @@
3
3
  import os
4
4
  from typing import Callable
5
5
 
6
- import git
7
- from git.exc import InvalidGitRepositoryError
8
6
  from pydantic import BaseModel, computed_field
9
7
 
10
8
  import calkit
@@ -176,6 +174,9 @@ def check_reproducibility(
176
174
  wdir: str = ".", log_func: Callable | None = None
177
175
  ) -> ReproCheck:
178
176
  """Check the reproducibility of a project."""
177
+ import git
178
+ from git.exc import InvalidGitRepositoryError
179
+
179
180
  res = dict()
180
181
  if log_func is None:
181
182
  log_func = print
@@ -11,22 +11,11 @@ import subprocess
11
11
  from typing import Annotated, Callable
12
12
 
13
13
  import dotenv
14
- import git
15
14
  import typer
16
15
 
17
16
  import calkit
18
- import calkit.environments
19
- import calkit.matlab
20
- import calkit.pipeline
21
- from calkit.check import check_reproducibility
22
17
  from calkit.cli import raise_error, warn
23
18
  from calkit.core import get_md5
24
- from calkit.environments import (
25
- get_all_conda_lock_fpaths,
26
- get_all_docker_lock_fpaths,
27
- get_all_venv_lock_fpaths,
28
- get_env_lock_fpath,
29
- )
30
19
 
31
20
  check_app = typer.Typer(no_args_is_help=True)
32
21
 
@@ -249,6 +238,8 @@ def check_repro(
249
238
  ] = ".",
250
239
  ) -> None:
251
240
  """Check the reproducibility of a project."""
241
+ from calkit.check import check_reproducibility
242
+
252
243
  res = check_reproducibility(wdir=wdir, log_func=typer.echo)
253
244
  calkit.echo(res.to_pretty())
254
245
 
@@ -268,6 +259,13 @@ def check_environment(
268
259
  ] = False,
269
260
  ) -> str | None:
270
261
  """Check that an environment is up-to-date."""
262
+ from calkit.environments import (
263
+ get_all_conda_lock_fpaths,
264
+ get_all_docker_lock_fpaths,
265
+ get_all_venv_lock_fpaths,
266
+ get_env_lock_fpath,
267
+ )
268
+
271
269
  dotenv.load_dotenv(dotenv_path=".env", verbose=verbose)
272
270
  ck_info = calkit.load_calkit_info(process_includes="environments")
273
271
  envs = ck_info.get("environments", {})
@@ -353,8 +351,8 @@ def check_environment(
353
351
  raise_error("venv environments require a prefix")
354
352
  if "path" not in env:
355
353
  raise_error("venv environments require a path")
356
- prefix = env["prefix"]
357
- path = env["path"]
354
+ prefix = os.path.expandvars(env["prefix"])
355
+ path = os.path.expandvars(env["path"])
358
356
  lock_fpath = get_env_lock_fpath(
359
357
  env=env, env_name=env_name, as_posix=False
360
358
  )
@@ -457,6 +455,10 @@ def check_environments(
457
455
  if not envs:
458
456
  typer.echo("No environments defined in calkit.yaml")
459
457
  return
458
+ # Set any project-level environmental variables before checking
459
+ # environments
460
+ dotenv.load_dotenv(dotenv_path=".env", verbose=verbose)
461
+ calkit.set_env_vars(ck_info=ck_info, cli=True)
460
462
  failures = []
461
463
  for env_name, env in envs.items():
462
464
  if env.get("kind") in calkit.environments.KINDS_NO_CHECK:
@@ -1290,6 +1292,8 @@ def check_env_vars(
1290
1292
  dotenv_path=".env", key_to_set=name, value_to_set=value
1291
1293
  )
1292
1294
  # Ensure that .env is ignored by git
1295
+ import git
1296
+
1293
1297
  repo = git.Repo()
1294
1298
  if not repo.ignored(".env"):
1295
1299
  typer.echo("Adding .env to .gitignore")
@@ -8,7 +8,6 @@ import webbrowser
8
8
  from typing import Annotated
9
9
 
10
10
  import typer
11
- from requests.exceptions import HTTPError
12
11
 
13
12
  import calkit
14
13
  from calkit.cli import raise_error
@@ -47,6 +46,8 @@ def login(
47
46
  First try a GET request to the /user endpoint to check if the user is
48
47
  already logged in. If not, perform OAuth device flow.
49
48
  """
49
+ from requests.exceptions import HTTPError
50
+
50
51
  try:
51
52
  calkit.cloud.get("/user")
52
53
  calkit.echo("Authenticated successfully ✅")
@@ -6,15 +6,11 @@ import glob
6
6
  import os
7
7
  import subprocess
8
8
 
9
- import git
10
9
  import typer
11
- from git.exc import InvalidGitRepositoryError
12
10
  from typing_extensions import Annotated
13
11
 
14
12
  import calkit
15
- from calkit import config
16
13
  from calkit.cli.core import raise_error
17
- from calkit.dvc import configure_remote, get_remotes, set_remote_auth
18
14
 
19
15
  config_app = typer.Typer(no_args_is_help=True)
20
16
 
@@ -22,6 +18,8 @@ config_app = typer.Typer(no_args_is_help=True)
22
18
  @config_app.command(name="set")
23
19
  def set_config_value(key: str, value: str):
24
20
  """Set a value in the config."""
21
+ from calkit import config
22
+
25
23
  keys = config.Settings.model_fields.keys()
26
24
  if key not in keys:
27
25
  raise_error(
@@ -38,6 +36,8 @@ def set_config_value(key: str, value: str):
38
36
  @config_app.command(name="get")
39
37
  def get_config_value(key: str) -> None:
40
38
  """Get and print a value from the config."""
39
+ from calkit import config
40
+
41
41
  cfg = config.read().model_dump()
42
42
  if key not in cfg:
43
43
  raise_error(
@@ -53,6 +53,8 @@ def get_config_value(key: str) -> None:
53
53
  @config_app.command(name="unset")
54
54
  def unset_config_value(key: str):
55
55
  """Unset a value in the config, returning it to default."""
56
+ from calkit import config
57
+
56
58
  model_fields = config.Settings.model_fields
57
59
  if key not in model_fields:
58
60
  raise_error(
@@ -90,6 +92,11 @@ def setup_remote(
90
92
  """Setup the Calkit cloud as the default DVC remote and store a token in
91
93
  the local config.
92
94
  """
95
+ import git
96
+ from git.exc import InvalidGitRepositoryError
97
+
98
+ from calkit.dvc import configure_remote, set_remote_auth
99
+
93
100
  try:
94
101
  remote_name = configure_remote(use_ck=not http)
95
102
  set_remote_auth(remote_name=remote_name)
@@ -119,6 +126,8 @@ def setup_remote_auth():
119
126
  """Store a Calkit cloud token in the local DVC config for all Calkit
120
127
  remotes.
121
128
  """
129
+ from calkit.dvc import get_remotes, set_remote_auth
130
+
122
131
  try:
123
132
  remotes = get_remotes()
124
133
  except Exception:
@@ -132,6 +141,8 @@ def setup_remote_auth():
132
141
  @config_app.command(name="list")
133
142
  def list_config_keys():
134
143
  """List keys in the config."""
144
+ from calkit import config
145
+
135
146
  cfg = config.read()
136
147
  for key in cfg.model_dump():
137
148
  typer.echo(key)
@@ -140,6 +151,8 @@ def list_config_keys():
140
151
  @config_app.command(name="github-ssh")
141
152
  def config_github_ssh():
142
153
  """Walk through the process of adding an SSH key to GitHub."""
154
+ import git
155
+
143
156
  typer.echo("Checking if you can already connect to GitHub via SSH")
144
157
  # First check if we can already connect to GitHub
145
158
  ssh_test_cmd = ["ssh", "-T", "git@github.com"]
@@ -0,0 +1,85 @@
1
+ """Core CLI functionality."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ import re
7
+ import subprocess
8
+ from typing import TYPE_CHECKING
9
+
10
+ import typer
11
+ from typer.core import TyperGroup
12
+
13
+ if TYPE_CHECKING:
14
+ import click
15
+
16
+
17
+ class AliasGroup(TyperGroup):
18
+ """TyperGroup that resolves command aliases defined with '|' in the name."""
19
+
20
+ _CMD_SPLIT_P = re.compile(r" ?[,|] ?")
21
+
22
+ def get_command(self, ctx, cmd_name):
23
+ cmd_name = self._group_cmd_name(cmd_name)
24
+ return super().get_command(ctx, cmd_name)
25
+
26
+ def _group_cmd_name(self, default_name):
27
+ for cmd in self.commands.values():
28
+ name = cmd.name
29
+ if name and default_name in self._CMD_SPLIT_P.split(name):
30
+ return name
31
+ return default_name
32
+
33
+
34
+ def complete_stage_names(
35
+ ctx: "click.Context",
36
+ param: "click.Parameter",
37
+ incomplete: str,
38
+ ) -> list:
39
+ """Return pipeline stage names for shell tab-completion."""
40
+ if not os.path.isfile("calkit.yaml"):
41
+ return []
42
+ try:
43
+ import ruamel.yaml
44
+ from click.shell_completion import CompletionItem
45
+
46
+ ryaml = ruamel.yaml.YAML()
47
+ with open("calkit.yaml") as f:
48
+ info = ryaml.load(f) or {}
49
+ stages = info.get("pipeline", {}).get("stages", {})
50
+ return [
51
+ CompletionItem(name)
52
+ for name in stages
53
+ if name.startswith(incomplete)
54
+ ]
55
+ except Exception:
56
+ return []
57
+
58
+
59
+ def print_sep(name: str):
60
+ width = 66
61
+ txt_width = len(name) + 2
62
+ buffer_width = (width - txt_width) // 2
63
+ buffer = "-" * buffer_width
64
+ line = f"{buffer} {name} {buffer}"
65
+ if len(line) == (width - 1):
66
+ line += "-"
67
+ typer.echo(line)
68
+
69
+
70
+ def run_cmd(cmd: list[str]):
71
+ if os.name == "nt":
72
+ subprocess.call(cmd)
73
+ else:
74
+ import pty
75
+
76
+ pty.spawn(cmd, lambda fd: os.read(fd, 1024))
77
+
78
+
79
+ def raise_error(txt: str):
80
+ typer.echo(typer.style("Error: " + str(txt), fg="red"), err=True)
81
+ raise typer.Exit(1)
82
+
83
+
84
+ def warn(txt: str, prefix: str = "Warning: "):
85
+ typer.echo(typer.style(prefix + str(txt), fg="yellow"))
@@ -9,16 +9,10 @@ import os
9
9
  from copy import deepcopy
10
10
  from typing import Annotated
11
11
 
12
- import git
13
- import requests
14
12
  import typer
15
- from tqdm import tqdm
16
13
 
17
14
  import calkit
18
- import calkit.invenio
19
15
  from calkit.cli import raise_error
20
- from calkit.dvc import run_dvc_command
21
- from calkit.models.core import _ImportedFromProject
22
16
 
23
17
  import_app = typer.Typer(no_args_is_help=True)
24
18
 
@@ -72,12 +66,19 @@ def import_dataset(
72
66
  "remote instead of ck://."
73
67
  ),
74
68
  ),
75
- ] = not calkit.dvc.USE_CK_REMOTE_BY_DEFAULT,
69
+ ] = False,
76
70
  ):
77
71
  """Import a dataset.
78
72
 
79
73
  Currently only supports datasets kept in DVC, not Git.
80
74
  """
75
+ import git
76
+ import requests
77
+ from tqdm import tqdm
78
+
79
+ from calkit.dvc import run_dvc_command
80
+ from calkit.models.core import _ImportedFromProject
81
+
81
82
  # Ensure we don't already have a dataset at this path
82
83
  path_split = src_path.split("/")
83
84
  owner_name = path_split[0]
@@ -260,6 +261,8 @@ def import_environment(
260
261
  ] = False,
261
262
  ) -> None:
262
263
  """Import an environment from another project."""
264
+ import git
265
+
263
266
  raise_error(
264
267
  "This command is not yet implemented; "
265
268
  "please thumbs-up this issue if you'd like to see "
@@ -368,6 +371,11 @@ def import_from_zenodo(
368
371
  ] = False,
369
372
  ):
370
373
  """Import files from a Zenodo record."""
374
+ import git
375
+ import requests
376
+
377
+ from calkit.dvc import run_dvc_command
378
+
371
379
  # Ensure destination directory either doesn't exist or is empty
372
380
  if os.path.isdir(dest_dir):
373
381
  if os.listdir(dest_dir):
@@ -7,9 +7,9 @@ from typing import Annotated, Literal
7
7
  import typer
8
8
 
9
9
  import calkit
10
- from calkit.cli import warn
10
+ from calkit.cli import AliasGroup, warn
11
11
 
12
- list_app = typer.Typer(no_args_is_help=True)
12
+ list_app = typer.Typer(cls=AliasGroup, no_args_is_help=True)
13
13
 
14
14
 
15
15
  def _list_objects(
@@ -50,33 +50,37 @@ def _list_objects(
50
50
  typer.echo(f" {k}: {v}")
51
51
 
52
52
 
53
- @list_app.command(name="notebooks")
53
+ @list_app.command(name="notebooks|nb")
54
54
  def list_notebooks():
55
+ """List notebooks in the project."""
55
56
  _list_objects("notebooks")
56
57
 
57
58
 
58
- @list_app.command(name="figures")
59
+ @list_app.command(name="figures|figs")
59
60
  def list_figures():
61
+ """List figures in the project."""
60
62
  _list_objects("figures")
61
63
 
62
64
 
63
65
  @list_app.command(name="datasets")
64
66
  def list_datasets():
67
+ """List datasets in the project."""
65
68
  _list_objects("datasets")
66
69
 
67
70
 
68
- @list_app.command(name="publications")
71
+ @list_app.command(name="publications|pubs")
69
72
  def list_publications():
73
+ """List publications in the project."""
70
74
  _list_objects("publications")
71
75
 
72
76
 
73
- @list_app.command(name="references")
77
+ @list_app.command(name="references|refs")
74
78
  def list_references():
79
+ """List reference collections in the project."""
75
80
  _list_objects("references")
76
81
 
77
82
 
78
- @list_app.command(name="environments")
79
- @list_app.command(name="envs")
83
+ @list_app.command(name="environments|envs")
80
84
  def list_environments():
81
85
  """List environments in the project."""
82
86
  envs = calkit.load_calkit_info().get("environments", {})
@@ -88,6 +92,7 @@ def list_environments():
88
92
 
89
93
  @list_app.command(name="templates")
90
94
  def list_templates():
95
+ """List all available Calkit templates."""
91
96
  for kind, tpl_dict in calkit.templates.TEMPLATES.items():
92
97
  for name in tpl_dict:
93
98
  typer.echo(f"{kind}/{name}")
@@ -95,6 +100,7 @@ def list_templates():
95
100
 
96
101
  @list_app.command(name="procedures")
97
102
  def list_procedures():
103
+ """List procedures in the current project."""
98
104
  ck_info = calkit.load_calkit_info()
99
105
  for p in ck_info.get("procedures", {}):
100
106
  typer.echo(p)
@@ -134,9 +140,29 @@ def list_stages(
134
140
  typer.Option("--kind", "-k", help="Filter stages by kind."),
135
141
  ] = None,
136
142
  ):
137
- """List stages."""
143
+ """List pipeline stages."""
138
144
  stages = calkit.load_calkit_info().get("pipeline", {}).get("stages", {})
139
145
  for name, stage in stages.items():
140
146
  if kinds is not None and stage.get("kind") not in kinds:
141
147
  continue
142
148
  typer.echo(name)
149
+
150
+
151
+ @list_app.command(name="remotes")
152
+ def list_remotes():
153
+ """List Git and DVC remotes."""
154
+ import git
155
+
156
+ try:
157
+ repo = git.Repo()
158
+ for remote in repo.remotes:
159
+ typer.echo(f"(Git) {remote.name}: {remote.url}")
160
+ except Exception as e:
161
+ warn(f"Could not list Git remotes: {e}")
162
+ # Now DVC remotes
163
+ try:
164
+ dvc_remotes = calkit.dvc.get_remotes()
165
+ for name, url in dvc_remotes.items():
166
+ typer.echo(f"(DVC) {name}: {url}")
167
+ except Exception as e:
168
+ warn(f"Could not list DVC remotes: {e}")