This guide walks through a minimal, container-friendly Galaxy wrapper for the
Bioconductor ComplexHeatmap package using Planemo.
The finished tool accepts a tabular numeric matrix and produces a PDF heatmap.
Install uv, then use it to install Planemo as an isolated command-line tool.
curl -LsSf https://astral.sh/uv/install.sh | sh
uv tool install planemoCheck the installation:
planemo --versionConcept: uv tool install keeps Planemo in its own isolated environment while
putting the planemo command on your shell path. Planemo is the command-line
SDK for Galaxy tool development: it can scaffold a wrapper, format it, lint it,
test it, serve it in a local Galaxy, and publish it to a ToolShed.
For the containerized test and preview steps, install and start Docker Desktop
before running Planemo with --biocontainers.
Run all commands from the root of the cloned Galaxy tool repository.
git clone https://github.com/afgane/galaxy-tools-repo.git
cd galaxy-tools-repoConcept: Galaxy tools usually live in a tools/<tool_id>/ directory with one
XML wrapper, any helper scripts, and test data.
Create the tool directory, then use planemo tool_init to create the first XML
wrapper directly inside it.
mkdir -p tools/complex_heatmapplanemo tool_init \
--id complex_heatmap \
--name "ComplexHeatmap" \
--description "draw a heatmap from a numeric matrix" \
--requirement bioconductor-complexheatmap@2.26.1 \
--input matrix.tsv \
--output heatmap.pdf \
--tool tools/complex_heatmap/complex_heatmap.xmlThis creates:
tools/complex_heatmap/complex_heatmap.xml
Concept: the --requirement value is the Conda package Galaxy will install or
resolve to a BioContainer.
Run:
planemo serve --biocontainers tools/complex_heatmap/complex_heatmap.xmlOpen the local Galaxy URL printed by Planemo and find the ComplexHeatmap tool. As you edit the wrapper in the next steps, refresh the tool page to see how the Galaxy form changes.
Concept: planemo serve starts a local Galaxy with your in-progress tool
loaded. This lets you inspect the user experience while you build: tool name,
description, input fields, defaults, job execution, history item, and output.
Create:
tools/complex_heatmap/complex_heatmap.R
with:
#!/usr/bin/env Rscript
suppressPackageStartupMessages({
library(ComplexHeatmap)
})
parse_args <- function(argv) {
args <- list(title = "Heatmap")
i <- 1
while (i <= length(argv)) {
opt <- argv[[i]]
if (!opt %in% c("--matrix", "--output", "--title")) {
stop("Unknown option: ", opt)
}
if (i == length(argv)) {
stop("Missing value for option: ", opt)
}
args[[sub("^--", "", opt)]] <- argv[[i + 1]]
i <- i + 2
}
if (is.null(args$matrix)) {
stop("Missing required option: --matrix")
}
if (is.null(args$output)) {
stop("Missing required option: --output")
}
args
}
args <- parse_args(commandArgs(trailingOnly = TRUE))
mat <- read.table(
args$matrix,
header = TRUE,
row.names = 1,
sep = "\t",
check.names = FALSE,
quote = "",
comment.char = ""
)
mat <- as.matrix(mat)
pdf(args$output)
draw(Heatmap(mat, name = args$title))
dev.off()Concept: Galaxy calls command-line programs. This script is the command-line interface around the R package.
In tools/complex_heatmap/complex_heatmap.xml, set the command to:
<command detect_errors="exit_code"><![CDATA[
Rscript '$__tool_directory__/complex_heatmap.R'
--matrix '$matrix'
--output '$heatmap'
--title '$title'
]]></command>Concept: $__tool_directory__ points to the directory containing the XML file,
so Galaxy can find the helper R script during test and runtime.
Use one matrix input, one title parameter, and one PDF output:
<inputs>
<param type="data" name="matrix" format="tsv"/>
<param name="title" type="text" value="Heatmap" label="Heatmap title"/>
</inputs>
<outputs>
<data name="heatmap" format="pdf"/>
</outputs>Concept: Galaxy exposes XML parameters as form fields and makes their values available in the command template.
Create:
tools/complex_heatmap/test-data/matrix.tsv
with:
gene sample_A sample_B sample_C sample_D
gene_1 1.2 2.1 3.0 4.4
gene_2 2.4 1.8 3.6 4.1
gene_3 3.1 2.9 1.7 2.5
gene_4 4.0 3.3 2.2 1.4Concept: Planemo looks for test files in a test-data/ directory next to the
tool XML.
Add this block after <outputs>:
<tests>
<test>
<param name="matrix" value="matrix.tsv"/>
<param name="title" value="Workshop heatmap"/>
<output name="heatmap" ftype="pdf">
<assert_contents>
<has_text text="%PDF"/>
</assert_contents>
</output>
</test>
</tests>Concept: plot files can vary slightly across systems, so this first test checks that the tool successfully creates a PDF instead of comparing exact bytes.
Add user-facing help:
<help><![CDATA[
Complex heatmaps are efficient to visualize associations between
different sources of data sets and reveal potential patterns. Here the
ComplexHeatmap package provides a highly flexible way to arrange
multiple heatmaps and supports various annotation graphics.
]]></help>Add citations:
<citations>
<citation type="doi">doi:10.1093/bioinformatics/btw313</citation>
<citation type="doi">doi:10.1002/imt2.43</citation>
</citations>Concept: Galaxy wrappers should document what the tool does and credit the software being wrapped.
Run:
planemo format tools/complex_heatmap/complex_heatmap.xmlConcept: formatting keeps wrapper XML consistent and easier to review.
Run:
planemo lint tools/complex_heatmap/complex_heatmap.xmlConcept: linting checks common Galaxy wrapper issues before running a full test.
Run:
planemo test --biocontainers tools/complex_heatmap/complex_heatmap.xmlConcept: the test runs through Galaxy using a containerized dependency environment. No local R installation is needed.
Create the ToolShed repository metadata with planemo shed_init.
planemo shed_init tools/complex_heatmap \
--name complex_heatmap \
--owner YOUR_TEST_TOOLSHED_USERNAME \
--description "Draw a heatmap from a numeric matrix with ComplexHeatmap" \
--long_description "A Galaxy wrapper for the Bioconductor ComplexHeatmap package. The tool accepts a tabular numeric matrix and produces a PDF heatmap." \
--category Visualization \
--remote_repository_url https://github.com/YOUR_GITHUB_USERNAME/galaxy-tools-repo/tree/main/tools/complex_heatmap \
--homepage_url https://bioconductor.org/packages/ComplexHeatmapThis creates:
tools/complex_heatmap/.shed.yml
Concept: .shed.yml describes the installable ToolShed repository: its name,
owner, description, category, and source links. Planemo uses this file when it
creates or updates the repository in a ToolShed.
Create an account on the Galaxy Test ToolShed and generate an API key:
https://testtoolshed.g2.bx.psu.edu/
Then make the key available to Planemo:
export PLANEMO_TEST_TOOLSHED_API_KEY=YOUR_TEST_TOOLSHED_API_KEYConcept: the Test ToolShed is the safe place to practice publishing. It behaves like the main ToolShed but is intended for testing and workshops.
Run:
planemo shed_lint --tools --ensure_metadata tools/complex_heatmapConcept: planemo lint checks the Galaxy tool XML, while planemo shed_lint
checks the ToolShed package around the tool. The --tools flag runs both
checks together.
Create the repository and upload the wrapper:
planemo shed_create \
--shed_target testtoolshed \
--shed_key_from_env PLANEMO_TEST_TOOLSHED_API_KEY \
tools/complex_heatmapConcept: shed_create creates the repository named in .shed.yml and uploads
the files in tools/complex_heatmap/.
After editing the wrapper, tests, help, or metadata, upload a new revision:
planemo shed_update \
--shed_target testtoolshed \
--shed_key_from_env PLANEMO_TEST_TOOLSHED_API_KEY \
--check_diff \
tools/complex_heatmapConcept: each meaningful upload creates a new installable ToolShed revision.
--check_diff avoids uploading when there is no real content change.
At the end, the tool directory should contain:
tools/complex_heatmap/
├── .shed.yml
├── complex_heatmap.R
├── complex_heatmap.xml
└── test-data/
└── matrix.tsv
The wrapper is now tested locally and published to the Galaxy Test ToolShed. From here, the workshop can continue with wrapper improvements such as row clustering, column clustering, image dimensions, color palettes, or annotations.