From bcb11e255df1f2f0b3e163e088718bbcb8e87d43 Mon Sep 17 00:00:00 2001
From: Nicholas Bollweg
Date: Mon, 11 Dec 2023 20:56:11 -0600
Subject: [PATCH 01/23] try lite vs 4.1.0 etc
---
jupyak_config.toml | 13 +++++++++++++
src/jupyak/tasks/_lite.ipynb | 22 +++++++++++++++-------
2 files changed, 28 insertions(+), 7 deletions(-)
create mode 100644 jupyak_config.toml
diff --git a/jupyak_config.toml b/jupyak_config.toml
new file mode 100644
index 0000000..ff00298
--- /dev/null
+++ b/jupyak_config.toml
@@ -0,0 +1,13 @@
+#:schema ./docs/_static/jupyak-v0.schema.json
+
+[lite]
+gist = "60d9f604bdf00715e3d25f6436f8751f"
+
+[repos.jupyterlite.github]
+merge_with=["pull/1263"]
+
+[repos.jupyterlite.js]
+link_exclude_patterns=[
+ "^@jupyterlab/(celltags-extension|debugger(-extension)?|extensionmanager(-extension)?|hub-extension|nbconvert-css|pluginmanager-extension|terminal(-extension)?|template)$",
+ "^@jupyter-notebook/(documentsearch-extension|lab-extension|terminal-extension)$",
+]
diff --git a/src/jupyak/tasks/_lite.ipynb b/src/jupyak/tasks/_lite.ipynb
index b9659ad..d3113e9 100644
--- a/src/jupyak/tasks/_lite.ipynb
+++ b/src/jupyak/tasks/_lite.ipynb
@@ -158,16 +158,24 @@
" contents=contents,\n",
" output_dir=os.path.relpath(yak.lite.app_path, work_path),\n",
" ignore_sys_prefix=[\"federated_extensions\"],\n",
- " federated_extensions=[\n",
- " os.path.relpath(pkg_json.parent, work_path) for pkg_json in pkg_jsons\n",
- " ],\n",
+ " federated_extensions=sorted(\n",
+ " [\n",
+ " *lbc.get(\"federated_extensions\", []),\n",
+ " *[\n",
+ " os.path.relpath(pkg_json.parent, work_path)\n",
+ " for pkg_json in pkg_jsons\n",
+ " ],\n",
+ " ]\n",
+ " ),\n",
" )\n",
"\n",
" pla.update(\n",
- " piplite_urls=[\n",
- " *pla.get(\"piplite_urls\", []),\n",
- " *[os.path.relpath(whl_shas.parent, work_path) for whl_shas in whl_deps],\n",
- " ]\n",
+ " piplite_urls=sorted(\n",
+ " [\n",
+ " *pla.get(\"piplite_urls\", []),\n",
+ " *[os.path.relpath(whl_shas.parent, work_path) for whl_shas in whl_deps],\n",
+ " ]\n",
+ " ),\n",
" )\n",
"\n",
" yak.lite.build_config_path.write_text(json.dumps(config, indent=2, sort_keys=True))"
From 79b3cea51efa2b8299ba85bc762659d2736332ef Mon Sep 17 00:00:00 2001
From: Nicholas Bollweg
Date: Mon, 11 Dec 2023 22:09:18 -0600
Subject: [PATCH 02/23] fix lite gist copy
---
src/jupyak/tasks/_lite.ipynb | 154 ++++++++++++++++++-----------------
1 file changed, 81 insertions(+), 73 deletions(-)
diff --git a/src/jupyak/tasks/_lite.ipynb b/src/jupyak/tasks/_lite.ipynb
index d3113e9..32a29b7 100644
--- a/src/jupyak/tasks/_lite.ipynb
+++ b/src/jupyak/tasks/_lite.ipynb
@@ -41,38 +41,22 @@
" lite = yak.lite.work_path\n",
" build_conf = yak.lite.build_config_path\n",
" in_work_lite = {\"cwd\": lite}\n",
- " run_args = yak.env.run_args\n",
- " lite_args = [*run_args, \"jupyter\", \"lite\"]\n",
+ " lite_args = [*yak.env.run_args, \"jupyter\", \"lite\"]\n",
"\n",
- " all_deps = cli_deps, build_deps, run_deps = _find_lite_deps(yak)\n",
- "\n",
- " gist_dep = []\n",
- "\n",
- " if yak.lite.gist:\n",
- " gist_dep += [yak.lite.gist_path / \".git/refs/heads\" / W.WORK_BRANCH]\n",
- "\n",
- " self_dist = os.environ.get(W.ENV_VAR_SELF_DIST)\n",
- "\n",
- " if self_dist:\n",
- " run_deps += [Path(self_dist)]\n",
+ " all_deps = cli_deps, conf_deps, conf_targets, build_deps = _find_lite_deps(yak)\n",
"\n",
" yield dict(\n",
" name=\"config\",\n",
" doc=\"> configure jupyterlite\",\n",
- " file_dep=[*build_deps, *run_deps, *gist_dep],\n",
- " actions=[(_make_lite_config, [build_deps, run_deps, yak])],\n",
- " targets=[build_conf],\n",
+ " file_dep=[*conf_deps, *build_deps],\n",
+ " actions=[(_make_lite_config, [yak, *all_deps])],\n",
+ " targets=sorted(set(conf_targets)),\n",
" )\n",
"\n",
" yield dict(\n",
" name=\"build\",\n",
" doc=\"> build lite site archive\",\n",
- " file_dep=[\n",
- " *sum(all_deps, []),\n",
- " *gist_dep,\n",
- " build_conf,\n",
- " yak.env.lab_share / \"static\" / W.PACKAGE_JSON,\n",
- " ],\n",
+ " file_dep=[*conf_targets, *build_deps, *cli_deps],\n",
" actions=[\n",
" A.run([*lite_args, \"build\"], in_work_lite),\n",
" A.run([*lite_args, \"archive\"], in_work_lite),\n",
@@ -89,28 +73,66 @@
"outputs": [],
"source": [
"def _find_lite_deps(yak: Y.Yak):\n",
- " cli_deps = []\n",
- " build_deps = []\n",
- " run_deps = []\n",
+ " all_deps = cli_deps, conf_deps, conf_targets, build_deps = [], [], [], []\n",
+ "\n",
+ " cli_deps += [yak.env.lab_share / \"static\" / W.PACKAGE_JSON]\n",
+ "\n",
" for name, repo in yak.py_repos.items():\n",
- " if not repo.lite:\n",
- " continue\n",
- "\n",
- " cli_deps += [\n",
- " yak.env.py_site_packages / P._pth_path(pth) for pth in repo.lite.needs_pth\n",
- " ]\n",
- " for ext_js_path, ext in repo.py.lab_extensions.items():\n",
- " build_deps += [repo.work_path / t for t in ext.targets]\n",
- " if repo.lite.wheel:\n",
- " for ppt in repo.py.pyproject_tomls:\n",
- " ppt_path = repo.work_path / ppt\n",
- " if any(\n",
- " re.match(swp, ppt_path.parent.name)\n",
- " for swp in repo.lite.skip_wheel_patterns\n",
- " ):\n",
- " continue\n",
- " run_deps += [ppt_path.parent / \"dist\" / W.SHA256SUMS]\n",
- " return cli_deps, build_deps, run_deps"
+ " if repo.lite:\n",
+ " _add_repo_deps(repo, *all_deps)\n",
+ "\n",
+ " if yak.lite.gist:\n",
+ " _add_gist_deps(yak, *all_deps)\n",
+ "\n",
+ " self_dist = os.environ.get(W.ENV_VAR_SELF_DIST)\n",
+ "\n",
+ " if self_dist:\n",
+ " build_deps += [Path(self_dist)]\n",
+ "\n",
+ " return all_deps"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "29acfebf-d3fd-4d27-b319-4aeb7d7d6aba",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def _add_gist_deps(yak: Y.Yak, cli_deps, conf_deps, conf_targets, build_deps):\n",
+ " gist_path = yak.lite.gist_path\n",
+ " work_path = yak.lite.work_path\n",
+ " conf_deps += [gist_path / \".git/refs/heads\" / W.WORK_BRANCH]\n",
+ " conf_targets += [yak.lite.build_config_path]\n",
+ " if yak.lite.gist_path.exists():\n",
+ " gist_files = [p for p in gist_path.glob(\"*\") if not p.is_dir()]\n",
+ " conf_deps += gist_files\n",
+ " conf_targets += [work_path / p.name for p in gist_files]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "e5e053b3-5ad6-4f40-a115-c04d9dbf6de9",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def _add_repo_deps(repo: Y.Repo, cli_deps, conf_deps, conf_targets, build_deps):\n",
+ " cli_deps += [\n",
+ " repo.parent.env.py_site_packages / P._pth_path(pth)\n",
+ " for pth in repo.lite.needs_pth\n",
+ " ]\n",
+ " for ext_js_path, ext in repo.py.lab_extensions.items():\n",
+ " build_deps += [repo.work_path / t for t in ext.targets]\n",
+ " if repo.lite.wheel:\n",
+ " for ppt in repo.py.pyproject_tomls:\n",
+ " ppt_path = repo.work_path / ppt\n",
+ " if any(\n",
+ " re.match(swp, ppt_path.parent.name)\n",
+ " for swp in repo.lite.skip_wheel_patterns\n",
+ " ):\n",
+ " continue\n",
+ " build_deps += [ppt_path.parent / \"dist\" / W.SHA256SUMS]"
]
},
{
@@ -120,13 +142,19 @@
"metadata": {},
"outputs": [],
"source": [
- "def _make_lite_config(build_deps, run_deps, yak: Y.Yak, config=None):\n",
+ "def _make_lite_config(yak: Y.Yak, cli_deps, conf_deps, conf_targets, build_deps):\n",
" work_path = yak.lite.work_path\n",
- " work_path.mkdir(exist_ok=True, parents=True)\n",
- " contents = []\n",
- " config = config or {}\n",
+ " config = {}\n",
+ " if yak.lite.gist_path.exists():\n",
+ " A.copy(yak.lite.gist_path, work_path)\n",
+ " if yak.lite.build_config_path.exists():\n",
+ " config = json.loads(yak.lite.build_config_path.read_text(encoding=\"utf-8\"))\n",
+ " else:\n",
+ " work_path.mkdir(exist_ok=True, parents=True)\n",
+ "\n",
" lbc = config.setdefault(\"LiteBuildConfig\", {})\n",
" pla = config.setdefault(\"PipliteAddon\", {})\n",
+ "\n",
" pkg_jsons = [\n",
" p\n",
" for p in build_deps\n",
@@ -135,29 +163,14 @@
" ]\n",
" whl_deps = [\n",
" p\n",
- " for p in run_deps\n",
+ " for p in build_deps\n",
" if p.name == W.SHA256SUMS and p.parent.glob(f\"*{W.NOARCH_WHL}\")\n",
" ]\n",
"\n",
- " if yak.lite.gist:\n",
- " contents = [os.path.relpath(yak.lite.gist_path, work_path)]\n",
- " gist_config_path = yak.lite.gist_path / W.JUPYTER_LITE_CONFIG\n",
- " if gist_config_path.exists():\n",
- " gist_config = json.loads(gist_config_path.read_text(encoding=\"utf-8\"))\n",
- " for has_traits, trait_values in gist_config.items():\n",
- " config.setdefault(has_traits, {}).update(trait_values)\n",
- " for run_path in [W.JUPYTER_LITE_JSON, W.JUPYTER_LITE_IPYNB]:\n",
- " src = yak.lite.gist_path / run_path\n",
- " if not src.exists():\n",
- " continue\n",
- " dest = work_path / run_path\n",
- " dest.write_text(src.read_text(encoding=\"utf-8\"), encoding=\"utf-8\")\n",
- "\n",
" lbc.update(\n",
" cache_dir=\"../.cache/lite\",\n",
- " contents=contents,\n",
+ " contents=[\".\"],\n",
" output_dir=os.path.relpath(yak.lite.app_path, work_path),\n",
- " ignore_sys_prefix=[\"federated_extensions\"],\n",
" federated_extensions=sorted(\n",
" [\n",
" *lbc.get(\"federated_extensions\", []),\n",
@@ -178,16 +191,11 @@
" ),\n",
" )\n",
"\n",
- " yak.lite.build_config_path.write_text(json.dumps(config, indent=2, sort_keys=True))"
+ " yak.lite.build_config_path.write_text(\n",
+ " json.dumps(config, indent=2, sort_keys=True),\n",
+ " encoding=\"utf-8\",\n",
+ " )"
]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "ad28a139-cf16-4f22-84cc-7b1a8afc63ad",
- "metadata": {},
- "outputs": [],
- "source": []
}
],
"metadata": {
From 03e65ca5797b1bf8b371c492625264e871a29cbe Mon Sep 17 00:00:00 2001
From: Nicholas Bollweg
Date: Tue, 12 Dec 2023 06:47:29 -0600
Subject: [PATCH 03/23] try adding 1267
---
jupyak_config.toml | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/jupyak_config.toml b/jupyak_config.toml
index ff00298..bbe235f 100644
--- a/jupyak_config.toml
+++ b/jupyak_config.toml
@@ -4,10 +4,13 @@
gist = "60d9f604bdf00715e3d25f6436f8751f"
[repos.jupyterlite.github]
-merge_with=["pull/1263"]
+merge_with=[
+ "pull/1267",
+ "pull/1263",
+]
[repos.jupyterlite.js]
link_exclude_patterns=[
- "^@jupyterlab/(celltags-extension|debugger(-extension)?|extensionmanager(-extension)?|hub-extension|nbconvert-css|pluginmanager-extension|terminal(-extension)?|template)$",
+ "^@jupyterlab/(debugger(-extension)?|extensionmanager(-extension)?|hub-extension|nbconvert-css|pluginmanager-extension|terminal(-extension)?|template)$",
"^@jupyter-notebook/(documentsearch-extension|lab-extension|terminal-extension)$",
]
From cefe9dad3812b59086b36263a892fae55e81ddf0 Mon Sep 17 00:00:00 2001
From: Nicholas Bollweg
Date: Tue, 12 Dec 2023 07:02:54 -0600
Subject: [PATCH 04/23] add ipywidgets pr
---
jupyak_config.toml | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/jupyak_config.toml b/jupyak_config.toml
index ff00298..0fef702 100644
--- a/jupyak_config.toml
+++ b/jupyak_config.toml
@@ -3,11 +3,21 @@
[lite]
gist = "60d9f604bdf00715e3d25f6436f8751f"
+[repos.ipywidgets.github]
+merge_with = [
+ "pull/3847",
+]
+
[repos.jupyterlite.github]
-merge_with=["pull/1263"]
+merge_strategy = "ort"
+merge_options = ["theirs"]
+merge_with = [
+ "pull/1267",
+ "pull/1263",
+]
[repos.jupyterlite.js]
-link_exclude_patterns=[
- "^@jupyterlab/(celltags-extension|debugger(-extension)?|extensionmanager(-extension)?|hub-extension|nbconvert-css|pluginmanager-extension|terminal(-extension)?|template)$",
+link_exclude_patterns = [
+ "^@jupyterlab/(debugger(-extension)?|extensionmanager(-extension)?|hub-extension|nbconvert-css|pluginmanager-extension|terminal(-extension)?|template)$",
"^@jupyter-notebook/(documentsearch-extension|lab-extension|terminal-extension)$",
]
From c1685c2575a4d9b1cf977c79eaced1e36faf66fc Mon Sep 17 00:00:00 2001
From: Nicholas Bollweg
Date: Tue, 12 Dec 2023 07:33:57 -0600
Subject: [PATCH 05/23] reverse lite pr order
---
jupyak_config.toml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/jupyak_config.toml b/jupyak_config.toml
index 0fef702..fd7d7c5 100644
--- a/jupyak_config.toml
+++ b/jupyak_config.toml
@@ -12,8 +12,8 @@ merge_with = [
merge_strategy = "ort"
merge_options = ["theirs"]
merge_with = [
- "pull/1267",
"pull/1263",
+ "pull/1267",
]
[repos.jupyterlite.js]
From c76b8173ed5ea8426ed4722b8bfadef5dbb0ad66 Mon Sep 17 00:00:00 2001
From: Nicholas Bollweg
Date: Tue, 12 Dec 2023 12:28:26 -0600
Subject: [PATCH 06/23] remove already-merged pr
---
jupyak_config.toml | 1 -
1 file changed, 1 deletion(-)
diff --git a/jupyak_config.toml b/jupyak_config.toml
index 0fef702..a37a96d 100644
--- a/jupyak_config.toml
+++ b/jupyak_config.toml
@@ -12,7 +12,6 @@ merge_with = [
merge_strategy = "ort"
merge_options = ["theirs"]
merge_with = [
- "pull/1267",
"pull/1263",
]
From 9877b37186ef2a16ec699e4585a035ffa2c550e1 Mon Sep 17 00:00:00 2001
From: Nicholas Bollweg
Date: Tue, 12 Dec 2023 12:29:09 -0600
Subject: [PATCH 07/23] remove already-merged pr
---
jupyak_config.toml | 1 -
1 file changed, 1 deletion(-)
diff --git a/jupyak_config.toml b/jupyak_config.toml
index fd7d7c5..a37a96d 100644
--- a/jupyak_config.toml
+++ b/jupyak_config.toml
@@ -13,7 +13,6 @@ merge_strategy = "ort"
merge_options = ["theirs"]
merge_with = [
"pull/1263",
- "pull/1267",
]
[repos.jupyterlite.js]
From 2f5efe9a75b9ecfd139c51f15480b09a723328b6 Mon Sep 17 00:00:00 2001
From: Nicholas Bollweg
Date: Tue, 12 Dec 2023 16:32:56 -0600
Subject: [PATCH 08/23] add patch_package_jsons
---
docs/_static/jupyak-v0.schema.json | 46 ++++++++++++++++++++++++
docs/_static/jupyak-v0.schema.toml | 44 +++++++++++++++++++++++
docs/_static/jupyak-v0.schema.yaml | 34 ++++++++++++++++++
jupyak_config.toml | 3 ++
src/jupyak/tasks/_js.ipynb | 34 +++++++++++++++++-
src/jupyak/tasks/_yak.ipynb | 57 +++++++++++++++++++++++++++---
6 files changed, 213 insertions(+), 5 deletions(-)
diff --git a/docs/_static/jupyak-v0.schema.json b/docs/_static/jupyak-v0.schema.json
index a837d29..96265cd 100644
--- a/docs/_static/jupyak-v0.schema.json
+++ b/docs/_static/jupyak-v0.schema.json
@@ -1207,6 +1207,14 @@
"type": "string"
}
},
+ "patch_package_jsons": {
+ "type": "object",
+ "title": "patch_package_jsons",
+ "description": "patches to package.json to help resolvability",
+ "additionalProperties": {
+ "$ref": "#/$defs/PackageJsonPatches"
+ }
+ },
"tasks": {
"type": "object",
"title": "tasks",
@@ -1260,6 +1268,44 @@
}
}
},
+ "PackageJsonPatches": {
+ "title": "PackageJsonPatches",
+ "description": "a subset of package.json",
+ "properties": {
+ "dependencies": {
+ "type": "object",
+ "title": "dependencies",
+ "description": "dependencies to add before linking",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "dev_dependencies": {
+ "type": "object",
+ "title": "dev_dependencies",
+ "description": "development dependencies to add before linking",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "resolutions": {
+ "type": "object",
+ "title": "resolutions",
+ "description": "resolutions to add before linking",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "scripts": {
+ "type": "object",
+ "title": "scripts",
+ "description": "scripts to overload to avoid bad effects",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ }
+ },
"PythonOptions": {
"title": "PythonOptions",
"description": "Python-related provisioning, building, and linking.",
diff --git a/docs/_static/jupyak-v0.schema.toml b/docs/_static/jupyak-v0.schema.toml
index 165cd7d..49da093 100644
--- a/docs/_static/jupyak-v0.schema.toml
+++ b/docs/_static/jupyak-v0.schema.toml
@@ -1182,6 +1182,14 @@ description = "regular expressions for the npm `@org/pkg` names that should _not
["$defs".JSOptions.properties.link_exclude_patterns.items]
type = "string"
+["$defs".JSOptions.properties.patch_package_jsons]
+type = "object"
+title = "patch_package_jsons"
+description = "patches to package.json to help resolvability"
+
+["$defs".JSOptions.properties.patch_package_jsons.additionalProperties]
+"$ref" = "#/$defs/PackageJsonPatches"
+
["$defs".JSOptions.properties.tasks]
type = "object"
title = "tasks"
@@ -1225,6 +1233,42 @@ type = "string"
title = "gist"
description = "a gist ID on GitHub to use as JupyterLite contents and config"
+["$defs".PackageJsonPatches]
+title = "PackageJsonPatches"
+description = "a subset of package.json"
+
+["$defs".PackageJsonPatches.properties.dependencies]
+type = "object"
+title = "dependencies"
+description = "dependencies to add before linking"
+
+["$defs".PackageJsonPatches.properties.dependencies.additionalProperties]
+type = "string"
+
+["$defs".PackageJsonPatches.properties.dev_dependencies]
+type = "object"
+title = "dev_dependencies"
+description = "development dependencies to add before linking"
+
+["$defs".PackageJsonPatches.properties.dev_dependencies.additionalProperties]
+type = "string"
+
+["$defs".PackageJsonPatches.properties.resolutions]
+type = "object"
+title = "resolutions"
+description = "resolutions to add before linking"
+
+["$defs".PackageJsonPatches.properties.resolutions.additionalProperties]
+type = "string"
+
+["$defs".PackageJsonPatches.properties.scripts]
+type = "object"
+title = "scripts"
+description = "scripts to overload to avoid bad effects"
+
+["$defs".PackageJsonPatches.properties.scripts.additionalProperties]
+type = "string"
+
["$defs".PythonOptions]
title = "PythonOptions"
description = "Python-related provisioning, building, and linking."
diff --git a/docs/_static/jupyak-v0.schema.yaml b/docs/_static/jupyak-v0.schema.yaml
index 3ab05bf..4a3fdf3 100644
--- a/docs/_static/jupyak-v0.schema.yaml
+++ b/docs/_static/jupyak-v0.schema.yaml
@@ -905,6 +905,12 @@ $defs:
into this repo
items:
type: string
+ patch_package_jsons:
+ type: object
+ title: patch_package_jsons
+ description: patches to package.json to help resolvability
+ additionalProperties:
+ $ref: '#/$defs/PackageJsonPatches'
tasks:
type: object
title: tasks
@@ -939,6 +945,34 @@ $defs:
type: string
title: gist
description: a gist ID on GitHub to use as JupyterLite contents and config
+ PackageJsonPatches:
+ title: PackageJsonPatches
+ description: a subset of package.json
+ properties:
+ dependencies:
+ type: object
+ title: dependencies
+ description: dependencies to add before linking
+ additionalProperties:
+ type: string
+ dev_dependencies:
+ type: object
+ title: dev_dependencies
+ description: development dependencies to add before linking
+ additionalProperties:
+ type: string
+ resolutions:
+ type: object
+ title: resolutions
+ description: resolutions to add before linking
+ additionalProperties:
+ type: string
+ scripts:
+ type: object
+ title: scripts
+ description: scripts to overload to avoid bad effects
+ additionalProperties:
+ type: string
PythonOptions:
title: PythonOptions
description: Python-related provisioning, building, and linking.
diff --git a/jupyak_config.toml b/jupyak_config.toml
index a37a96d..f178ab6 100644
--- a/jupyak_config.toml
+++ b/jupyak_config.toml
@@ -20,3 +20,6 @@ link_exclude_patterns = [
"^@jupyterlab/(debugger(-extension)?|extensionmanager(-extension)?|hub-extension|nbconvert-css|pluginmanager-extension|terminal(-extension)?|template)$",
"^@jupyter-notebook/(documentsearch-extension|lab-extension|terminal-extension)$",
]
+
+[repos.jupyterlite.js.patch_package_jsons."app/lab"]
+dependencies = { "@jupyterlab/celltags-extension" = "*" }
diff --git a/src/jupyak/tasks/_js.ipynb b/src/jupyak/tasks/_js.ipynb
index e3a1fbd..4f27598 100644
--- a/src/jupyak/tasks/_js.ipynb
+++ b/src/jupyak/tasks/_js.ipynb
@@ -171,10 +171,14 @@
"\n",
" install_deps += [yak.not_a_package_json]\n",
"\n",
+ " path_patches = {\n",
+ " work_path / path / W.PACKAGE_JSON: patch_package_json\n",
+ " for path, patch_package_json in js.patch_package_jsons.items()\n",
+ " }\n",
+ "\n",
" link_deps = [yak.work_path / DEP_YML_PATTERN.format(dep) for dep in js.dependencies]\n",
" install_deps += link_deps\n",
" pre_install_actions = [\n",
- " A.git([\"reset\", \"--hard\", \"HEAD\"], in_repo),\n",
" (\n",
" _fix_js_resolutions,\n",
" [\n",
@@ -183,12 +187,14 @@
" yak.not_a_package_json,\n",
" js.all_install_exclude_resolutions,\n",
" js.link_exclude_patterns,\n",
+ " path_patches,\n",
" ],\n",
" ),\n",
" ]\n",
"\n",
" yield dict(\n",
" name=f\"{repo.name}:yarn:install\",\n",
+ " uptodate=[doit.tools.config_changed({\"config\": js.to_dict()})],\n",
" doc=f\"> install npm dependencies of {repo.name}\",\n",
" actions=[*pre_install_actions, A.run([*yak.env.run_args, \"yarn\"], in_repo)],\n",
" file_dep=install_deps,\n",
@@ -250,6 +256,25 @@
" )"
]
},
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "a07c3dcf-c8eb-4372-850f-d1e23c681930",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def _patch_one_package_json(pkg_data: dict, patch_package_json: Y.PackageJsonPatches):\n",
+ " sections = {\n",
+ " \"dependencies\": patch_package_json.dependencies,\n",
+ " \"scripts\": patch_package_json.scripts,\n",
+ " \"devDependencies\": patch_package_json.dev_dependencies,\n",
+ " }\n",
+ " for section, values in sections.items():\n",
+ " if not values:\n",
+ " continue\n",
+ " pkg_data[section].update(values)"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
@@ -263,6 +288,7 @@
" not_a_package_json: Path,\n",
" install_exclude_resolutions: list[str],\n",
" link_exclude_patterns: list[str],\n",
+ " path_patches: dict[Path, Y.PackageJsonPatches],\n",
"):\n",
" print(f\" ... fixing resolutions for {package_json.parent.name}\")\n",
" pkg_data = json.loads(package_json.read_text(encoding=\"utf-8\"))\n",
@@ -271,6 +297,11 @@
" f\"\"\"link:{os.path.relpath(not_a_package_json.parent, package_json.parent)}\"\"\"\n",
" )\n",
"\n",
+ " patches = path_patches.get(package_json)\n",
+ " if patches:\n",
+ " print(f\"\"\" ... patching {package_json.parent.name}#/{section}\"\"\")\n",
+ " _patch_one_package_json(pkg_data, patches)\n",
+ "\n",
" for tgz_list in tgz_lists:\n",
" resolutions = yaml.safe_load(tgz_list.read_text(encoding=\"utf-8\"))\n",
" dest = package_json.parent.name\n",
@@ -303,6 +334,7 @@
" not_a_package_json,\n",
" install_exclude_resolutions,\n",
" link_exclude_patterns,\n",
+ " path_patches,\n",
" )"
]
},
diff --git a/src/jupyak/tasks/_yak.ipynb b/src/jupyak/tasks/_yak.ipynb
index b91a33b..791cc9e 100644
--- a/src/jupyak/tasks/_yak.ipynb
+++ b/src/jupyak/tasks/_yak.ipynb
@@ -644,6 +644,44 @@
" return as_dict"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "c65b12e4-0b2b-4325-84ec-fc73c1569de8",
+ "metadata": {},
+ "source": [
+ "a subset of package.json"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "3eb7d2c2-4b53-4420-9497-68dbcf277d8d",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class PackageJsonPatches(HasSchema):\n",
+ " dependencies = T.Dict(\n",
+ " key_trait=T.Unicode(),\n",
+ " value_trait=T.Unicode(),\n",
+ " help=\"dependencies to add before linking\",\n",
+ " )\n",
+ " dev_dependencies = T.Dict(\n",
+ " key_trait=T.Unicode(),\n",
+ " value_trait=T.Unicode(),\n",
+ " help=\"development dependencies to add before linking\",\n",
+ " )\n",
+ " resolutions = T.Dict(\n",
+ " key_trait=T.Unicode(),\n",
+ " value_trait=T.Unicode(),\n",
+ " help=\"resolutions to add before linking\",\n",
+ " )\n",
+ " scripts = T.Dict(\n",
+ " key_trait=T.Unicode(),\n",
+ " value_trait=T.Unicode(),\n",
+ " help=\"scripts to overload to avoid bad effects\",\n",
+ " )"
+ ]
+ },
{
"cell_type": "markdown",
"id": "e5a4859f-7fb6-4641-8945-51a4c4be01b2",
@@ -682,14 +720,25 @@
" T.Unicode(),\n",
" help=\"regular expressions for the npm `@org/pkg` names that should _not_ be installed, ever, in this repo\",\n",
" )\n",
+ " patch_package_jsons = T.Dict(\n",
+ " key_trait=T.Unicode(),\n",
+ " value_trait=InstanceDict(PackageJsonPatches),\n",
+ " help=\"patches to package.json to help resolvability\",\n",
+ " )\n",
"\n",
" def to_dict(self):\n",
" as_dict = super().to_dict()\n",
- " all_tasks = as_dict.get(\"tasks\", {})\n",
- " if all_tasks:\n",
+ " tasks = as_dict.get(\"tasks\", {})\n",
+ " if tasks:\n",
" as_dict[\"tasks\"] = {\n",
- " cwd: [task.to_dict() for task in path_tasks]\n",
- " for cwd, path_tasks in all_tasks.items()\n",
+ " path: [path_task.to_dict() for path_task in path_tasks]\n",
+ " for path, path_tasks in tasks.items()\n",
+ " }\n",
+ " patch_package_jsons = as_dict.get(\"patch_package_jsons\", {})\n",
+ " if patch_package_jsons:\n",
+ " as_dict[\"patch_package_jsons\"] = {\n",
+ " path: pkg_json.to_dict()\n",
+ " for path, pkg_json in patch_package_jsons.items()\n",
" }\n",
" return as_dict\n",
"\n",
From 2321dbb040ee62294f4a35a4cdb7fc42cb8f3ddb Mon Sep 17 00:00:00 2001
From: Nicholas Bollweg
Date: Tue, 12 Dec 2023 16:44:15 -0600
Subject: [PATCH 09/23] more backport from #21
---
docs/_static/jupyak-v0.schema.json | 46 ++++++++++++++++++++++++
docs/_static/jupyak-v0.schema.toml | 44 +++++++++++++++++++++++
docs/_static/jupyak-v0.schema.yaml | 34 ++++++++++++++++++
src/jupyak/tasks/_js.ipynb | 34 +++++++++++++++++-
src/jupyak/tasks/_yak.ipynb | 57 +++++++++++++++++++++++++++---
5 files changed, 210 insertions(+), 5 deletions(-)
diff --git a/docs/_static/jupyak-v0.schema.json b/docs/_static/jupyak-v0.schema.json
index a837d29..96265cd 100644
--- a/docs/_static/jupyak-v0.schema.json
+++ b/docs/_static/jupyak-v0.schema.json
@@ -1207,6 +1207,14 @@
"type": "string"
}
},
+ "patch_package_jsons": {
+ "type": "object",
+ "title": "patch_package_jsons",
+ "description": "patches to package.json to help resolvability",
+ "additionalProperties": {
+ "$ref": "#/$defs/PackageJsonPatches"
+ }
+ },
"tasks": {
"type": "object",
"title": "tasks",
@@ -1260,6 +1268,44 @@
}
}
},
+ "PackageJsonPatches": {
+ "title": "PackageJsonPatches",
+ "description": "a subset of package.json",
+ "properties": {
+ "dependencies": {
+ "type": "object",
+ "title": "dependencies",
+ "description": "dependencies to add before linking",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "dev_dependencies": {
+ "type": "object",
+ "title": "dev_dependencies",
+ "description": "development dependencies to add before linking",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "resolutions": {
+ "type": "object",
+ "title": "resolutions",
+ "description": "resolutions to add before linking",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "scripts": {
+ "type": "object",
+ "title": "scripts",
+ "description": "scripts to overload to avoid bad effects",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ }
+ },
"PythonOptions": {
"title": "PythonOptions",
"description": "Python-related provisioning, building, and linking.",
diff --git a/docs/_static/jupyak-v0.schema.toml b/docs/_static/jupyak-v0.schema.toml
index 165cd7d..49da093 100644
--- a/docs/_static/jupyak-v0.schema.toml
+++ b/docs/_static/jupyak-v0.schema.toml
@@ -1182,6 +1182,14 @@ description = "regular expressions for the npm `@org/pkg` names that should _not
["$defs".JSOptions.properties.link_exclude_patterns.items]
type = "string"
+["$defs".JSOptions.properties.patch_package_jsons]
+type = "object"
+title = "patch_package_jsons"
+description = "patches to package.json to help resolvability"
+
+["$defs".JSOptions.properties.patch_package_jsons.additionalProperties]
+"$ref" = "#/$defs/PackageJsonPatches"
+
["$defs".JSOptions.properties.tasks]
type = "object"
title = "tasks"
@@ -1225,6 +1233,42 @@ type = "string"
title = "gist"
description = "a gist ID on GitHub to use as JupyterLite contents and config"
+["$defs".PackageJsonPatches]
+title = "PackageJsonPatches"
+description = "a subset of package.json"
+
+["$defs".PackageJsonPatches.properties.dependencies]
+type = "object"
+title = "dependencies"
+description = "dependencies to add before linking"
+
+["$defs".PackageJsonPatches.properties.dependencies.additionalProperties]
+type = "string"
+
+["$defs".PackageJsonPatches.properties.dev_dependencies]
+type = "object"
+title = "dev_dependencies"
+description = "development dependencies to add before linking"
+
+["$defs".PackageJsonPatches.properties.dev_dependencies.additionalProperties]
+type = "string"
+
+["$defs".PackageJsonPatches.properties.resolutions]
+type = "object"
+title = "resolutions"
+description = "resolutions to add before linking"
+
+["$defs".PackageJsonPatches.properties.resolutions.additionalProperties]
+type = "string"
+
+["$defs".PackageJsonPatches.properties.scripts]
+type = "object"
+title = "scripts"
+description = "scripts to overload to avoid bad effects"
+
+["$defs".PackageJsonPatches.properties.scripts.additionalProperties]
+type = "string"
+
["$defs".PythonOptions]
title = "PythonOptions"
description = "Python-related provisioning, building, and linking."
diff --git a/docs/_static/jupyak-v0.schema.yaml b/docs/_static/jupyak-v0.schema.yaml
index 3ab05bf..4a3fdf3 100644
--- a/docs/_static/jupyak-v0.schema.yaml
+++ b/docs/_static/jupyak-v0.schema.yaml
@@ -905,6 +905,12 @@ $defs:
into this repo
items:
type: string
+ patch_package_jsons:
+ type: object
+ title: patch_package_jsons
+ description: patches to package.json to help resolvability
+ additionalProperties:
+ $ref: '#/$defs/PackageJsonPatches'
tasks:
type: object
title: tasks
@@ -939,6 +945,34 @@ $defs:
type: string
title: gist
description: a gist ID on GitHub to use as JupyterLite contents and config
+ PackageJsonPatches:
+ title: PackageJsonPatches
+ description: a subset of package.json
+ properties:
+ dependencies:
+ type: object
+ title: dependencies
+ description: dependencies to add before linking
+ additionalProperties:
+ type: string
+ dev_dependencies:
+ type: object
+ title: dev_dependencies
+ description: development dependencies to add before linking
+ additionalProperties:
+ type: string
+ resolutions:
+ type: object
+ title: resolutions
+ description: resolutions to add before linking
+ additionalProperties:
+ type: string
+ scripts:
+ type: object
+ title: scripts
+ description: scripts to overload to avoid bad effects
+ additionalProperties:
+ type: string
PythonOptions:
title: PythonOptions
description: Python-related provisioning, building, and linking.
diff --git a/src/jupyak/tasks/_js.ipynb b/src/jupyak/tasks/_js.ipynb
index e3a1fbd..4f27598 100644
--- a/src/jupyak/tasks/_js.ipynb
+++ b/src/jupyak/tasks/_js.ipynb
@@ -171,10 +171,14 @@
"\n",
" install_deps += [yak.not_a_package_json]\n",
"\n",
+ " path_patches = {\n",
+ " work_path / path / W.PACKAGE_JSON: patch_package_json\n",
+ " for path, patch_package_json in js.patch_package_jsons.items()\n",
+ " }\n",
+ "\n",
" link_deps = [yak.work_path / DEP_YML_PATTERN.format(dep) for dep in js.dependencies]\n",
" install_deps += link_deps\n",
" pre_install_actions = [\n",
- " A.git([\"reset\", \"--hard\", \"HEAD\"], in_repo),\n",
" (\n",
" _fix_js_resolutions,\n",
" [\n",
@@ -183,12 +187,14 @@
" yak.not_a_package_json,\n",
" js.all_install_exclude_resolutions,\n",
" js.link_exclude_patterns,\n",
+ " path_patches,\n",
" ],\n",
" ),\n",
" ]\n",
"\n",
" yield dict(\n",
" name=f\"{repo.name}:yarn:install\",\n",
+ " uptodate=[doit.tools.config_changed({\"config\": js.to_dict()})],\n",
" doc=f\"> install npm dependencies of {repo.name}\",\n",
" actions=[*pre_install_actions, A.run([*yak.env.run_args, \"yarn\"], in_repo)],\n",
" file_dep=install_deps,\n",
@@ -250,6 +256,25 @@
" )"
]
},
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "a07c3dcf-c8eb-4372-850f-d1e23c681930",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def _patch_one_package_json(pkg_data: dict, patch_package_json: Y.PackageJsonPatches):\n",
+ " sections = {\n",
+ " \"dependencies\": patch_package_json.dependencies,\n",
+ " \"scripts\": patch_package_json.scripts,\n",
+ " \"devDependencies\": patch_package_json.dev_dependencies,\n",
+ " }\n",
+ " for section, values in sections.items():\n",
+ " if not values:\n",
+ " continue\n",
+ " pkg_data[section].update(values)"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
@@ -263,6 +288,7 @@
" not_a_package_json: Path,\n",
" install_exclude_resolutions: list[str],\n",
" link_exclude_patterns: list[str],\n",
+ " path_patches: dict[Path, Y.PackageJsonPatches],\n",
"):\n",
" print(f\" ... fixing resolutions for {package_json.parent.name}\")\n",
" pkg_data = json.loads(package_json.read_text(encoding=\"utf-8\"))\n",
@@ -271,6 +297,11 @@
" f\"\"\"link:{os.path.relpath(not_a_package_json.parent, package_json.parent)}\"\"\"\n",
" )\n",
"\n",
+ " patches = path_patches.get(package_json)\n",
+ " if patches:\n",
+ " print(f\"\"\" ... patching {package_json.parent.name}#/{section}\"\"\")\n",
+ " _patch_one_package_json(pkg_data, patches)\n",
+ "\n",
" for tgz_list in tgz_lists:\n",
" resolutions = yaml.safe_load(tgz_list.read_text(encoding=\"utf-8\"))\n",
" dest = package_json.parent.name\n",
@@ -303,6 +334,7 @@
" not_a_package_json,\n",
" install_exclude_resolutions,\n",
" link_exclude_patterns,\n",
+ " path_patches,\n",
" )"
]
},
diff --git a/src/jupyak/tasks/_yak.ipynb b/src/jupyak/tasks/_yak.ipynb
index b91a33b..791cc9e 100644
--- a/src/jupyak/tasks/_yak.ipynb
+++ b/src/jupyak/tasks/_yak.ipynb
@@ -644,6 +644,44 @@
" return as_dict"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "c65b12e4-0b2b-4325-84ec-fc73c1569de8",
+ "metadata": {},
+ "source": [
+ "a subset of package.json"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "3eb7d2c2-4b53-4420-9497-68dbcf277d8d",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class PackageJsonPatches(HasSchema):\n",
+ " dependencies = T.Dict(\n",
+ " key_trait=T.Unicode(),\n",
+ " value_trait=T.Unicode(),\n",
+ " help=\"dependencies to add before linking\",\n",
+ " )\n",
+ " dev_dependencies = T.Dict(\n",
+ " key_trait=T.Unicode(),\n",
+ " value_trait=T.Unicode(),\n",
+ " help=\"development dependencies to add before linking\",\n",
+ " )\n",
+ " resolutions = T.Dict(\n",
+ " key_trait=T.Unicode(),\n",
+ " value_trait=T.Unicode(),\n",
+ " help=\"resolutions to add before linking\",\n",
+ " )\n",
+ " scripts = T.Dict(\n",
+ " key_trait=T.Unicode(),\n",
+ " value_trait=T.Unicode(),\n",
+ " help=\"scripts to overload to avoid bad effects\",\n",
+ " )"
+ ]
+ },
{
"cell_type": "markdown",
"id": "e5a4859f-7fb6-4641-8945-51a4c4be01b2",
@@ -682,14 +720,25 @@
" T.Unicode(),\n",
" help=\"regular expressions for the npm `@org/pkg` names that should _not_ be installed, ever, in this repo\",\n",
" )\n",
+ " patch_package_jsons = T.Dict(\n",
+ " key_trait=T.Unicode(),\n",
+ " value_trait=InstanceDict(PackageJsonPatches),\n",
+ " help=\"patches to package.json to help resolvability\",\n",
+ " )\n",
"\n",
" def to_dict(self):\n",
" as_dict = super().to_dict()\n",
- " all_tasks = as_dict.get(\"tasks\", {})\n",
- " if all_tasks:\n",
+ " tasks = as_dict.get(\"tasks\", {})\n",
+ " if tasks:\n",
" as_dict[\"tasks\"] = {\n",
- " cwd: [task.to_dict() for task in path_tasks]\n",
- " for cwd, path_tasks in all_tasks.items()\n",
+ " path: [path_task.to_dict() for path_task in path_tasks]\n",
+ " for path, path_tasks in tasks.items()\n",
+ " }\n",
+ " patch_package_jsons = as_dict.get(\"patch_package_jsons\", {})\n",
+ " if patch_package_jsons:\n",
+ " as_dict[\"patch_package_jsons\"] = {\n",
+ " path: pkg_json.to_dict()\n",
+ " for path, pkg_json in patch_package_jsons.items()\n",
" }\n",
" return as_dict\n",
"\n",
From fa65cb2e8f6a2fcfca60597053ebff5998151442 Mon Sep 17 00:00:00 2001
From: Nicholas Bollweg
Date: Fri, 15 Dec 2023 08:29:19 -0600
Subject: [PATCH 10/23] start custom archive name
---
.binder/conda-linux-64.lock | 26 +++++++++-------
.binder/environment.yml | 1 +
.github/conda-linux-64.lock | 19 ++++++++----
.github/environment.yml | 1 +
docs/conda-linux-64.lock | 15 ++++++---
docs/environment.yml | 1 +
src/jupyak/tasks/_actions.ipynb | 49 ++++++++++++++++++++++++++++--
src/jupyak/tasks/_lite.ipynb | 46 +++++++++++++++++++++-------
src/jupyak/tasks/_self.ipynb | 2 ++
src/jupyak/tasks/_well_known.ipynb | 44 +++++++++++++++++++++++++++
10 files changed, 170 insertions(+), 34 deletions(-)
diff --git a/.binder/conda-linux-64.lock b/.binder/conda-linux-64.lock
index 3ffc807..99b015a 100644
--- a/.binder/conda-linux-64.lock
+++ b/.binder/conda-linux-64.lock
@@ -1,6 +1,6 @@
# Generated by conda-lock.
# platform: linux-64
-# input_hash: 190558c330301bca8cb78bf20b221e3b8e7ffd1e86707d9fde930fe70d6055ac
+# input_hash: a1f7efb953a37541d4b8669cda161869cdd01ab1b3d572ba6894a75a18ceb972
@EXPLICIT
https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2#d7c89558ba9fa0495403155b64376d81
https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2023.11.17-hbcca054_0.conda#01ffc8d36f9eba0ce0b3c1955fa780ee
@@ -31,7 +31,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.19-hd590300_0.conda
https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.5.0-hcb278e6_1.conda#6305a3dd2752c76335295da4e581f2fd
https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.2-h7f98852_5.tar.bz2#d645c6d2ac96843a2bfaccd2d62b3ac3
https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-13.2.0-ha4646dd_3.conda#c714d905cdfa0e70200f68b80cc04764
-https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.17-h166bdaf_0.tar.bz2#b62b52da46c39ee2bc3c162ac7f1804d
+https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.17-hd590300_1.conda#4b06b43d0eca61db2899e4d7a289c302
https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.0.0-hd590300_1.conda#ea25936bb4080d843790b586850f82b8
https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hd590300_0.conda#30fd6e37fe21f86f4bd26d6ee73eeec7
https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.18-h36c2ea0_1.tar.bz2#c3788462a6fbddafdb413a9f9053e58d
@@ -39,6 +39,8 @@ https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda#
https://conda.anaconda.org/conda-forge/linux-64/libuv-1.46.0-hd590300_0.conda#d23c76f7e6dcd6243d1b6ef5e62d17d2
https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.3.2-hd590300_0.conda#30de3fd9b3b602f7473f30e684eeea8c
https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.2.13-hd590300_5.conda#f36c115f1ee199da648e0597ec2047ad
+https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.9.4-hcb278e6_0.conda#318b08df404f9c9be5712aaa5a6f0bb0
+https://conda.anaconda.org/conda-forge/linux-64/lzo-2.10-h516909a_1000.tar.bz2#bb14fcb13341b81d5eb386423b9d2bac
https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.4-h59595ed_2.conda#7dbaa197d7ba6032caf7ae7f32c1efa0
https://conda.anaconda.org/conda-forge/linux-64/openssl-3.2.0-hd590300_1.conda#603827b39ea2b835268adb8c821b8570
https://conda.anaconda.org/conda-forge/linux-64/pixman-0.42.2-h59595ed_0.conda#700edd63ccd5fc66b70b1c028cea9a68
@@ -58,7 +60,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-13.2.0-h69a702a_3
https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.39-h753d276_0.conda#e1c890aebdebbfbf87e2c917187b4416
https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.44.2-h2797004_0.conda#3b6a9f225c3dbe0d24f4fedd4625c5bf
https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.15-h0b41bf4_0.conda#33277193f5b92bad9fdd230eb700929c
-https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.12.2-h232c23b_0.conda#1917ed337979482731e8ac8c1bedf9dd
+https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.12.3-h232c23b_0.conda#bc6ac4c0cea148d924f621985bc3892b
https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.42-hcad00b1_0.conda#679c8961826aa4b50653bce17ee52abe
https://conda.anaconda.org/conda-forge/linux-64/perl-5.32.1-4_hd590300_perl5.conda#3e785bff761095eb7f8676f4694bd1b1
https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8228510_1.conda#47d31b792659ce70f470b5c82fdfb7a4
@@ -69,11 +71,12 @@ https://conda.anaconda.org/conda-forge/linux-64/zlib-1.2.13-hd590300_5.conda#68c
https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.5-hfc55251_0.conda#04b88013080254850d6c01ed54810589
https://conda.anaconda.org/conda-forge/linux-64/fftw-3.3.10-nompi_hc118613_108.conda#6fa90698000b05dfe8ce6515794fe71a
https://conda.anaconda.org/conda-forge/linux-64/freetype-2.12.1-h267a509_2.conda#9ae35c3d96db2c94ce0cef86efdfa2cb
+https://conda.anaconda.org/conda-forge/linux-64/libarchive-3.7.2-h2aa1ff5_1.conda#3bf887827d1968275978361a6e405e4f
https://conda.anaconda.org/conda-forge/linux-64/libglib-2.78.3-h783c2da_0.conda#9bd06b12bbfa6fd1740fd23af4b0f0c7
https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.6.0-ha9c0a0a_2.conda#55ed21669b2015f77c180feb1dd41930
https://conda.anaconda.org/conda-forge/linux-64/nodejs-20.9.0-hb753e55_0.conda#ddfcb003b0a6804fabe7dfbf1be16651
https://conda.anaconda.org/conda-forge/linux-64/pandoc-3.1.3-h32600fe_0.conda#8287aeb8462e2d4b235eff788e75919d
-https://conda.anaconda.org/conda-forge/linux-64/python-3.11.6-hab00c5b_0_cpython.conda#b0dfbe2fcbfdb097d321bfd50ecddab1
+https://conda.anaconda.org/conda-forge/linux-64/python-3.11.7-hab00c5b_0_cpython.conda#bf281a975393266ab95734a8cfd532ec
https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.7-h8ee46fc_0.conda#49e482d882669206653b095f5206c05b
https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.13-pyhd8ed1ab_0.conda#06006184e203b61d3525f90de394471e
https://conda.anaconda.org/conda-forge/linux-64/atk-1.0-2.38.0-hd4edc92_1.tar.bz2#6c72ec3e660a51736913ef6ea68c454b
@@ -127,12 +130,13 @@ https://conda.anaconda.org/conda-forge/noarch/pygments-2.17.2-pyhd8ed1ab_0.conda
https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha2e5f31_6.tar.bz2#2a7de29fb590ca14b5243c4c812c8025
https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.19.0-pyhd8ed1ab_0.conda#e4dbdb3585c0266b4710467fe7b75cf4
https://conda.anaconda.org/conda-forge/noarch/python-json-logger-2.0.7-pyhd8ed1ab_0.conda#a61bf9ec79426938ff785eb69dbb1960
+https://conda.anaconda.org/conda-forge/linux-64/python-libarchive-c-5.0-py311h38be061_2.conda#59706c47c2921d0889f6cc8b375b093a
https://conda.anaconda.org/conda-forge/noarch/pytz-2023.3.post1-pyhd8ed1ab_0.conda#c93346b446cd08c169d843ae5fc0da97
https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.1-py311h459d7ec_1.conda#52719a74ad130de8fb5d047dc91f247a
https://conda.anaconda.org/conda-forge/linux-64/pyzmq-25.1.2-py311h34ded2d_0.conda#819aa640a0493d4b52faf938e94d129e
https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2#912a71cc01012ee38e6b90ddd561e36f
https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.13.2-py311h46250e7_0.conda#c5f5089dd1fe0000fecaf0d12eca50b9
-https://conda.anaconda.org/conda-forge/linux-64/ruff-0.1.7-py311h7145743_0.conda#7e4329efd6a902a64470bfbe21a83e21
+https://conda.anaconda.org/conda-forge/linux-64/ruff-0.1.8-py311h7145743_0.conda#ed03c6cf88c287ce426c4d93013fbcbe
https://conda.anaconda.org/conda-forge/noarch/send2trash-1.8.2-pyh41d4057_0.conda#ada5a17adcd10be4fc7e37e4166ba0e2
https://conda.anaconda.org/conda-forge/noarch/setuptools-68.2.2-pyhd8ed1ab_0.conda#fc2166155db840c634a1291a5c35a709
https://conda.anaconda.org/conda-forge/noarch/six-1.16.0-pyh6c4a22f_0.tar.bz2#e5f25f8dbc060e9a8d912e432202afc2
@@ -165,14 +169,14 @@ https://conda.anaconda.org/conda-forge/noarch/accessible-pygments-0.0.4-pyhd8ed1
https://conda.anaconda.org/conda-forge/noarch/anyio-4.1.0-pyhd8ed1ab_0.conda#76a3b574717769c4c937c2afa2f1069f
https://conda.anaconda.org/conda-forge/noarch/asttokens-2.4.1-pyhd8ed1ab_0.conda#5f25798dcefd8252ce5f9dc494d5f571
https://conda.anaconda.org/conda-forge/noarch/async-lru-2.0.4-pyhd8ed1ab_0.conda#3d081de3a6ea9f894bbb585e8e3a4dcb
-https://conda.anaconda.org/conda-forge/noarch/babel-2.13.1-pyhd8ed1ab_0.conda#3ccff479c246692468f604df9c85ef26
+https://conda.anaconda.org/conda-forge/noarch/babel-2.14.0-pyhd8ed1ab_0.conda#9669586875baeced8fc30c0826c3270e
https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.12.2-pyha770c72_0.conda#a362ff7d976217f8fa78c0f1c4f59717
https://conda.anaconda.org/conda-forge/noarch/bleach-6.1.0-pyhd8ed1ab_0.conda#0ed9d7c0e9afa7c025807a9a8136ea3e
https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2#9b347a7ec10940d3f7941ff6c460b551
https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.0-h3faef2a_0.conda#f907bb958910dc404647326ca80c263e
https://conda.anaconda.org/conda-forge/linux-64/cffi-1.16.0-py311hb3a22ac_0.conda#b3469563ac5e808b0cd92810d0697043
https://conda.anaconda.org/conda-forge/noarch/comm-0.1.4-pyhd8ed1ab_0.conda#c8eaca39e2b6abae1fc96acc929ae939
-https://conda.anaconda.org/conda-forge/linux-64/coverage-7.3.2-py311h459d7ec_0.conda#7b3145fed7adc7c63a0e08f6f29f5480
+https://conda.anaconda.org/conda-forge/linux-64/coverage-7.3.3-py311h459d7ec_0.conda#9db2c1316e96068c0189beaeb716f3fe
https://conda.anaconda.org/conda-forge/noarch/h11-0.14.0-pyhd8ed1ab_0.tar.bz2#b21ed0883505ba1910994f1df031a428
https://conda.anaconda.org/conda-forge/noarch/h2-4.1.0-pyhd8ed1ab_0.tar.bz2#b748fbf7060927a6e82df7cb5ee8f097
https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-7.0.0-pyha770c72_0.conda#a941237cd06538837b25cd245fcd25d8
@@ -187,7 +191,7 @@ https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.1.6-pyhd8ed1ab
https://conda.anaconda.org/conda-forge/noarch/overrides-7.4.0-pyhd8ed1ab_0.conda#4625b7b01d7f4ac9c96300a5515acfaa
https://conda.anaconda.org/conda-forge/noarch/pexpect-4.8.0-pyh1a96a4e_2.tar.bz2#330448ce4403cc74990ac07c555942a1
https://conda.anaconda.org/conda-forge/noarch/pip-23.3.1-pyhd8ed1ab_0.conda#2400c0b86889f43aa52067161e1fb108
-https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.41-pyha770c72_0.conda#f511a993aa4336bef9dd874ee3403e67
+https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.42-pyha770c72_0.conda#0bf64bf10eee21f46ac83c161917fa86
https://conda.anaconda.org/conda-forge/noarch/pyproject_hooks-1.0.0-pyhd8ed1ab_0.conda#21de50391d584eb7f4441b9de1ad773f
https://conda.anaconda.org/conda-forge/noarch/pytest-7.4.3-pyhd8ed1ab_0.conda#5bdca0aca30b0ee62bb84854e027eae0
https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.8.2-pyhd8ed1ab_0.tar.bz2#dd999d1cc9f79e67dbb855c8924c7984
@@ -207,7 +211,7 @@ https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.2-pyhd8ed1ab_0.conda#
https://conda.anaconda.org/conda-forge/noarch/importlib_metadata-7.0.0-hd8ed1ab_0.conda#12aff14f84c337be5e5636bf612f4140
https://conda.anaconda.org/conda-forge/noarch/importnb-2023.11.1-pyhd8ed1ab_0.conda#ba8b9c1df29bfba4257b0dcddadbfa6b
https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2023.11.2-pyhd8ed1ab_0.conda#73884ca36d6d96cbce498cde99fab40f
-https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.4.4-pyhd8ed1ab_1.conda#7c0965e1d4a0ee1529e8eaa03a78a5b3
+https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.0-pyhd8ed1ab_0.conda#37a8b4098d428ecd40e58f8ec8a8e77d
https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.4.0-pyhd8ed1ab_0.conda#6c5358a10873a15398b6f15f60cb5e1f
https://conda.anaconda.org/conda-forge/noarch/pytest-cov-4.1.0-pyhd8ed1ab_0.conda#06eb685a3a0b146347a58dda979485da
https://conda.anaconda.org/conda-forge/noarch/pytest-metadata-3.0.0-pyhd8ed1ab_1.conda#8bdcc0f401561213821bf67513abeeff
@@ -224,7 +228,7 @@ https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.20.0-pyhd8ed1ab_0.con
https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.0-pyhd8ed1ab_0.conda#6bd3f1069cdebb44c7ae9efb900e312d
https://conda.anaconda.org/conda-forge/linux-64/pango-1.50.14-ha41ecd1_2.conda#1a66c10f6a0da3dbd2f3a68127e7f6a0
https://conda.anaconda.org/conda-forge/noarch/pytest-html-4.1.1-pyhd8ed1ab_0.conda#4d2040212307d18392a2687772b3a96d
-https://conda.anaconda.org/conda-forge/linux-64/gtk2-2.24.33-h90689f9_2.tar.bz2#957a0255ab58aaf394a91725d73ab422
+https://conda.anaconda.org/conda-forge/linux-64/gtk2-2.24.33-h7f000aa_3.conda#0abfa7f9241a0f4fd732bc15773cfb0c
https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.26.0-pyhf8b6a83_0.conda#2307f71f5f0896d4b91b93e6b468abff
https://conda.anaconda.org/conda-forge/noarch/ipywidgets-8.1.1-pyhd8ed1ab_0.conda#2605fae5ee27100e5f10037baebf4d41
https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.20.0-pyhd8ed1ab_0.conda#a168c5f84010711f6d4ae650bc22b480
@@ -234,7 +238,7 @@ https://conda.anaconda.org/conda-forge/linux-64/graphviz-9.0.0-h78e8752_1.conda#
https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.9.0-pyhd8ed1ab_0.conda#00ba25993f0dba38cf72a7224e33289f
https://conda.anaconda.org/conda-forge/noarch/nbclient-0.8.0-pyhd8ed1ab_0.conda#e78da91cf428faaf05701ce8cc8f2f9b
https://conda.anaconda.org/conda-forge/noarch/nbstripout-0.6.1-pyhd8ed1ab_0.tar.bz2#53913d98739527409e0f3227ed7eef7d
-https://conda.anaconda.org/conda-forge/linux-64/imagemagick-7.1.1_22-pl5321h3fa1221_0.conda#191ab65d14865220e410d7685f7baa4b
+https://conda.anaconda.org/conda-forge/linux-64/imagemagick-7.1.1_23-pl5321h3fa1221_0.conda#a6903dabfbd42af2b662e2b274656161
https://conda.anaconda.org/conda-forge/noarch/jupyter-cache-1.0.0-pyhd8ed1ab_0.conda#b667cf7b57baa559f628d374f017fa32
https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.12.0-pyhd8ed1ab_0.conda#4d67c68fd0d130091ada039bc2d81b33
https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.12.1-pyhd8ed1ab_0.conda#e9781be1e6c93b5df2c180a9f9242420
diff --git a/.binder/environment.yml b/.binder/environment.yml
index 1b75481..66664ea 100644
--- a/.binder/environment.yml
+++ b/.binder/environment.yml
@@ -45,6 +45,7 @@ dependencies:
- myst-nb
- nbconvert
- pydata-sphinx-theme
+ - python-libarchive-c
- sphinx-copybutton
- sphinxcontrib-mermaid
- sphinxext-rediraffe
diff --git a/.github/conda-linux-64.lock b/.github/conda-linux-64.lock
index 9a8865f..f4e5b54 100644
--- a/.github/conda-linux-64.lock
+++ b/.github/conda-linux-64.lock
@@ -1,6 +1,6 @@
# Generated by conda-lock.
# platform: linux-64
-# input_hash: 406816d1b1ba9f86cd9d04a6c8ba7691ec8b4fb173df268cf2719cbb8ac4f922
+# input_hash: ec4ac481daadd162773783456fc19f4c9a0910c2effd650a116d4ef2445838b1
@EXPLICIT
https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2#d7c89558ba9fa0495403155b64376d81
https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2023.11.17-hbcca054_0.conda#01ffc8d36f9eba0ce0b3c1955fa780ee
@@ -16,23 +16,29 @@ https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-h59595ed_0.conda#0e33e
https://conda.anaconda.org/conda-forge/linux-64/icu-73.2-h59595ed_0.conda#cc47e1facc155f91abd89b11e48e72ff
https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.5.0-hcb278e6_1.conda#6305a3dd2752c76335295da4e581f2fd
https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.2-h7f98852_5.tar.bz2#d645c6d2ac96843a2bfaccd2d62b3ac3
+https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.17-hd590300_1.conda#4b06b43d0eca61db2899e4d7a289c302
https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hd590300_0.conda#30fd6e37fe21f86f4bd26d6ee73eeec7
https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.18-h36c2ea0_1.tar.bz2#c3788462a6fbddafdb413a9f9053e58d
https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda#40b61aab5c7ba9ff276c41cfffe6b80b
https://conda.anaconda.org/conda-forge/linux-64/libuv-1.46.0-hd590300_0.conda#d23c76f7e6dcd6243d1b6ef5e62d17d2
https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.2.13-hd590300_5.conda#f36c115f1ee199da648e0597ec2047ad
+https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.9.4-hcb278e6_0.conda#318b08df404f9c9be5712aaa5a6f0bb0
+https://conda.anaconda.org/conda-forge/linux-64/lzo-2.10-h516909a_1000.tar.bz2#bb14fcb13341b81d5eb386423b9d2bac
https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.4-h59595ed_2.conda#7dbaa197d7ba6032caf7ae7f32c1efa0
https://conda.anaconda.org/conda-forge/linux-64/openssl-3.2.0-hd590300_1.conda#603827b39ea2b835268adb8c821b8570
https://conda.anaconda.org/conda-forge/linux-64/xz-5.2.6-h166bdaf_0.tar.bz2#2161070d867d1b1204ea749c8eec4ef0
https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h7f98852_2.tar.bz2#4cb3ad778ec2d5a7acbdf254eb1c42ae
https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.44.2-h2797004_0.conda#3b6a9f225c3dbe0d24f4fedd4625c5bf
+https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.12.3-h232c23b_0.conda#bc6ac4c0cea148d924f621985bc3892b
https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8228510_1.conda#47d31b792659ce70f470b5c82fdfb7a4
https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda#d453b98d9c83e71da0741bb0ff4d76bc
https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h59595ed_0.conda#8851084c192dbc56215ac4e3c9aa30fa
https://conda.anaconda.org/conda-forge/linux-64/zlib-1.2.13-hd590300_5.conda#68c34ec6149623be41a1933ab996a209
+https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.5-hfc55251_0.conda#04b88013080254850d6c01ed54810589
+https://conda.anaconda.org/conda-forge/linux-64/libarchive-3.7.2-h2aa1ff5_1.conda#3bf887827d1968275978361a6e405e4f
https://conda.anaconda.org/conda-forge/linux-64/nodejs-20.9.0-hb753e55_0.conda#ddfcb003b0a6804fabe7dfbf1be16651
https://conda.anaconda.org/conda-forge/linux-64/pandoc-3.1.3-h32600fe_0.conda#8287aeb8462e2d4b235eff788e75919d
-https://conda.anaconda.org/conda-forge/linux-64/python-3.11.6-hab00c5b_0_cpython.conda#b0dfbe2fcbfdb097d321bfd50ecddab1
+https://conda.anaconda.org/conda-forge/linux-64/python-3.11.7-hab00c5b_0_cpython.conda#bf281a975393266ab95734a8cfd532ec
https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.13-pyhd8ed1ab_0.conda#06006184e203b61d3525f90de394471e
https://conda.anaconda.org/conda-forge/noarch/attrs-23.1.0-pyh71513ae_1.conda#3edfead7cedd1ab4400a6c588f3e75f8
https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.1.0-py311hb755f60_1.conda#cce9e7c3f1c307f2a5fb08a2922d6164
@@ -70,11 +76,12 @@ https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.2-pyhd8ed1ab_0.tar.b
https://conda.anaconda.org/conda-forge/noarch/pygments-2.17.2-pyhd8ed1ab_0.conda#140a7f159396547e9799aa98f9f0742e
https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha2e5f31_6.tar.bz2#2a7de29fb590ca14b5243c4c812c8025
https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.19.0-pyhd8ed1ab_0.conda#e4dbdb3585c0266b4710467fe7b75cf4
+https://conda.anaconda.org/conda-forge/linux-64/python-libarchive-c-5.0-py311h38be061_2.conda#59706c47c2921d0889f6cc8b375b093a
https://conda.anaconda.org/conda-forge/noarch/pytz-2023.3.post1-pyhd8ed1ab_0.conda#c93346b446cd08c169d843ae5fc0da97
https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.1-py311h459d7ec_1.conda#52719a74ad130de8fb5d047dc91f247a
https://conda.anaconda.org/conda-forge/linux-64/pyzmq-25.1.2-py311h34ded2d_0.conda#819aa640a0493d4b52faf938e94d129e
https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.13.2-py311h46250e7_0.conda#c5f5089dd1fe0000fecaf0d12eca50b9
-https://conda.anaconda.org/conda-forge/linux-64/ruff-0.1.7-py311h7145743_0.conda#7e4329efd6a902a64470bfbe21a83e21
+https://conda.anaconda.org/conda-forge/linux-64/ruff-0.1.8-py311h7145743_0.conda#ed03c6cf88c287ce426c4d93013fbcbe
https://conda.anaconda.org/conda-forge/noarch/setuptools-68.2.2-pyhd8ed1ab_0.conda#fc2166155db840c634a1291a5c35a709
https://conda.anaconda.org/conda-forge/noarch/six-1.16.0-pyh6c4a22f_0.tar.bz2#e5f25f8dbc060e9a8d912e432202afc2
https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-2.2.0-pyhd8ed1ab_0.tar.bz2#4d22a9315e78c6827f806065957d566e
@@ -94,11 +101,11 @@ https://conda.anaconda.org/conda-forge/noarch/yarn-3.6.4-h31011fe_0.conda#10eada
https://conda.anaconda.org/conda-forge/noarch/zipp-3.17.0-pyhd8ed1ab_0.conda#2e4d6bc0b14e10f895fc6791a7d9b26a
https://conda.anaconda.org/conda-forge/noarch/accessible-pygments-0.0.4-pyhd8ed1ab_0.conda#46a2e6e3dfa718ce3492018d5a110dd6
https://conda.anaconda.org/conda-forge/noarch/asttokens-2.4.1-pyhd8ed1ab_0.conda#5f25798dcefd8252ce5f9dc494d5f571
-https://conda.anaconda.org/conda-forge/noarch/babel-2.13.1-pyhd8ed1ab_0.conda#3ccff479c246692468f604df9c85ef26
+https://conda.anaconda.org/conda-forge/noarch/babel-2.14.0-pyhd8ed1ab_0.conda#9669586875baeced8fc30c0826c3270e
https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.12.2-pyha770c72_0.conda#a362ff7d976217f8fa78c0f1c4f59717
https://conda.anaconda.org/conda-forge/noarch/bleach-6.1.0-pyhd8ed1ab_0.conda#0ed9d7c0e9afa7c025807a9a8136ea3e
https://conda.anaconda.org/conda-forge/noarch/comm-0.1.4-pyhd8ed1ab_0.conda#c8eaca39e2b6abae1fc96acc929ae939
-https://conda.anaconda.org/conda-forge/linux-64/coverage-7.3.2-py311h459d7ec_0.conda#7b3145fed7adc7c63a0e08f6f29f5480
+https://conda.anaconda.org/conda-forge/linux-64/coverage-7.3.3-py311h459d7ec_0.conda#9db2c1316e96068c0189beaeb716f3fe
https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-7.0.0-pyha770c72_0.conda#a941237cd06538837b25cd245fcd25d8
https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.1.1-pyhd8ed1ab_0.conda#3d5fa25cf42f3f32a12b2d874ace8574
https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.1-pyhd8ed1ab_0.conda#81a3be0b2023e1ea8555781f0ad904a2
@@ -109,7 +116,7 @@ https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_0.
https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.1.6-pyhd8ed1ab_0.tar.bz2#b21613793fcc81d944c76c9f2864a7de
https://conda.anaconda.org/conda-forge/noarch/pexpect-4.8.0-pyh1a96a4e_2.tar.bz2#330448ce4403cc74990ac07c555942a1
https://conda.anaconda.org/conda-forge/noarch/pip-23.3.1-pyhd8ed1ab_0.conda#2400c0b86889f43aa52067161e1fb108
-https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.41-pyha770c72_0.conda#f511a993aa4336bef9dd874ee3403e67
+https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.42-pyha770c72_0.conda#0bf64bf10eee21f46ac83c161917fa86
https://conda.anaconda.org/conda-forge/noarch/pyproject_hooks-1.0.0-pyhd8ed1ab_0.conda#21de50391d584eb7f4441b9de1ad773f
https://conda.anaconda.org/conda-forge/noarch/pytest-7.4.3-pyhd8ed1ab_0.conda#5bdca0aca30b0ee62bb84854e027eae0
https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.8.2-pyhd8ed1ab_0.tar.bz2#dd999d1cc9f79e67dbb855c8924c7984
diff --git a/.github/environment.yml b/.github/environment.yml
index 6084845..f78aa69 100644
--- a/.github/environment.yml
+++ b/.github/environment.yml
@@ -33,6 +33,7 @@ dependencies:
- myst-nb
- nbconvert
- pydata-sphinx-theme
+ - python-libarchive-c
- sphinx-copybutton
- sphinxcontrib-mermaid
- sphinxext-rediraffe
diff --git a/docs/conda-linux-64.lock b/docs/conda-linux-64.lock
index b74c842..3ab0ec2 100644
--- a/docs/conda-linux-64.lock
+++ b/docs/conda-linux-64.lock
@@ -1,6 +1,6 @@
# Generated by conda-lock.
# platform: linux-64
-# input_hash: 20f0ccc7420b2d04f6b206c46469fa21b102be2a042180c8c9afd795d3a61795
+# input_hash: e54fb9d2ff75a8153923001a772663276ca0d50e843fd022827a6ebf9f6d6c46
@EXPLICIT
https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2#d7c89558ba9fa0495403155b64376d81
https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2023.11.17-hbcca054_0.conda#01ffc8d36f9eba0ce0b3c1955fa780ee
@@ -16,23 +16,29 @@ https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-h59595ed_0.conda#0e33e
https://conda.anaconda.org/conda-forge/linux-64/icu-73.2-h59595ed_0.conda#cc47e1facc155f91abd89b11e48e72ff
https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.5.0-hcb278e6_1.conda#6305a3dd2752c76335295da4e581f2fd
https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.2-h7f98852_5.tar.bz2#d645c6d2ac96843a2bfaccd2d62b3ac3
+https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.17-hd590300_1.conda#4b06b43d0eca61db2899e4d7a289c302
https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hd590300_0.conda#30fd6e37fe21f86f4bd26d6ee73eeec7
https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.18-h36c2ea0_1.tar.bz2#c3788462a6fbddafdb413a9f9053e58d
https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda#40b61aab5c7ba9ff276c41cfffe6b80b
https://conda.anaconda.org/conda-forge/linux-64/libuv-1.46.0-hd590300_0.conda#d23c76f7e6dcd6243d1b6ef5e62d17d2
https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.2.13-hd590300_5.conda#f36c115f1ee199da648e0597ec2047ad
+https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.9.4-hcb278e6_0.conda#318b08df404f9c9be5712aaa5a6f0bb0
+https://conda.anaconda.org/conda-forge/linux-64/lzo-2.10-h516909a_1000.tar.bz2#bb14fcb13341b81d5eb386423b9d2bac
https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.4-h59595ed_2.conda#7dbaa197d7ba6032caf7ae7f32c1efa0
https://conda.anaconda.org/conda-forge/linux-64/openssl-3.2.0-hd590300_1.conda#603827b39ea2b835268adb8c821b8570
https://conda.anaconda.org/conda-forge/linux-64/xz-5.2.6-h166bdaf_0.tar.bz2#2161070d867d1b1204ea749c8eec4ef0
https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h7f98852_2.tar.bz2#4cb3ad778ec2d5a7acbdf254eb1c42ae
https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.44.2-h2797004_0.conda#3b6a9f225c3dbe0d24f4fedd4625c5bf
+https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.12.3-h232c23b_0.conda#bc6ac4c0cea148d924f621985bc3892b
https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8228510_1.conda#47d31b792659ce70f470b5c82fdfb7a4
https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda#d453b98d9c83e71da0741bb0ff4d76bc
https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h59595ed_0.conda#8851084c192dbc56215ac4e3c9aa30fa
https://conda.anaconda.org/conda-forge/linux-64/zlib-1.2.13-hd590300_5.conda#68c34ec6149623be41a1933ab996a209
+https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.5-hfc55251_0.conda#04b88013080254850d6c01ed54810589
+https://conda.anaconda.org/conda-forge/linux-64/libarchive-3.7.2-h2aa1ff5_1.conda#3bf887827d1968275978361a6e405e4f
https://conda.anaconda.org/conda-forge/linux-64/nodejs-20.9.0-hb753e55_0.conda#ddfcb003b0a6804fabe7dfbf1be16651
https://conda.anaconda.org/conda-forge/linux-64/pandoc-3.1.3-h32600fe_0.conda#8287aeb8462e2d4b235eff788e75919d
-https://conda.anaconda.org/conda-forge/linux-64/python-3.11.6-hab00c5b_0_cpython.conda#b0dfbe2fcbfdb097d321bfd50ecddab1
+https://conda.anaconda.org/conda-forge/linux-64/python-3.11.7-hab00c5b_0_cpython.conda#bf281a975393266ab95734a8cfd532ec
https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.13-pyhd8ed1ab_0.conda#06006184e203b61d3525f90de394471e
https://conda.anaconda.org/conda-forge/noarch/attrs-23.1.0-pyh71513ae_1.conda#3edfead7cedd1ab4400a6c588f3e75f8
https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.1.0-py311hb755f60_1.conda#cce9e7c3f1c307f2a5fb08a2922d6164
@@ -68,6 +74,7 @@ https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.2-pyhd8ed1ab_0.tar.b
https://conda.anaconda.org/conda-forge/noarch/pygments-2.17.2-pyhd8ed1ab_0.conda#140a7f159396547e9799aa98f9f0742e
https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha2e5f31_6.tar.bz2#2a7de29fb590ca14b5243c4c812c8025
https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.19.0-pyhd8ed1ab_0.conda#e4dbdb3585c0266b4710467fe7b75cf4
+https://conda.anaconda.org/conda-forge/linux-64/python-libarchive-c-5.0-py311h38be061_2.conda#59706c47c2921d0889f6cc8b375b093a
https://conda.anaconda.org/conda-forge/noarch/pytz-2023.3.post1-pyhd8ed1ab_0.conda#c93346b446cd08c169d843ae5fc0da97
https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.1-py311h459d7ec_1.conda#52719a74ad130de8fb5d047dc91f247a
https://conda.anaconda.org/conda-forge/linux-64/pyzmq-25.1.2-py311h34ded2d_0.conda#819aa640a0493d4b52faf938e94d129e
@@ -90,7 +97,7 @@ https://conda.anaconda.org/conda-forge/noarch/yarn-3.6.4-h31011fe_0.conda#10eada
https://conda.anaconda.org/conda-forge/noarch/zipp-3.17.0-pyhd8ed1ab_0.conda#2e4d6bc0b14e10f895fc6791a7d9b26a
https://conda.anaconda.org/conda-forge/noarch/accessible-pygments-0.0.4-pyhd8ed1ab_0.conda#46a2e6e3dfa718ce3492018d5a110dd6
https://conda.anaconda.org/conda-forge/noarch/asttokens-2.4.1-pyhd8ed1ab_0.conda#5f25798dcefd8252ce5f9dc494d5f571
-https://conda.anaconda.org/conda-forge/noarch/babel-2.13.1-pyhd8ed1ab_0.conda#3ccff479c246692468f604df9c85ef26
+https://conda.anaconda.org/conda-forge/noarch/babel-2.14.0-pyhd8ed1ab_0.conda#9669586875baeced8fc30c0826c3270e
https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.12.2-pyha770c72_0.conda#a362ff7d976217f8fa78c0f1c4f59717
https://conda.anaconda.org/conda-forge/noarch/bleach-6.1.0-pyhd8ed1ab_0.conda#0ed9d7c0e9afa7c025807a9a8136ea3e
https://conda.anaconda.org/conda-forge/noarch/comm-0.1.4-pyhd8ed1ab_0.conda#c8eaca39e2b6abae1fc96acc929ae939
@@ -104,7 +111,7 @@ https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_0.
https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.1.6-pyhd8ed1ab_0.tar.bz2#b21613793fcc81d944c76c9f2864a7de
https://conda.anaconda.org/conda-forge/noarch/pexpect-4.8.0-pyh1a96a4e_2.tar.bz2#330448ce4403cc74990ac07c555942a1
https://conda.anaconda.org/conda-forge/noarch/pip-23.3.1-pyhd8ed1ab_0.conda#2400c0b86889f43aa52067161e1fb108
-https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.41-pyha770c72_0.conda#f511a993aa4336bef9dd874ee3403e67
+https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.42-pyha770c72_0.conda#0bf64bf10eee21f46ac83c161917fa86
https://conda.anaconda.org/conda-forge/noarch/pyproject_hooks-1.0.0-pyhd8ed1ab_0.conda#21de50391d584eb7f4441b9de1ad773f
https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.8.2-pyhd8ed1ab_0.tar.bz2#dd999d1cc9f79e67dbb855c8924c7984
https://conda.anaconda.org/conda-forge/noarch/referencing-0.32.0-pyhd8ed1ab_0.conda#a7b5a535cd614e384594530aee7e6061
diff --git a/docs/environment.yml b/docs/environment.yml
index 81d7933..1033e59 100644
--- a/docs/environment.yml
+++ b/docs/environment.yml
@@ -22,6 +22,7 @@ dependencies:
- myst-nb
- nbconvert
- pydata-sphinx-theme
+ - python-libarchive-c
- sphinx-copybutton
- sphinxcontrib-mermaid
- sphinxext-rediraffe
diff --git a/src/jupyak/tasks/_actions.ipynb b/src/jupyak/tasks/_actions.ipynb
index 3433e66..35722f8 100644
--- a/src/jupyak/tasks/_actions.ipynb
+++ b/src/jupyak/tasks/_actions.ipynb
@@ -58,6 +58,8 @@
"import hashlib\n",
"import pprint\n",
"import shutil\n",
+ "import tempfile\n",
+ "import urllib.request\n",
"from pathlib import Path\n",
"\n",
"import doit"
@@ -382,10 +384,53 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "0cad306c-f352-4992-87fe-112398b9f0e4",
+ "id": "f4089555-b5c0-41a7-b839-fdcc23603c8f",
"metadata": {},
"outputs": [],
- "source": []
+ "source": [
+ "def fetch_one(self, url, dest):\n",
+ " if dest.exists():\n",
+ " self.log.info(f\"already downloaded {dest.name}, skipping...\")\n",
+ " return\n",
+ "\n",
+ " if not dest.parent.exists():\n",
+ " dest.parent.mkdir(parents=True)\n",
+ "\n",
+ " with tempfile.TemporaryDirectory() as td:\n",
+ " tdp = Path(td)\n",
+ " with urllib.request.urlopen(url) as response: # noqa: S310\n",
+ " tmp_dest = tdp / dest.name\n",
+ " with tmp_dest.open(\"wb\") as fd:\n",
+ " shutil.copyfileobj(response, fd)\n",
+ " last_modified = response.headers.get(\"Last-Modified\")\n",
+ " if last_modified:\n",
+ " epoch_time = time.mktime(email.utils.parsedate(last_modified))\n",
+ " os.utime(tmp_dest, (epoch_time, epoch_time))\n",
+ " shutil.copy2(tmp_dest, dest)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "e1048646-31d0-4567-9af6-5f4470f49e4a",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def extract_one(archive: Path, dest: Path):\n",
+ " \"\"\"Extract the contents of an archive to a path.\"\"\"\n",
+ " import libarchive\n",
+ "\n",
+ " clean(dest)\n",
+ "\n",
+ " dest.mkdir(parents=True)\n",
+ "\n",
+ " old_cwd = os.getcwd()\n",
+ " os.chdir(str(dest))\n",
+ " try:\n",
+ " libarchive.extract_file(str(archive))\n",
+ " finally:\n",
+ " os.chdir(old_cwd)"
+ ]
}
],
"metadata": {
diff --git a/src/jupyak/tasks/_lite.ipynb b/src/jupyak/tasks/_lite.ipynb
index 233c1e2..918cc3b 100644
--- a/src/jupyak/tasks/_lite.ipynb
+++ b/src/jupyak/tasks/_lite.ipynb
@@ -49,7 +49,7 @@
" name=\"config\",\n",
" doc=\"> configure jupyterlite\",\n",
" file_dep=[*conf_deps, *build_deps],\n",
- " actions=[(_make_lite_config, [yak, *all_deps])],\n",
+ " actions=[(_make_config, [yak, *all_deps])],\n",
" targets=sorted(set(conf_targets)),\n",
" )\n",
"\n",
@@ -137,22 +137,35 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "200305ee-54d6-4fcf-b4e6-763bbcadc898",
+ "id": "7f198818-a2ac-4aba-b4dd-8a6b6fc628fd",
"metadata": {},
"outputs": [],
"source": [
- "def _make_lite_config(yak: Y.Yak, cli_deps, conf_deps, conf_targets, build_deps):\n",
+ "def _make_config(yak: Y.Yak, cli_deps, conf_deps, conf_targets, build_deps):\n",
" work_path = yak.lite.work_path\n",
- " config = {}\n",
" if yak.lite.gist_path.exists():\n",
" A.copy(yak.lite.gist_path, work_path)\n",
- " if yak.lite.build_config_path.exists():\n",
- " config = json.loads(yak.lite.build_config_path.read_text(encoding=\"utf-8\"))\n",
" else:\n",
" work_path.mkdir(exist_ok=True, parents=True)\n",
+ " _patch_build_config(yak, cli_deps, conf_deps, conf_targets, build_deps)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "f9e22676-3ac9-4394-8e72-7d37c51d197f",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def _patch_build_config(yak: Y.Yak, cli_deps, conf_deps, conf_targets, build_deps):\n",
+ " work_path = yak.lite.work_path\n",
+ " build_config_path = yak.lite.build_config_path\n",
+ " build_config = {}\n",
+ " if build_config_path.exists():\n",
+ " build_config = json.loads(build_config_path.read_text(encoding=\"utf-8\"))\n",
"\n",
- " lbc = config.setdefault(\"LiteBuildConfig\", {})\n",
- " pla = config.setdefault(\"PipliteAddon\", {})\n",
+ " lbc = build_config.setdefault(\"LiteBuildConfig\", {})\n",
+ " pla = build_config.setdefault(\"PipliteAddon\", {})\n",
"\n",
" pkg_jsons = [\n",
" p\n",
@@ -166,10 +179,21 @@
" if p.name == W.SHA256SUMS and p.parent.glob(f\"*{W.NOARCH_WHL}\")\n",
" ]\n",
"\n",
+ " rel_output = os.path.relpath(yak.lite.app_path, work_path)\n",
+ "\n",
+ " pr_or_branch = \"unknown\"\n",
+ " if W.RTD_VERSION:\n",
+ " pr_or_branch = W.RTD_VERSION\n",
+ " elif W.GH_REF:\n",
+ " pr_or_branch = W.RTD_VERSION.split(\"/\")[-1]\n",
+ "\n",
+ " archive_name = f\"jupyak-{pr_or_branch}-jupyterlite.tgz\"\n",
+ "\n",
" lbc.update(\n",
" cache_dir=\"../.cache/lite\",\n",
" contents=[\".\"],\n",
- " output_dir=os.path.relpath(yak.lite.app_path, work_path),\n",
+ " output_dir=rel_output,\n",
+ " output_archive=f\"{rel_output}/{archive_name}\",\n",
" federated_extensions=sorted(\n",
" [\n",
" *lbc.get(\"federated_extensions\", []),\n",
@@ -190,8 +214,8 @@
" ),\n",
" )\n",
"\n",
- " yak.lite.build_config_path.write_text(\n",
- " json.dumps(config, indent=2, sort_keys=True),\n",
+ " build_config_path.write_text(\n",
+ " json.dumps(build_config, indent=2, sort_keys=True),\n",
" encoding=\"utf-8\",\n",
" )"
]
diff --git a/src/jupyak/tasks/_self.ipynb b/src/jupyak/tasks/_self.ipynb
index 44c8cd0..3f1f537 100644
--- a/src/jupyak/tasks/_self.ipynb
+++ b/src/jupyak/tasks/_self.ipynb
@@ -362,6 +362,8 @@
" file_dep=[DOCS_FAVICON],\n",
" targets=[DOCS_STATIC_WORK_FAVICON],\n",
" )\n",
+ " else:\n",
+ " pass\n",
"\n",
" yield dict(\n",
" name=\"form\",\n",
diff --git a/src/jupyak/tasks/_well_known.ipynb b/src/jupyak/tasks/_well_known.ipynb
index 091c5bb..2fa8d2d 100644
--- a/src/jupyak/tasks/_well_known.ipynb
+++ b/src/jupyak/tasks/_well_known.ipynb
@@ -10,6 +10,50 @@
"Names of files, paths and environment variables"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "9cfd8115-330d-4264-a124-58238956addc",
+ "metadata": {},
+ "source": [
+ "## ci"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "6b604241-5b78-4b00-9db6-c670405fe777",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import json\n",
+ "from os import environ as E"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "5f93f929-5ada-4ef4-ac6b-27a5ff6fb2f6",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def env_as_bool(env_var: str):\n",
+ " return json.loads(E.get(\"env_var\", \"0\").lower())"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "c94004ab-ffdd-4dff-afd5-a13be11dce9d",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "CI = env_as_bool(\"CI\")\n",
+ "RTD = env_as_bool(\"READTHEDOCS\")\n",
+ "RTD_VERSION = E.get(\"READTHEDOCS_VERSION\")\n",
+ "RTD_LOCALE = E.get(\"READTHEDOCS_LANGUAGE\", \"en\")\n",
+ "GH_REF = E.get(\"GITHUB_REF\")"
+ ]
+ },
{
"cell_type": "markdown",
"id": "74dd782a-48fa-4bbc-b4e1-fb7f62e057a3",
From f396bd7051f2bbfb8e7ed9c2a058994bb143c795 Mon Sep 17 00:00:00 2001
From: Nicholas Bollweg
Date: Fri, 15 Dec 2023 09:37:50 -0600
Subject: [PATCH 11/23] handle download and extract
---
src/jupyak/tasks/_actions.ipynb | 22 ++++++--
src/jupyak/tasks/_lite.ipynb | 39 ++++++++++---
src/jupyak/tasks/_self.ipynb | 91 ++++++++++++++++++++++++++++--
src/jupyak/tasks/_well_known.ipynb | 6 +-
4 files changed, 138 insertions(+), 20 deletions(-)
diff --git a/src/jupyak/tasks/_actions.ipynb b/src/jupyak/tasks/_actions.ipynb
index 35722f8..e32fcf2 100644
--- a/src/jupyak/tasks/_actions.ipynb
+++ b/src/jupyak/tasks/_actions.ipynb
@@ -45,7 +45,7 @@
"source": [
"## Conventions\n",
"\n",
- "This notebook should limit its imports."
+ "This notebook should limit its third-party library imports."
]
},
{
@@ -55,10 +55,13 @@
"metadata": {},
"outputs": [],
"source": [
+ "import email.utils\n",
"import hashlib\n",
+ "import os\n",
"import pprint\n",
"import shutil\n",
"import tempfile\n",
+ "import time\n",
"import urllib.request\n",
"from pathlib import Path\n",
"\n",
@@ -388,9 +391,9 @@
"metadata": {},
"outputs": [],
"source": [
- "def fetch_one(self, url, dest):\n",
+ "def fetch_one(url, dest):\n",
" if dest.exists():\n",
- " self.log.info(f\"already downloaded {dest.name}, skipping...\")\n",
+ " print(f\"already downloaded {dest.name}, skipping...\")\n",
" return\n",
"\n",
" if not dest.parent.exists():\n",
@@ -398,7 +401,18 @@
"\n",
" with tempfile.TemporaryDirectory() as td:\n",
" tdp = Path(td)\n",
- " with urllib.request.urlopen(url) as response: # noqa: S310\n",
+ " request = urllib.request.Request(\n",
+ " url,\n",
+ " headers={\n",
+ " \"User-Agent\": (\n",
+ " \"Mozilla/5.0 (Windows NT 10.0; Win64; x64)\"\n",
+ " \" AppleWebKit/537.36 (KHTML, like Gecko)\"\n",
+ " \" Chrome/102.0.0.0 Safari/537.36\"\n",
+ " )\n",
+ " },\n",
+ " )\n",
+ "\n",
+ " with urllib.request.urlopen(request) as response: # noqa: S310\n",
" tmp_dest = tdp / dest.name\n",
" with tmp_dest.open(\"wb\") as fd:\n",
" shutil.copyfileobj(response, fd)\n",
diff --git a/src/jupyak/tasks/_lite.ipynb b/src/jupyak/tasks/_lite.ipynb
index 918cc3b..ced6300 100644
--- a/src/jupyak/tasks/_lite.ipynb
+++ b/src/jupyak/tasks/_lite.ipynb
@@ -180,14 +180,7 @@
" ]\n",
"\n",
" rel_output = os.path.relpath(yak.lite.app_path, work_path)\n",
- "\n",
- " pr_or_branch = \"unknown\"\n",
- " if W.RTD_VERSION:\n",
- " pr_or_branch = W.RTD_VERSION\n",
- " elif W.GH_REF:\n",
- " pr_or_branch = W.RTD_VERSION.split(\"/\")[-1]\n",
- "\n",
- " archive_name = f\"jupyak-{pr_or_branch}-jupyterlite.tgz\"\n",
+ " archive_name = last_known_good_urls()[0]\n",
"\n",
" lbc.update(\n",
" cache_dir=\"../.cache/lite\",\n",
@@ -219,6 +212,36 @@
" encoding=\"utf-8\",\n",
" )"
]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bd04dbab-d871-4a83-b7ba-b92a5a142079",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def last_known_good_urls() -> tuple[str, list[str]]:\n",
+ " pr_or_branch = \"unknown\"\n",
+ " url_base = None\n",
+ " urls = []\n",
+ " if W.RTD_VERSION:\n",
+ " pr_or_branch = W.RTD_VERSION\n",
+ " url_base = f\"https://jupyak--{pr_or_branch}.org.readthedocs.build/{W.RTD_LOCALE}/{pr_or_branch}\"\n",
+ " elif W.GH_REF and W.GH_REF.endswith(\"main\"):\n",
+ " pr_or_branch = W.RTD_VERSION.split(\"/\")[-1]\n",
+ " url_base = \"https://deathbeds.github.io/jupyak\"\n",
+ "\n",
+ " archive_name = f\"jupyak-{pr_or_branch}-jupyterlite.tgz\"\n",
+ "\n",
+ " if url_base:\n",
+ " work_base = f\"{url_base}/_static/work\"\n",
+ " urls += [\n",
+ " f\"{work_base}/{stem}/{archive_name}\" for stem in [\"lite\", \"last-known-good\"]\n",
+ " ]\n",
+ " urls += [f\"{work_base}/lite/lite-jupyterlite.tgz\"]\n",
+ "\n",
+ " return archive_name, urls"
+ ]
}
],
"metadata": {
diff --git a/src/jupyak/tasks/_self.ipynb b/src/jupyak/tasks/_self.ipynb
index 3f1f537..c81eb9c 100644
--- a/src/jupyak/tasks/_self.ipynb
+++ b/src/jupyak/tasks/_self.ipynb
@@ -21,6 +21,7 @@
"import os\n",
"import re\n",
"import shutil\n",
+ "import tempfile\n",
"from pathlib import Path\n",
"\n",
"import doit\n",
@@ -32,6 +33,7 @@
" from jupyak.tasks import _actions as A\n",
" from jupyak.tasks import _form as F\n",
" from jupyak.tasks import _graph as G\n",
+ " from jupyak.tasks import _lite as L\n",
" from jupyak.tasks import _well_known as W\n",
" from jupyak.tasks import _yak as Y\n",
" from jupyak.tasks import load_tasks\n",
@@ -284,6 +286,75 @@
" )"
]
},
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "4a03e431-d21f-4050-bd65-581b7cd2ff1d",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def task_last_known_good():\n",
+ " if not FETCH_LAST_KNOWN_GOOD:\n",
+ " return\n",
+ "\n",
+ " archive_name, urls = L.last_known_good_urls()\n",
+ "\n",
+ " if not urls:\n",
+ " print(\"!!! no candidate URLS for last-known-good build\")\n",
+ " return\n",
+ "\n",
+ " archive = BUILD / archive_name\n",
+ " out_dir = BUILD / \"last-known-good\"\n",
+ "\n",
+ " yield dict(\n",
+ " name=\"fetch\",\n",
+ " doc=\"> download the last-known-good archive of this build\",\n",
+ " actions=[(_fetch_last_known_good, [urls, archive])],\n",
+ " targets=[archive],\n",
+ " )\n",
+ "\n",
+ " yield dict(\n",
+ " name=\"extract\",\n",
+ " doc=\"> extract the last-known-good archive of this build\",\n",
+ " file_dep=[archive],\n",
+ " targets=[out_dir / W.SHA256SUMS],\n",
+ " actions=[(_extract_last_known_good, [archive, out_dir])],\n",
+ " )"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "b6cd6233-3513-44e2-996b-4993c7c881e1",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def _fetch_last_known_good(urls, archive):\n",
+ " for url in urls:\n",
+ " try:\n",
+ " print(\"fetching...\\n\\t\", url)\n",
+ " A.fetch_one(url, archive)\n",
+ " break\n",
+ " except Exception as err:\n",
+ " print(\"\\t\", err)\n",
+ "\n",
+ " return archive.exists()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "fdb3e503-139b-4139-b726-22f73c923542",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def _extract_last_known_good(archive, out_dir):\n",
+ " with tempfile.TemporaryDirectory() as td:\n",
+ " tdp = Path(td)\n",
+ " A.extract_one(archive, tdp)\n",
+ " A.copy(tdp / \"package\", out_dir)"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
@@ -362,8 +433,6 @@
" file_dep=[DOCS_FAVICON],\n",
" targets=[DOCS_STATIC_WORK_FAVICON],\n",
" )\n",
- " else:\n",
- " pass\n",
"\n",
" yield dict(\n",
" name=\"form\",\n",
@@ -424,9 +493,10 @@
"metadata": {},
"outputs": [],
"source": [
+ "CI = bool(json.loads(os.environ.get(\"CI\", \"0\")))\n",
"CONDA_EXE = os.environ.get(\"CONDA_EXE\", \"conda\")\n",
- "SKIP_CONDA_LOCK = bool(json.loads(os.environ.get(\"JPYK_SKIP_CONDA_LOCK\", \"1\")))\n",
- "CI = bool(json.loads(os.environ.get(\"CI\", \"0\")))"
+ "SKIP_CONDA_LOCK = W.env_as_bool(W.ENV_VAR_SKIP_LOCK, \"1\")\n",
+ "FETCH_LAST_KNOWN_GOOD = W.env_as_bool(W.ENV_VAR_FETCH_LAST_KNOWN_GOOD)"
]
},
{
@@ -592,7 +662,7 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "b9db55d2-422f-475a-bad4-2bbb752b5b09",
+ "id": "7386f5b3-8268-4bfd-b1ee-465741eb4746",
"metadata": {},
"outputs": [],
"source": [
@@ -610,7 +680,16 @@
"DOCS_TEMPLATES = DOCS / \"_templates\"\n",
"DOCS_CSS = DOCS_STATIC / \"css\"\n",
"DOCS_STATIC_WORK = DOCS_STATIC / \"work\"\n",
- "DOCS_STATIC_WORK_FAVICON = DOCS_STATIC_WORK / \"lite/lab\" / DOCS_FAVICON.name\n",
+ "DOCS_STATIC_WORK_FAVICON = DOCS_STATIC_WORK / \"lite/lab\" / DOCS_FAVICON.name"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "1c6aca59-07fb-4952-b1a0-7c3ea64cbc57",
+ "metadata": {},
+ "outputs": [],
+ "source": [
"ALL_DOCS_STATIC = [\n",
" p\n",
" for p in [*DOCS_CSS.rglob(\"*.*\"), *DOCS_IMG.rglob(\"*.*\")]\n",
diff --git a/src/jupyak/tasks/_well_known.ipynb b/src/jupyak/tasks/_well_known.ipynb
index 2fa8d2d..7df0a71 100644
--- a/src/jupyak/tasks/_well_known.ipynb
+++ b/src/jupyak/tasks/_well_known.ipynb
@@ -36,8 +36,8 @@
"metadata": {},
"outputs": [],
"source": [
- "def env_as_bool(env_var: str):\n",
- " return json.loads(E.get(\"env_var\", \"0\").lower())"
+ "def env_as_bool(env_var: str, default=\"0\"):\n",
+ " return bool(json.loads(E.get(env_var, default).lower()))"
]
},
{
@@ -214,6 +214,8 @@
"ENV_VAR_ALLOW_NO_CONFIG = \"JPYK_ALLOW_NO_CONFIG\"\n",
"ENV_VAR_WORK_DIR = \"JPYK_WORK_DIR\"\n",
"ENV_VAR_SELF_DIST = \"JPYK_SELF_DIST\"\n",
+ "ENV_VAR_SKIP_LOCK = \"JPYK_SKIP_CONDA_LOCK\"\n",
+ "ENV_VAR_FETCH_LAST_KNOWN_GOOD = \"JPYK_FETCH_LAST_KNOWN_GOOD\"\n",
"JPYK_PIP_DEPS = \"build/pip-deps\"\n",
"JPYK_CONFIGS = [\n",
" \"jupyak_config.json\",\n",
From 14c8a751786e6cf02cb5546864d894534269b412 Mon Sep 17 00:00:00 2001
From: Nicholas Bollweg
Date: Fri, 15 Dec 2023 10:13:53 -0600
Subject: [PATCH 12/23] wire up last known good for rtd
---
.gitignore | 1 +
docs/.readthedocs.yaml | 18 +++++-----
docs/_static/jupyak-v0.schema.yaml | 54 +++++++++---------------------
package.json | 9 +++++
src/jupyak/tasks/_self.ipynb | 40 +++++++++++++++++++---
5 files changed, 71 insertions(+), 51 deletions(-)
diff --git a/.gitignore b/.gitignore
index 2635baa..defe489 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,4 @@ work/
jupyak_config.*
*.tsbuildinfo
node_modules/
+last-known-good/
diff --git a/docs/.readthedocs.yaml b/docs/.readthedocs.yaml
index 74e3553..668f7e9 100644
--- a/docs/.readthedocs.yaml
+++ b/docs/.readthedocs.yaml
@@ -8,18 +8,20 @@ build:
pre_build:
- git config --global user.email "jupyak@example.com"
- git config --global user.name "jupyak"
- - JPYK_ALLOW_NO_CONFIG=1 doit bootstrap || echo 'ok'
+ - JPYK_ALLOW_NO_CONFIG=1 doit bootstrap || echo 'ok'
# check out everything
- - JPYK_LOG_NAME=git doit shave:git:* || echo 'ok'
+ - JPYK_LOG_NAME=git doit shave:git:* || echo 'ok'
# prepare the work conda env
- - JPYK_LOG_NAME=env doit shave:env:* || echo 'ok'
+ - JPYK_LOG_NAME=env doit shave:env:* || echo 'ok'
# preflight some JS stuff
- - JPYK_LOG_NAME=lumino doit shave:js:lumino:* || echo 'ok'
+ - JPYK_LOG_NAME=lumino doit shave:js:lumino:* || echo 'ok'
# final pass
- - JPYK_LOG_NAME=shave doit shave || echo 'ok'
- - JPYK_LOG_NAME=shave2 doit shave || echo 'ok'
- - doit self:docs:deploy:work || echo 'ok'
- - JPYK_ALLOW_NO_CONFIG=1 doit self:docs:graph || echo 'ok'
+ - JPYK_LOG_NAME=shave doit shave || echo 'ok'
+ - JPYK_LOG_NAME=shave2 doit shave || echo 'ok'
+ - doit self:docs:deploy:work || echo 'ok'
+ - JPYK_ALLOW_NO_CONFIG=1 doit self:docs:graph || echo 'ok'
+ - JPYK_FETCH_LAST_KNOWN_GOOD=1 doit self:last_known_good || echo 'ok'
+ - JPYK_FETCH_LAST_KNOWN_GOOD=1 doit self:docs:deploy:last-known-good || echo 'ok'
sphinx:
builder: html
diff --git a/docs/_static/jupyak-v0.schema.yaml b/docs/_static/jupyak-v0.schema.yaml
index 4a3fdf3..b7687db 100644
--- a/docs/_static/jupyak-v0.schema.yaml
+++ b/docs/_static/jupyak-v0.schema.yaml
@@ -13,8 +13,7 @@ properties:
repos:
type: object
title: repos
- description:
- git-hosted projects to clone, build, and use to deploy a JupyterLite site
+ description: git-hosted projects to clone, build, and use to deploy a JupyterLite site
additionalProperties:
anyOf:
- $ref: '#/$defs/Repo'
@@ -802,8 +801,7 @@ $defs:
pypi_to_conda:
type: object
title: pypi_to_conda
- description:
- names of PyPI distributions to replace with their conda-forge counterparts
+ description: names of PyPI distributions to replace with their conda-forge counterparts
additionalProperties:
type: string
description: a normalized conda-forge name
@@ -815,9 +813,7 @@ $defs:
variables:
type: object
title: variables
- description:
- environment variables to set for all repos when the work environment is
- created
+ description: environment variables to set for all repos when the work environment is created
additionalProperties:
type: string
yarn_version:
@@ -877,32 +873,25 @@ $defs:
type: array
title: dependencies
description:
- the names of other members of `repos` that need to built and linked into this
- repo in the JS environment
+ the names of other members of `repos` that need to built and linked into this repo in the JS environment
items:
type: string
dist_exclude_patterns:
type: array
title: dist_exclude_patterns
- description:
- regular expressions for the paths in this repo that should _not_ be built and
- linked in other repos
+ description: regular expressions for the paths in this repo that should _not_ be built and linked in other repos
items:
type: string
install_exclude_resolutions:
type: array
title: install_exclude_resolutions
- description:
- regular expressions for the npm `@org/pkg` names that should _not_ be
- installed, ever, in this repo
+ description: regular expressions for the npm `@org/pkg` names that should _not_ be installed, ever, in this repo
items:
type: string
link_exclude_patterns:
type: array
title: link_exclude_patterns
- description:
- regular expressions for the npm `@org/pkg` names that should _not_ be linked
- into this repo
+ description: regular expressions for the npm `@org/pkg` names that should _not_ be linked into this repo
items:
type: string
patch_package_jsons:
@@ -981,22 +970,19 @@ $defs:
type: array
title: dependencies
description:
- the names of other members of `repos` that need to built and linked into this
- repo in the Python environment
+ the names of other members of `repos` that need to built and linked into this repo in the Python environment
items:
type: string
file_dep:
type: array
title: file_dep
- description:
- files needed (usually created by js tasks) before and editable python install
+ description: files needed (usually created by js tasks) before and editable python install
items:
type: string
lab_extensions:
type: object
title: lab_extensions
- description:
- paths with extra file dependencies needed to build an extension in this repo
+ description: paths with extra file dependencies needed to build an extension in this repo
additionalProperties:
$ref: '#/$defs/LabExtension'
modules:
@@ -1033,8 +1019,7 @@ $defs:
name:
type: string
title: name
- description:
- the duplicated name from the parent ``repos`` dictionary used for dependencies
+ description: the duplicated name from the parent ``repos`` dictionary used for dependencies
py:
$ref: '#/$defs/PythonOptions'
title: py
@@ -1050,9 +1035,7 @@ $defs:
needs_pth:
type: array
title: needs_pth
- description:
- names of packages this repo provides that need to be installed before a lite
- site build
+ description: names of packages this repo provides that need to be installed before a lite site build
items:
type: string
skip_wheel_patterns:
@@ -1071,8 +1054,7 @@ $defs:
description: extra files needed to build a given wheel
additionalProperties:
type: array
- description:
- globs to files that need to be built before the wheel can be built
+ description: globs to files that need to be built before the wheel can be built
items:
type: string
Task:
@@ -1090,8 +1072,7 @@ $defs:
file_dep:
type: array
title: file_dep
- description:
- relative globs for files that, when changed, trigger a need to run this task
+ description: relative globs for files that, when changed, trigger a need to run this task
items:
type: string
name:
@@ -1101,16 +1082,13 @@ $defs:
needs_pth:
type: array
title: needs_pth
- description:
- key of a repo that needs to be installed as a python .pth file before running
- this task
+ description: key of a repo that needs to be installed as a python .pth file before running this task
items:
type: string
targets:
type: array
title: targets
- description:
- relative globs for files that, when changed, trigger a need to run this task
+ description: relative globs for files that, when changed, trigger a need to run this task
items:
anyOf:
- type: string
diff --git a/package.json b/package.json
index 8d0b467..0db3f4f 100644
--- a/package.json
+++ b/package.json
@@ -39,6 +39,15 @@
"options": {
"arrayAutoCollapse": false
}
+ },
+ {
+ "files": [
+ "*.yaml",
+ "*.yml"
+ ],
+ "options": {
+ "printWidth": 120
+ }
}
]
},
diff --git a/src/jupyak/tasks/_self.ipynb b/src/jupyak/tasks/_self.ipynb
index c81eb9c..3c3cf5b 100644
--- a/src/jupyak/tasks/_self.ipynb
+++ b/src/jupyak/tasks/_self.ipynb
@@ -304,11 +304,11 @@
" return\n",
"\n",
" archive = BUILD / archive_name\n",
- " out_dir = BUILD / \"last-known-good\"\n",
"\n",
" yield dict(\n",
" name=\"fetch\",\n",
" doc=\"> download the last-known-good archive of this build\",\n",
+ " uptodate=[archive.exists],\n",
" actions=[(_fetch_last_known_good, [urls, archive])],\n",
" targets=[archive],\n",
" )\n",
@@ -317,8 +317,8 @@
" name=\"extract\",\n",
" doc=\"> extract the last-known-good archive of this build\",\n",
" file_dep=[archive],\n",
- " targets=[out_dir / W.SHA256SUMS],\n",
- " actions=[(_extract_last_known_good, [archive, out_dir])],\n",
+ " targets=[BUILD_LAST_KNOWN_GOOD / W.SHA256SUMS],\n",
+ " actions=[(_extract_last_known_good, [archive, BUILD_LAST_KNOWN_GOOD])],\n",
" )"
]
},
@@ -419,7 +419,6 @@
" )\n",
"\n",
" if WORK_DIST.exists():\n",
- " sphinx_task_dep += [\"self:docs:deploy:work\", \"self:docs:deploy:favicon\"]\n",
" yield dict(\n",
" name=\"deploy:work\",\n",
" doc=\"> copy built assets to docs static\",\n",
@@ -433,6 +432,18 @@
" file_dep=[DOCS_FAVICON],\n",
" targets=[DOCS_STATIC_WORK_FAVICON],\n",
" )\n",
+ " sphinx_task_dep += [\"self:docs:deploy:work\", \"self:docs:deploy:favicon\"]\n",
+ " elif FETCH_LAST_KNOWN_GOOD:\n",
+ " last_good_build_shasums = BUILD_LAST_KNOWN_GOOD / W.SHA256SUMS\n",
+ " last_good_docs_shasums = DOCS_STATIC_LAST_KNOWN_GOOD / W.SHA256SUMS\n",
+ " yield dict(\n",
+ " name=\"deploy:last-known-good\",\n",
+ " doc=\"> copy last-known-good built assets to docs static\",\n",
+ " actions=[(A.copy, [BUILD_LAST_KNOWN_GOOD, DOCS_STATIC_LAST_KNOWN_GOOD])],\n",
+ " file_dep=[last_good_build_shasums],\n",
+ " targets=[last_good_docs_shasums],\n",
+ " )\n",
+ " sphinx_task_dep += [\"self:docs:deploy:last-known-good\"]\n",
"\n",
" yield dict(\n",
" name=\"form\",\n",
@@ -651,6 +662,24 @@
"REPORT_HTMLCOV = REPORTS / \"htmlcov/index.html\""
]
},
+ {
+ "cell_type": "markdown",
+ "id": "db07b281-7c44-4366-bfbf-b359f82328a0",
+ "metadata": {},
+ "source": [
+ "## docs preflight"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "770a825f-aa2d-4be9-9b42-045f8991c6cc",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "BUILD_LAST_KNOWN_GOOD = BUILD / \"last-known-good\""
+ ]
+ },
{
"cell_type": "markdown",
"id": "afa41e89-b878-46c0-8e1d-01bf9826e7db",
@@ -680,7 +709,8 @@
"DOCS_TEMPLATES = DOCS / \"_templates\"\n",
"DOCS_CSS = DOCS_STATIC / \"css\"\n",
"DOCS_STATIC_WORK = DOCS_STATIC / \"work\"\n",
- "DOCS_STATIC_WORK_FAVICON = DOCS_STATIC_WORK / \"lite/lab\" / DOCS_FAVICON.name"
+ "DOCS_STATIC_WORK_FAVICON = DOCS_STATIC_WORK / \"lite/lab\" / DOCS_FAVICON.name\n",
+ "DOCS_STATIC_LAST_KNOWN_GOOD = DOCS_STATIC / BUILD_LAST_KNOWN_GOOD.name"
]
},
{
From 377368cafca9541e79f0dbf96e798babcbc98d8a Mon Sep 17 00:00:00 2001
From: Nicholas Bollweg
Date: Fri, 15 Dec 2023 10:26:33 -0600
Subject: [PATCH 13/23] hoist last-known-good to docs sidebar
---
docs/_templates/demo.html | 28 ++++++++++++++++++++++++++++
docs/conf.py | 22 ++++++++++++++++++----
2 files changed, 46 insertions(+), 4 deletions(-)
diff --git a/docs/_templates/demo.html b/docs/_templates/demo.html
index ee463b0..1d4ebc7 100644
--- a/docs/_templates/demo.html
+++ b/docs/_templates/demo.html
@@ -30,3 +30,31 @@
+
+{% if last_known_good_links %}
+
+
+
+{% endif %}
diff --git a/docs/conf.py b/docs/conf.py
index 462081d..c63a905 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -22,6 +22,7 @@
REPO_INFO = re.search(RE_GH, PROJ_DATA["project"]["urls"]["Source"])
NOW = datetime.datetime.now(tz=datetime.timezone.utc).date()
WORK_DIST = HERE / "_static/work"
+LAST_KNOWN_GOOD = HERE / "_static/last-known-good"
JUPYAK_CONF_CANDIDATES = [
ROOT / f"jupyak_config.{ext}"
for ext in ["toml", "yaml", "yml", "json"]
@@ -103,10 +104,8 @@
html_context["prjsf_url"] = f"{gh_pages}/_static/prjsf/prjsf.js"
if ALLOW_NO_CONFIG or JUPYAK_CONF_CANDIDATES:
- html_sidebars["*"] = [
- "demo",
- *html_sidebars["*"],
- ]
+ if "demo" not in html_sidebars["*"]:
+ html_sidebars["*"] = ["demo", *html_sidebars["*"]]
if WORK_DIST.exists():
html_context["lite_links"] = {
"lab": {"label": "Lab", "icon": "fas fa-flask"},
@@ -118,3 +117,18 @@
f"preview/{frag}/index": f"_static/work/lite/{frag}/index"
for frag in html_context["lite_links"]
}
+
+if LAST_KNOWN_GOOD.exists():
+ if "demo" not in html_sidebars["*"]:
+ html_sidebars["*"] = ["demo", *html_sidebars["*"]]
+
+ html_context["last_known_good_links"] = {
+ "lab": {"label": "Lab", "icon": "fas fa-flask"},
+ "repl": {"label": "Console", "icon": "fas fa-terminal"},
+ "tree": {"label": "File Tree", "icon": "fas fa-folder-tree"},
+ }
+
+ rediraffe_redirects = {
+ f"last-known-good/{frag}/index": f"_static/last-known-good/{frag}/index"
+ for frag in html_context["last_known_good_links"]
+ }
From 7d3c6167ff5633ea133fa0415094e5cc5ad35858 Mon Sep 17 00:00:00 2001
From: Nicholas Bollweg
Date: Fri, 15 Dec 2023 10:34:38 -0600
Subject: [PATCH 14/23] fix html context
---
docs/conf.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/conf.py b/docs/conf.py
index c63a905..8e18850 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -88,7 +88,7 @@
}
-html_context = {}
+html_context = {"lite_links": {}, "last_known_good_links": {}}
rediraffe_redirects = {}
html_sidebars = {
"*": ["page-toc", "edit-this-page", "sourcelink"],
From 3f28c732ecd60259925ddb2ec1d881abf55b2fad Mon Sep 17 00:00:00 2001
From: Nicholas Bollweg
Date: Fri, 15 Dec 2023 11:13:23 -0600
Subject: [PATCH 15/23] break the build
---
jupyak_config.toml | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/jupyak_config.toml b/jupyak_config.toml
index f178ab6..6d8c12a 100644
--- a/jupyak_config.toml
+++ b/jupyak_config.toml
@@ -9,8 +9,9 @@ merge_with = [
]
[repos.jupyterlite.github]
-merge_strategy = "ort"
-merge_options = ["theirs"]
+# restore to un-break the build
+# merge_strategy = "ort"
+# merge_options = ["theirs"]
merge_with = [
"pull/1263",
]
From 0f0bec38ca65559026b9acb7839439366b4e7a76 Mon Sep 17 00:00:00 2001
From: Nicholas Bollweg
Date: Fri, 15 Dec 2023 11:20:45 -0600
Subject: [PATCH 16/23] fix last-known-good redirects
---
docs/_templates/demo.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/_templates/demo.html b/docs/_templates/demo.html
index 1d4ebc7..7e6ec66 100644
--- a/docs/_templates/demo.html
+++ b/docs/_templates/demo.html
@@ -44,7 +44,7 @@
The current build seems to have failed, but a last-known-good site is available.
- {% for frag, info in lite_links.items() %}
+ {% for frag, info in last_known_good_links.items() %}
Date: Fri, 15 Dec 2023 11:31:14 -0600
Subject: [PATCH 17/23] also deploy the last-known-good tarball
---
docs/.readthedocs.yaml | 1 -
src/jupyak/tasks/_self.ipynb | 12 +++++++++---
2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/docs/.readthedocs.yaml b/docs/.readthedocs.yaml
index 668f7e9..5c1f699 100644
--- a/docs/.readthedocs.yaml
+++ b/docs/.readthedocs.yaml
@@ -20,7 +20,6 @@ build:
- JPYK_LOG_NAME=shave2 doit shave || echo 'ok'
- doit self:docs:deploy:work || echo 'ok'
- JPYK_ALLOW_NO_CONFIG=1 doit self:docs:graph || echo 'ok'
- - JPYK_FETCH_LAST_KNOWN_GOOD=1 doit self:last_known_good || echo 'ok'
- JPYK_FETCH_LAST_KNOWN_GOOD=1 doit self:docs:deploy:last-known-good || echo 'ok'
sphinx:
diff --git a/src/jupyak/tasks/_self.ipynb b/src/jupyak/tasks/_self.ipynb
index 3c3cf5b..7654769 100644
--- a/src/jupyak/tasks/_self.ipynb
+++ b/src/jupyak/tasks/_self.ipynb
@@ -434,14 +434,20 @@
" )\n",
" sphinx_task_dep += [\"self:docs:deploy:work\", \"self:docs:deploy:favicon\"]\n",
" elif FETCH_LAST_KNOWN_GOOD:\n",
+ " archive_name = L.last_known_good_urls()[0]\n",
" last_good_build_shasums = BUILD_LAST_KNOWN_GOOD / W.SHA256SUMS\n",
" last_good_docs_shasums = DOCS_STATIC_LAST_KNOWN_GOOD / W.SHA256SUMS\n",
+ " archive = BUILD / archive_name\n",
+ " static_archive = DOCS_STATIC_LAST_KNOWN_GOOD / archive.name\n",
" yield dict(\n",
" name=\"deploy:last-known-good\",\n",
" doc=\"> copy last-known-good built assets to docs static\",\n",
- " actions=[(A.copy, [BUILD_LAST_KNOWN_GOOD, DOCS_STATIC_LAST_KNOWN_GOOD])],\n",
- " file_dep=[last_good_build_shasums],\n",
- " targets=[last_good_docs_shasums],\n",
+ " actions=[\n",
+ " (A.copy, [BUILD_LAST_KNOWN_GOOD, DOCS_STATIC_LAST_KNOWN_GOOD]),\n",
+ " (A.copy, [archive, static_archive]),\n",
+ " ],\n",
+ " file_dep=[last_good_build_shasums, archive],\n",
+ " targets=[last_good_docs_shasums, static_archive],\n",
" )\n",
" sphinx_task_dep += [\"self:docs:deploy:last-known-good\"]\n",
"\n",
From 3f9d53259aabcaf468c0d6ba98a8ff7c485fb15f Mon Sep 17 00:00:00 2001
From: Nicholas Bollweg
Date: Fri, 15 Dec 2023 11:42:11 -0600
Subject: [PATCH 18/23] try to fix
---
jupyak_config.toml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/jupyak_config.toml b/jupyak_config.toml
index 6d8c12a..a9a20cd 100644
--- a/jupyak_config.toml
+++ b/jupyak_config.toml
@@ -9,9 +9,9 @@ merge_with = [
]
[repos.jupyterlite.github]
-# restore to un-break the build
-# merge_strategy = "ort"
-# merge_options = ["theirs"]
+# (un)comment the below to (un)break the build
+merge_strategy = "ort"
+merge_options = ["theirs"]
merge_with = [
"pull/1263",
]
From 10229147c59556e8158f4f70fc7bc7068f38535c Mon Sep 17 00:00:00 2001
From: Nicholas Bollweg
Date: Fri, 15 Dec 2023 12:01:27 -0600
Subject: [PATCH 19/23] force a fail
---
jupyak_config.toml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/jupyak_config.toml b/jupyak_config.toml
index a9a20cd..ad1df5b 100644
--- a/jupyak_config.toml
+++ b/jupyak_config.toml
@@ -10,8 +10,8 @@ merge_with = [
[repos.jupyterlite.github]
# (un)comment the below to (un)break the build
-merge_strategy = "ort"
-merge_options = ["theirs"]
+# merge_strategy = "ort"
+# merge_options = ["theirs"]
merge_with = [
"pull/1263",
]
From d986f88677eddd986b48ae533d12e765cfe62547 Mon Sep 17 00:00:00 2001
From: Nicholas Bollweg
Date: Fri, 15 Dec 2023 12:08:10 -0600
Subject: [PATCH 20/23] fix last-known-good url
---
src/jupyak/tasks/100_jupyterlab.ipynb | 3 +--
src/jupyak/tasks/_lite.ipynb | 6 +++---
2 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/src/jupyak/tasks/100_jupyterlab.ipynb b/src/jupyak/tasks/100_jupyterlab.ipynb
index bfc0343..ac863dc 100644
--- a/src/jupyak/tasks/100_jupyterlab.ipynb
+++ b/src/jupyak/tasks/100_jupyterlab.ipynb
@@ -276,7 +276,6 @@
" dest.write_text(\n",
" f\"\"\"\n",
"import sys\n",
- "print(\"DELETEME\", sys.prefix)\n",
"from jupyterlab import federated_labextensions\n",
"from jupyterlab.labextensions import LabExtensionApp\n",
"federated_labextensions._ensure_builder = lambda *_: \"{lib_js}\"\n",
@@ -306,7 +305,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.11.6"
+ "version": "3.11.7"
}
},
"nbformat": 4,
diff --git a/src/jupyak/tasks/_lite.ipynb b/src/jupyak/tasks/_lite.ipynb
index ced6300..2bdf408 100644
--- a/src/jupyak/tasks/_lite.ipynb
+++ b/src/jupyak/tasks/_lite.ipynb
@@ -234,11 +234,11 @@
" archive_name = f\"jupyak-{pr_or_branch}-jupyterlite.tgz\"\n",
"\n",
" if url_base:\n",
- " work_base = f\"{url_base}/_static/work\"\n",
+ " static = f\"{url_base}/_static\"\n",
" urls += [\n",
- " f\"{work_base}/{stem}/{archive_name}\" for stem in [\"lite\", \"last-known-good\"]\n",
+ " f\"{static}/{stem}/{archive_name}\"\n",
+ " for stem in [\"work/lite\", \"last-known-good\"]\n",
" ]\n",
- " urls += [f\"{work_base}/lite/lite-jupyterlite.tgz\"]\n",
"\n",
" return archive_name, urls"
]
From f1e9ea26b35e04c8efccface40c48d5f0df7ed58 Mon Sep 17 00:00:00 2001
From: Nicholas Bollweg
Date: Fri, 15 Dec 2023 12:09:32 -0600
Subject: [PATCH 21/23] back to pass
---
jupyak_config.toml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/jupyak_config.toml b/jupyak_config.toml
index ad1df5b..5ffdb84 100644
--- a/jupyak_config.toml
+++ b/jupyak_config.toml
@@ -9,9 +9,9 @@ merge_with = [
]
[repos.jupyterlite.github]
+merge_strategy = "ort"
# (un)comment the below to (un)break the build
-# merge_strategy = "ort"
-# merge_options = ["theirs"]
+merge_options = ["theirs"]
merge_with = [
"pull/1263",
]
From 2f668ad0fdb74eece2b99dd68a3dd8001b486ca0 Mon Sep 17 00:00:00 2001
From: Nicholas Bollweg
Date: Fri, 15 Dec 2023 13:15:31 -0600
Subject: [PATCH 22/23] break the build
---
jupyak_config.toml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/jupyak_config.toml b/jupyak_config.toml
index 5ffdb84..7c0ed71 100644
--- a/jupyak_config.toml
+++ b/jupyak_config.toml
@@ -11,7 +11,7 @@ merge_with = [
[repos.jupyterlite.github]
merge_strategy = "ort"
# (un)comment the below to (un)break the build
-merge_options = ["theirs"]
+# merge_options = ["theirs"]
merge_with = [
"pull/1263",
]
From 7a48a1d7c29d22cc12ebe0a0bbb81d553b16946a Mon Sep 17 00:00:00 2001
From: Nicholas Bollweg
Date: Fri, 15 Dec 2023 13:27:57 -0600
Subject: [PATCH 23/23] re-fix
---
jupyak_config.toml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/jupyak_config.toml b/jupyak_config.toml
index 7c0ed71..5ffdb84 100644
--- a/jupyak_config.toml
+++ b/jupyak_config.toml
@@ -11,7 +11,7 @@ merge_with = [
[repos.jupyterlite.github]
merge_strategy = "ort"
# (un)comment the below to (un)break the build
-# merge_options = ["theirs"]
+merge_options = ["theirs"]
merge_with = [
"pull/1263",
]