calkit-python 0.41.14__py3-none-any.whl → 0.41.16__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/check.py +5 -2
- calkit/cli/config.py +53 -6
- calkit/cli/main/core.py +14 -1
- calkit/cli/new.py +1 -1
- calkit/cli/notebooks.py +17 -10
- calkit/cli/update.py +1 -1
- calkit/core.py +7 -3
- calkit/detect.py +64 -0
- calkit/environments.py +18 -2
- calkit/julia.py +29 -2
- calkit/notebooks.py +1 -3
- calkit/pipeline.py +32 -8
- calkit/tests/jupyterlab/conftest.py +7 -0
- calkit/tests/test_core.py +15 -0
- calkit/tests/test_detect.py +49 -0
- calkit/tests/test_julia.py +46 -0
- calkit/tests/test_pipeline.py +49 -0
- {calkit_python-0.41.14.data → calkit_python-0.41.16.data}/data/share/jupyter/labextensions/calkit/package.json +3 -23
- {calkit_python-0.41.14.data → calkit_python-0.41.16.data}/data/share/jupyter/labextensions/calkit/schemas/calkit/package.json.orig +2 -22
- calkit_python-0.41.14.data/data/share/jupyter/labextensions/calkit/static/remoteEntry.65469af996e7a96aa983.js → calkit_python-0.41.16.data/data/share/jupyter/labextensions/calkit/static/remoteEntry.ac9035764d5b2adbb542.js +1 -1
- {calkit_python-0.41.14.dist-info → calkit_python-0.41.16.dist-info}/METADATA +1 -1
- {calkit_python-0.41.14.dist-info → calkit_python-0.41.16.dist-info}/RECORD +37 -36
- {calkit_python-0.41.14.data → calkit_python-0.41.16.data}/data/etc/jupyter/jupyter_server_config.d/calkit.json +0 -0
- {calkit_python-0.41.14.data → calkit_python-0.41.16.data}/data/share/jupyter/labextensions/calkit/install.json +0 -0
- {calkit_python-0.41.14.data → calkit_python-0.41.16.data}/data/share/jupyter/labextensions/calkit/schemas/calkit/plugin.json +0 -0
- {calkit_python-0.41.14.data → calkit_python-0.41.16.data}/data/share/jupyter/labextensions/calkit/static/502.9a2c5772a15466e923ef.js +0 -0
- {calkit_python-0.41.14.data → calkit_python-0.41.16.data}/data/share/jupyter/labextensions/calkit/static/695.2c41003a452d43d2b358.js +0 -0
- {calkit_python-0.41.14.data → calkit_python-0.41.16.data}/data/share/jupyter/labextensions/calkit/static/867.a42a046aa5108f54f8fb.js +0 -0
- {calkit_python-0.41.14.data → calkit_python-0.41.16.data}/data/share/jupyter/labextensions/calkit/static/909.e3f9cc3408834a7fdcc3.js +0 -0
- {calkit_python-0.41.14.data → calkit_python-0.41.16.data}/data/share/jupyter/labextensions/calkit/static/946.050af2abf7845cfbdbd2.js +0 -0
- {calkit_python-0.41.14.data → calkit_python-0.41.16.data}/data/share/jupyter/labextensions/calkit/static/946.050af2abf7845cfbdbd2.js.LICENSE.txt +0 -0
- {calkit_python-0.41.14.data → calkit_python-0.41.16.data}/data/share/jupyter/labextensions/calkit/static/b2f1c3efe70cb539d121.png +0 -0
- {calkit_python-0.41.14.data → calkit_python-0.41.16.data}/data/share/jupyter/labextensions/calkit/static/style.js +0 -0
- {calkit_python-0.41.14.data → calkit_python-0.41.16.data}/data/share/jupyter/labextensions/calkit/static/third-party-licenses.json +0 -0
- {calkit_python-0.41.14.dist-info → calkit_python-0.41.16.dist-info}/WHEEL +0 -0
- {calkit_python-0.41.14.dist-info → calkit_python-0.41.16.dist-info}/entry_points.txt +0 -0
- {calkit_python-0.41.14.dist-info → calkit_python-0.41.16.dist-info}/licenses/LICENSE +0 -0
calkit/cli/check.py
CHANGED
|
@@ -180,7 +180,8 @@ def _check_julia_env(
|
|
|
180
180
|
try:
|
|
181
181
|
subprocess.check_call(
|
|
182
182
|
cmd,
|
|
183
|
-
env=os.environ.copy()
|
|
183
|
+
env=os.environ.copy()
|
|
184
|
+
| {"JULIA_LOAD_PATH": calkit.julia.load_path()},
|
|
184
185
|
)
|
|
185
186
|
except subprocess.CalledProcessError:
|
|
186
187
|
calkit.environments.save_cache(
|
|
@@ -206,7 +207,9 @@ def _check_julia_env(
|
|
|
206
207
|
cmd = calkit.julia.ensure_startup_file_disabled_in_command(cmd)
|
|
207
208
|
try:
|
|
208
209
|
subprocess.check_call(
|
|
209
|
-
cmd,
|
|
210
|
+
cmd,
|
|
211
|
+
env=os.environ.copy()
|
|
212
|
+
| {"JULIA_LOAD_PATH": calkit.julia.load_path()},
|
|
210
213
|
)
|
|
211
214
|
except subprocess.CalledProcessError:
|
|
212
215
|
calkit.environments.save_cache(
|
calkit/cli/config.py
CHANGED
|
@@ -4,6 +4,8 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import glob
|
|
6
6
|
import os
|
|
7
|
+
import platform
|
|
8
|
+
import re
|
|
7
9
|
import subprocess
|
|
8
10
|
|
|
9
11
|
import typer
|
|
@@ -233,12 +235,57 @@ def config_github_ssh():
|
|
|
233
235
|
subprocess.run(keygen_cmd)
|
|
234
236
|
# Start the SSH agent in the background
|
|
235
237
|
typer.echo("Checking that the SSH agent is running")
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
).
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
238
|
+
# Note that under git bash / MSYS (MSYSTEM is set) we get a POSIX
|
|
239
|
+
# ssh-agent on PATH, so we use the POSIX path even on Windows there.
|
|
240
|
+
native_windows = platform.system() == "Windows" and not os.environ.get(
|
|
241
|
+
"MSYSTEM"
|
|
242
|
+
)
|
|
243
|
+
if native_windows:
|
|
244
|
+
# On native Windows, OpenSSH's ssh-agent runs as a Windows service
|
|
245
|
+
# rather than exporting environment variables to the current shell.
|
|
246
|
+
# The service ships disabled by default, so ensure it's enabled
|
|
247
|
+
# before starting it (enabling requires administrator privileges).
|
|
248
|
+
p = subprocess.run(
|
|
249
|
+
[
|
|
250
|
+
"powershell",
|
|
251
|
+
"-NoProfile",
|
|
252
|
+
"-Command",
|
|
253
|
+
(
|
|
254
|
+
"if ((Get-Service ssh-agent).StartType -eq 'Disabled') "
|
|
255
|
+
"{ Set-Service ssh-agent -StartupType Manual }; "
|
|
256
|
+
"Start-Service ssh-agent"
|
|
257
|
+
),
|
|
258
|
+
],
|
|
259
|
+
capture_output=True,
|
|
260
|
+
text=True,
|
|
261
|
+
)
|
|
262
|
+
if p.returncode != 0:
|
|
263
|
+
err = (p.stderr.strip() or p.stdout.strip()).lower()
|
|
264
|
+
if "access" in err and "denied" in err:
|
|
265
|
+
raise_error(
|
|
266
|
+
"Failed to start ssh-agent service: access denied.\n"
|
|
267
|
+
"The ssh-agent service is disabled and enabling it "
|
|
268
|
+
"requires administrator privileges. Please run the "
|
|
269
|
+
"following in an elevated (Run as administrator) "
|
|
270
|
+
"PowerShell, then try again:\n\n"
|
|
271
|
+
" Set-Service ssh-agent -StartupType Manual; "
|
|
272
|
+
"Start-Service ssh-agent"
|
|
273
|
+
)
|
|
274
|
+
raise_error(
|
|
275
|
+
"Failed to start ssh-agent service: "
|
|
276
|
+
f"{p.stderr.strip() or p.stdout.strip()}"
|
|
277
|
+
)
|
|
278
|
+
else:
|
|
279
|
+
# On POSIX systems, ssh-agent -s prints shell commands that export
|
|
280
|
+
# SSH_AUTH_SOCK and SSH_AGENT_PID; parse them into our environment so
|
|
281
|
+
# the subsequent ssh-add call can find the agent
|
|
282
|
+
p = subprocess.run(["ssh-agent", "-s"], capture_output=True, text=True)
|
|
283
|
+
if p.returncode != 0:
|
|
284
|
+
raise_error("Failed to start ssh-agent")
|
|
285
|
+
for match in re.finditer(
|
|
286
|
+
r"(SSH_AUTH_SOCK|SSH_AGENT_PID)=([^;\n]+);", p.stdout
|
|
287
|
+
):
|
|
288
|
+
os.environ[match.group(1)] = match.group(2)
|
|
242
289
|
# Add the SSH key to the ssh-agent
|
|
243
290
|
typer.echo(f"Adding SSH key to ssh-agent: {key_path}")
|
|
244
291
|
cmd = ["ssh-add", key_path]
|
calkit/cli/main/core.py
CHANGED
|
@@ -581,6 +581,18 @@ def get_status(
|
|
|
581
581
|
if pipeline_status and not pipeline_status.has_pipeline:
|
|
582
582
|
typer.echo("This project has no pipeline.")
|
|
583
583
|
return
|
|
584
|
+
# A failed environment check makes get_status bail out before computing
|
|
585
|
+
# staleness, leaving stale_stages empty. Don't let that masquerade as an
|
|
586
|
+
# up-to-date pipeline---say plainly that the status is unknown.
|
|
587
|
+
elif pipeline_status and pipeline_status.failed_environment_checks:
|
|
588
|
+
# The failing environments were already named in the warning emitted
|
|
589
|
+
# right after computing pipeline_status, so keep this explanatory
|
|
590
|
+
# only rather than repeating the list.
|
|
591
|
+
typer.echo(
|
|
592
|
+
"Pipeline status unavailable until the failed environment "
|
|
593
|
+
"checks above are resolved."
|
|
594
|
+
)
|
|
595
|
+
return
|
|
584
596
|
elif pipeline_status and pipeline_status.is_stale:
|
|
585
597
|
typer.echo("Stale stages:")
|
|
586
598
|
for stage_name in pipeline_status.stale_stage_names:
|
|
@@ -2586,7 +2598,8 @@ def run_in_env(
|
|
|
2586
2598
|
subprocess.check_call(
|
|
2587
2599
|
julia_cmd,
|
|
2588
2600
|
cwd=wdir,
|
|
2589
|
-
env=os.environ.copy()
|
|
2601
|
+
env=os.environ.copy()
|
|
2602
|
+
| {"JULIA_LOAD_PATH": calkit.julia.load_path()},
|
|
2590
2603
|
)
|
|
2591
2604
|
except subprocess.CalledProcessError:
|
|
2592
2605
|
raise_error("Failed to run in julia environment")
|
calkit/cli/new.py
CHANGED
|
@@ -2108,7 +2108,7 @@ def new_julia_env(
|
|
|
2108
2108
|
except subprocess.CalledProcessError:
|
|
2109
2109
|
raise_error(f"Failed to install Julia version {julia_version}")
|
|
2110
2110
|
cmd = ["julia", f"+{julia_version}", f"--project={env_dir}", "-e"]
|
|
2111
|
-
install_cmd = f'using Pkg; Pkg.activate("{env_dir}");'
|
|
2111
|
+
install_cmd = f'using Pkg; Pkg.activate("{calkit.julia.escape_string(env_dir)}");'
|
|
2112
2112
|
for package in packages or []:
|
|
2113
2113
|
install_cmd += f' Pkg.add("{package}");'
|
|
2114
2114
|
cmd.append(install_cmd)
|
calkit/cli/notebooks.py
CHANGED
|
@@ -310,14 +310,18 @@ def check_env_kernel(
|
|
|
310
310
|
"still failed."
|
|
311
311
|
)
|
|
312
312
|
# Don't include version in display_name; IJulia appends it automatically
|
|
313
|
+
# Escape interpolated values for the Julia string literals---notably the
|
|
314
|
+
# Windows project path, whose backslashes are otherwise read as invalid
|
|
315
|
+
# unicode escapes.
|
|
316
|
+
esc = calkit.julia.escape_string
|
|
313
317
|
julia_cmd = (
|
|
314
318
|
"import IJulia;"
|
|
315
319
|
"kp=IJulia.installkernel("
|
|
316
|
-
f'"{kernel_name}",'
|
|
317
|
-
f'"--project={env_dir_abs}",'
|
|
320
|
+
f'"{esc(kernel_name)}",'
|
|
321
|
+
f'"--project={esc(env_dir_abs)}",'
|
|
318
322
|
'"--startup-file=no",'
|
|
319
|
-
f'displayname="{display_name}",'
|
|
320
|
-
'env=Dict("JULIA_LOAD_PATH" => "
|
|
323
|
+
f'displayname="{esc(display_name)}",'
|
|
324
|
+
f'env=Dict("JULIA_LOAD_PATH" => "{esc(calkit.julia.load_path())}")'
|
|
321
325
|
");"
|
|
322
326
|
"println(kp);"
|
|
323
327
|
)
|
|
@@ -474,8 +478,7 @@ def execute_notebook(
|
|
|
474
478
|
# Create this environment and write it to file
|
|
475
479
|
envs[res.name] = res.env
|
|
476
480
|
ck_info["environments"] = envs
|
|
477
|
-
|
|
478
|
-
calkit.ryaml.dump(ck_info, f)
|
|
481
|
+
calkit.save_calkit_info(ck_info)
|
|
479
482
|
# Detect language from environment
|
|
480
483
|
if language is None:
|
|
481
484
|
detected_language = language_from_notebook(path)
|
|
@@ -501,16 +504,20 @@ def execute_notebook(
|
|
|
501
504
|
raise ValueError(
|
|
502
505
|
"Language must be one of 'python', 'matlab', 'julia', or 'r'"
|
|
503
506
|
)
|
|
504
|
-
# Try to set kernelspec metadata so execution uses the expected kernel
|
|
507
|
+
# Try to set kernelspec metadata so execution uses the expected kernel.
|
|
508
|
+
# Always read/write as UTF-8: notebooks routinely contain non-ASCII (e.g.,
|
|
509
|
+
# Greek letters such as "ν" in code), and on Windows the default open()
|
|
510
|
+
# encoding is cp1252, which mangles UTF-8 content into mojibake ("ν" ->
|
|
511
|
+
# "ν") and breaks execution.
|
|
505
512
|
try:
|
|
506
|
-
with open(path, "r") as f:
|
|
513
|
+
with open(path, "r", encoding="utf-8") as f:
|
|
507
514
|
nb_json = json.load(f)
|
|
508
515
|
metadata = nb_json.setdefault("metadata", {})
|
|
509
516
|
kernelspec = metadata.setdefault("kernelspec", {})
|
|
510
517
|
kernelspec["name"] = kernel_name
|
|
511
518
|
kernelspec["display_name"] = display_name
|
|
512
|
-
kernelspec
|
|
513
|
-
with open(path, "w") as f:
|
|
519
|
+
kernelspec["language"] = language.lower()
|
|
520
|
+
with open(path, "w", encoding="utf-8") as f:
|
|
514
521
|
json.dump(nb_json, f, indent=1)
|
|
515
522
|
except Exception as e:
|
|
516
523
|
if verbose:
|
calkit/cli/update.py
CHANGED
|
@@ -746,7 +746,7 @@ def update_julia_env(
|
|
|
746
746
|
env_dir = os.path.dirname(spec_path) or "."
|
|
747
747
|
julia_version = env.get("julia")
|
|
748
748
|
julia_bin = ["julia", f"+{julia_version}"] if julia_version else ["julia"]
|
|
749
|
-
cmds = [f'Pkg.activate("{env_dir}")']
|
|
749
|
+
cmds = [f'Pkg.activate("{calkit.julia.escape_string(env_dir)}")']
|
|
750
750
|
if add:
|
|
751
751
|
pkg_list = "[" + ", ".join(f'"{p}"' for p in add) + "]"
|
|
752
752
|
cmds.append(f"Pkg.add({pkg_list})")
|
calkit/core.py
CHANGED
|
@@ -144,7 +144,9 @@ def load_calkit_info(
|
|
|
144
144
|
if wdir is not None:
|
|
145
145
|
fpath = os.path.join(wdir, fpath)
|
|
146
146
|
if os.path.isfile(fpath):
|
|
147
|
-
|
|
147
|
+
# Always read as UTF-8; on Windows the default open() encoding is
|
|
148
|
+
# cp1252, which mangles non-ASCII content (e.g., Greek letters).
|
|
149
|
+
with open(fpath, encoding="utf-8") as f:
|
|
148
150
|
info = ryaml.load(f)
|
|
149
151
|
if info is None:
|
|
150
152
|
info = {}
|
|
@@ -166,7 +168,7 @@ def load_calkit_info(
|
|
|
166
168
|
if wdir is not None:
|
|
167
169
|
include_fpath = os.path.join(wdir, include_fpath)
|
|
168
170
|
if os.path.isfile(include_fpath):
|
|
169
|
-
with open(include_fpath) as f:
|
|
171
|
+
with open(include_fpath, encoding="utf-8") as f:
|
|
170
172
|
include_data = ryaml.load(f)
|
|
171
173
|
info[kind][obj_name] |= include_data
|
|
172
174
|
return info
|
|
@@ -180,7 +182,9 @@ def save_calkit_info(
|
|
|
180
182
|
fpath = "calkit.yaml"
|
|
181
183
|
if wdir is not None:
|
|
182
184
|
fpath = os.path.join(wdir, fpath)
|
|
183
|
-
|
|
185
|
+
# Always write as UTF-8; on Windows the default open() encoding is cp1252,
|
|
186
|
+
# which mangles non-ASCII content (e.g., Greek letters) into mojibake.
|
|
187
|
+
with open(fpath, "w", encoding="utf-8") as f:
|
|
184
188
|
ryaml.dump(info, f)
|
|
185
189
|
|
|
186
190
|
|
calkit/detect.py
CHANGED
|
@@ -1229,6 +1229,49 @@ def _extract_r_string_assignments(code: str) -> dict[str, str]:
|
|
|
1229
1229
|
return assignments
|
|
1230
1230
|
|
|
1231
1231
|
|
|
1232
|
+
def _extract_r_string_vector_assignments(code: str) -> dict[str, list[str]]:
|
|
1233
|
+
"""Extract character-vector assignments in R code.
|
|
1234
|
+
|
|
1235
|
+
Captures assignments of the form ``x <- c("a", "b")`` so that a later
|
|
1236
|
+
``pacman::p_load(char = x)`` can be resolved back to its package list.
|
|
1237
|
+
"""
|
|
1238
|
+
assignments = {}
|
|
1239
|
+
pattern = re.compile(
|
|
1240
|
+
r"([A-Za-z_][A-Za-z0-9_.]*)\s*(?:<-|=)\s*c\(([^)]*)\)",
|
|
1241
|
+
flags=re.DOTALL,
|
|
1242
|
+
)
|
|
1243
|
+
for name, body in pattern.findall(code):
|
|
1244
|
+
strings = re.findall(r'["\']([a-zA-Z0-9._]+)["\']', body)
|
|
1245
|
+
if strings:
|
|
1246
|
+
assignments[name] = strings
|
|
1247
|
+
return assignments
|
|
1248
|
+
|
|
1249
|
+
|
|
1250
|
+
def _resolve_r_package_args(
|
|
1251
|
+
call_args: str, vector_assignments: dict[str, list[str]]
|
|
1252
|
+
) -> set[str]:
|
|
1253
|
+
"""Resolve package names from a ``pacman::p_load()`` argument list.
|
|
1254
|
+
|
|
1255
|
+
Handles quoted literals, inline ``c(...)`` vectors, bare (non-standard
|
|
1256
|
+
evaluation) names like ``p_load(dplyr, tidyr)``, and ``char = x`` where
|
|
1257
|
+
``x`` is a character vector assigned earlier in the script.
|
|
1258
|
+
"""
|
|
1259
|
+
packages = set()
|
|
1260
|
+
# Quoted strings are package names, whether passed directly or inside c()
|
|
1261
|
+
packages.update(re.findall(r'["\']([a-zA-Z0-9._]+)["\']', call_args))
|
|
1262
|
+
# char = <var> referencing a character-vector assignment
|
|
1263
|
+
for var in re.findall(r"char\s*=\s*([A-Za-z_][A-Za-z0-9_.]*)", call_args):
|
|
1264
|
+
packages.update(vector_assignments.get(var, []))
|
|
1265
|
+
# Bare names passed positionally; drop keyword arguments (install=, update=,
|
|
1266
|
+
# character.only=, etc.) and their values before collecting identifiers
|
|
1267
|
+
stripped = re.sub(r"[A-Za-z_][A-Za-z0-9_.]*\s*=\s*[^,]+", "", call_args)
|
|
1268
|
+
for token in re.findall(r"[A-Za-z_][A-Za-z0-9_.]*", stripped):
|
|
1269
|
+
# c() is the vector constructor, not a package; TRUE/FALSE are values
|
|
1270
|
+
if token not in {"c", "TRUE", "FALSE", "T", "F"}:
|
|
1271
|
+
packages.add(token)
|
|
1272
|
+
return packages
|
|
1273
|
+
|
|
1274
|
+
|
|
1232
1275
|
def _extract_julia_string_assignments(code: str) -> dict[str, str]:
|
|
1233
1276
|
"""Extract simple string assignments in Julia code."""
|
|
1234
1277
|
assignments = {}
|
|
@@ -1622,6 +1665,27 @@ def detect_r_dependencies(
|
|
|
1622
1665
|
for pattern in patterns:
|
|
1623
1666
|
matches = re.findall(pattern, code)
|
|
1624
1667
|
dependencies.update(matches)
|
|
1668
|
+
# requireNamespace()/loadNamespace() take the package as a string and are
|
|
1669
|
+
# commonly used to guard optional installs (e.g. pacman/here bootstrapping)
|
|
1670
|
+
dependencies.update(
|
|
1671
|
+
re.findall(
|
|
1672
|
+
r'(?:require|load)Namespace\s*\(\s*["\']([a-zA-Z0-9._]+)["\']',
|
|
1673
|
+
code,
|
|
1674
|
+
)
|
|
1675
|
+
)
|
|
1676
|
+
# Qualified calls like pkg::fn() or pkg:::fn() reference a package without
|
|
1677
|
+
# ever attaching it, so the package itself is still a dependency
|
|
1678
|
+
dependencies.update(re.findall(r"\b([a-zA-Z][a-zA-Z0-9._]*)\s*:::?", code))
|
|
1679
|
+
# pacman::p_load() loads (and optionally installs) packages dynamically; its
|
|
1680
|
+
# arguments may be bare names, quoted strings, or a character vector passed
|
|
1681
|
+
# via char=, possibly referencing a variable assigned earlier in the script
|
|
1682
|
+
vector_assignments = _extract_r_string_vector_assignments(code)
|
|
1683
|
+
for call_args in re.findall(
|
|
1684
|
+
r"p_load\s*\(((?:[^()]|\([^()]*\))*)\)", code, flags=re.DOTALL
|
|
1685
|
+
):
|
|
1686
|
+
dependencies.update(
|
|
1687
|
+
_resolve_r_package_args(call_args, vector_assignments)
|
|
1688
|
+
)
|
|
1625
1689
|
# Filter out base R packages
|
|
1626
1690
|
base_packages = {
|
|
1627
1691
|
"base",
|
calkit/environments.py
CHANGED
|
@@ -5,6 +5,7 @@ import hashlib
|
|
|
5
5
|
import json
|
|
6
6
|
import os
|
|
7
7
|
import platform
|
|
8
|
+
import re
|
|
8
9
|
import subprocess
|
|
9
10
|
import tempfile
|
|
10
11
|
from pathlib import Path
|
|
@@ -1454,7 +1455,9 @@ def create_julia_project_file_content(
|
|
|
1454
1455
|
return content
|
|
1455
1456
|
|
|
1456
1457
|
|
|
1457
|
-
def create_r_description_content(
|
|
1458
|
+
def create_r_description_content(
|
|
1459
|
+
dependencies: list[str], project_name: str | None = None
|
|
1460
|
+
) -> str:
|
|
1458
1461
|
"""Generate R DESCRIPTION file content listing dependencies.
|
|
1459
1462
|
|
|
1460
1463
|
This creates a minimal DESCRIPTION file that renv can work with.
|
|
@@ -1463,13 +1466,26 @@ def create_r_description_content(dependencies: list[str]) -> str:
|
|
|
1463
1466
|
----------
|
|
1464
1467
|
dependencies : list[str]
|
|
1465
1468
|
List of R package names.
|
|
1469
|
+
project_name : str | None
|
|
1470
|
+
Name for the DESCRIPTION's ``Package`` field. It is sanitized into a
|
|
1471
|
+
valid R package name (letters, numbers and dots, starting with a
|
|
1472
|
+
letter). Falls back to the detected project name, then to
|
|
1473
|
+
``CalkitProject``.
|
|
1466
1474
|
|
|
1467
1475
|
Returns
|
|
1468
1476
|
-------
|
|
1469
1477
|
str
|
|
1470
1478
|
The DESCRIPTION file content.
|
|
1471
1479
|
"""
|
|
1472
|
-
|
|
1480
|
+
if project_name is None:
|
|
1481
|
+
project_name = calkit.detect_project_name(prepend_owner=False)
|
|
1482
|
+
# Valid R package names may only contain letters, numbers and dots, and
|
|
1483
|
+
# must start with a letter, so replace anything else (e.g. hyphens) with a
|
|
1484
|
+
# dot and prefix a letter if needed
|
|
1485
|
+
package_name = re.sub(r"[^A-Za-z0-9.]+", ".", project_name).strip(".")
|
|
1486
|
+
if not package_name or not package_name[0].isalpha():
|
|
1487
|
+
package_name = "Calkit." + package_name if package_name else "Calkit"
|
|
1488
|
+
content = f"""Package: {package_name}
|
|
1473
1489
|
Version: 0.0.1
|
|
1474
1490
|
Title: Auto-generated R environment
|
|
1475
1491
|
"""
|
calkit/julia.py
CHANGED
|
@@ -27,9 +27,36 @@ def get_julia_exe() -> str:
|
|
|
27
27
|
return "julia"
|
|
28
28
|
|
|
29
29
|
|
|
30
|
+
def load_path() -> str:
|
|
31
|
+
"""Return the ``JULIA_LOAD_PATH`` scoping resolution to the active project
|
|
32
|
+
and stdlib.
|
|
33
|
+
|
|
34
|
+
Julia splits ``JULIA_LOAD_PATH`` on the platform path separator---``;`` on
|
|
35
|
+
Windows and ``:`` elsewhere---so a hardcoded ``:`` leaves ``@stdlib`` off
|
|
36
|
+
the load path on Windows and even stdlib packages (e.g. ``Pkg``) fail to
|
|
37
|
+
resolve. ``os.pathsep`` matches Julia's rule on every platform.
|
|
38
|
+
"""
|
|
39
|
+
return os.pathsep.join(["@", "@stdlib"])
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def escape_string(value: str) -> str:
|
|
43
|
+
"""Escape ``value`` for embedding in a Julia double-quoted string literal.
|
|
44
|
+
|
|
45
|
+
Julia treats ``\\``, ``"`` and ``$`` specially inside double quotes. In
|
|
46
|
+
particular a Windows path like ``C:\\Users\\...`` is otherwise read as an
|
|
47
|
+
invalid ``\\U`` unicode escape, so any value interpolated into Julia source
|
|
48
|
+
(e.g., a ``--project`` path passed via ``julia -e``) must be escaped.
|
|
49
|
+
"""
|
|
50
|
+
return value.replace("\\", "\\\\").replace('"', '\\"').replace("$", "\\$")
|
|
51
|
+
|
|
52
|
+
|
|
30
53
|
def _is_julia_command(arg: str) -> bool:
|
|
31
|
-
"""Whether ``arg`` is a Julia executable (julia or the juliaup launcher).
|
|
32
|
-
|
|
54
|
+
"""Whether ``arg`` is a Julia executable (julia or the juliaup launcher).
|
|
55
|
+
|
|
56
|
+
The comparison is case-insensitive so Windows paths like ``julia.EXE``
|
|
57
|
+
(e.g. the ``WindowsApps`` execution-alias shim) are recognized.
|
|
58
|
+
"""
|
|
59
|
+
base = os.path.basename(arg).lower()
|
|
33
60
|
if base.endswith(".exe"):
|
|
34
61
|
base = base[: -len(".exe")]
|
|
35
62
|
return base in ("julia", "julialauncher")
|
calkit/notebooks.py
CHANGED
|
@@ -242,11 +242,9 @@ def declare_notebook(
|
|
|
242
242
|
}
|
|
243
243
|
)
|
|
244
244
|
# Write calkit.yaml
|
|
245
|
-
fpath = os.path.join(wdir, "calkit.yaml")
|
|
246
245
|
ck_info["pipeline"] = pipeline_dict
|
|
247
246
|
ck_info["notebooks"] = notebooks
|
|
248
|
-
|
|
249
|
-
calkit.ryaml.dump(ck_info, f)
|
|
247
|
+
calkit.save_calkit_info(ck_info, wdir=wdir)
|
|
250
248
|
if must_be_rerun:
|
|
251
249
|
raise RuntimeError(
|
|
252
250
|
f"Notebook stage '{stage_name}' was modified while the pipeline "
|
calkit/pipeline.py
CHANGED
|
@@ -1011,6 +1011,35 @@ def get_output_storage_map(
|
|
|
1011
1011
|
return result
|
|
1012
1012
|
|
|
1013
1013
|
|
|
1014
|
+
def _dump_yaml_if_changed(data, fpath: str, verbose: bool = False) -> bool:
|
|
1015
|
+
"""Write ``data`` to ``fpath`` as YAML only if it changes the file.
|
|
1016
|
+
|
|
1017
|
+
``calkit status`` recompiles the pipeline to DVC on every call, and the VS
|
|
1018
|
+
Code extension polls status continuously. Blindly rewriting an identical
|
|
1019
|
+
file causes two problems: (1) bumping ``dvc.yaml``'s mtime wakes the
|
|
1020
|
+
extension's file watcher, which triggers yet another status poll---an
|
|
1021
|
+
endless loop that keeps re-taking DVC's lock; and (2) the serializer formats
|
|
1022
|
+
slightly differently across platforms and ruamel versions, so the file
|
|
1023
|
+
churns in Git for no real change. Comparison is on the parsed structure, so
|
|
1024
|
+
trivial reformatting is not treated as a change. DVC keys stage staleness on
|
|
1025
|
+
``dvc.lock`` (not on ``dvc.yaml``'s mtime), so skipping a no-op write is
|
|
1026
|
+
safe. Returns whether the file was written.
|
|
1027
|
+
"""
|
|
1028
|
+
if os.path.isfile(fpath):
|
|
1029
|
+
try:
|
|
1030
|
+
with open(fpath) as f:
|
|
1031
|
+
if (calkit.ryaml.load(f) or {}) == data:
|
|
1032
|
+
return False
|
|
1033
|
+
except Exception:
|
|
1034
|
+
# Unreadable or invalid existing YAML: fall through and overwrite.
|
|
1035
|
+
pass
|
|
1036
|
+
if verbose:
|
|
1037
|
+
typer.echo(f"Writing to {os.path.basename(fpath)}")
|
|
1038
|
+
with open(fpath, "w") as f:
|
|
1039
|
+
calkit.ryaml.dump(data, f)
|
|
1040
|
+
return True
|
|
1041
|
+
|
|
1042
|
+
|
|
1014
1043
|
def to_dvc(
|
|
1015
1044
|
ck_info: dict | None = None,
|
|
1016
1045
|
wdir: str | None = None,
|
|
@@ -1099,8 +1128,7 @@ def to_dvc(
|
|
|
1099
1128
|
with open(dvc_yaml_fpath) as f:
|
|
1100
1129
|
existing = calkit.ryaml.load(f) or {}
|
|
1101
1130
|
existing.setdefault("stages", {}).update(wrapper_stages)
|
|
1102
|
-
|
|
1103
|
-
calkit.ryaml.dump(existing, f)
|
|
1131
|
+
_dump_yaml_if_changed(existing, dvc_yaml_fpath)
|
|
1104
1132
|
return wrapper_stages
|
|
1105
1133
|
# Detect stages with the old ``slurm:`` field before model validation
|
|
1106
1134
|
# because model_validate pops it in place.
|
|
@@ -1194,8 +1222,7 @@ def to_dvc(
|
|
|
1194
1222
|
for sname in slurm_field_stages:
|
|
1195
1223
|
stage_data = ck_yaml_data["pipeline"]["stages"][sname]
|
|
1196
1224
|
stage_data["scheduler"] = stage_data.pop("slurm")
|
|
1197
|
-
|
|
1198
|
-
calkit.ryaml.dump(ck_yaml_data, _f)
|
|
1225
|
+
_dump_yaml_if_changed(ck_yaml_data, ck_yaml_path)
|
|
1199
1226
|
# Validate and initialize scheduler options (SLURM/PBS) for stages
|
|
1200
1227
|
# whose outer environment is a job scheduler. Env defaults are applied
|
|
1201
1228
|
# at job-submission time, not here.
|
|
@@ -1372,10 +1399,7 @@ def to_dvc(
|
|
|
1372
1399
|
dvc_stages[stage_name] = stage
|
|
1373
1400
|
dvc_yaml["stages"] = dvc_stages
|
|
1374
1401
|
dvc_yaml_fpath = os.path.join(wdir, "dvc.yaml") if wdir else "dvc.yaml"
|
|
1375
|
-
|
|
1376
|
-
if verbose:
|
|
1377
|
-
typer.echo("Writing to dvc.yaml")
|
|
1378
|
-
calkit.ryaml.dump(dvc_yaml, f)
|
|
1402
|
+
_dump_yaml_if_changed(dvc_yaml, dvc_yaml_fpath, verbose=verbose)
|
|
1379
1403
|
# DVC errors out (FileIsGitIgnored) if dvc.lock is Git-ignored, so make
|
|
1380
1404
|
# sure it isn't---this keeps both status and pipeline runs working
|
|
1381
1405
|
calkit.dvc.ensure_dvc_lock_not_ignored(wdir)
|
calkit/tests/test_core.py
CHANGED
|
@@ -43,6 +43,21 @@ def test_detect_project_name(tmp_dir):
|
|
|
43
43
|
assert calkit.detect_project_name() == "someone-else/some-project"
|
|
44
44
|
|
|
45
45
|
|
|
46
|
+
def test_save_calkit_info_preserves_unicode(tmp_dir):
|
|
47
|
+
# Regression: on Windows, opening calkit.yaml without encoding="utf-8"
|
|
48
|
+
# writes as cp1252, which either errors or corrupts non-ASCII content
|
|
49
|
+
# (e.g., the Greek letter "ν") into mojibake ("ν"). ruamel dumps raw
|
|
50
|
+
# unicode (allow_unicode=True), so the encoding of the file handle matters.
|
|
51
|
+
info = {"name": "p", "owner": "o", "title": "viscosity ν"}
|
|
52
|
+
calkit.save_calkit_info(info)
|
|
53
|
+
# The value must survive the round-trip intact.
|
|
54
|
+
assert calkit.load_calkit_info()["title"] == "viscosity ν"
|
|
55
|
+
# Raw bytes must be the UTF-8 encoding of "ν", not cp1252 mojibake.
|
|
56
|
+
raw = open("calkit.yaml", "rb").read()
|
|
57
|
+
assert "ν".encode("utf-8") in raw
|
|
58
|
+
assert "ν".encode("utf-8") not in raw
|
|
59
|
+
|
|
60
|
+
|
|
46
61
|
def test_load_calkit_info(tmp_dir, monkeypatch):
|
|
47
62
|
subpath = "some/project"
|
|
48
63
|
os.makedirs(subpath)
|
calkit/tests/test_detect.py
CHANGED
|
@@ -863,6 +863,41 @@ data <- read.csv("data.csv")
|
|
|
863
863
|
assert "tidyr" in deps
|
|
864
864
|
# Base packages should not be included
|
|
865
865
|
assert "base" not in deps
|
|
866
|
+
# Qualified calls (pkg::fn), requireNamespace/loadNamespace, and
|
|
867
|
+
# pacman::p_load with a character vector should all be detected
|
|
868
|
+
pacman_content = """
|
|
869
|
+
if (!requireNamespace("here", quietly = TRUE)) install.packages("here")
|
|
870
|
+
here::i_am("code/master.R")
|
|
871
|
+
loadNamespace("withr")
|
|
872
|
+
pkgs <- c(
|
|
873
|
+
"haven", "readxl",
|
|
874
|
+
"dplyr", "ggplot2"
|
|
875
|
+
)
|
|
876
|
+
pacman::p_load(char = pkgs, install = TRUE, character.only = TRUE)
|
|
877
|
+
pacman::p_load(stringr, tidyr)
|
|
878
|
+
pacman::p_load("forcats", c("janitor", "lubridate"))
|
|
879
|
+
"""
|
|
880
|
+
deps = detect_r_dependencies(code=pacman_content)
|
|
881
|
+
# Qualified call and the requireNamespace/loadNamespace guards
|
|
882
|
+
assert "here" in deps
|
|
883
|
+
assert "pacman" in deps
|
|
884
|
+
assert "withr" in deps
|
|
885
|
+
# Vector resolved via char =
|
|
886
|
+
assert "haven" in deps
|
|
887
|
+
assert "readxl" in deps
|
|
888
|
+
assert "ggplot2" in deps
|
|
889
|
+
# Bare non-standard-evaluation names
|
|
890
|
+
assert "stringr" in deps
|
|
891
|
+
assert "tidyr" in deps
|
|
892
|
+
# Quoted names and inline c() vectors
|
|
893
|
+
assert "forcats" in deps
|
|
894
|
+
assert "janitor" in deps
|
|
895
|
+
assert "lubridate" in deps
|
|
896
|
+
# The vector constructor and keyword-argument values are not packages
|
|
897
|
+
assert "c" not in deps
|
|
898
|
+
assert "TRUE" not in deps
|
|
899
|
+
assert "install" not in deps
|
|
900
|
+
assert "character.only" not in deps
|
|
866
901
|
|
|
867
902
|
|
|
868
903
|
def test_detect_r_dependencies_from_code():
|
|
@@ -1064,6 +1099,20 @@ def test_create_r_description_file(tmp_dir):
|
|
|
1064
1099
|
assert "dplyr" in content
|
|
1065
1100
|
assert "tidyr" in content
|
|
1066
1101
|
assert "Imports:" in content
|
|
1102
|
+
# The Package field reflects the project name (sanitized to a valid R
|
|
1103
|
+
# package name), not a hard-coded placeholder
|
|
1104
|
+
from calkit.environments import create_r_description_content
|
|
1105
|
+
|
|
1106
|
+
content = create_r_description_content(deps, project_name="AI-Games")
|
|
1107
|
+
assert "Package: AI.Games" in content
|
|
1108
|
+
assert "CalkitProject" not in content
|
|
1109
|
+
# Names that don't start with a letter get a valid prefix
|
|
1110
|
+
content = create_r_description_content(deps, project_name="2023-study")
|
|
1111
|
+
package_line = [
|
|
1112
|
+
ln for ln in content.splitlines() if ln.startswith("Package:")
|
|
1113
|
+
][0]
|
|
1114
|
+
package_name = package_line.split(":", 1)[1].strip()
|
|
1115
|
+
assert package_name[0].isalpha()
|
|
1067
1116
|
|
|
1068
1117
|
|
|
1069
1118
|
def test_create_files_in_subdirectory(tmp_dir):
|
calkit/tests/test_julia.py
CHANGED
|
@@ -1,16 +1,40 @@
|
|
|
1
1
|
"""Tests for ``calkit.julia``"""
|
|
2
2
|
|
|
3
|
+
import os
|
|
3
4
|
from unittest import mock
|
|
4
5
|
|
|
5
6
|
import pytest
|
|
6
7
|
|
|
7
8
|
from calkit.julia import (
|
|
9
|
+
_is_julia_command,
|
|
8
10
|
check_version_in_command,
|
|
9
11
|
ensure_startup_file_disabled_in_command,
|
|
12
|
+
escape_string,
|
|
10
13
|
get_julia_exe,
|
|
14
|
+
load_path,
|
|
11
15
|
)
|
|
12
16
|
|
|
13
17
|
|
|
18
|
+
def test_escape_string_windows_path():
|
|
19
|
+
# A Windows path embedded in a Julia string literal must have its
|
|
20
|
+
# backslashes escaped, otherwise "C:\\Users" is read as an invalid \\U
|
|
21
|
+
# unicode escape (ParseError).
|
|
22
|
+
assert escape_string("C:\\Users\\peteb") == "C:\\\\Users\\\\peteb"
|
|
23
|
+
# Double quotes and dollar signs are the other special characters.
|
|
24
|
+
assert escape_string('a"b') == 'a\\"b'
|
|
25
|
+
assert escape_string("a$b") == "a\\$b"
|
|
26
|
+
# Plain values (e.g. the load path) are unchanged.
|
|
27
|
+
assert escape_string("@;@stdlib") == "@;@stdlib"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def test_load_path_uses_platform_separator():
|
|
31
|
+
# Julia splits JULIA_LOAD_PATH on the platform path separator, so the
|
|
32
|
+
# value must use ';' on Windows and ':' elsewhere (== os.pathsep).
|
|
33
|
+
assert load_path() == f"@{os.pathsep}@stdlib"
|
|
34
|
+
assert "@" in load_path()
|
|
35
|
+
assert "@stdlib" in load_path()
|
|
36
|
+
|
|
37
|
+
|
|
14
38
|
def test_get_julia_exe(monkeypatch, tmp_path):
|
|
15
39
|
# Prefer julia on the PATH when present
|
|
16
40
|
def which_julia(name):
|
|
@@ -44,6 +68,28 @@ def test_get_julia_exe(monkeypatch, tmp_path):
|
|
|
44
68
|
assert get_julia_exe() == "julia"
|
|
45
69
|
|
|
46
70
|
|
|
71
|
+
def test_is_julia_command_case_insensitive():
|
|
72
|
+
# Windows resolves the execution-alias shim to an uppercase extension
|
|
73
|
+
# (e.g. ``julia.EXE``); the check must still recognize it.
|
|
74
|
+
assert _is_julia_command("C:/x/julia.EXE")
|
|
75
|
+
assert _is_julia_command("C:/x/Julia.Exe")
|
|
76
|
+
assert _is_julia_command("C:/x/julialauncher.EXE")
|
|
77
|
+
assert _is_julia_command("/usr/bin/julia")
|
|
78
|
+
assert _is_julia_command("julialauncher")
|
|
79
|
+
assert not _is_julia_command("python")
|
|
80
|
+
assert not _is_julia_command("C:/x/python.exe")
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def test_disable_startup_file_accepts_uppercase_exe():
|
|
84
|
+
# Regression: julia.EXE (Windows execution alias) was rejected as not a
|
|
85
|
+
# Julia command, failing the env check and masking real pipeline status.
|
|
86
|
+
cmd = ensure_startup_file_disabled_in_command(
|
|
87
|
+
["C:/x/julia.EXE", "--version"]
|
|
88
|
+
)
|
|
89
|
+
assert cmd[0] == "C:/x/julia.EXE"
|
|
90
|
+
assert "--startup-file=no" in cmd
|
|
91
|
+
|
|
92
|
+
|
|
47
93
|
def test_check_version_in_command():
|
|
48
94
|
cmd = ["julia", "+1.11", "--project", "whatever"]
|
|
49
95
|
# Case 1: juliaup is available
|
calkit/tests/test_pipeline.py
CHANGED
|
@@ -521,6 +521,55 @@ def test_to_dvc_unignores_dvc_lock(tmp_dir):
|
|
|
521
521
|
assert not repo.ignored("dvc.lock")
|
|
522
522
|
|
|
523
523
|
|
|
524
|
+
def test_to_dvc_skips_no_op_writes(tmp_dir):
|
|
525
|
+
# Compiling to DVC happens on every `calkit status` (which the VS Code
|
|
526
|
+
# extension polls continuously). Rewriting an unchanged dvc.yaml churns Git
|
|
527
|
+
# across platforms (trivial reformatting) and wakes the extension's dvc.yaml
|
|
528
|
+
# watcher into another status poll, an endless loop that keeps re-taking
|
|
529
|
+
# DVC's lock. The write must be skipped unless the parsed content changes.
|
|
530
|
+
subprocess.check_call(["calkit", "init"])
|
|
531
|
+
ck_info = {
|
|
532
|
+
"pipeline": {
|
|
533
|
+
"stages": {
|
|
534
|
+
"s1": {
|
|
535
|
+
"kind": "command",
|
|
536
|
+
"environment": "_system",
|
|
537
|
+
"command": "echo a > a.txt",
|
|
538
|
+
"outputs": ["a.txt"],
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
},
|
|
542
|
+
}
|
|
543
|
+
with open("calkit.yaml", "w") as f:
|
|
544
|
+
calkit.ryaml.dump(ck_info, f)
|
|
545
|
+
# First compile creates dvc.yaml.
|
|
546
|
+
calkit.pipeline.to_dvc(ck_info=ck_info, write=True)
|
|
547
|
+
assert os.path.isfile("dvc.yaml")
|
|
548
|
+
# Pin an old mtime; a no-op recompile of identical content must leave it.
|
|
549
|
+
pinned = 1000000000.0
|
|
550
|
+
os.utime("dvc.yaml", (pinned, pinned))
|
|
551
|
+
calkit.pipeline.to_dvc(ck_info=ck_info, write=True)
|
|
552
|
+
assert os.path.getmtime("dvc.yaml") == pinned
|
|
553
|
+
# A semantically-equal but reformatted/commented file is also left as-is, so
|
|
554
|
+
# trivial cross-platform reformatting doesn't churn the file in Git.
|
|
555
|
+
with open("dvc.yaml") as f:
|
|
556
|
+
original = f.read()
|
|
557
|
+
with open("dvc.yaml", "w") as f:
|
|
558
|
+
f.write("# hand-written comment\n" + original)
|
|
559
|
+
with open("dvc.yaml") as f:
|
|
560
|
+
reformatted = f.read()
|
|
561
|
+
os.utime("dvc.yaml", (pinned, pinned))
|
|
562
|
+
calkit.pipeline.to_dvc(ck_info=ck_info, write=True)
|
|
563
|
+
with open("dvc.yaml") as f:
|
|
564
|
+
assert f.read() == reformatted
|
|
565
|
+
assert os.path.getmtime("dvc.yaml") == pinned
|
|
566
|
+
# A real change, though, is written.
|
|
567
|
+
ck_info["pipeline"]["stages"]["s1"]["command"] = "echo b > a.txt"
|
|
568
|
+
calkit.pipeline.to_dvc(ck_info=ck_info, write=True)
|
|
569
|
+
with open("dvc.yaml") as f:
|
|
570
|
+
assert f.read() != reformatted
|
|
571
|
+
|
|
572
|
+
|
|
524
573
|
def test_sbatch_stage_to_dvc(tmp_dir):
|
|
525
574
|
"""Cover the SLURM stage compilation paths.
|
|
526
575
|
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"clean": "jlpm clean:lib",
|
|
40
40
|
"clean:lib": "rimraf lib tsconfig.tsbuildinfo",
|
|
41
41
|
"clean:lintcache": "rimraf .eslintcache .stylelintcache",
|
|
42
|
-
"clean:labextension": "rimraf calkit/labextension calkit/_version.py",
|
|
42
|
+
"clean:labextension": "rimraf ../calkit/labextension ../calkit/_version.py",
|
|
43
43
|
"clean:all": "jlpm clean:lib && jlpm clean:labextension && jlpm clean:lintcache",
|
|
44
44
|
"eslint": "jlpm eslint:check --fix",
|
|
45
45
|
"eslint:check": "eslint . --cache --ext .ts,.tsx",
|
|
@@ -128,10 +128,10 @@
|
|
|
128
128
|
}
|
|
129
129
|
},
|
|
130
130
|
"extension": true,
|
|
131
|
-
"outputDir": "calkit/labextension",
|
|
131
|
+
"outputDir": "../calkit/labextension",
|
|
132
132
|
"schemaDir": "schema",
|
|
133
133
|
"_build": {
|
|
134
|
-
"load": "static/remoteEntry.
|
|
134
|
+
"load": "static/remoteEntry.ac9035764d5b2adbb542.js",
|
|
135
135
|
"extension": "./extension",
|
|
136
136
|
"style": "./style"
|
|
137
137
|
}
|
|
@@ -157,20 +157,6 @@
|
|
|
157
157
|
"project": "tsconfig.json",
|
|
158
158
|
"sourceType": "module"
|
|
159
159
|
},
|
|
160
|
-
"overrides": [
|
|
161
|
-
{
|
|
162
|
-
"files": [
|
|
163
|
-
"vscode-ext/**/*.ts"
|
|
164
|
-
],
|
|
165
|
-
"parserOptions": {
|
|
166
|
-
"project": "vscode-ext/tsconfig.json",
|
|
167
|
-
"sourceType": "module"
|
|
168
|
-
},
|
|
169
|
-
"rules": {
|
|
170
|
-
"@typescript-eslint/naming-convention": "off"
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
],
|
|
174
160
|
"plugins": [
|
|
175
161
|
"@typescript-eslint"
|
|
176
162
|
],
|
|
@@ -205,12 +191,6 @@
|
|
|
205
191
|
"prefer-arrow-callback": "error"
|
|
206
192
|
}
|
|
207
193
|
},
|
|
208
|
-
"prettier": {
|
|
209
|
-
"singleQuote": false,
|
|
210
|
-
"trailingComma": "all",
|
|
211
|
-
"arrowParens": "always",
|
|
212
|
-
"endOfLine": "auto"
|
|
213
|
-
},
|
|
214
194
|
"stylelint": {
|
|
215
195
|
"extends": [
|
|
216
196
|
"stylelint-config-recommended",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"clean": "jlpm clean:lib",
|
|
40
40
|
"clean:lib": "rimraf lib tsconfig.tsbuildinfo",
|
|
41
41
|
"clean:lintcache": "rimraf .eslintcache .stylelintcache",
|
|
42
|
-
"clean:labextension": "rimraf calkit/labextension calkit/_version.py",
|
|
42
|
+
"clean:labextension": "rimraf ../calkit/labextension ../calkit/_version.py",
|
|
43
43
|
"clean:all": "jlpm clean:lib && jlpm clean:labextension && jlpm clean:lintcache",
|
|
44
44
|
"eslint": "jlpm eslint:check --fix",
|
|
45
45
|
"eslint:check": "eslint . --cache --ext .ts,.tsx",
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
}
|
|
129
129
|
},
|
|
130
130
|
"extension": true,
|
|
131
|
-
"outputDir": "calkit/labextension",
|
|
131
|
+
"outputDir": "../calkit/labextension",
|
|
132
132
|
"schemaDir": "schema"
|
|
133
133
|
},
|
|
134
134
|
"eslintIgnore": [
|
|
@@ -152,20 +152,6 @@
|
|
|
152
152
|
"project": "tsconfig.json",
|
|
153
153
|
"sourceType": "module"
|
|
154
154
|
},
|
|
155
|
-
"overrides": [
|
|
156
|
-
{
|
|
157
|
-
"files": [
|
|
158
|
-
"vscode-ext/**/*.ts"
|
|
159
|
-
],
|
|
160
|
-
"parserOptions": {
|
|
161
|
-
"project": "vscode-ext/tsconfig.json",
|
|
162
|
-
"sourceType": "module"
|
|
163
|
-
},
|
|
164
|
-
"rules": {
|
|
165
|
-
"@typescript-eslint/naming-convention": "off"
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
],
|
|
169
155
|
"plugins": [
|
|
170
156
|
"@typescript-eslint"
|
|
171
157
|
],
|
|
@@ -200,12 +186,6 @@
|
|
|
200
186
|
"prefer-arrow-callback": "error"
|
|
201
187
|
}
|
|
202
188
|
},
|
|
203
|
-
"prettier": {
|
|
204
|
-
"singleQuote": false,
|
|
205
|
-
"trailingComma": "all",
|
|
206
|
-
"arrowParens": "always",
|
|
207
|
-
"endOfLine": "auto"
|
|
208
|
-
},
|
|
209
189
|
"stylelint": {
|
|
210
190
|
"extends": [
|
|
211
191
|
"stylelint-config-recommended",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var _JUPYTERLAB;(()=>{"use strict";var e,r,t,a,n,o,i,l,u,f,s,d,c,p,h,b,v,m,y,g,j,w,k,S={
|
|
1
|
+
var _JUPYTERLAB;(()=>{"use strict";var e,r,t,a,n,o,i,l,u,f,s,d,c,p,h,b,v,m,y,g,j,w,k,S={1336(e,r,t){var a={"./index":()=>Promise.all([t.e(867),t.e(345),t.e(909)]).then(()=>()=>t(5909)),"./extension":()=>Promise.all([t.e(867),t.e(345),t.e(909)]).then(()=>()=>t(5909)),"./style":()=>t.e(502).then(()=>()=>t(502))},n=(e,r)=>(t.R=r,r=t.o(a,e)?a[e]():Promise.resolve().then(()=>{throw new Error('Module "'+e+'" does not exist in container.')}),t.R=void 0,r),o=(e,r)=>{if(t.S){var a="default",n=t.S[a];if(n&&n!==e)throw new Error("Container initialization failed as it has already been initialized with a different share scope");return t.S[a]=e,t.I(a,r)}};t.d(r,{get:()=>n,init:()=>o})}},P={};function E(e){var r=P[e];if(void 0!==r)return r.exports;var t=P[e]={id:e,exports:{}};return S[e](t,t.exports,E),t.exports}E.m=S,E.c=P,E.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return E.d(r,{a:r}),r},E.d=(e,r)=>{for(var t in r)E.o(r,t)&&!E.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},E.f={},E.e=e=>Promise.all(Object.keys(E.f).reduce((r,t)=>(E.f[t](e,r),r),[])),E.u=e=>e+"."+{502:"9a2c5772a15466e923ef",695:"2c41003a452d43d2b358",867:"a42a046aa5108f54f8fb",909:"e3f9cc3408834a7fdcc3",946:"050af2abf7845cfbdbd2"}[e]+".js?v="+{502:"9a2c5772a15466e923ef",695:"2c41003a452d43d2b358",867:"a42a046aa5108f54f8fb",909:"e3f9cc3408834a7fdcc3",946:"050af2abf7845cfbdbd2"}[e],E.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),E.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),e={},r="calkit:",E.l=(t,a,n,o)=>{if(e[t])e[t].push(a);else{var i,l;if(void 0!==n)for(var u=document.getElementsByTagName("script"),f=0;f<u.length;f++){var s=u[f];if(s.getAttribute("src")==t||s.getAttribute("data-webpack")==r+n){i=s;break}}i||(l=!0,(i=document.createElement("script")).charset="utf-8",E.nc&&i.setAttribute("nonce",E.nc),i.setAttribute("data-webpack",r+n),i.src=t),e[t]=[a];var d=(r,a)=>{i.onerror=i.onload=null,clearTimeout(c);var n=e[t];if(delete e[t],i.parentNode&&i.parentNode.removeChild(i),n&&n.forEach(e=>e(a)),r)return r(a)},c=setTimeout(d.bind(null,void 0,{type:"timeout",target:i}),12e4);i.onerror=d.bind(null,i.onerror),i.onload=d.bind(null,i.onload),l&&document.head.appendChild(i)}},E.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{E.S={};var e={},r={};E.I=(t,a)=>{a||(a=[]);var n=r[t];if(n||(n=r[t]={}),!(a.indexOf(n)>=0)){if(a.push(n),e[t])return e[t];E.o(E.S,t)||(E.S[t]={});var o=E.S[t],i="calkit",l=(e,r,t,a)=>{var n=o[e]=o[e]||{},l=n[r];(!l||!l.loaded&&(!a!=!l.eager?a:i>l.from))&&(n[r]={get:t,from:i,eager:!!a})},u=[];return"default"===t&&(l("@tanstack/react-query-devtools","5.91.1",()=>E.e(695).then(()=>()=>E(6695))),l("@tanstack/react-query","5.90.12",()=>Promise.all([E.e(946),E.e(345)]).then(()=>()=>E(5946))),l("calkit","0.1.0",()=>Promise.all([E.e(867),E.e(345),E.e(909)]).then(()=>()=>E(5909)))),e[t]=u.length?Promise.all(u).then(()=>e[t]=1):1}}})(),(()=>{var e;E.g.importScripts&&(e=E.g.location+"");var r=E.g.document;if(!e&&r&&(r.currentScript&&"SCRIPT"===r.currentScript.tagName.toUpperCase()&&(e=r.currentScript.src),!e)){var t=r.getElementsByTagName("script");if(t.length)for(var a=t.length-1;a>-1&&(!e||!/^http(s?):/.test(e));)e=t[a--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),E.p=e})(),t=e=>{var r=e=>e.split(".").map(e=>+e==e?+e:e),t=/^([^-+]+)?(?:-([^+]+))?(?:\+(.+))?$/.exec(e),a=t[1]?r(t[1]):[];return t[2]&&(a.length++,a.push.apply(a,r(t[2]))),t[3]&&(a.push([]),a.push.apply(a,r(t[3]))),a},a=(e,r)=>{e=t(e),r=t(r);for(var a=0;;){if(a>=e.length)return a<r.length&&"u"!=(typeof r[a])[0];var n=e[a],o=(typeof n)[0];if(a>=r.length)return"u"==o;var i=r[a],l=(typeof i)[0];if(o!=l)return"o"==o&&"n"==l||"s"==l||"u"==o;if("o"!=o&&"u"!=o&&n!=i)return n<i;a++}},n=e=>{var r=e[0],t="";if(1===e.length)return"*";if(r+.5){t+=0==r?">=":-1==r?"<":1==r?"^":2==r?"~":r>0?"=":"!=";for(var a=1,o=1;o<e.length;o++)a--,t+="u"==(typeof(l=e[o]))[0]?"-":(a>0?".":"")+(a=2,l);return t}var i=[];for(o=1;o<e.length;o++){var l=e[o];i.push(0===l?"not("+u()+")":1===l?"("+u()+" || "+u()+")":2===l?i.pop()+" "+i.pop():n(l))}return u();function u(){return i.pop().replace(/^\((.+)\)$/,"$1")}},o=(e,r)=>{if(0 in e){r=t(r);var a=e[0],n=a<0;n&&(a=-a-1);for(var i=0,l=1,u=!0;;l++,i++){var f,s,d=l<e.length?(typeof e[l])[0]:"";if(i>=r.length||"o"==(s=(typeof(f=r[i]))[0]))return!u||("u"==d?l>a&&!n:""==d!=n);if("u"==s){if(!u||"u"!=d)return!1}else if(u)if(d==s)if(l<=a){if(f!=e[l])return!1}else{if(n?f>e[l]:f<e[l])return!1;f!=e[l]&&(u=!1)}else if("s"!=d&&"n"!=d){if(n||l<=a)return!1;u=!1,l--}else{if(l<=a||s<d!=n)return!1;u=!1}else"s"!=d&&"n"!=d&&(u=!1,l--)}}var c=[],p=c.pop.bind(c);for(i=1;i<e.length;i++){var h=e[i];c.push(1==h?p()|p():2==h?p()&p():h?o(h,r):!p())}return!!p()},i=(e,r)=>e&&E.o(e,r),l=e=>(e.loaded=1,e.get()),u=e=>Object.keys(e).reduce((r,t)=>(e[t].eager&&(r[t]=e[t]),r),{}),f=(e,r,t,n)=>{var i=n?u(e[r]):e[r];return(r=Object.keys(i).reduce((e,r)=>!o(t,r)||e&&!a(e,r)?e:r,0))&&i[r]},s=(e,r,t)=>{var n=t?u(e[r]):e[r];return Object.keys(n).reduce((e,r)=>!e||!n[e].loaded&&a(e,r)?r:e,0)},d=(e,r,t,a)=>"Unsatisfied version "+t+" from "+(t&&e[r][t].from)+" of shared singleton module "+r+" (required "+n(a)+")",c=(e,r,t,a,o)=>{var i=e[t];return"No satisfying version ("+n(a)+")"+(o?" for eager consumption":"")+" of shared module "+t+" found in shared scope "+r+".\nAvailable versions: "+Object.keys(i).map(e=>e+" from "+i[e].from).join(", ")},p=e=>{throw new Error(e)},h=e=>{"undefined"!=typeof console&&console.warn&&console.warn(e)},v=(e,r,t)=>t?t():((e,r)=>p("Shared module "+r+" doesn't exist in shared scope "+e))(e,r),m=(b=e=>function(r,t,a,n,o){var i=E.I(r);return i&&i.then&&!a?i.then(e.bind(e,r,E.S[r],t,!1,n,o)):e(r,E.S[r],t,a,n,o)})((e,r,t,a,n,o)=>{if(!i(r,t))return v(e,t,o);var u=f(r,t,n,a);return u?l(u):o?o():void p(c(r,e,t,n,a))}),y=b((e,r,t,a,n,u)=>{if(!i(r,t))return v(e,t,u);var f=s(r,t,a);return o(n,f)||h(d(r,t,f,n)),l(r[t][f])}),g={},j={3345:()=>y("default","react",!1,[1,18,2,0]),520:()=>y("default","@jupyterlab/coreutils",!1,[1,6,5,5]),1247:()=>y("default","@lumino/widgets",!1,[1,2,3,1,,"alpha",1]),1650:()=>y("default","@jupyterlab/launcher",!1,[1,4,5,5]),3476:()=>y("default","@jupyterlab/application",!1,[1,4,5,5]),3539:()=>y("default","@jupyterlab/settingregistry",!1,[1,4,5,5]),3712:()=>m("default","@tanstack/react-query",!1,[1,5,32,0],()=>E.e(946).then(()=>()=>E(5946))),3895:()=>y("default","@jupyterlab/statusbar",!1,[1,4,5,5]),6167:()=>y("default","@lumino/commands",!1,[1,2,0,1]),6200:()=>y("default","@jupyterlab/filebrowser",!1,[1,4,5,5]),6511:()=>y("default","@jupyterlab/apputils",!1,[1,4,6,5]),6641:()=>y("default","@jupyterlab/notebook",!1,[1,4,5,5]),6911:()=>y("default","@jupyterlab/statedb",!1,[1,4,5,5]),6965:()=>y("default","@jupyterlab/ui-components",!1,[1,4,5,5]),6979:()=>y("default","@jupyterlab/translation",!1,[1,4,5,5]),7034:()=>m("default","@tanstack/react-query-devtools",!1,[1,5,32,0],()=>E.e(695).then(()=>()=>E(6695))),7628:()=>y("default","react-dom",!1,[1,18,2,0]),9080:()=>y("default","@jupyterlab/mainmenu",!1,[1,4,5,5]),9519:()=>y("default","@jupyterlab/services",!1,[1,7,5,5])},w={345:[3345],909:[520,1247,1650,3476,3539,3712,3895,6167,6200,6511,6641,6911,6965,6979,7034,7628,9080,9519]},k={},E.f.consumes=(e,r)=>{E.o(w,e)&&w[e].forEach(e=>{if(E.o(g,e))return r.push(g[e]);if(!k[e]){var t=r=>{g[e]=0,E.m[e]=t=>{delete E.c[e],t.exports=r()}};k[e]=!0;var a=r=>{delete g[e],E.m[e]=t=>{throw delete E.c[e],r}};try{var n=j[e]();n.then?r.push(g[e]=n.then(t).catch(a)):t(n)}catch(e){a(e)}}})},(()=>{E.b="undefined"!=typeof document&&document.baseURI||self.location.href;var e={371:0};E.f.j=(r,t)=>{var a=E.o(e,r)?e[r]:void 0;if(0!==a)if(a)t.push(a[2]);else if(345!=r){var n=new Promise((t,n)=>a=e[r]=[t,n]);t.push(a[2]=n);var o=E.p+E.u(r),i=new Error;E.l(o,t=>{if(E.o(e,r)&&(0!==(a=e[r])&&(e[r]=void 0),a)){var n=t&&("load"===t.type?"missing":t.type),o=t&&t.target&&t.target.src;i.message="Loading chunk "+r+" failed.\n("+n+": "+o+")",i.name="ChunkLoadError",i.type=n,i.request=o,a[1](i)}},"chunk-"+r,r)}else e[r]=0};var r=(r,t)=>{var a,n,[o,i,l]=t,u=0;if(o.some(r=>0!==e[r])){for(a in i)E.o(i,a)&&(E.m[a]=i[a]);l&&l(E)}for(r&&r(t);u<o.length;u++)n=o[u],E.o(e,n)&&e[n]&&e[n][0](),e[n]=0},t=self.webpackChunkcalkit=self.webpackChunkcalkit||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})(),E.nc=void 0;var T=E(1336);(_JUPYTERLAB=void 0===_JUPYTERLAB?{}:_JUPYTERLAB).calkit=T})();
|
|
@@ -5,34 +5,34 @@ calkit/check.py,sha256=VVJErHeCzX-bcdRtu0dgMpLLMU7M38SZI_wqyMgdzwg,9080
|
|
|
5
5
|
calkit/cloud.py,sha256=Zd-Az72Gao_DuLnL2TueRQQ95SpD8oFKp0Bahb-PYXc,16802
|
|
6
6
|
calkit/conda.py,sha256=Jb1Fz3jwkk4SZ0NgoWXd4lf50gEC8d8U87ElrYjdiwk,30752
|
|
7
7
|
calkit/config.py,sha256=tkrdAQU1m3__B9efpYgK6IhtLtS3WWFcVpY2zEQpBio,7573
|
|
8
|
-
calkit/core.py,sha256=
|
|
8
|
+
calkit/core.py,sha256=ferYD6jmvbZ1h1MlNApmuHiMokrLPynWtuU62wudzsc,28534
|
|
9
9
|
calkit/datasets.py,sha256=9lOlOreey2aJGMw6MiV9MDzSHp-fYkCf1k1AZbWTdQE,2235
|
|
10
10
|
calkit/dependencies.py,sha256=y5N_4ctwp9rFZVg82Si9_2x8Yh64Ex-WqP0iiN5NNBE,13276
|
|
11
|
-
calkit/detect.py,sha256=
|
|
11
|
+
calkit/detect.py,sha256=u8dIFX1oFZ-LJexsXB-bM91yi9XtRrRr5ZUGd7LKTuw,79373
|
|
12
12
|
calkit/docker.py,sha256=EEcgbXjs-1ttixAZ-G-hmDlvnqSxYbIZmbzeAza37TI,15706
|
|
13
|
-
calkit/environments.py,sha256=
|
|
13
|
+
calkit/environments.py,sha256=PoAzpD3Esuupn3AGnR8J9ffvjHcxdBH1SQTXLxB1fY0,78060
|
|
14
14
|
calkit/fs.py,sha256=dKWUfi51F1ka7uikn_O__jxvPOUwY05ZmydxE1KaJUA,45459
|
|
15
15
|
calkit/git.py,sha256=rHAWdI13vA35m7q-MhlHj2KHMa42s4ecisTvKbdXKMw,13321
|
|
16
16
|
calkit/github.py,sha256=8_yZ0ej8TKM4qk8iPeGq47R1I4MHdSoJ_Zpr1gRwNEM,1701
|
|
17
17
|
calkit/gui.py,sha256=2UCrMyosc5v4CLlDcHO7oDwW9eLn5_WbNaLaG5bjMTc,23
|
|
18
18
|
calkit/install.py,sha256=n989NLyZSTndj_rEaHceSip5aXP7zZIlG9QwbFs8kTc,7913
|
|
19
19
|
calkit/invenio.py,sha256=aJH04-X9eFzxnrnbrPs71XBeFYBgKYYPiVM2KtyCXEE,4294
|
|
20
|
-
calkit/julia.py,sha256=
|
|
20
|
+
calkit/julia.py,sha256=4GxUSItNXpYcRlCD9N8dLiuX44-HQaKFcuEudD8At1I,5640
|
|
21
21
|
calkit/jupyter.py,sha256=lE8kKmauHqspY7aPOiNpLGQyw9jSn4taGZScm6aR87I,1157
|
|
22
22
|
calkit/licenses.py,sha256=3ZNBFxwRrfSjx3poG3G07z7GRCKAkdWiZ1AFe1yr8Gg,6853
|
|
23
23
|
calkit/magics.py,sha256=LrwJP7f84AHgKPSzmKmQjxRqzV_ATAUcpt6bHBdyDLQ,12151
|
|
24
24
|
calkit/matlab.py,sha256=wa7tjD5m8Xghwfj9u0oaYbuZ702CScvgk7pItFeTXoU,26061
|
|
25
|
-
calkit/notebooks.py,sha256=
|
|
25
|
+
calkit/notebooks.py,sha256=SGrVF_O5WmghMi7axr2WzHb4xLK7f6OmqTDMxQ5V5EY,8845
|
|
26
26
|
calkit/office.py,sha256=mZqCxkIsmWthBAeJZ5SiGe21fn5zD2zXsy1E6nQIpWE,1291
|
|
27
27
|
calkit/ops.py,sha256=lLlZAFeplU8uLeMavr99d__Iof-YYwKijus74WfLipk,854
|
|
28
28
|
calkit/overleaf.py,sha256=5SI8HwglLVtVlzj7d15Bft_3ZC6AHn3IrAbqMKOAPX0,30170
|
|
29
|
-
calkit/pipeline.py,sha256=
|
|
29
|
+
calkit/pipeline.py,sha256=U28GDnnjU4sQXxiEegEgFXkuW4mvVAwZR2CQVyaH2fY,66853
|
|
30
30
|
calkit/releases.py,sha256=JSmVX2s28WVJ5Lwitwjq5eRgUHZ38k6VbehEK-dR4mg,17478
|
|
31
31
|
calkit/server.py,sha256=GQm1bI5Q1NLFNwQL-iP6j4iWKUpKpP3cLEyfj5IMwe4,22009
|
|
32
32
|
calkit/cli/__init__.py,sha256=pP_1wFuewdUUvEWTtaEcdKblPaSYuTvthQb2Ef08UMo,1921
|
|
33
|
-
calkit/cli/check.py,sha256=
|
|
33
|
+
calkit/cli/check.py,sha256=tdiKIODqDn5y3TjfIA7JyunycPfDINpuRSOEIkYbMPY,49307
|
|
34
34
|
calkit/cli/cloud.py,sha256=mMFRRFvo8MrzxQ-B_WTCSI8-erAWnFzgN2Hd0kVvB24,1815
|
|
35
|
-
calkit/cli/config.py,sha256=
|
|
35
|
+
calkit/cli/config.py,sha256=MebDQvIByXS0q2Ci-_jPBfJWNI9TKo7JBF7pFfL4L7k,12493
|
|
36
36
|
calkit/cli/core.py,sha256=oICn4rLv9316X5bThD1Wrcc_qdmBHqye8NE4dIwojmk,3031
|
|
37
37
|
calkit/cli/delete.py,sha256=aI2mfEpzMT3bKYqgqz0aAui4UZfdbGJJpgYwiw41jTE,954
|
|
38
38
|
calkit/cli/describe.py,sha256=g6WWqa4nHSDda1Jt4D1g-VUm1k4bMskBfgKwDAhUokU,1817
|
|
@@ -40,14 +40,14 @@ calkit/cli/dev.py,sha256=cu4QsfDiA_KurGx4WJcgA2qgfghMoZutE8kl4IZbUcM,1070
|
|
|
40
40
|
calkit/cli/import_.py,sha256=5j2ANLq6v7HOku9kJUWylwvQnJfkb_OUKCNOdv1BQXU,18264
|
|
41
41
|
calkit/cli/latex.py,sha256=dhcbVNcR3YjVSD5mo-OBtZN1FhH4mv4mlGnuP19EbjU,6220
|
|
42
42
|
calkit/cli/list.py,sha256=rV3gCVvoZ4CkUYXYfNRow11-AV99b98w7sabcDq08uk,10521
|
|
43
|
-
calkit/cli/new.py,sha256=
|
|
44
|
-
calkit/cli/notebooks.py,sha256=
|
|
43
|
+
calkit/cli/new.py,sha256=OtXcXmhtywXM54dgyjxQgtYEfCYBAi_UVKvMlPjSI8k,129111
|
|
44
|
+
calkit/cli/notebooks.py,sha256=QV3_0wwgIm9cdTBM7CwlUth1xbTnPGp2LJUFVSAoBm4,21941
|
|
45
45
|
calkit/cli/office.py,sha256=jVSTvbl91TCzlglST5O2b8hdApZA_QHw_UiEQFJqxdc,1754
|
|
46
46
|
calkit/cli/overleaf.py,sha256=bS-SkYsSqqhC9YsP-NCzpYJCGS3820w18w_s8JOFihg,25216
|
|
47
47
|
calkit/cli/scheduler.py,sha256=Mn_G2tx78A_wJ3XYE0hRtTkPj376sKTWpSxMZKirHuA,38660
|
|
48
|
-
calkit/cli/update.py,sha256=
|
|
48
|
+
calkit/cli/update.py,sha256=KaO-VbUxMpR_a9FV42HG8d9p-iaA4-2-L-fAgb2LiYI,43499
|
|
49
49
|
calkit/cli/main/__init__.py,sha256=qu1POZPyqs33ZKfasOxv_Wc-EzVcEgK3Dt_vwFL8Bi8,65
|
|
50
|
-
calkit/cli/main/core.py,sha256=
|
|
50
|
+
calkit/cli/main/core.py,sha256=MMKEAI4bAJm1YJcS4E5MTQAR-XluwtGn3wlsNYjK-NE,123878
|
|
51
51
|
calkit/cli/main/xr.py,sha256=Bug5qJuiIq0tusmdu30t-ZdyaT_Sy5RwPSTiHvCtIqE,25600
|
|
52
52
|
calkit/dvc/__init__.py,sha256=-B6tilCb_jw7QFmJ2srILez24wDhNKUzIBhZUMt01dE,381
|
|
53
53
|
calkit/dvc/core.py,sha256=p42i_uCzgZD6ClGnLOn88zaiGTwrdSG09quL8Hb8Aas,30908
|
|
@@ -74,22 +74,22 @@ calkit/tests/test_calc.py,sha256=h-wOUIRqfyi06LTzhY_rS-a1xChZTkmwdEfBybMUM7E,203
|
|
|
74
74
|
calkit/tests/test_check.py,sha256=ngRZq1_dSRQoa0oSjcx_QpR94omG9Bpas_h0wqjwrK0,1475
|
|
75
75
|
calkit/tests/test_cloud.py,sha256=yCSuMq0o-i-kN-uWdvbSSBfz6mgKpS_hC3cFA-4DKjs,13542
|
|
76
76
|
calkit/tests/test_conda.py,sha256=t-Oy1mL3Vb5njj_t3LQ8HwMhsmLN64HAzSlebnN1A9s,14204
|
|
77
|
-
calkit/tests/test_core.py,sha256=
|
|
77
|
+
calkit/tests/test_core.py,sha256=CMhTx89ZpaHTK4nvll2S5M0NLJoBAuH_OBPhq9oEFfM,6272
|
|
78
78
|
calkit/tests/test_dependencies.py,sha256=HskXLzbvvRJz2TXnKPpPAo9lPhoZGYQFy4BmEF31nvk,11139
|
|
79
|
-
calkit/tests/test_detect.py,sha256=
|
|
79
|
+
calkit/tests/test_detect.py,sha256=lZvxUJbGI9RaMFIZQCbrX8S9KxRHmSblAxYnVhZtnVo,41720
|
|
80
80
|
calkit/tests/test_docker.py,sha256=27d0K1GOWiCNv_5TkZSob6EaC0EtQ9DSBIDfkEAEzGk,2077
|
|
81
81
|
calkit/tests/test_environments.py,sha256=ms8avkZy70QPD4GSWAFa04O5rhd2oePaBeo0CBgnXAo,40300
|
|
82
82
|
calkit/tests/test_fs.py,sha256=merhHGLypHTI4qP5qp0L9QFzKtJ7NcOQ2WzH4_CUnF0,13635
|
|
83
83
|
calkit/tests/test_git.py,sha256=bxPVTn-0DD9mhlarBjEnm6V8XSJHfvm2etl9Z5Pq-qg,15076
|
|
84
84
|
calkit/tests/test_install.py,sha256=Yh7-OFQ2L4S0uRkYPfQpqe4V2y1A9DwZddMEi8pQbMU,9228
|
|
85
85
|
calkit/tests/test_invenio.py,sha256=aDI8cFOUUQEkfgHSK_Nv1cMNMsnmNr2W2weuZhrxshI,998
|
|
86
|
-
calkit/tests/test_julia.py,sha256=
|
|
86
|
+
calkit/tests/test_julia.py,sha256=q7UYIJAvCQ8b6eMaledcV3rV3PPL6hDnpYJEzn2tmCE,6390
|
|
87
87
|
calkit/tests/test_jupyter.py,sha256=YTL6zI740UM2KUjskSipzvSKxsyQ8rVPFQIX5cb2tMQ,114
|
|
88
88
|
calkit/tests/test_licenses.py,sha256=AxoydeUG1Z6rDVeJJ64YXZ8xCJeyQyJdq6GSkDjlwJE,4001
|
|
89
89
|
calkit/tests/test_magics.py,sha256=1O_hYPLMBVQJj8rLCFV3sU2DejlLLnk6Tv4_Tr-FZHQ,2101
|
|
90
90
|
calkit/tests/test_matlab.py,sha256=7yFKOYDCtxYIkRyFOwTIxlvzx03Pac0FKGIUT4Zx7zA,7589
|
|
91
91
|
calkit/tests/test_notebooks.py,sha256=6xUpHjCbCv08oJkArj-NkTUMlz9zzm8pf1qam3s27M0,2692
|
|
92
|
-
calkit/tests/test_pipeline.py,sha256=
|
|
92
|
+
calkit/tests/test_pipeline.py,sha256=URq6n37NLLcw6AXlKPXE5EIgAAt8iK5RQUBjvzfbmtc,86847
|
|
93
93
|
calkit/tests/test_releases.py,sha256=if6OjeZbUtjyyZ2CMQWhxQPRR8QD2kv5CXkEbOAL9Kc,14199
|
|
94
94
|
calkit/tests/test_templates.py,sha256=RN4RIgmuFlmFYQFgfJUYS-KaLmie8fnWzmfg5Ay1egk,430
|
|
95
95
|
calkit/tests/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -114,6 +114,7 @@ calkit/tests/dvc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
|
|
|
114
114
|
calkit/tests/dvc/test_core.py,sha256=ywXBEyw1XpoSuu1EnMbFl-ebbdEJjpaBEPG157_3RBY,12914
|
|
115
115
|
calkit/tests/dvc/test_zip.py,sha256=H6L3uJdUpsaNQcOPKnmRxMb5Imr_MaDQFoAnMrZMErU,11212
|
|
116
116
|
calkit/tests/jupyterlab/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
117
|
+
calkit/tests/jupyterlab/conftest.py,sha256=Xsh5Zwg0fdqEFPkHDgG7oCHhHJj6WuZLWbmsl7ATABA,207
|
|
117
118
|
calkit/tests/jupyterlab/test_routes.py,sha256=TEEyoHiKnzzKOkQsJcMPKdqpKFQ25yBCvVSquqe9nsE,408
|
|
118
119
|
calkit/tests/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
119
120
|
calkit/tests/models/test_core.py,sha256=EY-8CRR-Nh6PIjqRfAvyz_An3fkf6Hzk7ed4da02afg,872
|
|
@@ -122,23 +123,23 @@ calkit/tests/models/test_pipeline.py,sha256=AJsMAX4928U3_Omt0_8K96U5LU_KoNErgpHe
|
|
|
122
123
|
calkit/agent_skills/add-pipeline-stage/SKILL.md,sha256=kpYYb-rJsS4B9p1Ub3gL21irCG5ZZ4DvWZpdJeEwPZk,3772
|
|
123
124
|
calkit/agent_skills/conventions/SKILL.md,sha256=nAM2FjSMk6ED56Dr5zh2bL_dhfzDra-h2ZgzHU7ruS4,9524
|
|
124
125
|
calkit/agent_skills/create-pipeline/SKILL.md,sha256=2FGw1iDQVRk5FUq79GP3lPdgvgof2Wi1O9O-abGGtgs,5422
|
|
125
|
-
calkit_python-0.41.
|
|
126
|
-
calkit_python-0.41.
|
|
127
|
-
calkit_python-0.41.
|
|
128
|
-
calkit_python-0.41.
|
|
129
|
-
calkit_python-0.41.
|
|
130
|
-
calkit_python-0.41.
|
|
131
|
-
calkit_python-0.41.
|
|
132
|
-
calkit_python-0.41.
|
|
133
|
-
calkit_python-0.41.
|
|
134
|
-
calkit_python-0.41.
|
|
135
|
-
calkit_python-0.41.
|
|
136
|
-
calkit_python-0.41.
|
|
137
|
-
calkit_python-0.41.
|
|
138
|
-
calkit_python-0.41.
|
|
139
|
-
calkit_python-0.41.
|
|
140
|
-
calkit_python-0.41.
|
|
141
|
-
calkit_python-0.41.
|
|
142
|
-
calkit_python-0.41.
|
|
143
|
-
calkit_python-0.41.
|
|
144
|
-
calkit_python-0.41.
|
|
126
|
+
calkit_python-0.41.16.data/data/etc/jupyter/jupyter_server_config.d/calkit.json,sha256=CWrZP--JDGz8fsvbAlKr_duTL1vDriGT48SL1YCtkY0,81
|
|
127
|
+
calkit_python-0.41.16.data/data/share/jupyter/labextensions/calkit/package.json,sha256=39PQEWOzw0qtqD7Kep3OPbUR113vI7CG5TeD84v7clM,6224
|
|
128
|
+
calkit_python-0.41.16.data/data/share/jupyter/labextensions/calkit/schemas/calkit/package.json.orig,sha256=NBG3t7gFYb6_2J-yPU29qS7Ck9pYgm8-wC5Q1LrzQeI,6082
|
|
129
|
+
calkit_python-0.41.16.data/data/share/jupyter/labextensions/calkit/schemas/calkit/plugin.json,sha256=YSpIrwpwB-lQBk9Mwv-npedWTOOZreO6nlWZhqlWyGI,840
|
|
130
|
+
calkit_python-0.41.16.data/data/share/jupyter/labextensions/calkit/static/502.9a2c5772a15466e923ef.js,sha256=mixXcqFUZukj7_jQVxHTavsYl7cdZv83sEe4phJgkh0,59893
|
|
131
|
+
calkit_python-0.41.16.data/data/share/jupyter/labextensions/calkit/static/695.2c41003a452d43d2b358.js,sha256=LEEAOkUtQ9KzWEHn-QFv5yGi70B-sBOnrvztzHr0Shw,223
|
|
132
|
+
calkit_python-0.41.16.data/data/share/jupyter/labextensions/calkit/static/867.a42a046aa5108f54f8fb.js,sha256=pCoEaqUQj1T4-zAc9SUd__9ZGm7uL2wHQve2xwL89NI,8156
|
|
133
|
+
calkit_python-0.41.16.data/data/share/jupyter/labextensions/calkit/static/909.e3f9cc3408834a7fdcc3.js,sha256=4_nMNAiDSn_cw7UjIHEwone4fizrvqrqSgbwUWvjmoU,114571
|
|
134
|
+
calkit_python-0.41.16.data/data/share/jupyter/labextensions/calkit/static/946.050af2abf7845cfbdbd2.js,sha256=n_a0yu_gE7l6fauyoXXv9BZ7ZEYt2387mTfs7CbLcs4,51939
|
|
135
|
+
calkit_python-0.41.16.data/data/share/jupyter/labextensions/calkit/static/946.050af2abf7845cfbdbd2.js.LICENSE.txt,sha256=eNJ8gc9n9IF8nW1d9sI9niuHstYzjNz5vqXx9UgWSPc,249
|
|
136
|
+
calkit_python-0.41.16.data/data/share/jupyter/labextensions/calkit/static/b2f1c3efe70cb539d121.png,sha256=svHD7-cMtTnRITFwugwsVaB9nZ-h8A61ose8z32HiRE,24850
|
|
137
|
+
calkit_python-0.41.16.data/data/share/jupyter/labextensions/calkit/static/remoteEntry.ac9035764d5b2adbb542.js,sha256=rJA1dk1bKtu1QkURrp5HEC2WCxzZppPV1SCYz-35GTc,8737
|
|
138
|
+
calkit_python-0.41.16.data/data/share/jupyter/labextensions/calkit/static/style.js,sha256=r89Jlk5v1drcwhCpv9FnC3Jig_JH4k24kZNIvxh6Htk,149
|
|
139
|
+
calkit_python-0.41.16.data/data/share/jupyter/labextensions/calkit/static/third-party-licenses.json,sha256=2BGdItLJwO3fAopLl4eJvp26TEwuscYC0-yFaF-LaLU,13683
|
|
140
|
+
calkit_python-0.41.16.data/data/share/jupyter/labextensions/calkit/install.json,sha256=DK9d8G-q-rMVlcT3rAeGIyo3REWKw6FySBZceLU9yaw,187
|
|
141
|
+
calkit_python-0.41.16.dist-info/METADATA,sha256=tUnzT2-o6dU9IUfQO05ysFgxfISBJ4ws9pUnrNGZU9Q,12071
|
|
142
|
+
calkit_python-0.41.16.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
|
|
143
|
+
calkit_python-0.41.16.dist-info/entry_points.txt,sha256=2iQBBzjTAOdk66CwS-f3ecXXW5DjUqkG1KBRj8mHI1I,133
|
|
144
|
+
calkit_python-0.41.16.dist-info/licenses/LICENSE,sha256=9ZamCaSUTZk9rcrnf-sWFKLOHr3ws-S_dgKMegW4nw8,1056
|
|
145
|
+
calkit_python-0.41.16.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|