calkit-python 0.45.2__py3-none-any.whl → 0.45.3__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/new.py +4 -1
- calkit/tests/cli/test_new.py +50 -6
- {calkit_python-0.45.2.dist-info → calkit_python-0.45.3.dist-info}/METADATA +2 -2
- {calkit_python-0.45.2.dist-info → calkit_python-0.45.3.dist-info}/RECORD +21 -21
- {calkit_python-0.45.2.dist-info → calkit_python-0.45.3.dist-info}/entry_points.txt +1 -1
- {calkit_python-0.45.2.data → calkit_python-0.45.3.data}/data/etc/jupyter/jupyter_server_config.d/calkit.json +0 -0
- {calkit_python-0.45.2.data → calkit_python-0.45.3.data}/data/share/jupyter/labextensions/calkit/package.json +0 -0
- {calkit_python-0.45.2.data → calkit_python-0.45.3.data}/data/share/jupyter/labextensions/calkit/schemas/calkit/package.json.orig +0 -0
- {calkit_python-0.45.2.data → calkit_python-0.45.3.data}/data/share/jupyter/labextensions/calkit/schemas/calkit/plugin.json +0 -0
- {calkit_python-0.45.2.data → calkit_python-0.45.3.data}/data/share/jupyter/labextensions/calkit/static/502.9a2c5772a15466e923ef.js +0 -0
- {calkit_python-0.45.2.data → calkit_python-0.45.3.data}/data/share/jupyter/labextensions/calkit/static/695.2c41003a452d43d2b358.js +0 -0
- {calkit_python-0.45.2.data → calkit_python-0.45.3.data}/data/share/jupyter/labextensions/calkit/static/867.a42a046aa5108f54f8fb.js +0 -0
- {calkit_python-0.45.2.data → calkit_python-0.45.3.data}/data/share/jupyter/labextensions/calkit/static/909.6d8285ce7c45878ac508.js +0 -0
- {calkit_python-0.45.2.data → calkit_python-0.45.3.data}/data/share/jupyter/labextensions/calkit/static/946.050af2abf7845cfbdbd2.js +0 -0
- {calkit_python-0.45.2.data → calkit_python-0.45.3.data}/data/share/jupyter/labextensions/calkit/static/946.050af2abf7845cfbdbd2.js.LICENSE.txt +0 -0
- {calkit_python-0.45.2.data → calkit_python-0.45.3.data}/data/share/jupyter/labextensions/calkit/static/b2f1c3efe70cb539d121.png +0 -0
- {calkit_python-0.45.2.data → calkit_python-0.45.3.data}/data/share/jupyter/labextensions/calkit/static/remoteEntry.d7a43c7948f690d37d19.js +0 -0
- {calkit_python-0.45.2.data → calkit_python-0.45.3.data}/data/share/jupyter/labextensions/calkit/static/style.js +0 -0
- {calkit_python-0.45.2.data → calkit_python-0.45.3.data}/data/share/jupyter/labextensions/calkit/static/third-party-licenses.json +0 -0
- {calkit_python-0.45.2.dist-info → calkit_python-0.45.3.dist-info}/WHEEL +0 -0
- {calkit_python-0.45.2.dist-info → calkit_python-0.45.3.dist-info}/licenses/LICENSE +0 -0
calkit/cli/new.py
CHANGED
|
@@ -3710,6 +3710,9 @@ def new_release(
|
|
|
3710
3710
|
f"'{project_name}'."
|
|
3711
3711
|
)
|
|
3712
3712
|
record_id = None
|
|
3713
|
+
# SPDX IDs are case-insensitive, but the InvenioRDM license vocabulary
|
|
3714
|
+
# used by Zenodo and CaltechDATA only accepts them lowercased
|
|
3715
|
+
license_ids = [lid.strip().lower() for lid in license_ids]
|
|
3713
3716
|
# Detect project license IDs if necessary
|
|
3714
3717
|
if not license_ids:
|
|
3715
3718
|
license_file = calkit.licenses.find_license_file()
|
|
@@ -3756,7 +3759,7 @@ def new_release(
|
|
|
3756
3759
|
publication_date=release_date,
|
|
3757
3760
|
version=name,
|
|
3758
3761
|
publisher=publisher_name,
|
|
3759
|
-
rights=[{"id": lid for lid in license_ids
|
|
3762
|
+
rights=[{"id": lid} for lid in license_ids],
|
|
3760
3763
|
)
|
|
3761
3764
|
# Add related identifiers
|
|
3762
3765
|
github_url = calkit.detect_project_github_url()
|
calkit/tests/cli/test_new.py
CHANGED
|
@@ -1100,6 +1100,10 @@ def test_new_nix_env_stages_flake(tmp_dir):
|
|
|
1100
1100
|
def test_new_release(tmp_dir, monkeypatch, httpserver):
|
|
1101
1101
|
# Set up a mock Zenodo API so the test doesn't depend on the real sandbox
|
|
1102
1102
|
record_id = "test-record-abc123"
|
|
1103
|
+
# A new version of a record gets its own ID, which the client must switch
|
|
1104
|
+
# to; only the draft endpoints below are shared between the two
|
|
1105
|
+
version_record_id = "test-record-def456"
|
|
1106
|
+
any_record_id = f"(?:{record_id}|{version_record_id})"
|
|
1103
1107
|
doi = "10.5072/zenodo.test123"
|
|
1104
1108
|
# Point the Zenodo base URL at the local mock server and provide a dummy
|
|
1105
1109
|
# token so no real credentials are needed. Both env vars are inherited
|
|
@@ -1115,26 +1119,27 @@ def test_new_release(tmp_dir, monkeypatch, httpserver):
|
|
|
1115
1119
|
).respond_with_json({"id": record_id, "pids": {}})
|
|
1116
1120
|
# POST /records/{id}/draft/files – initiate a file upload slot
|
|
1117
1121
|
httpserver.expect_request(
|
|
1118
|
-
re.compile(rf"^/records/{
|
|
1122
|
+
re.compile(rf"^/records/{any_record_id}/draft/files$"), method="POST"
|
|
1119
1123
|
).respond_with_json({"entries": []})
|
|
1120
1124
|
# PUT /records/{id}/draft/files/{filename}/content – stream file bytes
|
|
1121
1125
|
httpserver.expect_request(
|
|
1122
|
-
re.compile(rf"^/records/{
|
|
1126
|
+
re.compile(rf"^/records/{any_record_id}/draft/files/.+/content$"),
|
|
1123
1127
|
method="PUT",
|
|
1124
1128
|
).respond_with_data("", status=200)
|
|
1125
1129
|
# POST /records/{id}/draft/files/{filename}/commit – finalise upload
|
|
1126
1130
|
httpserver.expect_request(
|
|
1127
|
-
re.compile(rf"^/records/{
|
|
1131
|
+
re.compile(rf"^/records/{any_record_id}/draft/files/.+/commit$"),
|
|
1128
1132
|
method="POST",
|
|
1129
1133
|
).respond_with_json({"key": "file", "status": "completed"})
|
|
1130
1134
|
# POST /records/{id}/draft/pids/doi – reserve a DOI for a draft
|
|
1131
1135
|
httpserver.expect_request(
|
|
1132
|
-
re.compile(rf"^/records/{
|
|
1136
|
+
re.compile(rf"^/records/{any_record_id}/draft/pids/doi$"),
|
|
1137
|
+
method="POST",
|
|
1133
1138
|
).respond_with_json({"pids": {"doi": {"identifier": doi}}})
|
|
1134
1139
|
# GET /records/{id}/draft/files – list files already in the draft
|
|
1135
1140
|
# (used by --reupload to decide which files to delete first)
|
|
1136
1141
|
httpserver.expect_request(
|
|
1137
|
-
re.compile(rf"^/records/{
|
|
1142
|
+
re.compile(rf"^/records/{any_record_id}/draft/files$"), method="GET"
|
|
1138
1143
|
).respond_with_json({"entries": []})
|
|
1139
1144
|
# POST /records/{id}/draft/actions/publish – publish the draft
|
|
1140
1145
|
httpserver.expect_request(
|
|
@@ -1143,6 +1148,16 @@ def test_new_release(tmp_dir, monkeypatch, httpserver):
|
|
|
1143
1148
|
).respond_with_json(
|
|
1144
1149
|
{"id": record_id, "pids": {"doi": {"identifier": doi}}}
|
|
1145
1150
|
)
|
|
1151
|
+
# POST /records/{id}/versions – create a new version of a record, and
|
|
1152
|
+
# PUT /records/{new_id}/draft – set that new version's metadata; the draft
|
|
1153
|
+
# is only mocked under the new ID, so a client that failed to switch to it
|
|
1154
|
+
# would get no response here
|
|
1155
|
+
httpserver.expect_request(
|
|
1156
|
+
re.compile(rf"^/records/{record_id}/versions$"), method="POST"
|
|
1157
|
+
).respond_with_json({"id": version_record_id, "pids": {}})
|
|
1158
|
+
httpserver.expect_request(
|
|
1159
|
+
re.compile(rf"^/records/{version_record_id}/draft$"), method="PUT"
|
|
1160
|
+
).respond_with_json({"id": version_record_id, "pids": {}})
|
|
1146
1161
|
# GET /records/{id} – fetch the published record for post-test assertions
|
|
1147
1162
|
httpserver.expect_request(
|
|
1148
1163
|
re.compile(rf"^/records/{record_id}$"), method="GET"
|
|
@@ -1267,7 +1282,6 @@ def test_new_release(tmp_dir, monkeypatch, httpserver):
|
|
|
1267
1282
|
git_tags = git.Repo().tags
|
|
1268
1283
|
assert "v0.1.0" in [tag.name for tag in git_tags]
|
|
1269
1284
|
# Check the license is correct
|
|
1270
|
-
# TODO: It seems like we can't use multiple license IDs with the API
|
|
1271
1285
|
record_id = release["record_id"]
|
|
1272
1286
|
record = calkit.invenio.get(f"/records/{record_id}")
|
|
1273
1287
|
metadata = record["metadata"]
|
|
@@ -1275,6 +1289,36 @@ def test_new_release(tmp_dir, monkeypatch, httpserver):
|
|
|
1275
1289
|
assert metadata["license"] == {"id": "cc-by-4.0"}
|
|
1276
1290
|
related = metadata["related_identifiers"]
|
|
1277
1291
|
assert related[0]["identifier"] == "https://github.com/calkit/test-project"
|
|
1292
|
+
# Issue #1582: SPDX IDs are case-insensitive, but the InvenioRDM license
|
|
1293
|
+
# vocabulary rejects anything but the lowercase form, so release again
|
|
1294
|
+
# with the licenses spelled in uppercase to check they are normalized
|
|
1295
|
+
subprocess.check_call(
|
|
1296
|
+
[
|
|
1297
|
+
"calkit",
|
|
1298
|
+
"new",
|
|
1299
|
+
"release",
|
|
1300
|
+
"--name",
|
|
1301
|
+
"v0.2.0",
|
|
1302
|
+
"--license",
|
|
1303
|
+
"MIT",
|
|
1304
|
+
"--license",
|
|
1305
|
+
"CC-BY-4.0",
|
|
1306
|
+
"--draft",
|
|
1307
|
+
"--no-github",
|
|
1308
|
+
]
|
|
1309
|
+
)
|
|
1310
|
+
# Every set of metadata sent to the service should have carried both
|
|
1311
|
+
# licenses as separate lowercase rights entries, rather than collapsing
|
|
1312
|
+
# them into one: the first release detected them from the LICENSE file,
|
|
1313
|
+
# the second took them from the uppercase --license options
|
|
1314
|
+
rights_sent = [
|
|
1315
|
+
body["metadata"]["rights"]
|
|
1316
|
+
for request, _ in httpserver.log
|
|
1317
|
+
if (body := request.get_json(silent=True)) and "metadata" in body
|
|
1318
|
+
]
|
|
1319
|
+
expected_rights = [{"id": "mit"}, {"id": "cc-by-4.0"}]
|
|
1320
|
+
assert len(rights_sent) >= 2
|
|
1321
|
+
assert rights_sent == [expected_rights] * len(rights_sent)
|
|
1278
1322
|
# TODO: Test that we can delete the release
|
|
1279
1323
|
# This will fail if it's not a draft
|
|
1280
1324
|
# subprocess.check_call(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: calkit-python
|
|
3
|
-
Version: 0.45.
|
|
3
|
+
Version: 0.45.3
|
|
4
4
|
Summary: Reproducibility simplified.
|
|
5
5
|
Project-URL: Homepage, https://calkit.org
|
|
6
6
|
Project-URL: Issues, https://github.com/calkit/calkit/issues
|
|
@@ -192,7 +192,7 @@ If you want to use Calkit without installing it,
|
|
|
192
192
|
you can use uv's `uvx` command to run it directly:
|
|
193
193
|
|
|
194
194
|
```sh
|
|
195
|
-
uvx
|
|
195
|
+
uvx ck9 --help
|
|
196
196
|
```
|
|
197
197
|
|
|
198
198
|
### Nix
|
|
@@ -46,7 +46,7 @@ calkit/cli/hub.py,sha256=ZBOlL7-mV57q_ynr4hPuhV7NlkKEkINSRksXD-jjiOg,2972
|
|
|
46
46
|
calkit/cli/import_.py,sha256=ZAfPstDm_EoG9i8RMvVfctLOFMv0GbstkH0Wb7iq-9Q,18875
|
|
47
47
|
calkit/cli/latex.py,sha256=mvNxzZkWlwJnYA_l6NFEflV0AGYHPIT1ALUxQQGHZJ0,19708
|
|
48
48
|
calkit/cli/list.py,sha256=E40uJe_jRQcRin1RO4yFMUncKMpQe2syWhC54xzDhoQ,15090
|
|
49
|
-
calkit/cli/new.py,sha256=
|
|
49
|
+
calkit/cli/new.py,sha256=t3CHyNFTnzKUAuph31HsWuUxK4iw7s28IVC5STSTxy0,149724
|
|
50
50
|
calkit/cli/notebooks.py,sha256=aR4I0qatOtkrAxEG5PVLej20SBLKo8qr-lxDSzgljUQ,38836
|
|
51
51
|
calkit/cli/office.py,sha256=jVSTvbl91TCzlglST5O2b8hdApZA_QHw_UiEQFJqxdc,1754
|
|
52
52
|
calkit/cli/overleaf.py,sha256=PTL3MH3y3qlSCkZ39yaiWUWU6U7aiGyh6aKLA068-5U,38700
|
|
@@ -135,7 +135,7 @@ calkit/tests/cli/test_hub.py,sha256=z3ne8Bnjv-V85OEh15FbAV4STrFwZKMgl_DgWwQ2wzY,
|
|
|
135
135
|
calkit/tests/cli/test_import.py,sha256=e2BToVPebf4NalFQuIgyTNJHwbc9VMc6AYO-FAhYbQ0,663
|
|
136
136
|
calkit/tests/cli/test_latex.py,sha256=92ZhSIYOiBb0TKZmODTVvkp0dU_X5ZuGvrdA4v5bzQo,10976
|
|
137
137
|
calkit/tests/cli/test_list.py,sha256=5jc_OYI_rXNVv2UQc6IS8ItjQbBwEI5IDw5xKU_Uk98,9165
|
|
138
|
-
calkit/tests/cli/test_new.py,sha256=
|
|
138
|
+
calkit/tests/cli/test_new.py,sha256=q7kmZQ9IrMhDOcHuIXU0GJs0Z54SpX12vct8ntQaKLM,66977
|
|
139
139
|
calkit/tests/cli/test_notebooks.py,sha256=2t1KiGhEz9H9LcIdWy4jGM05REUxJpWiIg6fSpX12ME,10678
|
|
140
140
|
calkit/tests/cli/test_overleaf.py,sha256=w8tqRwOC6ilQX8wfkqppTBmcouxs61zEoq-R5G1emY8,49767
|
|
141
141
|
calkit/tests/cli/test_scheduler.py,sha256=YfJi_fcRlQt1bdFyo3b8BFelA1PcH-wn5lAVXiH7Zj4,24109
|
|
@@ -159,22 +159,22 @@ calkit/tests/models/test_pipeline.py,sha256=hglkTBry1ONKbzN1HmlpefbrqAbc-668C0MQ
|
|
|
159
159
|
calkit/agent_skills/add-pipeline-stage/SKILL.md,sha256=kpYYb-rJsS4B9p1Ub3gL21irCG5ZZ4DvWZpdJeEwPZk,3772
|
|
160
160
|
calkit/agent_skills/conventions/SKILL.md,sha256=osbAtYU0AwROZHgmOoQYbqYr3JwG_v-cJAmandm7yN4,9738
|
|
161
161
|
calkit/agent_skills/create-pipeline/SKILL.md,sha256=2FGw1iDQVRk5FUq79GP3lPdgvgof2Wi1O9O-abGGtgs,5422
|
|
162
|
-
calkit_python-0.45.
|
|
163
|
-
calkit_python-0.45.
|
|
164
|
-
calkit_python-0.45.
|
|
165
|
-
calkit_python-0.45.
|
|
166
|
-
calkit_python-0.45.
|
|
167
|
-
calkit_python-0.45.
|
|
168
|
-
calkit_python-0.45.
|
|
169
|
-
calkit_python-0.45.
|
|
170
|
-
calkit_python-0.45.
|
|
171
|
-
calkit_python-0.45.
|
|
172
|
-
calkit_python-0.45.
|
|
173
|
-
calkit_python-0.45.
|
|
174
|
-
calkit_python-0.45.
|
|
175
|
-
calkit_python-0.45.
|
|
176
|
-
calkit_python-0.45.
|
|
177
|
-
calkit_python-0.45.
|
|
178
|
-
calkit_python-0.45.
|
|
179
|
-
calkit_python-0.45.
|
|
180
|
-
calkit_python-0.45.
|
|
162
|
+
calkit_python-0.45.3.data/data/etc/jupyter/jupyter_server_config.d/calkit.json,sha256=CWrZP--JDGz8fsvbAlKr_duTL1vDriGT48SL1YCtkY0,81
|
|
163
|
+
calkit_python-0.45.3.data/data/share/jupyter/labextensions/calkit/package.json,sha256=tYRdVVqmPBoUJzNrMc7Da9Lk-NB54vhnplKRSlOTMIE,6224
|
|
164
|
+
calkit_python-0.45.3.data/data/share/jupyter/labextensions/calkit/schemas/calkit/package.json.orig,sha256=NBG3t7gFYb6_2J-yPU29qS7Ck9pYgm8-wC5Q1LrzQeI,6082
|
|
165
|
+
calkit_python-0.45.3.data/data/share/jupyter/labextensions/calkit/schemas/calkit/plugin.json,sha256=YSpIrwpwB-lQBk9Mwv-npedWTOOZreO6nlWZhqlWyGI,840
|
|
166
|
+
calkit_python-0.45.3.data/data/share/jupyter/labextensions/calkit/static/502.9a2c5772a15466e923ef.js,sha256=mixXcqFUZukj7_jQVxHTavsYl7cdZv83sEe4phJgkh0,59893
|
|
167
|
+
calkit_python-0.45.3.data/data/share/jupyter/labextensions/calkit/static/695.2c41003a452d43d2b358.js,sha256=LEEAOkUtQ9KzWEHn-QFv5yGi70B-sBOnrvztzHr0Shw,223
|
|
168
|
+
calkit_python-0.45.3.data/data/share/jupyter/labextensions/calkit/static/867.a42a046aa5108f54f8fb.js,sha256=pCoEaqUQj1T4-zAc9SUd__9ZGm7uL2wHQve2xwL89NI,8156
|
|
169
|
+
calkit_python-0.45.3.data/data/share/jupyter/labextensions/calkit/static/909.6d8285ce7c45878ac508.js,sha256=bYKFznxFh4rFCPs8tWnbZgaFGp72DuPZGdkzYCoCaSU,114583
|
|
170
|
+
calkit_python-0.45.3.data/data/share/jupyter/labextensions/calkit/static/946.050af2abf7845cfbdbd2.js,sha256=n_a0yu_gE7l6fauyoXXv9BZ7ZEYt2387mTfs7CbLcs4,51939
|
|
171
|
+
calkit_python-0.45.3.data/data/share/jupyter/labextensions/calkit/static/946.050af2abf7845cfbdbd2.js.LICENSE.txt,sha256=eNJ8gc9n9IF8nW1d9sI9niuHstYzjNz5vqXx9UgWSPc,249
|
|
172
|
+
calkit_python-0.45.3.data/data/share/jupyter/labextensions/calkit/static/b2f1c3efe70cb539d121.png,sha256=svHD7-cMtTnRITFwugwsVaB9nZ-h8A61ose8z32HiRE,24850
|
|
173
|
+
calkit_python-0.45.3.data/data/share/jupyter/labextensions/calkit/static/remoteEntry.d7a43c7948f690d37d19.js,sha256=16Q8eUj2kNN9Gaeoe3hOSEUPMJ5IUHQnJF1h9DRUIJY,8737
|
|
174
|
+
calkit_python-0.45.3.data/data/share/jupyter/labextensions/calkit/static/style.js,sha256=r89Jlk5v1drcwhCpv9FnC3Jig_JH4k24kZNIvxh6Htk,149
|
|
175
|
+
calkit_python-0.45.3.data/data/share/jupyter/labextensions/calkit/static/third-party-licenses.json,sha256=2BGdItLJwO3fAopLl4eJvp26TEwuscYC0-yFaF-LaLU,13683
|
|
176
|
+
calkit_python-0.45.3.dist-info/METADATA,sha256=Z809eOplrqKq9iYfrwUT3yBjzhSR1dfjXNPaHMaaG8w,12816
|
|
177
|
+
calkit_python-0.45.3.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
|
|
178
|
+
calkit_python-0.45.3.dist-info/entry_points.txt,sha256=TtpHpcv2vFVAVYxFVp0XrwCV_z7FWIOguEiypXRDoOw,131
|
|
179
|
+
calkit_python-0.45.3.dist-info/licenses/LICENSE,sha256=9ZamCaSUTZk9rcrnf-sWFKLOHr3ws-S_dgKMegW4nw8,1056
|
|
180
|
+
calkit_python-0.45.3.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
|
|
File without changes
|