From 881114faab6e9758166f6bdb386325e88866cc47 Mon Sep 17 00:00:00 2001
From: Nicholas Bollweg
Date: Fri, 15 Dec 2023 13:26:54 -0600
Subject: [PATCH] Preserve last-known-good preview site (#27)
---
.binder/conda-linux-64.lock | 26 +++---
.binder/environment.yml | 1 +
.github/conda-linux-64.lock | 19 ++--
.github/environment.yml | 1 +
.gitignore | 1 +
docs/.readthedocs.yaml | 17 ++--
docs/_static/jupyak-v0.schema.yaml | 54 ++++-------
docs/_templates/demo.html | 28 ++++++
docs/conda-linux-64.lock | 15 +++-
docs/conf.py | 24 +++--
docs/environment.yml | 1 +
package.json | 9 ++
src/jupyak/tasks/100_jupyterlab.ipynb | 3 +-
src/jupyak/tasks/_actions.ipynb | 65 +++++++++++++-
src/jupyak/tasks/_lite.ipynb | 69 +++++++++++---
src/jupyak/tasks/_self.ipynb | 125 +++++++++++++++++++++++++-
src/jupyak/tasks/_well_known.ipynb | 46 ++++++++++
17 files changed, 412 insertions(+), 92 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/.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..5c1f699 100644
--- a/docs/.readthedocs.yaml
+++ b/docs/.readthedocs.yaml
@@ -8,18 +8,19 @@ 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: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/docs/_templates/demo.html b/docs/_templates/demo.html
index ee463b0..7e6ec66 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/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/conf.py b/docs/conf.py
index 462081d..8e18850 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"]
@@ -87,7 +88,7 @@
}
-html_context = {}
+html_context = {"lite_links": {}, "last_known_good_links": {}}
rediraffe_redirects = {}
html_sidebars = {
"*": ["page-toc", "edit-this-page", "sourcelink"],
@@ -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"]
+ }
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/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/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/_actions.ipynb b/src/jupyak/tasks/_actions.ipynb
index 3433e66..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,9 +55,14 @@
"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",
"import doit"
@@ -382,10 +387,64 @@
{
"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(url, dest):\n",
+ " if dest.exists():\n",
+ " print(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",
+ " 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",
+ " 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..2bdf408 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,14 @@
" 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",
+ " archive_name = last_known_good_urls()[0]\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,11 +207,41 @@
" ),\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",
" )"
]
+ },
+ {
+ "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",
+ " static = f\"{url_base}/_static\"\n",
+ " urls += [\n",
+ " f\"{static}/{stem}/{archive_name}\"\n",
+ " for stem in [\"work/lite\", \"last-known-good\"]\n",
+ " ]\n",
+ "\n",
+ " return archive_name, urls"
+ ]
}
],
"metadata": {
diff --git a/src/jupyak/tasks/_self.ipynb b/src/jupyak/tasks/_self.ipynb
index 44c8cd0..7654769 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",
+ "\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",
+ "\n",
+ " yield dict(\n",
+ " name=\"extract\",\n",
+ " doc=\"> extract the last-known-good archive of this build\",\n",
+ " file_dep=[archive],\n",
+ " targets=[BUILD_LAST_KNOWN_GOOD / W.SHA256SUMS],\n",
+ " actions=[(_extract_last_known_good, [archive, BUILD_LAST_KNOWN_GOOD])],\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,
@@ -348,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",
@@ -362,6 +432,24 @@
" 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",
+ " 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=[\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",
" yield dict(\n",
" name=\"form\",\n",
@@ -422,9 +510,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)"
]
},
{
@@ -579,6 +668,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",
@@ -590,7 +697,7 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "b9db55d2-422f-475a-bad4-2bbb752b5b09",
+ "id": "7386f5b3-8268-4bfd-b1ee-465741eb4746",
"metadata": {},
"outputs": [],
"source": [
@@ -609,6 +716,16 @@
"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_LAST_KNOWN_GOOD = DOCS_STATIC / BUILD_LAST_KNOWN_GOOD.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 091c5bb..7df0a71 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, default=\"0\"):\n",
+ " return bool(json.loads(E.get(env_var, default).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",
@@ -170,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",