calkit-python 0.41.18__py3-none-any.whl → 0.41.20__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- calkit/cli/core.py +2 -2
- calkit/cli/latex.py +45 -1
- calkit/cli/list.py +12 -10
- calkit/cli/main/core.py +20 -3
- calkit/cli/new.py +645 -473
- calkit/cli/scheduler.py +60 -18
- calkit/cli/update.py +2 -3
- calkit/detect.py +62 -0
- calkit/dvc/zip.py +17 -0
- calkit/models/core.py +27 -26
- calkit/models/pipeline.py +71 -6
- calkit/pipeline.py +181 -2
- calkit/releases.py +53 -0
- calkit/tests/cli/main/test_core.py +82 -1
- calkit/tests/cli/test_latex.py +32 -0
- calkit/tests/cli/test_new.py +209 -0
- calkit/tests/cli/test_scheduler.py +18 -0
- calkit/tests/dvc/test_zip.py +25 -0
- calkit/tests/models/test_pipeline.py +94 -2
- calkit/tests/test_detect.py +31 -0
- calkit/tests/test_pipeline.py +115 -1
- {calkit_python-0.41.18.dist-info → calkit_python-0.41.20.dist-info}/METADATA +2 -2
- {calkit_python-0.41.18.dist-info → calkit_python-0.41.20.dist-info}/RECORD +41 -41
- {calkit_python-0.41.18.data → calkit_python-0.41.20.data}/data/etc/jupyter/jupyter_server_config.d/calkit.json +0 -0
- {calkit_python-0.41.18.data → calkit_python-0.41.20.data}/data/share/jupyter/labextensions/calkit/install.json +0 -0
- {calkit_python-0.41.18.data → calkit_python-0.41.20.data}/data/share/jupyter/labextensions/calkit/package.json +0 -0
- {calkit_python-0.41.18.data → calkit_python-0.41.20.data}/data/share/jupyter/labextensions/calkit/schemas/calkit/package.json.orig +0 -0
- {calkit_python-0.41.18.data → calkit_python-0.41.20.data}/data/share/jupyter/labextensions/calkit/schemas/calkit/plugin.json +0 -0
- {calkit_python-0.41.18.data → calkit_python-0.41.20.data}/data/share/jupyter/labextensions/calkit/static/502.9a2c5772a15466e923ef.js +0 -0
- {calkit_python-0.41.18.data → calkit_python-0.41.20.data}/data/share/jupyter/labextensions/calkit/static/695.2c41003a452d43d2b358.js +0 -0
- {calkit_python-0.41.18.data → calkit_python-0.41.20.data}/data/share/jupyter/labextensions/calkit/static/867.a42a046aa5108f54f8fb.js +0 -0
- {calkit_python-0.41.18.data → calkit_python-0.41.20.data}/data/share/jupyter/labextensions/calkit/static/909.e3f9cc3408834a7fdcc3.js +0 -0
- {calkit_python-0.41.18.data → calkit_python-0.41.20.data}/data/share/jupyter/labextensions/calkit/static/946.050af2abf7845cfbdbd2.js +0 -0
- {calkit_python-0.41.18.data → calkit_python-0.41.20.data}/data/share/jupyter/labextensions/calkit/static/946.050af2abf7845cfbdbd2.js.LICENSE.txt +0 -0
- {calkit_python-0.41.18.data → calkit_python-0.41.20.data}/data/share/jupyter/labextensions/calkit/static/b2f1c3efe70cb539d121.png +0 -0
- {calkit_python-0.41.18.data → calkit_python-0.41.20.data}/data/share/jupyter/labextensions/calkit/static/remoteEntry.ac9035764d5b2adbb542.js +0 -0
- {calkit_python-0.41.18.data → calkit_python-0.41.20.data}/data/share/jupyter/labextensions/calkit/static/style.js +0 -0
- {calkit_python-0.41.18.data → calkit_python-0.41.20.data}/data/share/jupyter/labextensions/calkit/static/third-party-licenses.json +0 -0
- {calkit_python-0.41.18.dist-info → calkit_python-0.41.20.dist-info}/WHEEL +0 -0
- {calkit_python-0.41.18.dist-info → calkit_python-0.41.20.dist-info}/entry_points.txt +0 -0
- {calkit_python-0.41.18.dist-info → calkit_python-0.41.20.dist-info}/licenses/LICENSE +0 -0
calkit/cli/core.py
CHANGED
|
@@ -5,7 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
import os
|
|
6
6
|
import re
|
|
7
7
|
import subprocess
|
|
8
|
-
from typing import TYPE_CHECKING
|
|
8
|
+
from typing import TYPE_CHECKING, NoReturn
|
|
9
9
|
|
|
10
10
|
import typer
|
|
11
11
|
from typer.core import TyperGroup
|
|
@@ -96,7 +96,7 @@ def run_cmd(cmd: list[str]):
|
|
|
96
96
|
pty.spawn(cmd, lambda fd: os.read(fd, 1024))
|
|
97
97
|
|
|
98
98
|
|
|
99
|
-
def raise_error(txt: str):
|
|
99
|
+
def raise_error(txt: str) -> NoReturn:
|
|
100
100
|
typer.echo(typer.style("Error: " + str(txt), fg="red"), err=True)
|
|
101
101
|
raise typer.Exit(1)
|
|
102
102
|
|
calkit/cli/latex.py
CHANGED
|
@@ -7,6 +7,7 @@ import os
|
|
|
7
7
|
import string
|
|
8
8
|
import subprocess
|
|
9
9
|
from copy import deepcopy
|
|
10
|
+
from pathlib import Path
|
|
10
11
|
|
|
11
12
|
import typer
|
|
12
13
|
from typing_extensions import Annotated
|
|
@@ -135,6 +136,36 @@ def build(
|
|
|
135
136
|
help="Path to a latexmkrc file to use for compilation.",
|
|
136
137
|
),
|
|
137
138
|
] = None,
|
|
139
|
+
output_dir: Annotated[
|
|
140
|
+
str | None,
|
|
141
|
+
typer.Option(
|
|
142
|
+
"--output-dir",
|
|
143
|
+
help=(
|
|
144
|
+
"Directory for the compiled PDF, relative to the current "
|
|
145
|
+
"directory. Passed to latexmk as -outdir."
|
|
146
|
+
),
|
|
147
|
+
),
|
|
148
|
+
] = None,
|
|
149
|
+
aux_dir: Annotated[
|
|
150
|
+
str | None,
|
|
151
|
+
typer.Option(
|
|
152
|
+
"--aux-dir",
|
|
153
|
+
help=(
|
|
154
|
+
"Directory for auxiliary files, relative to the current "
|
|
155
|
+
"directory. Passed to latexmk as -auxdir."
|
|
156
|
+
),
|
|
157
|
+
),
|
|
158
|
+
] = None,
|
|
159
|
+
latexmk_args: Annotated[
|
|
160
|
+
list[str],
|
|
161
|
+
typer.Option(
|
|
162
|
+
"--latexmk-arg",
|
|
163
|
+
help=(
|
|
164
|
+
"Extra argument to pass through to latexmk. Repeat the option "
|
|
165
|
+
"to pass more than one."
|
|
166
|
+
),
|
|
167
|
+
),
|
|
168
|
+
] = [],
|
|
138
169
|
no_synctex: Annotated[
|
|
139
170
|
bool,
|
|
140
171
|
typer.Option(
|
|
@@ -173,7 +204,20 @@ def build(
|
|
|
173
204
|
latexmk_cmd.append("-silent")
|
|
174
205
|
if force:
|
|
175
206
|
latexmk_cmd.append("-f")
|
|
176
|
-
|
|
207
|
+
# latexmk runs with -cd, so its -outdir/-auxdir are relative to the .tex
|
|
208
|
+
# file's directory; convert the (current-directory-relative) Calkit paths
|
|
209
|
+
# into that frame.
|
|
210
|
+
tex_dir = os.path.dirname(tex_file) or "."
|
|
211
|
+
if output_dir is not None:
|
|
212
|
+
rel = Path(os.path.relpath(output_dir, tex_dir)).as_posix()
|
|
213
|
+
latexmk_cmd.append(f"-outdir={rel}")
|
|
214
|
+
if aux_dir is not None:
|
|
215
|
+
rel = Path(os.path.relpath(aux_dir, tex_dir)).as_posix()
|
|
216
|
+
latexmk_cmd.append(f"-auxdir={rel}")
|
|
217
|
+
latexmk_cmd.append("-interaction=nonstopmode")
|
|
218
|
+
# User pass-through args come last so they can override Calkit's defaults.
|
|
219
|
+
latexmk_cmd += latexmk_args
|
|
220
|
+
latexmk_cmd.append(tex_file)
|
|
177
221
|
if environment is not None:
|
|
178
222
|
if no_check:
|
|
179
223
|
check_cmd = ["--no-check"]
|
calkit/cli/list.py
CHANGED
|
@@ -261,21 +261,23 @@ def list_releases():
|
|
|
261
261
|
objs = calkit.load_calkit_info().get("releases", {})
|
|
262
262
|
for name, obj in objs.items():
|
|
263
263
|
typer.echo(name + ":")
|
|
264
|
-
#
|
|
264
|
+
# Figure out if the release is published. Internal releases are never
|
|
265
|
+
# uploaded to an archival service, so skip the lookup for them.
|
|
265
266
|
published = None
|
|
266
|
-
|
|
267
|
-
published = calkit.invenio.get(
|
|
268
|
-
f"/records/{obj.get('record_id')}",
|
|
269
|
-
service=obj.get("publisher"),
|
|
270
|
-
)["is_published"]
|
|
271
|
-
except Exception:
|
|
267
|
+
if not obj.get("internal"):
|
|
272
268
|
try:
|
|
273
269
|
published = calkit.invenio.get(
|
|
274
|
-
f"/records/{obj.get('record_id')}
|
|
270
|
+
f"/records/{obj.get('record_id')}",
|
|
275
271
|
service=obj.get("publisher"),
|
|
276
272
|
)["is_published"]
|
|
277
|
-
except Exception
|
|
278
|
-
|
|
273
|
+
except Exception:
|
|
274
|
+
try:
|
|
275
|
+
published = calkit.invenio.get(
|
|
276
|
+
f"/records/{obj.get('record_id')}/draft",
|
|
277
|
+
service=obj.get("publisher"),
|
|
278
|
+
)["is_published"]
|
|
279
|
+
except Exception as e:
|
|
280
|
+
warn(f"Cannot tell if release {name} is published: {e}")
|
|
279
281
|
if published is not None:
|
|
280
282
|
typer.echo(f" published: {published}")
|
|
281
283
|
for k, v in obj.items():
|
calkit/cli/main/core.py
CHANGED
|
@@ -179,11 +179,26 @@ def init(
|
|
|
179
179
|
typer.Option(
|
|
180
180
|
"--force",
|
|
181
181
|
"-f",
|
|
182
|
-
help="
|
|
182
|
+
help="Re-initialize even if the project is already initialized.",
|
|
183
183
|
),
|
|
184
184
|
] = False,
|
|
185
185
|
):
|
|
186
186
|
"""Initialize the current working directory."""
|
|
187
|
+
import git
|
|
188
|
+
from git.exc import InvalidGitRepositoryError
|
|
189
|
+
|
|
190
|
+
def _project_is_initialized() -> bool:
|
|
191
|
+
try:
|
|
192
|
+
git.Repo(".", search_parent_directories=False)
|
|
193
|
+
except InvalidGitRepositoryError:
|
|
194
|
+
return False
|
|
195
|
+
return os.path.isfile(".dvc/config") and os.path.isfile("calkit.yaml")
|
|
196
|
+
|
|
197
|
+
if _project_is_initialized() and not force:
|
|
198
|
+
raise_error(
|
|
199
|
+
"This project is already initialized. "
|
|
200
|
+
"Use --force to re-initialize."
|
|
201
|
+
)
|
|
187
202
|
subprocess.run(["git", "init"])
|
|
188
203
|
result = calkit.dvc.run_dvc_command(
|
|
189
204
|
["init"] + (["--force"] if force else [])
|
|
@@ -197,13 +212,15 @@ def init(
|
|
|
197
212
|
# Commit the newly created .dvc directory
|
|
198
213
|
repo = calkit.git.get_repo()
|
|
199
214
|
repo.git.add(".dvc")
|
|
200
|
-
|
|
215
|
+
if calkit.git.get_staged_files(repo=repo):
|
|
216
|
+
repo.git.commit("-m", "Initialize DVC")
|
|
201
217
|
# Create an empty calkit.yaml if one doesn't already exist
|
|
202
218
|
if not os.path.isfile("calkit.yaml"):
|
|
203
219
|
with open("calkit.yaml", "w"):
|
|
204
220
|
pass
|
|
205
221
|
repo.git.add("calkit.yaml")
|
|
206
|
-
|
|
222
|
+
if calkit.git.get_staged_files(repo=repo):
|
|
223
|
+
repo.git.commit("-m", "Initialize Calkit")
|
|
207
224
|
# TODO: Initialize `dvc.yaml`
|
|
208
225
|
# TODO: Add a sane .gitignore file
|
|
209
226
|
# TODO: Add a sane LICENSE file?
|