diff --git a/test.py b/test.py index 35aadbd6172..b4764778596 100644 --- a/test.py +++ b/test.py @@ -5602,7 +5602,14 @@ def test_ensembl_annotation_gtf_gz(): def test_ensembl_regulatory_gff3_gz(): run( "bio/reference/ensembl-regulation", - ["snakemake", "--cores", "1", "resources/regulatory_features.gff3.gz", "--use-conda", "-F"], + [ + "snakemake", + "--cores", + "1", + "resources/regulatory_features.gff3.gz", + "--use-conda", + "-F", + ], ) @@ -5610,7 +5617,14 @@ def test_ensembl_regulatory_gff3_gz(): def test_ensembl_regulatory_features_grch37_gff(): run( "bio/reference/ensembl-regulation", - ["snakemake", "--cores", "1", "resources/regulatory_features.gff", "--use-conda", "-F"], + [ + "snakemake", + "--cores", + "1", + "resources/regulatory_features.gff", + "--use-conda", + "-F", + ], ) @@ -5618,7 +5632,14 @@ def test_ensembl_regulatory_features_grch37_gff(): def test_ensembl_regulatory_features_mouse_gff_gz(): run( "bio/reference/ensembl-regulation", - ["snakemake", "--cores", "1", "resources/regulatory_features.mouse.gff.gz", "--use-conda", "-F"], + [ + "snakemake", + "--cores", + "1", + "resources/regulatory_features.mouse.gff.gz", + "--use-conda", + "-F", + ], ) @@ -6710,3 +6731,101 @@ def test_emu_combine_output_split(): "-F", ], ) + + +@skip_if_not_modified +def test_quarto_simple_html(): + run( + "utils/quarto", + [ + "snakemake", + "--cores", + "1", + "output/simple.html", + "--use-conda", + ], + ) + + +@skip_if_not_modified +def test_quarto_simple_docx(): + run( + "utils/quarto", + [ + "snakemake", + "--cores", + "1", + "output/simple.docx", + "--use-conda", + ], + ) + + +@skip_if_not_modified +def test_quarto_simple_parameters(): + run( + "utils/quarto", + [ + "snakemake", + "--cores", + "1", + "output/example_proj_full.html", + "--use-conda", + ], + ) + + +@skip_if_not_modified +def test_quarto_simple_noreport(): + run( + "utils/quarto", + [ + "snakemake", + "--cores", + "1", + "output/example_proj_noreport.txt", + "--use-conda", + ], + ) + + +@skip_if_not_modified +def test_quarto_simple_extra_renv_deps(): + run( + "utils/quarto", + [ + "snakemake", + "--cores", + "1", + "output/extra_datatable_renv.html", + "--use-conda", + ], + ) + + +@skip_if_not_modified +def test_quarto_pass_resources(): + run( + "utils/quarto", + [ + "snakemake", + "--cores", + "1", + "output/resources_custom.html", + "--use-conda", + ], + ) + + +@skip_if_not_modified +def test_quarto_pass_threads(): + run( + "utils/quarto", + [ + "snakemake", + "--cores", + "1", + "output/resources_threads.html", + "--use-conda", + ], + ) diff --git a/utils/quarto/environment.linux-64.pin.txt b/utils/quarto/environment.linux-64.pin.txt new file mode 100644 index 00000000000..243c64641ff --- /dev/null +++ b/utils/quarto/environment.linux-64.pin.txt @@ -0,0 +1,138 @@ +# This file may be used to create an environment using: +# $ conda create --name --file +# platform: linux-64 +@EXPLICIT +https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2#d7c89558ba9fa0495403155b64376d81 +https://conda.anaconda.org/conda-forge/noarch/_r-mutex-1.0.1-anacondar_1.tar.bz2#19f9db5f4f1b7f5ef5f6d67207f25f38 +https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.6.2-hbcca054_0.conda#847c3c2905cc467cea52c24f9cfa8080 +https://conda.anaconda.org/conda-forge/linux-64/dart-sass-1.58.3-ha770c72_1.conda#d54982a58cd9be3d00a7efe76ba6f60c +https://conda.anaconda.org/conda-forge/linux-64/esbuild-0.19.2-ha770c72_0.conda#8fa87b764cf6143cb66e9cc3548b186a +https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2#0c96522c6bdaed4b1566d11387caaf45 +https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2#34893075a5c9e55cdafac56607368fc6 +https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb +https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_2.conda#cbbe59391138ea5ad3658c76912e147f +https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-2.6.32-he073ed8_17.conda#d731b543793afc0433c4fd593e693fce +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-hf3520f5_7.conda#b80f2f396ca2c28b8c14c437a4ed1e74 +https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-13.2.0-hdb50d1a_111.conda#43178c27fac2dcd495bd9e58e18272d9 +https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-13.2.0-hdb50d1a_111.conda#4ffa92ea4ba6555dee156ce3d0ae7a9b +https://conda.anaconda.org/conda-forge/linux-64/pandoc-3.1.11.1-ha770c72_0.conda#0e2f14aff42adf4675bcd5335d644a5f +https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2#f766549260d6815b0c52253f1fb1bb29 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h77fa898_11.conda#8c462ced2af33648195dc9459f331f31 +https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.12-he073ed8_17.conda#595db67e32b276298ff3d94d07d47fbf +https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d +https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.40-ha1999f0_7.conda#3f840c7ed70a96b5ebde8044b2f36f32 +https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h77fa898_11.conda#0b3b218a596bb4c3854cc9ee799f94e5 +https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hd590300_5.conda#69b8b6202a07720f448be700e300ccf4 +https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.28.1-hd590300_0.conda#dcde58ff9a1f30b0037a2315d1846d1f +https://conda.anaconda.org/conda-forge/linux-64/deno-1.37.2-h335b0a9_1.conda#50fe6d0064adfd83846a6f9c87da03e3 +https://conda.anaconda.org/conda-forge/linux-64/fribidi-1.0.10-h36c2ea0_0.tar.bz2#ac7bc6a654f8f41b352b38f4051135f8 +https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.1-h166bdaf_0.tar.bz2#30186d27e2c9fa62b45fb1476b7200e3 +https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.20-hd590300_0.conda#8e88f9389f1165d7c0936fe40d9a9a79 +https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.6.2-h59595ed_0.conda#e7ba12deb7020dd080c6c70e7b6f6a3d +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-h3d2ce59_11.conda#c485da4fdb454539f852a90ae06e9bb7 +https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.17-hd590300_2.conda#d66573916ffcf376178462f1b61c941e +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/libstdcxx-ng-13.2.0-hc0a3c3a_11.conda#eaa8ea74083fb4a78ae19e431e556003 +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda#40b61aab5c7ba9ff276c41cfffe6b80b +https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.4.0-hd590300_0.conda#b26e8aa824079e1be0294e7152ca4559 +https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-h4ab18f5_1.conda#57d7dc60e9325e3de37ff8dffd18e814 +https://conda.anaconda.org/conda-forge/linux-64/make-4.3-hd18ef5c_1.tar.bz2#4049ebfd3190b580dffe76daed26155a +https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h59595ed_0.conda#fcea371545eda051b6deafb24889fc69 +https://conda.anaconda.org/conda-forge/linux-64/openssl-3.3.1-h4ab18f5_0.conda#a41fa0e391cc9e0d6b78ac69ca047a6c +https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-h36c2ea0_1001.tar.bz2#22dad4df6e8630e8dff2428f6f6a7036 +https://conda.anaconda.org/conda-forge/linux-64/sed-4.8-he412f7d_0.tar.bz2#7362f0042e95681f5d371c46c83ebd08 +https://conda.anaconda.org/conda-forge/linux-64/xorg-kbproto-1.0.7-h7f98852_1002.tar.bz2#4b230e8381279d76131116660f5a241a +https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.1-hd590300_0.conda#b462a33c0be1421532f28bfe8f4a7514 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.11-hd590300_0.conda#2c80dc38fface310c9bd81b17037fee5 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.3-h7f98852_0.tar.bz2#be93aabceefa2fac576e971aef407908 +https://conda.anaconda.org/conda-forge/linux-64/xorg-renderproto-0.11.1-h7f98852_1002.tar.bz2#06feff3d2634e3097ce2fe681474b534 +https://conda.anaconda.org/conda-forge/linux-64/xorg-xextproto-7.3.0-h0b41bf4_1003.conda#bce9f945da8ad2ae9b1d7165a64d0f87 +https://conda.anaconda.org/conda-forge/linux-64/xorg-xproto-7.0.31-h7f98852_1007.tar.bz2#b4a4381d54784606820704f7b5f05a15 +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/deno-dom-0.1.35-hd9586b0_1.conda#263ee0870b18b013d9ec8539113ac69f +https://conda.anaconda.org/conda-forge/linux-64/expat-2.6.2-h59595ed_0.conda#53fb86322bdb89496d7579fe3f02fd61 +https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.13-h59595ed_1003.conda#f87c7b7c2cb45f323ffbce941c78ab7c +https://conda.anaconda.org/conda-forge/linux-64/icu-73.2-h59595ed_0.conda#cc47e1facc155f91abd89b11e48e72ff +https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h27087fc_0.tar.bz2#76bbff344f0134279f225174e9064c8f +https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20191231-he28a2e2_2.tar.bz2#4d331e44109e3f0e19b4cb8f9b82f3e1 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-13.2.0-h69a702a_11.conda#4c3e460d6acf8e43e4ce8bf405187eb7 +https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.58.0-h47da74e_1.conda#700ac6ea6d53d5510591c4344d5c989a +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.43-h2797004_0.conda#009981dd9cfcaa4dbfa25ffaed86bcae +https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-13.2.0-h6ddb7a1_11.conda#3227eb98475de9cb375391aa28b931d5 +https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.0-h0841786_0.conda#1f5a58e686b13bcfde88b93f547d23fe +https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.16-hd590300_0.conda#151cba22b85a989c2d6ef9633ffee1e4 +https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.44-h0f59acf_0.conda#3914f7ac1761dce57102c72ca7c35d01 +https://conda.anaconda.org/conda-forge/linux-64/pixman-0.43.2-h59595ed_0.conda#71004cbf7924e19c02746ccde9fd7123 +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/xorg-libsm-1.2.4-h7391055_0.conda#93ee23f12bc2e684548181256edd2cf6 +https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-h4ab18f5_1.conda#9653f1bf3766164d0e65fa723cabbc54 +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.6-ha6fb4c9_0.conda#4d056880988120e29d75bfff282e0f45 +https://conda.anaconda.org/conda-forge/linux-64/bwidget-1.9.14-ha770c72_1.tar.bz2#5746d6202ba2abad4a4707f2a2462795 +https://conda.anaconda.org/conda-forge/linux-64/freetype-2.12.1-h267a509_2.conda#9ae35c3d96db2c94ce0cef86efdfa2cb +https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-13.2.0-h9eb54c0_11.conda#6ba78509a489a8a7882328468f187cc9 +https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.2-h659d440_0.conda#cd95826dbd331ed1be26bdf401432844 +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.80.2-h8a4344b_1.conda#9c406bb3d4dac2b358873e6462496d09 +https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.27-pthreads_h413a1c8_0.conda#a356024784da6dfd4683dc5ecf45b155 +https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.6.0-h1dd3fc0_3.conda#66f03896ffbe1a110ffda05c7a856504 +https://conda.anaconda.org/conda-forge/linux-64/quarto-1.4.550-ha770c72_1.conda#b7b89be76bcdab239f7956e5fc2727ab +https://conda.anaconda.org/conda-forge/linux-64/tktable-2.10-h0c5db8f_5.conda#9464044754ea25557a9c93f0327d90a6 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.9-hb711507_1.conda#4a6d410296d7e39f00bacdee7df046e9 +https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.14.2-h14ed4e7_0.conda#0f69b688f52ff6da70bccb7ff7001d1d +https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-13.2.0-h9efe08d_11.conda#d08f638bb8b62d71f2222ecb7003a995 +https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-13.2.0-h2a599c4_11.conda#c2f0227c9bea564b8edc2f1de939c76d +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-22_linux64_openblas.conda#1a2a0cd3153464fee6646f3dd6dad9b8 +https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.8.0-hca28451_0.conda#f21c27f076a07907e70c49bb57bd0f20 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.4-h0b41bf4_2.conda#82b6df12252e6f32402b96dacc656fec +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.11-hd590300_0.conda#ed67c36f215b310412b2af935bf3e530 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxt-1.3.0-hd590300_1.conda#ae92aab42726eb29d16488924f7312cb +https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.0-hbb29018_1.conda#e31a51ddd52326d10a9cc50b0d68daab +https://conda.anaconda.org/conda-forge/linux-64/curl-8.8.0-he654da7_0.conda#042341d8b9ba4ee7f2722b81fae9f0ad +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-22_linux64_openblas.conda#b083767b6c877e24ee597d93b87ab838 +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-8.5.0-hfac3d4d_0.conda#f5126317dd0ce0ba26945e411ecc6960 +https://conda.anaconda.org/conda-forge/linux-64/pango-1.54.0-h84a9a3c_0.conda#7c51e110b2f059c0843269d3324e4b22 +https://conda.anaconda.org/conda-forge/linux-64/r-base-4.3.3-h8ee917f_2.conda#fdd20aea0c8243bfa7fb85d144f4febe +https://conda.anaconda.org/conda-forge/linux-64/r-base64enc-0.1_3-r43h57805ef_1006.conda#3cb46d4c0d2096491f9934da0e1555ee +https://conda.anaconda.org/conda-forge/linux-64/r-cli-3.6.2-r43ha503ecb_0.conda#7a325f68b1354c1a5261688b5e54d008 +https://conda.anaconda.org/conda-forge/linux-64/r-curl-5.1.0-r43hf9611b0_0.conda#d2a3cc302656e5ff30fc635fd9ef3ae6 +https://conda.anaconda.org/conda-forge/linux-64/r-digest-0.6.35-r43ha503ecb_0.conda#d28a7db9b060ceaf683f0b036780b962 +https://conda.anaconda.org/conda-forge/noarch/r-evaluate-0.24.0-r43hc72bb7e_0.conda#1c3aa7ca297fae40ea8d6a8fe78317f0 +https://conda.anaconda.org/conda-forge/linux-64/r-fastmap-1.2.0-r43ha18555a_0.conda#f60a0e293418fc91b73bd67aa62d4a79 +https://conda.anaconda.org/conda-forge/linux-64/r-fs-1.6.4-r43ha18555a_0.conda#c0cc6b111eb64c8d21f4feeb53c8d06d +https://conda.anaconda.org/conda-forge/linux-64/r-glue-1.7.0-r43h57805ef_0.conda#20e2cb7c0d27bccf8fe21ec5c3897751 +https://conda.anaconda.org/conda-forge/linux-64/r-jsonlite-1.8.8-r43h57805ef_0.conda#fb01953d78a87de6211b1ebccafed273 +https://conda.anaconda.org/conda-forge/linux-64/r-mime-0.12-r43h57805ef_2.conda#348f6adefce6912321b2a2ab0528ae89 +https://conda.anaconda.org/conda-forge/noarch/r-packrat-0.9.2-r43hc72bb7e_0.conda#acc0bee43ed5a63ef521aa6995541e97 +https://conda.anaconda.org/conda-forge/linux-64/r-ps-1.7.6-r43h57805ef_0.conda#48f9e73215aa6de4545ec3ec36e5e534 +https://conda.anaconda.org/conda-forge/noarch/r-r6-2.5.1-r43hc72bb7e_2.conda#79f167972554dc6b65aa099cd85c22a1 +https://conda.anaconda.org/conda-forge/linux-64/r-rappdirs-0.3.3-r43h57805ef_2.conda#788ac4f3dcfa79520bfc9eeadf50c2eb +https://conda.anaconda.org/conda-forge/linux-64/r-rcpp-1.0.12-r43h7df8631_0.conda#a8aac8be0868617b28f27484ea548d6c +https://conda.anaconda.org/conda-forge/noarch/r-renv-1.0.7-r43hc72bb7e_0.conda#efa116dc4d7118a48c97f6f8f4861427 +https://conda.anaconda.org/conda-forge/linux-64/r-rlang-1.1.4-r43ha18555a_0.conda#74c4cb6644843dccabc350cba4b56ec6 +https://conda.anaconda.org/conda-forge/noarch/r-rstudioapi-0.16.0-r43hc72bb7e_0.conda#02c7b3c36e390b0c538300adab8ca3eb +https://conda.anaconda.org/conda-forge/linux-64/r-sys-3.4.2-r43h57805ef_1.conda#ae6e4dd935d9c91064cbca07d2769d75 +https://conda.anaconda.org/conda-forge/linux-64/r-xfun-0.45-r43ha18555a_0.conda#cced29e73709a7c9b2495a4f5d695d66 +https://conda.anaconda.org/conda-forge/linux-64/r-yaml-2.3.8-r43h57805ef_0.conda#41db1ee9d0073339e681379b92e7dfb6 +https://conda.anaconda.org/conda-forge/linux-64/r-askpass-1.2.0-r43h57805ef_0.conda#ee095f1d72a1d80864816e44623ba392 +https://conda.anaconda.org/conda-forge/linux-64/r-cachem-1.1.0-r43hb1dbf0f_0.conda#d48720030e2b1d780389bafa5a9c7536 +https://conda.anaconda.org/conda-forge/linux-64/r-ellipsis-0.3.2-r43h57805ef_2.conda#10c5892991072cfa3a61489d2ac6ad66 +https://conda.anaconda.org/conda-forge/noarch/r-highr-0.11-r43hc72bb7e_0.conda#ecd3b95a01caa7bdcf63714427b5b88c +https://conda.anaconda.org/conda-forge/linux-64/r-later-1.3.2-r43ha503ecb_0.conda#6e120827a341f21444881e84408e98a7 +https://conda.anaconda.org/conda-forge/noarch/r-lifecycle-1.0.4-r43hc72bb7e_0.conda#291d2fb68ea1b181644b40d6743ae000 +https://conda.anaconda.org/conda-forge/linux-64/r-pki-0.1_14-r43hb1dbf0f_0.conda#58c4dc882730c0d96ca09e58be0150d8 +https://conda.anaconda.org/conda-forge/linux-64/r-processx-3.8.4-r43h57805ef_0.conda#660d4e9ff8beef35dbda645484d17a25 +https://conda.anaconda.org/conda-forge/noarch/r-tinytex-0.51-r43hc72bb7e_0.conda#16653f65f1ab934e1a9bdac874f9b63b +https://conda.anaconda.org/conda-forge/linux-64/r-htmltools-0.5.8.1-r43ha503ecb_0.conda#220b9c45f5867a42d49bde8d340e9e53 +https://conda.anaconda.org/conda-forge/noarch/r-knitr-1.47-r43hc72bb7e_0.conda#0310660d998a5933bb4545a312ed7385 +https://conda.anaconda.org/conda-forge/noarch/r-memoise-2.0.1-r43hc72bb7e_2.conda#6520452e207d8f9bab9f21492f88c48b +https://conda.anaconda.org/conda-forge/linux-64/r-openssl-2.2.0-r43hd7d0243_0.conda#60f961514ecc3ee1fd7b1afd6ea853ab +https://conda.anaconda.org/conda-forge/noarch/r-fontawesome-0.5.2-r43hc72bb7e_0.conda#d07f215759462959de39d7232386f1b9 +https://conda.anaconda.org/conda-forge/noarch/r-jquerylib-0.1.4-r43hc72bb7e_2.conda#49a3fad710cbccec9139b36587842f88 +https://conda.anaconda.org/conda-forge/noarch/r-rsconnect-1.3.1-r43hc72bb7e_0.conda#474409574da3aacf988008567cbf11b7 +https://conda.anaconda.org/conda-forge/linux-64/r-sass-0.4.9-r43ha503ecb_0.conda#58e32ad6d979828aa0fc3da59e1b4d78 +https://conda.anaconda.org/conda-forge/noarch/r-bslib-0.7.0-r43hc72bb7e_0.conda#6e2bfdc782284259390d09bb083142b2 +https://conda.anaconda.org/conda-forge/noarch/r-rmarkdown-2.27-r43hc72bb7e_1.conda#4b681e35650d7d10737bc0c6ed80ae9a +https://conda.anaconda.org/conda-forge/noarch/r-quarto-1.4-r43hc72bb7e_0.conda#a86d89513116deba7cc3c6e8e72a0f61 diff --git a/utils/quarto/environment.yaml b/utils/quarto/environment.yaml new file mode 100644 index 00000000000..dacd6737517 --- /dev/null +++ b/utils/quarto/environment.yaml @@ -0,0 +1,5 @@ +channels: + - conda-forge + - nodefaults +dependencies: + - r-quarto=1.4 \ No newline at end of file diff --git a/utils/quarto/meta.yaml b/utils/quarto/meta.yaml new file mode 100644 index 00000000000..46f9634108b --- /dev/null +++ b/utils/quarto/meta.yaml @@ -0,0 +1,53 @@ +name: quarto +description: Render quarto markdown documents +url: https://github.com/quarto-dev/quarto-r +authors: + -Vito Zanotelli +input: + - script: | + Quarto script to render (.qmd). + - The script must follow the following rules: + - If parameters are used (extra arguments in `input`, `output`, `params`) + they must be defined in the quarto header as params: https://quarto.org/docs/computations/parameters.html#knitr + - resources passed to the script must be defined in the quarto header as `resources_` followed by the resource name. + Eg `resources_mem` entry in the quarto header would cause the `sm.resources.mem` passed to the quarto script. + Threads will be passed if a parameter `resources_threads` is defined in the quarto header. + - All dependencies used in the script must either be: + - installed in the `renv` declared as `input.renv` (see `input.renv` documentation) + - installed in the conda environment used to run this wrapper. If this is customized, use + the `conda: ` parameter to overwrite the default conda environment. + - renv: | + Optional: + Path a folder containing restored `renv` environment or a file within + (eg `.Rprofile`, `renv.lock`). If this is used the `renv` must + contain a full `quarto` installation. + Note that the R version depends on the conda environment used in the wrapper. + If this needs to be changed, change the `conda:` parameter to point to an + appropriate conda environment. + Default: the project root directory + - additional_inputs: | + Additional input files. These the paths will be passed as `-P :` to the quarto script + and need to be defined in the quarto header as params: https://quarto.org/docs/computations/parameters.html#knitr +output: + - report: | + Optional: + Path to the rendered report. The file extension will be used to determine the output format (eg `report.html`, `report.docx`). + PDF rendering is currently not supported due to the lack of support of tinytex in conda-forge. + If not provided, the report will be rendered in a temporary directory and no output will be returned. + - additional_outputs: | + Additional output files. These the paths will be passed as `-P :` to the quarto script + and need to be defined in the quarto header as params: https://quarto.org/docs/computations/parameters.html#knitr +params: + - additional_params: | + Additional parameters to be passed to the quarto script. These the paths will be passed as `-P :` to the quarto script + and need to be defined in the quarto header as params: https://quarto.org/docs/computations/parameters.html#knitr +notes: | + This wrapper runs quarto to render markdown .qmd notebooks. + The wrapper supports r-package management via `conda` and `renv`: + - For `conda` overwrite the conda environment from the `conda:` directive of the rule with an environement with + the r dependencies as well as `r-quarto` installed. + - For `renv` restore an environment before and point the `input.renv` + to the environment folder or a file within (eg `.Rprofile`). The r-version needs used to build the `renv` needs to match + the one of the wrapper or the environment of the wrapper needs to be overwritten with via `conda:` with a matching `r-base` + installation. + PDF rendering is currently not working as tinytex is not properly supported in `conda`. \ No newline at end of file diff --git a/utils/quarto/test/Snakefile b/utils/quarto/test/Snakefile new file mode 100644 index 00000000000..3920b4ff887 --- /dev/null +++ b/utils/quarto/test/Snakefile @@ -0,0 +1,173 @@ +import os + + +rule all: # [hide] + input: # [hide] + "output/simple.html", # [hide] + "output/resources.html", # [hide] + "output/simple.docx", # [hide] + "output/example_proj_full.html", # [hide] + "output/example_proj_noreport.txt", # [hide] + "output/extra_datatable_renv.html", # [hide] + + +rule testfile: + output: + touch("{project}_input.txt"), + + +rule render_quarto_full: + input: + script="full.qmd", + input_txt="{project}_input.txt", + output: + report="{project}_full.html", + output_txt="{project}_output.txt", + params: + project=lambda wc: wc.project, + log: + "logs/{project}_html.log", + wrapper: + "master/utils/quarto" + + +rule render_html: + input: + script="simple.qmd", + output: + report="output/simple.html", + log: + "logs/simple_html.log", + wrapper: + "master/utils/quarto" + + +rule render_docx: + input: + script="simple.qmd", + output: + report="output/simple.docx", + log: + "logs/simple_docx.log", + wrapper: + "master/utils/quarto" + + +rule render_quarto_noreport: + input: + script="full.qmd", + input_txt="{project}_input.txt", + output: + output_txt="{project}_noreport.txt", + log: + "logs/{project}_noreport.log", + wrapper: + "master/utils/quarto" + + +rule pass_custom_resources: + input: + script="resources_custom.qmd", + output: + report="output/resources_custom.html", + resources: + custom_resource=1, + log: + "logs/pass_custom_resources.log", + wrapper: + "master/utils/quarto" + + +rule pass_threads: + input: + script="resources_threads.qmd", + output: + report="output/resources_threads.html", + log: + "logs/pass_threads.log", + wrapper: + "master/utils/quarto" + + +# To add additional r-dependencies used to render +# the report also the conda: directive can be +# overwritten. The only required dependency +# is r-quarto +# rule render_quarto_extra_conda: +# conda: +# "env/extra.yaml" +# input: +# script="extra_datatable.qmd", +# output: +# report="output/extra_datatable_conda.html", +# log: +# "logs/conda.log", +# wrapper: +# "master/utils/quarto" + + +# Rules for a example using renv +wildcard_constraints: + # Allows renv_dir also to be the empty (=root dir) + renv_dir=".*", + + +# The `renv_lock` on renv rules is an artificial resource to prevent multiple +# renv operations at the same time, which may cause issues.. +# In such cases restrict it via the +# resources CLI flag: --resources renv_lock=1 --set-resource-scopes renv_lock=global + + +rule renv_example_init: + conda: + "env/renv.yaml" + input: + lockfile="env/renv_dt.lock", + output: + rprofile="{renv_dir}/.Rprofile", + lockfile="{renv_dir}/renv.lock", + resources: + renv_lock=1, + log: + "logs/renv/{renv_dir}_init.log", + shell: + """ + Rscript -e "renv::init(project='{wildcards.renv_dir}', bare=T); \ + renv::restore(project='{wildcards.renv_dir}', lockfile='$(realpath {input.lockfile})');\ + renv::snapshot(type='all')" + """ + + +rule restore_renv: + conda: + "env/renv.yaml" + input: + rprofile="{renv_dir}.Rprofile", + lock="{renv_dir}renv.lock", + output: + restored="{renv_dir}restored.Rprofile", + resources: + renv_lock=1, + log: + "logs/renv/{renv_dir}_restore.log", + shell: + """ + R -e 'source("{input.rprofile}", chdir=TRUE);renv::restore()' + echo 'source("{input.rprofile}", chdir=TRUE)' > {output.restored} + """ + + +rule render_quarto_renv: + # If the renv is build using a different r version + # than the wrapper, the "conda:" directive may can be overwritten + # using an environment with the correct "r-base" & "r-conda" + # installed + input: + script="extra_datatable.qmd", + renv="env/renv_test/restored.Rprofile", + output: + report="output/extra_datatable_renv.html", + log: + "logs/renv.log", + wrapper: + "master/utils/quarto" diff --git a/utils/quarto/test/env/renv.linux-64.pin.txt b/utils/quarto/test/env/renv.linux-64.pin.txt new file mode 100644 index 00000000000..a1a3b84cb6e --- /dev/null +++ b/utils/quarto/test/env/renv.linux-64.pin.txt @@ -0,0 +1,92 @@ +# This file may be used to create an environment using: +# $ conda create --name --file +# platform: linux-64 +@EXPLICIT +https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2#d7c89558ba9fa0495403155b64376d81 +https://conda.anaconda.org/conda-forge/noarch/_r-mutex-1.0.1-anacondar_1.tar.bz2#19f9db5f4f1b7f5ef5f6d67207f25f38 +https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.6.2-hbcca054_0.conda#847c3c2905cc467cea52c24f9cfa8080 +https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2#0c96522c6bdaed4b1566d11387caaf45 +https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2#34893075a5c9e55cdafac56607368fc6 +https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb +https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_2.conda#cbbe59391138ea5ad3658c76912e147f +https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-2.6.32-he073ed8_17.conda#d731b543793afc0433c4fd593e693fce +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-hf3520f5_7.conda#b80f2f396ca2c28b8c14c437a4ed1e74 +https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-13.2.0-hdb50d1a_111.conda#43178c27fac2dcd495bd9e58e18272d9 +https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-13.2.0-hdb50d1a_111.conda#4ffa92ea4ba6555dee156ce3d0ae7a9b +https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2#f766549260d6815b0c52253f1fb1bb29 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h77fa898_11.conda#8c462ced2af33648195dc9459f331f31 +https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.12-he073ed8_17.conda#595db67e32b276298ff3d94d07d47fbf +https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d +https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.40-ha1999f0_7.conda#3f840c7ed70a96b5ebde8044b2f36f32 +https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h77fa898_11.conda#0b3b218a596bb4c3854cc9ee799f94e5 +https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hd590300_5.conda#69b8b6202a07720f448be700e300ccf4 +https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.28.1-hd590300_0.conda#dcde58ff9a1f30b0037a2315d1846d1f +https://conda.anaconda.org/conda-forge/linux-64/fribidi-1.0.10-h36c2ea0_0.tar.bz2#ac7bc6a654f8f41b352b38f4051135f8 +https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.1-h166bdaf_0.tar.bz2#30186d27e2c9fa62b45fb1476b7200e3 +https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.20-hd590300_0.conda#8e88f9389f1165d7c0936fe40d9a9a79 +https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.6.2-h59595ed_0.conda#e7ba12deb7020dd080c6c70e7b6f6a3d +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-h3d2ce59_11.conda#c485da4fdb454539f852a90ae06e9bb7 +https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.17-hd590300_2.conda#d66573916ffcf376178462f1b61c941e +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/libstdcxx-ng-13.2.0-hc0a3c3a_11.conda#eaa8ea74083fb4a78ae19e431e556003 +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda#40b61aab5c7ba9ff276c41cfffe6b80b +https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.4.0-hd590300_0.conda#b26e8aa824079e1be0294e7152ca4559 +https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-h4ab18f5_1.conda#57d7dc60e9325e3de37ff8dffd18e814 +https://conda.anaconda.org/conda-forge/linux-64/make-4.3-hd18ef5c_1.tar.bz2#4049ebfd3190b580dffe76daed26155a +https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h59595ed_0.conda#fcea371545eda051b6deafb24889fc69 +https://conda.anaconda.org/conda-forge/linux-64/openssl-3.3.1-h4ab18f5_0.conda#a41fa0e391cc9e0d6b78ac69ca047a6c +https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-h36c2ea0_1001.tar.bz2#22dad4df6e8630e8dff2428f6f6a7036 +https://conda.anaconda.org/conda-forge/linux-64/sed-4.8-he412f7d_0.tar.bz2#7362f0042e95681f5d371c46c83ebd08 +https://conda.anaconda.org/conda-forge/linux-64/xorg-kbproto-1.0.7-h7f98852_1002.tar.bz2#4b230e8381279d76131116660f5a241a +https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.1-hd590300_0.conda#b462a33c0be1421532f28bfe8f4a7514 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.11-hd590300_0.conda#2c80dc38fface310c9bd81b17037fee5 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.3-h7f98852_0.tar.bz2#be93aabceefa2fac576e971aef407908 +https://conda.anaconda.org/conda-forge/linux-64/xorg-renderproto-0.11.1-h7f98852_1002.tar.bz2#06feff3d2634e3097ce2fe681474b534 +https://conda.anaconda.org/conda-forge/linux-64/xorg-xextproto-7.3.0-h0b41bf4_1003.conda#bce9f945da8ad2ae9b1d7165a64d0f87 +https://conda.anaconda.org/conda-forge/linux-64/xorg-xproto-7.0.31-h7f98852_1007.tar.bz2#b4a4381d54784606820704f7b5f05a15 +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/expat-2.6.2-h59595ed_0.conda#53fb86322bdb89496d7579fe3f02fd61 +https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.13-h59595ed_1003.conda#f87c7b7c2cb45f323ffbce941c78ab7c +https://conda.anaconda.org/conda-forge/linux-64/icu-73.2-h59595ed_0.conda#cc47e1facc155f91abd89b11e48e72ff +https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h27087fc_0.tar.bz2#76bbff344f0134279f225174e9064c8f +https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20191231-he28a2e2_2.tar.bz2#4d331e44109e3f0e19b4cb8f9b82f3e1 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-13.2.0-h69a702a_11.conda#4c3e460d6acf8e43e4ce8bf405187eb7 +https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.58.0-h47da74e_1.conda#700ac6ea6d53d5510591c4344d5c989a +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.43-h2797004_0.conda#009981dd9cfcaa4dbfa25ffaed86bcae +https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-13.2.0-h6ddb7a1_11.conda#3227eb98475de9cb375391aa28b931d5 +https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.0-h0841786_0.conda#1f5a58e686b13bcfde88b93f547d23fe +https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.16-hd590300_0.conda#151cba22b85a989c2d6ef9633ffee1e4 +https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.44-h0f59acf_0.conda#3914f7ac1761dce57102c72ca7c35d01 +https://conda.anaconda.org/conda-forge/linux-64/pixman-0.43.2-h59595ed_0.conda#71004cbf7924e19c02746ccde9fd7123 +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/xorg-libsm-1.2.4-h7391055_0.conda#93ee23f12bc2e684548181256edd2cf6 +https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-h4ab18f5_1.conda#9653f1bf3766164d0e65fa723cabbc54 +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.6-ha6fb4c9_0.conda#4d056880988120e29d75bfff282e0f45 +https://conda.anaconda.org/conda-forge/linux-64/bwidget-1.9.14-ha770c72_1.tar.bz2#5746d6202ba2abad4a4707f2a2462795 +https://conda.anaconda.org/conda-forge/linux-64/freetype-2.12.1-h267a509_2.conda#9ae35c3d96db2c94ce0cef86efdfa2cb +https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-13.2.0-h9eb54c0_11.conda#6ba78509a489a8a7882328468f187cc9 +https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.2-h659d440_0.conda#cd95826dbd331ed1be26bdf401432844 +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.80.2-h8a4344b_1.conda#9c406bb3d4dac2b358873e6462496d09 +https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.27-pthreads_h413a1c8_0.conda#a356024784da6dfd4683dc5ecf45b155 +https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.6.0-h1dd3fc0_3.conda#66f03896ffbe1a110ffda05c7a856504 +https://conda.anaconda.org/conda-forge/linux-64/tktable-2.10-h0c5db8f_5.conda#9464044754ea25557a9c93f0327d90a6 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.9-hb711507_1.conda#4a6d410296d7e39f00bacdee7df046e9 +https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.14.2-h14ed4e7_0.conda#0f69b688f52ff6da70bccb7ff7001d1d +https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-13.2.0-h9efe08d_11.conda#d08f638bb8b62d71f2222ecb7003a995 +https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-13.2.0-h2a599c4_11.conda#c2f0227c9bea564b8edc2f1de939c76d +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-22_linux64_openblas.conda#1a2a0cd3153464fee6646f3dd6dad9b8 +https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.8.0-hca28451_0.conda#f21c27f076a07907e70c49bb57bd0f20 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.4-h0b41bf4_2.conda#82b6df12252e6f32402b96dacc656fec +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.11-hd590300_0.conda#ed67c36f215b310412b2af935bf3e530 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxt-1.3.0-hd590300_1.conda#ae92aab42726eb29d16488924f7312cb +https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.0-hbb29018_1.conda#e31a51ddd52326d10a9cc50b0d68daab +https://conda.anaconda.org/conda-forge/linux-64/curl-8.8.0-he654da7_0.conda#042341d8b9ba4ee7f2722b81fae9f0ad +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-22_linux64_openblas.conda#b083767b6c877e24ee597d93b87ab838 +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-8.5.0-hfac3d4d_0.conda#f5126317dd0ce0ba26945e411ecc6960 +https://conda.anaconda.org/conda-forge/linux-64/pango-1.54.0-h84a9a3c_0.conda#7c51e110b2f059c0843269d3324e4b22 +https://conda.anaconda.org/conda-forge/linux-64/r-base-4.3.3-h8ee917f_2.conda#fdd20aea0c8243bfa7fb85d144f4febe +https://conda.anaconda.org/conda-forge/noarch/r-renv-1.0.7-r43hc72bb7e_0.conda#efa116dc4d7118a48c97f6f8f4861427 diff --git a/utils/quarto/test/env/renv.yaml b/utils/quarto/test/env/renv.yaml new file mode 100644 index 00000000000..23355a5c8b1 --- /dev/null +++ b/utils/quarto/test/env/renv.yaml @@ -0,0 +1,6 @@ +channels: + - conda-forge + - nodefaults +dependencies: + - r-base=4.3.3 + - r-renv=1.0.7 \ No newline at end of file diff --git a/utils/quarto/test/env/renv_dt.lock b/utils/quarto/test/env/renv_dt.lock new file mode 100644 index 00000000000..13c0acdebee --- /dev/null +++ b/utils/quarto/test/env/renv_dt.lock @@ -0,0 +1,418 @@ +{ + "R": { + "Version": "4.3.3", + "Repositories": [ + { + "Name": "CRAN", + "URL": "https://cloud.r-project.org" + } + ] + }, + "Packages": { + "R6": { + "Package": "R6", + "Version": "2.5.1", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R" + ], + "Hash": "470851b6d5d0ac559e9d01bb352b4021" + }, + "Rcpp": { + "Package": "Rcpp", + "Version": "1.0.12", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "methods", + "utils" + ], + "Hash": "5ea2700d21e038ace58269ecdbeb9ec0" + }, + "base64enc": { + "Package": "base64enc", + "Version": "0.1-3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "543776ae6848fde2f48ff3816d0628bc" + }, + "bslib": { + "Package": "bslib", + "Version": "0.7.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "base64enc", + "cachem", + "fastmap", + "grDevices", + "htmltools", + "jquerylib", + "jsonlite", + "lifecycle", + "memoise", + "mime", + "rlang", + "sass" + ], + "Hash": "8644cc53f43828f19133548195d7e59e" + }, + "cachem": { + "Package": "cachem", + "Version": "1.1.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "fastmap", + "rlang" + ], + "Hash": "cd9a672193789068eb5a2aad65a0dedf" + }, + "cli": { + "Package": "cli", + "Version": "3.6.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "utils" + ], + "Hash": "1216ac65ac55ec0058a6f75d7ca0fd52" + }, + "data.table": { + "Package": "data.table", + "Version": "1.15.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "methods" + ], + "Hash": "8ee9ac56ef633d0c7cab8b2ca87d683e" + }, + "digest": { + "Package": "digest", + "Version": "0.6.35", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "utils" + ], + "Hash": "698ece7ba5a4fa4559e3d537e7ec3d31" + }, + "evaluate": { + "Package": "evaluate", + "Version": "0.24.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "methods" + ], + "Hash": "a1066cbc05caee9a4bf6d90f194ff4da" + }, + "fastmap": { + "Package": "fastmap", + "Version": "1.2.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "aa5e1cd11c2d15497494c5292d7ffcc8" + }, + "fontawesome": { + "Package": "fontawesome", + "Version": "0.5.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "htmltools", + "rlang" + ], + "Hash": "c2efdd5f0bcd1ea861c2d4e2a883a67d" + }, + "fs": { + "Package": "fs", + "Version": "1.6.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "methods" + ], + "Hash": "15aeb8c27f5ea5161f9f6a641fafd93a" + }, + "glue": { + "Package": "glue", + "Version": "1.7.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "methods" + ], + "Hash": "e0b3a53876554bd45879e596cdb10a52" + }, + "highr": { + "Package": "highr", + "Version": "0.11", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "xfun" + ], + "Hash": "d65ba49117ca223614f71b60d85b8ab7" + }, + "htmltools": { + "Package": "htmltools", + "Version": "0.5.8.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "base64enc", + "digest", + "fastmap", + "grDevices", + "rlang", + "utils" + ], + "Hash": "81d371a9cc60640e74e4ab6ac46dcedc" + }, + "jquerylib": { + "Package": "jquerylib", + "Version": "0.1.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "htmltools" + ], + "Hash": "5aab57a3bd297eee1c1d862735972182" + }, + "jsonlite": { + "Package": "jsonlite", + "Version": "1.8.8", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "methods" + ], + "Hash": "e1b9c55281c5adc4dd113652d9e26768" + }, + "knitr": { + "Package": "knitr", + "Version": "1.47", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "evaluate", + "highr", + "methods", + "tools", + "xfun", + "yaml" + ], + "Hash": "7c99b2d55584b982717fcc0950378612" + }, + "later": { + "Package": "later", + "Version": "1.3.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "Rcpp", + "rlang" + ], + "Hash": "a3e051d405326b8b0012377434c62b37" + }, + "lifecycle": { + "Package": "lifecycle", + "Version": "1.0.4", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "cli", + "glue", + "rlang" + ], + "Hash": "b8552d117e1b808b09a832f589b79035" + }, + "memoise": { + "Package": "memoise", + "Version": "2.0.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "cachem", + "rlang" + ], + "Hash": "e2817ccf4a065c5d9d7f2cfbe7c1d78c" + }, + "mime": { + "Package": "mime", + "Version": "0.12", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "tools" + ], + "Hash": "18e9c28c1d3ca1560ce30658b22ce104" + }, + "processx": { + "Package": "processx", + "Version": "3.8.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R6", + "ps", + "utils" + ], + "Hash": "0c90a7d71988856bad2a2a45dd871bb9" + }, + "ps": { + "Package": "ps", + "Version": "1.7.6", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "utils" + ], + "Hash": "dd2b9319ee0656c8acf45c7f40c59de7" + }, + "quarto": { + "Package": "quarto", + "Version": "1.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "jsonlite", + "later", + "processx", + "rlang", + "rmarkdown", + "rstudioapi", + "tools", + "utils", + "yaml" + ], + "Hash": "c94c271f9b998d116186a78b2a9b23c1" + }, + "rappdirs": { + "Package": "rappdirs", + "Version": "0.3.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "5e3c5dc0b071b21fa128676560dbe94d" + }, + "renv": { + "Package": "renv", + "Version": "1.0.7", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "utils" + ], + "Hash": "397b7b2a265bc5a7a06852524dabae20" + }, + "rlang": { + "Package": "rlang", + "Version": "1.1.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "utils" + ], + "Hash": "3eec01f8b1dee337674b2e34ab1f9bc1" + }, + "rmarkdown": { + "Package": "rmarkdown", + "Version": "2.27", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "bslib", + "evaluate", + "fontawesome", + "htmltools", + "jquerylib", + "jsonlite", + "knitr", + "methods", + "tinytex", + "tools", + "utils", + "xfun", + "yaml" + ], + "Hash": "27f9502e1cdbfa195f94e03b0f517484" + }, + "rstudioapi": { + "Package": "rstudioapi", + "Version": "0.16.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "96710351d642b70e8f02ddeb237c46a7" + }, + "sass": { + "Package": "sass", + "Version": "0.4.9", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R6", + "fs", + "htmltools", + "rappdirs", + "rlang" + ], + "Hash": "d53dbfddf695303ea4ad66f86e99b95d" + }, + "tinytex": { + "Package": "tinytex", + "Version": "0.51", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "xfun" + ], + "Hash": "d44e2fcd2e4e076f0aac540208559d1d" + }, + "xfun": { + "Package": "xfun", + "Version": "0.45", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "grDevices", + "stats", + "tools" + ], + "Hash": "ca59c87fe305b16a9141a5874c3a7889" + }, + "yaml": { + "Package": "yaml", + "Version": "2.3.8", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "29240487a071f535f5e5d5a323b7afbd" + } + } +} diff --git a/utils/quarto/test/extra_datatable.qmd b/utils/quarto/test/extra_datatable.qmd new file mode 100644 index 00000000000..0c724a0d4f7 --- /dev/null +++ b/utils/quarto/test/extra_datatable.qmd @@ -0,0 +1,15 @@ +--- +title: "Quarto example with additional package dependency" +author: "Vito Zanotelli, University Children's Hospital Zurich" +format: html +--- + +This quarto markdown is used to demonstrate how an extra +dependency - 'data.table' can be installed either via conda or renv. + +As 'data.table' is not available in the base environment, building +this report fails if it has not been additionally installed. + +```{r, Try to load data table} +library(data.table) +``` diff --git a/utils/quarto/test/full.qmd b/utils/quarto/test/full.qmd new file mode 100644 index 00000000000..c7a55a55495 --- /dev/null +++ b/utils/quarto/test/full.qmd @@ -0,0 +1,15 @@ +--- +title: "Full Quarto example: `r params$project`" +author: "Vito Zanotelli, University Children's Hospital Zurich" +format: html +params: + input_txt: '../results/test.txt' + output_txt: '../results/test_copy.txt' + project: 'Test' +--- + + +```{r} +#| label: copy example file +file.copy(params$input_txt, params$output_txt) +``` diff --git a/utils/quarto/test/resources_custom.qmd b/utils/quarto/test/resources_custom.qmd new file mode 100644 index 00000000000..ddda5d745e6 --- /dev/null +++ b/utils/quarto/test/resources_custom.qmd @@ -0,0 +1,15 @@ +--- +title: "Quarto resource passing example" +author: "Vito Zanotelli, University Children's Hospital Zurich" +format: html +params: + resources_custom_resource: NULL +--- + + +```{r} +#| label: Verify that resource custom_resource is passed +if (is.null(params$resources_custom_resource)){ + stop('resource "custom_resource" not passed to report') +} +``` \ No newline at end of file diff --git a/utils/quarto/test/resources_threads.qmd b/utils/quarto/test/resources_threads.qmd new file mode 100644 index 00000000000..d3ab453ca26 --- /dev/null +++ b/utils/quarto/test/resources_threads.qmd @@ -0,0 +1,16 @@ +--- +title: "Quarto resource passing example" +author: "Vito Zanotelli, University Children's Hospital Zurich" +format: html +params: + resources_threads: NULL +--- + + +```{r} +#| label: Verify that threads are passed +if (is.null(params$resources_threads)){ + stop('resource "threads" not passed to report') +} +``` + diff --git a/utils/quarto/test/simple.qmd b/utils/quarto/test/simple.qmd new file mode 100644 index 00000000000..eab3afb7372 --- /dev/null +++ b/utils/quarto/test/simple.qmd @@ -0,0 +1,7 @@ +--- +title: "Quarto example" +author: "Vito Zanotelli, University Children's Hospital Zurich" +format: html +--- + +Hello Quarto! \ No newline at end of file diff --git a/utils/quarto/wrapper.py b/utils/quarto/wrapper.py new file mode 100644 index 00000000000..871a2a12dc6 --- /dev/null +++ b/utils/quarto/wrapper.py @@ -0,0 +1,159 @@ +__author__ = "Vito Zanotelli" +__copyright__ = "Copyright 2024, Vito Zanotelli" +__email__ = "vito.zanotelli@kispi.uzh.ch" +__license__ = "MIT" + +import tempfile +from pathlib import Path +import warnings +import yaml +from snakemake.shell import shell + + +def parse_renv(renv_path: Path) -> str: + """Parse the renv path + + Args: + renv_path (Path): A path to an renv folder + or a file in the renv folder + + Returns: + str: the resolved path pointing to the + renv folder + """ + if renv_path.is_file(): + renv_path = renv_path.parent + return str(renv_path.resolve()) + + +def parse_qmd_header(fn_script): + """Parse the yml header of the a + quarto markdown file + + Args: + fn_script (path): Path to the qmd script + + Raises: + ValueError: qmd has not valid header + + Returns: + dict: parsed header + """ + with open(fn_script, mode="r") as f: + first = f.readline() + if first != "---\n": + raise ValueError(".qmd file has no valid yaml header.") + line = f.readline() + yml_lines = [] + while line != "---\n": + yml_lines.append(line) + line = f.readline() + return yaml.safe_load("".join(yml_lines)) + + +def add_parameter(name: str, value, param_list: list[str]) -> None: + """Add a parameter to the parameter list in place + + Args: + name (str): The name of the parameter + value (str): The value of the parameter + param_list (list[str]): The list of parameters + + Returns: + None + """ + if isinstance(value, list): + value = ",".join(value) + param_list.append("-P {}:{}".format(name, value)) + + +renv = parse_renv(Path(snakemake.input.get("renv", "."))) +script = Path(snakemake.input.get("script")) +report = snakemake.output.get("report", None) + + +# Build params to be passed to Quarto params (-P flag) +params = [] +for name, value in snakemake.input.items(): + if name not in {"renv", "script"}: + add_parameter(name, value, params) + +for name, value in snakemake.params.items(): + add_parameter(name, value, params) + +for name, value in snakemake.output.items(): + if name not in {"report"}: + add_parameter(name, value, params) + + +# Get the snakemake resources that correspond to +# Params in the qmd header that are prefixed with the resource prefix +# RESOURCE_PARAMS_PREFIX. +# eg resources_mem -> snakemake.resources.mem +RESOURCE_PARAMS_PREFIX = "resources_" +params_header = parse_qmd_header(script).get("params", {}) +resources = {**snakemake.resources} +resources["threads"] = snakemake.threads +passed_resource_params = { + f"{RESOURCE_PARAMS_PREFIX}{k}": v + for k, v in resources.items() + if f"{RESOURCE_PARAMS_PREFIX}{k}" in params_header.keys() +} + +for name, value in passed_resource_params.items(): + add_parameter(name, value, params) + + +# Resolve the logfile path and set the log_fmt_shell +# This is required as we may change the working directory +# to the renv folder for execution of quarto. +logfile = snakemake.log +if logfile: + snakemake.log = str(Path(str(logfile)).resolve()) + log = snakemake.log_fmt_shell(stdout=True, stderr=True) +else: + log = "" + +args = " ".join(params) + +with tempfile.TemporaryDirectory() as temp_output: + if report is None: + # In case no report output is specified, + # the output is created in a temporary folder + out_report = Path(temp_output) / script.name + out_report_rendered = out_report + report_path = f"{out_report}.tmp" + else: + # In case an output is specified, + # the output is created in the target folder. + report_path = Path(report).resolve() + # The report to-be-rendered is namespaced + # to prevent clashes. + out_report = ( + report_path.parent / f"{report_path.stem}_{report_path.suffix[1:]}.qmd" + ) + # The rendered report is named as the final report with the correct suffix + # Note that in addition ot the target report file, also a folder `*_files/` + # is created, which contains the images and other files linked in the html report. + out_report_rendered = out_report.with_suffix(report_path.suffix) + if report_path.suffix == ".pdf": + warnings.warn( + "PDF output is likely not supported yet, as tinytex not installable" + " via conda: https://github.com/conda-forge/quarto-feedstock/issues/26" + ) + args += f" --to={report_path.suffix[1:]}" + shell( + """ + # copy the input script to prevent name clashes + cp {script} {out_report} + WD=$(pwd) + # Change to renv directory to enable the renv + cd "{renv}" + quarto render {out_report} \ + {args} \ + --execute-dir="$WD" \ + {log} + # move the output to the final destination + mv {out_report_rendered} {report_path} + """ + )