From 8823577c5dfd0c7dbfa806b7b9b0e061ac55f562 Mon Sep 17 00:00:00 2001 From: an-altosian Date: Fri, 13 Feb 2026 21:38:57 +0000 Subject: [PATCH 1/9] Add new module: qcatch QCatch is a quality control and cell filtering tool for single-cell RNA-seq data processed by alevin-fry. It generates comprehensive QC reports and filtered count matrices. Inputs: - meta: sample metadata map - chemistry: chemistry type (10X_3p_v2, 10X_3p_v3, 10X_3p_v4, 10X_5p_v3, 10X_3p_LT, 10X_HT) - quant_dir: alevin-fry quantification results directory Outputs: - HTML QC report - Filtered h5ad file - Metrics summary CSV - versions.yml Co-Authored-By: Claude Opus 4.6 --- modules/nf-core/qcatch/environment.yml | 8 ++ modules/nf-core/qcatch/main.nf | 58 +++++++++++++ modules/nf-core/qcatch/meta.yml | 86 +++++++++++++++++++ modules/nf-core/qcatch/tests/main.nf.test | 69 +++++++++++++++ .../nf-core/qcatch/tests/main.nf.test.snap | 79 +++++++++++++++++ 5 files changed, 300 insertions(+) create mode 100644 modules/nf-core/qcatch/environment.yml create mode 100644 modules/nf-core/qcatch/main.nf create mode 100644 modules/nf-core/qcatch/meta.yml create mode 100644 modules/nf-core/qcatch/tests/main.nf.test create mode 100644 modules/nf-core/qcatch/tests/main.nf.test.snap diff --git a/modules/nf-core/qcatch/environment.yml b/modules/nf-core/qcatch/environment.yml new file mode 100644 index 00000000000..74aa8df77af --- /dev/null +++ b/modules/nf-core/qcatch/environment.yml @@ -0,0 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda + +dependencies: + - bioconda::qcatch=0.2.8 diff --git a/modules/nf-core/qcatch/main.nf b/modules/nf-core/qcatch/main.nf new file mode 100644 index 00000000000..6a050aa575d --- /dev/null +++ b/modules/nf-core/qcatch/main.nf @@ -0,0 +1,58 @@ +process QCATCH { + tag "$meta.id" + label 'process_low' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'oras://community.wave.seqera.io/library/qcatch:0.2.8--3089b62e628f96d7': + 'community.wave.seqera.io/library/qcatch:0.2.8--454a9b478b62c36f' }" + + input: + tuple val(meta), val(chemistry), path(quant_dir) + + output: + tuple val(meta), path("*.html") , emit: report + tuple val(meta), path("${prefix}_filtered_quants.h5ad") , emit: filtered_h5ad + tuple val(meta), path("${prefix}_metrics_summary.csv") , emit: metrics_summary + path "versions.yml" , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + + """ + qcatch \\ + --input ${quant_dir} \\ + --output ${prefix} \\ + --chemistry ${chemistry} \\ + --save_filtered_h5ad \\ + --export_summary_table \\ + ${args} + + mv ${prefix}/QCatch_report.html ${prefix}_qcatch_report.html + mv ${prefix}/filtered_quants.h5ad ${prefix}_filtered_quants.h5ad + mv ${prefix}/summary_table.csv ${prefix}_metrics_summary.csv + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + qcatch: \$(qcatch --version | sed -e "s/qcatch //g") + END_VERSIONS + """ + + stub: + prefix = task.ext.prefix ?: "${meta.id}" + + """ + touch ${prefix}_qcatch_report.html + touch ${prefix}_filtered_quants.h5ad + touch ${prefix}_metrics_summary.csv + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + qcatch: \$(qcatch --version | sed -e "s/qcatch //g") + END_VERSIONS + """ +} diff --git a/modules/nf-core/qcatch/meta.yml b/modules/nf-core/qcatch/meta.yml new file mode 100644 index 00000000000..f1ed6e310a9 --- /dev/null +++ b/modules/nf-core/qcatch/meta.yml @@ -0,0 +1,86 @@ +name: qcatch +description: Cell-filtering and QC reporting tool for alevin-fry quantification results +keywords: + - single-cell + - quality control + - alevin-fry + - cell filtering + - QC report +tools: + - qcatch: + description: | + QCatch is a quality control and cell filtering tool designed for single-cell RNA-seq data processed by alevin-fry. + It generates comprehensive QC reports and filtered count matrices. + homepage: https://github.com/COMBINE-lab/QCatch + licence: ["BSD-3-Clause"] + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - chemistry: + type: string + description: | + Chemistry type for the single-cell experiment, which determines the partition range for the empty_drops step. + Supported values: '10X_3p_v2', '10X_3p_v3', '10X_3p_v4', '10X_5p_v3', '10X_3p_LT', '10X_HT'. + If using a standard 10X chemistry and quantification was performed with simpleaf (v0.19.5 or later), + QCatch will try to infer the correct chemistry from the metadata. + - quant_dir: + type: directory + description: | + Directory containing alevin-fry quantification results (af_quant output from simpleaf quant). + Must contain the quantification matrix and associated metadata files. + ontologies: [] +output: + report: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.html": + type: file + description: | + HTML QC report generated by QCatch containing visualizations and metrics + pattern: "*.html" + ontologies: [] + filtered_h5ad: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - ${prefix}_filtered_quants.h5ad: + type: file + description: | + Filtered quantification matrix in h5ad format (AnnData) + pattern: "*_filtered_quants.h5ad" + ontologies: [] + metrics_summary: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - ${prefix}_metrics_summary.csv: + type: file + description: | + CSV file containing summary metrics from QC analysis + pattern: "*_metrics_summary.csv" + ontologies: [] + versions: + - versions.yml: + type: file + description: | + File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML +authors: + - "@wzheng0520" + - "@dongzehe" +maintainers: + - "@wzheng0520" + - "@dongzehe" diff --git a/modules/nf-core/qcatch/tests/main.nf.test b/modules/nf-core/qcatch/tests/main.nf.test new file mode 100644 index 00000000000..426fe542f59 --- /dev/null +++ b/modules/nf-core/qcatch/tests/main.nf.test @@ -0,0 +1,69 @@ +nextflow_process { + + name "Test Process QCATCH" + script "../main.nf" + process "QCATCH" + + tag "modules" + tag "modules_nfcore" + tag "qcatch" + tag "unzip" + + test("test_qcatch - 1k_pbmc_v3") { + + setup { + // Download and extract QCatch test data from COMBINE-lab using UNZIP module + run("UNZIP") { + script "modules/nf-core/unzip/main.nf" + process { + """ + meta = [id:'qcatch_test_data'] + input[0] = Channel.of([meta, file('https://umd.box.com/shared/static/zd4sai70uw9fs24e1qx6r41ec50pf45g.zip')]) + """ + } + } + } + + when { + process { + """ + // Get the 1k_pbmc_v3 subdirectory from the extracted archive + input[0] = UNZIP.out.unzipped_archive.map { meta, dir -> + def quant_dir = file("\${dir}/test_data/1k_pbmc_v3") + [[id:'1k_pbmc_v3'], '10X_3p_v3', quant_dir] + } + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert file(process.out.report.get(0).get(1)).exists() }, + { assert file(process.out.filtered_h5ad.get(0).get(1)).exists() }, + { assert file(process.out.metrics_summary.get(0).get(1)).exists() }, + { assert snapshot(process.out.versions).match() } + ) + } + } + + test("test_qcatch - stub") { + options "-stub-run" + + when { + process { + """ + meta = [id:'test_stub'] + input[0] = Channel.of([meta, '10X_3p_v3', file('stub_quant_dir')]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } +} diff --git a/modules/nf-core/qcatch/tests/main.nf.test.snap b/modules/nf-core/qcatch/tests/main.nf.test.snap new file mode 100644 index 00000000000..a5cbbdd2cf7 --- /dev/null +++ b/modules/nf-core/qcatch/tests/main.nf.test.snap @@ -0,0 +1,79 @@ +{ + "test_qcatch - 1k_pbmc_v3": { + "content": [ + [ + "versions.yml:md5,46f73aa6be1b23a13365040ab92e22af" + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.3" + }, + "timestamp": "2026-02-13T21:36:15.677759721" + }, + "test_qcatch - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test_stub" + }, + "test_stub_qcatch_report.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test_stub" + }, + "test_stub_filtered_quants.h5ad:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test_stub" + }, + "test_stub_metrics_summary.csv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + "versions.yml:md5,46f73aa6be1b23a13365040ab92e22af" + ], + "filtered_h5ad": [ + [ + { + "id": "test_stub" + }, + "test_stub_filtered_quants.h5ad:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "metrics_summary": [ + [ + { + "id": "test_stub" + }, + "test_stub_metrics_summary.csv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "report": [ + [ + { + "id": "test_stub" + }, + "test_stub_qcatch_report.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,46f73aa6be1b23a13365040ab92e22af" + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-02-13T21:56:57.673052701" + } +} \ No newline at end of file From 337d3463c053a500fcb582f60ce7e083418aef1f Mon Sep 17 00:00:00 2001 From: an-altosian Date: Fri, 13 Feb 2026 22:30:53 +0000 Subject: [PATCH 2/9] Fix Singularity compatibility for matplotlib config directory Add MPLCONFIGDIR and TMPDIR environment exports to redirect matplotlib config writes to the working directory. This fixes Singularity test failures where home directory is mounted read-only. Co-Authored-By: Claude Opus 4.6 --- modules/nf-core/qcatch/main.nf | 7 +++++++ modules/nf-core/qcatch/tests/main.nf.test.snap | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/modules/nf-core/qcatch/main.nf b/modules/nf-core/qcatch/main.nf index 6a050aa575d..b32351c8ec6 100644 --- a/modules/nf-core/qcatch/main.nf +++ b/modules/nf-core/qcatch/main.nf @@ -24,6 +24,9 @@ process QCATCH { prefix = task.ext.prefix ?: "${meta.id}" """ + export MPLCONFIGDIR=./tmp + export TMPDIR=./tmp + qcatch \\ --input ${quant_dir} \\ --output ${prefix} \\ @@ -43,9 +46,13 @@ process QCATCH { """ stub: + def args = task.ext.args ?: '' prefix = task.ext.prefix ?: "${meta.id}" """ + export MPLCONFIGDIR=./tmp + export TMPDIR=./tmp + touch ${prefix}_qcatch_report.html touch ${prefix}_filtered_quants.h5ad touch ${prefix}_metrics_summary.csv diff --git a/modules/nf-core/qcatch/tests/main.nf.test.snap b/modules/nf-core/qcatch/tests/main.nf.test.snap index a5cbbdd2cf7..d82b2a42341 100644 --- a/modules/nf-core/qcatch/tests/main.nf.test.snap +++ b/modules/nf-core/qcatch/tests/main.nf.test.snap @@ -76,4 +76,4 @@ }, "timestamp": "2026-02-13T21:56:57.673052701" } -} \ No newline at end of file +} From c86ca4f9765aa818505896cf48c1866c37eb0b0e Mon Sep 17 00:00:00 2001 From: an-altosian Date: Fri, 13 Feb 2026 22:37:56 +0000 Subject: [PATCH 3/9] Add NUMBA_CACHE_DIR for Singularity numba caching fix Scanpy uses numba for compiled functions, which requires a writable cache directory. In Singularity, the default cache location inside the container is read-only. Co-Authored-By: Claude Opus 4.6 --- modules/nf-core/qcatch/main.nf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/nf-core/qcatch/main.nf b/modules/nf-core/qcatch/main.nf index b32351c8ec6..0fdb9746caf 100644 --- a/modules/nf-core/qcatch/main.nf +++ b/modules/nf-core/qcatch/main.nf @@ -25,6 +25,7 @@ process QCATCH { """ export MPLCONFIGDIR=./tmp + export NUMBA_CACHE_DIR=./tmp export TMPDIR=./tmp qcatch \\ @@ -51,6 +52,7 @@ process QCATCH { """ export MPLCONFIGDIR=./tmp + export NUMBA_CACHE_DIR=./tmp export TMPDIR=./tmp touch ${prefix}_qcatch_report.html From 4cb85a1aa910d6fdced5434f1f3ae7fb6a75d60d Mon Sep 17 00:00:00 2001 From: an-altosian Date: Fri, 13 Feb 2026 22:40:12 +0000 Subject: [PATCH 4/9] Add NUMBA_DISABLE_CACHE and XDG_CACHE_HOME for Singularity Add additional environment variables commonly used alongside NUMBA_CACHE_DIR to ensure full compatibility with Singularity: - NUMBA_DISABLE_CACHE=1: Disables numba caching entirely - XDG_CACHE_HOME: Redirects XDG cache to working directory Co-Authored-By: Claude Opus 4.6 --- modules/nf-core/qcatch/main.nf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/nf-core/qcatch/main.nf b/modules/nf-core/qcatch/main.nf index 0fdb9746caf..3a720d51d86 100644 --- a/modules/nf-core/qcatch/main.nf +++ b/modules/nf-core/qcatch/main.nf @@ -26,6 +26,8 @@ process QCATCH { """ export MPLCONFIGDIR=./tmp export NUMBA_CACHE_DIR=./tmp + export NUMBA_DISABLE_CACHE=1 + export XDG_CACHE_HOME=./tmp export TMPDIR=./tmp qcatch \\ @@ -53,6 +55,8 @@ process QCATCH { """ export MPLCONFIGDIR=./tmp export NUMBA_CACHE_DIR=./tmp + export NUMBA_DISABLE_CACHE=1 + export XDG_CACHE_HOME=./tmp export TMPDIR=./tmp touch ${prefix}_qcatch_report.html From 9e0d516ed4568f84f69cff79998d09101e4f5a54 Mon Sep 17 00:00:00 2001 From: an-altosian Date: Sat, 14 Feb 2026 00:07:24 +0000 Subject: [PATCH 5/9] Switch to BioContainers for qcatch module Co-Authored-By: Claude Opus 4.6 --- modules/nf-core/qcatch/main.nf | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/nf-core/qcatch/main.nf b/modules/nf-core/qcatch/main.nf index 3a720d51d86..9b5acec21be 100644 --- a/modules/nf-core/qcatch/main.nf +++ b/modules/nf-core/qcatch/main.nf @@ -4,9 +4,8 @@ process QCATCH { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'oras://community.wave.seqera.io/library/qcatch:0.2.8--3089b62e628f96d7': - 'community.wave.seqera.io/library/qcatch:0.2.8--454a9b478b62c36f' }" - + 'https://depot.galaxyproject.org/singularity/qcatch:0.2.8--pyhdfd78af_0': + 'biocontainers/qcatch:0.2.8--pyhdfd78af_0' }" input: tuple val(meta), val(chemistry), path(quant_dir) From 31e52dd6b032802f2c28eb73c45d07a3cd5f9509 Mon Sep 17 00:00:00 2001 From: an-altosian Date: Sat, 14 Feb 2026 14:33:22 +0000 Subject: [PATCH 6/9] Address PR review: use Seqera Containers, local prefix, wildcard outputs Co-Authored-By: Claude Opus 4.6 --- modules/nf-core/qcatch/main.nf | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/nf-core/qcatch/main.nf b/modules/nf-core/qcatch/main.nf index 9b5acec21be..2ed886f6c21 100644 --- a/modules/nf-core/qcatch/main.nf +++ b/modules/nf-core/qcatch/main.nf @@ -4,15 +4,15 @@ process QCATCH { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/qcatch:0.2.8--pyhdfd78af_0': - 'biocontainers/qcatch:0.2.8--pyhdfd78af_0' }" + 'oras://community.wave.seqera.io/library/qcatch:0.2.8--3089b62e628f96d7': + 'community.wave.seqera.io/library/qcatch:0.2.8--454a9b478b62c36f' }" input: tuple val(meta), val(chemistry), path(quant_dir) output: tuple val(meta), path("*.html") , emit: report - tuple val(meta), path("${prefix}_filtered_quants.h5ad") , emit: filtered_h5ad - tuple val(meta), path("${prefix}_metrics_summary.csv") , emit: metrics_summary + tuple val(meta), path("*_filtered_quants.h5ad") , emit: filtered_h5ad + tuple val(meta), path("*_metrics_summary.csv") , emit: metrics_summary path "versions.yml" , emit: versions when: @@ -20,7 +20,7 @@ process QCATCH { script: def args = task.ext.args ?: '' - prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: "${meta.id}" """ export MPLCONFIGDIR=./tmp @@ -49,7 +49,7 @@ process QCATCH { stub: def args = task.ext.args ?: '' - prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: "${meta.id}" """ export MPLCONFIGDIR=./tmp From 1f75971fb20d597c17793a74029f076795f4c90a Mon Sep 17 00:00:00 2001 From: an-altosian Date: Sat, 14 Feb 2026 14:49:57 +0000 Subject: [PATCH 7/9] Fix lint: update meta.yml outputs, remove hardcoded env vars Co-Authored-By: Claude Opus 4.6 --- modules/nf-core/qcatch/main.nf | 12 ------------ modules/nf-core/qcatch/meta.yml | 4 ++-- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/modules/nf-core/qcatch/main.nf b/modules/nf-core/qcatch/main.nf index 2ed886f6c21..bb39f6fbd1f 100644 --- a/modules/nf-core/qcatch/main.nf +++ b/modules/nf-core/qcatch/main.nf @@ -23,12 +23,6 @@ process QCATCH { def prefix = task.ext.prefix ?: "${meta.id}" """ - export MPLCONFIGDIR=./tmp - export NUMBA_CACHE_DIR=./tmp - export NUMBA_DISABLE_CACHE=1 - export XDG_CACHE_HOME=./tmp - export TMPDIR=./tmp - qcatch \\ --input ${quant_dir} \\ --output ${prefix} \\ @@ -52,12 +46,6 @@ process QCATCH { def prefix = task.ext.prefix ?: "${meta.id}" """ - export MPLCONFIGDIR=./tmp - export NUMBA_CACHE_DIR=./tmp - export NUMBA_DISABLE_CACHE=1 - export XDG_CACHE_HOME=./tmp - export TMPDIR=./tmp - touch ${prefix}_qcatch_report.html touch ${prefix}_filtered_quants.h5ad touch ${prefix}_metrics_summary.csv diff --git a/modules/nf-core/qcatch/meta.yml b/modules/nf-core/qcatch/meta.yml index f1ed6e310a9..1764e1942fb 100644 --- a/modules/nf-core/qcatch/meta.yml +++ b/modules/nf-core/qcatch/meta.yml @@ -52,7 +52,7 @@ output: description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - ${prefix}_filtered_quants.h5ad: + - "*_filtered_quants.h5ad": type: file description: | Filtered quantification matrix in h5ad format (AnnData) @@ -64,7 +64,7 @@ output: description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - ${prefix}_metrics_summary.csv: + - "*_metrics_summary.csv": type: file description: | CSV file containing summary metrics from QC analysis From 371169c47108305b004eb330aa1ec7b42f3604ca Mon Sep 17 00:00:00 2001 From: an-altosian Date: Sat, 14 Feb 2026 14:59:25 +0000 Subject: [PATCH 8/9] Move env vars to test config for Singularity compatibility Co-Authored-By: Claude Opus 4.6 --- modules/nf-core/qcatch/tests/main.nf.test | 1 + modules/nf-core/qcatch/tests/nextflow.config | 7 +++++++ 2 files changed, 8 insertions(+) create mode 100644 modules/nf-core/qcatch/tests/nextflow.config diff --git a/modules/nf-core/qcatch/tests/main.nf.test b/modules/nf-core/qcatch/tests/main.nf.test index 426fe542f59..c1b99b70bcf 100644 --- a/modules/nf-core/qcatch/tests/main.nf.test +++ b/modules/nf-core/qcatch/tests/main.nf.test @@ -3,6 +3,7 @@ nextflow_process { name "Test Process QCATCH" script "../main.nf" process "QCATCH" + config "./nextflow.config" tag "modules" tag "modules_nfcore" diff --git a/modules/nf-core/qcatch/tests/nextflow.config b/modules/nf-core/qcatch/tests/nextflow.config new file mode 100644 index 00000000000..d01abb6a3f4 --- /dev/null +++ b/modules/nf-core/qcatch/tests/nextflow.config @@ -0,0 +1,7 @@ +env { + MPLCONFIGDIR = "./tmp" + NUMBA_CACHE_DIR = "./tmp" + NUMBA_DISABLE_CACHE = 1 + XDG_CACHE_HOME = "./tmp" + TMPDIR = "./tmp" +} From 2995baf242078b2ef534b61bc1113891c46cea89 Mon Sep 17 00:00:00 2001 From: an-altosian Date: Sat, 14 Feb 2026 15:43:01 +0000 Subject: [PATCH 9/9] Remove unnecessary TMPDIR and XDG_CACHE_HOME from test config Co-Authored-By: Claude Opus 4.6 --- modules/nf-core/qcatch/tests/nextflow.config | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/modules/nf-core/qcatch/tests/nextflow.config b/modules/nf-core/qcatch/tests/nextflow.config index d01abb6a3f4..edec92b9b9e 100644 --- a/modules/nf-core/qcatch/tests/nextflow.config +++ b/modules/nf-core/qcatch/tests/nextflow.config @@ -1,7 +1,5 @@ env { - MPLCONFIGDIR = "./tmp" - NUMBA_CACHE_DIR = "./tmp" + MPLCONFIGDIR = "./tmp" + NUMBA_CACHE_DIR = "./tmp" NUMBA_DISABLE_CACHE = 1 - XDG_CACHE_HOME = "./tmp" - TMPDIR = "./tmp" }