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 %} +
+ +
+
+ + last-known-good preview site +
+
+
+ The current build seems to have failed, but a last-known-good site is available. +
+

+ {% for frag, info in last_known_good_links.items() %} + + {{ info.label }} + + {% endfor %} +

+
+
+{% 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",